]> jfr.im git - solanum.git/blobdiff - ircd/authd.c
wsockd: various updates
[solanum.git] / ircd / authd.c
index 14218578c5f1d3a74d0b85b9016ef0f6bcec4e4b..1a186860f8d24dabb4b767973656454255cb7789 100644 (file)
 #include "msg.h"
 #include "dns.h"
 
+typedef void (*authd_cb_t)(int, char **);
+
+struct authd_cb
+{
+       authd_cb_t fn;
+       int min_parc;
+};
+
 static int start_authd(void);
 static void parse_authd_reply(rb_helper * helper);
 static void restart_authd_cb(rb_helper * helper);
 static EVH timeout_dead_authd_clients;
 
+static void cmd_accept_client(int parc, char **parv);
+static void cmd_reject_client(int parc, char **parv);
+static void cmd_dns_result(int parc, char **parv);
+static void cmd_notice_client(int parc, char **parv);
+static void cmd_oper_warn(int parc, char **parv);
+static void cmd_stats_results(int parc, char **parv);
+
 rb_helper *authd_helper;
 static char *authd_path;
 
@@ -54,6 +69,18 @@ static struct ev_entry *timeout_ev;
 
 rb_dictionary *bl_stats;
 
+static struct authd_cb authd_cmd_tab[256] =
+{
+       ['A'] = { cmd_accept_client,    4 },
+       ['E'] = { cmd_dns_result,       5 },
+       ['N'] = { cmd_notice_client,    3 },
+       ['R'] = { cmd_reject_client,    7 },
+       ['W'] = { cmd_oper_warn,        3 },
+       ['X'] = { cmd_stats_results,    3 },
+       ['Y'] = { cmd_stats_results,    3 },
+       ['Z'] = { cmd_stats_results,    3 },
+};
+
 static int
 start_authd(void)
 {
@@ -134,12 +161,8 @@ cid_to_client(uint32_t cid, bool delete)
        else
                client_p = rb_dictionary_retrieve(cid_clients, RB_UINT_TO_POINTER(cid));
 
-       if(client_p == NULL)
-       {
-               iwarn("authd sent us back a bad client ID: %ux", cid);
-               restart_authd();
-               return NULL;
-       }
+       /* If the client's not found, that's okay, it may have already gone away.
+        * --Elizafox */
 
        return client_p;
 }
@@ -156,134 +179,126 @@ str_cid_to_client(const char *str, bool delete)
 }
 
 static void
