Some code related to encrypted chat. Nothing works yet, but I believe it would work in the nearest future
This commit is contained in:
parent
5b8a4fdc60
commit
9dd3627afa
20
interface.c
20
interface.c
@ -919,6 +919,26 @@ void print_chat_name (peer_id_t id, peer_t *C) {
|
|||||||
pop_color ();
|
pop_color ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print_encr_chat_name (peer_id_t id, peer_t *C) {
|
||||||
|
push_color (COLOR_MAGENTA);
|
||||||
|
if (!C) {
|
||||||
|
printf ("encr_chat#%d", get_peer_id (id));
|
||||||
|
} else {
|
||||||
|
printf ("%s", C->print_name);
|
||||||
|
}
|
||||||
|
pop_color ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_encr_chat_name_full (peer_id_t id, peer_t *C) {
|
||||||
|
push_color (COLOR_MAGENTA);
|
||||||
|
if (!C) {
|
||||||
|
printf ("encr_chat#%d", get_peer_id (id));
|
||||||
|
} else {
|
||||||
|
printf ("%s", C->print_name);
|
||||||
|
}
|
||||||
|
pop_color ();
|
||||||
|
}
|
||||||
|
|
||||||
static char *monthes[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
|
static char *monthes[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
|
||||||
void print_date (long t) {
|
void print_date (long t) {
|
||||||
struct tm *tm = localtime (&t);
|
struct tm *tm = localtime (&t);
|
||||||
|
@ -45,6 +45,8 @@ union peer;
|
|||||||
void print_message (struct message *M);
|
void print_message (struct message *M);
|
||||||
void print_chat_name (peer_id_t id, union peer *C);
|
void print_chat_name (peer_id_t id, union peer *C);
|
||||||
void print_user_name (peer_id_t id, union peer *U);
|
void print_user_name (peer_id_t id, union peer *U);
|
||||||
|
void print_encr_chat_name_full (peer_id_t id, peer_t *C);
|
||||||
|
void print_encr_chat_name (peer_id_t id, peer_t *C);
|
||||||
//void print_media (struct message_media *M);
|
//void print_media (struct message_media *M);
|
||||||
void pop_color (void);
|
void pop_color (void);
|
||||||
void push_color (const char *color);
|
void push_color (const char *color);
|
||||||
|
@ -956,27 +956,79 @@ void work_update (struct connection *c UU, long long msg_id UU) {
|
|||||||
break;
|
break;
|
||||||
case CODE_update_new_encrypted_message:
|
case CODE_update_new_encrypted_message:
|
||||||
{
|
{
|
||||||
logprintf ("New encrypted message. Unsupported yet\n");
|
struct message *M = fetch_alloc_encrypted_message ();
|
||||||
|
unread_messages ++;
|
||||||
|
print_message (M);
|
||||||
|
update_prompt ();
|
||||||
|
fetch_qts ();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CODE_update_encryption:
|
case CODE_update_encryption:
|
||||||
{
|
{
|
||||||
logprintf ("New encrypted chat. Unsupported yet\n");
|
struct secret_chat *E = fetch_alloc_encrypted_chat ();
|
||||||
|
print_start ();
|
||||||
|
push_color (COLOR_YELLOW);
|
||||||
|
switch (E->state) {
|
||||||
|
case sc_none:
|
||||||
|
assert (0);
|
||||||
|
break;
|
||||||
|
case sc_waiting:
|
||||||
|
printf ("Encrypted chat ");
|
||||||
|
print_encr_chat_name (E->id, (void *)E);
|
||||||
|
printf (" is now in wait state\n");
|
||||||
|
break;
|
||||||
|
case sc_request:
|
||||||
|
printf ("Encrypted chat ");
|
||||||
|
print_encr_chat_name (E->id, (void *)E);
|
||||||
|
printf (" is now in request state. Sending request ok\n");
|
||||||
|
break;
|
||||||
|
case sc_ok:
|
||||||
|
printf ("Encrypted chat ");
|
||||||
|
print_encr_chat_name (E->id, (void *)E);
|
||||||
|
printf (" is now in ok state\n");
|
||||||
|
break;
|
||||||
|
case sc_deleted:
|
||||||
|
printf ("Encrypted chat ");
|
||||||
|
print_encr_chat_name (E->id, (void *)E);
|
||||||
|
printf (" is now in deleted state\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/*if (E->state == state_requested) {
|
||||||
|
do_accept_encr_chat_request (E);
|
||||||
|
}*/
|
||||||
|
fetch_int (); // date
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CODE_update_encrypted_chat_typing:
|
case CODE_update_encrypted_chat_typing:
|
||||||
{
|
{
|
||||||
logprintf ("Typing in encrypted chat. Unsupported yet\n");
|
peer_id_t id = MK_ENCR_CHAT (fetch_int ());
|
||||||
|
peer_t *P = user_chat_get (id);
|
||||||
|
print_start ();
|
||||||
|
push_color (COLOR_YELLOW);
|
||||||
|
if (P) {
|
||||||
|
printf ("User ");
|
||||||
|
peer_id_t user_id = MK_USER (P->encr_chat.user_id);
|
||||||
|
print_user_name (user_id, user_chat_get (user_id));
|
||||||
|
printf (" typing in secret chat ");
|
||||||
|
print_encr_chat_name (id, P);
|
||||||
|
printf ("\n");
|
||||||
|
} else {
|
||||||
|
printf ("Some user is typing in unknown secret chat\n");
|
||||||
|
}
|
||||||
|
pop_color ();
|
||||||
|
print_end ();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CODE_update_encrypted_messages_read:
|
case CODE_update_encrypted_messages_read:
|
||||||
{
|
{
|
||||||
fetch_int (); // chat_id
|
peer_id_t id = MK_ENCR_CHAT (fetch_int ()); // chat_id
|
||||||
fetch_int (); // max_date
|
fetch_int (); // max_date
|
||||||
fetch_int (); // date
|
fetch_int (); // date
|
||||||
print_start ();
|
print_start ();
|
||||||
push_color (COLOR_YELLOW);
|
push_color (COLOR_YELLOW);
|
||||||
printf ("Messages in encrypted chat mark read \n");
|
printf ("Messages in encrypted chat ");
|
||||||
|
print_encr_chat_name_full (id, user_chat_get (id));
|
||||||
|
printf (" marked read \n");
|
||||||
pop_color ();
|
pop_color ();
|
||||||
print_end ();
|
print_end ();
|
||||||
}
|
}
|
||||||
|
179
structures.c
179
structures.c
@ -192,6 +192,55 @@ void fetch_user (struct user *U) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fetch_encrypted_chat (struct secret_chat *U) {
|
||||||
|
unsigned x = fetch_int ();
|
||||||
|
assert (x == CODE_encrypted_chat_empty || x == CODE_encrypted_chat_waiting || x == CODE_encrypted_chat_requested || x == CODE_encrypted_chat || x == CODE_encrypted_chat_discarded);
|
||||||
|
U->id = MK_ENCR_CHAT (fetch_int ());
|
||||||
|
U->flags &= ~(FLAG_EMPTY | FLAG_DELETED);
|
||||||
|
if (x == CODE_encrypted_chat_empty) {
|
||||||
|
U->state = sc_none;
|
||||||
|
U->flags |= FLAG_EMPTY;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (x == CODE_encrypted_chat_discarded) {
|
||||||
|
U->state = sc_deleted;
|
||||||
|
U->flags |= FLAG_DELETED;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
U->access_hash = fetch_long ();
|
||||||
|
U->date = fetch_int ();
|
||||||
|
U->admin_id = fetch_int ();
|
||||||
|
U->user_id = fetch_int () + U->admin_id - our_id;
|
||||||
|
if (x == CODE_encrypted_chat_waiting) {
|
||||||
|
U->state = sc_waiting;
|
||||||
|
} else if (x == CODE_encrypted_chat_requested) {
|
||||||
|
U->state = sc_request;
|
||||||
|
if (!U->g_key) {
|
||||||
|
U->g_key = malloc (256);
|
||||||
|
}
|
||||||
|
if (!U->nonce) {
|
||||||
|
U->nonce = malloc (256);
|
||||||
|
}
|
||||||
|
assert (prefetch_strlen () == 256);
|
||||||
|
memcpy (U->g_key, fetch_str (256), 256);
|
||||||
|
assert (prefetch_strlen () == 256);
|
||||||
|
memcpy (U->nonce, fetch_str (256), 256);
|
||||||
|
} else {
|
||||||
|
U->state = sc_ok;
|
||||||
|
if (!U->g_key) {
|
||||||
|
U->g_key = malloc (256);
|
||||||
|
}
|
||||||
|
if (!U->nonce) {
|
||||||
|
U->nonce = malloc (256);
|
||||||
|
}
|
||||||
|
assert (prefetch_strlen () == 256);
|
||||||
|
memcpy (U->g_key, fetch_str (256), 256);
|
||||||
|
assert (prefetch_strlen () == 256);
|
||||||
|
memcpy (U->nonce, fetch_str (256), 256);
|
||||||
|
U->key_fingerprint = fetch_long ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void fetch_notify_settings (void);
|
void fetch_notify_settings (void);
|
||||||
void fetch_user_full (struct user *U) {
|
void fetch_user_full (struct user *U) {
|
||||||
assert (fetch_int () == CODE_user_full);
|
assert (fetch_int () == CODE_user_full);
|
||||||
@ -501,6 +550,87 @@ void fetch_message_media (struct message_media *M) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fetch_message_media_encrypted (struct message_media *M) {
|
||||||
|
memset (M, 0, sizeof (*M));
|
||||||
|
unsigned x = fetch_int ();
|
||||||
|
int l;
|
||||||
|
switch (M->type) {
|
||||||
|
case CODE_decrypted_message_media_empty:
|
||||||
|
M->type = CODE_message_media_empty;
|
||||||
|
break;
|
||||||
|
case CODE_decrypted_message_media_photo:
|
||||||
|
M->type = x;
|
||||||
|
l = prefetch_strlen ();
|
||||||
|
fetch_str (l); // thumb
|
||||||
|
fetch_int (); // thumb_w
|
||||||
|
fetch_int (); // thumb_h
|
||||||
|
M->encr_photo.w = fetch_int ();
|
||||||
|
M->encr_photo.h = fetch_int ();
|
||||||
|
M->encr_photo.size = fetch_int ();
|
||||||
|
l = fetch_int ();
|
||||||
|
assert (l > 0);
|
||||||
|
M->encr_photo.key = malloc (l);
|
||||||
|
memcpy (M->encr_photo.key, fetch_str (l), l);
|
||||||
|
|
||||||
|
l = fetch_int ();
|
||||||
|
assert (l > 0);
|
||||||
|
M->encr_photo.iv = malloc (l);
|
||||||
|
memcpy (M->encr_photo.iv, fetch_str (l), l);
|
||||||
|
break;
|
||||||
|
case CODE_decrypted_message_media_video:
|
||||||
|
M->type = x;
|
||||||
|
l = prefetch_strlen ();
|
||||||
|
fetch_str (l); // thumb
|
||||||
|
fetch_int (); // thumb_w
|
||||||
|
fetch_int (); // thumb_h
|
||||||
|
M->encr_video.w = fetch_int ();
|
||||||
|
M->encr_video.h = fetch_int ();
|
||||||
|
M->encr_video.size = fetch_int ();
|
||||||
|
M->encr_video.duration = fetch_int ();
|
||||||
|
l = fetch_int ();
|
||||||
|
assert (l > 0);
|
||||||
|
M->encr_video.key = malloc (l);
|
||||||
|
memcpy (M->encr_video.key, fetch_str (l), l);
|
||||||
|
|
||||||
|
l = fetch_int ();
|
||||||
|
assert (l > 0);
|
||||||
|
M->encr_video.iv = malloc (l);
|
||||||
|
memcpy (M->encr_video.iv, fetch_str (l), l);
|
||||||
|
break;
|
||||||
|
/* case CODE_decrypted_message_media_file:
|
||||||
|
M->type = x;
|
||||||
|
M->encr_file.filename = fetch_str_dup ();
|
||||||
|
l = prefetch_strlen ();
|
||||||
|
fetch_str (l); // thumb
|
||||||
|
l = fetch_int ();
|
||||||
|
assert (l > 0);
|
||||||
|
M->encr_file.key = malloc (l);
|
||||||
|
memcpy (M->encr_file.key, fetch_str (l), l);
|
||||||
|
|
||||||
|
l = fetch_int ();
|
||||||
|
assert (l > 0);
|
||||||
|
M->encr_file.iv = malloc (l);
|
||||||
|
memcpy (M->encr_file.iv, fetch_str (l), l);
|
||||||
|
break;
|
||||||
|
*/
|
||||||
|
case CODE_decrypted_message_media_geo_point:
|
||||||
|
M->geo.longitude = fetch_double ();
|
||||||
|
M->geo.latitude = fetch_double ();
|
||||||
|
M->type = CODE_message_media_geo;
|
||||||
|
break;
|
||||||
|
case CODE_decrypted_message_media_contact:
|
||||||
|
M->type = CODE_message_media_contact;
|
||||||
|
M->phone = fetch_str_dup ();
|
||||||
|
M->first_name = fetch_str_dup ();
|
||||||
|
M->last_name = fetch_str_dup ();
|
||||||
|
M->user_id = fetch_int ();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
logprintf ("type = 0x%08x\n", M->type);
|
||||||
|
assert (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
peer_id_t fetch_peer_id (void) {
|
peer_id_t fetch_peer_id (void) {
|
||||||
unsigned x =fetch_int ();
|
unsigned x =fetch_int ();
|
||||||
if (x == CODE_peer_user) {
|
if (x == CODE_peer_user) {
|
||||||
@ -629,6 +759,7 @@ void fetch_encrypted_message (struct message *M) {
|
|||||||
assert (!(len & 15));
|
assert (!(len & 15));
|
||||||
decr_ptr = (void *)fetch_str (len);
|
decr_ptr = (void *)fetch_str (len);
|
||||||
decr_end = in_ptr;
|
decr_end = in_ptr;
|
||||||
|
M->flags |= FLAG_ENCRYPTED;
|
||||||
if (P && decrypt_encrypted_message (&P->encr_chat) >= 0) {
|
if (P && decrypt_encrypted_message (&P->encr_chat) >= 0) {
|
||||||
in_ptr = decr_ptr;
|
in_ptr = decr_ptr;
|
||||||
unsigned x = fetch_int ();
|
unsigned x = fetch_int ();
|
||||||
@ -643,7 +774,29 @@ void fetch_encrypted_message (struct message *M) {
|
|||||||
fetch_str (l); // random_bytes
|
fetch_str (l); // random_bytes
|
||||||
M->from_id = MK_USER (fetch_int ());
|
M->from_id = MK_USER (fetch_int ());
|
||||||
M->date = fetch_int ();
|
M->date = fetch_int ();
|
||||||
|
if (x == CODE_decrypted_message) {
|
||||||
M->message = fetch_str_dup ();
|
M->message = fetch_str_dup ();
|
||||||
|
fetch_encrypted_message_file (&M->media);
|
||||||
|
} else {
|
||||||
|
assert (fetch_int () == (int)CODE_decrypted_message_action_set_message_t_t_l);
|
||||||
|
P->encr_chat.ttl = fetch_int ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fetch_encrypted_message_file (struct message_media *M) {
|
||||||
|
unsigned x = fetch_int ();
|
||||||
|
assert (x == CODE_encrypted_file || x == CODE_encrypted_file_empty);
|
||||||
|
if (x == CODE_encrypted_file_empty) {
|
||||||
|
assert (M->type != CODE_decrypted_message_media_photo && M->type != CODE_decrypted_message_media_video);
|
||||||
|
} else {
|
||||||
|
assert (M->type == CODE_decrypted_message_media_photo || M->type == CODE_decrypted_message_media_video);
|
||||||
|
M->encr_photo.id = fetch_long ();
|
||||||
|
M->encr_photo.access_hash = fetch_long ();
|
||||||
|
assert (M->encr_photo.size == fetch_int ());
|
||||||
|
M->encr_photo.dc_id = fetch_int ();
|
||||||
|
M->encr_photo.key_fingerprint = fetch_int ();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -689,6 +842,24 @@ struct user *fetch_alloc_user (void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct secret_chat *fetch_alloc_encrypted_chat (void) {
|
||||||
|
int data[2];
|
||||||
|
prefetch_data (data, 8);
|
||||||
|
peer_t *U = user_chat_get (MK_ENCR_CHAT (data[1]));
|
||||||
|
if (U) {
|
||||||
|
fetch_encrypted_chat (&U->encr_chat);
|
||||||
|
return &U->encr_chat;
|
||||||
|
} else {
|
||||||
|
chats_allocated ++;
|
||||||
|
U = malloc (sizeof (*U));
|
||||||
|
memset (U, 0, sizeof (*U));
|
||||||
|
fetch_encrypted_chat (&U->encr_chat);
|
||||||
|
peer_tree = tree_insert_peer (peer_tree, U, lrand48 ());
|
||||||
|
Peers[(chat_num ++) + user_num] = U;
|
||||||
|
return &U->encr_chat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct user *fetch_alloc_user_full (void) {
|
struct user *fetch_alloc_user_full (void) {
|
||||||
int data[3];
|
int data[3];
|
||||||
prefetch_data (data, 12);
|
prefetch_data (data, 12);
|
||||||
@ -759,6 +930,14 @@ void free_message_media (struct message_media *M) {
|
|||||||
case CODE_message_media_unsupported:
|
case CODE_message_media_unsupported:
|
||||||
free (M->data);
|
free (M->data);
|
||||||
return;
|
return;
|
||||||
|
case CODE_decrypted_message_media_photo:
|
||||||
|
free (M->encr_photo.key);
|
||||||
|
free (M->encr_photo.iv);
|
||||||
|
return;
|
||||||
|
case CODE_decrypted_message_media_video:
|
||||||
|
free (M->encr_video.key);
|
||||||
|
free (M->encr_video.iv);
|
||||||
|
return;
|
||||||
default:
|
default:
|
||||||
logprintf ("%08x\n", M->type);
|
logprintf ("%08x\n", M->type);
|
||||||
assert (0);
|
assert (0);
|
||||||
|
53
structures.h
53
structures.h
@ -35,6 +35,7 @@ typedef struct { int id; } peer_id_t;
|
|||||||
|
|
||||||
#define FLAG_CHAT_IN_CHAT 128
|
#define FLAG_CHAT_IN_CHAT 128
|
||||||
|
|
||||||
|
#define FLAG_ENCRYPTED 4096
|
||||||
|
|
||||||
struct file_location {
|
struct file_location {
|
||||||
int dc;
|
int dc;
|
||||||
@ -68,6 +69,40 @@ struct photo {
|
|||||||
struct photo_size *sizes;
|
struct photo_size *sizes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct encr_photo {
|
||||||
|
long long id;
|
||||||
|
long long access_hash;
|
||||||
|
int dc_id;
|
||||||
|
int size;
|
||||||
|
int key_fingerprint;
|
||||||
|
|
||||||
|
int w;
|
||||||
|
int h;
|
||||||
|
unsigned char *key;
|
||||||
|
unsigned char *iv;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct encr_video {
|
||||||
|
long long id;
|
||||||
|
long long access_hash;
|
||||||
|
int dc_id;
|
||||||
|
int size;
|
||||||
|
int key_fingerprint;
|
||||||
|
|
||||||
|
int w;
|
||||||
|
int h;
|
||||||
|
int duration;
|
||||||
|
unsigned char *key;
|
||||||
|
unsigned char *iv;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct encr_file {
|
||||||
|
char *filename;
|
||||||
|
unsigned char *key;
|
||||||
|
unsigned char *iv;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct user_status {
|
struct user_status {
|
||||||
int online;
|
int online;
|
||||||
int when;
|
int when;
|
||||||
@ -113,9 +148,10 @@ struct chat {
|
|||||||
|
|
||||||
enum secret_chat_state {
|
enum secret_chat_state {
|
||||||
sc_none,
|
sc_none,
|
||||||
sc_sent_request,
|
sc_waiting,
|
||||||
|
sc_request,
|
||||||
sc_ok,
|
sc_ok,
|
||||||
sc_bad
|
sc_deleted
|
||||||
};
|
};
|
||||||
|
|
||||||
struct secret_chat {
|
struct secret_chat {
|
||||||
@ -125,6 +161,13 @@ struct secret_chat {
|
|||||||
struct file_location photo_big;
|
struct file_location photo_big;
|
||||||
struct file_location photo_small;
|
struct file_location photo_small;
|
||||||
struct photo photo;
|
struct photo photo;
|
||||||
|
int user_id;
|
||||||
|
int admin_id;
|
||||||
|
int date;
|
||||||
|
int ttl;
|
||||||
|
long long access_hash;
|
||||||
|
unsigned char *g_key;
|
||||||
|
unsigned char *nonce;
|
||||||
|
|
||||||
enum secret_chat_state state;
|
enum secret_chat_state state;
|
||||||
int key[64];
|
int key[64];
|
||||||
@ -185,6 +228,9 @@ struct message_media {
|
|||||||
char *last_name;
|
char *last_name;
|
||||||
int user_id;
|
int user_id;
|
||||||
};
|
};
|
||||||
|
struct encr_photo encr_photo;
|
||||||
|
struct encr_video encr_video;
|
||||||
|
struct encr_file encr_file;
|
||||||
void *data;
|
void *data;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -218,10 +264,13 @@ struct user *fetch_alloc_user (void);
|
|||||||
struct user *fetch_alloc_user_full (void);
|
struct user *fetch_alloc_user_full (void);
|
||||||
struct chat *fetch_alloc_chat (void);
|
struct chat *fetch_alloc_chat (void);
|
||||||
struct chat *fetch_alloc_chat_full (void);
|
struct chat *fetch_alloc_chat_full (void);
|
||||||
|
struct secret_chat *fetch_alloc_encrypted_chat (void);
|
||||||
struct message *fetch_alloc_message (void);
|
struct message *fetch_alloc_message (void);
|
||||||
struct message *fetch_alloc_geo_message (void);
|
struct message *fetch_alloc_geo_message (void);
|
||||||
struct message *fetch_alloc_message_short (void);
|
struct message *fetch_alloc_message_short (void);
|
||||||
struct message *fetch_alloc_message_short_chat (void);
|
struct message *fetch_alloc_message_short_chat (void);
|
||||||
|
struct message *fetch_alloc_encrypted_message (void);
|
||||||
|
void fetch_encrypted_message_file (struct message_media *M);
|
||||||
peer_id_t fetch_peer_id (void);
|
peer_id_t fetch_peer_id (void);
|
||||||
|
|
||||||
void free_user (struct user *U);
|
void free_user (struct user *U);
|
||||||
|
Loading…
Reference in New Issue
Block a user