Refactor - Intermediate Commit 2
This commit is contained in:
parent
ed7aa7de5b
commit
8a2c043db4
18 changed files with 388 additions and 222 deletions
|
@ -53,6 +53,7 @@ PRPL_CFLAGS = \
|
|||
-fPIC \
|
||||
-DPURPLE_PLUGINS \
|
||||
-DPIC \
|
||||
-DDEBUG \
|
||||
-g \
|
||||
$(CFLAGS_PURPLE)
|
||||
|
||||
|
@ -84,10 +85,6 @@ plugin: $(PRPL_LIBNAME)
|
|||
strip: $(PRPL_LIBNAME)
|
||||
$(STRIP) --strip-unneeded $(PRPL_LIBNAME)
|
||||
|
||||
debug: PRPL_CFLAGS += -g -DDEBUG
|
||||
debug: $(PRPL_LIBNAME)
|
||||
gdb -tui -ex 'break telegram-purple.c:tgprpl_login' pidgin
|
||||
|
||||
# TODO: Find a better place for server.pub
|
||||
install: $(PRPL_LIBNAME)
|
||||
install -D $(PRPL_LIBNAME) $(DESTDIR)$(PLUGIN_DIR_PURPLE)/$(PRPL_LIBNAME)
|
||||
|
@ -108,6 +105,10 @@ uninstall: $(PRPL_LIBNAME)
|
|||
run: install
|
||||
pidgin -d | grep 'telegram\|plugin\|proxy'
|
||||
|
||||
.PHONY: debug
|
||||
debug: install
|
||||
gdb -tui -ex "$(shell echo $$GDB_BPOINTS )" pidgin
|
||||
|
||||
clean:
|
||||
rm -rf *.so *.a *.o telegram config.log config.status $(PRPL_C_OBJS) $(PRPL_LIBNAME) > /dev/null || echo "all clean"
|
||||
|
||||
|
|
38
binlog.c
38
binlog.c
|
@ -56,7 +56,13 @@ extern int seq;
|
|||
|
||||
#define MAX_LOG_EVENT_SIZE (1 << 17)
|
||||
|
||||
// TODO: remove this completely
|
||||
char *get_binlog_file_name (void);
|
||||
char *get_binlog_file_name()
|
||||
{
|
||||
return "/home/dev-jessie/.telegram/binlog";
|
||||
}
|
||||
|
||||
//extern struct dc *DC_list[];
|
||||
//extern int dc_working_num;
|
||||
extern int our_id;
|
||||
|
@ -1162,9 +1168,9 @@ void write_binlog (void) {
|
|||
}
|
||||
|
||||
void add_log_event (const int *data, int len) {
|
||||
if (verbosity) {
|
||||
logprintf ("Add log event: magic = 0x%08x, len = %d\n", data[0], len);
|
||||
}
|
||||
logprintf ("Add log event: magic = 0x%08x, len = %d\n", data[0], len);
|
||||
assert(0);
|
||||
// TODO: Mit add_log_event_i austauschen
|
||||
assert (!(len & 3));
|
||||
if (in_replay_log) { return; }
|
||||
rptr = (void *)data;
|
||||
|
@ -1185,7 +1191,29 @@ void add_log_event (const int *data, int len) {
|
|||
in_end = end;
|
||||
}
|
||||
|
||||
void bl_do_set_auth_key_id (int num, unsigned char *buf) {
|
||||
void add_log_event_i (struct telegram *instance, const int *data, int len) {
|
||||
logprintf ("Add log event: magic = 0x%08x, len = %d\n", data[0], len);
|
||||
assert (!(len & 3));
|
||||
if (in_replay_log) { return; }
|
||||
rptr = (void *)data;
|
||||
wptr = rptr + (len / 4);
|
||||
int *in = in_ptr;
|
||||
int *end = in_end;
|
||||
// TODO:
|
||||
replay_log_event (instance);
|
||||
if (rptr != wptr) {
|
||||
logprintf ("Unread %lld ints. Len = %d\n", (long long)(wptr - rptr), len);
|
||||
assert (rptr == wptr);
|
||||
}
|
||||
if (binlog_enabled) {
|
||||
assert (binlog_fd > 0);
|
||||
assert (write (binlog_fd, data, len) == len);
|
||||
}
|
||||
in_ptr = in;
|
||||
in_end = end;
|
||||
}
|
||||
|
||||
void bl_do_set_auth_key_id (struct telegram *instance, int num, unsigned char *buf) {
|
||||
static unsigned char sha1_buffer[20];
|
||||
SHA1 (buf, 256, sha1_buffer);
|
||||
long long fingerprint = *(long long *)(sha1_buffer + 12);
|
||||
|
@ -1194,7 +1222,7 @@ void bl_do_set_auth_key_id (int num, unsigned char *buf) {
|
|||
ev[1] = num;
|
||||
*(long long *)(ev + 2) = fingerprint;
|
||||
memcpy (ev + 4, buf, 256);
|
||||
add_log_event (ev, 8 + 8 + 256);
|
||||
add_log_event_i (instance, ev, 8 + 8 + 256);
|
||||
}
|
||||
|
||||
void bl_do_set_our_id (int id) {
|
||||
|
|
3
binlog.h
3
binlog.h
|
@ -87,8 +87,9 @@
|
|||
void *alloc_log_event (int l);
|
||||
void replay_log (struct telegram *instance);
|
||||
void add_log_event (const int *data, int l);
|
||||
void add_log_event_i (struct telegram *instance, const int *data, int l);
|
||||
void write_binlog (void);
|
||||
void bl_do_set_auth_key_id (int num, unsigned char *buf);
|
||||
void bl_do_set_auth_key_id (struct telegram *instance, int num, unsigned char *buf);
|
||||
|
||||
void bl_do_dc_option (int id, int l1, const char *name, int l2, const char *ip, int port, struct telegram *instance);
|
||||
|
||||
|
|
101
loop.c
101
loop.c
|
@ -148,6 +148,7 @@ int is_got_it (void) {
|
|||
return got_it_ok;
|
||||
}
|
||||
|
||||
/*
|
||||
int net_getline (char **s, size_t *l) {
|
||||
fflush (stdout);
|
||||
// rl_already_prompted = 1;
|
||||
|
@ -155,16 +156,19 @@ int net_getline (char **s, size_t *l) {
|
|||
_s = s;
|
||||
_l = l;
|
||||
// rl_callback_handler_install (0, got_it);
|
||||
net_loop (2, is_got_it);
|
||||
//net_loop (2, is_got_it);
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
int ret1 (void) { return 0; }
|
||||
|
||||
/*
|
||||
int main_loop (void) {
|
||||
net_loop (1, ret1);
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
//struct dc *DC_list[MAX_DC_ID + 1];
|
||||
|
@ -177,6 +181,7 @@ int zero[512];
|
|||
|
||||
|
||||
void write_dc (int auth_file_fd, struct dc *DC) {
|
||||
logprintf("writing to auth_file: auth_file_fd: %d, port: %d, ip: %s\n", auth_file_fd, DC->port, DC->ip);
|
||||
assert (write (auth_file_fd, &DC->port, 4) == 4);
|
||||
int l = strlen (DC->ip);
|
||||
assert (write (auth_file_fd, &l, 4) == 4);
|
||||
|
@ -194,28 +199,28 @@ void write_dc (int auth_file_fd, struct dc *DC) {
|
|||
|
||||
int our_id;
|
||||
|
||||
void write_auth_file (struct authorization_state state, const char *filename) {
|
||||
if (binlog_enabled) { return; }
|
||||
int auth_file_fd = open (filename /*get_auth_key_filename ()*/, O_CREAT | O_RDWR, 0600);
|
||||
void write_auth_file (struct authorization_state *state, const char *filename) {
|
||||
logprintf("Writing to auth_file: %s\n", filename);
|
||||
int auth_file_fd = open (filename, O_CREAT | O_RDWR, 0600);
|
||||
assert (auth_file_fd >= 0);
|
||||
int x = DC_SERIALIZED_MAGIC_V2;
|
||||
assert (write (auth_file_fd, &x, 4) == 4);
|
||||
x = MAX_DC_ID;
|
||||
assert (write (auth_file_fd, &x, 4) == 4);
|
||||
assert (write (auth_file_fd, &state.dc_working_num, 4) == 4);
|
||||
assert (write (auth_file_fd, &state.auth_state, 4) == 4);
|
||||
assert (write (auth_file_fd, &state->dc_working_num, 4) == 4);
|
||||
assert (write (auth_file_fd, &state->auth_state, 4) == 4);
|
||||
int i;
|
||||
for (i = 0; i <= MAX_DC_ID; i++) {
|
||||
if (state.DC_list[i]) {
|
||||
if (state->DC_list[i]) {
|
||||
x = 1;
|
||||
assert (write (auth_file_fd, &x, 4) == 4);
|
||||
write_dc (auth_file_fd, state.DC_list[i]);
|
||||
write_dc (auth_file_fd, state->DC_list[i]);
|
||||
} else {
|
||||
x = 0;
|
||||
assert (write (auth_file_fd, &x, 4) == 4);
|
||||
}
|
||||
}
|
||||
assert (write (auth_file_fd, &state.our_id, 4) == 4);
|
||||
assert (write (auth_file_fd, &state->our_id, 4) == 4);
|
||||
close (auth_file_fd);
|
||||
}
|
||||
|
||||
|
@ -232,9 +237,6 @@ void read_dc (int auth_file_fd, int id, unsigned ver, struct dc *DC_list[]) {
|
|||
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);
|
||||
logprintf("auth_key_id: %lli \n", DC->auth_key_id);
|
||||
logprintf("auth_key_id: ?");
|
||||
logprintf("server_salt: %lli \n", DC->server_salt);
|
||||
if (DC->auth_key_id) {
|
||||
DC->flags |= 1;
|
||||
}
|
||||
|
@ -247,23 +249,33 @@ void read_dc (int auth_file_fd, int id, unsigned ver, struct dc *DC_list[]) {
|
|||
|
||||
|
||||
void empty_auth_file (struct authorization_state *state, const char *filename) {
|
||||
logprintf("empty_auth_file()\n");
|
||||
alloc_dc (state->DC_list, 1, tstrdup (test_dc ? TG_SERVER_TEST : TG_SERVER), 443);
|
||||
state->dc_working_num = 1;
|
||||
state->auth_state = 0;
|
||||
write_auth_file (*state, filename);
|
||||
write_auth_file (state, filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the auth-file and return the read authorization state
|
||||
*
|
||||
* When the given file doesn't exist, create a new empty
|
||||
* file containing the default authorization state at this
|
||||
* path
|
||||
*/
|
||||
struct authorization_state read_auth_file (const char *filename) {
|
||||
struct authorization_state state;
|
||||
state.dc_working_num = 0;
|
||||
state.auth_state = 0;
|
||||
state.our_id = 0;
|
||||
logprintf("read_auth_file()\n");
|
||||
|
||||
if (binlog_enabled) { return state; }
|
||||
int auth_file_fd = open (filename /*get_auth_key_filename ()*/, O_CREAT | O_RDWR, 0600);
|
||||
struct authorization_state state;
|
||||
memset(state.DC_list, 0, 11 * sizeof(void *));
|
||||
|
||||
int auth_file_fd = open (filename, O_RDWR, 0600);
|
||||
logprintf("fd: %d\n", auth_file_fd);
|
||||
if (auth_file_fd < 0) {
|
||||
logprintf("auth_file does not exist, creating empty...\n");
|
||||
empty_auth_file (&state, filename);
|
||||
}
|
||||
auth_file_fd = open (filename, O_RDWR, 0600);
|
||||
assert (auth_file_fd >= 0);
|
||||
|
||||
// amount of data centers
|
||||
|
@ -271,6 +283,7 @@ struct authorization_state read_auth_file (const char *filename) {
|
|||
// magic number of file
|
||||
unsigned m;
|
||||
if (read (auth_file_fd, &m, 4) < 4 || (m != DC_SERIALIZED_MAGIC && m != DC_SERIALIZED_MAGIC_V2)) {
|
||||
logprintf("Invalid File content, wrong Magic numebr\n");
|
||||
close (auth_file_fd);
|
||||
empty_auth_file (&state, filename);
|
||||
return state;
|
||||
|
@ -288,6 +301,10 @@ struct authorization_state read_auth_file (const char *filename) {
|
|||
assert (read (auth_file_fd, &y, 4) == 4);
|
||||
if (y) {
|
||||
read_dc (auth_file_fd, i, m, state.DC_list);
|
||||
logprintf("loaded dc[%d] - port: %d, ip: %s, auth_key_id: %lli, server_salt: %lli, has_auth: %d\n",
|
||||
i, state.DC_list[i]->port, state.DC_list[i]->ip, state.DC_list[i]->auth_key_id, state.DC_list[i]->server_salt, state.DC_list[i]->has_auth);
|
||||
} else {
|
||||
logprintf("loaded dc[%d] - NULL\n", i);
|
||||
}
|
||||
}
|
||||
int l = read (auth_file_fd, &state.our_id, 4);
|
||||
|
@ -299,20 +316,17 @@ struct authorization_state read_auth_file (const char *filename) {
|
|||
if (m == DC_SERIALIZED_MAGIC) {
|
||||
DC_working->has_auth = 1;
|
||||
}
|
||||
logprintf("loaded authorization state - our_id: %d, auth_state: %d, dc_working_num: %d \n", state.our_id, state.auth_state, state.dc_working_num);
|
||||
return state;
|
||||
}
|
||||
|
||||
int pts, qts, seq, last_date;
|
||||
|
||||
struct protocol_state read_state_file (const char *filename) {
|
||||
struct protocol_state state;
|
||||
state.last_date = 0;
|
||||
state.qts = 0;
|
||||
state.pts = 0;
|
||||
state.seq = 0;
|
||||
logprintf("read_state_file()\n");
|
||||
struct protocol_state state = {0, 0, 0, 0};
|
||||
|
||||
if (binlog_enabled) { return state; }
|
||||
int state_file_fd = open (filename/*get_state_filename ()*/, O_CREAT | O_RDWR, 0600);
|
||||
int state_file_fd = open (filename, O_CREAT | O_RDWR, 0600);
|
||||
if (state_file_fd < 0) {
|
||||
return state;
|
||||
}
|
||||
|
@ -331,11 +345,12 @@ struct protocol_state read_state_file (const char *filename) {
|
|||
state.seq = x[2];
|
||||
state.last_date = x[3];
|
||||
close (state_file_fd);
|
||||
logprintf("loaded session state - pts: %d, qts: %d, seq: %d, last_date: %d.\n", state.pts,
|
||||
state.qts, state.seq, state.last_date);
|
||||
return state;
|
||||
}
|
||||
|
||||
void write_state_file (struct protocol_state state, const char* filename) {
|
||||
if (binlog_enabled) { return; }
|
||||
void write_state_file (struct protocol_state *state, const char* filename) {
|
||||
/*
|
||||
static int wseq;
|
||||
static int wpts;
|
||||
|
@ -350,10 +365,10 @@ void write_state_file (struct protocol_state state, const char* filename) {
|
|||
int x[6];
|
||||
x[0] = STATE_FILE_MAGIC;
|
||||
x[1] = 0;
|
||||
x[2] = state.pts;
|
||||
x[3] = state.qts;
|
||||
x[4] = state.seq;
|
||||
x[5] = state.last_date;
|
||||
x[2] = state->pts;
|
||||
x[3] = state->qts;
|
||||
x[4] = state->seq;
|
||||
x[5] = state->last_date;
|
||||
assert (write (state_file_fd, x, 24) == 24);
|
||||
close (state_file_fd);
|
||||
//wseq = seq; wpts = pts; wqts = qts; wdate = last_date;
|
||||
|
@ -569,32 +584,10 @@ int network_verify_phone_registration(const char* code, const char *sms_hash,
|
|||
{
|
||||
logprintf("Registering with code:%s, hash:%s, first:%s, last:%s\n", code, sms_hash,
|
||||
first, last);
|
||||
if (do_send_code_result_auth (code, sms_hash, first, last) >= 0) {
|
||||
logprintf ("Authentication successfull, state = 300\n");
|
||||
auth_state = 300;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Verify the current client by providing the given code
|
||||
*/
|
||||
/*
|
||||
int network_verify_registration(const char *code, const char *sms_hash)
|
||||
{
|
||||
logprintf("Verifying with hash:%s, code:%s\n", code, sms_hash);
|
||||
int state;
|
||||
if ((state = do_send_code_result (code, sms_hash)) >= 0) {
|
||||
logprintf ("Authentication successfull, state = 300\n");
|
||||
auth_state = 300;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Export current authentication state to all known data centers.
|
||||
*/
|
||||
|
|
7
loop.h
7
loop.h
|
@ -24,7 +24,6 @@
|
|||
#ifndef __LOOP_H__
|
||||
#define __LOOP_H__
|
||||
int loop();
|
||||
void net_loop (int flags, int (*end)(void));
|
||||
void write_secret_chat_file (const char *filename);
|
||||
#endif
|
||||
|
||||
|
@ -38,14 +37,14 @@ struct protocol_state {
|
|||
struct authorization_state {
|
||||
int dc_working_num;
|
||||
int auth_state;
|
||||
struct dc *DC_list[11];
|
||||
struct dc* DC_list[11];
|
||||
int our_id;
|
||||
};
|
||||
|
||||
void write_auth_file (struct authorization_state state, const char *filename);
|
||||
void write_auth_file (struct authorization_state *state, const char *filename);
|
||||
struct authorization_state read_auth_file (const char *filename);
|
||||
|
||||
void write_state_file (struct protocol_state state, const char *filename);
|
||||
void write_state_file (struct protocol_state *state, const char *filename);
|
||||
struct protocol_state read_state_file (const char *filename);
|
||||
|
||||
void on_start();
|
||||
|
|
|
@ -85,6 +85,8 @@ int allow_weak_random = 0;
|
|||
int total_packets_sent;
|
||||
long long total_data_sent;
|
||||
|
||||
extern int queries_num;
|
||||
|
||||
/*
|
||||
int rpc_execute (struct connection *c, int op, int len);
|
||||
int rpc_becomes_ready (struct connection *c);
|
||||
|
@ -224,6 +226,8 @@ int rpc_send_packet (struct connection *c) {
|
|||
//flush_out (c);
|
||||
|
||||
total_packets_sent ++;
|
||||
queries_num++;
|
||||
logprintf("pending queries: %d\n", queries_num);
|
||||
total_data_sent += total_len;
|
||||
return 1;
|
||||
}
|
||||
|
@ -248,6 +252,9 @@ int rpc_send_message (struct connection *c, void *data, int len) {
|
|||
}
|
||||
|
||||
int send_req_pq_packet (struct connection *c) {
|
||||
char byte = 0xef;
|
||||
assert (write_out (c, &byte, 1) == 1);
|
||||
|
||||
assert (c_state == st_init);
|
||||
secure_random (nonce, 16);
|
||||
unenc_msg_header.out_msg_id = 0;
|
||||
|
@ -255,6 +262,7 @@ int send_req_pq_packet (struct connection *c) {
|
|||
out_int (CODE_req_pq);
|
||||
out_ints ((int *)nonce, 4);
|
||||
rpc_send_packet (c);
|
||||
|
||||
c_state = st_reqpq_sent;
|
||||
return 1;
|
||||
}
|
||||
|
@ -539,9 +547,7 @@ int check_g_bn (BIGNUM *p, BIGNUM *g) {
|
|||
}
|
||||
|
||||
int process_dh_answer (struct connection *c, char *packet, int len) {
|
||||
if (verbosity) {
|
||||
logprintf ( "process_dh_answer(), len=%d\n", len);
|
||||
}
|
||||
logprintf ( "process_dh_answer(), len=%d\n", len);
|
||||
if (len < 116) {
|
||||
logprintf ( "%u * %u = %llu", p1, p2, what);
|
||||
}
|
||||
|
@ -633,15 +639,13 @@ int process_dh_answer (struct connection *c, char *packet, int len) {
|
|||
out_cstring ((char *) encrypt_buffer, l);
|
||||
|
||||
c_state = st_client_dh_sent;
|
||||
|
||||
return rpc_send_packet (c);
|
||||
}
|
||||
|
||||
|
||||
int process_auth_complete (struct connection *c UU, char *packet, int len) {
|
||||
if (verbosity) {
|
||||
logprintf ( "process_dh_answer(), len=%d\n", len);
|
||||
}
|
||||
|
||||
logprintf ( "process_dh_answer(), len=%d\n", len);
|
||||
assert (len == 72);
|
||||
assert (!*(long long *) packet);
|
||||
assert (*(int *) (packet + 16) == len - 20);
|
||||
|
@ -654,7 +658,8 @@ int process_auth_complete (struct connection *c UU, char *packet, int len) {
|
|||
tmp[32] = 1;
|
||||
//GET_DC(c)->auth_key_id = *(long long *)(sha1_buffer + 12);
|
||||
|
||||
bl_do_set_auth_key_id (GET_DC(c)->id, (unsigned char *)GET_DC(c)->auth_key);
|
||||
bl_do_set_auth_key_id (c->instance, GET_DC(c)->id, (unsigned char *)GET_DC(c)->auth_key);
|
||||
|
||||
sha1 ((unsigned char *)GET_DC(c)->auth_key, 256, sha1_buffer);
|
||||
|
||||
memcpy (tmp + 33, sha1_buffer, 8);
|
||||
|
@ -662,9 +667,8 @@ int process_auth_complete (struct connection *c UU, char *packet, int len) {
|
|||
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);
|
||||
}
|
||||
logprintf ( "auth_key_id=%016llx\n", GET_DC(c)->auth_key_id);
|
||||
//logprintf ( "auth_key=%s\n", GET_DC(c)->auth_key);
|
||||
//kprintf ("OK\n");
|
||||
|
||||
//c->status = conn_error;
|
||||
|
@ -672,9 +676,7 @@ int process_auth_complete (struct connection *c UU, char *packet, int len) {
|
|||
|
||||
c_state = st_authorized;
|
||||
//return 1;
|
||||
if (verbosity) {
|
||||
logprintf ( "Auth success\n");
|
||||
}
|
||||
logprintf ( "Auth success\n");
|
||||
auth_success ++;
|
||||
GET_DC(c)->flags |= 1;
|
||||
|
||||
|
@ -804,7 +806,7 @@ void fetch_pts (void) {
|
|||
} else {
|
||||
pts ++;
|
||||
}
|
||||
bl_do_set_pts (pts);
|
||||
//bl_do_set_pts (pts);
|
||||
}
|
||||
|
||||
void fetch_qts (void) {
|
||||
|
@ -821,14 +823,14 @@ void fetch_qts (void) {
|
|||
} else {
|
||||
qts ++;
|
||||
}
|
||||
bl_do_set_qts (qts);
|
||||
//bl_do_set_qts (qts);
|
||||
}
|
||||
|
||||
void fetch_date (void) {
|
||||
int p = fetch_int ();
|
||||
if (p > last_date) {
|
||||
last_date = p;
|
||||
bl_do_set_date (last_date);
|
||||
//bl_do_set_date (last_date);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1252,9 +1254,7 @@ void work_update (struct connection *c UU, long long msg_id UU, struct telegram
|
|||
case CODE_update_encryption:
|
||||
{
|
||||
struct secret_chat *E = fetch_alloc_encrypted_chat ();
|
||||
if (verbosity >= 2) {
|
||||
logprintf ("Secret chat state = %d\n", E->state);
|
||||
}
|
||||
logprintf ("Secret chat state = %d\n", E->state);
|
||||
//print_start ();
|
||||
//push_color (COLOR_YELLOW);
|
||||
//print_date (time (0));
|
||||
|
@ -1776,48 +1776,59 @@ int process_rpc_message (struct telegram *instance, struct encrypted_message *en
|
|||
//}
|
||||
|
||||
int rpc_execute_req_pq (struct telegram *instance, int len) {
|
||||
logprintf("rpc_execute_rq_dh()\n");
|
||||
struct connection *c = telegram_get_connection(instance);
|
||||
if (len >= MAX_RESPONSE_SIZE/* - 12*/ || len < 0/*12*/) {
|
||||
logprintf ( "answer too long (%d bytes), skipping\n", len);
|
||||
queries_num--;
|
||||
return 0;
|
||||
}
|
||||
int Response_len = len;
|
||||
assert (read_in (c, Response, Response_len) == Response_len);
|
||||
Response[Response_len] = 0;
|
||||
process_respq_answer (c, Response/* + 8*/, Response_len/* - 12*/);
|
||||
queries_num--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rpc_execute_rq_dh (struct telegram *instance, int len) {
|
||||
logprintf("rpc_execute_rq_dh()\n");
|
||||
struct connection *c = telegram_get_connection(instance);
|
||||
if (len >= MAX_RESPONSE_SIZE/* - 12*/ || len < 0/*12*/) {
|
||||
logprintf ( "answer too long (%d bytes), skipping\n", len);
|
||||
queries_num--;
|
||||
return 0;
|
||||
}
|
||||
int Response_len = len;
|
||||
assert (read_in (c, Response, Response_len) == Response_len);
|
||||
Response[Response_len] = 0;
|
||||
process_dh_answer (c, Response/* + 8*/, Response_len/* - 12*/);
|
||||
queries_num--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rpc_execute_cdh_sent (struct telegram *instance, int len) {
|
||||
logprintf("rpc_execute_cdh()\n");
|
||||
struct connection *c = telegram_get_connection(instance);
|
||||
if (len >= MAX_RESPONSE_SIZE/* - 12*/ || len < 0/*12*/) {
|
||||
logprintf ( "answer too long (%d bytes), skipping\n", len);
|
||||
queries_num--;
|
||||
return 0;
|
||||
}
|
||||
int Response_len = len;
|
||||
assert (read_in (c, Response, Response_len) == Response_len);
|
||||
Response[Response_len] = 0;
|
||||
process_auth_complete (c, Response/* + 8*/, Response_len/* - 12*/);
|
||||
queries_num--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rpc_execute_authorized (struct telegram *instance, int op, int len) {
|
||||
logprintf("rpc_execute_authorized()\n");
|
||||
struct connection *c = telegram_get_connection(instance);
|
||||
if (len >= MAX_RESPONSE_SIZE/* - 12*/ || len < 0/*12*/) {
|
||||
logprintf ( "answer too long (%d bytes), skipping\n", len);
|
||||
queries_num--;
|
||||
return 0;
|
||||
}
|
||||
int Response_len = len;
|
||||
|
@ -1828,11 +1839,10 @@ int rpc_execute_authorized (struct telegram *instance, int op, int len) {
|
|||
} else {
|
||||
process_rpc_message (instance, (void *)(Response/* + 8*/), Response_len/* - 12*/);
|
||||
}
|
||||
queries_num--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int tc_close (struct connection *c, int who) {
|
||||
if (verbosity) {
|
||||
logprintf ( "outbound http connection #%d : closing by %d\n", c->fd, who);
|
||||
|
@ -1900,11 +1910,13 @@ int auth_ok (void) {
|
|||
return auth_success;
|
||||
}
|
||||
|
||||
/*
|
||||
void dc_authorize (struct dc *DC) {
|
||||
c_state = 0;
|
||||
auth_success = 0;
|
||||
if (verbosity) {
|
||||
logprintf ( "Starting authorization for DC #%d: %s:%d\n", DC->id, DC->ip, DC->port);
|
||||
}
|
||||
net_loop (0, auth_ok);
|
||||
//net_loop (0, auth_ok);
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include <openssl/bn.h>
|
||||
void on_start (void);
|
||||
long long encrypt_send_message (struct connection *c, int *msg, int msg_ints, int useful);
|
||||
void dc_authorize (struct dc *DC);
|
||||
//void dc_authorize (struct dc *DC);
|
||||
void work_update (struct connection *c, long long msg_id);
|
||||
void work_update_binlog (void);
|
||||
int check_g (unsigned char p[256], BIGNUM *g);
|
||||
|
@ -32,7 +32,7 @@ int check_DH_params (BIGNUM *p, int g);
|
|||
void secure_random (void *s, int l);
|
||||
|
||||
|
||||
int send_req_pq_packet (struct telegram *instance);
|
||||
int send_req_pq_packet (struct connection *c);
|
||||
|
||||
int rpc_execute_req_pq (struct telegram *instance, int len);
|
||||
int rpc_execute_rq_dh (struct telegram *instance, int len);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#ifndef __MTPROTO_COMMON_H__
|
||||
#define __MTPROTO_COMMON_H__
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/bn.h>
|
||||
|
|
57
net.c
57
net.c
|
@ -113,10 +113,11 @@ void start_ping_timer (struct connection *c) {
|
|||
insert_event_timer (&c->ev);
|
||||
}
|
||||
|
||||
void restart_connection (struct connection *c);
|
||||
int fail_alarm (void *ev) {
|
||||
((struct connection *)ev)->in_fail_timer = 0;
|
||||
restart_connection (ev);
|
||||
struct connection *c = ev;
|
||||
c->in_fail_timer = 0;
|
||||
logprintf("Connection %d FAILED.", c->fd);
|
||||
telegram_change_state(c->instance, STATE_ERROR, NULL);
|
||||
return 0;
|
||||
}
|
||||
void start_fail_timer (struct connection *c) {
|
||||
|
@ -251,13 +252,14 @@ void rotate_port (struct connection *c) {
|
|||
}
|
||||
}
|
||||
|
||||
struct connection *create_connection (const char *host, int port, int fd) {
|
||||
struct connection *create_connection (const char *host, int port, int fd, struct telegram *instance) {
|
||||
struct connection *c = talloc0 (sizeof (*c));
|
||||
c->fd = fd;
|
||||
c->ip = tstrdup (host);
|
||||
c->flags = 0;
|
||||
c->state = conn_ready;
|
||||
c->port = port;
|
||||
c->instance = instance;
|
||||
if (verbosity) {
|
||||
logprintf ( "connect to %s:%d successful\n", host, port);
|
||||
}
|
||||
|
@ -316,12 +318,11 @@ void restart_connection (struct connection *c) {
|
|||
assert (write_out (c, &byte, 1) == 1);
|
||||
flush_out (c);
|
||||
}
|
||||
|
||||
*/
|
||||
void fail_connection (struct connection *c) {
|
||||
if (c->state == conn_ready || c->state == conn_connecting) {
|
||||
stop_ping_timer (c);
|
||||
}
|
||||
rotate_port (c);
|
||||
struct connection_buffer *b = c->out_head;
|
||||
while (b) {
|
||||
struct connection_buffer *d = b;
|
||||
|
@ -338,18 +339,15 @@ void fail_connection (struct connection *c) {
|
|||
c->state = conn_failed;
|
||||
c->out_bytes = c->in_bytes = 0;
|
||||
close (c->fd);
|
||||
Connections[c->fd] = 0;
|
||||
logprintf ("Lost connection to server... %s:%d\n", c->ip, c->port);
|
||||
restart_connection (c);
|
||||
telegram_change_state(c->instance, STATE_ERROR, NULL);
|
||||
}
|
||||
*/
|
||||
|
||||
extern FILE *log_net_f;
|
||||
void try_write (struct telegram *instance) {
|
||||
int try_write (struct telegram *instance) {
|
||||
struct connection *c = telegram_get_connection(instance);
|
||||
if (verbosity) {
|
||||
logprintf ( "try write: fd = %d\n", c->fd);
|
||||
}
|
||||
logprintf ("try write: fd = %d\n", c->fd);
|
||||
|
||||
int x = 0;
|
||||
while (c->out_head) {
|
||||
int r = netwrite (c->fd, c->out_head->rptr, c->out_head->wptr - c->out_head->rptr);
|
||||
|
@ -359,7 +357,6 @@ void try_write (struct telegram *instance) {
|
|||
fprintf (log_net_f, "%.02lf %d OUT %s:%d", get_utime (CLOCK_REALTIME), r, c->ip, c->port);
|
||||
int i;
|
||||
for (i = 0; i < r; i++) {
|
||||
|
||||
fprintf (log_net_f, " %02x", *(unsigned char *)(c->out_head->rptr + i));
|
||||
}
|
||||
fprintf (log_net_f, "\n");
|
||||
|
@ -387,16 +384,15 @@ void try_write (struct telegram *instance) {
|
|||
logprintf ("fail_connection: write_error %m\n");
|
||||
}
|
||||
fail_connection (c);
|
||||
return;
|
||||
return 0;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (verbosity) {
|
||||
logprintf ( "Sent %d bytes to %d\n", x, c->fd);
|
||||
}
|
||||
logprintf ( "Sent %d bytes to %d\n", x, c->fd);
|
||||
c->out_bytes -= x;
|
||||
return x;
|
||||
}
|
||||
|
||||
void hexdump_buf (struct connection_buffer *b) {
|
||||
|
@ -423,6 +419,9 @@ void hexdump_buf (struct connection_buffer *b) {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Read all rpc responses from the current connection
|
||||
*/
|
||||
void try_rpc_read (struct telegram *instance) {
|
||||
struct connection *c = instance->auth.DC_list[instance->auth.dc_working_num]->sessions[0]->c;
|
||||
|
||||
|
@ -467,10 +466,7 @@ void try_rpc_read (struct telegram *instance) {
|
|||
|
||||
void try_read (struct telegram *instance) {
|
||||
struct connection *c = instance->auth.DC_list[instance->auth.dc_working_num]->sessions[0]->c;
|
||||
|
||||
if (verbosity) {
|
||||
logprintf ( "try read: fd = %d\n", c->fd);
|
||||
}
|
||||
logprintf ( "try read: fd = %d\n", c->fd);
|
||||
if (!c->in_tail) {
|
||||
c->in_head = c->in_tail = new_connection_buffer (1 << 20);
|
||||
}
|
||||
|
@ -489,9 +485,11 @@ void try_read (struct telegram *instance) {
|
|||
}
|
||||
if (r > 0) {
|
||||
c->last_receive_time = get_double_time ();
|
||||
|
||||
// TODO: Implement the Ping-Timer
|
||||
// reset ping timer
|
||||
stop_ping_timer (c);
|
||||
start_ping_timer (c);
|
||||
//stop_ping_timer (c);
|
||||
//start_ping_timer (c);
|
||||
}
|
||||
if (r >= 0) {
|
||||
// write pointer nach vorne setzen
|
||||
|
@ -507,9 +505,7 @@ void try_read (struct telegram *instance) {
|
|||
c->in_tail = b;
|
||||
} else {
|
||||
if (errno != EAGAIN && errno != EWOULDBLOCK) {
|
||||
if (verbosity) {
|
||||
logprintf ("fail_connection: read_error %m\n");
|
||||
}
|
||||
logprintf ("fail_connection: read_error %m\n");
|
||||
fail_connection (c);
|
||||
return;
|
||||
} else {
|
||||
|
@ -517,9 +513,7 @@ void try_read (struct telegram *instance) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (verbosity) {
|
||||
logprintf ( "Received %d bytes from %d\n", x, c->fd);
|
||||
}
|
||||
logprintf ( "Received %d bytes from %d\n", x, c->fd);
|
||||
c->in_bytes += x;
|
||||
if (x) {
|
||||
try_rpc_read (instance);
|
||||
|
@ -609,10 +603,7 @@ void insert_msg_id (struct session *S, long long id) {
|
|||
}
|
||||
}
|
||||
|
||||
extern struct dc *DC_list[];
|
||||
|
||||
struct dc *alloc_dc (struct dc* DC_list[], int id, char *ip, int port UU) {
|
||||
assert (!DC_list[id]);
|
||||
struct dc *DC = talloc0 (sizeof (*DC));
|
||||
DC->id = id;
|
||||
DC->ip = ip;
|
||||
|
|
7
net.h
7
net.h
|
@ -130,6 +130,7 @@ struct connection {
|
|||
void *extra;
|
||||
struct event_timer ev;
|
||||
double last_receive_time;
|
||||
struct telegram *instance;
|
||||
};
|
||||
|
||||
extern struct connection *Connections[];
|
||||
|
@ -140,7 +141,7 @@ int read_in (struct connection *c, void *data, int len);
|
|||
|
||||
void create_all_outbound_connections (void);
|
||||
|
||||
struct connection *create_connection (const char *host, int port, int fd);
|
||||
struct connection *create_connection (const char *host, int port, int fd, struct telegram *instance);
|
||||
int connections_make_poll_array (struct pollfd *fds, int max);
|
||||
void connections_poll_result (struct pollfd *fds, int max);
|
||||
void insert_msg_id (struct session *S, long long id);
|
||||
|
@ -151,8 +152,8 @@ void dc_create_session (struct dc *DC, struct connection *c);
|
|||
void try_read (struct telegram *instance);
|
||||
void try_rpc_read (struct telegram *instance);
|
||||
|
||||
void try_write (struct telegram *instance);
|
||||
int try_write (struct telegram *instance);
|
||||
|
||||
#define GET_DC(c) (c->session->dc)
|
||||
#define GET_DC(c) (telegram_get_working_dc(c->instance))
|
||||
#endif
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
|
||||
// test
|
||||
|
||||
|
@ -42,6 +43,7 @@
|
|||
#include "prpl.h"
|
||||
#include "prefs.h"
|
||||
#include "util.h"
|
||||
#include "eventloop.h"
|
||||
|
||||
// struct telegram Includes
|
||||
#include "telegram.h"
|
||||
|
@ -105,7 +107,6 @@ static void tgprpl_tooltip_text(PurpleBuddy * buddy, PurpleNotifyUserInfo * info
|
|||
/**
|
||||
* Request a verification key, save the returned verification_hash in the account settings
|
||||
* for later usage and inform the user.
|
||||
*/
|
||||
static void login_request_verification(PurpleAccount *acct)
|
||||
{
|
||||
// TODO: we should find a way to request the key
|
||||
|
@ -119,6 +120,7 @@ static void login_request_verification(PurpleAccount *acct)
|
|||
"You need to verify this device, please enter the code struct telegram has sent to you by SMS.",
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handle a failed verification, by removing the invalid sms code and
|
||||
|
@ -135,25 +137,52 @@ static void login_verification_fail(PurpleAccount *acct)
|
|||
static void tgprpl_output_cb(gpointer data, gint source, PurpleInputCondition cond)
|
||||
{
|
||||
logprintf("tgprpl_output_cb()\n");
|
||||
PurpleConnection *c = data;
|
||||
telegram_conn *conn = purple_connection_get_protocol_data(c);
|
||||
telegram_write_output(conn->tg);
|
||||
struct telegram *tg = data;
|
||||
telegram_conn *conn = tg->extra;
|
||||
|
||||
int written = telegram_write_output(tg);
|
||||
logprintf("written(%d): %d.\n", telegram_get_connection(tg)->fd, written);
|
||||
if (written == 0) {
|
||||
logprintf("no output, removing output...\n");
|
||||
purple_input_remove(conn->wh);
|
||||
conn->wh = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void tgprpl_has_output(struct telegram *tg)
|
||||
{
|
||||
logprintf("tgprpl_has_output()\n");
|
||||
telegram_conn *conn = tg->extra;
|
||||
if (! conn->wh) {
|
||||
conn->wh = purple_input_add(telegram_get_connection(tg)->fd, PURPLE_INPUT_WRITE,
|
||||
tgprpl_output_cb, tg);
|
||||
logprintf("Attached write handle: %u ", conn->wh);
|
||||
}
|
||||
}
|
||||
|
||||
static void tgprpl_input_cb(gpointer data, gint source, PurpleInputCondition cond)
|
||||
{
|
||||
struct telegram *tg = data;
|
||||
//telegram_conn *conn = tg->extra;
|
||||
logprintf("tgprpl_input_cb()\n");
|
||||
PurpleConnection *c = data;
|
||||
telegram_conn *conn = purple_connection_get_protocol_data(c);
|
||||
telegram_read_input(conn->tg);
|
||||
|
||||
// TODO: remove input handler when no more input
|
||||
telegram_read_input(tg);
|
||||
if (telegram_has_output(tg)) {
|
||||
tgprpl_has_output(tg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
static void tgprpl_on_input(struct telegram *tg)
|
||||
static void tgprpl_has_input(struct telegram *tg)
|
||||
{
|
||||
PurpleConnection *c = data;
|
||||
logprintf("tgprpl_has_input()\n");
|
||||
telegram_conn *conn = tg->extra;
|
||||
if (! conn->rh) {
|
||||
conn->rh = purple_input_add(telegram_get_connection(tg)->fd, PURPLE_INPUT_READ,
|
||||
tgprpl_input_cb, tg);
|
||||
logprintf("Attached read handle: %u ", conn->rh);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
static void tgprpl_on_state_change(struct telegram *instance, int state, void *data)
|
||||
{
|
||||
|
@ -175,7 +204,8 @@ static void tgprpl_on_state_change(struct telegram *instance, int state, void *d
|
|||
NULL, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
network_verify_phone_registration(code, hash, first_name, last_name);
|
||||
|
||||
do_send_code_result_auth (instance, code, hash, first_name, last_name);
|
||||
break;
|
||||
|
||||
case STATE_PHONE_CODE_NOT_ENTERED:
|
||||
|
@ -190,7 +220,7 @@ static void tgprpl_on_state_change(struct telegram *instance, int state, void *d
|
|||
case STATE_CLIENT_CODE_NOT_ENTERED: {
|
||||
const char *code = purple_account_get_string(conn->pa, "verification_key", NULL);
|
||||
const char *hash = purple_account_get_string(conn->pa, "verification_hash", NULL);
|
||||
network_verify_registration(code, hash);
|
||||
do_send_code_result(instance, code, hash);
|
||||
// enter SMS code
|
||||
}
|
||||
break;
|
||||
|
@ -270,14 +300,13 @@ static void tgprpl_login(PurpleAccount * acct)
|
|||
|
||||
purple_connection_set_state(gc, PURPLE_CONNECTING);
|
||||
purple_proxy_connect(gc, acct, DC.ip, DC.port, tgprpl_login_on_connected, tg);
|
||||
purple_debug_info(PLUGIN_ID, "username: %s\n", username);
|
||||
purple_debug_info(PLUGIN_ID, "hostname: %s\n", DC.ip);
|
||||
}
|
||||
|
||||
void tgprpl_login_on_connected(gpointer *data, gint fd, const gchar *error_message)
|
||||
{
|
||||
purple_debug_info(PLUGIN_ID, "tgprpl_login_on_connected()\n");
|
||||
struct telegram *tg = (struct telegram*) data;
|
||||
telegram_conn *conn = tg->extra;
|
||||
//running_for_first_time();
|
||||
|
||||
if (fd == -1) {
|
||||
|
@ -286,9 +315,10 @@ void tgprpl_login_on_connected(gpointer *data, gint fd, const gchar *error_messa
|
|||
return;
|
||||
}
|
||||
|
||||
purple_debug_info(PLUGIN_ID, "Connecting to the struct telegram network...\n");
|
||||
purple_input_add(fd, PURPLE_INPUT_WRITE, tgprpl_output_cb, telegram_get_connection(tg));
|
||||
purple_input_add(fd, PURPLE_INPUT_READ, tgprpl_input_cb, telegram_get_connection(tg));
|
||||
|
||||
purple_debug_info(PLUGIN_ID, "Connecting to the telegram network...\n");
|
||||
conn->wh = purple_input_add(fd, PURPLE_INPUT_WRITE, tgprpl_output_cb, tg);
|
||||
conn->rh = purple_input_add(fd, PURPLE_INPUT_READ, tgprpl_input_cb, tg);
|
||||
telegram_network_connect(tg, fd);
|
||||
|
||||
// // load all settings: the known network topology, secret keys, logs and configuration file paths
|
||||
|
@ -896,10 +926,10 @@ static PurplePluginInfo info = {
|
|||
NULL,
|
||||
PURPLE_PRIORITY_DEFAULT,
|
||||
PLUGIN_ID,
|
||||
"struct telegram",
|
||||
"Telegram",
|
||||
"0.1",
|
||||
"struct telegram integration.",
|
||||
"Adds support for the struct telegram protocol to libpurple.",
|
||||
"Telegram protocol",
|
||||
"Adds support for the telegram protocol to libpurple.",
|
||||
"Christopher Althaus <althaus.christopher@gmail.com>, Markus Endres <endresma45241@th-nuernberg.de>, Matthias Jentsch <mtthsjntsch@gmail.com>",
|
||||
"https://bitbucket.org/telegrampurple/telegram-purple",
|
||||
NULL, // on load
|
||||
|
|
|
@ -39,4 +39,14 @@ typedef struct {
|
|||
struct telegram *tg;
|
||||
PurpleAccount *pa;
|
||||
PurpleConnection *gc;
|
||||
|
||||
/**
|
||||
* Write handler returned by purple_input_add
|
||||
*/
|
||||
guint wh;
|
||||
|
||||
/**
|
||||
* Read handler returned by purple_input_add
|
||||
*/
|
||||
guint rh;
|
||||
} telegram_conn;
|
||||
|
|
38
queries.c
38
queries.c
|
@ -196,14 +196,10 @@ void query_error (long long id) {
|
|||
int error_code = fetch_int ();
|
||||
int error_len = prefetch_strlen ();
|
||||
char *error = fetch_str (error_len);
|
||||
if (verbosity) {
|
||||
logprintf ( "error for query #%lld: #%d :%.*s\n", id, error_code, error_len, error);
|
||||
}
|
||||
logprintf ( "error for query #%lld: #%d :%.*s\n", id, error_code, error_len, error);
|
||||
struct query *q = query_get (id);
|
||||
if (!q) {
|
||||
if (verbosity) {
|
||||
logprintf ( "No such query\n");
|
||||
}
|
||||
logprintf ( "No such query\n");
|
||||
} else {
|
||||
if (!(q->flags & QUERY_ACK_RECEIVED)) {
|
||||
remove_event_timer (&q->ev);
|
||||
|
@ -281,16 +277,12 @@ DEFINE_TREE (timer, struct event_timer *, event_timer_cmp, 0)
|
|||
struct tree_timer *timer_tree;
|
||||
|
||||
void insert_event_timer (struct event_timer *ev) {
|
||||
if (verbosity > 2) {
|
||||
logprintf ( "INSERT: %lf %p %p\n", ev->timeout, ev->self, ev->alarm);
|
||||
}
|
||||
logprintf ( "INSERT: %lf %p %p\n", ev->timeout, ev->self, ev->alarm);
|
||||
timer_tree = tree_insert_timer (timer_tree, ev, lrand48 ());
|
||||
}
|
||||
|
||||
void remove_event_timer (struct event_timer *ev) {
|
||||
if (verbosity > 2) {
|
||||
logprintf ( "REMOVE: %lf %p %p\n", ev->timeout, ev->self, ev->alarm);
|
||||
}
|
||||
logprintf ( "REMOVE: %lf %p %p\n", ev->timeout, ev->self, ev->alarm);
|
||||
timer_tree = tree_delete_timer (timer_tree, ev);
|
||||
}
|
||||
|
||||
|
@ -641,14 +633,14 @@ struct query_methods nearest_dc_methods = {
|
|||
.on_error = fail_on_error
|
||||
};
|
||||
|
||||
int do_get_nearest_dc (struct telegram *instance) {
|
||||
void do_get_nearest_dc (struct telegram *instance) {
|
||||
struct dc *DC_working = telegram_get_working_dc(instance);
|
||||
clear_packet ();
|
||||
out_int (CODE_help_get_nearest_dc);
|
||||
nearest_dc_num = -1;
|
||||
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &nearest_dc_methods, 0);
|
||||
net_loop (0, nr_f);
|
||||
return nearest_dc_num;
|
||||
//net_loop (0, nr_f);
|
||||
//return nearest_dc_num;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -702,7 +694,7 @@ struct query_methods sign_in_methods = {
|
|||
.on_error = sign_in_on_error
|
||||
};
|
||||
|
||||
int do_send_code_result (struct telegram *instance, const char *code, const char *sms_hash) {
|
||||
void do_send_code_result (struct telegram *instance, const char *code, const char *sms_hash) {
|
||||
struct dc *DC_working = telegram_get_working_dc(instance);
|
||||
clear_packet ();
|
||||
out_int (CODE_auth_sign_in);
|
||||
|
@ -710,12 +702,14 @@ int do_send_code_result (struct telegram *instance, const char *code, const char
|
|||
out_string(sms_hash);
|
||||
out_string (code);
|
||||
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &sign_in_methods, instance);
|
||||
/*
|
||||
sign_in_ok = 0;
|
||||
net_loop (0, sign_in_is_ok);
|
||||
//net_loop (0, sign_in_is_ok);
|
||||
return sign_in_ok;
|
||||
*/
|
||||
}
|
||||
|
||||
int do_send_code_result_auth (struct telegram *instance, const char *code, const char *sms_hash, const char *first_name, const char *last_name) {
|
||||
void do_send_code_result_auth (struct telegram *instance, const char *code, const char *sms_hash, const char *first_name, const char *last_name) {
|
||||
struct dc *DC_working = telegram_get_working_dc(instance);
|
||||
clear_packet ();
|
||||
out_int (CODE_auth_sign_up);
|
||||
|
@ -725,9 +719,11 @@ int do_send_code_result_auth (struct telegram *instance, const char *code, const
|
|||
out_string (first_name);
|
||||
out_string (last_name);
|
||||
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &sign_in_methods, instance);
|
||||
/*
|
||||
sign_in_ok = 0;
|
||||
net_loop (0, sign_in_is_ok);
|
||||
return sign_in_ok;
|
||||
*/
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -1987,9 +1983,9 @@ void load_next_part (struct telegram *instance, struct download *D) {
|
|||
static char buf[PATH_MAX];
|
||||
int l;
|
||||
if (!D->id) {
|
||||
l = tsnprintf (buf, sizeof (buf), "%s/download_%lld_%d", get_downloads_directory (), D->volume, D->local_id);
|
||||
l = tsnprintf (buf, sizeof (buf), "%s/download_%lld_%d", instance->download_path, D->volume, D->local_id);
|
||||
} else {
|
||||
l = tsnprintf (buf, sizeof (buf), "%s/download_%lld", get_downloads_directory (), D->id);
|
||||
l = tsnprintf (buf, sizeof (buf), "%s/download_%lld", instance->download_path, D->id);
|
||||
}
|
||||
if (l >= (int) sizeof (buf)) {
|
||||
logprintf ("Download filename is too long");
|
||||
|
@ -2195,7 +2191,6 @@ void do_export_auth (struct telegram *instance, int num) {
|
|||
out_int (CODE_auth_export_authorization);
|
||||
out_int (num);
|
||||
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &export_auth_methods, 0);
|
||||
net_loop (0, is_export_auth_str);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -2220,7 +2215,6 @@ void do_import_auth (struct telegram *instance, int num) {
|
|||
out_int (our_id);
|
||||
out_cstring (export_auth_str, export_auth_str_len);
|
||||
send_query (instance->auth.DC_list[num], packet_ptr - packet_buffer, packet_buffer, &import_auth_methods, 0);
|
||||
net_loop (0, isn_export_auth_str);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ extern struct query_methods help_get_config_methods;
|
|||
|
||||
void do_send_code (struct telegram *instance, const char *user);
|
||||
void do_phone_call (struct telegram *instance, const char *user);
|
||||
int do_send_code_result (struct telegram *instance, const char *code, const char *sms_hash);
|
||||
void do_send_code_result (struct telegram *instance, const char *code, const char *sms_hash);
|
||||
double get_double_time (void);
|
||||
|
||||
void do_update_contact_list (struct telegram *instance);
|
||||
|
@ -101,8 +101,8 @@ void do_load_document (struct telegram *instance, struct document *V, int next);
|
|||
void do_load_document_thumb (struct telegram *instance, struct document *video, int next);
|
||||
void do_help_get_config (struct telegram *instance);
|
||||
int do_auth_check_phone (struct telegram *instance, const char *user);
|
||||
int do_get_nearest_dc (struct telegram*);
|
||||
int do_send_code_result_auth (struct telegram *instance, const char *code, const char *sms_hash, const char *first_name, const char *last_name);
|
||||
void do_get_nearest_dc (struct telegram*);
|
||||
void do_send_code_result_auth (struct telegram *instance, const char *code, const char *sms_hash, const char *first_name, const char *last_name);
|
||||
void do_import_auth (struct telegram *instance, int num);
|
||||
void do_export_auth (struct telegram *instance, int num);
|
||||
void do_add_contact (struct telegram *instance, const char *phone, int phone_len, const char *first_name, int first_name_len, const char *last_name, int last_name_len, int force);
|
||||
|
@ -127,3 +127,5 @@ void fetch_dc_option (struct telegram *instance);
|
|||
#endif
|
||||
|
||||
const char *get_last_err();
|
||||
|
||||
int all_queries_done();
|
||||
|
|
146
telegram.c
146
telegram.c
|
@ -4,17 +4,15 @@
|
|||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "mtproto-common.h"
|
||||
#include "telegram.h"
|
||||
#include "msglog.h"
|
||||
#include "glib.h"
|
||||
#include "tools.h"
|
||||
#include "mtproto-client.h"
|
||||
|
||||
/*
|
||||
* Events
|
||||
*/
|
||||
|
||||
/*
|
||||
* New message received
|
||||
*/
|
||||
|
@ -55,7 +53,7 @@ void telegram_add_state_change_listener(struct telegram *instance, state_listene
|
|||
}
|
||||
void telegram_change_state(struct telegram *instance, int state, void *data)
|
||||
{
|
||||
logprintf("Changing struct telegram state %d\n", state);
|
||||
logprintf("telegram connection state changed to: %d\n", state);
|
||||
instance->session_state = state;
|
||||
GList *curr = instance->change_state_listeners;
|
||||
while ((curr = g_list_next(change_listeners)) != NULL) {
|
||||
|
@ -65,22 +63,40 @@ void telegram_change_state(struct telegram *instance, int state, void *data)
|
|||
|
||||
struct telegram *telegram_new(struct dc *DC, const char* login, const char *config_path)
|
||||
{
|
||||
on_start ();
|
||||
struct telegram *this = malloc(sizeof(struct telegram));
|
||||
this->protocol_data = NULL;
|
||||
this->curr_dc = 0;
|
||||
this->auth.DC_list[0] = DC;
|
||||
this->change_state_listeners = NULL;
|
||||
this->config_path = config_path;
|
||||
strcpy(this->login, malloc(strlen(login) + 1));
|
||||
|
||||
this->login = g_strdup(login);
|
||||
this->config_path = g_strdup_printf("%s/%s", config_path, login);
|
||||
this->download_path = telegram_get_config(this, "downloads");
|
||||
this->auth_path = telegram_get_config(this, "auth");
|
||||
this->state_path = telegram_get_config(this, "state");
|
||||
this->secret_path = telegram_get_config(this, "secret");
|
||||
|
||||
logprintf("%s\n", this->login);
|
||||
logprintf("%s\n", this->config_path);
|
||||
logprintf("%s\n", this->download_path);
|
||||
logprintf("%s\n", this->auth_path);
|
||||
logprintf("%s\n", this->state_path);
|
||||
|
||||
telegram_change_state(this, STATE_INITIALISED, NULL);
|
||||
return this;
|
||||
}
|
||||
|
||||
void telegram_free(struct telegram *instance)
|
||||
void telegram_free(struct telegram *this)
|
||||
{
|
||||
g_list_free(instance->change_state_listeners);
|
||||
free(instance->login);
|
||||
free(instance);
|
||||
g_list_free(this->change_state_listeners);
|
||||
g_free(this->login);
|
||||
g_free(this->config_path);
|
||||
g_free(this->download_path);
|
||||
g_free(this->auth_path);
|
||||
g_free(this->state_path);
|
||||
g_free(this->secret_path);
|
||||
free(this);
|
||||
}
|
||||
|
||||
void assert_file_usable(const char *file)
|
||||
|
@ -90,56 +106,80 @@ void assert_file_usable(const char *file)
|
|||
|
||||
void assure_file_exists(const char *dir, const char *file)
|
||||
{
|
||||
char f[256];
|
||||
g_mkdir_with_parents(dir, 0700);
|
||||
sprintf(f, "%s/%s", dir, file);
|
||||
char *f = g_strdup_printf("%s/%s", dir, file);
|
||||
close(open(f, O_RDWR | O_CREAT, S_IRUSR, S_IWUSR));
|
||||
assert_file_usable(f);
|
||||
g_free(f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the currently used connection
|
||||
*
|
||||
* Will only work after telegram_connect has been called and the connection has
|
||||
* not errored.
|
||||
*/
|
||||
struct connection *telegram_get_connection(struct telegram *instance)
|
||||
{
|
||||
struct dc *DC = instance->auth.DC_list[instance->auth.dc_working_num];
|
||||
assert(instance->session_state != STATE_ERROR);
|
||||
|
||||
struct dc *DC = telegram_get_working_dc(instance);
|
||||
assert(DC);
|
||||
assert(DC->sessions[0]);
|
||||
assert(DC->sessions[0]->c);
|
||||
//logprintf("get_connection() -> fd: %d\n", DC->sessions[0]->c->fd);
|
||||
return DC->sessions[0]->c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the currently used DC
|
||||
*
|
||||
* Will only work after restore_session has been called and the data center configuration
|
||||
* was properly loaded
|
||||
*/
|
||||
struct dc *telegram_get_working_dc(struct telegram *instance)
|
||||
{
|
||||
assert(instance->session_state != STATE_ERROR);
|
||||
|
||||
assert(instance->auth.DC_list);
|
||||
assert(instance->auth.dc_working_num > 0);
|
||||
struct dc *DC = instance->auth.DC_list[instance->auth.dc_working_num];
|
||||
return DC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the current session state to a file
|
||||
*/
|
||||
void telegram_restore_session(struct telegram *instance)
|
||||
{
|
||||
char file[256];
|
||||
sprintf(file, "%s/%s/%s", instance->config_path, instance->login, "auth");
|
||||
instance->auth = read_auth_file(file);
|
||||
sprintf(file, "%s/%s/%s", instance->config_path, instance->login, "state");
|
||||
instance->proto = read_state_file(file);
|
||||
g_mkdir_with_parents(instance->config_path, 0700);
|
||||
instance->auth = read_auth_file(instance->auth_path);
|
||||
instance->proto = read_state_file(instance->state_path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the current session state from a file
|
||||
*/
|
||||
void telegram_store_session(struct telegram *instance)
|
||||
{
|
||||
char file[256];
|
||||
sprintf(file, "%s/%s", instance->config_path, instance->login);
|
||||
assure_file_exists(file, "auth");
|
||||
assure_file_exists(file, "state");
|
||||
|
||||
sprintf(file, "%s/%s/%s", instance->config_path, instance->login, "auth");
|
||||
write_auth_file(instance->auth, file);
|
||||
|
||||
sprintf(file, "%s/%s/%s", instance->config_path, instance->login, "state");
|
||||
write_state_file(instance->proto, file);
|
||||
assure_file_exists(instance->config_path, "auth");
|
||||
assure_file_exists(instance->config_path, "state");
|
||||
write_auth_file(&instance->auth, instance->auth_path);
|
||||
write_state_file(&instance->proto, instance->state_path);
|
||||
}
|
||||
|
||||
void telegram_get_downloads_dir(struct telegram *instance)
|
||||
char *telegram_get_config(struct telegram *instance, char *config)
|
||||
{
|
||||
|
||||
return g_strdup_printf("%s/%s", instance->config_path, config);
|
||||
}
|
||||
|
||||
void telegram_network_connect(struct telegram *instance, int fd)
|
||||
{
|
||||
on_start ();
|
||||
logprintf("telegram_network_connect()\n");
|
||||
if (!instance->auth.DC_list) {
|
||||
logprintf("telegram_network_connect(): cannot connect, restore / initialise a session first.\n");
|
||||
assert(0);
|
||||
}
|
||||
struct dc *DC_working = telegram_get_working_dc(instance);
|
||||
|
||||
// check whether authentication is needed
|
||||
|
@ -147,14 +187,12 @@ void telegram_network_connect(struct telegram *instance, int fd)
|
|||
logprintf("No working DC, authenticating.\n");
|
||||
|
||||
// init a new connection
|
||||
struct connection *c = create_connection (DC_working->ip, DC_working->port, fd);
|
||||
struct connection *c = create_connection (DC_working->ip, DC_working->port, fd, instance);
|
||||
// init a new session with random session id
|
||||
dc_create_session(DC_working, c);
|
||||
|
||||
// Request PQ
|
||||
char byte = 0xef;
|
||||
assert (write_out (c, &byte, 1) == 1);
|
||||
send_req_pq_packet (instance);
|
||||
send_req_pq_packet (c);
|
||||
telegram_change_state(instance, STATE_PQ_REQUESTED, NULL);
|
||||
} else {
|
||||
logprintf("Already working session, setting state to connected.\n");
|
||||
|
@ -175,11 +213,23 @@ void on_state_change(struct telegram *instance, int state, void *data)
|
|||
case STATE_CONNECTED:
|
||||
on_connected(instance);
|
||||
break;
|
||||
|
||||
case STATE_ERROR: {
|
||||
const char* err = data;
|
||||
logprintf("Telegram errored: %s \n", err);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case STATE_AUTH_DONE:
|
||||
logprintf("requesting configuration");
|
||||
telegram_change_state(instance, STATE_CONFIG_REQUESTED, NULL);
|
||||
do_help_get_config (instance);
|
||||
break;
|
||||
|
||||
case STATE_CONFIG_REQUESTED:
|
||||
logprintf("switch: config_requested\n");
|
||||
telegram_store_session(instance);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -191,31 +241,39 @@ void try_rpc_interpret(struct telegram *instance, int op, int len)
|
|||
{
|
||||
switch (instance->session_state) {
|
||||
case STATE_PQ_REQUESTED:
|
||||
logprintf("switch: pq_requested\n");
|
||||
rpc_execute_req_pq(instance, len);
|
||||
telegram_change_state(instance, STATE_DH_REQUESTED, NULL);
|
||||
break;
|
||||
case STATE_DH_REQUESTED:
|
||||
logprintf("switch: dh_requested\n");
|
||||
rpc_execute_rq_dh(instance, len);
|
||||
telegram_change_state(instance, STATE_CDH_REQUESTED, NULL);
|
||||
break;
|
||||
case STATE_CDH_REQUESTED:
|
||||
logprintf("switch: cdh_requested\n");
|
||||
rpc_execute_cdh_sent(instance, len);
|
||||
telegram_change_state(instance, STATE_AUTH_DONE, NULL);
|
||||
break;
|
||||
case STATE_AUTH_DONE:
|
||||
logprintf("switch: auth_done\n");
|
||||
rpc_execute_authorized(instance, op, len);
|
||||
telegram_change_state(instance, STATE_CONFIG_REQUESTED, NULL);
|
||||
do_help_get_config (instance);
|
||||
break;
|
||||
case STATE_CONFIG_REQUESTED:
|
||||
// ?
|
||||
telegram_store_session(instance);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void telegram_read_input (struct telegram *instance)
|
||||
{
|
||||
try_read(instance);
|
||||
return try_read(instance);
|
||||
}
|
||||
|
||||
int telegram_write_output (struct telegram *instance)
|
||||
{
|
||||
return try_write(instance);
|
||||
}
|
||||
|
||||
int telegram_has_output (struct telegram *instance)
|
||||
{
|
||||
return !all_queries_done();
|
||||
}
|
||||
|
||||
|
|
24
telegram.h
24
telegram.h
|
@ -70,8 +70,14 @@
|
|||
struct telegram {
|
||||
void *protocol_data;
|
||||
int curr_dc;
|
||||
|
||||
char *login;
|
||||
const char *config_path;
|
||||
char *config_path;
|
||||
char *download_path;
|
||||
char *auth_path;
|
||||
char *state_path;
|
||||
char *secret_path;
|
||||
|
||||
int session_state;
|
||||
|
||||
/*
|
||||
|
@ -81,6 +87,10 @@ struct telegram {
|
|||
struct authorization_state auth;
|
||||
|
||||
GList *change_state_listeners;
|
||||
|
||||
/*
|
||||
* Callbacks
|
||||
*/
|
||||
void (*on_output)(struct telegram *instance);
|
||||
|
||||
void *extra;
|
||||
|
@ -89,13 +99,16 @@ struct telegram {
|
|||
/**
|
||||
* Constructor
|
||||
*/
|
||||
struct telegram *telegram_new(struct dc *DC, const char* login, const char* config_path);
|
||||
struct telegram *telegram_new(struct dc *DC, const char* login,
|
||||
const char* config_path);
|
||||
|
||||
/**
|
||||
* Resume the session to
|
||||
*/
|
||||
void telegram_restore_session(struct telegram *instance);
|
||||
|
||||
char *telegram_get_config(struct telegram *instance, char *config);
|
||||
|
||||
/**
|
||||
* Store
|
||||
*/
|
||||
|
@ -176,7 +189,12 @@ void telegram_read_input (struct telegram *instance);
|
|||
/**
|
||||
* Write all available output to the network
|
||||
*/
|
||||
void telegram_write_output (struct telegram *instance);
|
||||
int telegram_write_output (struct telegram *instance);
|
||||
|
||||
/**
|
||||
* Return whether there is pending output.
|
||||
*/
|
||||
int telegram_has_output (struct telegram *instance);
|
||||
|
||||
/**
|
||||
* Try to interpret RPC calls and apply the changes to the current telegram state
|
||||
|
|
26
tools.c
26
tools.c
|
@ -105,6 +105,32 @@ void tfree (void *ptr, int size __attribute__ ((unused))) {
|
|||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a variable amount of strings together
|
||||
*/
|
||||
//char *stradd(const char *strs, ...)
|
||||
//{
|
||||
// va_list args;
|
||||
// size_t size = 0;
|
||||
// char *result;
|
||||
//
|
||||
// // count strlen
|
||||
// va_start(args, strs);
|
||||
// for (int i = 0; strs[i] != '\0'; i++) {
|
||||
// size += strlen(va_arg(args, char*));
|
||||
// }
|
||||
// va_end(args);
|
||||
//
|
||||
// // create the new string
|
||||
// result = talloc0(size + 1);
|
||||
// va_start(args, strs);
|
||||
// for (int i = 0; strs[i] != '\0'; i++) {
|
||||
// strcat(result, va_arg(args, char*));
|
||||
// }
|
||||
// va_end(args);
|
||||
// return result;
|
||||
//}
|
||||
|
||||
void tfree_str (void *ptr) {
|
||||
if (!ptr) { return; }
|
||||
tfree (ptr, strlen (ptr) + 1);
|
||||
|
|
1
tools.h
1
tools.h
|
@ -25,6 +25,7 @@ void *trealloc (void *ptr, size_t old_size, size_t size);
|
|||
void *talloc0 (size_t size);
|
||||
char *tstrdup (const char *s);
|
||||
char *tstrndup (const char *s, size_t n);
|
||||
//char *stradd(const char *, ...);
|
||||
int tinflate (void *input, int ilen, void *output, int olen);
|
||||
void ensure (int r);
|
||||
void ensure_ptr (void *p);
|
||||
|
|
Loading…
Add table
Reference in a new issue