1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-09-29 02:25:36 +02:00

Use DNS server list instead of hard coding domains/keys

This commit is contained in:
Jfreegman 2014-08-10 21:40:19 -04:00
parent 2f12a8d429
commit d9a861331f
No known key found for this signature in database
GPG Key ID: 3627F3144076AE63
6 changed files with 145 additions and 36 deletions

View File

@ -1,7 +1,7 @@
MISC_DIR = ../misc
DOC_DIR = ../doc
SND_DIR = ../sounds
DATAFILES = DHTnodes toxic.conf.example
DATAFILES = DHTnodes DNSservers toxic.conf.example
MANFILES = toxic.1 toxic.conf.5
SNDFILES = ContactLogsIn.wav ContactLogsOut.wav Error.wav IncomingCall.wav
SNDFILES += LogIn.wav LogOut.wav NewMessage.wav OutgoingCall.wav

2
misc/DNSservers Normal file
View File

@ -0,0 +1,2 @@
utox.org d3154f65d28a5b41a05d4ac7e4b39c6b1c233cc857fb365c56e8392737462a12
toxme.se 5d72c517df6aec54f1e977a6b6f25914ea4cf7277a85027cd9f5196df17e0b13

128
src/dns.c
View File

@ -40,19 +40,21 @@
#include "dns.h"
#include "global_commands.h"
#include "misc_tools.h"
#include "configdir.h"
#define DNS3_KEY_SIZE 32
#define MAX_DNS_REQST_SIZE 256
#define NUM_DNS3_SERVERS 2 /* must correspond to number of items in dns3_servers array */
#define NUM_DNS3_BACKUP_SERVERS 2 /* must correspond to number of items in dns3_servers array */
#define TOX_DNS3_TXT_PREFIX "v=tox3;id="
#define DNS3_KEY_SZ 32
extern struct _Winthread Winthread;
extern struct _dns3_servers dns3_servers;
/* TODO: process keys from key file instead of hard-coding like a noob */
static struct dns3_server {
/* Hardcoded backup in case domain list is not loaded */
static struct dns3_server_backup {
const char *name;
char key[DNS3_KEY_SZ];
} dns3_servers[] = {
char key[DNS3_KEY_SIZE];
} dns3_servers_backup[] = {
{
"utox.org",
{
@ -84,6 +86,54 @@ static struct _dns_thread {
} dns_thread;
#define MAX_DNS_SERVERS 50
#define MAX_DOMAIN_SIZE 128
#define MAX_DNS_LINE MAX_DOMAIN_SIZE + DNS3_KEY_SIZE + 2
struct _dns3_servers {
bool loaded;
int lines;
char names[MAX_DNS_SERVERS][MAX_DOMAIN_SIZE];
char keys[MAX_DNS_SERVERS][DNS3_KEY_SIZE];
} dns3_servers;
static int load_dns_domainlist(void)
{
const char *path = PACKAGE_DATADIR "/DNSservers";
FILE *fp = fopen(path, "r");
if (fp == NULL)
return -1;
char line[MAX_DNS_LINE];
while (fgets(line, sizeof(line), fp) && dns3_servers.lines < MAX_DNS_SERVERS) {
if (strlen(line) < (2 * DNS3_KEY_SIZE) + 4)
continue;
const char *name = strtok(line, " ");
const char *keystr = strtok(NULL, " ");
if (name == NULL || keystr == NULL)
continue;
snprintf(dns3_servers.names[dns3_servers.lines], sizeof(dns3_servers.names[dns3_servers.lines]), "%s", name);
int res = hex_string_to_bytes(dns3_servers.keys[dns3_servers.lines], DNS3_KEY_SIZE, keystr, strlen(keystr));
if (res == -1)
continue;
++dns3_servers.lines;
}
fclose(fp);
if (dns3_servers.lines < 1)
return -2;
return 0;
}
static int dns_error(ToxWindow *self, const char *errmsg)
{
pthread_mutex_lock(&Winthread.lock);
@ -191,35 +241,61 @@ static int parse_addr(const char *addr, char *namebuf, char *dombuf)
return strlen(namebuf);
}
/* 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;
}
}
/* 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;
}
/* 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 domain[MAX_STR_SIZE];
char inputdomain[MAX_STR_SIZE];
char name[MAX_STR_SIZE];
int namelen = parse_addr(t_data.addr, name, domain);
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");
kill_dns_thread(NULL);
}
/* get domain name/pub key */
const char *DNS_pubkey = NULL;
const char *domname = NULL;
int i;
char DNS_pubkey[DNS3_KEY_SIZE];
char domain[MAX_DOMAIN_SIZE];
for (i = 0; i < NUM_DNS3_SERVERS; ++i) {
if (strcmp(dns3_servers[i].name, domain) == 0) {
DNS_pubkey = dns3_servers[i].key;
domname = dns3_servers[i].name;
break;
}
}
int match = get_domain_match(DNS_pubkey, domain, inputdomain);
if (domname == NULL) {
if (match == -1) {
dns_error(self, "Domain not found.");
kill_dns_thread(NULL);
}
@ -248,7 +324,7 @@ void *dns3_lookup_thread(void *data)
char d_string[MAX_DNS_REQST_SIZE];
/* format string and create dns query */
snprintf(d_string, sizeof(d_string), "_%s._tox.%s", string, domname);
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) {
@ -296,6 +372,16 @@ void dns3_lookup(ToxWindow *self, Tox *m, const char *id_bin, const char *addr,
return;
}
if (!dns3_servers.loaded) {
dns3_servers.loaded = true;
int ret = load_dns_domainlist();
if (ret < 0) {
const char *errmsg = "DNS server list failed to load with error code %d. Falling back to hard-coded list.";
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg, ret);
}
}
snprintf(t_data.id_bin, sizeof(t_data.id_bin), "%s", id_bin);
snprintf(t_data.addr, sizeof(t_data.addr), "%s", addr);
snprintf(t_data.msg, sizeof(t_data.msg), "%s", msg);

View File

@ -124,6 +124,25 @@ char *hex_string_to_bin(const char *hex_string)
return val;
}
int hex_string_to_bytes(char *buf, int size, const char *keystr, int strsize)
{
if (size % 2 != 0)
return -1;
int i, res;
const char *pos = keystr;
for (i = 0; i < size; ++i) {
res = sscanf(pos, "%2hhx", &buf[i]);
pos += 2;
if (res == EOF || res < 1)
return -1;
}
return 0;
}
/* Returns 1 if the string is empty, 0 otherwise */
int string_is_empty(const char *string)
{

View File

@ -42,6 +42,9 @@ void host_to_net(uint8_t *num, uint16_t numbytes);
/* convert a hex string to binary */
char *hex_string_to_bin(const char *hex_string);
/* convert a hex string to bytes. returns 0 on success, -1 on failure */
int hex_string_to_bytes(char *buf, int size, const char *keystr, int strsize);
/* get the current unix time */
uint64_t get_unix_time(void);

View File

@ -226,10 +226,10 @@ static Tox *init_tox(int ipv4)
return m;
}
#define MINLINE 50 /* IP: 7 + port: 5 + key: 38 + spaces: 2 = 70. ! (& e.g. tox.im = 6) */
#define MAXLINE 256 /* Approx max number of chars in a sever line (name + port + key) */
#define MIN_NODE_LINE 50 /* IP: 7 + port: 5 + key: 38 + spaces: 2 = 70. ! (& e.g. tox.im = 6) */
#define MAX_NODE_LINE 256 /* Approx max number of chars in a sever line (name + port + key) */
#define MAXNODES 50
#define NODELEN (MAXLINE - TOX_CLIENT_ID_SIZE - 7)
#define NODELEN (MAX_NODE_LINE - TOX_CLIENT_ID_SIZE - 7)
static struct _toxNodes {
int lines;
@ -238,7 +238,7 @@ static struct _toxNodes {
char keys[MAXNODES][TOX_CLIENT_ID_SIZE];
} toxNodes;
static int nodelist_load(const char *filename)
static int load_nodelist(const char *filename)
{
if (!filename)
return 1;
@ -248,10 +248,10 @@ static int nodelist_load(const char *filename)
if (fp == NULL)
return 1;
char line[MAXLINE];
char line[MAX_NODE_LINE];
while (fgets(line, sizeof(line), fp) && toxNodes.lines < MAXNODES) {
if (strlen(line) > MINLINE) {
if (strlen(line) > MIN_NODE_LINE) {
const char *name = strtok(line, " ");
const char *port = strtok(NULL, " ");
const char *key_ascii = strtok(NULL, " ");
@ -272,12 +272,11 @@ static int nodelist_load(const char *filename)
}
}
if (toxNodes.lines < 1) {
fclose(fp);
return 2;
}
fclose(fp);
if (toxNodes.lines < 1)
return 1;
return 0;
}
@ -313,11 +312,11 @@ int init_connection(Tox *m)
int res;
if (!arg_opts.nodes_path[0])
res = nodelist_load(PACKAGE_DATADIR "/DHTnodes");
res = load_nodelist(PACKAGE_DATADIR "/DHTnodes");
else
res = nodelist_load(arg_opts.nodes_path);
res = load_nodelist(arg_opts.nodes_path);
if (toxNodes.lines < 1)
if (res != 0)
return res;
res = 3;