From 69be1bc3989ecb635554c7c6536ba18c1f1b23d0 Mon Sep 17 00:00:00 2001 From: Jfreegman Date: Fri, 28 Aug 2015 02:44:38 -0400 Subject: [PATCH 1/5] Fix nodes parsing bug --- src/toxic.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/toxic.c b/src/toxic.c index a0796da..849d441 100644 --- a/src/toxic.c +++ b/src/toxic.c @@ -316,16 +316,14 @@ static int load_nodelist(const char *filename) toxNodes.ports[toxNodes.lines] = atoi(port); /* remove possible trailing newline from key string */ - char key_binary[TOX_PUBLIC_KEY_SIZE * 2 + 1]; - memcpy(key_binary, key_ascii, TOX_PUBLIC_KEY_SIZE * 2); + char real_ascii_key[TOX_PUBLIC_KEY_SIZE * 2 + 1]; + memcpy(real_ascii_key, key_ascii, TOX_PUBLIC_KEY_SIZE * 2); key_len = TOX_PUBLIC_KEY_SIZE * 2; - key_binary[key_len] = '\0'; + real_ascii_key[key_len] = '\0'; - if (hex_string_to_bin(key_ascii, key_len, key_binary, TOX_PUBLIC_KEY_SIZE) == -1) + if (hex_string_to_bin(real_ascii_key, key_len, toxNodes.keys[toxNodes.lines], TOX_PUBLIC_KEY_SIZE) == -1) continue; - memcpy(toxNodes.keys[toxNodes.lines], key_binary, TOX_PUBLIC_KEY_SIZE); - toxNodes.lines++; } } From ffcc804efe84bc4285f5fcc34a8f301fd40fa8d4 Mon Sep 17 00:00:00 2001 From: Jfreegman Date: Tue, 1 Sep 2015 13:00:56 -0400 Subject: [PATCH 2/5] Moved version up --- cfg/global_vars.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cfg/global_vars.mk b/cfg/global_vars.mk index 5d192de..a62d277 100644 --- a/cfg/global_vars.mk +++ b/cfg/global_vars.mk @@ -1,5 +1,5 @@ # Version -TOXIC_VERSION = 0.6.0 +TOXIC_VERSION = 0.6.1 REV = $(shell git rev-list HEAD --count 2>/dev/null || echo -n "error") ifneq (, $(findstring error, $(REV))) VERSION = $(TOXIC_VERSION) From f29535249547dfd74a5f727afbe18f0077b5b6af Mon Sep 17 00:00:00 2001 From: Jfreegman Date: Wed, 2 Sep 2015 19:41:21 -0400 Subject: [PATCH 3/5] Replace instances of unsafe atoi function with safe counterpart --- src/chat_commands.c | 12 ++++++------ src/global_commands.c | 18 ++++++++++-------- src/toxic.c | 33 +++++++++++++++++++++++++++------ src/toxic.h | 4 ++++ 4 files changed, 47 insertions(+), 20 deletions(-) diff --git a/src/chat_commands.c b/src/chat_commands.c index 2a4b8e7..3e479cc 100644 --- a/src/chat_commands.c +++ b/src/chat_commands.c @@ -45,9 +45,9 @@ void cmd_cancelfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*ar char msg[MAX_STR_SIZE]; const char *inoutstr = argv[1]; - int idx = atoi(argv[2]); + long int idx = strtol(argv[2], NULL, 10); - if (idx >= MAX_FILES || idx < 0) { + if ((idx == 0 && strcmp(argv[2], "0")) || idx >= MAX_FILES || idx < 0) { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid file ID."); return; } @@ -85,9 +85,9 @@ void cmd_groupinvite(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*a return; } - int groupnum = atoi(argv[1]); + long int groupnum = strtol(argv[1], NULL, 10); - if (groupnum == 0 && strcmp(argv[1], "0")) { /* atoi returns 0 value on invalid input */ + if ((groupnum == 0 && strcmp(argv[1], "0")) || groupnum < 0 || groupnum == LONG_MAX) { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid group number."); return; } @@ -146,9 +146,9 @@ void cmd_savefile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv return; } - int idx = atoi(argv[1]); + long int idx = strtol(argv[1], NULL, 10); - if ((idx == 0 && strcmp(argv[1], "0")) || idx >= MAX_FILES) { + if ((idx == 0 && strcmp(argv[1], "0")) || idx < 0 || idx >= MAX_FILES) { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending file transfers with that ID."); return; } diff --git a/src/global_commands.c b/src/global_commands.c index 170a9ff..1ce3b21 100644 --- a/src/global_commands.c +++ b/src/global_commands.c @@ -50,9 +50,9 @@ void cmd_accept(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[ return; } - int req = atoi(argv[1]); + long int req = strtol(argv[1], NULL, 10); - if ((req == 0 && strcmp(argv[1], "0")) || req < 0 || req > MAX_FRIEND_REQUESTS) { + if ((req == 0 && strcmp(argv[1], "0")) || req < 0 || req >= MAX_FRIEND_REQUESTS) { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending friend request with that ID."); return; } @@ -248,10 +248,12 @@ void cmd_connect(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv) } const char *ip = argv[1]; - const char *port = argv[2]; + const char *port_str = argv[2]; const char *ascii_key = argv[3]; - if (atoi(port) == 0) { + long int port = strtol(port_str, NULL, 10); + + if (port <= 0 || port > MAX_PORT_RANGE) { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid port."); return; } @@ -263,8 +265,8 @@ void cmd_connect(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv) } TOX_ERR_BOOTSTRAP err; - tox_bootstrap(m, ip, atoi(port), (uint8_t *) key_binary, &err); - tox_add_tcp_relay(m, ip, atoi(port), (uint8_t *) key_binary, &err); + tox_bootstrap(m, ip, port, (uint8_t *) key_binary, &err); + tox_add_tcp_relay(m, ip, port, (uint8_t *) key_binary, &err); switch (err) { case TOX_ERR_BOOTSTRAP_BAD_HOST: @@ -290,9 +292,9 @@ void cmd_decline(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv) return; } - int req = atoi(argv[1]); + long int req = strtol(argv[1], NULL, 10); - if ((req == 0 && strcmp(argv[1], "0")) || req < 0 || req > MAX_FRIEND_REQUESTS) { + if ((req == 0 && strcmp(argv[1], "0")) || req < 0 || req >= MAX_FRIEND_REQUESTS) { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending friend request with that ID."); return; } diff --git a/src/toxic.c b/src/toxic.c index 849d441..012671f 100644 --- a/src/toxic.c +++ b/src/toxic.c @@ -299,10 +299,15 @@ static int load_nodelist(const char *filename) if (line_len >= MIN_NODE_LINE && line_len <= MAX_NODE_LINE) { const char *name = strtok(line, " "); - const char *port = strtok(NULL, " "); + const char *port_str = strtok(NULL, " "); const char *key_ascii = strtok(NULL, " "); - if (name == NULL || port == NULL || key_ascii == NULL) + if (name == NULL || port_str == NULL || key_ascii == NULL) + continue; + + long int port = strtol(port_str, NULL, 10); + + if (port <= 0 || port > MAX_PORT_RANGE) continue; size_t key_len = strlen(key_ascii); @@ -313,7 +318,7 @@ static int load_nodelist(const char *filename) snprintf(toxNodes.nodes[toxNodes.lines], sizeof(toxNodes.nodes[toxNodes.lines]), "%s", name); toxNodes.nodes[toxNodes.lines][NODELEN - 1] = 0; - toxNodes.ports[toxNodes.lines] = atoi(port); + toxNodes.ports[toxNodes.lines] = port; /* remove possible trailing newline from key string */ char real_ascii_key[TOX_PUBLIC_KEY_SIZE * 2 + 1]; @@ -938,6 +943,7 @@ static void parse_args(int argc, char *argv[]) const char *opts_str = "4bdehotuxc:f:n:r:p:P:T:"; int opt, indexptr; + long int port = 0; while ((opt = getopt_long(argc, argv, opts_str, long_opts, &indexptr)) != -1) { switch (opt) { @@ -1014,7 +1020,12 @@ static void parse_args(int argc, char *argv[]) if (++optind > argc || argv[optind-1][0] == '-') exit_toxic_err("Proxy error", FATALERR_PROXY); - arg_opts.proxy_port = (uint16_t) atoi(argv[optind-1]); + port = strtol(argv[optind-1], NULL, 10); + + if (port <= 0 || port > MAX_PORT_RANGE) + exit_toxic_err("Proxy error", FATALERR_PROXY); + + arg_opts.proxy_port = port; break; case 'P': @@ -1024,7 +1035,12 @@ static void parse_args(int argc, char *argv[]) if (++optind > argc || argv[optind-1][0] == '-') exit_toxic_err("Proxy error", FATALERR_PROXY); - arg_opts.proxy_port = (uint16_t) atoi(argv[optind-1]); + port = strtol(argv[optind-1], NULL, 10); + + if (port <= 0 || port > MAX_PORT_RANGE) + exit_toxic_err("Proxy error", FATALERR_PROXY); + + arg_opts.proxy_port = port; break; case 'r': @@ -1040,7 +1056,12 @@ static void parse_args(int argc, char *argv[]) break; case 'T': - arg_opts.tcp_port = (uint16_t) atoi(optarg); + port = strtol(optarg, NULL, 10); + + if (port <= 0 || port > MAX_PORT_RANGE) + port = 14191; + + arg_opts.tcp_port = port; break; case 'u': diff --git a/src/toxic.h b/src/toxic.h index 6129fab..67c8d85 100644 --- a/src/toxic.h +++ b/src/toxic.h @@ -49,6 +49,10 @@ #define KEY_IDENT_DIGITS 3 /* number of hex digits to display for the pub-key based identifier */ #define TIME_STR_SIZE 32 +#ifndef MAX_PORT_RANGE +#define MAX_PORT_RANGE 65535 +#endif + /* ASCII key codes */ #define T_KEY_ESC 0x1B /* ESC key */ #define T_KEY_KILL 0x0B /* ctrl-k */ From a920f3edfe9982c553dea8f21f374772f8cae882 Mon Sep 17 00:00:00 2001 From: Jfreegman Date: Sat, 12 Sep 2015 21:31:19 -0400 Subject: [PATCH 4/5] Replace toxme.se with toxme.io in DNSservers list and remove hardcoded servers from source --- misc/DNSservers | 3 ++- src/dns.c | 45 ++------------------------------------------- 2 files changed, 4 insertions(+), 44 deletions(-) diff --git a/misc/DNSservers b/misc/DNSservers index d82acbe..379637d 100644 --- a/misc/DNSservers +++ b/misc/DNSservers @@ -1,2 +1,3 @@ utox.org d3154f65d28a5b41a05d4ac7e4b39c6b1c233cc857fb365c56e8392737462a12 -toxme.se 5d72c517df6aec54f1e977a6b6f25914ea4cf7277a85027cd9f5196df17e0b13 +toxme.io 1A39E7A5D5FA9CF155C751570A32E625698A60A55F6D88028F949F66144F4F25 + diff --git a/src/dns.c b/src/dns.c index 0403f6c..c5457a7 100644 --- a/src/dns.c +++ b/src/dns.c @@ -50,29 +50,6 @@ extern struct Winthread Winthread; extern struct dns3_servers dns3_servers; extern struct arg_opts arg_opts; -#define NUM_DNS3_BACKUP_SERVERS 2 - -/* Hardcoded backup in case domain list is not loaded */ -static struct dns3_server_backup { - const char *name; - char key[DNS3_KEY_SIZE]; -} dns3_servers_backup[] = { - { - "utox.org", - { - 0xD3, 0x15, 0x4F, 0x65, 0xD2, 0x8A, 0x5B, 0x41, 0xA0, 0x5D, 0x4A, 0xC7, 0xE4, 0xB3, 0x9C, 0x6B, - 0x1C, 0x23, 0x3C, 0xC8, 0x57, 0xFB, 0x36, 0x5C, 0x56, 0xE8, 0x39, 0x27, 0x37, 0x46, 0x2A, 0x12 - } - }, - { - "toxme.se", - { - 0x5D, 0x72, 0xC5, 0x17, 0xDF, 0x6A, 0xEC, 0x54, 0xF1, 0xE9, 0x77, 0xA6, 0xB6, 0xF2, 0x59, 0x14, - 0xEA, 0x4C, 0xF7, 0x27, 0x7A, 0x85, 0x02, 0x7C, 0xD9, 0xF5, 0x19, 0x6D, 0xF1, 0x7E, 0x0B, 0x13 - } - }, -}; - static struct thread_data { ToxWindow *self; char id_bin[TOX_ADDRESS_SIZE]; @@ -260,35 +237,17 @@ static int parse_addr(const char *addr, char *namebuf, size_t namebuf_sz, char * /* matches input domain name with domains in list and obtains key. Return 0 on success, -1 on failure */ static int get_domain_match(char *pubkey, char *domain, const char *inputdomain) { - /* check server list first */ int i; - bool match = false; for (i = 0; i < dns3_servers.lines; ++i) { if (strcmp(dns3_servers.names[i], inputdomain) == 0) { memcpy(pubkey, dns3_servers.keys[i], DNS3_KEY_SIZE); snprintf(domain, MAX_DOMAIN_SIZE, "%s", dns3_servers.names[i]); - match = true; - break; + return 0; } } - /* fall back to hard-coded domains on server list failure */ - if (!match) { - for (i = 0; i < NUM_DNS3_BACKUP_SERVERS; ++i) { - if (strcmp(dns3_servers_backup[i].name, inputdomain) == 0) { - memcpy(pubkey, dns3_servers_backup[i].key, DNS3_KEY_SIZE); - snprintf(domain, MAX_DOMAIN_SIZE, "%s", dns3_servers_backup[i].name); - match = true; - break; - } - } - - if (!match) - return -1; - } - - return 0; + return -1; } /* Does DNS lookup for addr and puts resulting tox id in id_bin. */ From db410cb01e78964897274152d1ad510a44c5d4a0 Mon Sep 17 00:00:00 2001 From: Jfreegman Date: Wed, 14 Oct 2015 23:09:11 -0400 Subject: [PATCH 5/5] Use profile name that conforms with the standard --- src/friendlist.c | 2 +- src/toxic.c | 74 ++++++++++++++++++++++++++++++++++++------------ 2 files changed, 57 insertions(+), 19 deletions(-) diff --git a/src/friendlist.c b/src/friendlist.c index be2856c..2e235cf 100644 --- a/src/friendlist.c +++ b/src/friendlist.c @@ -704,7 +704,7 @@ static void unblock_friend(Tox *m, uint32_t bnum) uint32_t friendnum = tox_friend_add_norequest(m, (uint8_t *) Blocked.list[bnum].pub_key, &err); if (err != TOX_ERR_FRIEND_ADD_OK) { - line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to unblock friend (error %d)\n", err); + line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to unblock friend (error %d)", err); return; } diff --git a/src/toxic.c b/src/toxic.c index 012671f..0a0c302 100644 --- a/src/toxic.c +++ b/src/toxic.c @@ -77,8 +77,8 @@ char *DATA_FILE = NULL; char *BLOCK_FILE = NULL; ToxWindow *prompt = NULL; -#define DATANAME "data" -#define BLOCKNAME "data-blocklist" +#define DATANAME "toxic_profile.tox" +#define BLOCKNAME "toxic_blocklist" #define AUTOSAVE_FREQ 60 #define MIN_PASSWORD_LEN 6 @@ -1076,26 +1076,67 @@ static void parse_args(int argc, char *argv[]) } } -static int init_default_data_files(void) +/* Looks for an old default profile data file and blocklist, and renames them to the new default names. + * Saves the old data files under the names "toxic_data.old" and "toxic_data_blocklist.old". + * + * Returns 0 on success. + * Returns -1 on failure. + */ +#define OLD_DATA_NAME "data" +#define OLD_DATA_BLOCKLIST_NAME "data-blocklist" +static int rename_old_profile(const char *user_config_dir) { - if (arg_opts.use_custom_data) + char old_data_file[strlen(user_config_dir) + strlen(CONFIGDIR) + strlen(OLD_DATA_NAME) + 1]; + snprintf(old_data_file, sizeof(old_data_file), "%s%s%s", user_config_dir, CONFIGDIR, OLD_DATA_NAME); + + if (!file_exists(old_data_file)) return 0; + if (rename(old_data_file, DATA_FILE) != 0) + return -1; + + queue_init_message("Data file has been moved to %s", DATA_FILE); + + char old_data_blocklist[strlen(user_config_dir) + strlen(CONFIGDIR) + strlen(OLD_DATA_BLOCKLIST_NAME) + 1]; + snprintf(old_data_blocklist, sizeof(old_data_blocklist), "%s%s%s", user_config_dir, CONFIGDIR, OLD_DATA_BLOCKLIST_NAME); + + if (!file_exists(old_data_blocklist)) + return 0; + + if (rename(old_data_blocklist, BLOCK_FILE) != 0) + return -1; + + return 0; +} + +/* Initializes the default config directory and data files used by toxic. + * + * Exits the process with an error on failure. + */ +static void init_default_data_files(void) +{ + if (arg_opts.use_custom_data) + return; + char *user_config_dir = get_user_config_dir(); + + if (user_config_dir == NULL) + exit_toxic_err("failed in init_default_data_files()", FATALERR_FILEOP); + int config_err = create_user_config_dirs(user_config_dir); - if (config_err) { + if (config_err == -1) { DATA_FILE = strdup(DATANAME); BLOCK_FILE = strdup(BLOCKNAME); if (DATA_FILE == NULL || BLOCK_FILE == NULL) - exit_toxic_err("failed in load_data_structures", FATALERR_MEMORY); + exit_toxic_err("failed in init_default_data_files()", FATALERR_MEMORY); } else { DATA_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen(DATANAME) + 1); BLOCK_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen(BLOCKNAME) + 1); if (DATA_FILE == NULL || BLOCK_FILE == NULL) - exit_toxic_err("failed in load_data_structures", FATALERR_MEMORY); + exit_toxic_err("failed in init_default_data_files()", FATALERR_MEMORY); strcpy(DATA_FILE, user_config_dir); strcat(DATA_FILE, CONFIGDIR); @@ -1106,8 +1147,11 @@ static int init_default_data_files(void) strcat(BLOCK_FILE, BLOCKNAME); } + /* For backwards compatibility with old toxic profile names. TODO: remove this some day */ + if (rename_old_profile(user_config_dir) == -1) + queue_init_message("Warning: Profile backwards compatibility failed."); + free(user_config_dir); - return config_err; } #define REC_TOX_DO_LOOPS_PER_SEC 25 @@ -1138,11 +1182,11 @@ void DnD_callback(const char* asdv, DropType dt) // pthread_mutex_lock(&Winthread.lock); // line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, asdv); - pthread_mutex_unlock(&Winthread.lock); + // pthread_mutex_unlock(&Winthread.lock); } #endif /* X11 */ -int main(int argc, char *argv[]) +int main(int argc, char **argv) { parse_args(argc, argv); @@ -1159,7 +1203,8 @@ int main(int argc, char *argv[]) /* Make sure all written files are read/writeable only by the current user. */ umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); - int config_err = init_default_data_files(); + init_default_data_files(); + bool datafile_exists = file_exists(DATA_FILE); if (datafile_exists) @@ -1227,13 +1272,6 @@ int main(int argc, char *argv[]) init_notify(60, 3000); - const char *msg; - - if (config_err) { - msg = "Unable to determine configuration directory. Defaulting to 'data' for data file..."; - queue_init_message("%s", msg); - } - if (settings_err == -1) queue_init_message("Failed to load user settings");