]> jfr.im git - solanum.git/blobdiff - authd/providers/opm.c
authd: mention rDNS in found your hostname message
[solanum.git] / authd / providers / opm.c
index 84784de82d62a98fea637720710f0cb61dde1f48..1d76f647d6fa5d9ae4abb4e8cc0c201b72ad717a 100644 (file)
@@ -39,6 +39,7 @@ typedef enum protocol_t
 struct opm_lookup
 {
        rb_dlink_list scans;    /* List of scans */
+       bool in_progress;
 };
 
 struct opm_proxy
@@ -121,6 +122,7 @@ find_proxy_scanner(protocol_t proto, uint16_t port)
        return NULL;
 }
 
+/* This is called when an open proxy connects to us */
 static void
 read_opm_reply(rb_fde_t *F, void *data)
 {
@@ -130,11 +132,9 @@ read_opm_reply(rb_fde_t *F, void *data)
        char readbuf[OPM_READSIZE];
        ssize_t len;
 
-       if(auth == NULL || (lookup = auth->data[PROVIDER_OPM]) == NULL)
-       {
-               rb_close(F);
-               return;
-       }
+       lrb_assert(auth != NULL);
+       lookup = get_provider_data(auth, PROVIDER_OPM);
+       lrb_assert(lookup != NULL);
 
        if((len = rb_read(F, readbuf, sizeof(readbuf))) < 0 && rb_ignore_errno(errno))
        {
@@ -254,12 +254,14 @@ socks4_connected(rb_fde_t *F, int error, void *data)
        uint8_t *c = sendbuf;
        ssize_t ret;
 
-       if(scan == NULL || (auth = scan->auth) == NULL || (lookup = auth->data[PROVIDER_OPM]) == NULL)
-               return;
-
        if(error || !opm_enable)
                goto end;
 
+       lrb_assert(scan != NULL);
+
+       auth = scan->auth;
+       lookup = get_provider_data(auth, PROVIDER_OPM);
+
        memcpy(c, "\x04\x01", 2); c += 2; /* Socks version 4, connect command */
 
        switch(GET_SS_FAMILY(&auth->c_addr))
@@ -307,12 +309,14 @@ socks5_connected(rb_fde_t *F, int error, void *data)
        uint8_t *c = sendbuf;
        ssize_t ret;
 
-       if(scan == NULL || (auth = scan->auth) == NULL || (lookup = auth->data[PROVIDER_OPM]) == NULL)
-               return;
-
        if(error || !opm_enable)
                goto end;
 
+       lrb_assert(scan != NULL);
+
+       auth = scan->auth;
+       lookup = get_provider_data(auth, PROVIDER_OPM);
+
        /* Build the version header and socks request
         * version header (3 bytes): version, number of auth methods, auth type (0 for none)
         * connect req (3 bytes): version, command (1 = connect), reserved (0)
@@ -370,12 +374,14 @@ http_connect_connected(rb_fde_t *F, int error, void *data)
        char *c = sendbuf;
        ssize_t ret;
 
-       if(scan == NULL || (auth = scan->auth) == NULL || (lookup = auth->data[PROVIDER_OPM]) == NULL)
-               return;
-
        if(error || !opm_enable)
                goto end;
 
+       lrb_assert(scan != NULL);
+
+       auth = scan->auth;
+       lookup = get_provider_data(auth, PROVIDER_OPM);
+
        switch(GET_SS_FAMILY(&auth->c_addr))
        {
        case AF_INET:
@@ -419,13 +425,15 @@ end:
 static inline void
 establish_connection(struct auth_client *auth, struct opm_proxy *proxy)
 {
-       struct opm_lookup *lookup = auth->data[PROVIDER_OPM];
+       struct opm_lookup *lookup = get_provider_data(auth, PROVIDER_OPM);
        struct opm_listener *listener;
        struct opm_scan *scan = rb_malloc(sizeof(struct opm_scan));
        struct rb_sockaddr_storage c_a, l_a;
        int opt = 1;
        CNCB *callback;
 
+       lrb_assert(lookup != NULL);
+
        switch(proxy->proto)
        {
        case PROTO_SOCKS4:
@@ -463,7 +471,7 @@ establish_connection(struct auth_client *auth, struct opm_proxy *proxy)
        scan->proxy = proxy;
        if((scan->F = rb_socket(GET_SS_FAMILY(&auth->c_addr), SOCK_STREAM, 0, proxy->note)) == NULL)
        {
-               warn_opers(L_CRIT, "OPM: could not create OPM socket (proto %s): %s", proxy->note, strerror(errno));
+               warn_opers(L_WARN, "OPM: could not create OPM socket (proto %s): %s", proxy->note, strerror(errno));
                rb_free(scan);
                return;
        }
@@ -506,6 +514,8 @@ create_listener(const char *ip, uint16_t port)
                exit(EX_PROVIDER_ERROR);
        }
 
+       SET_SS_PORT(&addr, htons(port));
+
 #ifdef RB_IPV6
        if(GET_SS_FAMILY(&addr) == AF_INET6)
        {
@@ -557,14 +567,6 @@ create_listener(const char *ip, uint16_t port)
                exit(EX_PROVIDER_ERROR);
        }
 
-       /* Set up ports for binding */
-#ifdef RB_IPV6
-       if(GET_SS_FAMILY(&addr) == AF_INET6)
-               ((struct sockaddr_in6 *)&addr)->sin6_port = htons(port);
-       else
-#endif
-               ((struct sockaddr_in *)&addr)->sin_port = htons(port);
-
        if(bind(rb_get_fd(F), (struct sockaddr *)&addr, GET_SS_LEN(&addr)))
        {
                /* Shit happens, let's not cripple authd over /this/ since it could be user error */
@@ -607,51 +609,74 @@ create_listener(const char *ip, uint16_t port)
        return true;
 }
 
-
 static void
-opm_destroy(void)
+opm_scan(struct auth_client *auth)
 {
-       struct auth_client *auth;
-       rb_dictionary_iter iter;
+       rb_dlink_node *ptr;
+       struct opm_lookup *lookup;
 
-       /* Nuke all opm lookups */
-       RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
+       lrb_assert(auth != NULL);
+
+       lookup = get_provider_data(auth, PROVIDER_OPM);
+       set_provider_timeout_relative(auth, PROVIDER_OPM, opm_timeout);
+
+       lookup->in_progress = true;
+
+       RB_DLINK_FOREACH(ptr, proxy_scanners.head)
        {
-               opm_cancel(auth);
+               struct opm_proxy *proxy = ptr->data;
+               establish_connection(auth, proxy);
        }
+
+       notice_client(auth->cid, "*** Scanning for open proxies...");
+}
+
+/* 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)
+{
+       struct opm_lookup *lookup = get_provider_data(auth, PROVIDER_OPM);
+
+       lrb_assert(provider != PROVIDER_OPM);
+       lrb_assert(!is_provider_done(auth, PROVIDER_OPM));
+       lrb_assert(rb_dlink_list_length(&proxy_scanners) > 0);
+
+       if(lookup == NULL || lookup->in_progress)
+               /* 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 */
+               return;
+       else
+               opm_scan(auth);
 }
 
 static bool
 opm_start(struct auth_client *auth)
 {
-       rb_dlink_node *ptr;
-       struct opm_lookup *lookup = rb_malloc(sizeof(struct opm_lookup));
+       lrb_assert(get_provider_data(auth, PROVIDER_OPM) == NULL);
 
-       if(!opm_enable || !rb_dlink_list_length(&proxy_scanners))
+       if(!opm_enable || rb_dlink_list_length(&proxy_scanners) == 0)
        {
+               /* Nothing to do... */
                notice_client(auth->cid, "*** Proxy scanning disabled, not scanning");
                return true;
        }
 
-       auth->data[PROVIDER_OPM] = lookup = rb_malloc(sizeof(struct opm_lookup));
-       auth->timeout[PROVIDER_OPM] = rb_current_time() + opm_timeout;
+       set_provider_data(auth, PROVIDER_BLACKLIST, rb_malloc(sizeof(struct opm_lookup)));
 
-       RB_DLINK_FOREACH(ptr, proxy_scanners.head)
-       {
-               struct opm_proxy *proxy = ptr->data;
-               establish_connection(auth, proxy);
-       }
-
-       notice_client(auth->cid, "*** Scanning for open proxies...");
-       set_provider_on(auth, PROVIDER_OPM);
+       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 */
+               opm_scan(auth);
 
+       set_provider_on(auth, PROVIDER_BLACKLIST);
        return true;
 }
 
 static void
 opm_cancel(struct auth_client *auth)
 {
-       struct opm_lookup *lookup = auth->data[PROVIDER_OPM];
+       struct opm_lookup *lookup = get_provider_data(auth, PROVIDER_OPM);
 
        if(lookup != NULL)
        {
@@ -668,10 +693,27 @@ opm_cancel(struct auth_client *auth)
                }
 
                rb_free(lookup);
+
+               set_provider_data(auth, PROVIDER_OPM, NULL);
+               set_provider_timeout_absolute(auth, PROVIDER_OPM, 0);
                provider_done(auth, PROVIDER_OPM);
        }
 }
 
