]> jfr.im git - solanum.git/commitdiff
Change the way authd configures opm
authorElizabeth Myers <redacted>
Tue, 12 Apr 2016 14:33:51 +0000 (09:33 -0500)
committerElizabeth Myers <redacted>
Tue, 12 Apr 2016 14:36:09 +0000 (09:36 -0500)
It's a bit of a hack, but better than before. Rather than rehashing
(which could get us into an endless loop), we now segregate the
configuration phase (creating entries ircd-side in case we restart authd
later) and sending phases (when configure_authd() is called). Since we
have to call configure_authd() no matter what (to send timeouts etc.)
and we have to send this data to configure authd anyway, and sending
duplicate data is bad, this is the only way I can think of for now.

authd/providers/opm.c
include/authproc.h
ircd/authproc.c
ircd/newconf.c
ircd/s_user.c
modules/m_stats.c

index 746604b5c0b35ed27e167fbe5d4adde044a2f49b..3fbc53a65a06cc3bfa36eeb723e4c23ca586a511 100644 (file)
@@ -98,11 +98,15 @@ static bool create_listener(const char *ip, uint16_t port);
 static int opm_timeout = OPM_TIMEOUT_DEFAULT;
 static bool opm_enable = false;
 
-#define LISTEN_IPV4 0
-#define LISTEN_IPV6 1
+enum
+{
+       LISTEN_IPV4,
+       LISTEN_IPV6,
+       LISTEN_LAST,
+};
 
 /* IPv4 and IPv6 */
-static struct opm_listener listeners[2];
+static struct opm_listener listeners[LISTEN_LAST];
 
 static inline protocol_t
 get_protocol_from_string(const char *str)
@@ -891,12 +895,27 @@ delete_opm_scanner_all(const char *key __unused, int parc __unused, const char *
        opm_enable = false;
 }
 
