diff options
Diffstat (limited to 'degesch.c')
-rw-r--r-- | degesch.c | 74 |
1 files changed, 52 insertions, 22 deletions
@@ -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: |