void cmd_add(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) { char *errmsg; if (argc < 1) { errmsg = "Invalid syntax."; line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg); return; } char *id = argv[1]; char msg[MAX_STR_SIZE]; if (argc > 1) { char *temp = argv[2]; if (temp[0] != '\"') { errmsg = "Message must be enclosed in quotes."; line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg); return; } ++temp; temp[strlen(temp) - 1] = '\0'; snprintf(msg, sizeof(msg), "%s", temp); } else { char selfname[TOX_MAX_NAME_LENGTH]; uint16_t n_len = tox_get_self_name(m, (uint8_t *) selfname); selfname[n_len] = '\0'; snprintf(msg, sizeof(msg), "Hello, my name is %s. Care to Tox?", selfname); } char id_bin[TOX_FRIEND_ADDRESS_SIZE] = {0}; uint16_t id_len = (uint16_t) strlen(id); /* try to add tox ID */ if (id_len == 2 * TOX_FRIEND_ADDRESS_SIZE) { size_t i; char xx[3]; uint32_t x; for (i = 0; i < TOX_FRIEND_ADDRESS_SIZE; ++i) { xx[0] = id[2 * i]; xx[1] = id[2 * i + 1]; xx[2] = '\0'; if (sscanf(xx, "%02x", &x) != 1) { errmsg = "Invalid ID."; line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg); return; } id_bin[i] = x; } cmd_add_helper(self, m, id_bin, msg); } else { /* assume id is a username@domain address and do DNS lookup */ dns3_lookup(self, m, id_bin, id, msg); } }
void cmd_add(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) { if (argc < 1) { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Tox ID or address required."); return; } const char *id = argv[1]; char msg[MAX_STR_SIZE]; if (argc > 1) { if (argv[2][0] != '\"') { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Message must be enclosed in quotes."); return; } /* remove opening and closing quotes */ char tmp[MAX_STR_SIZE]; snprintf(tmp, sizeof(tmp), "%s", &argv[2][1]); int len = strlen(tmp) - 1; tmp[len] = '\0'; snprintf(msg, sizeof(msg), "%s", tmp); } else { char selfname[TOX_MAX_NAME_LENGTH]; tox_self_get_name(m, (uint8_t *) selfname); size_t n_len = tox_self_get_name_size(m); selfname[n_len] = '\0'; snprintf(msg, sizeof(msg), "Hello, my name is %s. Care to Tox?", selfname); } char id_bin[TOX_ADDRESS_SIZE] = {0}; uint16_t id_len = (uint16_t) strlen(id); /* try to add tox ID */ if (id_len == 2 * TOX_ADDRESS_SIZE) { size_t i; char xx[3]; uint32_t x; for (i = 0; i < TOX_ADDRESS_SIZE; ++i) { xx[0] = id[2 * i]; xx[1] = id[2 * i + 1]; xx[2] = '\0'; if (sscanf(xx, "%02x", &x) != 1) { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid Tox ID."); return; } id_bin[i] = x; } cmd_add_helper(self, m, id_bin, msg); } else { /* assume id is a username@domain address and do DNS lookup */ dns3_lookup(self, m, id_bin, id, msg); } }
/* Does DNS lookup for addr and puts resulting tox id in id_bin. */ void *dns3_lookup_thread(void *data) { ToxWindow *self = t_data.self; char inputdomain[MAX_STR_SIZE]; char name[MAX_STR_SIZE]; int namelen = parse_addr(t_data.addr, name, inputdomain); if (namelen == -1) { dns_error(self, "Must be a Tox ID or an address in the form username@domain"); killdns_thread(NULL); } char DNS_pubkey[DNS3_KEY_SIZE]; char domain[MAX_DOMAIN_SIZE]; int match = get_domain_match(DNS_pubkey, domain, inputdomain); if (match == -1) { dns_error(self, "Domain not found."); killdns_thread(NULL); } void *dns_obj = tox_dns3_new((uint8_t *) DNS_pubkey); if (dns_obj == NULL) { dns_error(self, "Core failed to create DNS object."); killdns_thread(NULL); } char string[MAX_DNS_REQST_SIZE + 1]; uint32_t request_id; int str_len = tox_generate_dns3_string(dns_obj, (uint8_t *) string, sizeof(string), &request_id, (uint8_t *) name, namelen); if (str_len == -1) { dns_error(self, "Core failed to generate DNS3 string."); killdns_thread(dns_obj); } string[str_len] = '\0'; u_char answer[PACKETSZ]; char d_string[MAX_DOMAIN_SIZE + MAX_DNS_REQST_SIZE + 10]; /* format string and create dns query */ snprintf(d_string, sizeof(d_string), "_%s._tox.%s", string, domain); int ans_len = res_query(d_string, C_IN, T_TXT, answer, sizeof(answer)); if (ans_len <= 0) { dns_error(self, "DNS query failed."); killdns_thread(dns_obj); } char ans_id[MAX_DNS_REQST_SIZE + 1]; /* extract TXT from DNS response */ if (parse_dns_response(self, answer, ans_len, ans_id) == -1) killdns_thread(dns_obj); char encrypted_id[MAX_DNS_REQST_SIZE + 1]; int prfx_len = strlen(TOX_DNS3_TXT_PREFIX); /* extract the encrypted ID from TXT response */ if (strncmp(ans_id, TOX_DNS3_TXT_PREFIX, prfx_len) != 0) { dns_error(self, "Bad DNS3 TXT response."); killdns_thread(dns_obj); } memcpy(encrypted_id, ans_id + prfx_len, ans_len - prfx_len); if (tox_decrypt_dns3_TXT(dns_obj, (uint8_t *) t_data.id_bin, (uint8_t *) encrypted_id, strlen(encrypted_id), request_id) == -1) { dns_error(self, "Core failed to decrypt DNS response."); killdns_thread(dns_obj); } pthread_mutex_lock(&Winthread.lock); cmd_add_helper(self, t_data.m, t_data.id_bin, t_data.msg); pthread_mutex_unlock(&Winthread.lock); killdns_thread(dns_obj); return 0; }