Support two factor authentication

This commit is contained in:
mjentsch 2015-05-29 18:25:55 +02:00
parent 0bcbb272ee
commit 49cc80f8c0
9 changed files with 194 additions and 87 deletions

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6751" systemVersion="14C1514" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14D136" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6751"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="TelegramAccountViewController">
@ -14,6 +14,7 @@
<outlet property="textField_accountUIDLabel" destination="yae-v6-YMB" id="XHk-zX-T5y"/>
<outlet property="textField_historyRetrieveDays" destination="gKj-Oj-qll" id="tvW-aI-8ws"/>
<outlet property="textField_inactiveDaysOffline" destination="Nvv-1I-L31" id="8Sn-4f-M5j"/>
<outlet property="textField_passwordTwoFactor" destination="Hkg-uU-btb" id="LvJ-1q-ud2"/>
<outlet property="view_options" destination="DGa-mQ-g3C" id="L0S-pj-8w4"/>
<outlet property="view_setup" destination="c22-O7-iKe" id="xp5-o5-fb9"/>
</connections>
@ -21,11 +22,11 @@
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView id="c22-O7-iKe" userLabel="Setup">
<rect key="frame" x="0.0" y="0.0" width="321" height="100"/>
<rect key="frame" x="0.0" y="5" width="321" height="150"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Mv3-b8-21b">
<rect key="frame" x="124" y="56" width="177" height="22"/>
<rect key="frame" x="124" y="106" width="177" height="22"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" placeholderString="+491573123456" drawsBackground="YES" id="ddM-ki-WMe">
<font key="font" metaFont="system"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
@ -33,26 +34,53 @@
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="yae-v6-YMB">
<rect key="frame" x="-54" y="59" width="172" height="17"/>
<rect key="frame" x="-54" y="109" width="172" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Phone Number:" id="0UB-Dx-PpB">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="CGg-HM-Fxl">
<rect key="frame" x="-54" y="39" width="172" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Password:" id="8u1-y6-XZw">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="MCb-6Q-kUW">
<rect key="frame" x="28" y="20" width="264" height="28"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" title="Your phone number in the international format, a leading '+' and without any other special chars." id="2C9-SB-kKZ">
<rect key="frame" x="22" y="70" width="274" height="28"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="left" title="Your phone number in the international format, a leading '+' and without any other special chars." id="2C9-SB-kKZ">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="PaN-W9-uI1">
<rect key="frame" x="22" y="0.0" width="285" height="28"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="left" title="Needed when using two factor authentication." id="cCC-Jv-B6B">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<secureTextField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Hkg-uU-btb">
<rect key="frame" x="124" y="36" width="177" height="22"/>
<secureTextFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" usesSingleLineMode="YES" id="xzm-aB-xvz">
<font key="font" metaFont="system"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
<allowedInputSourceLocales>
<string>NSAllRomanInputSourcesLocaleIdentifier</string>
</allowedInputSourceLocales>
</secureTextFieldCell>
</secureTextField>
</subviews>
<point key="canvasLocation" x="380.5" y="13"/>
<point key="canvasLocation" x="380.5" y="38"/>
</customView>
<customView id="DGa-mQ-g3C" userLabel="Options">
<rect key="frame" x="0.0" y="0.0" width="272" height="183"/>
<rect key="frame" x="0.0" y="0.0" width="272" height="190"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zRH-KJ-uvC" userLabel="Accept Secret Chats">
@ -170,7 +198,7 @@
</textFieldCell>
</textField>
</subviews>
<point key="canvasLocation" x="356" y="209.5"/>
<point key="canvasLocation" x="356" y="294"/>
</customView>
<userDefaultsController representsSharedInstance="YES" id="OjL-yD-9te"/>
</objects>

View file

@ -1,17 +1,19 @@
/*
* Adium is the legal property of its developers, whose names are listed in the copyright file included
* with this source distribution.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU
* General Public License as published by the Free Software Foundation; either version 2 of the License,
* or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program; if not,
* write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*
* Copyright Matthias Jentsch 2014-2015
*/
#import <Adium/AIAccountViewController.h>
@ -24,6 +26,7 @@
IBOutlet NSTextField *textField_maxMsgSplitCount;
IBOutlet NSTextField *textField_inactiveDaysOffline;
IBOutlet NSTextField *textField_historyRetrieveDays;
IBOutlet NSSecureTextField *textField_passwordTwoFactor;
IBOutlet NSMatrix *radio_Encryption;
}

View file

