]> jfr.im git - solanum.git/blobdiff - src/s_auth.c
Fix some compiler warnings about signed/unsigned comparison.
[solanum.git] / src / s_auth.c
index 6c27d211e928b1d134175092900f7143e02e24d8..593ca56f31083b2b5aeef9346617da1c02a46700 100644 (file)
@@ -39,8 +39,7 @@
 #include "s_conf.h"
 #include "client.h"
 #include "common.h"
-#include "irc_string.h"
-#include "sprintf_irc.h"
+#include "match.h"
 #include "ircd.h"
 #include "numeric.h"
 #include "packet.h"
 #include "send.h"
 #include "hook.h"
 #include "blacklist.h"
+#include "s_assert.h"
+
+struct AuthRequest
+{
+       rb_dlink_node node;
+       struct Client *client;  /* pointer to client struct for request */
+       struct DNSQuery dns_query; /* DNS Query */
+       unsigned int flags;     /* current state of request */
+       rb_fde_t *F;            /* file descriptor for auth queries */
+       time_t timeout;         /* time when query expires */
+       uint16_t lport;
+       uint16_t rport;
+};
+
+/*
+ * flag values for AuthRequest
+ * NAMESPACE: AM_xxx - Authentication Module
+ */
+#define AM_AUTH_CONNECTING   (1 << 0)
+#define AM_AUTH_PENDING      (1 << 1)
+#define AM_DNS_PENDING       (1 << 2)
+
+#define SetDNSPending(x)     ((x)->flags |= AM_DNS_PENDING)
+#define ClearDNSPending(x)   ((x)->flags &= ~AM_DNS_PENDING)
+#define IsDNSPending(x)      ((x)->flags &  AM_DNS_PENDING)
+
+#define SetAuthConnect(x)    ((x)->flags |= AM_AUTH_CONNECTING)
+#define ClearAuthConnect(x)  ((x)->flags &= ~AM_AUTH_CONNECTING)
+#define IsAuthConnect(x)     ((x)->flags &  AM_AUTH_CONNECTING)
+
+#define SetAuthPending(x)    ((x)->flags |= AM_AUTH_PENDING)
+#define ClearAuthPending(x)  ((x)->flags &= AM_AUTH_PENDING)
+#define IsAuthPending(x)     ((x)->flags &  AM_AUTH_PENDING)
+
+#define ClearAuth(x)         ((x)->flags &= ~(AM_AUTH_PENDING | AM_AUTH_CONNECTING))
+#define IsDoingAuth(x)       ((x)->flags &  (AM_AUTH_PENDING | AM_AUTH_CONNECTING))
 
 /*
  * a bit different approach
@@ -83,7 +118,7 @@ typedef enum
 }
 ReportType;
 
-#define sendheader(c, r) sendto_one_notice(c, HeaderMessages[(r)]) 
+#define sendheader(c, r) sendto_one_notice(c, "%s", HeaderMessages[(r)])
 
 static rb_dlink_list auth_poll_list;
 static rb_bh *auth_heap;
@@ -138,20 +173,19 @@ static void
 release_auth_client(struct AuthRequest *auth)
 {
        struct Client *client = auth->client;
-       
+
        if(IsDNSPending(auth) || IsDoingAuth(auth))
                return;
 
        client->localClient->auth_request = NULL;
        rb_dlinkDelete(&auth->node, &auth_poll_list);
-       free_auth_request(auth);        
+       free_auth_request(auth);
 
        /*
         * When a client has auth'ed, we want to start reading what it sends
         * us. This is what read_packet() does.
         *     -- adrian
         */
-       client->localClient->allow_read = MAX_FLOOD;
        rb_dlinkAddTail(client, &client->node, &global_client_list);
        read_packet(client->localClient->F, client);
 }
@@ -247,12 +281,12 @@ auth_error(struct AuthRequest *auth)
 
        ClearAuth(auth);
        sendheader(auth->client, REPORT_FAIL_ID);
-               
+
        release_auth_client(auth);
 }
 
 /*
- * start_auth_query - Flag the client to show that an attempt to 
+ * start_auth_query - Flag the client to show that an attempt to
  * contact the ident server on
  * the client's host.  The connect and subsequently the socket are all put
  * into 'non-blocking' mode.  Should the connect or any later phase of the
@@ -263,13 +297,12 @@ static int
 start_auth_query(struct AuthRequest *auth)
 {
        struct rb_sockaddr_storage localaddr, destaddr;
-       socklen_t locallen = sizeof(struct rb_sockaddr_storage);
        rb_fde_t *F;
        int family;
-       
+
        if(IsAnyDead(auth->client))
                return 0;
-       
+
        family = auth->client->localClient->ip.ss_family;
        if((F = rb_socket(family, SOCK_STREAM, 0, "ident")) == NULL)
        {
@@ -292,48 +325,56 @@ start_auth_query(struct AuthRequest *auth)
 
        sendheader(auth->client, REPORT_DO_ID);
 
-       /* 
+       /*
         * get the local address of the client and bind to that to
         * make the auth request.  This used to be done only for
         * ifdef VIRTUAL_HOST, but needs to be done for all clients
         * since the ident request must originate from that same address--
         * and machines with multiple IP addresses are common now
         */
