tgl_peer_t *find_peer_by_name (struct tgl_state *TLS, const char *who) { tgl_peer_t *peer = tgl_peer_get (TLS, TGL_MK_USER(atoi (who))); if (peer) { return peer; } peer = tgl_peer_get (TLS, TGL_MK_CHAT(atoi(who))); if (peer) { return peer; } peer = tgl_peer_get (TLS, TGL_MK_ENCR_CHAT(atoi(who))); if (peer) { return peer; } return NULL; }
tgl_peer_id_t tgp_blist_buddy_get_id (PurpleBuddy *buddy) { int id = purple_blist_node_get_int (&buddy->node, TGP_BUDDY_KEY_PEER_ID), type = purple_blist_node_get_int (&buddy->node, TGP_BUDDY_KEY_PEER_TYPE); if (type == TGL_PEER_USER) { return TGL_MK_USER (id); } else if (type == TGL_PEER_ENCR_CHAT) { return TGL_MK_ENCR_CHAT (id); } else { assert (FALSE); } }
void read_secret_chat (int fd, int v) { int id, l, user_id, admin_id, date, ttl, layer, state; long long access_hash, key_fingerprint; static char s[1000]; static unsigned char key[256]; static unsigned char sha[20]; assert (read (fd, &id, 4) == 4); //assert (read (fd, &flags, 4) == 4); assert (read (fd, &l, 4) == 4); assert (l > 0 && l < 1000); assert (read (fd, s, l) == l); assert (read (fd, &user_id, 4) == 4); assert (read (fd, &admin_id, 4) == 4); assert (read (fd, &date, 4) == 4); assert (read (fd, &ttl, 4) == 4); assert (read (fd, &layer, 4) == 4); assert (read (fd, &access_hash, 8) == 8); assert (read (fd, &state, 4) == 4); assert (read (fd, &key_fingerprint, 8) == 8); assert (read (fd, &key, 256) == 256); if (v >= 2) { assert (read (fd, sha, 20) == 20); } int in_seq_no = 0, out_seq_no = 0, last_in_seq_no = 0; if (v >= 1) { assert (read (fd, &in_seq_no, 4) == 4); assert (read (fd, &last_in_seq_no, 4) == 4); assert (read (fd, &out_seq_no, 4) == 4); } bl_do_encr_chat_create (TLS, id, user_id, admin_id, s, l); struct tgl_secret_chat *P = (void *)tgl_peer_get (TLS, TGL_MK_ENCR_CHAT (id)); assert (P && (P->flags & FLAG_CREATED)); bl_do_encr_chat_set_date (TLS, P, date); bl_do_encr_chat_set_ttl (TLS, P, ttl); bl_do_encr_chat_set_layer (TLS ,P, layer); bl_do_encr_chat_set_access_hash (TLS, P, access_hash); bl_do_encr_chat_set_state (TLS, P, state); bl_do_encr_chat_set_key (TLS, P, key, key_fingerprint); if (v >= 2) { bl_do_encr_chat_set_sha (TLS, P, sha); } else { SHA1 ((void *)key, 256, sha); bl_do_encr_chat_set_sha (TLS, P, sha); } if (v >= 1) { bl_do_encr_chat_set_seq (TLS, P, in_seq_no, last_in_seq_no, out_seq_no); } }
void tgl_do_send_create_encr_chat (struct tgl_state *TLS, void *x, unsigned char *random, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_secret_chat *E), void *callback_extra) { int user_id = (long)x; int i; unsigned char random_here[256]; tglt_secure_random (random_here, 256); for (i = 0; i < 256; i++) { random[i] ^= random_here[i]; } BIGNUM *a = BN_bin2bn (random, 256, 0); ensure_ptr (a); BIGNUM *p = BN_bin2bn (TLS->encr_prime, 256, 0); ensure_ptr (p); BIGNUM *g = BN_new (); ensure_ptr (g); ensure (BN_set_word (g, TLS->encr_root)); BIGNUM *r = BN_new (); ensure_ptr (r); ensure (BN_mod_exp (r, g, a, p, TLS->BN_ctx)); BN_clear_free (a); static char g_a[256]; memset (g_a, 0, 256); BN_bn2bin (r, (void *)(g_a + (256 - BN_num_bytes (r)))); int t = lrand48 (); while (tgl_peer_get (TLS, TGL_MK_ENCR_CHAT (t))) { t = lrand48 (); } //bl_do_encr_chat_init (TLS, t, user_id, (void *)random, (void *)g_a); int state = sc_waiting; bl_do_encr_chat_new (TLS, t, NULL, NULL, &TLS->our_id, &user_id, random, NULL, NULL, &state, NULL, NULL, NULL, NULL, NULL, NULL, TGLPF_CREATE | TGLPF_CREATED); tgl_peer_t *_E = tgl_peer_get (TLS, TGL_MK_ENCR_CHAT (t)); assert (_E); struct tgl_secret_chat *E = &_E->encr_chat; clear_packet (); out_int (CODE_messages_request_encryption); tgl_peer_t *U = tgl_peer_get (TLS, TGL_MK_USER (E->user_id)); assert (U); if (U && U->user.access_hash) { out_int (CODE_input_user_foreign); out_int (E->user_id); out_long (U->user.access_hash); } else { out_int (CODE_input_user_contact); out_int (E->user_id); } out_int (tgl_get_peer_id (E->id)); out_cstring (g_a, 256); //write_secret_chat_file (); BN_clear_free (g); BN_clear_free (p); BN_clear_free (r); tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &send_encr_request_methods, E, callback, callback_extra); }
void bl_do_encr_chat (struct tgl_state *TLS, int id, long long *access_hash, int *date, int *admin, int *user_id, void *key, void *g_key, void *first_key_id, int *state, int *ttl, int *layer, int *in_seq_no, int *last_in_seq_no, int *out_seq_no, long long *key_fingerprint, int flags, const char *print_name, int print_name_len) /* {{{ */ { tgl_peer_t *_U = tgl_peer_get (TLS, TGL_MK_ENCR_CHAT (id)); unsigned updates = 0; if ((flags & TGLPF_CREATE) && (flags != TGL_FLAGS_UNCHANGED)) { if (!_U) { _U = talloc0 (sizeof (*_U)); _U->id = TGL_MK_ENCR_CHAT (id); tglp_insert_encrypted_chat (TLS, _U); } else { assert (!(_U->flags & TGLPF_CREATED)); } updates |= TGL_UPDATE_CREATED; } else { assert (_U->flags & TGLPF_CREATED); } struct tgl_secret_chat *U = (void *)_U; if (flags == TGL_FLAGS_UNCHANGED) { flags = U->flags; } flags &= TGLECF_TYPE_MASK; if ((flags & TGLECF_TYPE_MASK) != (U->flags & TGLECF_TYPE_MASK)) { updates |= TGL_UPDATE_FLAGS; } U->flags = (U->flags & ~TGLECF_TYPE_MASK) | flags; if (access_hash && *access_hash != U->access_hash) { U->access_hash = *access_hash; U->id.access_hash = *access_hash; updates |= TGL_UPDATE_ACCESS_HASH; } if (date) { U->date = *date; } if (admin) { U->admin_id = *admin; } if (user_id) { U->user_id = *user_id; } if (key_fingerprint) { U->key_fingerprint = *key_fingerprint; } if (in_seq_no) { U->in_seq_no = *in_seq_no; } if (out_seq_no) { U->out_seq_no = *out_seq_no; } if (last_in_seq_no) { U->last_in_seq_no = *last_in_seq_no; } tgl_peer_t *Us = tgl_peer_get (TLS, TGL_MK_USER (U->user_id)); if (!U->print_name) { if (print_name) { U->print_name = tstrndup (print_name, print_name_len); } else { if (Us) { U->print_name = TLS->callback.create_print_name (TLS, TGL_MK_ENCR_CHAT (id), "!", Us->user.first_name, Us->user.last_name, 0); } else { static char buf[100]; tsnprintf (buf, 99, "user#%d", U->user_id); U->print_name = TLS->callback.create_print_name (TLS, TGL_MK_ENCR_CHAT (id), "!", buf, 0, 0); } tglp_peer_insert_name (TLS, (void *)U); } } if (g_key) { if (!U->g_key) { U->g_key = talloc (256); } memcpy (U->g_key, g_key, 256); } if (key) { memcpy (U->key, key, 256); } if (first_key_id) { memcpy (U->first_key_sha, first_key_id, 20); } if (state) { if (U->state == sc_waiting && *state == sc_ok) { tgl_do_create_keys_end (TLS, U); } if ((int)U->state != *state) { switch (*state) { case sc_request: updates |= TGL_UPDATE_REQUESTED; break; case sc_ok: updates |= TGL_UPDATE_WORKING; vlogprintf (E_WARNING, "Secret chat in ok state\n"); break; default: break; } } U->state = *state; } if (TLS->callback.secret_chat_update && updates) { TLS->callback.secret_chat_update (TLS, U, updates); } }