@ -1,17 +1,19 @@
/*
* Adium is the legal property of its developers, whose names are listed in the copyright file included
* with this source distribution.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU
* General Public License as published by the Free Software Foundation; either version 2 of the License,
* or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program; if not,
* write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*
* Copyright Matthias Jentsch 2014-2015
*/
#import "TelegramAccountViewController.h"
@ -46,6 +48,10 @@
}
[radio_Encryption selectCellAtRow:row column:0];
NSString *passwordTwoFactor = [account preferenceForKey:@"Telegram:"TGP_KEY_PASSWORD_TWO_FACTOR
group:GROUP_ACCOUNT_STATUS] ?: nil;
[textField_password setStringValue:passwordTwoFactor];
id s = [account preferenceForKey:@"Telegram:"TGP_KEY_HISTORY_SYNC_ALL group:GROUP_ACCOUNT_STATUS];
[checkbox_historySyncAll setState:[s boolValue]];
@ -69,6 +75,10 @@
NSArray *selections = @[@"ask", @"always", @"never"];
[account setPreference:[textField_password stringValue]
forKey:@"Telegram:"TGP_KEY_PASSWORD_TWO_FACTOR
group:GROUP_ACCOUNT_STATUS];
[account setPreference:selections[[radio_Encryption selectedRow]]
forKey:@"Telegram:"TGP_KEY_ACCEPT_SECRET_CHATS
group:GROUP_ACCOUNT_STATUS];

View file

@ -1,17 +1,19 @@
/*
* Adium is the legal property of its developers, whose names are listed in the copyright file included
* with this source distribution.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU
* General Public License as published by the Free Software Foundation; either version 2 of the License,
* or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program; if not,
* write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*
* Copyright Matthias Jentsch 2014-2015
*/
#import <Adium/DCJoinChatViewController.h>
@ -19,7 +21,6 @@
@class AIAccount, AICompletingTextField;
@interface TelegramJoinChatViewController : DCJoinChatViewController {
// IBOutlet NSTextField *textField_newChat;
IBOutlet NSPopUpButton *popupButton_existingChat;
}

View file

@ -1,17 +1,19 @@
/*
* Adium is the legal property of its developers, whose names are listed in the copyright file included
* with this source distribution.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU
* General Public License as published by the Free Software Foundation; either version 2 of the License,
* or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program; if not,
* write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*
* Copyright Matthias Jentsch 2014-2015
*/
#include <tgl.h>

View file