+static void
+opm_destroy(void)
+{
+       struct auth_client *auth;
+       rb_dictionary_iter iter;
+
+       /* Nuke all opm lookups */
+       RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
+       {
+               opm_cancel(auth);
+       }
+}
+
+
 static void
 add_conf_opm_timeout(const char *key __unused, int parc __unused, const char **parv)
 {
@@ -827,7 +869,7 @@ delete_opm_scanner(const char *key __unused, int parc __unused, const char **par
        RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
        {
                rb_dlink_node *ptr;
-               struct opm_lookup *lookup = auth->data[PROVIDER_OPM];
+               struct opm_lookup *lookup = get_provider_data(auth, PROVIDER_OPM);
 
                if(lookup == NULL)
                        continue;
@@ -842,7 +884,7 @@ delete_opm_scanner(const char *key __unused, int parc __unused, const char **par
                                rb_dlinkDelete(&scan->node, &lookup->scans);
                                rb_free(scan);
 
-                               if(!rb_dlink_list_length(&lookup->scans))
+                               if(rb_dlink_list_length(&lookup->scans) == 0)
                                        opm_cancel(auth);
 
                                break;
@@ -852,6 +894,9 @@ delete_opm_scanner(const char *key __unused, int parc __unused, const char **par
 
        rb_dlinkDelete(&proxy->node, &proxy_scanners);
        rb_free(proxy);
+
+       if(rb_dlink_list_length(&proxy_scanners) == 0)
+               opm_enable = false;
 }
 
 static void
@@ -871,6 +916,8 @@ delete_opm_scanner_all(const char *key __unused, int parc __unused, const char *
        {
                opm_cancel(auth);
        }
+
+       opm_enable = false;
 }