From 5e6094e437a5437ceb6b083d16995ea629a4d720 Mon Sep 17 00:00:00 2001 From: "C. McEnroe" Date: Sun, 12 Jan 2020 18:07:54 -0500 Subject: Add option to set local client CA This is a little bit messy. Allows setting either -A or -W or both. Implements SASL EXTERNAL for clients that expect that when connecting with a client certificate. Need to test that reloading still works inside capsicum, since I suspect that rewind call may be blocked. --- client.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'client.c') diff --git a/client.c b/client.c index a598ec0..fe5eceb 100644 --- a/client.c +++ b/client.c @@ -30,6 +30,7 @@ #include "bounce.h" +bool clientCA; char *clientPass; char *clientAway; @@ -57,6 +58,9 @@ struct Client *clientAlloc(struct tls *tls) { if (!client) err(EX_OSERR, "calloc"); client->tls = tls; client->need = NeedNick | NeedUser | (clientPass ? NeedPass : 0); + if (clientCA && tls_peer_cert_provided(tls)) { + client->need &= ~NeedPass; + } return client; } @@ -160,7 +164,9 @@ static void handlePass(struct Client *client, struct Message *msg) { static void handleCap(struct Client *client, struct Message *msg) { if (!msg->params[0]) msg->params[0] = ""; + enum Cap avail = CapServerTime | CapPassive | (stateCaps & ~CapSASL); + if (clientCA) avail |= CapSASL; if (!strcmp(msg->params[0], "END")) { if (!client->need) return; @@ -192,6 +198,27 @@ static void handleCap(struct Client *client, struct Message *msg) { } } +static void handleAuthenticate(struct Client *client, struct Message *msg) { + if (!msg->params[0]) msg->params[0] = ""; + if (!strcmp(msg->params[0], "EXTERNAL")) { + clientFormat(client, "AUTHENTICATE +\r\n"); + } else if (!strcmp(msg->params[0], "+")) { + clientFormat( + client, ":%s 900 * %s * :You are now logged in as *\r\n", + ORIGIN, stateEcho() + ); + clientFormat( + client, ":%s 903 * :SASL authentication successful\r\n", + ORIGIN + ); + } else { + clientFormat( + client, ":%s 904 * :SASL authentication failed\r\n", + ORIGIN + ); + } +} + static void handleQuit(struct Client *client, struct Message *msg) { (void)msg; clientFormat(client, "ERROR :Detaching\r\n"); @@ -218,6 +245,7 @@ static const struct { Handler *fn; bool need; } Handlers[] = { + { "AUTHENTICATE", handleAuthenticate, false }, { "CAP", handleCap, false }, { "NICK", handleNick, false }, { "NOTICE", handlePrivmsg, true }, -- cgit 1.4.1