Some changes to add encrypted chat in nearest future
This commit is contained in:
parent
c9c1641b70
commit
5b8a4fdc60
@ -942,7 +942,7 @@ void print_service_message (struct message *M) {
|
|||||||
|
|
||||||
push_color (COLOR_MAGENTA);
|
push_color (COLOR_MAGENTA);
|
||||||
if (msg_num_mode) {
|
if (msg_num_mode) {
|
||||||
printf ("%d ", M->id);
|
printf ("%lld ", M->id);
|
||||||
}
|
}
|
||||||
print_date (M->date);
|
print_date (M->date);
|
||||||
pop_color ();
|
pop_color ();
|
||||||
@ -1002,7 +1002,7 @@ void print_message (struct message *M) {
|
|||||||
if (M->out) {
|
if (M->out) {
|
||||||
push_color (COLOR_GREEN);
|
push_color (COLOR_GREEN);
|
||||||
if (msg_num_mode) {
|
if (msg_num_mode) {
|
||||||
printf ("%d ", M->id);
|
printf ("%lld ", M->id);
|
||||||
}
|
}
|
||||||
print_date (M->date);
|
print_date (M->date);
|
||||||
pop_color ();
|
pop_color ();
|
||||||
@ -1017,7 +1017,7 @@ void print_message (struct message *M) {
|
|||||||
} else {
|
} else {
|
||||||
push_color (COLOR_BLUE);
|
push_color (COLOR_BLUE);
|
||||||
if (msg_num_mode) {
|
if (msg_num_mode) {
|
||||||
printf ("%d ", M->id);
|
printf ("%lld ", M->id);
|
||||||
}
|
}
|
||||||
print_date (M->date);
|
print_date (M->date);
|
||||||
pop_color ();
|
pop_color ();
|
||||||
@ -1033,7 +1033,7 @@ void print_message (struct message *M) {
|
|||||||
} else {
|
} else {
|
||||||
push_color (COLOR_MAGENTA);
|
push_color (COLOR_MAGENTA);
|
||||||
if (msg_num_mode) {
|
if (msg_num_mode) {
|
||||||
printf ("%d ", M->id);
|
printf ("%lld ", M->id);
|
||||||
}
|
}
|
||||||
print_date (M->date);
|
print_date (M->date);
|
||||||
pop_color ();
|
pop_color ();
|
||||||
|
127
structures.c
127
structures.c
@ -23,6 +23,12 @@
|
|||||||
#include "telegram.h"
|
#include "telegram.h"
|
||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
#include "loop.h"
|
#include "loop.h"
|
||||||
|
#include <openssl/rand.h>
|
||||||
|
#include <openssl/aes.h>
|
||||||
|
#include <openssl/sha.h>
|
||||||
|
|
||||||
|
#define sha1 SHA1
|
||||||
|
|
||||||
int verbosity;
|
int verbosity;
|
||||||
peer_t *Peers[MAX_USER_NUM];
|
peer_t *Peers[MAX_USER_NUM];
|
||||||
|
|
||||||
@ -553,7 +559,100 @@ void fetch_geo_message (struct message *M) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define id_cmp(a,b) ((a)->id - (b)->id)
|
int *decr_ptr;
|
||||||
|
int *decr_end;
|
||||||
|
|
||||||
|
int decrypt_encrypted_message (struct secret_chat *E) {
|
||||||
|
int *msg_key = decr_ptr;
|
||||||
|
decr_ptr += 4;
|
||||||
|
assert (decr_ptr < decr_end);
|
||||||
|
static unsigned char sha1a_buffer[20];
|
||||||
|
static unsigned char sha1b_buffer[20];
|
||||||
|
static unsigned char sha1c_buffer[20];
|
||||||
|
static unsigned char sha1d_buffer[20];
|
||||||
|
|
||||||
|
static unsigned char buf[64];
|
||||||
|
memcpy (buf, msg_key, 16);
|
||||||
|
memcpy (buf + 16, E->key, 32);
|
||||||
|
sha1 (buf, 48, sha1a_buffer);
|
||||||
|
|
||||||
|
memcpy (buf, E->key + 8, 16);
|
||||||
|
memcpy (buf + 16, msg_key, 16);
|
||||||
|
memcpy (buf + 32, E->key + 12, 16);
|
||||||
|
sha1 (buf, 48, sha1b_buffer);
|
||||||
|
|
||||||
|
memcpy (buf, E->key + 16, 32);
|
||||||
|
memcpy (buf + 32, msg_key, 16);
|
||||||
|
sha1 (buf, 48, sha1c_buffer);
|
||||||
|
|
||||||
|
memcpy (buf, msg_key, 16);
|
||||||
|
memcpy (buf + 16, E->key + 24, 32);
|
||||||
|
sha1 (buf, 48, sha1d_buffer);
|
||||||
|
|
||||||
|
static unsigned char iv[32];
|
||||||
|
memcpy (iv, sha1a_buffer + 0, 8);
|
||||||
|
memcpy (iv + 8, sha1b_buffer + 8, 12);
|
||||||
|
memcpy (iv + 20, sha1c_buffer + 4, 12);
|
||||||
|
|
||||||
|
static unsigned char key[32];
|
||||||
|
memcpy (key, sha1a_buffer + 8, 12);
|
||||||
|
memcpy (key + 12, sha1b_buffer + 0, 8);
|
||||||
|
memcpy (key + 20, sha1c_buffer + 16, 4);
|
||||||
|
memcpy (key + 24, sha1d_buffer + 0, 8);
|
||||||
|
|
||||||
|
AES_KEY aes_key;
|
||||||
|
AES_set_decrypt_key (key, 256, &aes_key);
|
||||||
|
AES_ige_encrypt ((void *)decr_ptr, (void *)decr_ptr, 4 * (decr_end - decr_ptr), &aes_key, iv, 0);
|
||||||
|
|
||||||
|
sha1 ((void *)decr_ptr, 4 * (decr_end - decr_ptr), sha1a_buffer);
|
||||||
|
|
||||||
|
if (memcmp (sha1a_buffer, msg_key, 16)) {
|
||||||
|
logprintf ("Sha1 mismatch\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fetch_encrypted_message (struct message *M) {
|
||||||
|
memset (M, 0, sizeof (*M));
|
||||||
|
unsigned x = fetch_int ();
|
||||||
|
assert (x == CODE_encrypted_message || x == CODE_encrypted_message_service);
|
||||||
|
peer_id_t chat = MK_ENCR_CHAT (fetch_int ());
|
||||||
|
M->id = fetch_long ();
|
||||||
|
peer_t *P = user_chat_get (chat);
|
||||||
|
if (!P) {
|
||||||
|
logprintf ("Encrypted message to unknown chat. Dropping\n");
|
||||||
|
}
|
||||||
|
M->date = fetch_int ();
|
||||||
|
|
||||||
|
int len = prefetch_strlen ();
|
||||||
|
assert (!(len & 15));
|
||||||
|
decr_ptr = (void *)fetch_str (len);
|
||||||
|
decr_end = in_ptr;
|
||||||
|
if (P && decrypt_encrypted_message (&P->encr_chat) >= 0) {
|
||||||
|
in_ptr = decr_ptr;
|
||||||
|
unsigned x = fetch_int ();
|
||||||
|
if (x == CODE_decrypted_message_layer) {
|
||||||
|
int layer = fetch_int ();
|
||||||
|
assert (layer >= 0);
|
||||||
|
x = fetch_int ();
|
||||||
|
}
|
||||||
|
assert (x == CODE_decrypted_message);
|
||||||
|
assert (M->id = fetch_long ());
|
||||||
|
int l = prefetch_strlen ();
|
||||||
|
fetch_str (l); // random_bytes
|
||||||
|
M->from_id = MK_USER (fetch_int ());
|
||||||
|
M->date = fetch_int ();
|
||||||
|
M->message = fetch_str_dup ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int id_cmp (struct message *M1, struct message *M2) {
|
||||||
|
if (M1->id < M2->id) { return -1; }
|
||||||
|
else if (M1->id > M2->id) { return 1; }
|
||||||
|
else { return 0; }
|
||||||
|
}
|
||||||
|
|
||||||
#define peer_cmp(a,b) (cmp_peer_id (a->id, b->id))
|
#define peer_cmp(a,b) (cmp_peer_id (a->id, b->id))
|
||||||
|
|
||||||
DEFINE_TREE(peer,peer_t *,peer_cmp,0)
|
DEFINE_TREE(peer,peer_t *,peer_cmp,0)
|
||||||
@ -752,6 +851,26 @@ struct message *fetch_alloc_geo_message (void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct message *fetch_alloc_encrypted_message (void) {
|
||||||
|
struct message *M = malloc (sizeof (*M));
|
||||||
|
fetch_encrypted_message (M);
|
||||||
|
struct message *M1 = tree_lookup_message (message_tree, M);
|
||||||
|
messages_allocated ++;
|
||||||
|
if (M1) {
|
||||||
|
message_del_use (M1);
|
||||||
|
free_message (M1);
|
||||||
|
memcpy (M1, M, sizeof (*M));
|
||||||
|
free (M);
|
||||||
|
message_add_use (M1);
|
||||||
|
messages_allocated --;
|
||||||
|
return M1;
|
||||||
|
} else {
|
||||||
|
message_add_use (M);
|
||||||
|
message_tree = tree_insert_message (message_tree, M, lrand48 ());
|
||||||
|
return M;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct message *fetch_alloc_message_short (void) {
|
struct message *fetch_alloc_message_short (void) {
|
||||||
struct message *M = malloc (sizeof (*M));
|
struct message *M = malloc (sizeof (*M));
|
||||||
fetch_message_short (M);
|
fetch_message_short (M);
|
||||||
@ -776,7 +895,7 @@ struct message *fetch_alloc_message_short_chat (void) {
|
|||||||
struct message *M = malloc (sizeof (*M));
|
struct message *M = malloc (sizeof (*M));
|
||||||
fetch_message_short_chat (M);
|
fetch_message_short_chat (M);
|
||||||
if (verbosity >= 2) {
|
if (verbosity >= 2) {
|
||||||
logprintf ("Read message with id %d\n", M->id);
|
logprintf ("Read message with id %lld\n", M->id);
|
||||||
}
|
}
|
||||||
struct message *M1 = tree_lookup_message (message_tree, M);
|
struct message *M1 = tree_lookup_message (message_tree, M);
|
||||||
messages_allocated ++;
|
messages_allocated ++;
|
||||||
@ -854,13 +973,13 @@ peer_t *user_chat_get (peer_id_t id) {
|
|||||||
return tree_lookup_peer (peer_tree, &U);
|
return tree_lookup_peer (peer_tree, &U);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct message *message_get (int id) {
|
struct message *message_get (long long id) {
|
||||||
struct message M;
|
struct message M;
|
||||||
M.id = id;
|
M.id = id;
|
||||||
return tree_lookup_message (message_tree, &M);
|
return tree_lookup_message (message_tree, &M);
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_message_id (struct message *M, int id) {
|
void update_message_id (struct message *M, long long id) {
|
||||||
message_tree = tree_delete_message (message_tree, M);
|
message_tree = tree_delete_message (message_tree, M);
|
||||||
M->id = id;
|
M->id = id;
|
||||||
message_tree = tree_insert_message (message_tree, M, lrand48 ());
|
message_tree = tree_insert_message (message_tree, M, lrand48 ());
|
||||||
|
37
structures.h
37
structures.h
@ -111,6 +111,26 @@ struct chat {
|
|||||||
int admin_id;
|
int admin_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum secret_chat_state {
|
||||||
|
sc_none,
|
||||||
|
sc_sent_request,
|
||||||
|
sc_ok,
|
||||||
|
sc_bad
|
||||||
|
};
|
||||||
|
|
||||||
|
struct secret_chat {
|
||||||
|
peer_id_t id;
|
||||||
|
int flags;
|
||||||
|
char *print_name;
|
||||||
|
struct file_location photo_big;
|
||||||
|
struct file_location photo_small;
|
||||||
|
struct photo photo;
|
||||||
|
|
||||||
|
enum secret_chat_state state;
|
||||||
|
int key[64];
|
||||||
|
long long key_fingerprint;
|
||||||
|
};
|
||||||
|
|
||||||
typedef union peer {
|
typedef union peer {
|
||||||
struct {
|
struct {
|
||||||
peer_id_t id;
|
peer_id_t id;
|
||||||
@ -122,6 +142,7 @@ typedef union peer {
|
|||||||
};
|
};
|
||||||
struct user user;
|
struct user user;
|
||||||
struct chat chat;
|
struct chat chat;
|
||||||
|
struct secret_chat encr_chat;
|
||||||
} peer_t;
|
} peer_t;
|
||||||
|
|
||||||
struct video {
|
struct video {
|
||||||
@ -170,7 +191,7 @@ struct message_media {
|
|||||||
|
|
||||||
struct message {
|
struct message {
|
||||||
struct message *next_use, *prev_use;
|
struct message *next_use, *prev_use;
|
||||||
int id;
|
long long id;
|
||||||
int flags;
|
int flags;
|
||||||
peer_id_t fwd_from_id;
|
peer_id_t fwd_from_id;
|
||||||
int fwd_date;
|
int fwd_date;
|
||||||
@ -208,8 +229,8 @@ void free_chat (struct chat *U);
|
|||||||
|
|
||||||
int print_stat (char *s, int len);
|
int print_stat (char *s, int len);
|
||||||
peer_t *user_chat_get (peer_id_t id);
|
peer_t *user_chat_get (peer_id_t id);
|
||||||
struct message *message_get (int id);
|
struct message *message_get (long long id);
|
||||||
void update_message_id (struct message *M, int id);
|
void update_message_id (struct message *M, long long id);
|
||||||
void message_insert (struct message *M);
|
void message_insert (struct message *M);
|
||||||
void free_photo (struct photo *P);
|
void free_photo (struct photo *P);
|
||||||
void fetch_photo (struct photo *P);
|
void fetch_photo (struct photo *P);
|
||||||
@ -217,13 +238,18 @@ void fetch_photo (struct photo *P);
|
|||||||
#define PEER_USER 1
|
#define PEER_USER 1
|
||||||
#define PEER_CHAT 2
|
#define PEER_CHAT 2
|
||||||
#define PEER_GEO_CHAT 3
|
#define PEER_GEO_CHAT 3
|
||||||
|
#define PEER_ENCR_CHAT 4
|
||||||
#define PEER_UNKNOWN 0
|
#define PEER_UNKNOWN 0
|
||||||
|
|
||||||
#define MK_USER(id) set_peer_id (PEER_USER,id)
|
#define MK_USER(id) set_peer_id (PEER_USER,id)
|
||||||
#define MK_CHAT(id) set_peer_id (PEER_CHAT,id)
|
#define MK_CHAT(id) set_peer_id (PEER_CHAT,id)
|
||||||
#define MK_GEO_CHAT(id) set_peer_id (PEER_GEO_CHAT,id)
|
#define MK_GEO_CHAT(id) set_peer_id (PEER_GEO_CHAT,id)
|
||||||
|
#define MK_ENCR_CHAT(id) set_peer_id (PEER_ENCR_CHAT,id)
|
||||||
|
|
||||||
static inline int get_peer_type (peer_id_t id) {
|
static inline int get_peer_type (peer_id_t id) {
|
||||||
|
if (id.id > 1000000000) {
|
||||||
|
return PEER_ENCR_CHAT;
|
||||||
|
}
|
||||||
if (id.id > 0) {
|
if (id.id > 0) {
|
||||||
return PEER_USER;
|
return PEER_USER;
|
||||||
}
|
}
|
||||||
@ -244,6 +270,8 @@ static inline int get_peer_id (peer_id_t id) {
|
|||||||
return -id.id;
|
return -id.id;
|
||||||
case PEER_GEO_CHAT:
|
case PEER_GEO_CHAT:
|
||||||
return -id.id - 1000000000;
|
return -id.id - 1000000000;
|
||||||
|
case PEER_ENCR_CHAT:
|
||||||
|
return id.id - 1000000000;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -261,6 +289,9 @@ static inline peer_id_t set_peer_id (int type, int id) {
|
|||||||
case PEER_GEO_CHAT:
|
case PEER_GEO_CHAT:
|
||||||
ID.id = -id - 1000000000;
|
ID.id = -id - 1000000000;
|
||||||
return ID;
|
return ID;
|
||||||
|
case PEER_ENCR_CHAT:
|
||||||
|
ID.id = id + 1000000000;
|
||||||
|
return ID;
|
||||||
default:
|
default:
|
||||||
assert (0);
|
assert (0);
|
||||||
return ID;
|
return ID;
|
||||||
|
Loading…
Reference in New Issue
Block a user