diff --git a/Makefile b/Makefile index ba848c9..47ce820 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ LINK_FLAGS=${LDFLAGS} ${LOCAL_LDFLAGS} HEADERS= ${srcdir}/constants.h ${srcdir}/include.h ${srcdir}/interface.h ${srcdir}/LICENSE.h ${srcdir}/loop.h ${srcdir}/mtproto-client.h ${srcdir}/mtproto-common.h ${srcdir}/net.h ${srcdir}/no-preview.h ${srcdir}/queries.h ${srcdir}/structures.h ${srcdir}/telegram.h ${srcdir}/tree.h ${srcdir}/config.h ${srcdir}/binlog.h INCLUDE=-I. -I${srcdir} CC=gcc -OBJECTS=main.o loop.o interface.o net.o mtproto-common.o mtproto-client.o queries.o structures.o binlog.o +OBJECTS=main.o loop.o interface.o net.o mtproto-common.o mtproto-client.o queries.o structures.o binlog.o tools.o .SUFFIXES: diff --git a/Makefile.in b/Makefile.in index 7c6589d..7898905 100644 --- a/Makefile.in +++ b/Makefile.in @@ -13,7 +13,7 @@ LINK_FLAGS=${LDFLAGS} ${LOCAL_LDFLAGS} HEADERS= ${srcdir}/constants.h ${srcdir}/include.h ${srcdir}/interface.h ${srcdir}/LICENSE.h ${srcdir}/loop.h ${srcdir}/mtproto-client.h ${srcdir}/mtproto-common.h ${srcdir}/net.h ${srcdir}/no-preview.h ${srcdir}/queries.h ${srcdir}/structures.h ${srcdir}/telegram.h ${srcdir}/tree.h ${srcdir}/config.h ${srcdir}/binlog.h INCLUDE=-I. -I${srcdir} CC=@CC@ -OBJECTS=main.o loop.o interface.o net.o mtproto-common.o mtproto-client.o queries.o structures.o binlog.o +OBJECTS=main.o loop.o interface.o net.o mtproto-common.o mtproto-client.o queries.o structures.o binlog.o tools.o .SUFFIXES: diff --git a/binlog.c b/binlog.c index a71b4a7..0414fa1 100644 --- a/binlog.c +++ b/binlog.c @@ -183,7 +183,7 @@ void replay_log_event (void) { memcpy (U->key, rptr, 256); rptr += 64; if (!U->g_key) { - U->g_key = malloc (256); + U->g_key = talloc (256); } memcpy (U->g_key, rptr, 256); rptr += 64; @@ -196,8 +196,7 @@ void replay_log_event (void) { struct secret_chat *U = (void *)user_chat_get (id); assert (!U || !(U->flags & FLAG_CREATED)); if (!U) { - U = malloc (sizeof (peer_t)); - memset (U, 0, sizeof (peer_t)); + U = talloc0 (sizeof (peer_t)); U->id = id; insert_encrypted_chat ((void *)U); } @@ -223,8 +222,7 @@ void replay_log_event (void) { peer_id_t id = MK_ENCR_CHAT (*(rptr ++)); struct secret_chat *U = (void *)user_chat_get (id); if (!U) { - U = malloc (sizeof (peer_t)); - memset (U, 0, sizeof (peer_t)); + U = talloc0 (sizeof (peer_t)); U->id = id; insert_encrypted_chat ((void *)U); } @@ -252,8 +250,7 @@ void replay_log_event (void) { peer_id_t id = MK_ENCR_CHAT (*(rptr ++)); struct secret_chat *U = (void *)user_chat_get (id); if (!U) { - U = malloc (sizeof (peer_t)); - memset (U, 0, sizeof (peer_t)); + U = talloc0 (sizeof (peer_t)); U->id = id; insert_encrypted_chat ((void *)U); } @@ -291,8 +288,7 @@ void replay_log_event (void) { peer_id_t id = MK_USER (fetch_int ()); peer_t *_U = user_chat_get (id); if (!_U) { - _U = malloc (sizeof (*_U)); - memset (_U, 0, sizeof (*_U)); + _U = talloc0 (sizeof (*_U)); _U->id = id; insert_user (_U); } else { @@ -418,8 +414,7 @@ void replay_log_event (void) { peer_id_t id = MK_ENCR_CHAT (*(rptr ++)); peer_t *_U = user_chat_get (id); if (!_U) { - _U = malloc (sizeof (*_U)); - memset (_U, 0, sizeof (*_U)); + _U = talloc0 (sizeof (*_U)); _U->id = id; insert_encrypted_chat (_U); } else { @@ -440,8 +435,8 @@ void replay_log_event (void) { sprintf (buf, "user#%d", U->user_id); U->print_name = create_print_name (id, "!", buf, 0, 0); } - U->g_key = malloc (256); - U->nonce = malloc (256); + U->g_key = talloc (256); + U->nonce = talloc (256); memcpy (U->g_key, rptr, 256); rptr += 64; memcpy (U->nonce, rptr, 256); @@ -487,10 +482,10 @@ void replay_log_event (void) { assert (_U); struct secret_chat *U = &_U->encr_chat; if (!U->g_key) { - U->g_key = malloc (256); + U->g_key = talloc (256); } if (!U->nonce) { - U->nonce = malloc (256); + U->nonce = talloc (256); } memcpy (U->g_key, rptr, 256); rptr += 64; @@ -522,7 +517,7 @@ void replay_log_event (void) { { if (encr_prime) { free (encr_prime); } encr_root = *(rptr ++); - encr_prime = malloc (256); + encr_prime = talloc (256); memcpy (encr_prime, rptr, 256); rptr += 64; encr_param_version = *(rptr ++); @@ -532,8 +527,7 @@ void replay_log_event (void) { case CODE_binlog_encr_chat_init: rptr ++; { - peer_t *P = malloc (sizeof (*P)); - memset (P, 0, sizeof (*P)); + peer_t *P = talloc0 (sizeof (*P)); P->id = MK_ENCR_CHAT (*(rptr ++)); assert (!user_chat_get (P->id)); P->encr_chat.user_id = *(rptr ++); @@ -544,7 +538,7 @@ void replay_log_event (void) { P->print_name = create_print_name (P->id, "!", Us->user.first_name, Us->user.last_name, 0); memcpy (P->encr_chat.key, rptr, 256); rptr += 64; - P->encr_chat.g_key = malloc (256); + P->encr_chat.g_key = talloc (256); memcpy (P->encr_chat.g_key, rptr, 256); rptr += 64; P->flags |= FLAG_CREATED; @@ -572,8 +566,7 @@ void replay_log_event (void) { peer_id_t id = MK_CHAT (fetch_int ()); peer_t *_C = user_chat_get (id); if (!_C) { - _C = malloc (sizeof (*_C)); - memset (_C, 0, sizeof (*_C)); + _C = talloc0 (sizeof (*_C)); _C->id = id; insert_chat (_C); } else { @@ -655,7 +648,7 @@ void replay_log_event (void) { C->chat.user_list_version = *(rptr ++); C->chat.user_list_size = *(rptr ++); if (C->chat.user_list) { free (C->chat.user_list); } - C->chat.user_list = malloc (12 * C->chat.user_list_size); + C->chat.user_list = talloc (12 * C->chat.user_list_size); memcpy (C->chat.user_list, rptr, 12 * C->chat.user_list_size); rptr += 3 * C->chat.user_list_size; }; @@ -738,8 +731,7 @@ void replay_log_event (void) { } struct message *M = message_get (id); if (!M) { - M = malloc (sizeof (*M)); - memset (M, 0, sizeof (*M)); + M = talloc0 (sizeof (*M)); M->id = id; message_insert_tree (M); messages_allocated ++; @@ -756,7 +748,7 @@ void replay_log_event (void) { M->date = fetch_int (); int l = prefetch_strlen (); - M->message = malloc (l + 1); + M->message = talloc (l + 1); memcpy (M->message, fetch_str (l), l); M->message[l] = 0; M->message_len = l; @@ -783,8 +775,7 @@ void replay_log_event (void) { int id = fetch_int (); struct message *M = message_get (id); if (!M) { - M = malloc (sizeof (*M)); - memset (M, 0, sizeof (*M)); + M = talloc0 (sizeof (*M)); M->id = id; message_insert_tree (M); messages_allocated ++; @@ -800,7 +791,7 @@ void replay_log_event (void) { M->fwd_date = fetch_int (); int l = prefetch_strlen (); - M->message = malloc (l + 1); + M->message = talloc (l + 1); memcpy (M->message, fetch_str (l), l); M->message[l] = 0; M->message_len = l; @@ -819,8 +810,7 @@ void replay_log_event (void) { int id = fetch_int (); struct message *M = message_get (id); if (!M) { - M = malloc (sizeof (*M)); - memset (M, 0, sizeof (*M)); + M = talloc0 (sizeof (*M)); M->id = id; message_insert_tree (M); messages_allocated ++; @@ -834,7 +824,7 @@ void replay_log_event (void) { M->date = fetch_int (); int l = prefetch_strlen (); - M->message = malloc (l + 1); + M->message = talloc (l + 1); memcpy (M->message, fetch_str (l), l); M->message[l] = 0; M->message_len = l; @@ -853,8 +843,7 @@ void replay_log_event (void) { long long id = fetch_long (); struct message *M = message_get (id); if (!M) { - M = malloc (sizeof (*M)); - memset (M, 0, sizeof (*M)); + M = talloc0 (sizeof (*M)); M->id = id; message_insert_tree (M); messages_allocated ++; @@ -868,7 +857,7 @@ void replay_log_event (void) { M->date = fetch_int (); int l = prefetch_strlen (); - M->message = malloc (l + 1); + M->message = talloc (l + 1); memcpy (M->message, fetch_str (l), l); M->message[l] = 0; M->message_len = l; @@ -889,8 +878,7 @@ void replay_log_event (void) { int id = fetch_int (); struct message *M = message_get (id); if (!M) { - M = malloc (sizeof (*M)); - memset (M, 0, sizeof (*M)); + M = talloc0 (sizeof (*M)); M->id = id; message_insert_tree (M); messages_allocated ++; @@ -906,7 +894,7 @@ void replay_log_event (void) { M->fwd_date = fetch_int (); int l = prefetch_strlen (); - M->message = malloc (l + 1); + M->message = talloc (l + 1); memcpy (M->message, fetch_str (l), l); M->message[l] = 0; M->message_len = l; @@ -925,8 +913,7 @@ void replay_log_event (void) { int id = fetch_int (); struct message *M = message_get (id); if (!M) { - M = malloc (sizeof (*M)); - memset (M, 0, sizeof (*M)); + M = talloc0 (sizeof (*M)); M->id = id; message_insert_tree (M); messages_allocated ++; @@ -954,8 +941,7 @@ void replay_log_event (void) { long long id = fetch_long (); struct message *M = message_get (id); if (!M) { - M = malloc (sizeof (*M)); - memset (M, 0, sizeof (*M)); + M = talloc0 (sizeof (*M)); M->id = id; message_insert_tree (M); messages_allocated ++; @@ -984,8 +970,7 @@ void replay_log_event (void) { int id = fetch_int (); struct message *M = message_get (id); if (!M) { - M = malloc (sizeof (*M)); - memset (M, 0, sizeof (*M)); + M = talloc0 (sizeof (*M)); M->id = id; message_insert_tree (M); messages_allocated ++; diff --git a/interface.c b/interface.c index a535e82..65a5f56 100644 --- a/interface.c +++ b/interface.c @@ -413,7 +413,7 @@ int complete_user_list (int index, const char *text, int len, char **R) { index ++; } if (index < peer_num) { - *R = strdup (Peers[index]->print_name); + *R = tstrdup (Peers[index]->print_name); return index; } else { return -1; @@ -426,7 +426,7 @@ int complete_chat_list (int index, const char *text, int len, char **R) { index ++; } if (index < peer_num) { - *R = strdup (Peers[index]->print_name); + *R = tstrdup (Peers[index]->print_name); return index; } else { return -1; @@ -439,7 +439,7 @@ int complete_encr_chat_list (int index, const char *text, int len, char **R) { index ++; } if (index < peer_num) { - *R = strdup (Peers[index]->print_name); + *R = tstrdup (Peers[index]->print_name); return index; } else { return -1; @@ -452,7 +452,7 @@ int complete_user_chat_list (int index, const char *text, int len, char **R) { index ++; } if (index < peer_num) { - *R = strdup (Peers[index]->print_name); + *R = tstrdup (Peers[index]->print_name); return index; } else { return -1; @@ -465,7 +465,7 @@ int complete_string_list (char **list, int index, const char *text, int len, cha index ++; } if (list[index]) { - *R = strdup (list[index]); + *R = tstrdup (list[index]); return index; } else { *R = 0; @@ -1100,7 +1100,7 @@ void print_start (void) { rl_replace_line("", 0); #else assert (rl_end >= 0); - saved_line = malloc (rl_end + 1); + saved_line = talloc (rl_end + 1); memcpy (saved_line, rl_line_buffer, rl_end + 1); rl_line_buffer[0] = 0; set_prompt (""); diff --git a/loop.c b/loop.c index f4b5fef..71c4746 100644 --- a/loop.c +++ b/loop.c @@ -200,7 +200,7 @@ void read_dc (int auth_file_fd, int id, unsigned ver) { int l = 0; assert (read (auth_file_fd, &l, 4) == 4); assert (l >= 0); - char *ip = malloc (l + 1); + char *ip = talloc (l + 1); assert (read (auth_file_fd, ip, l) == l); ip[l] = 0; struct dc *DC = alloc_dc (id, ip, port); @@ -218,8 +218,7 @@ void read_dc (int auth_file_fd, int id, unsigned ver) { } void empty_auth_file (void) { - struct dc *DC = alloc_dc (1, strdup (test_dc ? TG_SERVER_TEST : TG_SERVER), 443); - assert (DC); + alloc_dc (1, tstrdup (test_dc ? TG_SERVER_TEST : TG_SERVER), 443); dc_working_num = 1; auth_state = 0; write_auth_file (); @@ -338,8 +337,7 @@ void read_secret_chat_file (void) { assert (read (fd, &cc, 4) == 4); int i; for (i = 0; i < cc; i++) { - peer_t *P = malloc (sizeof (*P)); - memset (P, 0, sizeof (*P)); + peer_t *P = talloc0 (sizeof (*P)); struct secret_chat *E = &P->encr_chat; int t; assert (read (fd, &t, 4) == 4); @@ -347,7 +345,7 @@ void read_secret_chat_file (void) { assert (read (fd, &P->flags, 4) == 4); assert (read (fd, &t, 4) == 4); assert (t > 0); - P->print_name = malloc (t + 1); + P->print_name = talloc (t + 1); assert (read (fd, P->print_name, t) == t); P->print_name[t] = 0; @@ -358,9 +356,9 @@ void read_secret_chat_file (void) { assert (read (fd, &E->access_hash, 8) == 8); if (E->state != sc_waiting) { - E->g_key = malloc (256); + E->g_key = talloc (256); assert (read (fd, E->g_key, 256) == 256); - E->nonce = malloc (256); + E->nonce = talloc (256); assert (read (fd, E->nonce, 256) == 256); } assert (read (fd, E->key, 256) == 256); @@ -371,7 +369,7 @@ void read_secret_chat_file (void) { assert (read (fd, &encr_root, 4) == 4); if (encr_root) { assert (read (fd, &encr_param_version, 4) == 4); - encr_prime = malloc (256); + encr_prime = talloc (256); assert (read (fd, encr_prime, 256) == 256); } } diff --git a/main.c b/main.c index f0cd56d..4c6841f 100644 --- a/main.c +++ b/main.c @@ -45,6 +45,7 @@ #include "loop.h" #include "mtproto-client.h" #include "interface.h" +#include "tools.h" #define PROGNAME "telegram-client" #define VERSION "0.01" @@ -84,7 +85,7 @@ void set_default_username (const char *s) { if (default_username) { free (default_username); } - default_username = strdup (s); + default_username = tstrdup (s); } @@ -236,13 +237,13 @@ void parse_config_val (config_t *conf, char **s, char *param_name, const char *d if (path) { assert (asprintf (s, "%s/%s", path, r) >= 0); } else { - *s = strdup (r); + *s = tstrdup (r); } } else { if (path) { assert (asprintf (s, "%s/%s", path, default_name) >= 0); } else { - *s = strdup (default_name); + *s = tstrdup (default_name); } } } @@ -338,7 +339,7 @@ void args_parse (int argc, char **argv) { set_default_username (optarg); break; case 'k': - rsa_public_key_name = strdup (optarg); + rsa_public_key_name = tstrdup (optarg); break; case 'v': verbosity ++; @@ -347,10 +348,10 @@ void args_parse (int argc, char **argv) { msg_num_mode ++; break; case 'c': - config_filename = strdup (optarg); + config_filename = tstrdup (optarg); break; case 'p': - prefix = strdup (optarg); + prefix = tstrdup (optarg); assert (strlen (prefix) <= 100); break; case 'l': @@ -369,7 +370,7 @@ void args_parse (int argc, char **argv) { if (log_net_file) { usage (); } - log_net_file = strdup (optarg); + log_net_file = tstrdup (optarg); log_net_f = fopen (log_net_file, "a"); assert (log_net_f); break; diff --git a/mtproto-client.c b/mtproto-client.c index 54fde7a..3fc865c 100644 --- a/mtproto-client.c +++ b/mtproto-client.c @@ -431,9 +431,9 @@ int check_DH_params (BIGNUM *p, int g) { BN_init (&t); BN_init (&dh_g); - BN_set_word (&dh_g, 4 * g); + ensure (BN_set_word (&dh_g, 4 * g)); - BN_mod (&t, p, &dh_g, BN_ctx); + ensure (BN_mod (&t, p, &dh_g, BN_ctx)); int x = BN_get_word (&t); assert (x >= 0 && x < 4 * g); @@ -463,8 +463,8 @@ int check_DH_params (BIGNUM *p, int g) { BIGNUM b; BN_init (&b); - BN_set_word (&b, 2); - BN_div (&t, 0, p, &b, BN_ctx); + ensure (BN_set_word (&b, 2)); + ensure (BN_div (&t, 0, p, &b, BN_ctx)); if (!BN_is_prime (&t, BN_prime_checks, 0, BN_ctx, 0)) { return -1; } BN_clear (&b); BN_clear (&t); @@ -571,19 +571,20 @@ int process_dh_answer (struct connection *c, char *packet, int len) { out_long (0LL); BN_init (&dh_g); - BN_set_word (&dh_g, g); + ensure (BN_set_word (&dh_g, g)); secure_random (s_power, 256); - BIGNUM *dh_power = BN_new (); - assert (BN_bin2bn ((unsigned char *)s_power, 256, dh_power) == dh_power); + BIGNUM *dh_power = BN_bin2bn ((unsigned char *)s_power, 256, 0); + ensure_ptr (dh_power); BIGNUM *y = BN_new (); - assert (BN_mod_exp (y, &dh_g, dh_power, &dh_prime, BN_ctx) == 1); + ensure_ptr (y); + ensure (BN_mod_exp (y, &dh_g, dh_power, &dh_prime, BN_ctx)); out_bignum (y); BN_free (y); BN_init (&auth_key_num); - assert (BN_mod_exp (&auth_key_num, &g_a, dh_power, &dh_prime, BN_ctx) == 1); + ensure (BN_mod_exp (&auth_key_num, &g_a, dh_power, &dh_prime, BN_ctx)); l = BN_num_bytes (&auth_key_num); assert (l >= 250 && l <= 256); assert (BN_bn2bin (&auth_key_num, (unsigned char *)GET_DC(c)->auth_key)); @@ -1098,7 +1099,7 @@ void work_update (struct connection *c UU, long long msg_id UU) { bl_do_set_chat_admin (&C->chat, fetch_int ()); assert (fetch_int () == CODE_vector); n = fetch_int (); - struct chat_user *users = malloc (12 * n); + struct chat_user *users = talloc (12 * n); int i; for (i = 0; i < n; i++) { assert (fetch_int () == (int)CODE_chat_participant); diff --git a/mtproto-common.c b/mtproto-common.c index 07d073c..2d87f83 100644 --- a/mtproto-common.c +++ b/mtproto-common.c @@ -102,8 +102,7 @@ void my_clock_gettime (int clock_id UU, struct timespec *T) { void prng_seed (const char *password_filename, int password_length) { - unsigned char *a = calloc (64 + password_length, 1); - assert (a != NULL); + unsigned char *a = talloc0 (64 + password_length); long long r = rdtsc (); struct timespec T; my_clock_gettime (CLOCK_REALTIME, &T); diff --git a/mtproto-common.h b/mtproto-common.h index b811ecc..0b8bffd 100644 --- a/mtproto-common.h +++ b/mtproto-common.h @@ -27,6 +27,7 @@ #include #include "interface.h" +#include "tools.h" #include "constants.h" /* DH key exchange protocol data structures */ #define CODE_req_pq 0x60469778 @@ -305,7 +306,7 @@ static inline char *fetch_str (int len) { static inline char *fetch_str_dup (void) { int l = prefetch_strlen (); assert (l >= 0); - char *s = malloc (l + 1); + char *s = talloc (l + 1); memcpy (s, fetch_str (l), l); s[l] = 0; return s; @@ -320,7 +321,7 @@ static inline int fetch_update_str (char **s) { char *r = fetch_str (l); if (memcmp (*s, r, l) || (*s)[l]) { free (*s); - *s = malloc (l + 1); + *s = talloc (l + 1); memcpy (*s, r, l); (*s)[l] = 0; return 1; diff --git a/net.c b/net.c index c6643f6..3ecfa51 100644 --- a/net.c +++ b/net.c @@ -103,9 +103,8 @@ void start_fail_timer (struct connection *c) { } struct connection_buffer *new_connection_buffer (int size) { - struct connection_buffer *b = malloc (sizeof (*b)); - memset (b, 0, sizeof (*b)); - b->start = malloc (size); + struct connection_buffer *b = talloc0 (sizeof (*b)); + b->start = talloc (size); b->end = b->start + size; b->rptr = b->wptr = b->start; return b; @@ -224,8 +223,7 @@ void rotate_port (struct connection *c) { } struct connection *create_connection (const char *host, int port, struct session *session, struct connection_methods *methods) { - struct connection *c = malloc (sizeof (*c)); - memset (c, 0, sizeof (*c)); + struct connection *c = talloc0 (sizeof (*c)); int fd = socket (AF_INET, SOCK_STREAM, 0); if (fd == -1) { logprintf ("Can not create socket: %m\n"); @@ -276,7 +274,7 @@ struct connection *create_connection (const char *host, int port, struct session c->session = session; c->fd = fd; - c->ip = strdup (host); + c->ip = tstrdup (host); c->flags = 0; c->state = conn_ready; c->methods = methods; @@ -615,8 +613,7 @@ extern struct dc *DC_list[]; struct dc *alloc_dc (int id, char *ip, int port UU) { assert (!DC_list[id]); - struct dc *DC = malloc (sizeof (*DC)); - memset (DC, 0, sizeof (*DC)); + struct dc *DC = talloc0 (sizeof (*DC)); DC->id = id; DC->ip = ip; DC->port = port; @@ -625,8 +622,7 @@ struct dc *alloc_dc (int id, char *ip, int port UU) { } void dc_create_session (struct dc *DC) { - struct session *S = malloc (sizeof (*S)); - memset (S, 0, sizeof (*S)); + struct session *S = talloc0 (sizeof (*S)); assert (RAND_pseudo_bytes ((unsigned char *) &S->session_id, 8) >= 0); S->dc = DC; S->c = create_connection (DC->ip, DC->port, S, &auth_methods); diff --git a/queries.c b/queries.c index bd5a86d..72d6962 100644 --- a/queries.c +++ b/queries.c @@ -126,10 +126,9 @@ struct query *send_query (struct dc *DC, int ints, void *data, struct query_meth if (verbosity) { logprintf ( "Sending query of size %d to DC (%s:%d)\n", 4 * ints, DC->ip, DC->port); } - struct query *q = malloc (sizeof (*q)); - memset (q, 0, sizeof (*q)); + struct query *q = talloc0 (sizeof (*q)); q->data_len = ints; - q->data = malloc (4 * ints); + q->data = talloc (4 * ints); memcpy (q->data, data, 4 * ints); q->msg_id = encrypt_send_message (DC->sessions[0]->c, data, ints, 1); q->session = DC->sessions[0]; @@ -436,7 +435,7 @@ char *suser; extern int dc_working_num; void do_send_code (const char *user) { logprintf ("sending code\n"); - suser = strdup (user); + suser = tstrdup (user); want_dc_num = 0; clear_packet (); do_insert_header (); @@ -527,7 +526,7 @@ struct query_methods check_phone_methods = { }; int do_auth_check_phone (const char *user) { - suser = strdup (user); + suser = tstrdup (user); clear_packet (); out_int (CODE_auth_check_phone); out_string (user); @@ -1363,8 +1362,7 @@ void send_part (struct send_file *f) { out_long (-lrand48 () * (1ll << 32) - lrand48 ()); send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &send_file_methods, 0); } else { - struct message *M = malloc (sizeof (*M)); - memset (M, 0, sizeof (*M)); + struct message *M = talloc0 (sizeof (*M)); out_int (CODE_messages_send_encrypted_file); out_int (CODE_input_encrypted_chat); @@ -1446,7 +1444,7 @@ void send_part (struct send_file *f) { M->from_id = MK_USER (our_id); M->to_id = f->to_id; M->unread = 1; - M->message = strdup (""); + M->message = tstrdup (""); M->out = 1; M->id = r; M->date = time (0); @@ -1483,8 +1481,7 @@ void do_send_photo (int type, peer_id_t to_id, char *file_name) { close (fd); return; } - struct send_file *f = malloc (sizeof (*f)); - memset (f, 0, sizeof (*f)); + struct send_file *f = talloc0 (sizeof (*f)); f->fd = fd; f->size = size; f->offset = 0; @@ -1501,11 +1498,11 @@ void do_send_photo (int type, peer_id_t to_id, char *file_name) { f->file_name = file_name; if (get_peer_type (f->to_id) == PEER_ENCR_CHAT) { f->encr = 1; - f->iv = malloc (32); + f->iv = talloc (32); secure_random (f->iv, 32); - f->init_iv = malloc (32); + f->init_iv = talloc (32); memcpy (f->init_iv, f->iv, 32); - f->key = malloc (32); + f->key = talloc (32); secure_random (f->key, 32); } if (f->part_size > (512 << 10)) { @@ -1831,7 +1828,7 @@ void load_next_part (struct download *D) { } else { sprintf (buf, "%s/download_%lld", get_downloads_directory (), D->id); } - D->name = strdup (buf); + D->name = tstrdup (buf); struct stat st; if (stat (buf, &st) >= 0) { D->offset = st.st_size; @@ -1878,8 +1875,7 @@ void do_load_photo_size (struct photo_size *P, int next) { assert (P); assert (next); - struct download *D = malloc (sizeof (*D)); - memset (D, 0, sizeof (*D)); + struct download *D = talloc0 (sizeof (*D)); D->id = 0; D->offset = 0; D->size = P->size; @@ -1918,8 +1914,7 @@ void do_load_document_thumb (struct document *video, int next) { void do_load_video (struct video *V, int next) { assert (V); assert (next); - struct download *D = malloc (sizeof (*D)); - memset (D, 0, sizeof (*D)); + struct download *D = talloc0 (sizeof (*D)); D->offset = 0; D->size = V->size; D->id = V->id; @@ -1935,8 +1930,7 @@ void do_load_video (struct video *V, int next) { void do_load_document (struct document *V, int next) { assert (V); assert (next); - struct download *D = malloc (sizeof (*D)); - memset (D, 0, sizeof (*D)); + struct download *D = talloc0 (sizeof (*D)); D->offset = 0; D->size = V->size; D->id = V->id; @@ -1952,8 +1946,7 @@ void do_load_document (struct document *V, int next) { void do_load_encr_video (struct encr_video *V, int next) { assert (V); assert (next); - struct download *D = malloc (sizeof (*D)); - memset (D, 0, sizeof (*D)); + struct download *D = talloc0 (sizeof (*D)); D->offset = 0; D->size = V->size; D->id = V->id; @@ -1963,7 +1956,7 @@ void do_load_encr_video (struct encr_video *V, int next) { D->name = 0; D->fd = -1; D->key = V->key; - D->iv = malloc (32); + D->iv = talloc (32); memcpy (D->iv, V->iv, 32); load_next_part (D); @@ -1995,7 +1988,7 @@ int export_auth_on_answer (struct query *q UU) { assert (our_id == l); } l = prefetch_strlen (); - char *s = malloc (l); + char *s = talloc (l); memcpy (s, fetch_str (l), l); export_auth_str_len = l; export_auth_str = s; @@ -2261,18 +2254,19 @@ void do_send_accept_encr_chat (struct secret_chat *E, unsigned char *random) { random[i] ^= random_here[i]; } BIGNUM *b = BN_bin2bn (random, 256, 0); - assert (b); + ensure_ptr (b); BIGNUM *g_a = BN_bin2bn (E->g_key, 256, 0); - assert (g_a); + ensure_ptr (g_a); assert (check_g (encr_prime, g_a) >= 0); if (!ctx) { ctx = BN_CTX_new (); - BN_CTX_init (ctx); + ensure_ptr (ctx); } BIGNUM *p = BN_bin2bn (encr_prime, 256, 0); + ensure_ptr (p); BIGNUM *r = BN_new (); - BN_init (r); - BN_mod_exp (r, g_a, b, p, ctx); + ensure_ptr (r); + ensure (BN_mod_exp (r, g_a, b, p, ctx)); static unsigned char kk[256]; memset (kk, 0, sizeof (kk)); BN_bn2bin (r, kk); @@ -2290,8 +2284,8 @@ void do_send_accept_encr_chat (struct secret_chat *E, unsigned char *random) { out_int (get_peer_id (E->id)); out_long (E->access_hash); - BN_set_word (g_a, encr_root); - BN_mod_exp (r, g_a, b, p, ctx); + ensure (BN_set_word (g_a, encr_root)); + ensure (BN_mod_exp (r, g_a, b, p, ctx)); static unsigned char buf[256]; memset (buf, 0, sizeof (buf)); BN_bn2bin (r, buf); @@ -2309,19 +2303,21 @@ void do_send_accept_encr_chat (struct secret_chat *E, unsigned char *random) { void do_create_keys_end (struct secret_chat *U) { assert (encr_prime); BIGNUM *g_b = BN_bin2bn (U->g_key, 256, 0); - assert (g_b); + ensure_ptr (g_b); assert (check_g (encr_prime, g_b) >= 0); if (!ctx) { ctx = BN_CTX_new (); - BN_CTX_init (ctx); + ensure_ptr (ctx); } BIGNUM *p = BN_bin2bn (encr_prime, 256, 0); + ensure_ptr (p); BIGNUM *r = BN_new (); + ensure_ptr (r); BIGNUM *a = BN_bin2bn ((void *)U->key, 256, 0); - BN_init (r); - BN_mod_exp (r, g_b, a, p, ctx); + ensure_ptr (a); + ensure (BN_mod_exp (r, g_b, a, p, ctx)); - void *t = malloc (256); + void *t = talloc (256); memcpy (t, U->key, 256); memset (U->key, 0, sizeof (U->key)); @@ -2344,6 +2340,9 @@ void do_create_keys_end (struct secret_chat *U) { logprintf ("!!Key fingerprint mismatch (my 0x%llx 0x%llx)\n", (unsigned long long)k, (unsigned long long)U->key_fingerprint); U->state = sc_deleted; } + + memset (t, 0, 256); + free (t); BN_clear_free (p); BN_clear_free (g_b); @@ -2361,21 +2360,24 @@ void do_send_create_encr_chat (void *x, unsigned char *random) { } if (!ctx) { ctx = BN_CTX_new (); - BN_CTX_init (ctx); + ensure_ptr (ctx); } BIGNUM *a = BN_bin2bn (random, 256, 0); - assert (a); + ensure_ptr (a); BIGNUM *p = BN_bin2bn (encr_prime, 256, 0); + ensure_ptr (p); BIGNUM *g = BN_new (); - BN_init (g); + ensure_ptr (g); - BN_set_word (g, encr_root); + ensure (BN_set_word (g, encr_root)); BIGNUM *r = BN_new (); - BN_init (r); + ensure_ptr (r); - BN_mod_exp (r, g, a, p, ctx); + ensure (BN_mod_exp (r, g, a, p, ctx)); + + BN_clear_free (a); static char g_a[256]; memset (g_a, 0, 256); @@ -2428,6 +2430,7 @@ int get_dh_config_on_answer (struct query *q UU) { bl_do_set_dh_params (a, (void *)s, v); BIGNUM *p = BN_bin2bn ((void *)s, 256, 0); + ensure_ptr (p); assert (check_DH_params (p, a) >= 0); BN_free (p); } @@ -2457,7 +2460,7 @@ void do_accept_encr_chat_request (struct secret_chat *E) { out_int (CODE_messages_get_dh_config); out_int (encr_param_version); out_int (256); - void **x = malloc (2 * sizeof (void *)); + void **x = talloc (2 * sizeof (void *)); x[0] = do_send_accept_encr_chat; x[1] = E; send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &get_dh_config_methods, x); @@ -2468,7 +2471,7 @@ void do_create_encr_chat_request (int user_id) { out_int (CODE_messages_get_dh_config); out_int (encr_param_version); out_int (256); - void **x = malloc (2 * sizeof (void *)); + void **x = talloc (2 * sizeof (void *)); x[0] = do_send_create_encr_chat; x[1] = (void *)(long)(user_id); send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &get_dh_config_methods, x); diff --git a/structures.c b/structures.c index 014a8e9..2992fe7 100644 --- a/structures.c +++ b/structures.c @@ -179,7 +179,7 @@ char *create_print_name (peer_id_t id, const char *a1, const char *a2, const cha assert (cc <= 9999); sprintf (s + fl, "#%d", cc); } - return strdup (s); + return tstrdup (s); } /* @@ -564,7 +564,7 @@ void fetch_chat_full (struct chat *C) { admin_id = fetch_int (); assert (fetch_int () == CODE_vector); users_num = fetch_int (); - users = malloc (sizeof (struct chat_user) * users_num); + users = talloc (sizeof (struct chat_user) * users_num); int i; for (i = 0; i < users_num; i++) { assert (fetch_int () == (int)CODE_chat_participant); @@ -613,8 +613,7 @@ void fetch_photo_size (struct photo_size *S) { S->size = fetch_int (); } else { S->size = prefetch_strlen (); -// S->data = malloc (S->size); -// assert (S->data); +// S->data = talloc (S->size); fetch_str (S->size); // memcpy (S->data, fetch_str (S->size), S->size); } @@ -671,7 +670,7 @@ void fetch_photo (struct photo *P) { fetch_geo (&P->geo); assert (fetch_int () == CODE_vector); P->sizes_num = fetch_int (); - P->sizes = malloc (sizeof (struct photo_size) * P->sizes_num); + P->sizes = talloc (sizeof (struct photo_size) * P->sizes_num); int i; for (i = 0; i < P->sizes_num; i++) { fetch_photo_size (&P->sizes[i]); @@ -795,7 +794,7 @@ void fetch_message_action (struct message_action *M) { M->title = fetch_str_dup (); assert (fetch_int () == (int)CODE_vector); M->user_num = fetch_int (); - M->users = malloc (M->user_num * 4); + M->users = talloc (M->user_num * 4); fetch_ints (M->users, M->user_num); break; case CODE_message_action_chat_edit_title: @@ -1092,14 +1091,14 @@ void fetch_message_media_encrypted (struct message_media *M) { l = prefetch_strlen (); assert (l > 0); - M->encr_photo.key = malloc (32); + M->encr_photo.key = talloc (32); memset (M->encr_photo.key, 0, 32); if (l <= 32) { memcpy (M->encr_photo.key + (32 - l), fetch_str (l), l); } else { memcpy (M->encr_photo.key, fetch_str (l) + (l - 32), 32); } - M->encr_photo.iv = malloc (32); + M->encr_photo.iv = talloc (32); l = prefetch_strlen (); assert (l > 0); memset (M->encr_photo.iv, 0, 32); @@ -1122,14 +1121,13 @@ void fetch_message_media_encrypted (struct message_media *M) { l = prefetch_strlen (); assert (l > 0); - M->encr_video.key = malloc (32); - memset (M->encr_photo.key, 0, 32); + M->encr_video.key = talloc0 (32); if (l <= 32) { memcpy (M->encr_video.key + (32 - l), fetch_str (l), l); } else { memcpy (M->encr_video.key, fetch_str (l) + (l - 32), 32); } - M->encr_video.iv = malloc (32); + M->encr_video.iv = talloc (32); l = prefetch_strlen (); assert (l > 0); memset (M->encr_video.iv, 0, 32); @@ -1146,17 +1144,15 @@ void fetch_message_media_encrypted (struct message_media *M) { l = prefetch_strlen (); assert (l > 0); - M->encr_video.key = malloc (32); - memset (M->encr_photo.key, 0, 32); + M->encr_video.key = talloc0 (32); if (l <= 32) { memcpy (M->encr_video.key + (32 - l), fetch_str (l), l); } else { memcpy (M->encr_video.key, fetch_str (l) + (l - 32), 32); } - M->encr_video.iv = malloc (32); + M->encr_video.iv = talloc0 (32); l = prefetch_strlen (); assert (l > 0); - memset (M->encr_video.iv, 0, 32); if (l <= 32) { memcpy (M->encr_video.iv + (32 - l), fetch_str (l), l); } else { @@ -1175,17 +1171,15 @@ void fetch_message_media_encrypted (struct message_media *M) { l = prefetch_strlen (); assert (l > 0); - M->encr_video.key = malloc (32); - memset (M->encr_photo.key, 0, 32); + M->encr_video.key = talloc0 (32); if (l <= 32) { memcpy (M->encr_video.key + (32 - l), fetch_str (l), l); } else { memcpy (M->encr_video.key, fetch_str (l) + (l - 32), 32); } - M->encr_video.iv = malloc (32); + M->encr_video.iv = talloc0 (32); l = prefetch_strlen (); assert (l > 0); - memset (M->encr_video.iv, 0, 32); if (l <= 32) { memcpy (M->encr_video.iv + (32 - l), fetch_str (l), l); } else { @@ -1199,12 +1193,12 @@ void fetch_message_media_encrypted (struct message_media *M) { fetch_str (l); // thumb l = fetch_int (); assert (l > 0); - M->encr_file.key = malloc (l); + M->encr_file.key = talloc (l); memcpy (M->encr_file.key, fetch_str (l), l); l = fetch_int (); assert (l > 0); - M->encr_file.iv = malloc (l); + M->encr_file.iv = talloc (l); memcpy (M->encr_file.iv, fetch_str (l), l); break; */ @@ -1521,8 +1515,7 @@ struct user *fetch_alloc_user (void) { peer_t *U = user_chat_get (MK_USER (data[1])); if (!U) { users_allocated ++; - U = malloc (sizeof (*U)); - memset (U, 0, sizeof (*U)); + U = talloc0 (sizeof (*U)); U->id = MK_USER (data[1]); peer_tree = tree_insert_peer (peer_tree, U, lrand48 ()); assert (peer_num < MAX_PEER_NUM); @@ -1537,8 +1530,7 @@ struct secret_chat *fetch_alloc_encrypted_chat (void) { prefetch_data (data, 8); peer_t *U = user_chat_get (MK_ENCR_CHAT (data[1])); if (!U) { - U = malloc (sizeof (*U)); - memset (U, 0, sizeof (*U)); + U = talloc0 (sizeof (*U)); U->id = MK_ENCR_CHAT (data[1]); encr_chats_allocated ++; peer_tree = tree_insert_peer (peer_tree, U, lrand48 ()); @@ -1579,8 +1571,7 @@ struct user *fetch_alloc_user_full (void) { return &U->user; } else { users_allocated ++; - U = malloc (sizeof (*U)); - memset (U, 0, sizeof (*U)); + U = talloc0 (sizeof (*U)); U->id = MK_USER (data[2]); peer_tree = tree_insert_peer (peer_tree, U, lrand48 ()); fetch_user_full (&U->user); @@ -1724,8 +1715,7 @@ void message_add_peer (struct message *M) { } peer_t *P = user_chat_get (id); if (!P) { - P = malloc (sizeof (*P)); - memset (P, 0, sizeof (*P)); + P = talloc0 (sizeof (*P)); P->id = id; switch (get_peer_type (id)) { case PEER_USER: @@ -1799,8 +1789,7 @@ struct message *fetch_alloc_message (void) { struct message *M = message_get (data[1]); if (!M) { - M = malloc (sizeof (*M)); - memset (M, 0, sizeof (*M)); + M = talloc0 (sizeof (*M)); M->id = data[1]; message_insert_tree (M); messages_allocated ++; @@ -1810,7 +1799,7 @@ struct message *fetch_alloc_message (void) { } struct message *fetch_alloc_geo_message (void) { - struct message *M = malloc (sizeof (*M)); + struct message *M = talloc (sizeof (*M)); fetch_geo_message (M); struct message *M1 = tree_lookup_message (message_tree, M); messages_allocated ++; @@ -1838,8 +1827,7 @@ struct message *fetch_alloc_encrypted_message (void) { struct message *M = message_get (*(long long *)(data + 1)); if (!M) { - M = malloc (sizeof (*M)); - memset (M, 0, sizeof (*M)); + M = talloc0 (sizeof (*M)); M->id = *(long long *)(data + 1); message_insert_tree (M); messages_allocated ++; @@ -1856,8 +1844,7 @@ struct message *fetch_alloc_message_short (void) { struct message *M = message_get (data[0]); if (!M) { - M = malloc (sizeof (*M)); - memset (M, 0, sizeof (*M)); + M = talloc0 (sizeof (*M)); M->id = data[0]; message_insert_tree (M); messages_allocated ++; @@ -1872,8 +1859,7 @@ struct message *fetch_alloc_message_short_chat (void) { struct message *M = message_get (data[0]); if (!M) { - M = malloc (sizeof (*M)); - memset (M, 0, sizeof (*M)); + M = talloc0 (sizeof (*M)); M->id = data[0]; message_insert_tree (M); messages_allocated ++; @@ -1888,8 +1874,7 @@ struct chat *fetch_alloc_chat (void) { peer_t *U = user_chat_get (MK_CHAT (data[1])); if (!U) { chats_allocated ++; - U = malloc (sizeof (*U)); - memset (U, 0, sizeof (*U)); + U = talloc0 (sizeof (*U)); U->id = MK_CHAT (data[1]); peer_tree = tree_insert_peer (peer_tree, U, lrand48 ()); assert (peer_num < MAX_PEER_NUM); @@ -1908,8 +1893,7 @@ struct chat *fetch_alloc_chat_full (void) { return &U->chat; } else { chats_allocated ++; - U = malloc (sizeof (*U)); - memset (U, 0, sizeof (*U)); + U = talloc0 (sizeof (*U)); U->id = MK_CHAT (data[2]); peer_tree = tree_insert_peer (peer_tree, U, lrand48 ()); fetch_chat_full (&U->chat); diff --git a/tools.c b/tools.c new file mode 100644 index 0000000..bcaa527 --- /dev/null +++ b/tools.c @@ -0,0 +1,66 @@ +/* + This file is part of telegram-client. + + Telegram-client is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Telegram-client is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this telegram-client. If not, see . + + Copyright Vitaly Valtman 2013 +*/ + +#include +#include +#include +#include +#include + +#include "interface.h" +#include "tools.h" + +static void out_of_memory (void) { + logprintf ("Out of memory\n"); + assert (0 && "Out of memory"); +} + +void *talloc (size_t size) { + void *p = malloc (size); + ensure_ptr (p); + return p; +} + +void *talloc0 (size_t size) { + void *p = talloc (size); + memset (p, 0, size); + return p; +} + +char *tstrdup (const char *s) { + char *p = strdup (s); + if (p == NULL) { + out_of_memory (); + } + return p; +} + +void ensure (int r) { + if (!r) { + logprintf ("Open SSL error\n"); + ERR_print_errors_fp (stderr); + assert (0); + } +} + +void ensure_ptr (void *p) { + if (p == NULL) { + out_of_memory (); + } +} diff --git a/tools.h b/tools.h new file mode 100644 index 0000000..f3f7f88 --- /dev/null +++ b/tools.h @@ -0,0 +1,29 @@ +/* + This file is part of telegram-client. + + Telegram-client is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Telegram-client is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this telegram-client. If not, see . + + Copyright Vitaly Valtman 2013 +*/ + +#ifndef __TOOLS_H__ +#define __TOOLS_H__ + +void *talloc (size_t size); +void *talloc0 (size_t size); +char *tstrdup (const char *s); +void ensure (int r); +void ensure_ptr (void *p); + +#endif