2000-08-26 11:39:44 -04:00
|
|
|
/*
|
|
|
|
servers-setup.c : irssi
|
|
|
|
|
2001-02-20 11:23:28 -05:00
|
|
|
Copyright (C) 1999-2001 Timo Sirainen
|
2000-08-26 11:39:44 -04:00
|
|
|
|
|
|
|
This program 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.
|
|
|
|
|
|
|
|
This program 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.
|
|
|
|
|
2007-05-08 14:41:10 -04:00
|
|
|
You should have received a copy of the GNU General Public License along
|
|
|
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
2000-08-26 11:39:44 -04:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "module.h"
|
|
|
|
#include "signals.h"
|
|
|
|
#include "network.h"
|
|
|
|
#include "lib-config/iconfig.h"
|
|
|
|
#include "settings.h"
|
|
|
|
|
2001-02-17 14:44:22 -05:00
|
|
|
#include "chat-protocols.h"
|
|
|
|
#include "chatnets.h"
|
2000-08-26 11:39:44 -04:00
|
|
|
#include "servers.h"
|
|
|
|
#include "servers-setup.h"
|
|
|
|
|
|
|
|
GSList *setupservers;
|
|
|
|
|
2008-04-28 05:27:13 -04:00
|
|
|
static char *old_source_host;
|
2000-08-26 11:39:44 -04:00
|
|
|
int source_host_ok; /* Use source_host_ip .. */
|
2015-09-22 15:59:17 -04:00
|
|
|
IPADDR *source_host_ip4, *source_host_ip6; /* Resolved address */
|
2001-03-03 20:47:13 -05:00
|
|
|
|
2015-09-22 15:59:17 -04:00
|
|
|
static void save_ips(IPADDR *ip4, IPADDR *ip6,
|
|
|
|
IPADDR **save_ip4, IPADDR **save_ip6)
|
2001-03-03 20:47:13 -05:00
|
|
|
{
|
2015-09-22 15:59:17 -04:00
|
|
|
if (ip4->family == 0)
|
|
|
|
g_free_and_null(*save_ip4);
|
2001-03-03 20:47:13 -05:00
|
|
|
else {
|
2015-09-22 15:59:17 -04:00
|
|
|
if (*save_ip4 == NULL)
|
|
|
|
*save_ip4 = g_new(IPADDR, 1);
|
|
|
|
memcpy(*save_ip4, ip4, sizeof(IPADDR));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ip6->family == 0)
|
|
|
|
g_free_and_null(*save_ip6);
|
|
|
|
else {
|
|
|
|
if (*save_ip6 == NULL)
|
|
|
|
*save_ip6 = g_new(IPADDR, 1);
|
|
|
|
memcpy(*save_ip6, ip6, sizeof(IPADDR));
|
2001-03-03 20:47:13 -05:00
|
|
|
}
|
|
|
|
}
|
2000-08-26 11:39:44 -04:00
|
|
|
|
|
|
|
static void get_source_host_ip(void)
|
|
|
|
{
|
2001-03-03 20:47:13 -05:00
|
|
|
const char *hostname;
|
2015-09-22 15:59:17 -04:00
|
|
|
IPADDR ip4, ip6;
|
2000-08-26 11:39:44 -04:00
|
|
|
|
|
|
|
if (source_host_ok)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* FIXME: This will block! */
|
2001-03-03 20:47:13 -05:00
|
|
|
hostname = settings_get_str("hostname");
|
|
|
|
source_host_ok = *hostname != '\0' &&
|
2015-09-22 15:59:17 -04:00
|
|
|
net_gethostbyname(hostname, &ip4, &ip6) == 0;
|
|
|
|
|
|
|
|
if (source_host_ok)
|
|
|
|
save_ips(&ip4, &ip6, &source_host_ip4, &source_host_ip6);
|
|
|
|
else {
|
|
|
|
g_free_and_null(source_host_ip4);
|
|
|
|
g_free_and_null(source_host_ip6);
|
|
|
|
}
|
2000-08-26 11:39:44 -04:00
|
|
|
}
|
|
|
|
|
2001-03-03 20:47:13 -05:00
|
|
|
static void conn_set_ip(SERVER_CONNECT_REC *conn, const char *own_host,
|
2015-09-22 15:59:17 -04:00
|
|
|
IPADDR **own_ip4, IPADDR **own_ip6)
|
2000-08-26 11:39:44 -04:00
|
|
|
{
|
2015-09-22 15:59:17 -04:00
|
|
|
IPADDR ip4, ip6;
|
2000-08-26 11:39:44 -04:00
|
|
|
|
2015-09-22 15:59:17 -04:00
|
|
|
if (*own_ip4 == NULL && *own_ip6 == NULL) {
|
2001-03-03 20:47:13 -05:00
|
|
|
/* resolve the IP */
|
2015-09-22 15:59:17 -04:00
|
|
|
if (net_gethostbyname(own_host, &ip4, &ip6) == 0)
|
|
|
|
save_ips(&ip4, &ip6, own_ip4, own_ip6);
|
2000-08-26 11:39:44 -04:00
|
|
|
}
|
|
|
|
|
2015-09-22 15:59:17 -04:00
|
|
|
server_connect_own_ip_save(conn, *own_ip4, *own_ip6);
|
2000-08-26 11:39:44 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Fill information to connection from server setup record */
|
|
|
|
void server_setup_fill_reconn(SERVER_CONNECT_REC *conn,
|
|
|
|
SERVER_SETUP_REC *sserver)
|
|
|
|
{
|
|
|
|
g_return_if_fail(IS_SERVER_CONNECT(conn));
|
|
|
|
g_return_if_fail(IS_SERVER_SETUP(sserver));
|
|
|
|
|
2001-03-03 20:47:13 -05:00
|
|
|
if (sserver->own_host != NULL) {
|
2015-09-22 15:59:17 -04:00
|
|
|
conn_set_ip(conn, sserver->own_host,
|
|
|
|
&sserver->own_ip4, &sserver->own_ip6);
|
2001-03-03 20:47:13 -05:00
|
|
|
}
|
2000-08-26 11:39:44 -04:00
|
|
|
|
|
|
|
if (sserver->chatnet != NULL && conn->chatnet == NULL)
|
|
|
|
conn->chatnet = g_strdup(sserver->chatnet);
|
|
|
|
|
|
|
|
if (sserver->password != NULL && conn->password == NULL)
|
|
|
|
conn->password = g_strdup(sserver->password);
|
|
|
|
|
|
|
|
signal_emit("server setup fill reconn", 2, conn, sserver);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void server_setup_fill(SERVER_CONNECT_REC *conn,
|
|
|
|
const char *address, int port)
|
|
|
|
{
|
|
|
|
g_return_if_fail(conn != NULL);
|
|
|
|
g_return_if_fail(address != NULL);
|
|
|
|
|
|
|
|
conn->type = module_get_uniq_id("SERVER CONNECT", 0);
|
|
|
|
|
|
|
|
conn->address = g_strdup(address);
|
2000-09-26 20:25:26 -04:00
|
|
|
if (port > 0) conn->port = port;
|
2000-08-26 11:39:44 -04:00
|
|
|
|
2014-11-20 11:01:07 -05:00
|
|
|
if (strchr(address, '/') != NULL)
|
|
|
|
conn->unix_socket = TRUE;
|
|
|
|
|
2000-09-06 19:24:12 -04:00
|
|
|
if (!conn->nick) conn->nick = g_strdup(settings_get_str("nick"));
|
2000-08-26 11:39:44 -04:00
|
|
|
conn->username = g_strdup(settings_get_str("user_name"));
|
|
|
|
conn->realname = g_strdup(settings_get_str("real_name"));
|
|
|
|
|
|
|
|
/* proxy settings */
|
|
|
|
if (settings_get_bool("use_proxy")) {
|
|
|
|
conn->proxy = g_strdup(settings_get_str("proxy_address"));
|
|
|
|
conn->proxy_port = settings_get_int("proxy_port");
|
|
|
|
conn->proxy_string = g_strdup(settings_get_str("proxy_string"));
|
2002-01-22 15:29:45 -05:00
|
|
|
conn->proxy_string_after = g_strdup(settings_get_str("proxy_string_after"));
|
2001-03-20 18:24:45 -05:00
|
|
|
conn->proxy_password = g_strdup(settings_get_str("proxy_password"));
|
2000-08-26 11:39:44 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* source IP */
|
2015-09-22 15:59:17 -04:00
|
|
|
if (source_host_ip4 != NULL) {
|
|
|
|
conn->own_ip4 = g_new(IPADDR, 1);
|
|
|
|
memcpy(conn->own_ip4, source_host_ip4, sizeof(IPADDR));
|
|
|
|
}
|
|
|
|
if (source_host_ip6 != NULL) {
|
|
|
|
conn->own_ip6 = g_new(IPADDR, 1);
|
|
|
|
memcpy(conn->own_ip6, source_host_ip6, sizeof(IPADDR));
|
2000-08-26 11:39:44 -04:00
|
|
|
}
|
2001-12-06 18:29:48 -05:00
|
|
|
|
|
|
|
signal_emit("server setup fill connect", 1, conn);
|
2000-08-26 11:39:44 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void server_setup_fill_server(SERVER_CONNECT_REC *conn,
|
|
|
|
SERVER_SETUP_REC *sserver)
|
|
|
|
{
|
|
|
|
g_return_if_fail(IS_SERVER_CONNECT(conn));
|
|
|
|
g_return_if_fail(IS_SERVER_SETUP(sserver));
|
|
|
|
|
|
|
|
sserver->last_connect = time(NULL);
|
|
|
|
|
2002-01-24 15:57:16 -05:00
|
|
|
if (sserver->no_proxy)
|
|
|
|
g_free_and_null(conn->proxy);
|
|
|
|
|
2001-02-20 11:23:28 -05:00
|
|
|
if (sserver->family != 0 && conn->family == 0)
|
|
|
|
conn->family = sserver->family;
|
2000-09-26 20:25:26 -04:00
|
|
|
if (sserver->port > 0 && conn->port <= 0)
|
|
|
|
conn->port = sserver->port;
|
2003-11-16 12:53:55 -05:00
|
|
|
|
2016-10-16 07:46:58 -04:00
|
|
|
conn->use_tls = sserver->use_tls;
|
|
|
|
if (conn->tls_cert == NULL && sserver->tls_cert != NULL && sserver->tls_cert[0] != '\0')
|
|
|
|
conn->tls_cert = g_strdup(sserver->tls_cert);
|
|
|
|
if (conn->tls_pkey == NULL && sserver->tls_pkey != NULL && sserver->tls_pkey[0] != '\0')
|
|
|
|
conn->tls_pkey = g_strdup(sserver->tls_pkey);
|
|
|
|
if (conn->tls_pass == NULL && sserver->tls_pass != NULL && sserver->tls_pass[0] != '\0')
|
|
|
|
conn->tls_pass = g_strdup(sserver->tls_pass);
|
|
|
|
conn->tls_verify = sserver->tls_verify;
|
|
|
|
if (conn->tls_cafile == NULL && sserver->tls_cafile != NULL && sserver->tls_cafile[0] != '\0')
|
|
|
|
conn->tls_cafile = g_strdup(sserver->tls_cafile);
|
|
|
|
if (conn->tls_capath == NULL && sserver->tls_capath != NULL && sserver->tls_capath[0] != '\0')
|
|
|
|
conn->tls_capath = g_strdup(sserver->tls_capath);
|
|
|
|
if (conn->tls_ciphers == NULL && sserver->tls_ciphers != NULL && sserver->tls_ciphers[0] != '\0')
|
|
|
|
conn->tls_ciphers = g_strdup(sserver->tls_ciphers);
|
2016-10-16 08:39:00 -04:00
|
|
|
if (conn->tls_pinned_cert == NULL && sserver->tls_pinned_cert != NULL && sserver->tls_pinned_cert[0] != '\0')
|
|
|
|
conn->tls_pinned_cert = g_strdup(sserver->tls_pinned_cert);
|
|
|
|
if (conn->tls_pinned_pubkey == NULL && sserver->tls_pinned_pubkey != NULL && sserver->tls_pinned_pubkey[0] != '\0')
|
|
|
|
conn->tls_pinned_pubkey = g_strdup(sserver->tls_pinned_pubkey);
|
2002-08-26 18:53:55 -04:00
|
|
|
|
2000-08-26 11:39:44 -04:00
|
|
|
server_setup_fill_reconn(conn, sserver);
|
|
|
|
|
|
|
|
signal_emit("server setup fill server", 2, conn, sserver);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void server_setup_fill_chatnet(SERVER_CONNECT_REC *conn,
|
|
|
|
CHATNET_REC *chatnet)
|
|
|
|
{
|
|
|
|
g_return_if_fail(IS_SERVER_CONNECT(conn));
|
|
|
|
g_return_if_fail(IS_CHATNET(chatnet));
|
|
|
|
|
2001-10-21 09:59:07 -04:00
|
|
|
if (chatnet->nick != NULL) {
|
2000-08-26 11:39:44 -04:00
|
|
|
g_free(conn->nick);
|
|
|
|
conn->nick = g_strdup(chatnet->nick);;
|
|
|
|
}
|
2001-10-21 09:59:07 -04:00
|
|
|
if (chatnet->username != NULL) {
|
2000-08-26 11:39:44 -04:00
|
|
|
g_free(conn->username);
|
|
|
|
conn->username = g_strdup(chatnet->username);;
|
|
|
|
}
|
2001-10-21 09:59:07 -04:00
|
|
|
if (chatnet->realname != NULL) {
|
2000-08-26 11:39:44 -04:00
|
|
|
g_free(conn->realname);
|
|
|
|
conn->realname = g_strdup(chatnet->realname);;
|
|
|
|
}
|
2001-03-03 20:47:13 -05:00
|
|
|
if (chatnet->own_host != NULL) {
|
2015-09-22 15:59:17 -04:00
|
|
|
conn_set_ip(conn, chatnet->own_host,
|
|
|
|
&chatnet->own_ip4, &chatnet->own_ip6);
|
2001-03-03 20:47:13 -05:00
|
|
|
}
|
2000-08-26 11:39:44 -04:00
|
|
|
|
|
|
|
signal_emit("server setup fill chatnet", 2, conn, chatnet);
|
|
|
|
}
|
|
|
|
|
|
|
|
static SERVER_CONNECT_REC *
|
2001-02-17 14:44:22 -05:00
|
|
|
create_addr_conn(int chat_type, const char *address, int port,
|
2001-03-07 19:24:27 -05:00
|
|
|
const char *chatnet, const char *password,
|
|
|
|
const char *nick)
|
2000-08-26 11:39:44 -04:00
|
|
|
{
|
2001-02-17 14:44:22 -05:00
|
|
|
CHAT_PROTOCOL_REC *proto;
|
2000-08-26 11:39:44 -04:00
|
|
|
SERVER_CONNECT_REC *conn;
|
|
|
|
SERVER_SETUP_REC *sserver;
|
2001-03-07 19:24:27 -05:00
|
|
|
CHATNET_REC *chatnetrec;
|
2000-08-26 11:39:44 -04:00
|
|
|
|
|
|
|
g_return_val_if_fail(address != NULL, NULL);
|
|
|
|
|
2001-06-27 17:47:31 -04:00
|
|
|
sserver = server_setup_find(address, port, chatnet);
|
2001-02-18 21:15:15 -05:00
|
|
|
if (sserver != NULL) {
|
|
|
|
if (chat_type < 0)
|
|
|
|
chat_type = sserver->chat_type;
|
|
|
|
else if (chat_type != sserver->chat_type)
|
|
|
|
sserver = NULL;
|
|
|
|
}
|
2001-02-17 14:44:22 -05:00
|
|
|
|
|
|
|
proto = chat_type >= 0 ? chat_protocol_find_id(chat_type) :
|
|
|
|
chat_protocol_get_default();
|
|
|
|
|
|
|
|
conn = proto->create_server_connect();
|
2001-10-21 09:59:07 -04:00
|
|
|
server_connect_ref(conn);
|
|
|
|
|
2001-03-07 19:24:27 -05:00
|
|
|
conn->chat_type = proto->id;
|
|
|
|
if (chatnet != NULL && *chatnet != '\0')
|
|
|
|
conn->chatnet = g_strdup(chatnet);
|
2000-08-26 11:39:44 -04:00
|
|
|
|
|
|
|
/* fill in the defaults */
|
|
|
|
server_setup_fill(conn, address, port);
|
|
|
|
|
|
|
|
/* fill the rest from chat network settings */
|
2001-03-07 19:24:27 -05:00
|
|
|
chatnetrec = chatnet != NULL ? chatnet_find(chatnet) :
|
|
|
|
(sserver == NULL || sserver->chatnet == NULL ? NULL :
|
|
|
|
chatnet_find(sserver->chatnet));
|
|
|
|
if (chatnetrec != NULL)
|
|
|
|
server_setup_fill_chatnet(conn, chatnetrec);
|
2000-08-26 11:39:44 -04:00
|
|
|
|
|
|
|
/* fill the information from setup */
|
|
|
|
if (sserver != NULL)
|
|
|
|
server_setup_fill_server(conn, sserver);
|
|
|
|
|
|
|
|
/* nick / password given in command line overrides all settings */
|
|
|
|
if (password && *password) {
|
|
|
|
g_free_not_null(conn->password);
|
|
|
|
conn->password = g_strdup(password);
|
|
|
|
}
|
|
|
|
if (nick && *nick) {
|
|
|
|
g_free_not_null(conn->nick);
|
|
|
|
conn->nick = g_strdup(nick);
|
|
|
|
}
|
|
|
|
|
|
|
|
return conn;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Connect to server where last connect succeeded (or we haven't tried to
|
|
|
|
connect yet). If there's no such server, connect to server where we
|
|
|
|
haven't connected for the longest time */
|
|
|
|
static SERVER_CONNECT_REC *
|
|
|
|
create_chatnet_conn(const char *dest, int port,
|
|
|
|
const char *password, const char *nick)
|
|
|
|
{
|
|
|
|
SERVER_SETUP_REC *bestrec;
|
|
|
|
GSList *tmp;
|
|
|
|
time_t now, besttime;
|
|
|
|
|
|
|
|
now = time(NULL);
|
|
|
|
bestrec = NULL; besttime = now;
|
|
|
|
for (tmp = setupservers; tmp != NULL; tmp = tmp->next) {
|
|
|
|
SERVER_SETUP_REC *rec = tmp->data;
|
|
|
|
|
|
|
|
if (rec->chatnet == NULL ||
|
2014-06-10 12:06:19 -04:00
|
|
|
g_ascii_strcasecmp(rec->chatnet, dest) != 0)
|
2000-08-26 11:39:44 -04:00
|
|
|
continue;
|
|
|
|
|
|
|
|
if (!rec->last_failed) {
|
|
|
|
bestrec = rec;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bestrec == NULL || besttime > rec->last_connect) {
|
|
|
|
bestrec = rec;
|
|
|
|
besttime = rec->last_connect;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return bestrec == NULL ? NULL :
|
2001-03-07 19:24:27 -05:00
|
|
|
create_addr_conn(bestrec->chat_type, bestrec->address, 0,
|
|
|
|
dest, NULL, nick);
|
2000-08-26 11:39:44 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Create server connection record. `dest' is required, rest can be NULL.
|
|
|
|
`dest' is either a server address or chat network */
|
|
|
|
SERVER_CONNECT_REC *
|
2001-02-17 14:44:22 -05:00
|
|
|
server_create_conn(int chat_type, const char *dest, int port,
|
2001-03-07 19:24:27 -05:00
|
|
|
const char *chatnet, const char *password,
|
|
|
|
const char *nick)
|
2000-08-26 11:39:44 -04:00
|
|
|
{
|
|
|
|
SERVER_CONNECT_REC *rec;
|
2001-10-20 17:39:01 -04:00
|
|
|
CHATNET_REC *chatrec;
|
2000-08-26 11:39:44 -04:00
|
|
|
|
|
|
|
g_return_val_if_fail(dest != NULL, NULL);
|
|
|
|
|
2001-10-20 17:39:01 -04:00
|
|
|
chatrec = chatnet_find(dest);
|
|
|
|
if (chatrec != NULL) {
|
|
|
|
rec = create_chatnet_conn(chatrec->name, port, password, nick);
|
2016-03-22 10:45:08 -04:00
|
|
|
/* If rec is NULL the chatnet has no url to connect to */
|
|
|
|
return rec;
|
2000-08-26 11:39:44 -04:00
|
|
|
}
|
|
|
|
|
2001-10-20 18:02:55 -04:00
|
|
|
chatrec = chatnet == NULL ? NULL : chatnet_find(chatnet);
|
2001-10-20 17:39:01 -04:00
|
|
|
if (chatrec != NULL)
|
|
|
|
chatnet = chatrec->name;
|
|
|
|
|
2001-03-07 19:24:27 -05:00
|
|
|
return create_addr_conn(chat_type, dest, port,
|
|
|
|
chatnet, password, nick);
|
2000-08-26 11:39:44 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Find matching server from setup. Try to find record with a same port,
|
|
|
|
but fallback to any server with the same address. */
|
2001-06-27 17:47:31 -04:00
|
|
|
SERVER_SETUP_REC *server_setup_find(const char *address, int port,
|
|
|
|
const char *chatnet)
|
2000-08-26 11:39:44 -04:00
|
|
|
{
|
|
|
|
SERVER_SETUP_REC *server;
|
|
|
|
GSList *tmp;
|
|
|
|
|
|
|
|
g_return_val_if_fail(address != NULL, NULL);
|
|
|
|
|
|
|
|
server = NULL;
|
|
|
|
for (tmp = setupservers; tmp != NULL; tmp = tmp->next) {
|
|
|
|
SERVER_SETUP_REC *rec = tmp->data;
|
|
|
|
|
2014-06-10 12:06:19 -04:00
|
|
|
if (g_ascii_strcasecmp(rec->address, address) == 0 &&
|
2001-06-27 17:47:31 -04:00
|
|
|
(chatnet == NULL || rec->chatnet == NULL ||
|
2014-06-10 12:06:19 -04:00
|
|
|
g_ascii_strcasecmp(rec->chatnet, chatnet) == 0)) {
|
2000-08-26 11:39:44 -04:00
|
|
|
server = rec;
|
|
|
|
if (rec->port == port)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return server;
|
|
|
|
}
|
|
|
|
|
|
|
|
static SERVER_SETUP_REC *server_setup_read(CONFIG_NODE *node)
|
|
|
|
{
|
|
|
|
SERVER_SETUP_REC *rec;
|
2016-10-16 07:46:58 -04:00
|
|
|
CHATNET_REC *chatnetrec;
|
2001-02-20 11:23:28 -05:00
|
|
|
char *server, *chatnet, *family;
|
2000-08-26 11:39:44 -04:00
|
|
|
int port;
|
2016-10-16 07:46:58 -04:00
|
|
|
char *value = NULL;
|
2000-08-26 11:39:44 -04:00
|
|
|
|
|
|
|
g_return_val_if_fail(node != NULL, NULL);
|
|
|
|
|
|
|
|
server = config_node_get_str(node, "address", NULL);
|
|
|
|
if (server == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
2000-09-26 20:25:26 -04:00
|
|
|
port = config_node_get_int(node, "port", 0);
|
2010-03-21 16:06:10 -04:00
|
|
|
chatnet = config_node_get_str(node, "chatnet", NULL);
|
|
|
|
|
|
|
|
if (server_setup_find(server, port, chatnet) != NULL) {
|
2000-08-26 11:39:44 -04:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
rec = NULL;
|
2001-02-17 14:44:22 -05:00
|
|
|
|
|
|
|
chatnetrec = chatnet == NULL ? NULL : chatnet_find(chatnet);
|
|
|
|
if (chatnetrec == NULL && chatnet != NULL) {
|
|
|
|
/* chat network not found, create it. */
|
|
|
|
chatnetrec = chat_protocol_get_default()->create_chatnet();
|
|
|
|
chatnetrec->chat_type = chat_protocol_get_default()->id;
|
|
|
|
chatnetrec->name = g_strdup(chatnet);
|
|
|
|
chatnet_create(chatnetrec);
|
2000-08-26 11:39:44 -04:00
|
|
|
}
|
|
|
|
|
2016-10-16 07:46:58 -04:00
|
|
|
family = config_node_get_str(node, "family", "");
|
2001-02-20 11:23:28 -05:00
|
|
|
|
2001-02-17 14:44:22 -05:00
|
|
|
rec = CHAT_PROTOCOL(chatnetrec)->create_server_setup();
|
2000-08-26 11:39:44 -04:00
|
|
|
rec->type = module_get_uniq_id("SERVER SETUP", 0);
|
2001-02-20 11:23:28 -05:00
|
|
|
rec->chat_type = CHAT_PROTOCOL(chatnetrec)->id;
|
|
|
|
rec->chatnet = chatnetrec == NULL ? NULL : g_strdup(chatnetrec->name);
|
2008-03-09 08:01:16 -04:00
|
|
|
rec->family = g_ascii_strcasecmp(family, "inet6") == 0 ? AF_INET6 :
|
|
|
|
(g_ascii_strcasecmp(family, "inet") == 0 ? AF_INET : 0);
|
2000-08-26 11:39:44 -04:00
|
|
|
rec->address = g_strdup(server);
|
|
|
|
rec->password = g_strdup(config_node_get_str(node, "password", NULL));
|
2016-10-16 07:46:58 -04:00
|
|
|
|
|
|
|
rec->use_tls = config_node_get_bool(node, "use_tls", FALSE) || config_node_get_bool(node, "use_ssl", FALSE);
|
|
|
|
rec->tls_verify = config_node_get_bool(node, "tls_verify", FALSE) || config_node_get_bool(node, "ssl_verify", FALSE);
|
|
|
|
|
|
|
|
value = config_node_get_str(node, "tls_cert", NULL);
|
|
|
|
if (value == NULL)
|
|
|
|
value = config_node_get_str(node, "ssl_cert", NULL);
|
|
|
|
rec->tls_cert = g_strdup(value);
|
|
|
|
|
|
|
|
value = config_node_get_str(node, "tls_pkey", NULL);
|
|
|
|
if (value == NULL)
|
|
|
|
value = config_node_get_str(node, "ssl_pkey", NULL);
|
|
|
|
rec->tls_pkey = g_strdup(value);
|
|
|
|
|
|
|
|
value = config_node_get_str(node, "tls_pass", NULL);
|
|
|
|
if (value == NULL)
|
|
|
|
value = config_node_get_str(node, "ssl_pass", NULL);
|
|
|
|
rec->tls_pass = g_strdup(value);
|
|
|
|
|
|
|
|
value = config_node_get_str(node, "tls_cafile", NULL);
|
|
|
|
if (value == NULL)
|
|
|
|
value = config_node_get_str(node, "ssl_cafile", NULL);
|
|
|
|
rec->tls_cafile = g_strdup(value);
|
|
|
|
|
|
|
|
value = config_node_get_str(node, "tls_capath", NULL);
|
|
|
|
if (value == NULL)
|
|
|
|
value = config_node_get_str(node, "ssl_capath", NULL);
|
|
|
|
rec->tls_capath = g_strdup(value);
|
|
|
|
|
|
|
|
value = config_node_get_str(node, "tls_ciphers", NULL);
|
|
|
|
if (value == NULL)
|
|
|
|
value = config_node_get_str(node, "ssl_ciphers", NULL);
|
|
|
|
rec->tls_ciphers = g_strdup(value);
|
|
|
|
|
2016-10-16 08:39:00 -04:00
|
|
|
value = config_node_get_str(node, "tls_pinned_cert", NULL);
|
|
|
|
if (value == NULL)
|
|
|
|
value = config_node_get_str(node, "ssl_pinned_cert", NULL);
|
|
|
|
rec->tls_pinned_cert = g_strdup(value);
|
|
|
|
|
|
|
|
value = config_node_get_str(node, "tls_pinned_pubkey", NULL);
|
|
|
|
if (value == NULL)
|
|
|
|
value = config_node_get_str(node, "ssl_pinned_pubkey", NULL);
|
|
|
|
rec->tls_pinned_pubkey = g_strdup(value);
|
|
|
|
|
2016-10-16 07:46:58 -04:00
|
|
|
if (rec->tls_cafile || rec->tls_capath)
|
|
|
|
rec->tls_verify = TRUE;
|
|
|
|
if (rec->tls_cert != NULL || rec->tls_verify)
|
|
|
|
rec->use_tls = TRUE;
|
|
|
|
|
2000-08-26 11:39:44 -04:00
|
|
|
rec->port = port;
|
|
|
|
rec->autoconnect = config_node_get_bool(node, "autoconnect", FALSE);
|
2002-01-24 21:28:42 -05:00
|
|
|
rec->no_proxy = config_node_get_bool(node, "no_proxy", FALSE);
|
2000-11-02 11:29:05 -05:00
|
|
|
rec->own_host = g_strdup(config_node_get_str(node, "own_host", NULL));
|
2000-08-26 11:39:44 -04:00
|
|
|
|
2001-02-17 14:44:22 -05:00
|
|
|
signal_emit("server setup read", 2, rec, node);
|
|
|
|
|
2000-08-26 11:39:44 -04:00
|
|
|
setupservers = g_slist_append(setupservers, rec);
|
|
|
|
return rec;
|
|
|
|
}
|
|
|
|
|
2015-12-09 10:02:37 -05:00
|
|
|
static int compare_server_setup (CONFIG_NODE *node, SERVER_SETUP_REC *server)
|
|
|
|
{
|
|
|
|
char *address, *chatnet;
|
|
|
|
int port;
|
|
|
|
|
|
|
|
address = config_node_get_str(node, "address", NULL);
|
|
|
|
chatnet = config_node_get_str(node, "chatnet", NULL);
|
|
|
|
port = config_node_get_int(node, "port", 0);
|
|
|
|
|
2015-12-09 10:16:03 -05:00
|
|
|
if (g_strcmp0(address, server->address) != 0 ||
|
|
|
|
g_strcmp0(chatnet, server->chatnet) != 0 ||
|
|
|
|
port != server->port)
|
2015-12-09 10:02:37 -05:00
|
|
|
return 1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2000-08-26 11:39:44 -04:00
|
|
|
static void server_setup_save(SERVER_SETUP_REC *rec)
|
|
|
|
{
|
2015-12-09 10:02:37 -05:00
|
|
|
CONFIG_NODE *parent_node, *node;
|
|
|
|
GSList *config_node;
|
2000-08-26 11:39:44 -04:00
|
|
|
|
2015-12-09 10:02:37 -05:00
|
|
|
parent_node = iconfig_node_traverse("(servers", TRUE);
|
2000-08-26 11:39:44 -04:00
|
|
|
|
2015-12-09 10:02:37 -05:00
|
|
|
/* Try to find this channel in the configuration */
|
|
|
|
config_node = g_slist_find_custom(parent_node->value, rec,
|
|
|
|
(GCompareFunc)compare_server_setup);
|
|
|
|
if (config_node != NULL)
|
|
|
|
/* Let's update this server record */
|
|
|
|
node = config_node->data;
|
|
|
|
else
|
|
|
|
/* Create a brand-new server record */
|
|
|
|
node = iconfig_node_section(parent_node, NULL, NODE_TYPE_BLOCK);
|
2000-08-26 11:39:44 -04:00
|
|
|
|
|
|
|
iconfig_node_clear(node);
|
|
|
|
iconfig_node_set_str(node, "address", rec->address);
|
|
|
|
iconfig_node_set_str(node, "chatnet", rec->chatnet);
|
|
|
|
|
2000-11-26 05:24:30 -05:00
|
|
|
iconfig_node_set_int(node, "port", rec->port);
|
2000-08-26 11:39:44 -04:00
|
|
|
iconfig_node_set_str(node, "password", rec->password);
|
2016-10-16 07:46:58 -04:00
|
|
|
|
|
|
|
iconfig_node_set_bool(node, "use_tls", rec->use_tls);
|
|
|
|
iconfig_node_set_str(node, "tls_cert", rec->tls_cert);
|
|
|
|
iconfig_node_set_str(node, "tls_pkey", rec->tls_pkey);
|
|
|
|
iconfig_node_set_str(node, "tls_pass", rec->tls_pass);
|
|
|
|
iconfig_node_set_bool(node, "tls_verify", rec->tls_verify);
|
|
|
|
iconfig_node_set_str(node, "tls_cafile", rec->tls_cafile);
|
|
|
|
iconfig_node_set_str(node, "tls_capath", rec->tls_capath);
|
|
|
|
iconfig_node_set_str(node, "tls_ciphers", rec->tls_ciphers);
|
2016-10-16 08:39:00 -04:00
|
|
|
iconfig_node_set_str(node, "tls_pinned_cert", rec->tls_pinned_cert);
|
|
|
|
iconfig_node_set_str(node, "tls_pinned_pubkey", rec->tls_pinned_pubkey);
|
2016-10-16 07:46:58 -04:00
|
|
|
|
2000-08-26 11:39:44 -04:00
|
|
|
iconfig_node_set_str(node, "own_host", rec->own_host);
|
|
|
|
|
2001-02-20 11:23:28 -05:00
|
|
|
iconfig_node_set_str(node, "family",
|
|
|
|
rec->family == AF_INET6 ? "inet6" :
|
|
|
|
rec->family == AF_INET ? "inet" : NULL);
|
|
|
|
|
2000-08-26 11:39:44 -04:00
|
|
|
if (rec->autoconnect)
|
2000-11-26 05:24:30 -05:00
|
|
|
iconfig_node_set_bool(node, "autoconnect", TRUE);
|
2002-01-24 21:28:42 -05:00
|
|
|
if (rec->no_proxy)
|
|
|
|
iconfig_node_set_bool(node, "no_proxy", TRUE);
|
2000-08-26 11:39:44 -04:00
|
|
|
|
|
|
|
signal_emit("server setup saved", 2, rec, node);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void server_setup_remove_config(SERVER_SETUP_REC *rec)
|
|
|
|
{
|
2015-12-09 10:02:37 -05:00
|
|
|
CONFIG_NODE *parent_node;
|
|
|
|
GSList *config_node;
|
2000-08-26 11:39:44 -04:00
|
|
|
|
2015-12-09 10:02:37 -05:00
|
|
|
parent_node = iconfig_node_traverse("servers", FALSE);
|
|
|
|
|
|
|
|
if (parent_node == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Try to find this server in the configuration */
|
|
|
|
config_node = g_slist_find_custom(parent_node->value, rec,
|
|
|
|
(GCompareFunc)compare_server_setup);
|
|
|
|
|
|
|
|
if (config_node != NULL)
|
|
|
|
/* Delete the server from the configuration */
|
|
|
|
iconfig_node_remove(parent_node, config_node->data);
|
2000-08-26 11:39:44 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void server_setup_destroy(SERVER_SETUP_REC *rec)
|
|
|
|
{
|
|
|
|
setupservers = g_slist_remove(setupservers, rec);
|
|
|
|
signal_emit("server setup destroyed", 1, rec);
|
|
|
|
|
|
|
|
g_free_not_null(rec->own_host);
|
2015-09-22 15:59:17 -04:00
|
|
|
g_free_not_null(rec->own_ip4);
|
|
|
|
g_free_not_null(rec->own_ip6);
|
2000-08-26 11:39:44 -04:00
|
|
|
g_free_not_null(rec->chatnet);
|
|
|
|
g_free_not_null(rec->password);
|
2016-10-16 07:46:58 -04:00
|
|
|
g_free_not_null(rec->tls_cert);
|
|
|
|
g_free_not_null(rec->tls_pkey);
|
|
|
|
g_free_not_null(rec->tls_pass);
|
|
|
|
g_free_not_null(rec->tls_cafile);
|
|
|
|
g_free_not_null(rec->tls_capath);
|
|
|
|
g_free_not_null(rec->tls_ciphers);
|
2016-10-16 08:39:00 -04:00
|
|
|
g_free_not_null(rec->tls_pinned_cert);
|
|
|
|
g_free_not_null(rec->tls_pinned_pubkey);
|
2001-02-17 14:44:22 -05:00
|
|
|
g_free(rec->address);
|
2000-08-26 11:39:44 -04:00
|
|
|
g_free(rec);
|
|
|
|
}
|
|
|
|
|
|
|
|
void server_setup_add(SERVER_SETUP_REC *rec)
|
|
|
|
{
|
2000-09-06 17:30:56 -04:00
|
|
|
rec->type = module_get_uniq_id("SERVER SETUP", 0);
|
2000-08-26 11:39:44 -04:00
|
|
|
if (g_slist_find(setupservers, rec) == NULL)
|
|
|
|
setupservers = g_slist_append(setupservers, rec);
|
|
|
|
server_setup_save(rec);
|
2002-05-10 20:37:48 -04:00
|
|
|
|
|
|
|
signal_emit("server setup updated", 1, rec);
|
2000-08-26 11:39:44 -04:00
|
|
|
}
|
|
|
|
|
2015-10-01 16:36:02 -04:00
|
|
|
void server_setup_remove_chatnet(const char *chatnet)
|
|
|
|
{
|
|
|
|
GSList *tmp, *next;
|
|
|
|
|
2015-10-01 16:53:34 -04:00
|
|
|
g_return_if_fail(chatnet != NULL);
|
2015-10-01 16:36:02 -04:00
|
|
|
|
|
|
|
for (tmp = setupservers; tmp != NULL; tmp = next) {
|
|
|
|
SERVER_SETUP_REC *rec = tmp->data;
|
|
|
|
|
|
|
|
next = tmp->next;
|
|
|
|
if (g_ascii_strcasecmp(rec->chatnet, chatnet) == 0)
|
|
|
|
server_setup_remove(rec);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-08-26 11:39:44 -04:00
|
|
|
void server_setup_remove(SERVER_SETUP_REC *rec)
|
|
|
|
{
|
|
|
|
server_setup_remove_config(rec);
|
|
|
|
server_setup_destroy(rec);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void read_servers(void)
|
|
|
|
{
|
|
|
|
CONFIG_NODE *node;
|
|
|
|
GSList *tmp;
|
|
|
|
|
|
|
|
while (setupservers != NULL)
|
|
|
|
server_setup_destroy(setupservers->data);
|
|
|
|
|
|
|
|
/* Read servers */
|
|
|
|
node = iconfig_node_traverse("servers", FALSE);
|
|
|
|
if (node != NULL) {
|
2002-02-02 12:37:44 -05:00
|
|
|
tmp = config_node_first(node->value);
|
|
|
|
for (; tmp != NULL; tmp = config_node_next(tmp))
|
2000-08-26 11:39:44 -04:00
|
|
|
server_setup_read(tmp->data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void read_settings(void)
|
|
|
|
{
|
2001-02-20 11:23:28 -05:00
|
|
|
if (old_source_host == NULL ||
|
2015-04-07 21:39:05 -04:00
|
|
|
g_strcmp0(old_source_host, settings_get_str("hostname")) != 0) {
|
2001-02-20 11:23:28 -05:00
|
|
|
g_free_not_null(old_source_host);
|
|
|
|
old_source_host = g_strdup(settings_get_str("hostname"));
|
|
|
|
|
|
|
|
source_host_ok = FALSE;
|
|
|
|
get_source_host_ip();
|
|
|
|
}
|
2000-08-26 11:39:44 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void servers_setup_init(void)
|
|
|
|
{
|
|
|
|
settings_add_str("server", "hostname", "");
|
|
|
|
|
2000-09-06 19:24:12 -04:00
|
|
|
settings_add_str("server", "nick", NULL);
|
2000-08-26 11:39:44 -04:00
|
|
|
settings_add_str("server", "user_name", NULL);
|
|
|
|
settings_add_str("server", "real_name", NULL);
|
|
|
|
|
|
|
|
settings_add_bool("proxy", "use_proxy", FALSE);
|
|
|
|
settings_add_str("proxy", "proxy_address", "");
|
|
|
|
settings_add_int("proxy", "proxy_port", 6667);
|
|
|
|
settings_add_str("proxy", "proxy_string", "CONNECT %s %d");
|
2002-01-22 15:29:45 -05:00
|
|
|
settings_add_str("proxy", "proxy_string_after", "");
|
2001-03-20 18:24:45 -05:00
|
|
|
settings_add_str("proxy", "proxy_password", "");
|
2000-08-26 11:39:44 -04:00
|
|
|
|
2001-02-17 14:44:22 -05:00
|
|
|
setupservers = NULL;
|
2015-09-22 15:59:17 -04:00
|
|
|
source_host_ip4 = source_host_ip6 = NULL;
|
2001-02-20 11:23:28 -05:00
|
|
|
old_source_host = NULL;
|
2000-08-26 11:39:44 -04:00
|
|
|
read_settings();
|
|
|
|
|
|
|
|
signal_add("setup changed", (SIGNAL_FUNC) read_settings);
|
|
|
|
signal_add("setup reread", (SIGNAL_FUNC) read_servers);
|
|
|
|
signal_add("irssi init read settings", (SIGNAL_FUNC) read_servers);
|
|
|
|
}
|
|
|
|
|
|
|
|
void servers_setup_deinit(void)
|
|
|
|
{
|
2015-09-22 15:59:17 -04:00
|
|
|
g_free_not_null(source_host_ip4);
|
|
|
|
g_free_not_null(source_host_ip6);
|
2001-02-20 11:23:28 -05:00
|
|
|
g_free_not_null(old_source_host);
|
2000-08-26 11:39:44 -04:00
|
|
|
|
|
|
|
while (setupservers != NULL)
|
|
|
|
server_setup_destroy(setupservers->data);
|
|
|
|
|
|
|
|
signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
|
|
|
|
signal_remove("setup reread", (SIGNAL_FUNC) read_servers);
|
|
|
|
signal_remove("irssi init read settings", (SIGNAL_FUNC) read_servers);
|
|
|
|
|
|
|
|
module_uniq_destroy("SERVER SETUP");
|
|
|
|
}
|