From 244a8c72b4d1226469f1193b3ca58946c01d9e00 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 7 Apr 2021 22:18:05 +0200 Subject: [PATCH] verify tls connection --- irssi.conf | 4 +- src/core/chat-commands.c | 47 +------------------- src/core/servers-setup.c | 74 ++++++++++++++++++++++++++++--- src/fe-common/core/fe-server.c | 39 +++++++++++----- src/fe-common/irc/fe-irc-server.c | 8 ++-- src/irc/core/irc-servers-setup.c | 17 ++++++- src/irc/core/irc-servers.c | 1 + src/irc/core/irc-session.c | 4 +- 8 files changed, 123 insertions(+), 71 deletions(-) diff --git a/irssi.conf b/irssi.conf index 174d0552..80c2b9c3 100644 --- a/irssi.conf +++ b/irssi.conf @@ -1,10 +1,10 @@ servers = ( { address = "irc.dal.net"; chatnet = "DALnet"; port = "6667"; }, - { address = "ssl.efnet.org"; chatnet = "EFNet"; port = "9999"; use_tls = "yes"; }, + { address = "ssl.efnet.org"; chatnet = "EFNet"; port = "9999"; use_tls = "yes"; tls_verify = "no"; }, { address = "irc.esper.net"; chatnet = "EsperNet"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, { address = "chat.freenode.net"; chatnet = "Freenode"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, { address = "irc.gamesurge.net"; chatnet = "GameSurge"; port = "6667"; }, - { address = "eu.irc6.net"; chatnet = "IRCnet"; port = "6667"; use_tls = "yes"; }, + { address = "ssl.ircnet.ovh"; chatnet = "IRCnet"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, { address = "open.ircnet.net"; chatnet = "IRCnet"; port = "6667"; }, { address = "irc.ircsource.net"; chatnet = "IRCSource"; port = "6667"; }, { address = "irc.netfuze.net"; chatnet = "NetFuze"; port = "6667"; }, diff --git a/src/core/chat-commands.c b/src/core/chat-commands.c index 92bb9db8..dd8dbe75 100644 --- a/src/core/chat-commands.c +++ b/src/core/chat-commands.c @@ -40,7 +40,7 @@ static SERVER_CONNECT_REC *get_server_connect(const char *data, int *plus_addr, CHAT_PROTOCOL_REC *proto; SERVER_CONNECT_REC *conn; GHashTable *optlist; - char *addr, *portstr, *password, *nick, *chatnet, *host, *tmp; + char *addr, *portstr, *password, *nick, *chatnet, *host; void *free_arg; g_return_val_if_fail(data != NULL, NULL); @@ -94,50 +94,7 @@ static SERVER_CONNECT_REC *get_server_connect(const char *data, int *plus_addr, if (strchr(addr, '/') != NULL) conn->unix_socket = TRUE; - if (g_hash_table_lookup(optlist, "6") != NULL) - conn->family = AF_INET6; - else if (g_hash_table_lookup(optlist, "4") != NULL) - conn->family = AF_INET; - - if (g_hash_table_lookup(optlist, "notls") != NULL) - conn->use_tls = FALSE; - if (g_hash_table_lookup(optlist, "tls") != NULL || g_hash_table_lookup(optlist, "ssl") != NULL) - conn->use_tls = TRUE; - if ((tmp = g_hash_table_lookup(optlist, "tls_cert")) != NULL || (tmp = g_hash_table_lookup(optlist, "ssl_cert")) != NULL) - conn->tls_cert = g_strdup(tmp); - if ((tmp = g_hash_table_lookup(optlist, "tls_pkey")) != NULL || (tmp = g_hash_table_lookup(optlist, "ssl_pkey")) != NULL) - conn->tls_pkey = g_strdup(tmp); - if ((tmp = g_hash_table_lookup(optlist, "tls_pass")) != NULL || (tmp = g_hash_table_lookup(optlist, "ssl_pass")) != NULL) - conn->tls_pass = g_strdup(tmp); - if (g_hash_table_lookup(optlist, "notls_verify") != NULL) - conn->tls_verify = FALSE; - if (g_hash_table_lookup(optlist, "tls_verify") != NULL || g_hash_table_lookup(optlist, "ssl_verify") != NULL) - conn->tls_verify = TRUE; - if ((tmp = g_hash_table_lookup(optlist, "tls_cafile")) != NULL || (tmp = g_hash_table_lookup(optlist, "ssl_cafile")) != NULL) - conn->tls_cafile = g_strdup(tmp); - if ((tmp = g_hash_table_lookup(optlist, "tls_capath")) != NULL || (tmp = g_hash_table_lookup(optlist, "ssl_capath")) != NULL) - conn->tls_capath = g_strdup(tmp); - if ((tmp = g_hash_table_lookup(optlist, "tls_ciphers")) != NULL || (tmp = g_hash_table_lookup(optlist, "ssl_ciphers")) != NULL) - conn->tls_ciphers = g_strdup(tmp); - if ((tmp = g_hash_table_lookup(optlist, "tls_pinned_cert")) != NULL || (tmp = g_hash_table_lookup(optlist, "ssl_pinned_cert")) != NULL) - conn->tls_pinned_cert = g_strdup(tmp); - if ((tmp = g_hash_table_lookup(optlist, "tls_pinned_pubkey")) != NULL || (tmp = g_hash_table_lookup(optlist, "ssl_pinned_pubkey")) != NULL) - conn->tls_pinned_pubkey = g_strdup(tmp); - if ((conn->tls_capath != NULL && conn->tls_capath[0] != '\0') - || (conn->tls_cafile != NULL && conn->tls_cafile[0] != '\0')) - conn->tls_verify = TRUE; - if ((conn->tls_cert != NULL && conn->tls_cert[0] != '\0') || conn->tls_verify) - conn->use_tls = TRUE; - - if (g_hash_table_lookup(optlist, "!") != NULL) - conn->no_autojoin_channels = TRUE; - - if (g_hash_table_lookup(optlist, "noautosendcmd") != NULL) - conn->no_autosendcmd = TRUE; - - if (g_hash_table_lookup(optlist, "noproxy") != NULL) - g_free_and_null(conn->proxy); - + /* TLS options are handled in server_create_conn_opt ... -> server_setup_fill_optlist */ *rawlog_file = g_strdup(g_hash_table_lookup(optlist, "rawlog")); diff --git a/src/core/servers-setup.c b/src/core/servers-setup.c index c6612e84..357e8ebe 100644 --- a/src/core/servers-setup.c +++ b/src/core/servers-setup.c @@ -180,6 +180,68 @@ static void server_setup_fill(SERVER_CONNECT_REC *conn, const char *address, int signal_emit("server setup fill connect", 2, conn, optlist); } +static void server_setup_fill_optlist(SERVER_CONNECT_REC *conn, GHashTable *optlist) +{ + char *tmp; + + if (g_hash_table_lookup(optlist, "6") != NULL) + conn->family = AF_INET6; + else if (g_hash_table_lookup(optlist, "4") != NULL) + conn->family = AF_INET; + + /* ad-hoc TLS settings from command optlist */ + if ((tmp = g_hash_table_lookup(optlist, "tls_cert")) != NULL || + (tmp = g_hash_table_lookup(optlist, "ssl_cert")) != NULL) + conn->tls_cert = g_strdup(tmp); + if ((tmp = g_hash_table_lookup(optlist, "tls_pkey")) != NULL || + (tmp = g_hash_table_lookup(optlist, "ssl_pkey")) != NULL) + conn->tls_pkey = g_strdup(tmp); + if ((tmp = g_hash_table_lookup(optlist, "tls_pass")) != NULL || + (tmp = g_hash_table_lookup(optlist, "ssl_pass")) != NULL) + conn->tls_pass = g_strdup(tmp); + if ((tmp = g_hash_table_lookup(optlist, "tls_cafile")) != NULL || + (tmp = g_hash_table_lookup(optlist, "ssl_cafile")) != NULL) + conn->tls_cafile = g_strdup(tmp); + if ((tmp = g_hash_table_lookup(optlist, "tls_capath")) != NULL || + (tmp = g_hash_table_lookup(optlist, "ssl_capath")) != NULL) + conn->tls_capath = g_strdup(tmp); + if ((tmp = g_hash_table_lookup(optlist, "tls_ciphers")) != NULL || + (tmp = g_hash_table_lookup(optlist, "ssl_ciphers")) != NULL) + conn->tls_ciphers = g_strdup(tmp); + if ((tmp = g_hash_table_lookup(optlist, "tls_pinned_cert")) != NULL || + (tmp = g_hash_table_lookup(optlist, "ssl_pinned_cert")) != NULL) + conn->tls_pinned_cert = g_strdup(tmp); + if ((tmp = g_hash_table_lookup(optlist, "tls_pinned_pubkey")) != NULL || + (tmp = g_hash_table_lookup(optlist, "ssl_pinned_pubkey")) != NULL) + conn->tls_pinned_pubkey = g_strdup(tmp); + if ((conn->tls_capath != NULL && conn->tls_capath[0] != '\0') || + (conn->tls_cafile != NULL && conn->tls_cafile[0] != '\0')) + conn->tls_verify = TRUE; + if (g_hash_table_lookup(optlist, "notls_verify") != NULL) + conn->tls_verify = FALSE; + if (g_hash_table_lookup(optlist, "tls_verify") != NULL || + g_hash_table_lookup(optlist, "ssl_verify") != NULL) + conn->tls_verify = TRUE; + if ((conn->tls_cert != NULL && conn->tls_cert[0] != '\0') || conn->tls_verify) + conn->use_tls = TRUE; + if (g_hash_table_lookup(optlist, "notls") != NULL) + conn->use_tls = FALSE; + if (g_hash_table_lookup(optlist, "tls") != NULL || + g_hash_table_lookup(optlist, "ssl") != NULL) + conn->use_tls = TRUE; + + if (g_hash_table_lookup(optlist, "!") != NULL) + conn->no_autojoin_channels = TRUE; + + if (g_hash_table_lookup(optlist, "noautosendcmd") != NULL) + conn->no_autosendcmd = TRUE; + + if (g_hash_table_lookup(optlist, "noproxy") != NULL) + g_free_and_null(conn->proxy); + + signal_emit("server setup fill optlist", 2, conn, optlist); +} + static void server_setup_fill_server(SERVER_CONNECT_REC *conn, SERVER_SETUP_REC *sserver) { @@ -262,6 +324,10 @@ static SERVER_CONNECT_REC *create_addr_conn(int chat_type, const char *address, if (sserver != NULL) server_setup_fill_server(conn, sserver); + /* fill the optlist overrides */ + if (g_hash_table_size(optlist)) + server_setup_fill_optlist(conn, optlist); + /* nick / password given in command line overrides all settings */ if (password && *password) { g_free_not_null(conn->password); @@ -418,7 +484,8 @@ static SERVER_SETUP_REC *server_setup_read(CONFIG_NODE *node) rec->password = g_strdup(config_node_get_str(node, "password", NULL)); 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); + rec->tls_verify = config_node_get_bool(node, "tls_verify", TRUE) || + config_node_get_bool(node, "ssl_verify", FALSE); value = config_node_get_str(node, "tls_cert", NULL); if (value == NULL) @@ -460,11 +527,6 @@ static SERVER_SETUP_REC *server_setup_read(CONFIG_NODE *node) value = config_node_get_str(node, "ssl_pinned_pubkey", NULL); rec->tls_pinned_pubkey = g_strdup(value); - if (rec->tls_cafile || rec->tls_capath) - rec->tls_verify = TRUE; - if (rec->tls_cert != NULL || rec->tls_verify) - rec->use_tls = TRUE; - rec->port = port; rec->autoconnect = config_node_get_bool(node, "autoconnect", FALSE); rec->no_proxy = config_node_get_bool(node, "no_proxy", FALSE); diff --git a/src/fe-common/core/fe-server.c b/src/fe-common/core/fe-server.c index 5e51e511..e0100618 100644 --- a/src/fe-common/core/fe-server.c +++ b/src/fe-common/core/fe-server.c @@ -101,6 +101,7 @@ static SERVER_SETUP_REC *create_server_setup(GHashTable *optlist) server = rec->create_server_setup(); server->chat_type = rec->id; + server->tls_verify = TRUE; return server; } @@ -110,6 +111,7 @@ static void cmd_server_add_modify(const char *data, gboolean add) SERVER_SETUP_REC *rec; char *addr, *portstr, *password, *value, *chatnet; void *free_arg; + gboolean newrec; int port; if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_OPTIONS, @@ -135,6 +137,7 @@ static void cmd_server_add_modify(const char *data, gboolean add) rec = server_setup_find(addr, port, chatnet); if (rec == NULL) { + newrec = TRUE; if (add == FALSE) { printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_SETUPSERVER_NOT_FOUND, addr, port); @@ -150,6 +153,7 @@ static void cmd_server_add_modify(const char *data, gboolean add) rec->address = g_strdup(addr); rec->port = port; } else { + newrec = FALSE; if (*portstr != '\0' || g_hash_table_lookup(optlist, "port")) rec->port = port; @@ -165,16 +169,17 @@ static void cmd_server_add_modify(const char *data, gboolean add) else if (g_hash_table_lookup(optlist, "4")) rec->family = AF_INET; - if (g_hash_table_lookup(optlist, "tls") || g_hash_table_lookup(optlist, "ssl")) - rec->use_tls = TRUE; - else if (g_hash_table_lookup(optlist, "notls") || g_hash_table_lookup(optlist, "nossl")) - rec->use_tls = FALSE; - value = g_hash_table_lookup(optlist, "tls_cert"); if (value == NULL) value = g_hash_table_lookup(optlist, "ssl_cert"); - if (value != NULL && *value != '\0') + if (value != NULL && *value != '\0') { rec->tls_cert = g_strdup(value); + if (newrec) { + /* convenience and backward compatibility, turn on tls if tls_cert is given + */ + rec->use_tls = TRUE; + } + } value = g_hash_table_lookup(optlist, "tls_pkey"); if (value == NULL) @@ -188,11 +193,6 @@ static void cmd_server_add_modify(const char *data, gboolean add) if (value != NULL && *value != '\0') rec->tls_pass = g_strdup(value); - if (g_hash_table_lookup(optlist, "tls_verify") || g_hash_table_lookup(optlist, "ssl_verify")) - rec->tls_verify = TRUE; - else if (g_hash_table_lookup(optlist, "notls_verify") || g_hash_table_lookup(optlist, "nossl_verify")) - rec->tls_verify = FALSE; - value = g_hash_table_lookup(optlist, "tls_cafile"); if (value == NULL) value = g_hash_table_lookup(optlist, "ssl_cafile"); @@ -227,8 +227,23 @@ static void cmd_server_add_modify(const char *data, gboolean add) || (rec->tls_capath != NULL && rec->tls_capath[0] != '\0')) rec->tls_verify = TRUE; - if ((rec->tls_cert != NULL && rec->tls_cert[0] != '\0') || rec->tls_verify == TRUE) + if (g_hash_table_lookup(optlist, "tls_verify") || + g_hash_table_lookup(optlist, "ssl_verify")) { + rec->tls_verify = TRUE; + if (newrec) { + /* convenience and backward compatibility, turn on tls if tls_verify is + * given */ + rec->use_tls = TRUE; + } + } else if (g_hash_table_lookup(optlist, "notls_verify") || + g_hash_table_lookup(optlist, "nossl_verify")) { + rec->tls_verify = FALSE; + } + + if (g_hash_table_lookup(optlist, "tls") || g_hash_table_lookup(optlist, "ssl")) rec->use_tls = TRUE; + else if (g_hash_table_lookup(optlist, "notls") || g_hash_table_lookup(optlist, "nossl")) + rec->use_tls = FALSE; if (g_hash_table_lookup(optlist, "auto")) rec->autoconnect = TRUE; if (g_hash_table_lookup(optlist, "noauto")) rec->autoconnect = FALSE; diff --git a/src/fe-common/irc/fe-irc-server.c b/src/fe-common/irc/fe-irc-server.c index d30aa45d..66483991 100644 --- a/src/fe-common/irc/fe-irc-server.c +++ b/src/fe-common/irc/fe-irc-server.c @@ -91,8 +91,10 @@ static void sig_server_add_fill(IRC_SERVER_SETUP_REC *rec, rec->starttls = -1; if (g_hash_table_lookup(optlist, "disallow_starttls")) rec->starttls = 0; - if (g_hash_table_lookup(optlist, "starttls")) + if (g_hash_table_lookup(optlist, "starttls")) { rec->starttls = 1; + rec->use_tls = 0; + } } /* SYNTAX: SERVER LIST */ @@ -129,8 +131,8 @@ static void cmd_server_list(const char *data) if (rec->tls_pass) g_string_append_printf(str, "(pass), "); } - if (rec->tls_verify) - g_string_append(str, "tls_verify, "); + if (!rec->tls_verify) + g_string_append(str, "notls_verify, "); if (rec->tls_cafile) g_string_append_printf(str, "tls_cafile: %s, ", rec->tls_cafile); if (rec->tls_capath) diff --git a/src/irc/core/irc-servers-setup.c b/src/irc/core/irc-servers-setup.c index 6ba22862..a48e1e92 100644 --- a/src/irc/core/irc-servers-setup.c +++ b/src/irc/core/irc-servers-setup.c @@ -64,11 +64,19 @@ static void sig_server_setup_fill_connect(IRC_SERVER_CONNECT_REC *conn, GHashTab value = settings_get_str("usermode"); conn->usermode = (value != NULL && *value != '\0') ? g_strdup(value) : NULL; +} - if (g_hash_table_lookup(optlist, "starttls") != NULL) +static void sig_server_setup_fill_optlist(IRC_SERVER_CONNECT_REC *conn, GHashTable *optlist) +{ + if (!IS_IRC_SERVER_CONNECT(conn)) + return; + + if (g_hash_table_lookup(optlist, "starttls") != NULL) { conn->starttls = 1; - else if (g_hash_table_lookup(optlist, "disallow_starttls") != NULL) + conn->use_tls = 0; + } else if (g_hash_table_lookup(optlist, "disallow_starttls") != NULL) { conn->disallow_starttls = 1; + } } static void sig_server_setup_fill_chatnet(IRC_SERVER_CONNECT_REC *conn, @@ -184,6 +192,9 @@ static void sig_server_setup_read(IRC_SERVER_SETUP_REC *rec, CONFIG_NODE *node) rec->cmd_queue_speed = config_node_get_int(node, "cmd_queue_speed", 0); rec->max_query_chans = config_node_get_int(node, "max_query_chans", 0); rec->starttls = config_node_get_bool(node, "starttls", -1); + if (rec->starttls == 1) { + rec->use_tls = 0; + } } static void sig_server_setup_saved(IRC_SERVER_SETUP_REC *rec, @@ -213,6 +224,7 @@ void irc_servers_setup_init(void) signal_add("server setup fill reconn", (SIGNAL_FUNC) sig_server_setup_fill_reconn); signal_add("server setup fill connect", (SIGNAL_FUNC) sig_server_setup_fill_connect); signal_add("server setup fill chatnet", (SIGNAL_FUNC) sig_server_setup_fill_chatnet); + signal_add("server setup fill optlist", (SIGNAL_FUNC) sig_server_setup_fill_optlist); signal_add("server setup read", (SIGNAL_FUNC) sig_server_setup_read); signal_add("server setup saved", (SIGNAL_FUNC) sig_server_setup_saved); } @@ -222,6 +234,7 @@ void irc_servers_setup_deinit(void) signal_remove("server setup fill reconn", (SIGNAL_FUNC) sig_server_setup_fill_reconn); signal_remove("server setup fill connect", (SIGNAL_FUNC) sig_server_setup_fill_connect); signal_remove("server setup fill chatnet", (SIGNAL_FUNC) sig_server_setup_fill_chatnet); + signal_remove("server setup fill optlist", (SIGNAL_FUNC) sig_server_setup_fill_optlist); signal_remove("server setup read", (SIGNAL_FUNC) sig_server_setup_read); signal_remove("server setup saved", (SIGNAL_FUNC) sig_server_setup_saved); } diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 00a6458b..62d47db1 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -470,6 +470,7 @@ void irc_server_connect(SERVER_REC *server) g_return_if_fail(server != NULL); if (server->connrec->connect_handle != NULL) { + /* an existing handle from upgrade */ IRC_SERVER_CONNECT_REC *conn; int tls_disconnect; diff --git a/src/irc/core/irc-session.c b/src/irc/core/irc-session.c index 70683c4f..164e68bc 100644 --- a/src/irc/core/irc-session.c +++ b/src/irc/core/irc-session.c @@ -128,8 +128,10 @@ static void sig_session_restore_server(IRC_SERVER_REC *server, starttls_mode = config_node_get_int(node, "starttls", -1); if (starttls_mode == 0) server->connrec->disallow_starttls = 1; - if (starttls_mode == 1) + if (starttls_mode == 1) { server->connrec->starttls = 1; + server->connrec->use_tls = 0; + } if (server->isupport == NULL) { server->isupport =