Commit e179f25f authored by vvaltman's avatar vvaltman

Added PFS support. Parallel auth_key generation. Small bug fixes

parent bc5a7e67
decryptedMessageMediaVideoL12#4cee6ef3 thumb:bytes thumb_w:int thumb_h:int duration:int w:int h:int size:int key:bytes iv:bytes = DecryptedMessageMedia; decryptedMessageMediaVideoL12#4cee6ef3 thumb:bytes thumb_w:int thumb_h:int duration:int w:int h:int size:int key:bytes iv:bytes = DecryptedMessageMedia;
decryptedMessageMediaAudioL12#6080758f duration:int size:int key:bytes iv:bytes = DecryptedMessageMedia; decryptedMessageMediaAudioL12#6080758f duration:int size:int key:bytes iv:bytes = DecryptedMessageMedia;
auth.bindTempAuthKey perm_auth_key_id:long nonce:long expires_at:int encrypted_message:string = Bool;
...@@ -226,6 +226,16 @@ int is_authorized (void) { ...@@ -226,6 +226,16 @@ int is_authorized (void) {
return tgl_authorized_dc (cur_a_dc); return tgl_authorized_dc (cur_a_dc);
} }
int all_authorized (void) {
int i;
for (i = 0; i <= tgl_state.max_dc_num; i++) if (tgl_state.DC_list[i]) {
if (!tgl_authorized_dc (tgl_state.DC_list[i])) {
return 0;
}
}
return 1;
}
int config_got; int config_got;
int got_config (void) { int got_config (void) {
...@@ -491,25 +501,12 @@ int loop (void) { ...@@ -491,25 +501,12 @@ int loop (void) {
lua_binlog_end (); lua_binlog_end ();
#endif #endif
update_prompt (); update_prompt ();
if (!tgl_authorized_dc (tgl_state.DC_working)) { net_loop (0, all_authorized);
cur_a_dc = tgl_state.DC_working;
tgl_dc_authorize (tgl_state.DC_working);
net_loop (0, is_authorized);
}
tgl_do_help_get_config (on_get_config, 0);
net_loop (0, got_config);
if (verbosity >= E_DEBUG) {
logprintf ("DC_info: %d new DC got\n", new_dc_num);
}
int i; int i;
for (i = 0; i <= tgl_state.max_dc_num; i++) if (tgl_state.DC_list[i] && !tgl_authorized_dc (tgl_state.DC_list[i])) { for (i = 0; i <= tgl_state.max_dc_num; i++) if (tgl_state.DC_list[i] && !tgl_authorized_dc (tgl_state.DC_list[i])) {
cur_a_dc = tgl_state.DC_list[i]; assert (0);
tgl_dc_authorize (cur_a_dc);
net_loop (0, is_authorized);
} }
if (!tgl_signed_dc (tgl_state.DC_working)) { if (!tgl_signed_dc (tgl_state.DC_working)) {
...@@ -610,7 +607,7 @@ int loop (void) { ...@@ -610,7 +607,7 @@ int loop (void) {
assert (tgl_signed_dc (tgl_state.DC_list[i])); assert (tgl_signed_dc (tgl_state.DC_list[i]));
} }
write_auth_file (); write_auth_file ();
fflush (stdout); fflush (stdout);
fflush (stderr); fflush (stderr);
......
...@@ -477,6 +477,7 @@ enum lua_query_type { ...@@ -477,6 +477,7 @@ enum lua_query_type {
lq_load_document_thumb, lq_load_document_thumb,
lq_delete_msg, lq_delete_msg,
lq_restore_msg, lq_restore_msg,
lq_accept_secret_chat
}; };
struct lua_query_extra { struct lua_query_extra {
...@@ -1000,6 +1001,10 @@ void lua_do_all (void) { ...@@ -1000,6 +1001,10 @@ void lua_do_all (void) {
tgl_do_delete_msg ((long)lua_ptr[p + 1], lua_empty_cb, lua_ptr[p]); tgl_do_delete_msg ((long)lua_ptr[p + 1], lua_empty_cb, lua_ptr[p]);
p += 2; p += 2;
break; break;
case lq_accept_secret_chat:
tgl_do_accept_encr_chat_request (lua_ptr[p + 1], lua_secret_chat_cb, lua_ptr[p]);
p += 2;
break;
/* /*
lq_delete_msg, lq_delete_msg,
lq_restore_msg, lq_restore_msg,
...@@ -1076,6 +1081,7 @@ struct lua_function functions[] = { ...@@ -1076,6 +1081,7 @@ struct lua_function functions[] = {
{"create_group_chat", lq_create_group_chat, { lfp_user, lfp_string, lfp_none }}, {"create_group_chat", lq_create_group_chat, { lfp_user, lfp_string, lfp_none }},
{"delete_msg", lq_delete_msg, { lfp_msg, lfp_none }}, {"delete_msg", lq_delete_msg, { lfp_msg, lfp_none }},
{"restore_msg", lq_restore_msg, { lfp_positive_number, lfp_none }}, {"restore_msg", lq_restore_msg, { lfp_positive_number, lfp_none }},
{"accept_secret_chat", lq_accept_secret_chat, { lfp_secret_chat, lfp_none }},
{ 0, 0, { lfp_none}} { 0, 0, { lfp_none}}
}; };
......
...@@ -330,6 +330,13 @@ void parse_config (void) { ...@@ -330,6 +330,13 @@ void parse_config (void) {
strcpy (buf + l, "binlog_enabled"); strcpy (buf + l, "binlog_enabled");
config_lookup_bool (&conf, buf, &binlog_enabled); config_lookup_bool (&conf, buf, &binlog_enabled);
int pfs_enabled;
strcpy (buf + l, "pfs_enabled");
config_lookup_bool (&conf, buf, &pfs_enabled);
if (pfs_enabled) {
tgl_enable_pfs ();
}
if (binlog_enabled) { if (binlog_enabled) {
parse_config_val (&conf, &binlog_file_name, "binlog", BINLOG_FILE, config_directory); parse_config_val (&conf, &binlog_file_name, "binlog", BINLOG_FILE, config_directory);
...@@ -534,7 +541,7 @@ int main (int argc, char **argv) { ...@@ -534,7 +541,7 @@ int main (int argc, char **argv) {
running_for_first_time (); running_for_first_time ();
parse_config (); parse_config ();
tgl_set_rsa_key ("/etc/ " PROG_NAME "/server.pub"); tgl_set_rsa_key ("/etc/" PROG_NAME "/server.pub");
tgl_set_rsa_key ("tg-server.pub"); tgl_set_rsa_key ("tg-server.pub");
......
This diff is collapsed.
...@@ -45,11 +45,12 @@ struct tgl_dc; ...@@ -45,11 +45,12 @@ struct tgl_dc;
struct connection; struct connection;
long long tglmp_encrypt_send_message (struct connection *c, int *msg, int msg_ints, int useful); long long tglmp_encrypt_send_message (struct connection *c, int *msg, int msg_ints, int flags);
void tglmp_dc_create_session (struct tgl_dc *DC); void tglmp_dc_create_session (struct tgl_dc *DC);
int tglmp_check_g (unsigned char p[256], BIGNUM *g); int tglmp_check_g (unsigned char p[256], BIGNUM *g);
int tglmp_check_DH_params (BIGNUM *p, int g); int tglmp_check_DH_params (BIGNUM *p, int g);
struct tgl_dc *tglmp_alloc_dc (int id, char *ip, int port); struct tgl_dc *tglmp_alloc_dc (int id, char *ip, int port);
void tglmp_regenerate_temp_auth_key (struct tgl_dc *D);
void tgln_insert_msg_id (struct tgl_session *S, long long id); void tgln_insert_msg_id (struct tgl_session *S, long long id);
void tglmp_on_start (void); void tglmp_on_start (void);
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#define CODE_resPQ 0x05162463 #define CODE_resPQ 0x05162463
#define CODE_req_DH_params 0xd712e4be #define CODE_req_DH_params 0xd712e4be
#define CODE_p_q_inner_data 0x83c95aec #define CODE_p_q_inner_data 0x83c95aec
#define CODE_p_q_inner_data_temp 0x3c6a84d4
#define CODE_server_DH_inner_data 0xb5890dba #define CODE_server_DH_inner_data 0xb5890dba
#define CODE_server_DH_params_fail 0x79cb045d #define CODE_server_DH_params_fail 0x79cb045d
#define CODE_server_DH_params_ok 0xd0e8075c #define CODE_server_DH_params_ok 0xd0e8075c
...@@ -48,6 +49,8 @@ ...@@ -48,6 +49,8 @@
#define CODE_dh_gen_retry 0x46dc1fb9 #define CODE_dh_gen_retry 0x46dc1fb9
#define CODE_dh_gen_fail 0xa69dae02 #define CODE_dh_gen_fail 0xa69dae02
#define CODE_bind_auth_key_inner 0x75a3f765
/* service messages */ /* service messages */
#define CODE_rpc_result 0xf35c6d01 #define CODE_rpc_result 0xf35c6d01
#define CODE_rpc_error 0x2144ca19 #define CODE_rpc_error 0x2144ca19
......
...@@ -101,15 +101,23 @@ static int alarm_query (struct query *q) { ...@@ -101,15 +101,23 @@ static int alarm_query (struct query *q) {
return 0; return 0;
}*/ }*/
clear_packet (); if (q->session->session_id == q->session_id) {
out_int (CODE_msg_container); clear_packet ();
out_int (1); out_int (CODE_msg_container);
out_long (q->msg_id); out_int (1);
out_int (q->seq_no); out_long (q->msg_id);
out_int (4 * q->data_len); out_int (q->seq_no);
out_ints (q->data, q->data_len); out_int (4 * q->data_len);
out_ints (q->data, q->data_len);
tglmp_encrypt_send_message (q->session->c, packet_buffer, packet_ptr - packet_buffer, 0); tglmp_encrypt_send_message (q->session->c, packet_buffer, packet_ptr - packet_buffer, q->flags & QUERY_FORCE_SEND);
} else {
q->msg_id = tglmp_encrypt_send_message (q->session->c, q->data, q->data_len, (q->flags & QUERY_FORCE_SEND) | 1);
q->session_id = q->session->session_id;
if (!(q->session->dc->flags & 4) && !(q->flags & QUERY_FORCE_SEND)) {
q->session_id = 0;
}
}
return 0; return 0;
} }
...@@ -126,7 +134,7 @@ static void alarm_query_gateway (evutil_socket_t fd, short what, void *arg) { ...@@ -126,7 +134,7 @@ static void alarm_query_gateway (evutil_socket_t fd, short what, void *arg) {
} }
struct query *tglq_send_query (struct tgl_dc *DC, int ints, void *data, struct query_methods *methods, void *extra, void *callback, void *callback_extra) { struct query *tglq_send_query_ex (struct tgl_dc *DC, int ints, void *data, struct query_methods *methods, void *extra, void *callback, void *callback_extra, int flags) {
assert (DC); assert (DC);
assert (DC->auth_key_id); assert (DC->auth_key_id);
if (!DC->sessions[0]) { if (!DC->sessions[0]) {
...@@ -137,12 +145,17 @@ struct query *tglq_send_query (struct tgl_dc *DC, int ints, void *data, struct q ...@@ -137,12 +145,17 @@ struct query *tglq_send_query (struct tgl_dc *DC, int ints, void *data, struct q
q->data_len = ints; q->data_len = ints;
q->data = talloc (4 * ints); q->data = talloc (4 * ints);
memcpy (q->data, data, 4 * ints); memcpy (q->data, data, 4 * ints);
q->msg_id = tglmp_encrypt_send_message (DC->sessions[0]->c, data, ints, 1); q->msg_id = tglmp_encrypt_send_message (DC->sessions[0]->c, data, ints, 1 | (flags & QUERY_FORCE_SEND));
q->session = DC->sessions[0]; q->session = DC->sessions[0];
q->seq_no = DC->sessions[0]->seq_no - 1; q->seq_no = q->session->seq_no - 1;
q->session_id = q->session->session_id;
if (!(DC->flags & 4) && !(flags & QUERY_FORCE_SEND)) {
q->session_id = 0;
}
vlogprintf (E_DEBUG, "Msg_id is %lld %p\n", q->msg_id, q); vlogprintf (E_DEBUG, "Msg_id is %lld %p\n", q->msg_id, q);
q->methods = methods; q->methods = methods;
q->DC = DC; q->DC = DC;
q->flags = flags & QUERY_FORCE_SEND;
if (queries_tree) { if (queries_tree) {
vlogprintf (E_DEBUG + 2, "%lld %lld\n", q->msg_id, queries_tree->x->msg_id); vlogprintf (E_DEBUG + 2, "%lld %lld\n", q->msg_id, queries_tree->x->msg_id);
} }
...@@ -164,6 +177,10 @@ struct query *tglq_send_query (struct tgl_dc *DC, int ints, void *data, struct q ...@@ -164,6 +177,10 @@ struct query *tglq_send_query (struct tgl_dc *DC, int ints, void *data, struct q
return q; return q;
} }
struct query *tglq_send_query (struct tgl_dc *DC, int ints, void *data, struct query_methods *methods, void *extra, void *callback, void *callback_extra) {
return tglq_send_query_ex (DC, ints, data, methods, extra, callback, callback_extra, 0);
}
static int fail_on_error (struct query *q UU, int error_code UU, int l UU, char *error UU) { static int fail_on_error (struct query *q UU, int error_code UU, int l UU, char *error UU) {
fprintf (stderr, "error #%d: %.*s\n", error_code, l, error); fprintf (stderr, "error #%d: %.*s\n", error_code, l, error);
assert (0); assert (0);
...@@ -364,6 +381,13 @@ void tgl_do_help_get_config (void (*callback)(void *, int), void *callback_extra ...@@ -364,6 +381,13 @@ void tgl_do_help_get_config (void (*callback)(void *, int), void *callback_extra
out_int (CODE_help_get_config); out_int (CODE_help_get_config);
tglq_send_query (tgl_state.DC_working, packet_ptr - packet_buffer, packet_buffer, &help_get_config_methods, 0, callback, callback_extra); tglq_send_query (tgl_state.DC_working, packet_ptr - packet_buffer, packet_buffer, &help_get_config_methods, 0, callback, callback_extra);
} }
void tgl_do_help_get_config_dc (struct tgl_dc *D, void (*callback)(void *, int), void *callback_extra) {
clear_packet ();
tgl_do_insert_header ();
out_int (CODE_help_get_config);
tglq_send_query_ex (D, packet_ptr - packet_buffer, packet_buffer, &help_get_config_methods, 0, callback, callback_extra, 2);
}
/* }}} */ /* }}} */
/* {{{ Send code */ /* {{{ Send code */
...@@ -2821,7 +2845,8 @@ static int get_difference_on_answer (struct query *q UU) { ...@@ -2821,7 +2845,8 @@ static int get_difference_on_answer (struct query *q UU) {
bl_do_set_date (fetch_int ()); bl_do_set_date (fetch_int ());
bl_do_set_seq (fetch_int ()); bl_do_set_seq (fetch_int ());
//difference_got = 1; //difference_got = 1;
vlogprintf (E_DEBUG, "Empty difference. Seq = %d\n", tgl_state.seq);
if (q->callback) { if (q->callback) {
((void (*)(void *, int))q->callback) (q->callback_extra, 1); ((void (*)(void *, int))q->callback) (q->callback_extra, 1);
} }
...@@ -2862,6 +2887,7 @@ static int get_difference_on_answer (struct query *q UU) { ...@@ -2862,6 +2887,7 @@ static int get_difference_on_answer (struct query *q UU) {
bl_do_set_date (fetch_int ()); bl_do_set_date (fetch_int ());
if (x == CODE_updates_difference) { if (x == CODE_updates_difference) {
bl_do_set_seq (fetch_int ()); bl_do_set_seq (fetch_int ());
vlogprintf (E_DEBUG, "Difference end. New seq = %d\n", tgl_state.seq);
} else { } else {
fetch_int (); fetch_int ();
} }
...@@ -3172,6 +3198,41 @@ void tgl_do_restore_msg (long long id, void (*callback)(void *callback_extra, in ...@@ -3172,6 +3198,41 @@ void tgl_do_restore_msg (long long id, void (*callback)(void *callback_extra, in
} }
/* }}} */ /* }}} */
static void set_flag_4 (void *_D, int success) {
struct tgl_dc *D = _D;
assert (success);
D->flags |= 4;
static struct timeval ptimeout;
ptimeout.tv_sec = tgl_state.temp_key_expire_time * 0.9;
event_add (D->ev, &ptimeout);
}
static int send_bind_temp_on_answer (struct query *q UU) {
assert (fetch_int () == (int)CODE_bool_true);
struct tgl_dc *D = q->extra;
D->flags |= 2;
tgl_do_help_get_config_dc (D, set_flag_4, D);
vlogprintf (E_DEBUG, "Bind successful in dc %d\n", D->id);
return 0;
}
static struct query_methods send_bind_temp_methods = {
.on_answer = send_bind_temp_on_answer,
.type = TYPE_TO_PARAM (bool)
};
void tgl_do_send_bind_temp_key (struct tgl_dc *D, long long nonce, int expires_at, void *data, int len, long long msg_id) {
clear_packet ();
out_int (CODE_auth_bind_temp_auth_key);
out_long (D->auth_key_id);
out_long (nonce);
out_int (expires_at);
out_cstring (data, len);
struct query *q = tglq_send_query_ex (D, packet_ptr - packet_buffer, packet_buffer, &send_bind_temp_methods, D, 0, 0, 2);
assert (q->msg_id == msg_id);
}
static int update_status_on_answer (struct query *q UU) { static int update_status_on_answer (struct query *q UU) {
fetch_bool (); fetch_bool ();
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
struct event; struct event;
#define QUERY_ACK_RECEIVED 1 #define QUERY_ACK_RECEIVED 1
#define QUERY_FORCE_SEND 2
struct query; struct query;
struct query_methods { struct query_methods {
...@@ -41,6 +42,7 @@ struct query { ...@@ -41,6 +42,7 @@ struct query {
int data_len; int data_len;
int flags; int flags;
int seq_no; int seq_no;
long long session_id;
void *data; void *data;
struct query_methods *methods; struct query_methods *methods;
struct event *ev; struct event *ev;
...@@ -65,6 +67,7 @@ void work_timers (void); ...@@ -65,6 +67,7 @@ void work_timers (void);
double get_double_time (void); double get_double_time (void);
void tgl_do_send_bind_temp_key (struct tgl_dc *D, long long nonce, int expires_at, void *data, int len, long long msg_id);
// For binlog // For binlog
......
...@@ -46,6 +46,10 @@ enum tgl_dc_state { ...@@ -46,6 +46,10 @@ enum tgl_dc_state {
st_reqpq_sent, st_reqpq_sent,
st_reqdh_sent, st_reqdh_sent,
st_client_dh_sent, st_client_dh_sent,
st_init_temp,
st_reqpq_sent_temp,
st_reqdh_sent_temp,
st_client_dh_sent_temp,
st_authorized, st_authorized,
st_error st_error
}; };
...@@ -71,8 +75,15 @@ struct tgl_dc { ...@@ -71,8 +75,15 @@ struct tgl_dc {
char *user; char *user;
struct tgl_session *sessions[MAX_DC_SESSIONS]; struct tgl_session *sessions[MAX_DC_SESSIONS];
char auth_key[256]; char auth_key[256];
char temp_auth_key[256];
char nonce[256];
char new_nonce[256];
char server_nonce[256];
long long auth_key_id; long long auth_key_id;
long long temp_auth_key_id;
long long server_salt; long long server_salt;
struct event *ev;
int server_time_delta; int server_time_delta;
double server_time_udelta; double server_time_udelta;
......
...@@ -69,12 +69,16 @@ void tgl_init (void) { ...@@ -69,12 +69,16 @@ void tgl_init (void) {
if (!tgl_state.callback.create_print_name) { if (!tgl_state.callback.create_print_name) {
tgl_state.callback.create_print_name = tgls_default_create_print_name; tgl_state.callback.create_print_name = tgls_default_create_print_name;
} }
if (!tgl_state.temp_key_expire_time) {
tgl_state.temp_key_expire_time = 60; //100000;
}
tglmp_on_start (); tglmp_on_start ();
} }
int tgl_authorized_dc (struct tgl_dc *DC) { int tgl_authorized_dc (struct tgl_dc *DC) {
assert (DC); assert (DC);
return DC->auth_key_id; return (DC->flags & 4) != 0;//DC->auth_key_id;
} }
int tgl_signed_dc (struct tgl_dc *DC) { int tgl_signed_dc (struct tgl_dc *DC) {
......
...@@ -136,6 +136,8 @@ struct tgl_state { ...@@ -136,6 +136,8 @@ struct tgl_state {
struct tgl_dc *DC_working; struct tgl_dc *DC_working;
int max_dc_num; int max_dc_num;
int dc_working_num; int dc_working_num;
int enable_pfs;
int temp_key_expire_time;
long long cur_uploading_bytes; long long cur_uploading_bytes;
long long cur_uploaded_bytes; long long cur_uploaded_bytes;
...@@ -219,6 +221,10 @@ static inline void tgl_set_verbosity (int val) { ...@@ -219,6 +221,10 @@ static inline void tgl_set_verbosity (int val) {
tgl_state.verbosity = val; tgl_state.verbosity = val;
} }
static inline void tgl_enable_pfs (void) {
tgl_state.enable_pfs = 1;
}
static inline void tgl_set_test_mode (void) { static inline void tgl_set_test_mode (void) {
tgl_state.test_mode ++; tgl_state.test_mode ++;
} }
...@@ -267,6 +273,8 @@ void tgl_do_create_group_chat (tgl_peer_id_t id, char *chat_topic, void (*callba ...@@ -267,6 +273,8 @@ void tgl_do_create_group_chat (tgl_peer_id_t id, char *chat_topic, void (*callba
void tgl_do_delete_msg (long long id, void (*callback)(void *callback_extra, int success), void *callback_extra); void tgl_do_delete_msg (long long id, void (*callback)(void *callback_extra, int success), void *callback_extra);
void tgl_do_restore_msg (long long id, void (*callback)(void *callback_extra, int success), void *callback_extra); void tgl_do_restore_msg (long long id, void (*callback)(void *callback_extra, int success), void *callback_extra);
void tgl_do_update_status (int online, void (*callback)(void *callback_extra, int success), void *callback_extra); void tgl_do_update_status (int online, void (*callback)(void *callback_extra, int success), void *callback_extra);
void tgl_do_help_get_config_dc (struct tgl_dc *D, void (*callback)(void *, int), void *callback_extra);
void tgl_do_visualize_key (tgl_peer_id_t id, unsigned char buf[16]); void tgl_do_visualize_key (tgl_peer_id_t id, unsigned char buf[16]);
......
...@@ -427,6 +427,7 @@ static int do_skip_seq (int seq) { ...@@ -427,6 +427,7 @@ static int do_skip_seq (int seq) {
} }
if (seq > tgl_state.seq + 1) { if (seq > tgl_state.seq + 1) {
vlogprintf (E_NOTICE, "Hole in seq (seq = %d, cur_seq = %d)\n", seq, tgl_state.seq); vlogprintf (E_NOTICE, "Hole in seq (seq = %d, cur_seq = %d)\n", seq, tgl_state.seq);
//vlogprintf (E_NOTICE, "lock_diff = %s\n", (tgl_state.locks & TGL_LOCK_DIFF) ? "true" : "false");
tgl_do_get_difference (0, 0, 0); tgl_do_get_difference (0, 0, 0);
return -1; return -1;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment