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;
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) {
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 got_config (void) {
......@@ -491,25 +501,12 @@ int loop (void) {
lua_binlog_end ();
#endif
update_prompt ();
if (!tgl_authorized_dc (tgl_state.DC_working)) {
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);
}
net_loop (0, all_authorized);
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])) {
cur_a_dc = tgl_state.DC_list[i];
tgl_dc_authorize (cur_a_dc);
net_loop (0, is_authorized);
assert (0);
}
if (!tgl_signed_dc (tgl_state.DC_working)) {
......@@ -610,7 +607,7 @@ int loop (void) {
assert (tgl_signed_dc (tgl_state.DC_list[i]));
}
write_auth_file ();
fflush (stdout);
fflush (stderr);
......
......@@ -477,6 +477,7 @@ enum lua_query_type {
lq_load_document_thumb,
lq_delete_msg,
lq_restore_msg,
lq_accept_secret_chat
};
struct lua_query_extra {
......@@ -1000,6 +1001,10 @@ void lua_do_all (void) {
tgl_do_delete_msg ((long)lua_ptr[p + 1], lua_empty_cb, lua_ptr[p]);
p += 2;
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_restore_msg,
......@@ -1076,6 +1081,7 @@ struct lua_function functions[] = {
{"create_group_chat", lq_create_group_chat, { lfp_user, lfp_string, lfp_none }},
{"delete_msg", lq_delete_msg, { lfp_msg, 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}}
};
......
......@@ -330,6 +330,13 @@ void parse_config (void) {
strcpy (buf + l, "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) {
parse_config_val (&conf, &binlog_file_name, "binlog", BINLOG_FILE, config_directory);
......@@ -534,7 +541,7 @@ int main (int argc, char **argv) {
running_for_first_time ();
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");
......
This diff is collapsed.
......@@ -45,11 +45,12 @@ struct tgl_dc;
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);
int tglmp_check_g (unsigned char p[256], BIGNUM *g);
int tglmp_check_DH_params (BIGNUM *p, int g);
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 tglmp_on_start (void);
......
......@@ -39,6 +39,7 @@
#define CODE_resPQ 0x05162463
#define CODE_req_DH_params 0xd712e4be
#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_params_fail 0x79cb045d
#define CODE_server_DH_params_ok 0xd0e8075c
......@@ -48,6 +49,8 @@
#define CODE_dh_gen_retry 0x46dc1fb9
#define CODE_dh_gen_fail 0xa69dae02
#define CODE_bind_auth_key_inner 0x75a3f765
/* service messages */
#define CODE_rpc_result 0xf35c6d01
#define CODE_rpc_error 0x2144ca19
......
......@@ -101,15 +101,23 @@ static int alarm_query (struct query *q) {
return 0;
}*/
clear_packet ();
out_int (CODE_msg_container);
out_int (1);
out_long (q->msg_id);
out_int (q->seq_no);
out_int (4 * q->data_len);
out_ints (q->data, q->data_len);
if (q->session->session_id == q->session_id) {
clear_packet ();
out_int (CODE_msg_container);
out_int (1);
out_long (q->msg_id);
out_int (q->seq_no);
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;
}
......@@ -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->auth_key_id);
if (!DC->sessions[0]) {
......@@ -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 = talloc (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->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);
q->methods = methods;
q->DC = DC;
q->flags = flags & QUERY_FORCE_SEND;
if (queries_tree) {
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
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) {
fprintf (stderr, "error #%d: %.*s\n", error_code, l, error);
assert (0);
......@@ -364,6 +381,13 @@ void tgl_do_help_get_config (void (*callback)(void *, int), void *callback_extra
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);
}
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 */
......@@ -2821,7 +2845,8 @@ static int get_difference_on_answer (struct query *q UU) {
bl_do_set_date (fetch_int ());
bl_do_set_seq (fetch_int ());
//difference_got = 1;
vlogprintf (E_DEBUG, "Empty difference. Seq = %d\n", tgl_state.seq);
if (q->callback) {
((void (*)(void *, int))q->callback) (q->callback_extra, 1);
}
......@@ -2862,6 +2887,7 @@ static int get_difference_on_answer (struct query *q UU) {
bl_do_set_date (fetch_int ());
if (x == CODE_updates_difference) {
bl_do_set_seq (fetch_int ());
vlogprintf (E_DEBUG, "Difference end. New seq = %d\n", tgl_state.seq);
} else {
fetch_int ();
}
......@@ -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) {
fetch_bool ();
......
......@@ -27,6 +27,7 @@
struct event;
#define QUERY_ACK_RECEIVED 1
#define QUERY_FORCE_SEND 2
struct query;
struct query_methods {
......@@ -41,6 +42,7 @@ struct query {
int data_len;
int flags;
int seq_no;
long long session_id;
void *data;
struct query_methods *methods;
struct event *ev;
......@@ -65,6 +67,7 @@ void work_timers (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
......
......@@ -46,6 +46,10 @@ enum tgl_dc_state {
st_reqpq_sent,
st_reqdh_sent,
st_client_dh_sent,
st_init_temp,
st_reqpq_sent_temp,
st_reqdh_sent_temp,
st_client_dh_sent_temp,
st_authorized,
st_error
};
......@@ -71,8 +75,15 @@ struct tgl_dc {
char *user;
struct tgl_session *sessions[MAX_DC_SESSIONS];
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 temp_auth_key_id;
long long server_salt;
struct event *ev;
int server_time_delta;
double server_time_udelta;
......
......@@ -69,12 +69,16 @@ void tgl_init (void) {
if (!tgl_state.callback.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 ();
}
int tgl_authorized_dc (struct tgl_dc *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) {
......
......@@ -136,6 +136,8 @@ struct tgl_state {
struct tgl_dc *DC_working;
int max_dc_num;
int dc_working_num;
int enable_pfs;
int temp_key_expire_time;
long long cur_uploading_bytes;
long long cur_uploaded_bytes;
......@@ -219,6 +221,10 @@ static inline void tgl_set_verbosity (int 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) {
tgl_state.test_mode ++;
}
......@@ -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_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_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]);
......
......@@ -427,6 +427,7 @@ static int do_skip_seq (int seq) {
}
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, "lock_diff = %s\n", (tgl_state.locks & TGL_LOCK_DIFF) ? "true" : "false");
tgl_do_get_difference (0, 0, 0);
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