-       memset(&localaddr, 0, locallen);
-       getsockname(rb_get_fd(auth->client->localClient->F),
-                   (struct sockaddr *) &localaddr, &locallen);
-       
+       localaddr = auth->client->preClient->lip;
+
        /* XXX mangle_mapped_sockaddr((struct sockaddr *)&localaddr); */
 #ifdef RB_IPV6
        if(localaddr.ss_family == AF_INET6)
        {
+               auth->lport = ntohs(((struct sockaddr_in6 *)&localaddr)->sin6_port);
                ((struct sockaddr_in6 *)&localaddr)->sin6_port = 0;
-       } else
+       }
+       else
 #endif
-       ((struct sockaddr_in *)&localaddr)->sin_port = 0;
+       {
+               auth->lport = ntohs(((struct sockaddr_in *)&localaddr)->sin_port);
+               ((struct sockaddr_in *)&localaddr)->sin_port = 0;
+       }
 
        destaddr = auth->client->localClient->ip;
 #ifdef RB_IPV6
        if(localaddr.ss_family == AF_INET6)
        {
+               auth->rport = ntohs(((struct sockaddr_in6 *)&destaddr)->sin6_port);
                ((struct sockaddr_in6 *)&destaddr)->sin6_port = htons(113);
-       } else
+       }
+       else
 #endif
-       ((struct sockaddr_in *)&destaddr)->sin_port = htons(113);
-       
+       {
+               auth->rport = ntohs(((struct sockaddr_in *)&destaddr)->sin_port);
+               ((struct sockaddr_in *)&destaddr)->sin_port = htons(113);
+       }
+
        auth->F = F;
        SetAuthConnect(auth);
 
        rb_connect_tcp(F, (struct sockaddr *)&destaddr,
                         (struct sockaddr *) &localaddr, GET_SS_LEN(&localaddr),
-                        auth_connect_callback, auth, 
+                        auth_connect_callback, auth,
                         GlobalSetOptions.ident_timeout);
        return 1;               /* We suceed here for now */
 }
 
 /*
  * GetValidIdent - parse ident query reply from identd server
- * 
+ *
  * Inputs        - pointer to ident buf
  * Output        - NULL if no valid ident found, otherwise pointer to name
  * Side effects  -
@@ -477,11 +518,8 @@ static void
 auth_connect_callback(rb_fde_t *F, int error, void *data)
 {
        struct AuthRequest *auth = data;
-       struct sockaddr_in us;
-       struct sockaddr_in them;
        char authbuf[32];
-       socklen_t ulen = sizeof(struct sockaddr_in);
-       socklen_t tlen = sizeof(struct sockaddr_in);
+       int authlen;
 
        /* Check the error */
        if(error != RB_OK)
@@ -491,21 +529,11 @@ auth_connect_callback(rb_fde_t *F, int error, void *data)
                return;
        }
 
-       if(getsockname
-          (rb_get_fd(auth->client->localClient->F), (struct sockaddr *) &us,
-           (socklen_t *) & ulen)
-          || getpeername(rb_get_fd(auth->client->localClient->F),
-                         (struct sockaddr *) &them, (socklen_t *) & tlen))
-       {
-               ilog(L_IOERROR, "auth get{sock,peer}name error for %s:%m",
-                    log_client_name(auth->client, SHOW_IP));
-               auth_error(auth);
-               return;
-       }
        rb_snprintf(authbuf, sizeof(authbuf), "%u , %u\r\n",
-                  (unsigned int) ntohs(them.sin_port), (unsigned int) ntohs(us.sin_port));
+                  auth->rport, auth->lport);
+       authlen = strlen(authbuf);
 
-       if(write(rb_get_fd(auth->F), authbuf, strlen(authbuf)) == -1)
+       if(rb_write(auth->F, authbuf, authlen) != authlen)
        {
                auth_error(auth);
                return;
@@ -517,7 +545,7 @@ auth_connect_callback(rb_fde_t *F, int error, void *data)
 
 
 /*
- * read_auth_reply - read the reply (if any) from the ident server 
+ * read_auth_reply - read the reply (if any) from the ident server
  * we connected to.
  * We only give it one shot, if the reply isn't good the first time
  * fail the authentication entirely. --Bleep
@@ -534,7 +562,7 @@ read_auth_reply(rb_fde_t *F, void *data)
        int count;
        char buf[AUTH_BUFSIZ + 1];      /* buffer to read auth reply into */
 
-       len = read(rb_get_fd(F), buf, AUTH_BUFSIZ);
+       len = rb_read(F, buf, AUTH_BUFSIZ);
 
        if(len < 0 && rb_ignore_errno(errno))
        {
@@ -603,7 +631,7 @@ delete_auth_queries(struct Client *target_p)
        if(target_p == NULL || target_p->localClient == NULL ||
           target_p->localClient->auth_request == NULL)
                return;
-       
+
        auth = target_p->localClient->auth_request;
        target_p->localClient->auth_request = NULL;
 
@@ -612,7 +640,7 @@ delete_auth_queries(struct Client *target_p)
 
        if(auth->F != NULL)
                rb_close(auth->F);
-               
+
        rb_dlinkDelete(&auth->node, &auth_poll_list);
        free_auth_request(auth);
 }