+static void
+delete_opm_listener_all(const char *key __unused, int parc __unused, const char **parv __unused)
+{
+       if(listeners[LISTEN_IPV4].F != NULL)
+               rb_close(listeners[LISTEN_IPV4].F);
+
+#ifdef RB_IPV6
+       if(listeners[LISTEN_IPV6].F != NULL)
+               rb_close(listeners[LISTEN_IPV6].F);
+#endif
+
+       memset(&listeners, 0, sizeof(listeners));
+}
+
 
 struct auth_opts_handler opm_options[] =
 {
        { "opm_timeout", 1, add_conf_opm_timeout },
        { "opm_enabled", 1, set_opm_enabled },
        { "opm_listener", 2, set_opm_listener },
+       { "opm_listener_del_all", 0, delete_opm_listener_all },
        { "opm_scanner", 2, create_opm_scanner },
        { "opm_scanner_del", 2, delete_opm_scanner },
        { "opm_scanner_del_all", 0, delete_opm_scanner_all },
index 884983d14a81763e031a325b09f9393f29eb6d33..00de574aab12550bac72f6eec5eab6ce3182aeeb 100644 (file)
 #include "rb_dictionary.h"
 #include "client.h"
 
-struct blacklist_stats
+struct BlacklistStats
 {
        uint8_t iptype;
        unsigned int hits;
 };
 
+struct OPMScanner
+{
+       char type[16];  /* Type of proxy */
+       uint16_t port;  /* Port */
+
+       rb_dlink_node node;
+};
+
+struct OPMListener
+{
+       char ipaddr[HOSTIPLEN]; /* Listener address */
+       uint16_t port;          /* Listener port */
+};
+
+enum
+{
+       LISTEN_IPV4,
+       LISTEN_IPV6,
+       LISTEN_LAST,
+};
+
 extern rb_helper *authd_helper;
 
 extern rb_dictionary *bl_stats;
+extern rb_dlink_list opm_list;
+extern struct OPMListener opm_listeners[LISTEN_LAST];
 
 void init_authd(void);
 void configure_authd(void);
@@ -58,10 +81,13 @@ void del_blacklist_all(void);
 bool set_authd_timeout(const char *key, int timeout);
 void ident_check_enable(bool enabled);
 
+void conf_create_opm_listener(const char *ip, uint16_t port);
 void create_opm_listener(const char *ip, uint16_t port);
-void opm_check_enable(bool enabled);
+void conf_create_opm_proxy_scanner(const char *type, uint16_t port);
 void create_opm_proxy_scanner(const char *type, uint16_t port);
 void delete_opm_proxy_scanner(const char *type, uint16_t port);
 void delete_opm_proxy_scanner_all(void);
+void delete_opm_listener_all(void);
+void opm_check_enable(bool enabled);
 
 #endif
index 2a0da431e9694a8d51ddd39175450763c707a0fa..a07db671eb32aa4b1e064108f136baef7d728512 100644 (file)
@@ -69,6 +69,9 @@ static struct ev_entry *timeout_ev;
 
 rb_dictionary *bl_stats;
 
+rb_dlink_list opm_list;
+struct OPMListener opm_listeners[LISTEN_LAST];
+
 static struct authd_cb authd_cmd_tab[256] =
 {
        ['A'] = { cmd_accept_client,    4 },
@@ -316,11 +319,41 @@ init_authd(void)
 void
 configure_authd(void)
 {
-       /* These will do for now */
+       /* Timeouts */
        set_authd_timeout("ident_timeout", GlobalSetOptions.ident_timeout);
        set_authd_timeout("rdns_timeout", ConfigFileEntry.connect_timeout);
        set_authd_timeout("rbl_timeout", ConfigFileEntry.connect_timeout);
+
        ident_check_enable(!ConfigFileEntry.disable_auth);
+
+       /* Configure OPM */
+       if(rb_dlink_list_length(&opm_list) > 0 &&
+               (opm_listeners[LISTEN_IPV4].ipaddr[0] != '\0' ||
+               opm_listeners[LISTEN_IPV6].ipaddr[0] != '\0'))
+       {
+               rb_dlink_node *ptr;
+
+               if(opm_listeners[LISTEN_IPV4].ipaddr[0] != '\0')
+                       rb_helper_write(authd_helper, "O opm_listener %s %hu",
+                               opm_listeners[LISTEN_IPV4].ipaddr, opm_listeners[LISTEN_IPV4].port);
+
+#ifdef RB_IPV6
+               if(opm_listeners[LISTEN_IPV6].ipaddr[0] != '\0')
+                       rb_helper_write(authd_helper, "O opm_listener %s %hu",
+                               opm_listeners[LISTEN_IPV6].ipaddr, opm_listeners[LISTEN_IPV6].port);
+#endif
+
+               RB_DLINK_FOREACH(ptr, opm_list.head)
+               {
+                       struct OPMScanner *scanner = ptr->data;
+                       rb_helper_write(authd_helper, "O opm_scanner %s %hu",
+                               scanner->type, scanner->port);
+               }
+
+               opm_check_enable(true);
+       }
+       else
+               opm_check_enable(false);
 }
 
 static void
@@ -346,7 +379,6 @@ restart_authd_cb(rb_helper * helper)
 
        start_authd();
        configure_authd();
-       rehash(false);  /* FIXME - needed to reload authd configuration */
 }
 
 void
@@ -507,7 +539,7 @@ void
 add_blacklist(const char *host, const char *reason, uint8_t iptype, rb_dlink_list *filters)
 {
        rb_dlink_node *ptr;
-       struct blacklist_stats *stats = rb_malloc(sizeof(struct blacklist_stats));
+       struct BlacklistStats *stats = rb_malloc(sizeof(struct BlacklistStats));
        char filterbuf[BUFSIZE] = "*";
        size_t s = 0;
 
@@ -541,7 +573,12 @@ add_blacklist(const char *host, const char *reason, uint8_t iptype, rb_dlink_lis
 void
 del_blacklist(const char *host)
 {
-       rb_free(rb_dictionary_delete(bl_stats, host));
+       struct BlacklistStats *stats = rb_dictionary_retrieve(bl_stats, host);
+       if(stats != NULL)
+       {
+               rb_dictionary_delete(bl_stats, host);
+               rb_free(stats);
+       }
 
        rb_helper_write(authd_helper, "O rbl_del %s", host);
 }
@@ -550,7 +587,7 @@ del_blacklist(const char *host)
 void
 del_blacklist_all(void)
 {
-       struct blacklist_stats *stats;
+       struct BlacklistStats *stats;
        rb_dictionary_iter iter;
 
        RB_DICTIONARY_FOREACH(stats, &iter, bl_stats)
@@ -580,11 +617,35 @@ ident_check_enable(bool enabled)
        rb_helper_write(authd_helper, "O ident_enabled %d", enabled ? 1 : 0);
 }
 
-/* Create an OPM listener */
+/* Create an OPM listener
+ * XXX - This is a big nasty hack, but it avoids resending duplicate data when
+ * configure_authd() is called.
+ */
+void
+conf_create_opm_listener(const char *ip, uint16_t port)
+{
+       char ipbuf[HOSTIPLEN];
+       struct OPMListener *listener;
+
+       rb_strlcpy(ipbuf, ip, sizeof(ipbuf));
+       if(ipbuf[0] == ':')
+       {
+               memmove(ipbuf + 1, ipbuf, sizeof(ipbuf) - 1);
+               ipbuf[0] = '0';
+       }
+
+       /* I am much too lazy to use rb_inet_pton and GET_SS_FAMILY for now --Elizafox */
+       listener = &opm_listeners[(strchr(ipbuf, ':') != NULL ? LISTEN_IPV6 : LISTEN_IPV4)];
+       rb_strlcpy(listener->ipaddr, ipbuf, sizeof(listener->ipaddr));
+       listener->port = port;
+}
+
 void
 create_opm_listener(const char *ip, uint16_t port)
 {
        char ipbuf[HOSTIPLEN];
+
+       /* XXX duplicated in conf_create_opm_listener */
        rb_strlcpy(ipbuf, ip, sizeof(ipbuf));
        if(ipbuf[0] == ':')
        {
@@ -592,7 +653,15 @@ create_opm_listener(const char *ip, uint16_t port)
                ipbuf[0] = '0';
        }
 
-       rb_helper_write(authd_helper, "O opm_listener %s %hu", ipbuf, port);
+       conf_create_opm_listener(ip, port);
+       rb_helper_write(authd_helper, "O opm_listener %s %hu", ip, port);
+}
+
+void
+delete_opm_listener_all(void)
+{
+       memset(&opm_listeners, 0, sizeof(opm_listeners));
+       rb_helper_write(authd_helper, "O opm_listener_del_all");
 }
 
 /* Disable all OPM scans */
@@ -602,21 +671,60 @@ opm_check_enable(bool enabled)
        rb_helper_write(authd_helper, "O opm_enabled %d", enabled ? 1 : 0);
 }
 
-/* Create an OPM proxy scanner */
+/* Create an OPM proxy scanner
+ * XXX - This is a big nasty hack, but it avoids resending duplicate data when
+ * configure_authd() is called.
+ */
+void
+conf_create_opm_proxy_scanner(const char *type, uint16_t port)
+{
+       struct OPMScanner *scanner = rb_malloc(sizeof(struct OPMScanner));
+
+       rb_strlcpy(scanner->type, type, sizeof(scanner->type));
+       scanner->port = port;
+       rb_dlinkAdd(scanner, &scanner->node, &opm_list);
+}
+
 void
 create_opm_proxy_scanner(const char *type, uint16_t port)
 {
+       conf_create_opm_proxy_scanner(type, port);
        rb_helper_write(authd_helper, "O opm_scanner %s %hu", type, port);
 }
 
 void
 delete_opm_proxy_scanner(const char *type, uint16_t port)
 {
+       rb_dlink_node *ptr, *nptr;
+
+       RB_DLINK_FOREACH_SAFE(ptr, nptr, opm_list.head)
+       {
+               struct OPMScanner *scanner = ptr->data;
+
+               if(rb_strncasecmp(scanner->type, type, sizeof(scanner->type)) == 0 &&
+                       scanner->port == port)
+               {
+                       rb_dlinkDelete(ptr, &opm_list);
+                       rb_free(scanner);
+                       break;
+               }
+       }
+
        rb_helper_write(authd_helper, "O opm_scanner_del %s %hu", type, port);
 }
 
 void
 delete_opm_proxy_scanner_all(void)
 {
+       rb_dlink_node *ptr, *nptr;
+
+       RB_DLINK_FOREACH_SAFE(ptr, nptr, opm_list.head)
+       {
+               struct OPMScanner *scanner = ptr->data;
+
+               rb_dlinkDelete(ptr, &opm_list);
+               rb_free(scanner);
+       }
+
        rb_helper_write(authd_helper, "O opm_scanner_del_all");
 }
index 79c76baccca301a6ac2ad27b716df240d2453570..01af2eb70f02afc961616574a3f9689efcede912 100644 (file)
@@ -2043,6 +2043,7 @@ conf_begin_opm(struct TopConf *tc)
        yy_opm_address_ipv4 = yy_opm_address_ipv6 = NULL;
        yy_opm_port_ipv4 = yy_opm_port_ipv6 = yy_opm_timeout = 0;
        delete_opm_proxy_scanner_all();
+       delete_opm_listener_all();
        return 0;
 }
 
@@ -2062,28 +2063,28 @@ conf_end_opm(struct TopConf *tc)
        if(yy_opm_port_ipv4 > 0)
        {
                if(yy_opm_address_ipv4 != NULL)
-                       create_opm_listener(yy_opm_address_ipv4, yy_opm_port_ipv4);
+                       conf_create_opm_listener(yy_opm_address_ipv4, yy_opm_port_ipv4);
                else
                {
                        char ip[HOSTIPLEN];
                        if(!rb_inet_ntop_sock((struct sockaddr *)&ServerInfo.ip, ip, sizeof(ip)))
                                conf_report_error("No opm::listen_ipv4 nor serverinfo::vhost directive; cannot listen on IPv4");
                        else
-                               create_opm_listener(ip, yy_opm_port_ipv4);
+                               conf_create_opm_listener(ip, yy_opm_port_ipv4);
                }
        }
 
        if(yy_opm_port_ipv6 > 0)
        {
                if(yy_opm_address_ipv6 != NULL)
-                       create_opm_listener(yy_opm_address_ipv6, yy_opm_port_ipv6);
+                       conf_create_opm_listener(yy_opm_address_ipv6, yy_opm_port_ipv6);
                else
                {
                        char ip[HOSTIPLEN];
                        if(!rb_inet_ntop_sock((struct sockaddr *)&ServerInfo.ip6, ip, sizeof(ip)))
                                conf_report_error("No opm::listen_ipv6 nor serverinfo::vhost directive; cannot listen on IPv6");
                        else
-                               create_opm_listener(ip, yy_opm_port_ipv6);
+                               conf_create_opm_listener(ip, yy_opm_port_ipv6);
                }
        }
 
@@ -2272,7 +2273,7 @@ conf_set_opm_scan_ports_all(void *data, const char *node, const char *type)
                        conf_report_error("%s argument is not an integer -- ignoring.", node);
                        continue;
                }
-               
+
                if(args->v.number > 65535 || args->v.number <= 0)
                {
                        conf_report_error("%s argument is not an integer between 1 and 65535 -- ignoring.", node);
index bed466546cbcf41bd2b7bdcd322fe5f7a0e4febd..18104c6a649a07fc36912a2bf3c5286118645d79 100644 (file)
@@ -215,7 +215,7 @@ authd_check(struct Client *client_p, struct Client *source_p)
        {
        case 'B':       /* Blacklists */
                {
-                       struct blacklist_stats *stats;
+                       struct BlacklistStats *stats;
                        char *blacklist = source_p->preClient->auth.data;
 
                        if((stats = rb_dictionary_retrieve(bl_stats, blacklist)) != NULL)
index 7d9ac86f4a5cfdc9157a7c0d8bfee32bb5a0ad91..4e21ab4c2b50a0c6207f2d14178cf294e053c250 100644 (file)
@@ -753,7 +753,7 @@ static void
 stats_dnsbl(struct Client *source_p)
 {
        rb_dictionary_iter iter;
-       struct blacklist_stats *stats;
+       struct BlacklistStats *stats;
 
        RB_DICTIONARY_FOREACH(stats, &iter, bl_stats)
        {