From fd44fd8b2524fb73543216e8761dad2aa294dea7 Mon Sep 17 00:00:00 2001 From: Acts1631 Date: Thu, 9 Jul 2026 17:13:04 -0400 Subject: [PATCH] irc-proxy: expire unauthenticated clients The TCP proxy allocates a client record before PASS is processed. Silent peers can keep unauthenticated connections open indefinitely, even when a proxy password is configured. Add a configurable one-minute authentication timeout and cancel it after successful registration. --- src/irc/proxy/listen.c | 16 ++++++++++++++++ src/irc/proxy/proxy.c | 1 + src/irc/proxy/proxy.h | 2 +- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/irc/proxy/listen.c b/src/irc/proxy/listen.c index 1fed639e..c7b9e766 100644 --- a/src/irc/proxy/listen.c +++ b/src/irc/proxy/listen.c @@ -116,11 +116,21 @@ static void remove_client(CLIENT_REC *rec) g_free(rec->proxy_address); net_sendbuffer_destroy(rec->handle, TRUE); g_source_remove(rec->recv_tag); + if (rec->auth_timeout != -1) + g_source_remove(rec->auth_timeout); g_free_not_null(rec->nick); g_free_not_null(rec->addr); g_free(rec); } +static int sig_client_auth_timeout(CLIENT_REC *client) +{ + client->auth_timeout = -1; + if (!client->connected) + remove_client(client); + return 0; +} + static void proxy_redirect_event(CLIENT_REC *client, const char *command, int count, const char *arg, int remote) { @@ -222,6 +232,10 @@ static void handle_client_connect_cmd(CLIENT_REC *client, /* client didn't send us PASS, kill it */ remove_client(client); } else { + if (client->auth_timeout != -1) { + g_source_remove(client->auth_timeout); + client->auth_timeout = -1; + } signal_emit("proxy client connected", 1, client); printtext(client->server, NULL, MSGLEVEL_CLIENTNOTICE, "Proxy: Client %s connected", @@ -471,6 +485,8 @@ static void sig_listen(LISTEN_REC *listen) IRC_SERVER(server_find_chatnet(listen->ircnet)); } rec->recv_tag = i_input_add(handle, I_INPUT_READ, (GInputFunction) sig_listen_client, rec); + rec->auth_timeout = g_timeout_add(settings_get_time("irssiproxy_timeout"), + (GSourceFunc) sig_client_auth_timeout, rec); proxy_clients = g_slist_prepend(proxy_clients, rec); listen->clients = g_slist_prepend(listen->clients, rec); diff --git a/src/irc/proxy/proxy.c b/src/irc/proxy/proxy.c index 240df971..2bbd1824 100644 --- a/src/irc/proxy/proxy.c +++ b/src/irc/proxy/proxy.c @@ -75,6 +75,7 @@ static void irc_proxy_setup_changed(void) void irc_proxy_init(void) { settings_add_bool("irssiproxy", "irssiproxy_prefer_ipv6", TRUE); + settings_add_time("irssiproxy", "irssiproxy_timeout", "1min"); settings_add_str("irssiproxy", "irssiproxy_ports", ""); settings_add_str("irssiproxy", "irssiproxy_password", ""); settings_add_str("irssiproxy", "irssiproxy_bind", ""); diff --git a/src/irc/proxy/proxy.h b/src/irc/proxy/proxy.h index 5b3d25f5..b43bb751 100644 --- a/src/irc/proxy/proxy.h +++ b/src/irc/proxy/proxy.h @@ -22,7 +22,7 @@ typedef struct { typedef struct { char *nick, *addr; NET_SENDBUF_REC *handle; - int recv_tag; + int recv_tag, auth_timeout; char *proxy_address; LISTEN_REC *listen; IRC_SERVER_REC *server;