-parse_authd_reply(rb_helper * helper)
+cmd_accept_client(int parc, char **parv)
 {
-       ssize_t len;
-       int parc;
-       char authdBuf[READBUF_SIZE];
-       char *parv[MAXPARA + 1];
        struct Client *client_p;
 
-       while((len = rb_helper_read(helper, authdBuf, sizeof(authdBuf))) > 0)
-       {
-               parc = rb_string_to_array(authdBuf, parv, MAXPARA+1);
+       /* cid to uid (retrieve and delete) */
+       if((client_p = str_cid_to_client(parv[1], true)) == NULL)
+               return;
 
-               switch (*parv[0])
-               {
-               case 'A':       /* Accepted a client */
-                       if(parc != 4)
-                       {
-                               iwarn("authd sent a result with wrong number of arguments: got %d", parc);
-                               restart_authd();
-                               return;
-                       }
+       authd_accept_client(client_p, parv[2], parv[3]);
+}
 
-                       /* cid to uid (retrieve and delete) */
-                       if((client_p = str_cid_to_client(parv[1], true)) == NULL)
-                               return;
+static void
+cmd_dns_result(int parc, char **parv)
+{
+       dns_results_callback(parv[1], parv[2], parv[3], parv[4]);
+}
 
-                       authd_accept_client(client_p, parv[2], parv[3]);
-                       break;
-               case 'R':       /* Reject client */
-                       if(parc != 7)
-                       {
-                               iwarn("authd sent us a result with wrong number of arguments: got %d", parc);
-                               restart_authd();
-                               return;
-                       }
+static void
+cmd_notice_client(int parc, char **parv)
+{
+       struct Client *client_p;
 
-                       /* cid to uid (retrieve and delete) */
-                       if((client_p = str_cid_to_client(parv[1], true)) == NULL)
-                               return;
+       if((client_p = str_cid_to_client(parv[1], false)) == NULL)
+               return;
 
-                       authd_reject_client(client_p, parv[3], parv[4], toupper(*parv[2]), parv[5], parv[6]);
-                       break;
-               case 'N':       /* Notice to client */
-                       if(parc != 3)
-                       {
-                               iwarn("authd sent us a result with wrong number of arguments: got %d", parc);
-                               restart_authd();
-                               return;
-                       }
+       sendto_one_notice(client_p, ":%s", parv[2]);
+}
 
-                       if((client_p = str_cid_to_client(parv[1], false)) == NULL)
-                               return;
+static void
+cmd_reject_client(int parc, char **parv)
+{
+       struct Client *client_p;
 
-                       sendto_one_notice(client_p, ":%s", parv[2]);
-                       break;
-               case 'E':       /* DNS Result */
-                       if(parc != 5)
-                       {
-                               iwarn("authd sent a result with wrong number of arguments: got %d", parc);
-                               restart_authd();
-                               return;
-                       }
+       /* cid to uid (retrieve and delete) */
+       if((client_p = str_cid_to_client(parv[1], true)) == NULL)
+               return;
 
-                       dns_results_callback(parv[1], parv[2], parv[3], parv[4]);
-                       break;
-               case 'W':       /* Oper warning */
-                       if(parc != 3)
-                       {
-                               iwarn("authd sent a result with wrong number of arguments: got %d", parc);
-                               restart_authd();
-                               return;
-                       }
+       authd_reject_client(client_p, parv[3], parv[4], toupper(*parv[2]), parv[5], parv[6]);
+}
 
-                       switch(*parv[2])
-                       {
-                       case 'D':       /* Debug */
-                               sendto_realops_snomask(SNO_DEBUG, L_ALL, "authd debug: %s", parv[3]);
-                               idebug("authd: %s", parv[3]);
-                               break;
-                       case 'I':       /* Info */
-                               sendto_realops_snomask(SNO_GENERAL, L_ALL, "authd info: %s", parv[3]);
-                               inotice("authd: %s", parv[3]);
-                               break;
-                       case 'W':       /* Warning */
-                               sendto_realops_snomask(SNO_GENERAL, L_ALL, "authd WARNING: %s", parv[3]);
-                               iwarn("authd: %s", parv[3]);
-                               break;
-                       case 'C':       /* Critical (error) */
-                               sendto_realops_snomask(SNO_GENERAL, L_ALL, "authd CRITICAL: %s", parv[3]);
-                               ierror("authd: %s", parv[3]);
-                               break;
-                       default:        /* idk */
-                               sendto_realops_snomask(SNO_GENERAL, L_ALL, "authd sent us an unknown oper notice type (%s): %s", parv[2], parv[3]);
-                               ilog(L_MAIN, "authd unknown oper notice type (%s): %s", parv[2], parv[3]);
-                               break;
-                       }
+static void
+cmd_oper_warn(int parc, char **parv)
+{
+       switch(*parv[2])
+       {
+       case 'D':       /* Debug */
+               sendto_realops_snomask(SNO_DEBUG, L_ALL, "authd debug: %s", parv[3]);
+               idebug("authd: %s", parv[3]);
+               break;
+       case 'I':       /* Info */
+               sendto_realops_snomask(SNO_GENERAL, L_ALL, "authd info: %s", parv[3]);
+               inotice("authd: %s", parv[3]);
+               break;
+       case 'W':       /* Warning */
+               sendto_realops_snomask(SNO_GENERAL, L_ALL, "authd WARNING: %s", parv[3]);
+               iwarn("authd: %s", parv[3]);
+               break;
+       case 'C':       /* Critical (error) */
+               sendto_realops_snomask(SNO_GENERAL, L_ALL, "authd CRITICAL: %s", parv[3]);
+               ierror("authd: %s", parv[3]);
+               break;
+       default:        /* idk */
+               sendto_realops_snomask(SNO_GENERAL, L_ALL, "authd sent us an unknown oper notice type (%s): %s", parv[2], parv[3]);
+               ilog(L_MAIN, "authd unknown oper notice type (%s): %s", parv[2], parv[3]);
+               break;
+       }
+}
 
-                       /* NOTREACHED */
-                       break;
-               case 'X':       /* Stats error */
-               case 'Y':       /* Stats reply */
-               case 'Z':       /* End of stats reply */
-                       if(parc < 3)
+static void
+cmd_stats_results(int parc, char **parv)
+{
+       /* Select by type */
+       switch(*parv[2])
+       {
+       case 'D':
+               /* parv[0] conveys status */
+               if(parc < 4)
+               {
+                       iwarn("authd sent a result with wrong number of arguments: got %d", parc);
+                       restart_authd();
+                       return;
+               }
+               dns_stats_results_callback(parv[1], parv[0], parc - 3, (const char **)&parv[3]);
+               break;
+       default:
+               break;
+       }
+}
+
+static void
+parse_authd_reply(rb_helper * helper)
+{
+       ssize_t len;
+       int parc;
+       char buf[READBUF_SIZE];
+       char *parv[MAXPARA + 1];
+
+       while((len = rb_helper_read(helper, buf, sizeof(buf))) > 0)
+       {
+               struct authd_cb *cmd;
+
+               parc = rb_string_to_array(buf, parv, MAXPARA+1);
+               cmd = &authd_cmd_tab[*parv[0]];
+               if(cmd->fn != NULL)
+               {
+                       if(cmd->min_parc > parc)
                        {
-                               iwarn("authd sent a result with wrong number of arguments: got %d", parc);
+                               iwarn("authd sent a result with wrong number of arguments: expected %d, got %d",
+                                       cmd->min_parc, parc);
                                restart_authd();
-                               return;
+                               continue;
                        }
 
-                       /* Select by type */
-                       switch(*parv[2])
-                       {
-                       case 'D':
-                               /* parv[0] conveys status */
-                               if(parc < 4)
-                               {
-                                       iwarn("authd sent a result with wrong number of arguments: got %d", parc);
-                                       restart_authd();
-                                       return;
-                               }
-                               dns_stats_results_callback(parv[1], parv[0], parc - 3, (const char **)&parv[3]);
-                               break;
-                       default:
-                               break;
-                       }
-                       break;
-               default:
-                       break;
+                       cmd->fn(parc, parv);
+               }
+               else
+               {
+                       iwarn("authd sent us a bad command type: %c", *parv[0]);
+                       restart_authd();
+                       continue;
                }
        }
 }
@@ -420,12 +435,12 @@ authd_decide_client(struct Client *client_p, const char *ident, const char *host
        if(*host != '*')
                rb_strlcpy(client_p->host, host, sizeof(client_p->host));
 
+       rb_dictionary_delete(cid_clients, RB_UINT_TO_POINTER(client_p->preClient->authd_cid));
+
        client_p->preClient->authd_accepted = accept;
        client_p->preClient->authd_cause = cause;
        client_p->preClient->authd_data = (data == NULL ? NULL : rb_strdup(data));
        client_p->preClient->authd_reason = (reason == NULL ? NULL : rb_strdup(reason));
-
-       rb_dictionary_delete(cid_clients, RB_UINT_TO_POINTER(client_p->preClient->authd_cid));
        client_p->preClient->authd_cid = 0;
 
        /*
@@ -468,8 +483,7 @@ authd_abort_client(struct Client *client_p)
        if(authd_helper != NULL)
                rb_helper_write(authd_helper, "E %x", client_p->preClient->authd_cid);
 
-       /* XXX should we blindly allow like this? */
-       authd_accept_client(client_p, "*", "*");
+       client_p->preClient->authd_accepted = true;
        client_p->preClient->authd_cid = 0;
 }
 
@@ -486,23 +500,6 @@ timeout_dead_authd_clients(void *notused __unused)
        }
 }
 
-/* Turn a cause char (who rejected us) into the name of the provider */
-const char *
-get_provider_string(char cause)
-{
-       switch(cause)
-       {
-       case 'B':
-               return "Blacklist";
-       case 'D':
-               return "rDNS";
-       case 'I':
-               return "Ident";
-       default:
-               return "Unknown";
-       }
-}
-
 /* Send a new blacklist to authd */
 void
 add_blacklist(const char *host, const char *reason, uint8_t iptype, rb_dlink_list *filters)