mirror of
https://github.com/Tha14/toxic.git
synced 2025-06-20 04:56:36 +02:00
Merge with master
This commit is contained in:
@ -63,9 +63,9 @@ static void kill_infobox(ToxWindow *self);
|
||||
#endif /* AUDIO */
|
||||
|
||||
#ifdef AUDIO
|
||||
#define AC_NUM_CHAT_COMMANDS 27
|
||||
#define AC_NUM_CHAT_COMMANDS 28
|
||||
#else
|
||||
#define AC_NUM_CHAT_COMMANDS 20
|
||||
#define AC_NUM_CHAT_COMMANDS 21
|
||||
#endif /* AUDIO */
|
||||
|
||||
/* Array of chat command names used for tab completion. */
|
||||
@ -86,6 +86,7 @@ static const char chat_cmd_list[AC_NUM_CHAT_COMMANDS][MAX_CMDNAME_SIZE] = {
|
||||
{ "/myid" },
|
||||
{ "/nick" },
|
||||
{ "/note" },
|
||||
{ "/nospam" },
|
||||
{ "/quit" },
|
||||
{ "/savefile" },
|
||||
{ "/sendfile" },
|
||||
|
391
src/dns.c
391
src/dns.c
@ -1,391 +0,0 @@
|
||||
/* dns.c
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2014 Toxic All Rights Reserved.
|
||||
*
|
||||
* This file is part of Toxic.
|
||||
*
|
||||
* Toxic 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Toxic 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 Toxic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h> /* for u_char */
|
||||
#include <netinet/in.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <arpa/nameser_compat.h>
|
||||
#else
|
||||
#include <arpa/nameser.h>
|
||||
#endif /* ifdef __APPLE__ */
|
||||
|
||||
#include <tox/toxdns.h>
|
||||
|
||||
#include "toxic.h"
|
||||
#include "windows.h"
|
||||
#include "line_info.h"
|
||||
#include "dns.h"
|
||||
#include "global_commands.h"
|
||||
#include "misc_tools.h"
|
||||
#include "configdir.h"
|
||||
|
||||
#define DNS3_KEY_SIZE 32
|
||||
#define MAX_DNS_REQST_SIZE 255
|
||||
#define TOX_DNS3_TXT_PREFIX "v=tox3;id="
|
||||
|
||||
extern struct Winthread Winthread;
|
||||
extern struct dns3_servers dns3_servers;
|
||||
extern struct arg_opts arg_opts;
|
||||
|
||||
static struct thread_data {
|
||||
ToxWindow *self;
|
||||
char id_bin[TOX_ADDRESS_SIZE];
|
||||
char addr[MAX_STR_SIZE];
|
||||
char msg[MAX_STR_SIZE];
|
||||
uint8_t busy;
|
||||
Tox *m;
|
||||
} t_data;
|
||||
|
||||
static struct dns_thread {
|
||||
pthread_t tid;
|
||||
pthread_attr_t attr;
|
||||
} dns_thread;
|
||||
|
||||
|
||||
#define MAX_DNS_SERVERS 50
|
||||
#define MAX_DOMAIN_SIZE 32
|
||||
#define MAX_DNS_LINE MAX_DOMAIN_SIZE + (DNS3_KEY_SIZE * 2) + 3
|
||||
|
||||
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(const char *path)
|
||||
{
|
||||
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) {
|
||||
int linelen = strlen(line);
|
||||
|
||||
if (linelen < DNS3_KEY_SIZE * 2 + 5)
|
||||
continue;
|
||||
|
||||
if (line[linelen - 1] == '\n')
|
||||
line[--linelen] = '\0';
|
||||
|
||||
const char *name = strtok(line, " ");
|
||||
const char *keystr = strtok(NULL, " ");
|
||||
|
||||
if (name == NULL || keystr == NULL)
|
||||
continue;
|
||||
|
||||
if (strlen(keystr) != DNS3_KEY_SIZE * 2)
|
||||
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);
|
||||
|
||||
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);
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "User lookup failed: %s", errmsg);
|
||||
pthread_mutex_unlock(&Winthread.lock);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void killdns_thread(void *dns_obj)
|
||||
{
|
||||
if (dns_obj)
|
||||
tox_dns3_kill(dns_obj);
|
||||
|
||||
memset(&t_data, 0, sizeof(struct thread_data));
|
||||
pthread_attr_destroy(&dns_thread.attr);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
/* puts TXT from dns response in buf. Returns length of TXT on success, -1 on fail.*/
|
||||
static int parse_dns_response(ToxWindow *self, u_char *answer, int ans_len, char *buf)
|
||||
{
|
||||
uint8_t *ans_pt = answer + sizeof(HEADER);
|
||||
uint8_t *ans_end = answer + ans_len;
|
||||
char exp_ans[PACKETSZ];
|
||||
|
||||
int len = dn_expand(answer, ans_end, ans_pt, exp_ans, sizeof(exp_ans));
|
||||
|
||||
if (len == -1)
|
||||
return dns_error(self, "dn_expand failed.");
|
||||
|
||||
ans_pt += len;
|
||||
|
||||
if (ans_pt > ans_end - 4)
|
||||
return dns_error(self, "DNS reply was too short.");
|
||||
|
||||
int type;
|
||||
GETSHORT(type, ans_pt);
|
||||
|
||||
if (type != T_TXT)
|
||||
return dns_error(self, "Broken DNS reply.");
|
||||
|
||||
|
||||
ans_pt += INT16SZ; /* class */
|
||||
uint32_t size = 0;
|
||||
|
||||
/* recurse through CNAME rr's */
|
||||
do {
|
||||
ans_pt += size;
|
||||
len = dn_expand(answer, ans_end, ans_pt, exp_ans, sizeof(exp_ans));
|
||||
|
||||
if (len == -1)
|
||||
return dns_error(self, "Second dn_expand failed.");
|
||||
|
||||
ans_pt += len;
|
||||
|
||||
if (ans_pt > ans_end - 10)
|
||||
return dns_error(self, "DNS reply was too short.");
|
||||
|
||||
GETSHORT(type, ans_pt);
|
||||
ans_pt += INT16SZ;
|
||||
ans_pt += 4;
|
||||
GETSHORT(size, ans_pt);
|
||||
|
||||
if (ans_pt + size < answer || ans_pt + size > ans_end)
|
||||
return dns_error(self, "RR overflow.");
|
||||
|
||||
} while (type == T_CNAME);
|
||||
|
||||
if (type != T_TXT)
|
||||
return dns_error(self, "DNS response failed.");
|
||||
|
||||
uint32_t txt_len = *ans_pt;
|
||||
|
||||
if (!size || txt_len >= size || !txt_len)
|
||||
return dns_error(self, "No record found.");
|
||||
|
||||
if (txt_len > MAX_DNS_REQST_SIZE)
|
||||
return dns_error(self, "Invalid DNS response.");
|
||||
|
||||
ans_pt++;
|
||||
ans_pt[txt_len] = '\0';
|
||||
memcpy(buf, ans_pt, txt_len + 1);
|
||||
|
||||
return txt_len;
|
||||
}
|
||||
|
||||
/* Takes address addr in the form "username@domain", puts the username in namebuf,
|
||||
and the domain in dombuf.
|
||||
|
||||
return length of username on success, -1 on failure */
|
||||
static int parse_addr(const char *addr, char *namebuf, size_t namebuf_sz, char *dombuf, size_t dombuf_sz)
|
||||
{
|
||||
if (strlen(addr) >= MAX_STR_SIZE)
|
||||
return -1;
|
||||
|
||||
char tmpaddr[MAX_STR_SIZE];
|
||||
char *tmpname = NULL;
|
||||
char *tmpdom = NULL;
|
||||
|
||||
snprintf(tmpaddr, sizeof(tmpaddr), "%s", addr);
|
||||
tmpname = strtok(tmpaddr, "@");
|
||||
tmpdom = strtok(NULL, "");
|
||||
|
||||
if (tmpname == NULL || tmpdom == NULL)
|
||||
return -1;
|
||||
|
||||
str_to_lower(tmpdom);
|
||||
snprintf(namebuf, namebuf_sz, "%s", tmpname);
|
||||
snprintf(dombuf, dombuf_sz, "%s", tmpdom);
|
||||
|
||||
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)
|
||||
{
|
||||
int i;
|
||||
|
||||
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]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 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, sizeof(name), inputdomain, sizeof(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;
|
||||
}
|
||||
|
||||
/* creates new thread for dns3 lookup. Only allows one lookup at a time. */
|
||||
void dns3_lookup(ToxWindow *self, Tox *m, const char *id_bin, const char *addr, const char *msg)
|
||||
{
|
||||
if (arg_opts.proxy_type != TOX_PROXY_TYPE_NONE && arg_opts.force_tcp) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "DNS lookups are disabled.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (t_data.busy) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Please wait for previous user lookup to finish.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dns3_servers.loaded) {
|
||||
const char *path = arg_opts.dns_path[0] ? arg_opts.dns_path : PACKAGE_DATADIR "/DNSservers";
|
||||
dns3_servers.loaded = true;
|
||||
int ret = load_dns_domainlist(path);
|
||||
|
||||
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);
|
||||
t_data.self = self;
|
||||
t_data.m = m;
|
||||
t_data.busy = 1;
|
||||
|
||||
if (pthread_attr_init(&dns_thread.attr) != 0) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, "Error: DNS thread attr failed to init");
|
||||
memset(&t_data, 0, sizeof(struct thread_data));
|
||||
return;
|
||||
}
|
||||
|
||||
if (pthread_attr_setdetachstate(&dns_thread.attr, PTHREAD_CREATE_DETACHED) != 0) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, "Error: DNS thread attr failed to set");
|
||||
pthread_attr_destroy(&dns_thread.attr);
|
||||
memset(&t_data, 0, sizeof(struct thread_data));
|
||||
return;
|
||||
}
|
||||
|
||||
if (pthread_create(&dns_thread.tid, &dns_thread.attr, dns3_lookup_thread, NULL) != 0) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, "Error: DNS thread failed to init");
|
||||
pthread_attr_destroy(&dns_thread.attr);
|
||||
memset(&t_data, 0, sizeof(struct thread_data));
|
||||
return;
|
||||
}
|
||||
}
|
@ -53,6 +53,7 @@ static struct cmd_func global_commands[] = {
|
||||
{ "/myid", cmd_myid },
|
||||
{ "/nick", cmd_nick },
|
||||
{ "/note", cmd_note },
|
||||
{ "/nospam", cmd_nospam },
|
||||
{ "/q", cmd_quit },
|
||||
{ "/quit", cmd_quit },
|
||||
{ "/requests", cmd_requests },
|
||||
|
@ -30,12 +30,12 @@
|
||||
#include "friendlist.h"
|
||||
#include "log.h"
|
||||
#include "line_info.h"
|
||||
#include "dns.h"
|
||||
#include "groupchat.h"
|
||||
#include "prompt.h"
|
||||
#include "help.h"
|
||||
#include "term_mplex.h"
|
||||
#include "avatars.h"
|
||||
#include "name_lookup.h"
|
||||
|
||||
extern char *DATA_FILE;
|
||||
extern ToxWindow *prompt;
|
||||
@ -192,8 +192,8 @@ void cmd_add(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
|
||||
}
|
||||
|
||||
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);
|
||||
} else { /* assume id is a username@domain address and do http name server lookup */
|
||||
name_lookup(self, m, id_bin, id, msg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -370,9 +370,9 @@ void cmd_log(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
|
||||
|
||||
if (argc == 0) {
|
||||
if (log->log_on)
|
||||
msg = "Logging for this window is ON. Type \"/log off\" to disable.";
|
||||
msg = "Logging for this window is ON; type \"/log off\" to disable. (Logs are not encrypted)";
|
||||
else
|
||||
msg = "Logging for this window is OFF. Type \"/log on\" to enable.";
|
||||
msg = "Logging for this window is OFF; type \"/log on\" to enable.";
|
||||
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, msg);
|
||||
return;
|
||||
@ -484,6 +484,15 @@ void cmd_note(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA
|
||||
prompt_update_statusmessage(prompt, m, msg);
|
||||
}
|
||||
|
||||
void cmd_nospam(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||
{
|
||||
uint32_t nospam = rand(); /* should be random enough */
|
||||
tox_self_set_nospam(m, nospam);
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Your Tox ID has been changed to:");
|
||||
cmd_myid(window, self, m, 0, NULL);
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Any services that relied on your old ID will need to be updated manually.");
|
||||
}
|
||||
|
||||
void cmd_prompt_help(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||
{
|
||||
help_init_menu(self);
|
||||
|
@ -37,6 +37,7 @@ void cmd_log(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE])
|
||||
void cmd_myid(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||
void cmd_nick(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||
void cmd_note(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||
void cmd_nospam(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||
void cmd_prompt_help(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||
void cmd_quit(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||
void cmd_requests(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||
|
@ -70,9 +70,9 @@ extern struct user_settings *user_settings;
|
||||
extern struct Winthread Winthread;
|
||||
|
||||
#ifdef AUDIO
|
||||
#define AC_NUM_GROUP_COMMANDS 22
|
||||
#define AC_NUM_GROUP_COMMANDS 23
|
||||
#else
|
||||
#define AC_NUM_GROUP_COMMANDS 18
|
||||
#define AC_NUM_GROUP_COMMANDS 19
|
||||
#endif /* AUDIO */
|
||||
|
||||
/* Array of groupchat command names used for tab completion. */
|
||||
@ -91,6 +91,7 @@ static const char group_cmd_list[AC_NUM_GROUP_COMMANDS][MAX_CMDNAME_SIZE] = {
|
||||
{ "/myid" },
|
||||
{ "/nick" },
|
||||
{ "/note" },
|
||||
{ "/nospam" },
|
||||
{ "/quit" },
|
||||
{ "/requests" },
|
||||
{ "/status" },
|
||||
|
@ -151,6 +151,7 @@ static void help_draw_global(ToxWindow *self)
|
||||
wprintw(win, " /status <type> <msg> : Set status with optional note\n");
|
||||
wprintw(win, " /note <msg> : Set a personal note\n");
|
||||
wprintw(win, " /nick <nick> : Set your nickname\n");
|
||||
wprintw(win, " /nospam : Change part of your Tox ID to stop spam\n");
|
||||
wprintw(win, " /log <on> or <off> : Enable/disable logging\n");
|
||||
wprintw(win, " /group <type> : Create a group chat where type: text | audio\n");
|
||||
wprintw(win, " /myid : Print your Tox ID\n");
|
||||
@ -310,11 +311,10 @@ void help_onKey(ToxWindow *self, wint_t key)
|
||||
|
||||
case 'g':
|
||||
#ifdef VIDEO
|
||||
help_init_window(self, 28, 80);
|
||||
help_init_window(self, 29, 80);
|
||||
#elif AUDIO
|
||||
help_init_window(self, 24, 80);
|
||||
#else
|
||||
help_init_window(self, 20, 80);
|
||||
help_init_window(self, 21, 80);
|
||||
#endif
|
||||
self->help->type = HELP_GLOBAL;
|
||||
break;
|
||||
|
461
src/name_lookup.c
Normal file
461
src/name_lookup.c
Normal file
@ -0,0 +1,461 @@
|
||||
/* name_lookup.c
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2015 Toxic All Rights Reserved.
|
||||
*
|
||||
* This file is part of Toxic.
|
||||
*
|
||||
* Toxic 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Toxic 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 Toxic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h> /* for u_char */
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "toxic.h"
|
||||
#include "windows.h"
|
||||
#include "line_info.h"
|
||||
#include "global_commands.h"
|
||||
#include "misc_tools.h"
|
||||
#include "configdir.h"
|
||||
|
||||
extern struct arg_opts arg_opts;
|
||||
extern struct Winthread Winthread;;
|
||||
|
||||
#define NAMESERVER_API_PATH "api"
|
||||
#define SERVER_KEY_SIZE 32
|
||||
#define MAX_SERVERS 50
|
||||
#define MAX_DOMAIN_SIZE 32
|
||||
#define MAX_SERVER_LINE MAX_DOMAIN_SIZE + (SERVER_KEY_SIZE * 2) + 3
|
||||
|
||||
/* List based on Mozilla's recommended configurations for modern browsers */
|
||||
#define TLS_CIPHER_SUITE_LIST "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK"
|
||||
|
||||
struct Nameservers {
|
||||
int lines;
|
||||
char names[MAX_SERVERS][MAX_DOMAIN_SIZE];
|
||||
char keys[MAX_SERVERS][SERVER_KEY_SIZE];
|
||||
} Nameservers;
|
||||
|
||||
static struct thread_data {
|
||||
Tox *m;
|
||||
ToxWindow *self;
|
||||
char id_bin[TOX_ADDRESS_SIZE];
|
||||
char addr[MAX_STR_SIZE];
|
||||
char msg[MAX_STR_SIZE];
|
||||
bool busy;
|
||||
bool disabled;
|
||||
} t_data;
|
||||
|
||||
static struct lookup_thread {
|
||||
pthread_t tid;
|
||||
pthread_attr_t attr;
|
||||
} lookup_thread;
|
||||
|
||||
static int lookup_error(ToxWindow *self, const char *errmsg, ...)
|
||||
{
|
||||
char frmt_msg[MAX_STR_SIZE];
|
||||
|
||||
va_list args;
|
||||
va_start(args, errmsg);
|
||||
vsnprintf(frmt_msg, sizeof(frmt_msg), errmsg, args);
|
||||
va_end(args);
|
||||
|
||||
pthread_mutex_lock(&Winthread.lock);
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "name lookup failed: %s", frmt_msg);
|
||||
pthread_mutex_unlock(&Winthread.lock);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void kill_lookup_thread(void)
|
||||
{
|
||||
memset(&t_data, 0, sizeof(struct thread_data));
|
||||
pthread_attr_destroy(&lookup_thread.attr);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
/* Attempts to load the nameserver list pointed at by path into the Nameservers structure.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
* -1 is reserved.
|
||||
* Returns -2 if the supplied path does not exist.
|
||||
* Returns -3 if the list does not contain any valid entries.
|
||||
*/
|
||||
static int load_nameserver_list(const char *path)
|
||||
{
|
||||
FILE *fp = fopen(path, "r");
|
||||
|
||||
if (fp == NULL)
|
||||
return -2;
|
||||
|
||||
char line[MAX_SERVER_LINE];
|
||||
|
||||
while (fgets(line, sizeof(line), fp) && Nameservers.lines < MAX_SERVERS) {
|
||||
int linelen = strlen(line);
|
||||
|
||||
if (linelen < SERVER_KEY_SIZE * 2 + 5)
|
||||
continue;
|
||||
|
||||
if (line[linelen - 1] == '\n')
|
||||
line[--linelen] = '\0';
|
||||
|
||||
const char *name = strtok(line, " ");
|
||||
const char *keystr = strtok(NULL, " ");
|
||||
|
||||
if (name == NULL || keystr == NULL)
|
||||
continue;
|
||||
|
||||
if (strlen(keystr) != SERVER_KEY_SIZE * 2)
|
||||
continue;
|
||||
|
||||
snprintf(Nameservers.names[Nameservers.lines], sizeof(Nameservers.names[Nameservers.lines]), "%s", name);
|
||||
int res = hex_string_to_bytes(Nameservers.keys[Nameservers.lines], SERVER_KEY_SIZE, keystr);
|
||||
|
||||
if (res == -1)
|
||||
continue;
|
||||
|
||||
++Nameservers.lines;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
if (Nameservers.lines < 1)
|
||||
return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Takes address addr in the form "username@domain", puts the username in namebuf,
|
||||
* and the domain in dombuf.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
* Returns -1 on failure
|
||||
*/
|
||||
static int parse_addr(const char *addr, char *namebuf, size_t namebuf_sz, char *dombuf, size_t dombuf_sz)
|
||||
{
|
||||
if (strlen(addr) >= (MAX_STR_SIZE - strlen(NAMESERVER_API_PATH)))
|
||||
return -1;
|
||||
|
||||
char tmpaddr[MAX_STR_SIZE];
|
||||
char *tmpname = NULL;
|
||||
char *tmpdom = NULL;
|
||||
|
||||
snprintf(tmpaddr, sizeof(tmpaddr), "%s", addr);
|
||||
tmpname = strtok(tmpaddr, "@");
|
||||
tmpdom = strtok(NULL, "");
|
||||
|
||||
if (tmpname == NULL || tmpdom == NULL)
|
||||
return -1;
|
||||
|
||||
str_to_lower(tmpdom);
|
||||
snprintf(namebuf, namebuf_sz, "%s", tmpname);
|
||||
snprintf(dombuf, dombuf_sz, "%s", tmpdom);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* matches input domain name with domains in list and obtains key.
|
||||
* Turns out_domain into the full domain we need to make a POST request.
|
||||
*
|
||||
* Return true on match.
|
||||
* Returns false on no match.
|
||||
*/
|
||||
static bool get_domain_match(char *pubkey, char *out_domain, size_t out_domain_size, const char *inputdomain)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < Nameservers.lines; ++i) {
|
||||
if (strcmp(Nameservers.names[i], inputdomain) == 0) {
|
||||
memcpy(pubkey, Nameservers.keys[i], SERVER_KEY_SIZE);
|
||||
snprintf(out_domain, out_domain_size, "https://%s/%s", Nameservers.names[i], NAMESERVER_API_PATH);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#define MAX_RECV_LOOKUP_DATA_SIZE 1024
|
||||
|
||||
/* Holds raw data received from name server */
|
||||
struct Recv_Data {
|
||||
char data[MAX_RECV_LOOKUP_DATA_SIZE];
|
||||
size_t size;
|
||||
};
|
||||
|
||||
size_t write_lookup_data(void *data, size_t size, size_t nmemb, void *user_pointer)
|
||||
{
|
||||
struct Recv_Data *recv_data = (struct Recv_Data *) user_pointer;
|
||||
size_t real_size = size * nmemb;
|
||||
|
||||
if (real_size > MAX_RECV_LOOKUP_DATA_SIZE)
|
||||
return 0;
|
||||
|
||||
memcpy(&recv_data->data, data, real_size);
|
||||
recv_data->size = real_size;
|
||||
recv_data->data[real_size] = 0;
|
||||
|
||||
return real_size;
|
||||
}
|
||||
|
||||
/* Converts Tox ID string contained in recv_data to binary format and puts it in thread's ID buffer.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
* Returns -1 on failure.
|
||||
*/
|
||||
#define ID_PREFIX "\"tox_id\": \""
|
||||
static int process_response(struct Recv_Data *recv_data)
|
||||
{
|
||||
size_t prefix_size = strlen(ID_PREFIX);
|
||||
|
||||
if (recv_data->size < TOX_ADDRESS_SIZE * 2 + prefix_size)
|
||||
return -1;
|
||||
|
||||
const char *IDstart = strstr(recv_data->data, ID_PREFIX);
|
||||
|
||||
if (IDstart == NULL)
|
||||
return -1;
|
||||
|
||||
if (strlen(IDstart) < TOX_ADDRESS_SIZE * 2 + prefix_size)
|
||||
return -1;
|
||||
|
||||
char ID_string[TOX_ADDRESS_SIZE * 2 + 1];
|
||||
memcpy(ID_string, IDstart + prefix_size, TOX_ADDRESS_SIZE * 2);
|
||||
ID_string[TOX_ADDRESS_SIZE * 2] = 0;
|
||||
|
||||
if (hex_string_to_bin(ID_string, strlen(ID_string), t_data.id_bin, sizeof(t_data.id_bin)) == -1)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Sets proxy info for given CURL handler.
|
||||
*
|
||||
* Returns 0 on success or if no proxy is set by the client.
|
||||
* Returns -1 on failure.
|
||||
*/
|
||||
static int set_lookup_proxy(ToxWindow *self, CURL *c_handle, const char *proxy_address, uint16_t port, uint8_t proxy_type)
|
||||
{
|
||||
if (proxy_type == TOX_PROXY_TYPE_NONE)
|
||||
return 0;
|
||||
|
||||
if (proxy_address == NULL || port == 0) {
|
||||
lookup_error(self, "Unknown proxy error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ret = curl_easy_setopt(c_handle, CURLOPT_PROXYPORT, (long) port);
|
||||
|
||||
if (ret != CURLE_OK) {
|
||||
lookup_error(self, "Failed to set proxy port (libcurl error %d)", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
long int type = proxy_type == TOX_PROXY_TYPE_SOCKS5 ? CURLPROXY_SOCKS5_HOSTNAME : CURLPROXY_HTTP;
|
||||
|
||||
ret = curl_easy_setopt(c_handle, CURLOPT_PROXYTYPE, type);
|
||||
|
||||
if (ret != CURLE_OK) {
|
||||
lookup_error(self, "Failed to set proxy type (libcurl error %d)", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = curl_easy_setopt(c_handle, CURLOPT_PROXY, proxy_address);
|
||||
|
||||
if (ret != CURLE_OK) {
|
||||
lookup_error(self, "Failed to set proxy (libcurl error %d)", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *lookup_thread_func(void *data)
|
||||
{
|
||||
ToxWindow *self = t_data.self;
|
||||
|
||||
char input_domain[MAX_STR_SIZE];
|
||||
char name[MAX_STR_SIZE];
|
||||
|
||||
if (parse_addr(t_data.addr, name, sizeof(name), input_domain, sizeof(input_domain)) == -1) {
|
||||
lookup_error(self, "Input must be a 76 character Tox ID or an address in the form: username@domain");
|
||||
kill_lookup_thread();
|
||||
}
|
||||
|
||||
char nameserver_key[SERVER_KEY_SIZE];
|
||||
char real_domain[MAX_DOMAIN_SIZE];
|
||||
|
||||
if (!get_domain_match(nameserver_key, real_domain, sizeof(real_domain), input_domain)) {
|
||||
if (!strcasecmp(input_domain, "utox.org"))
|
||||
lookup_error(self, "utox.org uses deprecated DNS-based lookups and is no longer supported by Toxic");
|
||||
else
|
||||
lookup_error(self, "Name server domain not found.");
|
||||
|
||||
kill_lookup_thread();
|
||||
}
|
||||
|
||||
CURL *c_handle = curl_easy_init();
|
||||
|
||||
if (!c_handle) {
|
||||
lookup_error(self, "curl handler error");
|
||||
kill_lookup_thread();
|
||||
}
|
||||
|
||||
struct Recv_Data recv_data;
|
||||
memset(&recv_data, 0, sizeof(struct Recv_Data));
|
||||
|
||||
char post_data[MAX_STR_SIZE];
|
||||
snprintf(post_data, sizeof(post_data), "{\"action\": 3, \"name\": \"%s\"}", name);
|
||||
|
||||
struct curl_slist *headers = NULL;
|
||||
|
||||
headers = curl_slist_append(headers, "Content-Type: application/json");
|
||||
headers = curl_slist_append(headers, "charsets: utf-8");
|
||||
|
||||
curl_easy_setopt(c_handle, CURLOPT_HTTPHEADER, headers);
|
||||
curl_easy_setopt(c_handle, CURLOPT_URL, real_domain);
|
||||
curl_easy_setopt(c_handle, CURLOPT_WRITEFUNCTION, write_lookup_data);
|
||||
curl_easy_setopt(c_handle, CURLOPT_WRITEDATA, (void *) &recv_data);
|
||||
curl_easy_setopt(c_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
|
||||
curl_easy_setopt(c_handle, CURLOPT_POSTFIELDS, post_data);
|
||||
|
||||
if (set_lookup_proxy(self, c_handle, arg_opts.proxy_address, arg_opts.proxy_port, arg_opts.proxy_type) == -1)
|
||||
goto on_exit;
|
||||
|
||||
int ret = curl_easy_setopt(c_handle, CURLOPT_USE_SSL, CURLUSESSL_ALL);
|
||||
|
||||
if (ret != CURLE_OK) {
|
||||
lookup_error(self, "TLS could not be enabled (libcurl error %d)", ret);
|
||||
goto on_exit;
|
||||
}
|
||||
|
||||
ret = curl_easy_setopt(c_handle, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
|
||||
|
||||
if (ret != CURLE_OK) {
|
||||
lookup_error(self, "TLSv1.2 could not be set (libcurl error %d)", ret);
|
||||
goto on_exit;
|
||||
}
|
||||
|
||||
ret = curl_easy_setopt(c_handle, CURLOPT_SSL_CIPHER_LIST, TLS_CIPHER_SUITE_LIST);
|
||||
|
||||
if (ret != CURLE_OK) {
|
||||
lookup_error(self, "Failed to set TLS cipher list (libcurl error %d)", ret);
|
||||
goto on_exit;
|
||||
}
|
||||
|
||||
ret = curl_easy_perform(c_handle);
|
||||
|
||||
if (ret != CURLE_OK) {
|
||||
/* If system doesn't support any of the specified ciphers suites, fall back to default */
|
||||
if (ret == CURLE_SSL_CIPHER) {
|
||||
curl_easy_setopt(c_handle, CURLOPT_SSL_CIPHER_LIST, NULL);
|
||||
ret = curl_easy_perform(c_handle);
|
||||
}
|
||||
|
||||
if (ret != CURLE_OK) {
|
||||
lookup_error(self, "HTTPS lookup error (libcurl error %d)", ret);
|
||||
goto on_exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (process_response(&recv_data) == -1) {
|
||||
lookup_error(self, "Bad response.");
|
||||
goto on_exit;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&Winthread.lock);
|
||||
cmd_add_helper(self, t_data.m, t_data.id_bin, t_data.msg);
|
||||
pthread_mutex_unlock(&Winthread.lock);
|
||||
|
||||
on_exit:
|
||||
curl_slist_free_all(headers);
|
||||
curl_easy_cleanup(c_handle);
|
||||
kill_lookup_thread();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void name_lookup(ToxWindow *self, Tox *m, const char *id_bin, const char *addr, const char *message)
|
||||
{
|
||||
if (t_data.disabled) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "name lookups are disabled.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (t_data.busy) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Please wait for previous name lookup to finish.");
|
||||
return;
|
||||
}
|
||||
|
||||
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", message);
|
||||
t_data.self = self;
|
||||
t_data.m = m;
|
||||
t_data.busy = true;
|
||||
|
||||
if (pthread_attr_init(&lookup_thread.attr) != 0) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, "Error: lookup thread attr failed to init");
|
||||
memset(&t_data, 0, sizeof(struct thread_data));
|
||||
return;
|
||||
}
|
||||
|
||||
if (pthread_attr_setdetachstate(&lookup_thread.attr, PTHREAD_CREATE_DETACHED) != 0) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, "Error: lookup thread attr failed to set");
|
||||
pthread_attr_destroy(&lookup_thread.attr);
|
||||
memset(&t_data, 0, sizeof(struct thread_data));
|
||||
return;
|
||||
}
|
||||
|
||||
if (pthread_create(&lookup_thread.tid, &lookup_thread.attr, lookup_thread_func, NULL) != 0) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, "Error: lookup thread failed to init");
|
||||
pthread_attr_destroy(&lookup_thread.attr);
|
||||
memset(&t_data, 0, sizeof(struct thread_data));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initializes http based name lookups. Note: This function must be called only once before additional
|
||||
* threads are spawned.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
* Returns -1 if curl failed to init.
|
||||
* Returns -2 if the nameserver list cannot be found.
|
||||
* Returns -3 if the nameserver list does not contain any valid entries.
|
||||
*/
|
||||
int name_lookup_init(void)
|
||||
{
|
||||
if (curl_global_init(CURL_GLOBAL_ALL) != 0) {
|
||||
t_data.disabled = true;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *path = arg_opts.nameserver_path[0] ? arg_opts.nameserver_path : PACKAGE_DATADIR "/nameservers";
|
||||
int ret = load_nameserver_list(path);
|
||||
|
||||
if (ret != 0) {
|
||||
t_data.disabled = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void name_lookup_cleanup(void)
|
||||
{
|
||||
curl_global_cleanup();
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
/* dns.c
|
||||
/* name_lookup.h
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2014 Toxic All Rights Reserved.
|
||||
* Copyright (C) 2015 Toxic All Rights Reserved.
|
||||
*
|
||||
* This file is part of Toxic.
|
||||
*
|
||||
@ -20,13 +20,18 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/* Does DNS lookup for addr and puts resulting tox id in id_bin.
|
||||
Return 0 on success, -1 on failure. */
|
||||
#ifndef NAME_LOOKUP
|
||||
#define NAME_LOOKUP
|
||||
|
||||
#ifndef DNS_H
|
||||
#define DNS_H
|
||||
/* Initializes http based name lookups. Note: This function must be called only once before additional
|
||||
* threads are spawned.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
* Returns -1 on failure.
|
||||
*/
|
||||
int name_lookup_init(void);
|
||||
void name_lookup_cleanup(void);
|
||||
|
||||
/* creates new thread for dns3 lookup. Only allows one lookup at a time. */
|
||||
void dns3_lookup(ToxWindow *self, Tox *m, const char *id_bin, const char *addr, const char *msg);
|
||||
int name_lookup(ToxWindow *self, Tox *m, const char *id_bin, const char *addr, const char *message);
|
||||
|
||||
#endif /* #define DNS_H */
|
||||
#endif /* NAME_LOOKUP */
|
@ -50,11 +50,10 @@ extern struct Winthread Winthread;
|
||||
extern FriendsList Friends;
|
||||
FriendRequests FrndRequests;
|
||||
#ifdef VIDEO
|
||||
#define AC_NUM_GLOB_COMMANDS 20
|
||||
#define AC_NUM_GLOB_COMMANDS 21
|
||||
#elif AUDIO
|
||||
#define AC_NUM_GLOB_COMMANDS 18
|
||||
#else
|
||||
#define AC_NUM_GLOB_COMMANDS 16
|
||||
#define AC_NUM_GLOB_COMMANDS 17
|
||||
#endif
|
||||
|
||||
/* Array of global command names used for tab completion. */
|
||||
@ -72,6 +71,7 @@ static const char glob_cmd_list[AC_NUM_GLOB_COMMANDS][MAX_CMDNAME_SIZE] = {
|
||||
{ "/myid" },
|
||||
{ "/nick" },
|
||||
{ "/note" },
|
||||
{ "/nospam" },
|
||||
{ "/quit" },
|
||||
{ "/requests" },
|
||||
{ "/status" },
|
||||
|
29
src/toxic.c
29
src/toxic.c
@ -58,6 +58,7 @@
|
||||
#include "message_queue.h"
|
||||
#include "execute.h"
|
||||
#include "term_mplex.h"
|
||||
#include "name_lookup.h"
|
||||
|
||||
#ifdef X11
|
||||
#include "xtra.h"
|
||||
@ -163,6 +164,7 @@ void exit_toxic_success(Tox *m)
|
||||
free_global_data();
|
||||
tox_kill(m);
|
||||
endwin();
|
||||
name_lookup_cleanup();
|
||||
|
||||
#ifdef X11
|
||||
/* We have to terminate xtra last coz reasons
|
||||
@ -912,7 +914,7 @@ static void print_usage(void)
|
||||
fprintf(stderr, " -o, --noconnect Do not connect to the DHT network\n");
|
||||
fprintf(stderr, " -p, --SOCKS5-proxy Use SOCKS5 proxy: Requires [IP] [port]\n");
|
||||
fprintf(stderr, " -P, --HTTP-proxy Use HTTP proxy: Requires [IP] [port]\n");
|
||||
fprintf(stderr, " -r, --dnslist Use specified DNSservers file\n");
|
||||
fprintf(stderr, " -r, --namelist Use specified name lookup server list\n");
|
||||
fprintf(stderr, " -t, --force-tcp Force toxic to use a TCP connection (use with proxies)\n");
|
||||
fprintf(stderr, " -T, --tcp-server Act as a TCP relay server: Requires [port]\n");
|
||||
fprintf(stderr, " -u, --unencrypt-data Unencrypt an encrypted data file\n");
|
||||
@ -940,7 +942,7 @@ static void parse_args(int argc, char *argv[])
|
||||
{"nodes", required_argument, 0, 'n'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"noconnect", no_argument, 0, 'o'},
|
||||
{"dnslist", required_argument, 0, 'r'},
|
||||
{"namelist", required_argument, 0, 'r'},
|
||||
{"force-tcp", no_argument, 0, 't'},
|
||||
{"tcp-server", required_argument, 0, 'T'},
|
||||
{"SOCKS5-proxy", required_argument, 0, 'p'},
|
||||
@ -1052,10 +1054,10 @@ static void parse_args(int argc, char *argv[])
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
snprintf(arg_opts.dns_path, sizeof(arg_opts.dns_path), "%s", optarg);
|
||||
snprintf(arg_opts.nameserver_path, sizeof(arg_opts.nameserver_path), "%s", optarg);
|
||||
|
||||
if (!file_exists(arg_opts.dns_path))
|
||||
queue_init_message("DNSservers file not found");
|
||||
if (!file_exists(arg_opts.nameserver_path))
|
||||
queue_init_message("nameserver list not found");
|
||||
|
||||
break;
|
||||
|
||||
@ -1085,7 +1087,6 @@ static void parse_args(int argc, char *argv[])
|
||||
}
|
||||
|
||||
/* 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.
|
||||
@ -1231,7 +1232,18 @@ int main(int argc, char **argv)
|
||||
exit_toxic_err("failed in main", FATALERR_MEMORY);
|
||||
|
||||
const char *p = arg_opts.config_path[0] ? arg_opts.config_path : NULL;
|
||||
int settings_err = settings_load(user_settings, p);
|
||||
|
||||
if (settings_load(user_settings, p) == -1)
|
||||
queue_init_message("Failed to load user settings");
|
||||
|
||||
int nameserver_ret = name_lookup_init();
|
||||
|
||||
if (nameserver_ret == -1)
|
||||
queue_init_message("curl failed to initialize; name lookup service is disabled.");
|
||||
else if (nameserver_ret == -2)
|
||||
queue_init_message("Name lookup server list could not be found.");
|
||||
else if (nameserver_ret == -3)
|
||||
queue_init_message("Name lookup server list does not contain any valid entries.");
|
||||
|
||||
#ifdef X11
|
||||
if (init_xtra(DnD_callback) == -1)
|
||||
@ -1285,9 +1297,6 @@ int main(int argc, char **argv)
|
||||
|
||||
init_notify(60, 3000);
|
||||
|
||||
if (settings_err == -1)
|
||||
queue_init_message("Failed to load user settings");
|
||||
|
||||
/* screen/tmux auto-away timer */
|
||||
if (init_mplex_away_timer(m) == -1)
|
||||
queue_init_message("Failed to init mplex auto-away.");
|
||||
|
@ -90,7 +90,7 @@ struct arg_opts {
|
||||
bool encrypt_data;
|
||||
bool unencrypt_data;
|
||||
|
||||
char dns_path[MAX_STR_SIZE];
|
||||
char nameserver_path[MAX_STR_SIZE];
|
||||
char config_path[MAX_STR_SIZE];
|
||||
char nodes_path[MAX_STR_SIZE];
|
||||
|
||||
|
Reference in New Issue
Block a user