]> jfr.im git - irc/freenode/ircd-seven.git/commitdiff
m_sasl: add configuration option for the nick of the SASL agent
authorMax Teufel <redacted>
Sat, 14 Feb 2015 09:41:10 +0000 (10:41 +0100)
committerMax Teufel <redacted>
Sat, 14 Feb 2015 19:31:25 +0000 (20:31 +0100)
This allows multiple improvements to m_sasl. With this change, the SASL
authentication gets aborted immediately when services are offline.
Additionally, we send the SASL ENCAP messages directly to the specified
SASL agent.

doc/ircd.conf.example
doc/reference.conf
include/s_conf.h
modules/m_sasl.c
src/newconf.c
src/s_conf.c

index c5c5fbe3f73f3821e69c055b72c05be40498a0ef..28a926ab78907f1c43dc71fd09871610db5725f3 100755 (executable)
@@ -461,6 +461,14 @@ general {
        default_operstring = "is an IRC Operator";
        default_adminstring = "is a Server Administrator";
        servicestring = "is a Network Service";
+
+       /*
+        * Nick of the network's SASL agent. Used to check whether services are here,
+        * SASL credentials are only sent to its server. Needs to be a service.
+        *
+        * Defaults to SaslServ if unspecified.
+        */
+       sasl_service = "SaslServ";
        disable_fake_channels = no;
        tkline_expire_notices = no;
        default_floodcount = 10;
index c4a9c06cfac3f1ea3c4fa96fb142c1af58be53cb..b49104ea38d7d181d6651544448e38d47171207c 100755 (executable)
@@ -955,6 +955,14 @@ general {
         */
        servicestring = "is a Network Service";
 
+       /*
+        * Nick of the network's SASL agent. Used to check whether services are here,
+        * SASL credentials are only sent to its server. Needs to be a service.
+        *
+        * Defaults to SaslServ if unspecified.
+        */
+       sasl_service = "SaslServ";
+
        /* disable fake channels: disable local users joining fake versions
         * of channels, eg #foo^B^B.  Disables bold, mirc colour, reverse,
         * underline and hard space.  (ASCII 2, 3, 22, 31, 160 respectively).
index 58e57b64cada7cb3fe86190340e37438732f6f1e..ceeae01a109bf74beac537ecf0b9c16a85c2e8f2 100644 (file)
@@ -151,6 +151,8 @@ struct config_file_entry
        char *identifyservice;
        char *identifycommand;
 
+       char *sasl_service;
+
        char *fname_userlog;
        char *fname_fuserlog;
        char *fname_operlog;
index 840175237c5510bb999e8d5fdc714ec9244785e6..9b139951565e4b72d6bd6377f8f3c76c767a6377 100644 (file)
@@ -40,6 +40,8 @@
 #include "s_serv.h"
 #include "s_stats.h"
 #include "string.h"
+#include "s_newconf.h"
+#include "s_conf.h"
 
 static int mr_authenticate(struct Client *, struct Client *, int, const char **);
 static int me_sasl(struct Client *, struct Client *, int, const char **);
@@ -72,6 +74,7 @@ mr_authenticate(struct Client *client_p, struct Client *source_p,
        int parc, const char *parv[])
 {
        struct Client *agent_p = NULL;
+       struct Client *saslserv_p = NULL;
 
        /* They really should use CAP for their own sake. */
        if(!IsCapable(source_p, CLICAP_SASL))
@@ -83,6 +86,13 @@ mr_authenticate(struct Client *client_p, struct Client *source_p,
                return 0;
        }
 
+       saslserv_p = find_named_client(ConfigFileEntry.sasl_service);
+       if (saslserv_p == NULL || !IsService(saslserv_p))
+       {
+               sendto_one(source_p, form_str(ERR_SASLABORTED), me.name, EmptyString(source_p->name) ? "*" : source_p->name);
+               return 0;
+       }
+
        if(source_p->preClient->sasl_complete)
        {
                sendto_one(source_p, form_str(ERR_SASLALREADY), me.name, EmptyString(source_p->name) ? "*" : source_p->name);
@@ -108,16 +118,20 @@ mr_authenticate(struct Client *client_p, struct Client *source_p,
        if(agent_p == NULL)
        {
                if (!strcmp(parv[1], "EXTERNAL") && source_p->certfp != NULL)
-                       sendto_server(NULL, NULL, CAP_TS6|CAP_ENCAP, NOCAPS, ":%s ENCAP * SASL %s * S %s %s", me.id,
-                                       source_p->id, parv[1],
-                                       source_p->certfp);
+                       sendto_one(saslserv_p, ":%s ENCAP %s SASL %s %s S %s %s", me.id, saslserv_p->servptr->name,
+                                       source_p->id, saslserv_p->id,
+                                       parv[1], source_p->certfp);
                else
-                       sendto_server(NULL, NULL, CAP_TS6|CAP_ENCAP, NOCAPS, ":%s ENCAP * SASL %s * S %s", me.id,
-                                       source_p->id, parv[1]);
+                       sendto_one(saslserv_p, ":%s ENCAP %s SASL %s %s S %s", me.id, saslserv_p->servptr->name,
+                                       source_p->id, saslserv_p->id,
+                                       parv[1]);
+
+               rb_strlcpy(source_p->preClient->sasl_agent, saslserv_p->id, IDLEN);
        }
        else
                sendto_one(agent_p, ":%s ENCAP %s SASL %s %s C %s", me.id, agent_p->servptr->name,
-                               source_p->id, agent_p->id, parv[1]);
+                               source_p->id, agent_p->id,
+                               parv[1]);
        source_p->preClient->sasl_out++;
 
        return 0;
index 7af7ad9de1874c48b8683a73e08c340f14ad6f5c..6a7a256d98bc3ac4a0905e237f8967a498c9132b 100644 (file)
@@ -2315,6 +2315,7 @@ static struct ConfEntry conf_general_table[] =
        { "kline_reason",       CF_QSTRING, NULL, REALLEN, &ConfigFileEntry.kline_reason },
        { "identify_service",   CF_QSTRING, NULL, REALLEN, &ConfigFileEntry.identifyservice },
        { "identify_command",   CF_QSTRING, NULL, REALLEN, &ConfigFileEntry.identifycommand },
+       { "sasl_service",       CF_QSTRING, NULL, REALLEN, &ConfigFileEntry.sasl_service },
 
        { "anti_spam_exit_message_time", CF_TIME,  NULL, 0, &ConfigFileEntry.anti_spam_exit_message_time },
        { "disable_fake_channels",       CF_YESNO, NULL, 0, &ConfigFileEntry.disable_fake_channels },
index 1a70de25300cb91eb94256a087c098a1ff51c0d7..a329c7b786d74f687012e457f10f9c662cdaa253 100644 (file)
@@ -692,6 +692,7 @@ set_default_conf(void)
        ConfigFileEntry.default_operstring = NULL;
        ConfigFileEntry.default_adminstring = NULL;
        ConfigFileEntry.servicestring = NULL;
+       ConfigFileEntry.sasl_service = NULL;
 
        ConfigFileEntry.default_umodes = UMODE_INVISIBLE;
        ConfigFileEntry.failed_oper_notice = YES;
@@ -886,6 +887,9 @@ validate_conf(void)
        if (ConfigFileEntry.servicestring == NULL)
                ConfigFileEntry.servicestring = rb_strdup("is a Network Service");
 
+       if (ConfigFileEntry.sasl_service == NULL)
+               ConfigFileEntry.sasl_service = rb_strdup("SaslServ");
+
        /* RFC 1459 says 1 message per 2 seconds on average and bursts of
         * 5 messages are acceptable, so allow at least that.
         */
@@ -1489,6 +1493,8 @@ clear_out_old_conf(void)
        ConfigFileEntry.servicestring = NULL;
        rb_free(ConfigFileEntry.kline_reason);
        ConfigFileEntry.kline_reason = NULL;
+       rb_free(ConfigFileEntry.sasl_service);
+       ConfigFileEntry.sasl_service = NULL;
 
        /* clean out log */
        rb_free(ConfigFileEntry.fname_userlog);