degesch: add trivial SASL EXTERNAL support
Just set `tls_cert`, and add `sasl` to `capabilities`.
This commit is contained in:
parent
bb451a5050
commit
5a0b2d1c57
3
NEWS
3
NEWS
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
* degesch: added a /squery command for IRCnet
|
* 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
|
* degesch: now supporting IRCv3.2 capability negotiation, including CAP DEL
|
||||||
|
|
||||||
|
|
||||||
|
|
74
degesch.c
74
degesch.c
|
@ -1721,6 +1721,7 @@ struct server
|
||||||
struct strv cap_ls_buf; ///< Buffer for IRCv3.2 CAP LS
|
struct strv cap_ls_buf; ///< Buffer for IRCv3.2 CAP LS
|
||||||
bool cap_echo_message; ///< Whether the server echoes messages
|
bool cap_echo_message; ///< Whether the server echoes messages
|
||||||
bool cap_away_notify; ///< Whether we get AWAY notifications
|
bool cap_away_notify; ///< Whether we get AWAY notifications
|
||||||
|
bool cap_sasl; ///< Whether SASL is available
|
||||||
|
|
||||||
// Server-specific information (from RPL_ISUPPORT):
|
// Server-specific information (from RPL_ISUPPORT):
|
||||||
|
|
||||||
|
@ -4962,6 +4963,7 @@ irc_destroy_state (struct server *s)
|
||||||
strv_reset (&s->cap_ls_buf);
|
strv_reset (&s->cap_ls_buf);
|
||||||
s->cap_away_notify = false;
|
s->cap_away_notify = false;
|
||||||
s->cap_echo_message = false;
|
s->cap_echo_message = false;
|
||||||
|
s->cap_sasl = false;
|
||||||
|
|
||||||
// Need to call this before server_init_specifics()
|
// Need to call this before server_init_specifics()
|
||||||
irc_set_casemapping (s, irc_tolower, irc_strxfrm);
|
irc_set_casemapping (s, irc_tolower, irc_strxfrm);
|
||||||
|
@ -6526,6 +6528,20 @@ irc_process_sent_message (const struct irc_message *msg, struct server *s)
|
||||||
|
|
||||||
// --- Input handling ----------------------------------------------------------
|
// --- 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
|
static void
|
||||||
irc_handle_away (struct server *s, const struct irc_message *msg)
|
irc_handle_away (struct server *s, const struct irc_message *msg)
|
||||||
{
|
{
|
||||||
|
@ -6579,10 +6595,9 @@ irc_process_cap_ls (struct server *s)
|
||||||
static void
|
static void
|
||||||
irc_toggle_cap (struct server *s, const char *cap, bool active)
|
irc_toggle_cap (struct server *s, const char *cap, bool active)
|
||||||
{
|
{
|
||||||
if (!strcasecmp_ascii (cap, "echo-message"))
|
if (!strcasecmp_ascii (cap, "echo-message")) s->cap_echo_message = active;
|
||||||
s->cap_echo_message = active;
|
if (!strcasecmp_ascii (cap, "away-notify")) s->cap_away_notify = active;
|
||||||
if (!strcasecmp_ascii (cap, "away-notify"))
|
if (!strcasecmp_ascii (cap, "sasl")) s->cap_sasl = active;
|
||||||
s->cap_away_notify = active;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -6612,13 +6627,17 @@ irc_handle_cap (struct server *s, const struct irc_message *msg)
|
||||||
}
|
}
|
||||||
irc_toggle_cap (s, cap, active);
|
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"))
|
else if (!strcasecmp_ascii (subcommand, "NAK"))
|
||||||
{
|
{
|
||||||
log_server_error (s, s->buffer,
|
log_server_error (s, s->buffer,
|
||||||
"#s: #S", "Capabilities not acknowledged", args);
|
"#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"))
|
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[] =
|
static struct irc_handler g_irc_handlers[] =
|
||||||
{
|
{
|
||||||
// This list needs to stay sorted
|
// This list needs to stay sorted
|
||||||
{ "AWAY", irc_handle_away },
|
{ "AUTHENTICATE", irc_handle_authenticate },
|
||||||
{ "CAP", irc_handle_cap },
|
{ "AWAY", irc_handle_away },
|
||||||
{ "ERROR", irc_handle_error },
|
{ "CAP", irc_handle_cap },
|
||||||
{ "INVITE", irc_handle_invite },
|
{ "ERROR", irc_handle_error },
|
||||||
{ "JOIN", irc_handle_join },
|
{ "INVITE", irc_handle_invite },
|
||||||
{ "KICK", irc_handle_kick },
|
{ "JOIN", irc_handle_join },
|
||||||
{ "KILL", irc_handle_kill },
|
{ "KICK", irc_handle_kick },
|
||||||
{ "MODE", irc_handle_mode },
|
{ "KILL", irc_handle_kill },
|
||||||
{ "NICK", irc_handle_nick },
|
{ "MODE", irc_handle_mode },
|
||||||
{ "NOTICE", irc_handle_notice },
|
{ "NICK", irc_handle_nick },
|
||||||
{ "PART", irc_handle_part },
|
{ "NOTICE", irc_handle_notice },
|
||||||
{ "PING", irc_handle_ping },
|
{ "PART", irc_handle_part },
|
||||||
{ "PRIVMSG", irc_handle_privmsg },
|
{ "PING", irc_handle_ping },
|
||||||
{ "QUIT", irc_handle_quit },
|
{ "PRIVMSG", irc_handle_privmsg },
|
||||||
{ "TAGMSG", irc_handle_tagmsg },
|
{ "QUIT", irc_handle_quit },
|
||||||
{ "TOPIC", irc_handle_topic },
|
{ "TAGMSG", irc_handle_tagmsg },
|
||||||
|
{ "TOPIC", irc_handle_topic },
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -7976,6 +7996,16 @@ irc_process_numeric (struct server *s,
|
||||||
if (irc_handle_rpl_endofwho (s, msg)) buffer = NULL;
|
if (irc_handle_rpl_endofwho (s, msg)) buffer = NULL;
|
||||||
break;
|
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_RPL_LIST:
|
||||||
|
|
||||||
case IRC_ERR_UNKNOWNCOMMAND:
|
case IRC_ERR_UNKNOWNCOMMAND:
|
||||||
|
|
|
@ -85,3 +85,9 @@
|
||||||
482 IRC_ERR_CHANOPRIVSNEEDED "%s :You're not channel operator"
|
482 IRC_ERR_CHANOPRIVSNEEDED "%s :You're not channel operator"
|
||||||
501 IRC_ERR_UMODEUNKNOWNFLAG ":Unknown MODE flag"
|
501 IRC_ERR_UMODEUNKNOWNFLAG ":Unknown MODE flag"
|
||||||
502 IRC_ERR_USERSDONTMATCH ":Cannot change mode for other users"
|
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"
|
||||||
|
|
Loading…
Reference in New Issue