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 ();
|
||||
}
|
||||
|
||||
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"};
|
||||
void print_date (long t) {
|
||||
struct tm *tm = localtime (&t);
|
||||
|
@ -45,6 +45,8 @@ union peer;
|
||||
void print_message (struct message *M);
|
||||
void print_chat_name (peer_id_t id, union peer *C);
|
||||
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 pop_color (void);
|
||||
void push_color (const char *color);
|
||||
|
@ -956,27 +956,79 @@ void work_update (struct connection *c UU, long long msg_id UU) {
|
||||
break;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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 (); // date
|
||||
print_start ();
|
||||
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 ();
|
||||
print_end ();
|
||||
}
|
||||
|
181
structures.c
181
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_user_full (struct user *U) {
|
||||
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) {
|
||||
unsigned x =fetch_int ();
|
||||
if (x == CODE_peer_user) {
|
||||
@ -629,6 +759,7 @@ void fetch_encrypted_message (struct message *M) {
|
||||
assert (!(len & 15));
|
||||
decr_ptr = (void *)fetch_str (len);
|
||||
decr_end = in_ptr;
|
||||
M->flags |= FLAG_ENCRYPTED;
|
||||
if (P && decrypt_encrypted_message (&P->encr_chat) >= 0) {
|
||||
in_ptr = decr_ptr;
|
||||
unsigned x = fetch_int ();
|
||||
@ -643,7 +774,29 @@ void fetch_encrypted_message (struct message *M) {
|
||||
fetch_str (l); // random_bytes
|
||||
M->from_id = MK_USER (fetch_int ());
|
||||
M->date = fetch_int ();
|
||||
M->message = fetch_str_dup ();
|
||||
if (x == CODE_decrypted_message) {
|
||||
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) {
|
||||
int data[3];
|
||||
prefetch_data (data, 12);
|
||||
@ -759,6 +930,14 @@ void free_message_media (struct message_media *M) {
|
||||
case CODE_message_media_unsupported:
|
||||
free (M->data);
|
||||
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:
|
||||
logprintf ("%08x\n", M->type);
|
||||
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_ENCRYPTED 4096
|
||||
|
||||
struct file_location {
|
||||
int dc;
|
||||
@ -68,6 +69,40 @@ struct photo {
|
||||
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 {
|
||||
int online;
|
||||
int when;
|
||||
@ -113,9 +148,10 @@ struct chat {
|
||||
|
||||
enum secret_chat_state {
|
||||
sc_none,
|
||||
sc_sent_request,
|
||||
sc_waiting,
|
||||
sc_request,
|
||||
sc_ok,
|
||||
sc_bad
|
||||
sc_deleted
|
||||
};
|
||||
|
||||
struct secret_chat {
|
||||
@ -125,6 +161,13 @@ struct secret_chat {
|
||||
struct file_location photo_big;
|
||||
struct file_location photo_small;
|
||||
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;
|
||||
int key[64];
|
||||
@ -185,6 +228,9 @@ struct message_media {
|
||||
char *last_name;
|
||||
int user_id;
|
||||
};
|
||||
struct encr_photo encr_photo;
|
||||
struct encr_video encr_video;
|
||||
struct encr_file encr_file;
|
||||
void *data;
|
||||
};
|
||||
};
|
||||
@ -218,10 +264,13 @@ struct user *fetch_alloc_user (void);
|
||||
struct user *fetch_alloc_user_full (void);
|
||||
struct chat *fetch_alloc_chat (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_geo_message (void);
|
||||
struct message *fetch_alloc_message_short (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);
|
||||
|
||||
void free_user (struct user *U);
|
||||
|
Loading…
Reference in New Issue
Block a user