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.
This commit is contained in:
parent
da57c79053
commit
377c809ba7
10 changed files with 178 additions and 125 deletions
10
Makefile.in
10
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"
|
||||
|
|
20
README.md
20
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
|
||||
|
|
80
interface.c
80
interface.c
|
@ -21,7 +21,7 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
@ -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:
|
||||
|
|
1
libtg.h
1
libtg.h
|
@ -1 +0,0 @@
|
|||
int runtg (int argc, char **argv);
|
19
main.c
19
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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#include <glib.h>
|
||||
|
||||
// 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 <libtg.h>
|
||||
// Telegram Includes
|
||||
#include <tg-cli.h>
|
||||
|
||||
#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)
|
||||
|
|
38
purple-plugin/telegram-purple.h
Normal file
38
purple-plugin/telegram-purple.h
Normal file
|
@ -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 <glib.h>
|
||||
|
||||
#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;
|
3
tg-cli.h
Executable file
3
tg-cli.h
Executable file
|
@ -0,0 +1,3 @@
|
|||
// Export functions for plugins
|
||||
|
||||
int tg_login ();
|
Loading…
Add table
Reference in a new issue