From 377c809ba760368c118cb21c286ab3a5f45ff15e Mon Sep 17 00:00:00 2001 From: mjentsch Date: Sun, 11 May 2014 22:18:21 +0200 Subject: [PATCH] Add options for user verification, refactor header file-name to include functions into the purple-plugin and copy server.pub into the /etc/telegram directory when installing. --- Makefile.in | 10 ++--- README.md | 20 ++++----- interface.c | 80 +++++++++++++++++---------------- libtg.h | 1 - main.c | 19 ++++---- mtproto-client.c | 74 +++++++++++++++--------------- purple-plugin/Makefile | 5 ++- purple-plugin/telegram-purple.c | 53 ++++++++++++---------- purple-plugin/telegram-purple.h | 38 ++++++++++++++++ tg-cli.h | 3 ++ 10 files changed, 178 insertions(+), 125 deletions(-) delete mode 100755 libtg.h create mode 100644 purple-plugin/telegram-purple.h create mode 100755 tg-cli.h diff --git a/Makefile.in b/Makefile.in index cdf6230..e710bd7 100644 --- a/Makefile.in +++ b/Makefile.in @@ -6,6 +6,9 @@ CPPFLAGS=@CPPFLAGS@ DEFS=@DEFS@ COMPILE_FLAGS=${CFLAGS} ${CPPFLAGS} ${DEFS} -Wall -Wextra -Werror -Wno-deprecated-declarations -fno-strict-aliasing -fno-omit-frame-pointer -ggdb +# include libpurple headers for debugging purposes +CFLAGS_PURPLE = $(shell pkg-config --cflags purple) + EXTRA_LIBS=@LIBS@ @EXTRA_LIBS@ LOCAL_LDFLAGS=-rdynamic -ggdb ${EXTRA_LIBS} LINK_FLAGS=${LDFLAGS} ${LOCAL_LDFLAGS} @@ -27,12 +30,9 @@ telegram: ${OBJECTS} ${CC} ${OBJECTS} ${LINK_FLAGS} -o $@ .c.o : - ${CC} -fPIC -DPIC ${COMPILE_FLAGS} ${INCLUDE} -c $< -o $@ + ${CC} -fPIC -DPIC ${CFLAGS_PURPLE} ${COMPILE_FLAGS} ${INCLUDE} -c $< -o $@ -libtg.a: ${OBJECTS} - ar rs $@ ${OBJECTS} - -library: libtg.a +objects: ${OBJECTS} clean: rm -rf *.a *.o telegram config.log config.status > /dev/null || echo "all clean" diff --git a/README.md b/README.md index 6bb221f..2550852 100644 --- a/README.md +++ b/README.md @@ -15,10 +15,10 @@ telegram-purple cd telgram-purple - ./configure --disable-liblua --disable-libconfig - make - cd purple-plugin - make install + ./configure --disable-liblua --disable-libconfig + make objects + cd purple-plugin + make install Das Protokoll Telegram sollte dann beim nächsten Start in der Accountverwaltung von Pidgin automatisch auftauchen. @@ -31,7 +31,7 @@ Um **telegram-purple** während der Entwicklung zu testen, ist es sinnvoll vorhe sudo chmod 777 -R `pkg-config --variable=plugindir purple` sudo chmod 777 -R `pkg-config --variable=datarootdir purple`pixmaps/pidgin/protocol - + ## Testen @@ -40,7 +40,7 @@ Zum Compilen, Testen und Ausgeben aller Debugnachrichten folgenden Befehl ausfü make run - + Falls die Lognachrichten nach kurzer Zeit nicht mehr angezeigt werden, und die Meldung "Wird geschlossen, da bereits ein andere libpurple-Client läuft" erscheint, die laufende Instanz von Pidgin mit folgendem Befehl beenden: @@ -48,7 +48,7 @@ Falls die Lognachrichten nach kurzer Zeit nicht mehr angezeigt werden, und die M sudo killall pidgin - + ### Filtern der Lognachrichten Wenn Pidgin einfach mit **make run** ausgeführt wird, werden alle Debugnachrichten des gesamten Programms ausgegegeben. Libpurple verwendet interne Loggingfunktionen die den Lognachrichten automatisch einen Prefix hinzufügen, z.B. "plugins:" für Nachrichten des Pluginsloaders und "prpl-telegram:" für Nachrichten dieses Plugins. @@ -86,14 +86,14 @@ Wir wollen wenn möglichen den typischen Linux-C-Coding-Style verwenden. Bei Fun ## Logging -Wenn irgendeine Ausgabe gemacht wird, sollte das ausschließlich über die Libpurple Debugging-Funktionen passieren (Siehe die Anleitung zum Debuggen im [Libpurple-Howto](https://developer.pidgin.im/wiki/CHowTo/DebugAPIHowTo "Libpurple-HowTo")). +Wenn irgendeine Ausgabe gemacht wird, sollte das ausschließlich über die Libpurple Debugging-Funktionen passieren (Siehe die Anleitung zum Debuggen im [Libpurple-Howto](https://developer.pidgin.im/wiki/CHowTo/DebugAPIHowTo "Libpurple-HowTo")). #include "debug.h" #define PLUGIN_ID "prpl-telegram" - + // ... - + purple_debug_info(PLUGIN_ID, "Debugnachricht"); ## Troubleshooting diff --git a/interface.c b/interface.c index 2be2268..cd7635e 100644 --- a/interface.c +++ b/interface.c @@ -21,7 +21,7 @@ #include "config.h" #endif -#define _GNU_SOURCE +#define _GNU_SOURCE #include #include @@ -46,6 +46,10 @@ #include "mtproto-common.h" +// libpurple debugging-messages +#include "debug.h" +#include "purple-plugin/telegram-purple.h" + #define ALLOW_MULT 1 char *default_prompt = "> "; @@ -79,7 +83,7 @@ int is_same_word (const char *s, size_t l, const char *word) { char *next_token (int *l) { while (*line_ptr == ' ') { line_ptr ++; } - if (!*line_ptr) { + if (!*line_ptr) { *l = 0; return 0; } @@ -110,7 +114,7 @@ long long next_token_int (void) { if (!s) { return NOT_FOUND; } char *r; long long x = strtoll (s, &r, 10); - if (r == s + l) { + if (r == s + l) { return x; } else { return NOT_FOUND; @@ -123,7 +127,7 @@ peer_id_t next_token_user (void) { if (!s) { return PEER_NOT_FOUND; } if (l >= 6 && !memcmp (s, "user#", 5)) { - s += 5; + s += 5; l -= 5; int r = atoi (s); if (r >= 0) { return set_peer_id (PEER_USER, r); } @@ -145,9 +149,9 @@ peer_id_t next_token_chat (void) { int l; char *s = next_token (&l); if (!s) { return PEER_NOT_FOUND; } - + if (l >= 6 && !memcmp (s, "chat#", 5)) { - s += 5; + s += 5; l -= 5; int r = atoi (s); if (r >= 0) { return set_peer_id (PEER_CHAT, r); } @@ -185,16 +189,16 @@ peer_id_t next_token_peer (void) { int l; char *s = next_token (&l); if (!s) { return PEER_NOT_FOUND; } - + if (l >= 6 && !memcmp (s, "user#", 5)) { - s += 5; + s += 5; l -= 5; int r = atoi (s); if (r >= 0) { return set_peer_id (PEER_USER, r); } else { return PEER_NOT_FOUND; } } if (l >= 6 && !memcmp (s, "chat#", 5)) { - s += 5; + s += 5; l -= 5; int r = atoi (s); if (r >= 0) { return set_peer_id (PEER_CHAT, r); } @@ -239,7 +243,7 @@ char *get_default_prompt (void) { } l += tsnprintf (buf + l, 999 - l, "]" COLOR_NORMAL); return buf; - } + } l += tsnprintf (buf + l, 999 - l, "%s", default_prompt); return buf; } @@ -391,7 +395,7 @@ int get_complete_mode (void) { if (*r == '[' && !r[l]) { return 6; } - + if (!*line_ptr) { return 0; } char **command = commands; int n = 0; @@ -482,7 +486,7 @@ int complete_string_list (char **list, int index, const char *text, int len, cha return -1; } } -char *command_generator (const char *text, int state) { +char *command_generator (const char *text, int state) { static int len, index, mode; if (in_chat_mode) { @@ -490,12 +494,12 @@ char *command_generator (const char *text, int state) { index = complete_string_list (in_chat_commands, index, text, rl_point, &R); return R; } - + char c = 0; if (!state) { len = strlen (text); index = -1; - + c = rl_line_buffer[rl_point]; rl_line_buffer[rl_point] = 0; mode = get_complete_mode (); @@ -503,9 +507,9 @@ char *command_generator (const char *text, int state) { if (index == -1) { return 0; } } - if (mode == -1) { + if (mode == -1) { if (c) { rl_line_buffer[rl_point] = c; } - return 0; + return 0; } char *R = 0; @@ -515,7 +519,7 @@ char *command_generator (const char *text, int state) { if (c) { rl_line_buffer[rl_point] = c; } return R; case 1: - index = complete_user_list (index, text, len, &R); + index = complete_user_list (index, text, len, &R); if (c) { rl_line_buffer[rl_point] = c; } return R; case 2: @@ -597,9 +601,9 @@ void interpreter (char *line UU) { line_ptr = line; offline_mode = 0; count = 1; - if (!line) { + if (!line) { in_readline = 0; - return; + return; } if (line && *line) { add_history (line); @@ -626,7 +630,7 @@ void interpreter (char *line UU) { l = ll; command = cs; #define IS_WORD(s) is_same_word (command, l, (s)) -#define RET in_readline = 0; return; +#define RET in_readline = 0; return; peer_id_t id; #define GET_PEER \ @@ -634,25 +638,25 @@ void interpreter (char *line UU) { if (!cmp_peer_id (id, PEER_NOT_FOUND)) { \ printf ("Bad user/chat id\n"); \ RET; \ - } + } #define GET_PEER_USER \ id = next_token_user (); \ if (!cmp_peer_id (id, PEER_NOT_FOUND)) { \ printf ("Bad user id\n"); \ RET; \ - } + } #define GET_PEER_CHAT \ id = next_token_chat (); \ if (!cmp_peer_id (id, PEER_NOT_FOUND)) { \ printf ("Bad chat id\n"); \ RET; \ - } + } #define GET_PEER_ENCR_CHAT \ id = next_token_encr_chat (); \ if (!cmp_peer_id (id, PEER_NOT_FOUND)) { \ printf ("Bad encr_chat id\n"); \ RET; \ - } + } if (IS_WORD ("contact_list")) { do_update_contact_list (); @@ -725,7 +729,7 @@ void interpreter (char *line UU) { if (M && !M->service && M->media.type == CODE_message_media_photo) { do_load_photo (&M->media.photo, 1); } else if (M && !M->service && M->media.type == CODE_decrypted_message_media_photo) { - do_load_encr_video (&M->media.encr_video, 1); // this is not a bug. + do_load_encr_video (&M->media.encr_video, 1); // this is not a bug. } else { printf ("Bad msg id\n"); RET; @@ -740,7 +744,7 @@ void interpreter (char *line UU) { if (M && !M->service && M->media.type == CODE_message_media_photo) { do_load_photo (&M->media.photo, 2); } else if (M && !M->service && M->media.type == CODE_decrypted_message_media_photo) { - do_load_encr_video (&M->media.encr_video, 2); // this is not a bug. + do_load_encr_video (&M->media.encr_video, 2); // this is not a bug. } else { printf ("Bad msg id\n"); RET; @@ -812,12 +816,12 @@ void interpreter (char *line UU) { int limit = next_token_int (); do_get_history (id, limit > 0 ? limit : 40); } else if (IS_WORD ("chat_add_user")) { - GET_PEER_CHAT; + GET_PEER_CHAT; peer_id_t chat_id = id; GET_PEER_USER; do_add_user_to_chat (chat_id, id, 100); } else if (IS_WORD ("chat_del_user")) { - GET_PEER_CHAT; + GET_PEER_CHAT; peer_id_t chat_id = id; GET_PEER_USER; do_del_user_from_chat (chat_id, id); @@ -907,7 +911,7 @@ void interpreter (char *line UU) { ); pop_color (); } else if (IS_WORD ("show_license")) { - char *b = + char *b = #include "LICENSE.h" ; printf ("%s", b); @@ -941,7 +945,7 @@ void interpreter (char *line UU) { GET_PEER_ENCR_CHAT; do_visualize_key (id); } else if (IS_WORD ("create_secret_chat")) { - GET_PEER; + GET_PEER; do_create_secret_chat (id); } else if (IS_WORD ("create_group_chat")) { GET_PEER; @@ -950,8 +954,8 @@ void interpreter (char *line UU) { if (!s) { printf ("Empty chat topic\n"); RET; - } - do_create_group_chat (id, s); + } + do_create_group_chat (id, s); } else if (IS_WORD ("suggested_contacts")) { do_get_suggested (); } else if (IS_WORD ("status_online")) { @@ -1169,7 +1173,7 @@ void print_end (void) { #if READLINE_GNU rl_replace_line(saved_line, 0); #else - memcpy (rl_line_buffer, saved_line, rl_end + 1); // not safe, but I hope this would work. + memcpy (rl_line_buffer, saved_line, rl_end + 1); // not safe, but I hope this would work. #endif rl_point = saved_point; rl_redisplay(); @@ -1183,7 +1187,7 @@ void hexdump (int *in_ptr, int *in_end) { int *ptr = in_ptr; while (ptr < in_end) { printf (" %08x", *(ptr ++)); } printf ("\n"); - print_end (); + print_end (); } void logprintf (const char *format, ...) { @@ -1311,7 +1315,7 @@ void print_user_name (peer_id_t id, peer_t *U) { } else if (!U->user.last_name || !strlen (U->user.last_name)) { printf ("%s", U->user.first_name); } else { - printf ("%s %s", U->user.first_name, U->user.last_name); + printf ("%s %s", U->user.first_name, U->user.last_name); } if (U->flags & (FLAG_USER_SELF | FLAG_USER_CONTACT)) { pop_color (); @@ -1374,7 +1378,7 @@ void print_service_message (struct message *M) { assert (M); print_start (); push_color (COLOR_GREY); - + push_color (COLOR_MAGENTA); if (msg_num_mode) { printf ("%lld ", M->id); @@ -1390,7 +1394,7 @@ void print_service_message (struct message *M) { } printf (" "); print_user_name (M->from_id, user_chat_get (M->from_id)); - + switch (M->action.type) { case CODE_message_action_empty: printf ("\n"); @@ -1405,7 +1409,7 @@ void print_service_message (struct message *M) { printf (" created chat %s. %d users\n", M->action.title, M->action.user_num); break; case CODE_message_action_chat_edit_title: - printf (" changed title to %s\n", + printf (" changed title to %s\n", M->action.new_title); break; case CODE_message_action_chat_edit_photo: diff --git a/libtg.h b/libtg.h deleted file mode 100755 index 13b1fb5..0000000 --- a/libtg.h +++ /dev/null @@ -1 +0,0 @@ -int runtg (int argc, char **argv); diff --git a/main.c b/main.c index 7f6f32a..9d858df 100644 --- a/main.c +++ b/main.c @@ -300,7 +300,7 @@ void parse_config (void) { strcpy (buf + l, "test"); config_lookup_bool (&conf, buf, &test_dc); - strcpy (buf + l, "log_level"); + strcpy (buf + l, "log_lev el"); long long t = log_level; config_lookup_int (&conf, buf, (void *)&t); log_level = t; @@ -476,23 +476,16 @@ void sig_abrt_handler (int signum __attribute__ ((unused))) { exit (EXIT_FAILURE); } -int runtg (int argc, char **argv) { +int main (int argc, char **argv) { signal (SIGSEGV, sig_segv_handler); signal (SIGABRT, sig_abrt_handler); log_level = 10; args_parse (argc, argv); - printf ( - "Telegram-client version " TG_VERSION ", Copyright (C) 2013 Vitaly Valtman\n" - "Telegram-client comes with ABSOLUTELY NO WARRANTY; for details type `show_license'.\n" - "This is free software, and you are welcome to redistribute it\n" - "under certain conditions; type `show_license' for details.\n" - ); running_for_first_time (); parse_config (); - get_terminal_attributes (); #ifdef USE_LUA @@ -505,3 +498,11 @@ int runtg (int argc, char **argv) { return 0; } + + +/** + * Log into Telegram with the given login credentials. + */ +int tg_login () { + return main(0, NULL); +} diff --git a/mtproto-client.c b/mtproto-client.c index d19a26f..cb598d3 100644 --- a/mtproto-client.c +++ b/mtproto-client.c @@ -131,7 +131,7 @@ int Response_len; * */ -#define TG_SERVER_PUBKEY_FILENAME "tg-server.pub" +#define TG_SERVER_PUBKEY_FILENAME "/etc/telegram/server.pub" char *rsa_public_key_name; // = TG_SERVER_PUBKEY_FILENAME; RSA *pubKey; long long pk_fingerprint; @@ -249,7 +249,7 @@ int send_req_pq_packet (struct connection *c) { clear_packet (); out_int (CODE_req_pq); out_ints ((int *)nonce, 4); - rpc_send_packet (c); + rpc_send_packet (c); c_state = st_reqpq_sent; return 1; } @@ -333,7 +333,7 @@ int process_respq_answer (struct connection *c, char *packet, int len) { if (p1 > p2) { unsigned t = p1; p1 = p2; p2 = t; } - + if (verbosity) { logprintf ( "p1 = %d, p2 = %d, %d iterations\n", p1, p2, it); @@ -370,7 +370,7 @@ int process_respq_answer (struct connection *c, char *packet, int len) { clen = 3; } else { clen = 4; - } + } p1 = __builtin_bswap32 (p1); out_cstring ((char *)&p1 + 4 - clen, clen); p1 = __builtin_bswap32 (p1); @@ -387,7 +387,7 @@ int process_respq_answer (struct connection *c, char *packet, int len) { p2 = __builtin_bswap32 (p2); out_cstring ((char *)&p2 + 4 - clen, clen); p2 = __builtin_bswap32 (p2); - + //out_int (0x0301); // p=3 //out_int (0x0501); // q=5 out_ints ((int *) nonce, 4); @@ -397,7 +397,7 @@ int process_respq_answer (struct connection *c, char *packet, int len) { sha1 ((unsigned char *) (packet_buffer + 5), (packet_ptr - packet_buffer - 5) * 4, (unsigned char *) packet_buffer); int l = encrypt_packet_buffer (); - + clear_packet (); out_int (CODE_req_DH_params); out_ints ((int *) nonce, 4); @@ -412,7 +412,7 @@ int process_respq_answer (struct connection *c, char *packet, int len) { clen = 3; } else { clen = 4; - } + } p1 = __builtin_bswap32 (p1); out_cstring ((char *)&p1 + 4 - clen, clen); p1 = __builtin_bswap32 (p1); @@ -428,12 +428,12 @@ int process_respq_answer (struct connection *c, char *packet, int len) { p2 = __builtin_bswap32 (p2); out_cstring ((char *)&p2 + 4 - clen, clen); p2 = __builtin_bswap32 (p2); - + out_long (pk_fingerprint); out_cstring ((char *) encrypt_buffer, l); c_state = st_reqdh_sent; - + return rpc_send_packet (c); } @@ -497,7 +497,7 @@ int check_g (unsigned char p[256], BIGNUM *g) { int ok = 0; int i; for (i = 0; i < 64; i++) { - if (s[i]) { + if (s[i]) { ok = 1; break; } @@ -505,7 +505,7 @@ int check_g (unsigned char p[256], BIGNUM *g) { if (!ok) { return -1; } ok = 0; for (i = 0; i < 64; i++) { - if (s[255 - i]) { + if (s[255 - i]) { ok = 1; break; } @@ -513,7 +513,7 @@ int check_g (unsigned char p[256], BIGNUM *g) { if (!ok) { return -1; } ok = 0; for (i = 0; i < 64; i++) { - if (s[i] < p[i]) { + if (s[i] < p[i]) { ok = 1; break; } else if (s[i] > p[i]) { @@ -587,7 +587,7 @@ int process_dh_answer (struct connection *c, char *packet, int len) { out_ints ((int *) nonce, 4); out_ints ((int *) server_nonce, 4); out_long (0LL); - + BN_init (&dh_g); ensure (BN_set_word (&dh_g, g)); @@ -614,7 +614,7 @@ int process_dh_answer (struct connection *c, char *packet, int len) { BN_free (&dh_prime); //hexdump (auth_key, auth_key + 256); - + sha1 ((unsigned char *) (packet_buffer + 5), (packet_ptr - packet_buffer - 5) * 4, (unsigned char *) packet_buffer); //hexdump ((char *)packet_buffer, (char *)packet_ptr); @@ -656,7 +656,7 @@ int process_auth_complete (struct connection *c UU, char *packet, int len) { sha1 (tmp, 41, sha1_buffer); assert (!memcmp (packet + 56, sha1_buffer + 4, 16)); GET_DC(c)->server_salt = *(long long *)server_nonce ^ *(long long *)new_nonce; - + if (verbosity >= 3) { logprintf ( "auth_key_id=%016llx\n", GET_DC(c)->auth_key_id); } @@ -673,7 +673,7 @@ int process_auth_complete (struct connection *c UU, char *packet, int len) { auth_success ++; GET_DC(c)->flags |= 1; write_auth_file (); - + return 1; } @@ -765,7 +765,7 @@ long long encrypt_send_message (struct connection *c, int *msg, int msg_ints, in //hexdump ((char *)&enc_msg, (char *)&enc_msg + l + 24); assert (l > 0); rpc_send_message (c, &enc_msg, l + UNENCSZ); - + return client_last_msg_id; } @@ -850,9 +850,9 @@ void work_update_binlog (void) { struct user *U = &UC->user; if (U->first_name) { tfree_str (U->first_name); } if (U->last_name) { tfree_str (U->last_name); } - if (U->print_name) { + if (U->print_name) { peer_delete_name (UC); - tfree_str (U->print_name); + tfree_str (U->print_name); } U->first_name = fetch_str_dup (); U->last_name = fetch_str_dup (); @@ -871,7 +871,7 @@ void work_update_binlog (void) { fetch_date (); if (UC) { struct user *U = &UC->user; - + unsigned y = fetch_int (); if (y == CODE_user_profile_photo_empty) { U->photo_id = 0; @@ -1058,7 +1058,7 @@ void work_update (struct connection *c UU, long long msg_id UU) { fetch_file_location (&big); } bl_do_set_user_profile_photo (U, photo_id, &big, &small); - + print_start (); push_color (COLOR_YELLOW); print_date (time (0)); @@ -1129,7 +1129,7 @@ void work_update (struct connection *c UU, long long msg_id UU) { users[i].inviter_id = fetch_int (); users[i].date = fetch_int (); } - int version = fetch_int (); + int version = fetch_int (); bl_do_set_chat_participants (&C->chat, version, n, users); } } else { @@ -1339,8 +1339,8 @@ void work_update (struct connection *c UU, long long msg_id UU) { peer_id_t chat_id = MK_CHAT (fetch_int ()); peer_id_t user_id = MK_USER (fetch_int ()); peer_id_t inviter_id = MK_USER (fetch_int ()); - int version = fetch_int (); - + int version = fetch_int (); + peer_t *C = user_chat_get (chat_id); if (C && (C->flags & FLAG_CREATED)) { bl_do_chat_add_user (&C->chat, version, get_peer_id (user_id), get_peer_id (inviter_id), time (0)); @@ -1365,7 +1365,7 @@ void work_update (struct connection *c UU, long long msg_id UU) { peer_id_t chat_id = MK_CHAT (fetch_int ()); peer_id_t user_id = MK_USER (fetch_int ()); int version = fetch_int (); - + peer_t *C = user_chat_get (chat_id); if (C && (C->flags & FLAG_CREATED)) { bl_do_chat_del_user (&C->chat, version, get_peer_id (user_id)); @@ -1430,7 +1430,7 @@ void work_updates (struct connection *c, long long msg_id) { void work_update_short_message (struct connection *c UU, long long msg_id UU) { assert (fetch_int () == (int)CODE_update_short_message); - struct message *M = fetch_alloc_message_short (); + struct message *M = fetch_alloc_message_short (); unread_messages ++; print_message (M); update_prompt (); @@ -1441,7 +1441,7 @@ void work_update_short_message (struct connection *c UU, long long msg_id UU) { void work_update_short_chat_message (struct connection *c UU, long long msg_id UU) { assert (fetch_int () == CODE_update_short_chat_message); - struct message *M = fetch_alloc_message_short_chat (); + struct message *M = fetch_alloc_message_short_chat (); unread_messages ++; print_message (M); update_prompt (); @@ -1458,8 +1458,8 @@ void work_container (struct connection *c, long long msg_id UU) { int n = fetch_int (); int i; for (i = 0; i < n; i++) { - long long id = fetch_long (); - //int seqno = fetch_int (); + long long id = fetch_long (); + //int seqno = fetch_int (); fetch_int (); // seq_no if (id & 1) { insert_msg_id (c->session, id); @@ -1482,7 +1482,7 @@ void work_new_session_created (struct connection *c, long long msg_id UU) { //DC->session_id = fetch_long (); fetch_long (); // unique_id GET_DC(c)->server_salt = fetch_long (); - + } void work_msgs_ack (struct connection *c UU, long long msg_id UU) { @@ -1523,7 +1523,7 @@ void work_packed (struct connection *c, long long msg_id) { static int buf[MAX_PACKED_SIZE >> 2]; assert (!in_gzip); in_gzip = 1; - + int l = prefetch_strlen (); char *s = fetch_str (l); @@ -1650,7 +1650,7 @@ int process_rpc_message (struct connection *c UU, struct encrypted_message *enc, const int MINSZ = offsetof (struct encrypted_message, message); const int UNENCSZ = offsetof (struct encrypted_message, server_salt); if (verbosity) { - logprintf ( "process_rpc_message(), len=%d\n", len); + logprintf ( "process_rpc_message(), len=%d\n", len); } assert (len >= MINSZ && (len & 15) == (UNENCSZ & 15)); struct dc *DC = GET_DC(c); @@ -1669,7 +1669,7 @@ int process_rpc_message (struct connection *c UU, struct encrypted_message *enc, DC->server_salt = enc->server_salt; write_auth_file (); } - + int this_server_time = enc->msg_id >> 32LL; if (!DC->server_time_delta) { DC->server_time_delta = this_server_time - get_utime (CLOCK_REALTIME); @@ -1697,10 +1697,10 @@ int process_rpc_message (struct connection *c UU, struct encrypted_message *enc, assert (l >= (MINSZ - UNENCSZ) + 8); //assert (enc->message[0] == CODE_rpc_result && *(long long *)(enc->message + 1) == client_last_msg_id); ++good_messages; - + in_ptr = enc->message; in_end = in_ptr + (enc->msg_len / 4); - + if (enc->msg_id & 1) { insert_msg_id (c->session, enc->msg_id); } @@ -1774,7 +1774,7 @@ int rpc_execute (struct connection *c, int op, int len) { logprintf ( "fatal: cannot receive answer in state %d\n", c_state); exit (2); } - + return 0; } @@ -1793,7 +1793,7 @@ int tc_becomes_ready (struct connection *c) { char byte = 0xef; assert (write_out (c, &byte, 1) == 1); flush_out (c); - + #if !defined(__MACH__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined (__CYGWIN__) setsockopt (c->fd, IPPROTO_TCP, TCP_QUICKACK, (int[]){0}, 4); #endif diff --git a/purple-plugin/Makefile b/purple-plugin/Makefile index cf6ec88..5edef35 100755 --- a/purple-plugin/Makefile +++ b/purple-plugin/Makefile @@ -56,9 +56,11 @@ debug: $(LIBNAME) PLUGIN_DIR_PURPLE:=$(shell pkg-config --variable=plugindir purple) DATA_ROOT_DIR_PURPLE:=$(shell pkg-config --variable=datarootdir purple) +# TODO: Find a better place for server.pub .PHONY: install install: $(LIBNAME) install -D $(LIBNAME) $(DESTDIR)$(PLUGIN_DIR_PURPLE)/$(LIBNAME) + install -D ../tg-server.pub /etc/telegram/server.pub install -D telegram16.png $(DESTDIR)$(DATA_ROOT_DIR_PURPLE)/pixmaps/pidgin/protocols/16/telegram.png install -D telegram22.png $(DESTDIR)$(DATA_ROOT_DIR_PURPLE)/pixmaps/pidgin/protocols/22/telegram.png install -D telegram48.png $(DESTDIR)$(DATA_ROOT_DIR_PURPLE)/pixmaps/pidgin/protocols/48/telegram.png @@ -66,6 +68,7 @@ install: $(LIBNAME) .PHONY: uninstall uninstall: $(LIBNAME) rm -f $(DESTDIR)$(PLUGIN_DIR_PURPLE)/$(LIBNAME) + rm -f /etc/telegram/server.pub rm -f $(DESTDIR)$(DATA_ROOT_DIR_PURPLE)/pixmaps/pidgin/protocols/16/telegram.png rm -f $(DESTDIR)$(DATA_ROOT_DIR_PURPLE)/pixmaps/pidgin/protocols/22/telegram.png rm -f $(DESTDIR)$(DATA_ROOT_DIR_PURPLE)/pixmaps/pidgin/protocols/48/telegram.png @@ -77,4 +80,4 @@ clean: .PHONY: run run: all install - pidgin -d | grep -i 'plugins\|telegram' + pidgin -d diff --git a/purple-plugin/telegram-purple.c b/purple-plugin/telegram-purple.c index 287ad80..ad49259 100644 --- a/purple-plugin/telegram-purple.c +++ b/purple-plugin/telegram-purple.c @@ -16,7 +16,7 @@ #include -// TODO: check if we really need all those includes... +// Libpurple Plugin Includes #include "notify.h" #include "plugin.h" // NEEDED? #include "version.h" @@ -34,23 +34,12 @@ #include "util.h" #include "prpl.h" -#include +// Telegram Includes +#include -#define PLUGIN_ID "prpl-telegram" +// telegram-purple includes +#include "telegram-purple.h" -#define TELEGRAM_APP_API_ID 16944 -#define TELEGRAM_APP_API_HASH "457b5a190c750ed0a772bc48bbdf75dc" -#define TELEGRAM_TEST_SERVER "173.240.5.253" -#define TELEGRAM_PRODUCTION_SERVER "173.240.5.1" -#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-----" - - -typedef struct { - PurpleAccount *account; - PurpleConnection *gc; - PurpleSslConnection *gsc; -} telegram_conn; static PurplePlugin *_telegram_protocol = NULL; @@ -94,7 +83,7 @@ static void tgprpl_login(PurpleAccount * acct) purple_debug_info(PLUGIN_ID, "tgprpl_login()\n"); purple_debug_info(PLUGIN_ID, "calling runtg()\n"); - runtg(0, NULL); + tg_login(); purple_debug_info(PLUGIN_ID, "returned from runtg()\n"); /* @@ -498,19 +487,35 @@ static PurplePluginProtocolInfo prpl_info = { NULL /* add_buddies_with_invite */ }; -static void init_plugin(PurplePlugin *plugin) +static void tgprpl_init(PurplePlugin *plugin) { - PurpleAccountOption *option; + PurpleAccountOption *option; + PurpleAccountUserSplit *split; + GList *verification_values = NULL; - prpl_info.user_splits = NULL; + // Required Verification-Key + split = purple_account_user_split_new("Verification key", "-", '@'); + purple_account_user_split_set_reverse(split, FALSE); + prpl_info.user_splits = g_list_append(prpl_info.user_splits, split); + + // Extra Options + #define ADD_VALUE(list, desc, v) { \ + PurpleKeyValuePair *kvp = g_new0(PurpleKeyValuePair, 1); \ + kvp->key = g_strdup((desc)); \ + kvp->value = g_strdup((v)); \ + list = g_list_prepend(list, kvp); \ + } + ADD_VALUE(verification_values, "Phone", "phone"); + ADD_VALUE(verification_values, "SMS", "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); - option = purple_account_option_int_new("Port", "port", TELEGRAM_DEFAULT_PORT); - 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) - option = purple_account_option_string_new("SMS-Key", "sms_key", "0000"); + option = purple_account_option_int_new("Port", "port", TELEGRAM_DEFAULT_PORT); prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); _telegram_protocol = plugin; @@ -559,4 +564,4 @@ static PurplePluginInfo info = { NULL // reserved }; -PURPLE_INIT_PLUGIN(telegram, init_plugin, info) +PURPLE_INIT_PLUGIN(telegram, tgprpl_init, info) diff --git a/purple-plugin/telegram-purple.h b/purple-plugin/telegram-purple.h new file mode 100644 index 0000000..72f7c32 --- /dev/null +++ b/purple-plugin/telegram-purple.h @@ -0,0 +1,38 @@ +/** + * 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 + */ + +#include + +#include "notify.h" +#include "plugin.h" +#include "version.h" +#include "account.h" +#include "connection.h" + +#define PLUGIN_ID "prpl-telegram" + +#define TELEGRAM_APP_API_ID 16944 +#define TELEGRAM_APP_API_HASH "457b5a190c750ed0a772bc48bbdf75dc" +#define TELEGRAM_TEST_SERVER "173.240.5.253" +#define TELEGRAM_PRODUCTION_SERVER "173.240.5.1" +#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-----" + +typedef struct { + PurpleAccount *account; + PurpleConnection *gc; + PurpleSslConnection *gsc; +} telegram_conn; diff --git a/tg-cli.h b/tg-cli.h new file mode 100755 index 0000000..b51fbf4 --- /dev/null +++ b/tg-cli.h @@ -0,0 +1,3 @@ +// Export functions for plugins + +int tg_login ();