Skip to content

Commit

Permalink
small fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
vvaltman committed Jan 9, 2015
1 parent 2b35bf5 commit 0205b66
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 51 deletions.
87 changes: 53 additions & 34 deletions mtproto-client.c
Original file line number Diff line number Diff line change
Expand Up @@ -544,12 +544,14 @@ static int process_dh_answer (struct tgl_state *TLS, struct connection *c, char
/* }}} */

static void create_temp_auth_key (struct tgl_state *TLS, struct connection *c) {
assert (TLS->enable_pfs);
send_req_pq_temp_packet (TLS, c);
}

int tglmp_encrypt_inner_temp (struct tgl_state *TLS, struct connection *c, int *msg, int msg_ints, int useful, void *data, long long msg_id);
static long long msg_id_override;
static void mpc_on_get_config (struct tgl_state *TLS, void *extra, int success);
static void bind_temp_auth_key (struct tgl_state *TLS, struct connection *c);

/* {{{ RECV AUTH COMPLETE */

Expand Down Expand Up @@ -613,8 +615,8 @@ static int process_auth_complete (struct tgl_state *TLS, struct connection *c, c
bl_do_set_auth_key_id (TLS, DC->id, (unsigned char *)DC->auth_key);
sha1 ((unsigned char *)DC->auth_key, 256, sha1_buffer);
} else {
DC->temp_auth_key_id = *(long long *)(sha1_buffer + 12);
sha1 ((unsigned char *)DC->temp_auth_key, 256, sha1_buffer);
DC->temp_auth_key_id = *(long long *)(sha1_buffer + 12);
}

DC->server_salt = *(long long *)DC->server_nonce ^ *(long long *)DC->new_nonce;
Expand All @@ -623,28 +625,7 @@ static int process_auth_complete (struct tgl_state *TLS, struct connection *c, c

vlogprintf (E_DEBUG, "Auth success\n");
if (temp_key) {
long long msg_id = generate_next_msg_id (TLS, DC, TLS->net_methods->get_session (c));
clear_packet ();
out_int (CODE_bind_auth_key_inner);
long long rand;
tglt_secure_random (&rand, 8);
out_long (rand);
out_long (DC->temp_auth_key_id);
out_long (DC->auth_key_id);

struct tgl_session *S = TLS->net_methods->get_session (c);
if (!S->session_id) {
tglt_secure_random (&S->session_id, 8);
}
out_long (S->session_id);
int expires = time (0) + DC->server_time_delta + TLS->temp_key_expire_time;
out_int (expires);

static int data[1000];
int len = tglmp_encrypt_inner_temp (TLS, c, packet_buffer, packet_ptr - packet_buffer, 0, data, msg_id);
msg_id_override = msg_id;
tgl_do_send_bind_temp_key (TLS, DC, rand, expires, (void *)data, len, msg_id);
msg_id_override = 0;
bind_temp_auth_key (TLS, c);
} else {
DC->flags |= 1;
if (TLS->enable_pfs) {
Expand All @@ -663,6 +644,37 @@ static int process_auth_complete (struct tgl_state *TLS, struct connection *c, c
}
/* }}} */

static void bind_temp_auth_key (struct tgl_state *TLS, struct connection *c) {
struct tgl_dc *DC = TLS->net_methods->get_dc (c);
if (DC->temp_auth_key_bind_query_id) {
tglq_query_delete (TLS, DC->temp_auth_key_bind_query_id);
}
struct tgl_session *S = TLS->net_methods->get_session (c);
long long msg_id = generate_next_msg_id (TLS, DC, S);

clear_packet ();
out_int (CODE_bind_auth_key_inner);
long long rand;
tglt_secure_random (&rand, 8);
out_long (rand);
out_long (DC->temp_auth_key_id);
out_long (DC->auth_key_id);

if (!S->session_id) {
tglt_secure_random (&S->session_id, 8);
}
out_long (S->session_id);
int expires = time (0) + DC->server_time_delta + TLS->temp_key_expire_time;
out_int (expires);

static int data[1000];
int len = tglmp_encrypt_inner_temp (TLS, c, packet_buffer, packet_ptr - packet_buffer, 0, data, msg_id);
msg_id_override = msg_id;
DC->temp_auth_key_bind_query_id = msg_id;
tgl_do_send_bind_temp_key (TLS, DC, rand, expires, (void *)data, len, msg_id);
msg_id_override = 0;
}

/*
*
* AUTHORIZED (MAIN) PROTOCOL PART
Expand All @@ -672,9 +684,9 @@ static int process_auth_complete (struct tgl_state *TLS, struct connection *c, c
static struct encrypted_message enc_msg;

static double get_server_time (struct tgl_dc *DC) {
if (!DC->server_time_udelta) {
DC->server_time_udelta = get_utime (CLOCK_REALTIME) - get_utime (CLOCK_MONOTONIC);
}
//if (!DC->server_time_udelta) {
// DC->server_time_udelta = get_utime (CLOCK_REALTIME) - get_utime (CLOCK_MONOTONIC);
//}
return get_utime (CLOCK_MONOTONIC) + DC->server_time_udelta;
}

Expand Down Expand Up @@ -756,7 +768,6 @@ long long tglmp_encrypt_send_message (struct tgl_state *TLS, struct connection *
assert (l > 0);
vlogprintf (E_DEBUG, "Sending message to DC%d: %s:%d with key_id=%lld\n", DC->id, DC->ip, DC->port, enc_msg.auth_key_id);
rpc_send_message (TLS, c, &enc_msg, l + UNENCSZ);


return S->last_msg_id;
}
Expand Down Expand Up @@ -814,7 +825,7 @@ static int work_new_session_created (struct tgl_state *TLS, struct connection *c
fetch_long (); // first message id
fetch_long (); // unique_id
TLS->net_methods->get_dc (c)->server_salt = fetch_long ();
if (TLS->started && !(TLS->locks & TGL_LOCK_DIFF)) {
if (TLS->started && !(TLS->locks & TGL_LOCK_DIFF) && TLS->DC_working->has_auth) {
tgl_do_get_difference (TLS, 0, 0, 0);
}
return 0;
Expand All @@ -840,11 +851,10 @@ static int work_rpc_result (struct tgl_state *TLS, struct connection *c, long lo
long long id = fetch_long ();
int op = prefetch_int ();
if (op == CODE_rpc_error) {
tglq_query_error (TLS, id);
return tglq_query_error (TLS, id);
} else {
tglq_query_result (TLS, id);
return tglq_query_result (TLS, id);
}
return 0;
}

#define MAX_PACKED_SIZE (1 << 24)
Expand Down Expand Up @@ -983,6 +993,7 @@ static void fail_connection (struct tgl_state *TLS, struct connection *c) {
}

static void fail_session (struct tgl_state *TLS, struct tgl_session *S) {
vlogprintf (E_NOTICE, "failing session %lld\n", S->session_id);
struct tgl_dc *DC = S->dc;
tgls_free_session (TLS, S);
DC->sessions[0] = NULL;
Expand Down Expand Up @@ -1110,6 +1121,9 @@ static int rpc_execute (struct tgl_state *TLS, struct connection *c, int op, int
#endif
int o = DC->state;
//if (DC->flags & 1) { o = st_authorized;}
if (o != st_authorized) {
vlogprintf (E_DEBUG, "%s: state = %d\n", __func__, o);
}
switch (o) {
case st_reqpq_sent:
process_respq_answer (TLS, c, Response/* + 8*/, Response_len/* - 12*/, 0);
Expand Down Expand Up @@ -1157,7 +1171,7 @@ static void mpc_on_get_config (struct tgl_state *TLS, void *extra, int success)
}

static int tc_becomes_ready (struct tgl_state *TLS, struct connection *c) {
vlogprintf (E_DEBUG, "outbound rpc connection from dc #%d becomed ready\n", TLS->net_methods->get_dc(c)->id);
vlogprintf (E_NOTICE, "outbound rpc connection from dc #%d becomed ready\n", TLS->net_methods->get_dc(c)->id);
//char byte = 0xef;
//assert (TLS->net_methods->write_out (c, &byte, 1) == 1);
//TLS->net_methods->flush_out (c);
Expand All @@ -1176,8 +1190,13 @@ static int tc_becomes_ready (struct tgl_state *TLS, struct connection *c) {
break;
case st_authorized:
if (!(DC->flags & 2)) {
assert (!DC->temp_auth_key_id);
create_temp_auth_key (TLS, c);
assert (TLS->enable_pfs);
if (!DC->temp_auth_key_id) {
assert (!DC->temp_auth_key_id);
create_temp_auth_key (TLS, c);
} else {
bind_temp_auth_key (TLS, c);
}
} else if (!(DC->flags & 4)) {
tgl_do_help_get_config_dc (TLS, DC, mpc_on_get_config, DC);
}
Expand Down
73 changes: 58 additions & 15 deletions queries.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,14 +121,18 @@ void tglq_regen_query (struct tgl_state *TLS, long long id) {
struct query *q = tglq_query_get (TLS, id);
if (!q) { return; }
q->flags &= ~QUERY_ACK_RECEIVED;

q->session_id = 0;

if (!(q->session->dc->flags & 4) && !(q->flags & QUERY_FORCE_SEND)) {
q->session_id = 0;
}
vlogprintf (E_NOTICE, "regen query %lld\n", id);
TLS->timer_methods->insert (q->ev, 0.001);
}

void tglq_query_restart (struct tgl_state *TLS, long long id) {
struct query *q = tglq_query_get (TLS, id);
if (q) {
vlogprintf (E_NOTICE, "restarting query %lld\n", id);
TLS->timer_methods->remove (q->ev);
alarm_query (TLS, q);
}
Expand Down Expand Up @@ -196,7 +200,21 @@ void tglq_query_ack (struct tgl_state *TLS, long long id) {
}
}

void tglq_query_error (struct tgl_state *TLS, long long id) {
void tglq_query_delete (struct tgl_state *TLS, long long id) {
struct query *q = tglq_query_get (TLS, id);
if (!q) {
return;
}
if (!(q->flags & QUERY_ACK_RECEIVED)) {
TLS->timer_methods->remove (q->ev);
}
TLS->queries_tree = tree_delete_query (TLS->queries_tree, q);
tfree (q->data, q->data_len * 4);
TLS->timer_methods->free (q->ev);
TLS->active_queries --;
}

int tglq_query_error (struct tgl_state *TLS, long long id) {
assert (fetch_int () == CODE_rpc_error);
int error_code = fetch_int ();
int error_len = prefetch_strlen ();
Expand Down Expand Up @@ -237,7 +255,11 @@ void tglq_query_error (struct tgl_state *TLS, long long id) {
if (i > 0 && i < TGL_MAX_DC_NUM) {
bl_do_set_working_dc (TLS, i);
q->flags &= ~QUERY_ACK_RECEIVED;
q->session_id = 0;
//q->session_id = 0;
struct tgl_dc *DC = q->DC;
if (!(DC->flags & 4) && !(q->flags & QUERY_FORCE_SEND)) {
q->session_id = 0;
}
q->DC = TLS->DC_working;
TLS->timer_methods->insert (q->ev, 0);
error_handled = 1;
Expand Down Expand Up @@ -278,7 +300,10 @@ void tglq_query_error (struct tgl_state *TLS, long long id) {
}
q->flags &= ~QUERY_ACK_RECEIVED;
TLS->timer_methods->insert (q->ev, wait);
q->session_id = 0;
struct tgl_dc *DC = q->DC;
if (!(DC->flags & 4) && !(q->flags & QUERY_FORCE_SEND)) {
q->session_id = 0;
}
error_handled = 1;
}
break;
Expand All @@ -297,14 +322,21 @@ void tglq_query_error (struct tgl_state *TLS, long long id) {
tfree (q->data, q->data_len * 4);
TLS->timer_methods->free (q->ev);
}

if (res == -11) {
TLS->active_queries --;
return -1;

}
}
TLS->active_queries --;
return 0;
}

#define MAX_PACKED_SIZE (1 << 24)
static int packed_buffer[MAX_PACKED_SIZE / 4];

void tglq_query_result (struct tgl_state *TLS, long long id) {
int tglq_query_result (struct tgl_state *TLS, long long id) {
vlogprintf (E_DEBUG, "result for query #%lld. Size %ld bytes\n", id, (long)4 * (in_end - in_ptr));
int op = prefetch_int ();
int *end = 0;
Expand Down Expand Up @@ -354,6 +386,7 @@ void tglq_query_result (struct tgl_state *TLS, long long id) {
in_end = eend;
}
TLS->active_queries --;
return 0;
}

static void out_random (int n) {
Expand Down Expand Up @@ -561,8 +594,7 @@ static int sign_in_on_answer (struct tgl_state *TLS, struct query *q) {

struct tgl_user *U = tglf_fetch_alloc_user (TLS);

TLS->DC_working->has_auth = 1;

//TLS->DC_working->has_auth = 1;
bl_do_dc_signed (TLS, TLS->DC_working->id);

if (q->callback) {
Expand Down Expand Up @@ -2713,13 +2745,16 @@ static struct query_methods import_auth_methods = {
.type = TYPE_TO_PARAM(auth_authorization)
};

static int export_auth_on_answer (struct tgl_state *TLS, struct query *q) {
static int export_auth_on_answer (struct tgl_state *TLS, struct query *q) {
assert (fetch_int () == (int)CODE_auth_exported_authorization);
bl_do_set_our_id (TLS, fetch_int ());
int l = prefetch_strlen ();
char *s = talloc (l);
memcpy (s, fetch_str (l), l);


//struct tgl_dc *DC = q->extra;
//vlogprintf (0, "exported auth (to %d)\n", DC->id);

clear_packet ();
tgl_do_insert_header (TLS);
out_int (CODE_auth_import_authorization);
Expand Down Expand Up @@ -3966,16 +4001,24 @@ static void set_flag_4 (struct tgl_state *TLS, void *_D, int success) {

static int send_bind_temp_on_answer (struct tgl_state *TLS, struct query *q) {
assert (fetch_int () == (int)CODE_bool_true);
struct tgl_dc *D = q->extra;
D->flags |= 2;
tgl_do_help_get_config_dc (TLS, D, set_flag_4, D);
vlogprintf (E_DEBUG, "Bind successful in dc %d\n", D->id);
struct tgl_dc *DC = q->extra;
DC->flags |= 2;
tgl_do_help_get_config_dc (TLS, DC, set_flag_4, DC);
vlogprintf (E_DEBUG, "Bind successful in dc %d\n", DC->id);
return 0;
}

static int send_bind_on_error (struct tgl_state *TLS, struct query *q, int error_code, int l, char *error) {
vlogprintf (E_WARNING, "bind: error %d: %.*s\n", error_code, l, error);
if (error_code == 400) {
return -11;
}
return 0;
}

static struct query_methods send_bind_temp_methods = {
.on_answer = send_bind_temp_on_answer,
//.on_error = fail_on_error,
.on_error = send_bind_on_error,
.type = TYPE_TO_PARAM (bool)
};

Expand Down
5 changes: 3 additions & 2 deletions queries.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ struct query {

struct query *tglq_send_query (struct tgl_state *TLS, struct tgl_dc *DC, int len, void *data, struct query_methods *methods, void *extra, void *callback, void *callback_extra);
void tglq_query_ack (struct tgl_state *TLS, long long id);
void tglq_query_error (struct tgl_state *TLS, long long id);
void tglq_query_result (struct tgl_state *TLS, long long id);
int tglq_query_error (struct tgl_state *TLS, long long id);
int tglq_query_result (struct tgl_state *TLS, long long id);
void tglq_query_restart (struct tgl_state *TLS, long long id);

//double next_timer_in (void);
Expand All @@ -75,6 +75,7 @@ void tgl_do_commit_exchange (struct tgl_state *TLS, struct tgl_secret_chat *E, u
void tgl_do_abort_exchange (struct tgl_state *TLS, struct tgl_secret_chat *E);

void tglq_regen_query (struct tgl_state *TLS, long long id);
void tglq_query_delete (struct tgl_state *TLS, long long id);
// For binlog

//int get_dh_config_on_answer (struct query *q);
Expand Down
1 change: 1 addition & 0 deletions tgl-layout.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ struct tgl_dc {
char server_nonce[256];
long long auth_key_id;
long long temp_auth_key_id;
long long temp_auth_key_bind_query_id;

long long server_salt;
struct tgl_timer *ev;
Expand Down

0 comments on commit 0205b66

Please sign in to comment.