aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Eric Janouch <p@janouch.name>2021-05-28 02:11:23 +0200
committerPřemysl Eric Janouch <p@janouch.name>2021-05-28 04:59:20 +0200
commit5a0b2d1c5752c6e6541c9bb8c2ca7f5ce6a58565 (patch)
tree693b9d429d0bf8d3d8e4380200ec59b42da84061
parentbb451a5050e5083b516d3eebce94deb15a666ddd (diff)
downloadxK-5a0b2d1c5752c6e6541c9bb8c2ca7f5ce6a58565.tar.gz
xK-5a0b2d1c5752c6e6541c9bb8c2ca7f5ce6a58565.tar.xz
xK-5a0b2d1c5752c6e6541c9bb8c2ca7f5ce6a58565.zip
degesch: add trivial SASL EXTERNAL support
Just set `tls_cert`, and add `sasl` to `capabilities`.
-rw-r--r--NEWS3
-rw-r--r--degesch.c74
-rw-r--r--kike-replies6
3 files changed, 61 insertions, 22 deletions
diff --git a/NEWS b/NEWS
index 8c56d81..1c1a528 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,9 @@
* degesch: added a /squery command for IRCnet
+ * degesch: added trivial support for SASL EXTERNAL, enabled by adding "sasl"
+ to the respective server's "capabilities" list
+
* degesch: now supporting IRCv3.2 capability negotiation, including CAP DEL
diff --git a/degesch.c b/degesch.c
index eaf71fa..b186125 100644
--- a/degesch.c
+++ b/degesch.c
@@ -1721,6 +1721,7 @@ struct server
struct strv cap_ls_buf; ///< Buffer for IRCv3.2 CAP LS
bool cap_echo_message; ///< Whether the server echoes messages
bool cap_away_notify; ///< Whether we get AWAY notifications
+ bool cap_sasl; ///< Whether SASL is available
// Server-specific information (from RPL_ISUPPORT):
@@ -4962,6 +4963,7 @@ irc_destroy_state (struct server *s)
strv_reset (&s->cap_ls_buf);
s->cap_away_notify = false;
s->cap_echo_message = false;
+ s->cap_sasl = false;
// Need to call this before server_init_specifics()
irc_set_casemapping (s, irc_tolower, irc_strxfrm);
@@ -6527,6 +6529,20 @@ irc_process_sent_message (const struct irc_message *msg, struct server *s)
// --- Input handling ----------------------------------------------------------
static void
+irc_handle_authenticate (struct server *s, const struct irc_message *msg)
+{
+ if (msg->params.len < 1)
+ return;
+
+ // Empty challenge -> empty response for e.g. SASL EXTERNAL,
+ // abort anything else as it doesn't make much sense to let the user do it
+ if (!strcmp (msg->params.vector[0], "+"))
+ irc_send (s, "AUTHENTICATE +");
+ else
+ irc_send (s, "AUTHENTICATE *");
+}
+
+static void
irc_handle_away (struct server *s, const struct irc_message *msg)
{
if (!msg->prefix)
@@ -6579,10 +6595,9 @@ irc_process_cap_ls (struct server *s)
static void
irc_toggle_cap (struct server *s, const char *cap, bool active)
{
- if (!strcasecmp_ascii (cap, "echo-message"))
- s->cap_echo_message = active;
- if (!strcasecmp_ascii (cap, "away-notify"))
- s->cap_away_notify = active;
+ if (!strcasecmp_ascii (cap, "echo-message")) s->cap_echo_message = active;
+ if (!strcasecmp_ascii (cap, "away-notify")) s->cap_away_notify = active;
+ if (!strcasecmp_ascii (cap, "sasl")) s->cap_sasl = active;
}
static void
@@ -6612,13 +6627,17 @@ irc_handle_cap (struct server *s, const struct irc_message *msg)
}
irc_toggle_cap (s, cap, active);
}
- irc_send (s, "CAP END");
+ if (s->cap_sasl && s->transport == &g_transport_tls)
+ irc_send (s, "AUTHENTICATE EXTERNAL");
+ else if (s->state == IRC_CONNECTED)
+ irc_send (s, "CAP END");
}
else if (!strcasecmp_ascii (subcommand, "NAK"))
{
log_server_error (s, s->buffer,
"#s: #S", "Capabilities not acknowledged", args);
- irc_send (s, "CAP END");
+ if (s->state == IRC_CONNECTED)
+ irc_send (s, "CAP END");
}
else if (!strcasecmp_ascii (subcommand, "DEL"))
{
@@ -7280,22 +7299,23 @@ irc_handle_topic (struct server *s, const struct irc_message *msg)
static struct irc_handler g_irc_handlers[] =
{
// This list needs to stay sorted
- { "AWAY", irc_handle_away },
- { "CAP", irc_handle_cap },
- { "ERROR", irc_handle_error },
- { "INVITE", irc_handle_invite },
- { "JOIN", irc_handle_join },
- { "KICK", irc_handle_kick },
- { "KILL", irc_handle_kill },
- { "MODE", irc_handle_mode },
- { "NICK", irc_handle_nick },
- { "NOTICE", irc_handle_notice },
- { "PART", irc_handle_part },
- { "PING", irc_handle_ping },
- { "PRIVMSG", irc_handle_privmsg },
- { "QUIT", irc_handle_quit },
- { "TAGMSG", irc_handle_tagmsg },
- { "TOPIC", irc_handle_topic },
+ { "AUTHENTICATE", irc_handle_authenticate },
+ { "AWAY", irc_handle_away },
+ { "CAP", irc_handle_cap },
+ { "ERROR", irc_handle_error },
+ { "INVITE", irc_handle_invite },
+ { "JOIN", irc_handle_join },
+ { "KICK", irc_handle_kick },
+ { "KILL", irc_handle_kill },
+ { "MODE", irc_handle_mode },
+ { "NICK", irc_handle_nick },
+ { "NOTICE", irc_handle_notice },
+ { "PART", irc_handle_part },
+ { "PING", irc_handle_ping },
+ { "PRIVMSG", irc_handle_privmsg },
+ { "QUIT", irc_handle_quit },
+ { "TAGMSG", irc_handle_tagmsg },
+ { "TOPIC", irc_handle_topic },
};
static bool
@@ -7976,6 +7996,16 @@ irc_process_numeric (struct server *s,
if (irc_handle_rpl_endofwho (s, msg)) buffer = NULL;
break;
+ case IRC_ERR_NICKLOCKED:
+ case IRC_RPL_SASLSUCCESS:
+ case IRC_ERR_SASLFAIL:
+ case IRC_ERR_SASLTOOLONG:
+ case IRC_ERR_SASLABORTED:
+ case IRC_ERR_SASLALREADY:
+ if (s->state == IRC_CONNECTED)
+ irc_send (s, "CAP END");
+ break;
+
case IRC_RPL_LIST:
case IRC_ERR_UNKNOWNCOMMAND:
diff --git a/kike-replies b/kike-replies
index 942eb38..fc8d6df 100644
--- a/kike-replies
+++ b/kike-replies
@@ -85,3 +85,9 @@
482 IRC_ERR_CHANOPRIVSNEEDED "%s :You're not channel operator"
501 IRC_ERR_UMODEUNKNOWNFLAG ":Unknown MODE flag"
502 IRC_ERR_USERSDONTMATCH ":Cannot change mode for other users"
+902 IRC_ERR_NICKLOCKED ":You must use a nick assigned to you"
+903 IRC_RPL_SASLSUCCESS ":SASL authentication successful"
+904 IRC_ERR_SASLFAIL ":SASL authentication failed"
+905 IRC_ERR_SASLTOOLONG ":SASL message too long"
+906 IRC_ERR_SASLABORTED ":SASL authentication aborted"
+907 IRC_ERR_SASLALREADY ":You have already authenticated using SASL"