@ -467,25 +467,6 @@ static void request_code_canceled (gpointer data) {
PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, "registration canceled");
}
static void request_name_code_entered (PurpleConnection* gc, PurpleRequestFields* fields) {
connection_data *conn = purple_connection_get_protocol_data(gc);
struct tgl_state *TLS = conn->TLS;
char const *username = purple_account_get_username(conn->pa);
const char* first = purple_request_fields_get_string(fields, "first_name");
const char* last = purple_request_fields_get_string(fields, "last_name");
const char* code = purple_request_fields_get_string(fields, "code");
if (!first || !last || !code) {
request_name_and_code (TLS);
return;
}
tgl_do_send_code_result_auth(TLS, username, (int)strlen(username), conn->hash,
(int)strlen (conn->hash), code, (int)strlen (code), first,
(int)strlen (first), last, (int)strlen (last),
code_auth_receive_result, NULL);
}
static void request_code (struct tgl_state *TLS) {
debug ("Client is not registered, registering...");
connection_data *conn = TLS->ev_base;
@ -507,6 +488,25 @@ static void request_code (struct tgl_state *TLS) {
}
}
static void request_name_code_entered (PurpleConnection* gc, PurpleRequestFields* fields) {
connection_data *conn = purple_connection_get_protocol_data(gc);
struct tgl_state *TLS = conn->TLS;
char const *username = purple_account_get_username(conn->pa);
const char* first = purple_request_fields_get_string(fields, "first_name");
const char* last = purple_request_fields_get_string(fields, "last_name");
const char* code = purple_request_fields_get_string(fields, "code");
if (!first || !last || !code) {
request_name_and_code (TLS);
return;
}
tgl_do_send_code_result_auth(TLS, username, (int)strlen(username), conn->hash,
(int)strlen (conn->hash), code, (int)strlen (code), first,
(int)strlen (first), last, (int)strlen (last),
code_auth_receive_result, NULL);
}
static void request_name_and_code (struct tgl_state *TLS) {
debug ("Phone is not registered, registering...");
@ -536,6 +536,41 @@ static void request_name_and_code (struct tgl_state *TLS) {
}
}
static void request_password_entered (struct request_password_data *data, PurpleRequestFields* fields) {
const char* pass = purple_request_fields_get_string (fields, "password");
data->callback (data->TLS, pass, data->arg);
free (data);
}
void request_password (struct tgl_state *TLS,
void (*callback)(struct tgl_state *TLS, const char *string, void *arg),
void *arg) {
connection_data *conn = TLS->ev_base;
struct request_password_data *data = malloc (sizeof(struct request_password_data));
data->TLS = TLS;
data->arg = arg;
data->callback = callback;
PurpleRequestFields* fields = purple_request_fields_new();
PurpleRequestField* field = NULL;
PurpleRequestFieldGroup* group = purple_request_field_group_new ("");
field = purple_request_field_string_new ("password", "Password", "", 0);
purple_request_field_string_set_masked (field, TRUE);
purple_request_field_group_add_field (group, field);
purple_request_fields_add_group (fields, group);
if (!purple_request_fields (conn->gc, "Password needed", "Enter password for two factor authentication",
NULL, fields, "Ok", G_CALLBACK(request_password_entered), "Cancel", NULL, conn->pa,
NULL, NULL, data)) {
const char *error = "No password for two factor authentication, enter it in extended settings.";
purple_connection_error_reason (conn->gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, error);
purple_notify_error (_telegram_protocol, "Password invalid", "Password invalid", error);
}
}
void write_secret_chat_gw (struct tgl_state *TLS, void *extra, int success, struct tgl_secret_chat *E) {
if (!success) { return; }
write_secret_chat_file (TLS);

View file

@ -22,6 +22,12 @@
#include "telegram-purple.h"
struct request_password_data {
struct tgl_state *TLS;
void (*callback)(struct tgl_state *TLS, const char *string, void *arg);
void *arg;
};
void read_state_file (struct tgl_state *TLS);
void read_auth_file (struct tgl_state *TLS);
void write_auth_file (struct tgl_state *TLS);
@ -33,6 +39,7 @@ void write_secret_chat_gw (struct tgl_state *TLS, void *extra, int success, stru
void telegram_login (struct tgl_state *TLS);
void request_code_entered (gpointer data, const gchar *code);
void request_password (struct tgl_state *TLS, void (*callback)(struct tgl_state *TLS, const char *string, void *arg), void *arg);
void request_accept_secret_chat (struct tgl_state *TLS, struct tgl_secret_chat *U);

View file

@ -72,6 +72,7 @@
#include "tgp-ft.h"
#include "tgp-msg.h"
static void get_password (struct tgl_state *TLS, const char *prompt, int flags, void (*callback)(struct tgl_state *TLS, const char *string, void *arg), void *arg);
static void update_message_received (struct tgl_state *TLS, struct tgl_message *M);
static void update_user_handler (struct tgl_state *TLS, struct tgl_user *U, unsigned flags);
static void update_user_status_handler (struct tgl_state *TLS, struct tgl_user *U);
@ -87,6 +88,7 @@ const char *pk_path = "/etc/telegram-purple/server.pub";
struct tgl_update_callback tgp_callback = {
.logprintf = debug,
.get_string = get_password,
.new_msg = update_message_received,
.msg_receive = update_message_received,
.user_update = update_user_handler,
@ -251,6 +253,19 @@ static char *format_print_name (struct tgl_state *TLS, tgl_peer_id_t id, const c
return tgl_strdup (s);
}
static void get_password (struct tgl_state *TLS, const char *prompt, int flags,
void (*callback)(struct tgl_state *TLS, const char *string, void *arg), void *arg) {
connection_data *conn = TLS->ev_base;
const char *P = purple_account_get_string (conn->pa, TGP_KEY_PASSWORD_TWO_FACTOR, NULL);
if (str_not_empty (P)) {
if (conn->password_retries++ < 1) {
callback (TLS, P, arg);
return;
}
}
request_password (TLS, callback, arg);
}
static void on_contact_added (struct tgl_state *TLS,void *callback_extra, int success, int size, struct tgl_user *users[]) {
PurpleBuddy *buddy = callback_extra;
@ -762,10 +777,14 @@ static void tgprpl_init (PurplePlugin *plugin) {
// Login
opt = purple_account_option_string_new ("Password (two factor authentication)",
TGP_KEY_PASSWORD_TWO_FACTOR, NULL);
prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, opt);
opt = purple_account_option_bool_new("Fallback SMS Verification", "compat-verification", 0);
prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, opt);
// Messaging
GList *verification_values = NULL;

View file

@ -54,6 +54,8 @@
#define TGP_KEY_HISTORY_SYNC_ALL "history-sync-all"
#define TGP_DEFAULT_HISTORY_SYNC_ALL FALSE
#define TGP_KEY_PASSWORD_TWO_FACTOR "password-two-factor"
void on_chat_get_info (struct tgl_state *TLS, void *extra, int success, struct tgl_chat *C);
void on_ready (struct tgl_state *TLS);
extern const char *pk_path;