]> jfr.im git - solanum.git/blobdiff - authd/providers/blacklist.c
authd: fix auth->cid type sizes
[solanum.git] / authd / providers / blacklist.c
index bd81c244c2a25834afbfa257efc1ae376e6d1343..769a34a424123035818f4fb5cf0c2b3a40790549 100644 (file)
  */
 
 #include "authd.h"
+#include "defaults.h"
 #include "provider.h"
 #include "notice.h"
 #include "stdinc.h"
 #include "dns.h"
 
+#define SELF_PID (blacklist_provider.id)
+
 typedef enum filter_t
 {
        FILTER_ALL = 1,
@@ -91,11 +94,9 @@ struct blacklist_filter
 struct blacklist_user
 {
        rb_dlink_list queries;          /* Blacklist queries in flight */
-       time_t timeout;                 /* When this times out */
 };
 
 /* public interfaces */
-static bool blacklists_init(void);
 static void blacklists_destroy(void);
 
 static bool blacklists_start(struct auth_client *);
@@ -108,12 +109,10 @@ static struct blacklist *find_blacklist(const char *);
 static bool blacklist_check_reply(struct blacklist_lookup *, const char *);
 static void blacklist_dns_callback(const char *, bool, query_type, void *);
 static void initiate_blacklist_dnsquery(struct blacklist *, struct auth_client *);
-static void timeout_blacklist_queries_event(void *);
 
 /* Variables */
 static rb_dlink_list blacklist_list = { NULL, NULL, 0 };
-static struct ev_entry *timeout_ev;
-static int blacklist_timeout = 15;
+static int blacklist_timeout = BLACKLIST_TIMEOUT_DEFAULT;
 
 /* private interfaces */
 
@@ -235,13 +234,13 @@ blacklist_dns_callback(const char *result, bool status, query_type type, void *d
        struct blacklist *bl;
        struct auth_client *auth;
 
-       if (bllookup == NULL || bllookup->auth == NULL)
-               return;
+       lrb_assert(bllookup != NULL);
+       lrb_assert(bllookup->auth != NULL);
 
        bl = bllookup->bl;
        auth = bllookup->auth;
-       bluser = auth->data[PROVIDER_BLACKLIST];
-       if(bluser == NULL)
+
+       if((bluser = get_provider_data(auth, SELF_PID)) == NULL)
                return;
 
        if (result != NULL && status && blacklist_check_reply(bllookup, result))
@@ -249,7 +248,7 @@ blacklist_dns_callback(const char *result, bool status, query_type type, void *d
                /* Match found, so proceed no further */
                bl->hits++;
                blacklists_cancel(auth);
-               reject_client(auth, PROVIDER_BLACKLIST, bl->host, bl->reason);
+               reject_client(auth, SELF_PID, bl->host, bl->reason);
                return;
        }
 
@@ -262,10 +261,11 @@ blacklist_dns_callback(const char *result, bool status, query_type type, void *d
        {
                /* Done here */
                notice_client(auth->cid, "*** IP not found in DNS blacklist%s",
-                               rb_dlink_list_length(&blacklist_list) > 1 : "s" : "");
+                               rb_dlink_list_length(&blacklist_list) > 1 ? "s" : "");
                rb_free(bluser);
-               auth->data[PROVIDER_BLACKLIST] = NULL;
-               provider_done(auth, PROVIDER_BLACKLIST);
+               set_provider_data(auth, SELF_PID, NULL);
+               set_provider_timeout_absolute(auth, SELF_PID, 0);
+               provider_done(auth, SELF_PID);
        }
 }
 
@@ -273,7 +273,7 @@ static void
 initiate_blacklist_dnsquery(struct blacklist *bl, struct auth_client *auth)
 {
        struct blacklist_lookup *bllookup = rb_malloc(sizeof(struct blacklist_lookup));
-       struct blacklist_user *bluser = auth->data[PROVIDER_BLACKLIST];
+       struct blacklist_user *bluser = get_provider_data(auth, SELF_PID);
        char buf[IRCD_RES_HOSTLEN + 1];
        int aftype;
 
@@ -284,7 +284,10 @@ initiate_blacklist_dnsquery(struct blacklist *bl, struct auth_client *auth)
        if((aftype == AF_INET && (bl->iptype & IPTYPE_IPV4) == 0) ||
                (aftype == AF_INET6 && (bl->iptype & IPTYPE_IPV6) == 0))
                /* Incorrect blacklist type for this IP... */
+       {
+               rb_free(bllookup);
                return;
+       }
 
        build_rdns(buf, sizeof(buf), &auth->c_addr, bl->host);
 
@@ -294,29 +297,10 @@ initiate_blacklist_dnsquery(struct blacklist *bl, struct auth_client *auth)
        bl->refcount++;
 }
 
-/* Timeout outstanding queries */
-static void
-timeout_blacklist_queries_event(void *notused)
-{
-       struct auth_client *auth;
-       rb_dictionary_iter iter;
-
-       RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
-       {
-               struct blacklist_user *bluser = auth->data[PROVIDER_BLACKLIST];
-
-               if(bluser != NULL && bluser->timeout < rb_current_time())
-               {
-                       blacklists_cancel(auth);
-                       provider_done(auth, PROVIDER_BLACKLIST);
-               }
-       }
-}
-
 static inline void
 lookup_all_blacklists(struct auth_client *auth)
 {
-       struct blacklist_user *bluser = auth->data[PROVIDER_BLACKLIST];
+       struct blacklist_user *bluser = get_provider_data(auth, SELF_PID);
        rb_dlink_node *ptr;
 
        notice_client(auth->cid, "*** Checking your IP against DNS blacklist%s",
@@ -330,7 +314,7 @@ lookup_all_blacklists(struct auth_client *auth)
                        initiate_blacklist_dnsquery(bl, auth);
        }
 
-       bluser->timeout = rb_current_time() + blacklist_timeout;
+       set_provider_timeout_relative(auth, SELF_PID, blacklist_timeout);
 }
 
 static inline void
@@ -360,41 +344,44 @@ delete_all_blacklists(void)
 static bool
 blacklists_start(struct auth_client *auth)
 {
-       if(auth->data[PROVIDER_BLACKLIST] != NULL)
-               return true;
+       uint32_t rdns_pid, ident_pid;
+
+       lrb_assert(get_provider_data(auth, SELF_PID) == NULL);
 
        if(!rb_dlink_list_length(&blacklist_list))
-       {
                /* Nothing to do... */
-               notice_client(auth->cid, "*** No DNS blacklists configured, not checking your IP");
                return true;
-       }
 
-       auth->data[PROVIDER_BLACKLIST] = rb_malloc(sizeof(struct blacklist_user));
+       set_provider_data(auth, SELF_PID, rb_malloc(sizeof(struct blacklist_user)));
 
-       if(is_provider_done(auth, PROVIDER_RDNS) && is_provider_done(auth, PROVIDER_IDENT))
-               /* This probably can't happen but let's handle this case anyway */
+       if((!get_provider_id("rdns", &rdns_pid) || is_provider_done(auth, rdns_pid)) &&
+               (!get_provider_id("ident", &ident_pid) || is_provider_done(auth, ident_pid)))
+       {
+               /* Start the lookup if ident and rdns are finished, or not loaded. */
                lookup_all_blacklists(auth);
+       }
 
-       set_provider_on(auth, PROVIDER_BLACKLIST);
+       set_provider_running(auth, SELF_PID);
        return true;
 }
 
 /* This is called every time a provider is completed as long as we are marked not done */
 static void
-blacklists_initiate(struct auth_client *auth, provider_t provider)
+blacklists_initiate(struct auth_client *auth, uint32_t provider)
 {
-       struct blacklist_user *bluser = auth->data[PROVIDER_BLACKLIST];
+       struct blacklist_user *bluser = get_provider_data(auth, SELF_PID);
+       uint32_t rdns_pid, ident_pid;
 
-       lrb_assert(provider != PROVIDER_BLACKLIST);
-       lrb_assert(!is_provider_done(auth, PROVIDER_BLACKLIST));
+       lrb_assert(provider != SELF_PID);
+       lrb_assert(!is_provider_done(auth, SELF_PID));
        lrb_assert(rb_dlink_list_length(&blacklist_list) > 0);
 
        if(bluser == NULL || rb_dlink_list_length(&bluser->queries))
                /* Nothing to do */
                return;
-       else if(!(is_provider_done(auth, PROVIDER_RDNS) && is_provider_done(auth, PROVIDER_IDENT)))
-               /* Don't start until we've completed these */
+       else if((!get_provider_id("rdns", &rdns_pid) || is_provider_done(auth, rdns_pid)) &&
+               (!get_provider_id("ident", &ident_pid) || is_provider_done(auth, ident_pid)))
+               /* Don't start until ident and rdns are finished (or not loaded) */
                return;
        else
                lookup_all_blacklists(auth);
@@ -404,7 +391,7 @@ static void
 blacklists_cancel(struct auth_client *auth)
 {
        rb_dlink_node *ptr, *nptr;
-       struct blacklist_user *bluser = auth->data[PROVIDER_BLACKLIST];
+       struct blacklist_user *bluser = get_provider_data(auth, SELF_PID);
 
        if(bluser == NULL)
                return;
@@ -426,14 +413,9 @@ blacklists_cancel(struct auth_client *auth)
        }
 
        rb_free(bluser);
-       auth->data[PROVIDER_BLACKLIST] = NULL;
-}
-
-static bool
-blacklists_init(void)
-{
-       timeout_ev = rb_event_addish("timeout_blacklist_queries_event", timeout_blacklist_queries_event, NULL, 1);
-       return (timeout_ev != NULL);
+       set_provider_data(auth, SELF_PID, NULL);
+       set_provider_timeout_absolute(auth, SELF_PID, 0);
+       provider_done(auth, SELF_PID);
 }
 
 static void
@@ -448,7 +430,6 @@ blacklists_destroy(void)
        }
 
        delete_all_blacklists();
-       rb_event_delete(timeout_ev);
 }
 
 static void
@@ -575,11 +556,12 @@ struct auth_opts_handler blacklist_options[] =
 
 struct auth_provider blacklist_provider =
 {
-       .id = PROVIDER_BLACKLIST,
-       .init = blacklists_init,
+       .name = "blacklist",
+       .letter = 'B',
        .destroy = blacklists_destroy,
        .start = blacklists_start,
        .cancel = blacklists_cancel,
+       .timeout = blacklists_cancel,
        .completed = blacklists_initiate,
        .opt_handlers = blacklist_options,
        /* .stats_handler = { 'B', blacklist_stats }, */