diff --git a/loop.c b/loop.c index 1ed78e5..644593d 100644 --- a/loop.c +++ b/loop.c @@ -53,6 +53,12 @@ #include "binlog.h" #include "lua-tg.h" +// + +#include "purple-plugin/telegram-purple.h" +// + + extern char *default_username; extern char *auth_token; extern int test_dc; @@ -92,7 +98,7 @@ void net_loop (int flags, int (*is_end)(void)) { if (flags & 1) { rl_callback_read_char (); } else { - char *line = 0; + char *line = 0; size_t len = 0; assert (getline (&line, &len, stdin) >= 0); got_it (line, strlen (line)); @@ -110,7 +116,7 @@ void net_loop (int flags, int (*is_end)(void)) { if (unknown_user_list_pos) { do_get_user_list_info_silent (unknown_user_list_pos, unknown_user_list); unknown_user_list_pos = 0; - } + } } } @@ -122,7 +128,7 @@ void got_it (char *line, int len) { assert (len > 0); line[-- len] = 0; // delete end of line *_s = line; - *_l = len; + *_l = len; got_it_ok = 1; } @@ -170,7 +176,7 @@ void write_dc (int auth_file_fd, struct dc *DC) { } else { assert (write (auth_file_fd, zero, 256 + 8) == 256 + 8); } - + assert (write (auth_file_fd, &DC->server_salt, 8) == 8); assert (write (auth_file_fd, &DC->has_auth, 4) == 4); } @@ -214,6 +220,9 @@ void read_dc (int auth_file_fd, int id, unsigned ver) { assert (read (auth_file_fd, &DC->auth_key_id, 8) == 8); assert (read (auth_file_fd, &DC->auth_key, 256) == 256); assert (read (auth_file_fd, &DC->server_salt, 8) == 8); + printf("auth_key_id: %lli \n", DC->auth_key_id); + printf("auth_key_id: ?"); + printf("server_salt: %lli \n", DC->server_salt); if (DC->auth_key_id) { DC->flags |= 1; } @@ -287,14 +296,14 @@ void read_state_file (void) { assert (version >= 0); int x[4]; if (read (state_file_fd, x, 16) < 16) { - close (state_file_fd); + close (state_file_fd); return; } pts = x[0]; qts = x[1]; seq = x[2]; last_date = x[3]; - close (state_file_fd); + close (state_file_fd); } void write_state_file (void) { @@ -316,7 +325,7 @@ void write_state_file (void) { x[4] = seq; x[5] = last_date; assert (write (state_file_fd, x, 24) == 24); - close (state_file_fd); + close (state_file_fd); wseq = seq; wpts = pts; wqts = qts; wdate = last_date; } @@ -412,7 +421,7 @@ void write_secret_chat_file (void) { t = strlen (Peers[i]->print_name); assert (write (fd, &t, 4) == 4); assert (write (fd, Peers[i]->print_name, t) == t); - + assert (write (fd, &Peers[i]->encr_chat.state, 4) == 4); assert (write (fd, &Peers[i]->encr_chat.user_id, 4) == 4); @@ -426,7 +435,7 @@ void write_secret_chat_file (void) { assert (write (fd, Peers[i]->encr_chat.nonce, 256) == 256); } assert (write (fd, Peers[i]->encr_chat.key, 256) == 256); - assert (write (fd, &Peers[i]->encr_chat.key_fingerprint, 8) == 8); + assert (write (fd, &Peers[i]->encr_chat.key_fingerprint, 8) == 8); } } assert (write (fd, &encr_root, 4) == 4); @@ -454,7 +463,7 @@ int readline_active; int new_dc_num; int wait_dialog_list; -int loop (void) { +void init_loop (void) { on_start (); if (binlog_enabled) { double t = get_double_time (); @@ -480,7 +489,7 @@ int loop (void) { auth_state = 100; write_auth_file (); } - + if (verbosity) { logprintf ("Requesting info about DC...\n"); } @@ -495,61 +504,42 @@ int loop (void) { assert (DC_list[i]->auth_key_id); write_auth_file (); } +} +int start_loop (char* code, char* auth_mode) { if (auth_state == 100 || !(DC_working->has_auth)) { - if (!default_username) { - size_t size = 0; - char *user = 0; - - if (!user) { - printf ("Telephone number (with '+' sign): "); - if (net_getline (&user, &size) == -1) { - perror ("getline()"); - exit (EXIT_FAILURE); - } - set_default_username (user); - } - } int res = do_auth_check_phone (default_username); assert (res >= 0); logprintf ("%s\n", res > 0 ? "phone registered" : "phone not registered"); if (res > 0 && !register_mode) { - do_send_code (default_username); - char *code = 0; - size_t size = 0; - printf ("Code from sms (if you did not receive an SMS and want to be called, type \"call\"): "); - while (1) { - if (net_getline (&code, &size) == -1) { - perror ("getline()"); - exit (EXIT_FAILURE); - } - if (!strcmp (code, "call")) { - printf ("You typed \"call\", switching to phone system.\n"); - do_phone_call (default_username); - printf ("Calling you! Code: "); - continue; - } + // Register Mode 1 + if (code) { if (do_send_code_result (code) >= 0) { - break; + printf ("Authentication successfull, state = 300\n"); + auth_state = 300; } - printf ("Invalid code. Try again: "); - tfree_str (code); + } else { + // Send Code + if (strcmp(TELEGRAM_AUTH_MODE_SMS, auth_mode)) { + do_send_code (default_username); + printf ("Code from sms (if you did not receive an SMS and want to be called, type \"call\"): "); + } else { + printf ("You typed \"call\", switching to phone system.\n"); + do_phone_call (default_username); + printf ("Calling you!"); + } } - auth_state = 300; } else { printf ("User is not registered. Do you want to register? [Y/n] "); - char *code; + printf ("ERROR THIS IS NOT POSSIBLE!\n"); + return 1; + // Register Mode 2 + // TODO: Requires first and last name, decide how to handle this. + // - We need some sort of switch between registration modes + // - When this mode is selected First and Last name should be added to the form + // Currently Requires Manuel Entry in Terminal. + /* size_t size; - if (net_getline (&code, &size) == -1) { - perror ("getline()"); - exit (EXIT_FAILURE); - } - if (!*code || *code == 'y' || *code == 'Y') { - printf ("Ok, starting registartion.\n"); - } else { - printf ("Then try again\n"); - exit (EXIT_SUCCESS); - } char *first_name; printf ("First name: "); if (net_getline (&first_name, &size) == -1) { @@ -567,30 +557,26 @@ int loop (void) { assert (dc_num >= 0 && dc_num <= MAX_DC_NUM && DC_list[dc_num]); dc_working_num = dc_num; DC_working = DC_list[dc_working_num]; - - do_send_code (default_username); - printf ("Code from sms (if you did not receive an SMS and want to be called, type \"call\"): "); - while (1) { - if (net_getline (&code, &size) == -1) { - perror ("getline()"); - exit (EXIT_FAILURE); - } - if (!strcmp (code, "call")) { - printf ("You typed \"call\", switching to phone system.\n"); - do_phone_call (default_username); - printf ("Calling you! Code: "); - continue; - } - if (do_send_code_result_auth (code, first_name, last_name) >= 0) { - break; - } - printf ("Invalid code. Try again: "); - tfree_str (code); + + if (*code) { + if (do_send_code_result_auth (code, first_name, last_name) >= 0) { + auth_state = 300; + } + } else { + if (strcmp(TELEGRAM_AUTH_MODE_SMS, auth_mode)) { + do_send_code (default_username); + printf ("Code from sms (if you did not receive an SMS and want to be called, type \"call\"): "); + } else { + printf ("You typed \"call\", switching to phone system.\n"); + do_phone_call (default_username); + printf ("Calling you! Code: "); + } } - auth_state = 300; + */ } } + int i; for (i = 0; i <= MAX_DC_NUM; i++) if (DC_list[i] && !DC_list[i]->has_auth) { do_export_auth (i); do_import_auth (i); @@ -614,13 +600,29 @@ int loop (void) { #endif send_all_unsent (); - do_get_dialog_list (); if (wait_dialog_list) { dialog_list_got = 0; net_loop (0, dlgot); } - return main_loop (); + return 0; //main_loop (); } +/** + * Do what loop does, but use input from arguments instead of prompting + * the user + * + * When authentication is not yet done, request authenticatino code and exit + * with 0. In all other cases exit with 1. + */ +int loop_auto(char *username, char *code, char* auth_mode) { + init_loop(); + set_default_username (username); + return start_loop(code, auth_mode); +} + +int loop (void) { + init_loop(); + return start_loop(NULL, NULL); +} diff --git a/loop.h b/loop.h index 6f7c7e4..b586133 100644 --- a/loop.h +++ b/loop.h @@ -19,6 +19,7 @@ #ifndef __LOOP_H__ #define __LOOP_H__ int loop (void); +int loop_auto(char *username, char *code, char *auth_mode); void net_loop (int flags, int (*end)(void)); void write_auth_file (void); void write_state_file (void); diff --git a/main.c b/main.c index 9d858df..a8aa8e8 100644 --- a/main.c +++ b/main.c @@ -476,7 +476,7 @@ void sig_abrt_handler (int signum __attribute__ ((unused))) { exit (EXIT_FAILURE); } -int main (int argc, char **argv) { +int tgmain (int argc, char **argv) { signal (SIGSEGV, sig_segv_handler); signal (SIGABRT, sig_abrt_handler); @@ -503,6 +503,19 @@ int main (int argc, char **argv) { /** * Log into Telegram with the given login credentials. */ -int tg_login () { - return main(0, NULL); +int tg_login (char *username, char *code, char *auth_mode) { + log_level = 10; + running_for_first_time (); + parse_config (); + + get_terminal_attributes (); + + #ifdef USE_LUA + if (lua_file) { + lua_init (lua_file); + } + #endif + + loop_auto(username, code, auth_mode); + return 0; } diff --git a/purple-plugin/telegram-purple.c b/purple-plugin/telegram-purple.c index ad49259..31f5db6 100644 --- a/purple-plugin/telegram-purple.c +++ b/purple-plugin/telegram-purple.c @@ -15,6 +15,7 @@ */ #include +#include // Libpurple Plugin Includes #include "notify.h" @@ -82,18 +83,34 @@ static void tgprpl_login(PurpleAccount * acct) { purple_debug_info(PLUGIN_ID, "tgprpl_login()\n"); - purple_debug_info(PLUGIN_ID, "calling runtg()\n"); - tg_login(); - purple_debug_info(PLUGIN_ID, "returned from runtg()\n"); - - /* - PurpleConnection *gc = purple_account_get_connection(acct); - const char *username = purple_account_get_username(acct); - const char *sms_key = purple_account_get_string(acct, "sms_key", ""); + const char *code = purple_account_get_string(acct, "sms_key", NULL); const char *hostname = purple_account_get_string(acct, "server", TELEGRAM_TEST_SERVER); int port = purple_account_get_int(acct, "port", TELEGRAM_DEFAULT_PORT); + printf("username: %s\n", username); + printf("code: %s\n", code); + printf("hostname: %s\n", hostname); + + // TODO: Do proper input validation + if (code && strcmp(code, "")) { + code = NULL; + } +// You should receive a SMS with a code soon, please copy that code into the account option 'Verification Key'. + if (!code) { + purple_notify_message( + _telegram_protocol, + PURPLE_NOTIFY_MSG_INFO, + "Telegram Verification", + "Telegram needs to verify this phone number. ", + NULL, + NULL, + NULL + ); + } + tg_login(username, code, TELEGRAM_AUTH_MODE_SMS); + /* + PurpleConnection *gc = purple_account_get_connection(acct); purple_debug_info(PLUGIN_ID, "logging in %s\n", username); if (strcmp(sms_key[0], "")) { @@ -494,7 +511,7 @@ static void tgprpl_init(PurplePlugin *plugin) GList *verification_values = NULL; // Required Verification-Key - split = purple_account_user_split_new("Verification key", "-", '@'); + split = purple_account_user_split_new("Verification key", NULL, '@'); purple_account_user_split_set_reverse(split, FALSE); prpl_info.user_splits = g_list_append(prpl_info.user_splits, split); @@ -505,15 +522,16 @@ static void tgprpl_init(PurplePlugin *plugin) kvp->value = g_strdup((v)); \ list = g_list_prepend(list, kvp); \ } - ADD_VALUE(verification_values, "Phone", "phone"); - ADD_VALUE(verification_values, "SMS", "sms"); + ADD_VALUE(verification_values, "Phone", TELEGRAM_AUTH_MODE_PHONE); + ADD_VALUE(verification_values, "SMS", TELEGRAM_AUTH_MODE_SMS); option = purple_account_option_list_new("Verification type", "verification_type", verification_values); prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); option = purple_account_option_string_new("Server", "server", TELEGRAM_TEST_SERVER); prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); - // TODO: Path to public key (When you can change the server hostname, you should also be able to change the public key) + // TODO: Path to public key (When you can change the server hostname, + // you should also be able to change the public key) option = purple_account_option_int_new("Port", "port", TELEGRAM_DEFAULT_PORT); prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); @@ -521,14 +539,6 @@ static void tgprpl_init(PurplePlugin *plugin) _telegram_protocol = plugin; } -/* -static gboolean plugin_load(PurplePlugin *plugin) { - purple_notify_message(plugin, PURPLE_NOTIFY_MSG_INFO, "Hallo Telegram", - "Das ist nur ein Test des Build-Systems, bitte einfach weiter gehen.", NULL, NULL, NULL); - return TRUE; -} -*/ - static GList *tgprpl_actions(PurplePlugin * plugin, gpointer context) { // return possible actions (See Libpurple doc) diff --git a/purple-plugin/telegram-purple.h b/purple-plugin/telegram-purple.h index 72f7c32..3c0d48a 100644 --- a/purple-plugin/telegram-purple.h +++ b/purple-plugin/telegram-purple.h @@ -31,6 +31,9 @@ #define TELEGRAM_DEFAULT_PORT 443 #define TELEGRAM_PUBLIC_KEY "-----BEGIN RSA PUBLIC KEY-----MIIBCgKCAQEAwVACPi9w23mF3tBkdZz+zwrzKOaaQdr01vAbU4E1pvkfj4sqDsm6lyDONS789sVoD/xCS9Y0hkkC3gtL1tSfTlgCMOOul9lcixlEKzwKENj1Yz/s7daSan9tqw3bfUV/nqgbhGX81v/+7RFAEd+RwFnK7a+XYl9sluzHRyVVaTTveB2GazTwEfzk2DWgkBluml8OREmvfraX3bkHZJTKX4EQSjBbbdJ2ZXIsRrYOXfaA+xayEGB+8hdlLmAjbCVfaigxX0CDqWeR1yFL9kwd9P0NsZRPsmoqVwMbMu7mStFai6aIhc3nSlv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB-----END RSA PUBLIC KEY-----" +#define TELEGRAM_AUTH_MODE_PHONE "phone" +#define TELEGRAM_AUTH_MODE_SMS "sms" + typedef struct { PurpleAccount *account; PurpleConnection *gc; diff --git a/tg-cli.h b/tg-cli.h index b51fbf4..95b1156 100755 --- a/tg-cli.h +++ b/tg-cli.h @@ -1,3 +1,7 @@ // Export functions for plugins int tg_login (); + +// Settings +#define AUTH_MODE_SMS "sms" +#define AUTH_MODE_PHONE "phone"