]> jfr.im git - irc/rqf/shadowircd.git/blobdiff - src/s_auth.c
Don't allow +Z to be set by default_umodes
[irc/rqf/shadowircd.git] / src / s_auth.c
index 124a3c1ca995985bffb4d00fc11862015feb738a..2644ff14aa2ac3265f5bc2d03acb085e831ca91d 100644 (file)
@@ -20,8 +20,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
  *  USA
- *
- *  $Id: s_auth.c 3354 2007-04-03 09:21:31Z nenolod $ */
+ */
 
 /*
  * Changes:
  */
 #include "stdinc.h"
 #include "config.h"
-#include "tools.h"
 #include "s_auth.h"
 #include "s_conf.h"
 #include "client.h"
 #include "common.h"
-#include "event.h"
-#include "irc_string.h"
-#include "sprintf_irc.h"
+#include "match.h"
 #include "ircd.h"
 #include "numeric.h"
 #include "packet.h"
 #include "res.h"
-#include "commio.h"
-#include "s_log.h"
+#include "logger.h"
 #include "s_stats.h"
 #include "send.h"
-#include "memory.h"
 #include "hook.h"
 #include "blacklist.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
  * this replaces the original sendheader macros
@@ -90,7 +119,7 @@ ReportType;
 #define sendheader(c, r) sendto_one_notice(c, HeaderMessages[(r)]) 
 
 static rb_dlink_list auth_poll_list;
-static BlockHeap *auth_heap;
+static rb_bh *auth_heap;
 static EVH timeout_auth_queries_event;
 
 static PF read_auth_reply;
@@ -106,8 +135,8 @@ init_auth(void)
 {
        /* This hook takes a struct Client for its argument */
        memset(&auth_poll_list, 0, sizeof(auth_poll_list));
-       eventAddIsh("timeout_auth_queries_event", timeout_auth_queries_event, NULL, 1);
-       auth_heap = BlockHeapCreate(sizeof(struct AuthRequest), LCLIENT_HEAP_SIZE);
+       rb_event_addish("timeout_auth_queries_event", timeout_auth_queries_event, NULL, 1);
+       auth_heap = rb_bh_create(sizeof(struct AuthRequest), LCLIENT_HEAP_SIZE, "auth_heap");
 }
 
 /*
@@ -116,11 +145,11 @@ init_auth(void)
 static struct AuthRequest *
 make_auth_request(struct Client *client)
 {
-       struct AuthRequest *request = BlockHeapAlloc(auth_heap);
+       struct AuthRequest *request = rb_bh_alloc(auth_heap);
        client->localClient->auth_request = request;
-       request->fd = -1;
+       request->F = NULL;
        request->client = client;
-       request->timeout = CurrentTime + ConfigFileEntry.connect_timeout;
+       request->timeout = rb_current_time() + ConfigFileEntry.connect_timeout;
        return request;
 }
 
@@ -130,7 +159,7 @@ make_auth_request(struct Client *client)
 static void
 free_auth_request(struct AuthRequest *request)
 {
-       BlockHeapFree(auth_heap, request);
+       rb_bh_free(auth_heap, request);
 }
 
 /*
@@ -149,8 +178,6 @@ release_auth_client(struct AuthRequest *auth)
        client->localClient->auth_request = NULL;
        rb_dlinkDelete(&auth->node, &auth_poll_list);
        free_auth_request(auth);        
-       if(client->localClient->F->fd > highest_fd)
-               highest_fd = client->localClient->F->fd;
 
        /*
         * When a client has auth'ed, we want to start reading what it sends
@@ -158,9 +185,8 @@ release_auth_client(struct AuthRequest *auth)
         *     -- adrian
         */
        client->localClient->allow_read = MAX_FLOOD;
-       rb_setflush(client->localClient->F->fd, 1000, flood_recalc, client);
        rb_dlinkAddTail(client, &client->node, &global_client_list);
-       read_packet(client->localClient->F->fd, client);
+       read_packet(client->localClient->F, client);
 }
 
 /*
@@ -206,7 +232,7 @@ auth_dns_callback(void *vptr, struct DNSReply *reply)
                                good = 0;
                        }
                }
-#ifdef IPV6
+#ifdef RB_IPV6
                else if(auth->client->localClient->ip.ss_family == AF_INET6)
                {
                        struct sockaddr_in6 *ip, *ip_fwd;
@@ -229,7 +255,7 @@ auth_dns_callback(void *vptr, struct DNSReply *reply)
 
                 if(good && strlen(reply->h_name) <= HOSTLEN)
                 {
-                        strlcpy(auth->client->host, reply->h_name, sizeof(auth->client->host));
+                        rb_strlcpy(auth->client->host, reply->h_name, sizeof(auth->client->host));
                         sendheader(auth->client, REPORT_FIN_DNS);
                 }
                 else if (strlen(reply->h_name) > HOSTLEN)
@@ -247,10 +273,10 @@ auth_dns_callback(void *vptr, struct DNSReply *reply)
 static void
 auth_error(struct AuthRequest *auth)
 {
-       ++ServerStats->is_abad;
+       ++ServerStats.is_abad;
 
-       rb_close(auth->fd);
-       auth->fd = -1;
+       rb_close(auth->F);
+       auth->F = NULL;
 
        ClearAuth(auth);
        sendheader(auth->client, REPORT_FAIL_ID);
@@ -269,33 +295,30 @@ auth_error(struct AuthRequest *auth)
 static int
 start_auth_query(struct AuthRequest *auth)
 {
-       struct irc_sockaddr_storage localaddr;
-       socklen_t locallen = sizeof(struct irc_sockaddr_storage);
-       int fd;
+       struct rb_sockaddr_storage localaddr, destaddr;
+       rb_fde_t *F;
        int family;
        
        if(IsAnyDead(auth->client))
                return 0;
        
        family = auth->client->localClient->ip.ss_family;
-       if((fd = rb_socket(family, SOCK_STREAM, 0, "ident")) == -1)
+       if((F = rb_socket(family, SOCK_STREAM, 0, "ident")) == NULL)
        {
-               report_error("creating auth stream socket %s:%s",
-                            get_client_name(auth->client, SHOW_IP), 
-                            log_client_name(auth->client, SHOW_IP), errno);
-               ++ServerStats->is_abad;
+               ilog_error("creating auth stream socket");
+               ++ServerStats.is_abad;
                return 0;
        }
 
        /*
         * TBD: this is a pointless arbitrary limit .. we either have a socket or not. -nenolod
         */
-       if((rb_get_maxconnections() - 10) < fd)
+       if((maxconnections - 10) < rb_get_fd(F))
        {
                sendto_realops_snomask(SNO_GENERAL, L_ALL,
                                     "Can't allocate fd for auth on %s",
                                     get_client_name(auth->client, SHOW_IP));
-               rb_close(fd);
+               rb_close(F);
                return 0;
        }
 
@@ -308,26 +331,43 @@ start_auth_query(struct AuthRequest *auth)
         * since the ident request must originate from that same address--
         * and machines with multiple IP addresses are common now
         */
-       memset(&localaddr, 0, locallen);
-       getsockname(auth->client->localClient->F->fd,
-                   (struct sockaddr *) &localaddr, &locallen);
+       localaddr = auth->client->preClient->lip;
        
-       mangle_mapped_sockaddr((struct sockaddr *)&localaddr);
-#ifdef IPV6
+       /* 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
+#endif
+       {
+               auth->rport = ntohs(((struct sockaddr_in *)&destaddr)->sin_port);
+               ((struct sockaddr_in *)&destaddr)->sin_port = htons(113);
+       }
        
-       auth->fd = fd;
+       auth->F = F;
        SetAuthConnect(auth);
 
-       rb_connect_tcp(fd, auth->client->sockhost, 113,
-                        (struct sockaddr *) &localaddr, GET_SS_LEN(localaddr),
+       rb_connect_tcp(F, (struct sockaddr *)&destaddr,
+                        (struct sockaddr *) &localaddr, GET_SS_LEN(&localaddr),
                         auth_connect_callback, auth, 
-                        localaddr.ss_family, GlobalSetOptions.ident_timeout);
+                        GlobalSetOptions.ident_timeout);
        return 1;               /* We suceed here for now */
 }
 
@@ -433,19 +473,19 @@ timeout_auth_queries_event(void *notused)
        rb_dlink_node *next_ptr;
        struct AuthRequest *auth;
 
-       DLINK_FOREACH_SAFE(ptr, next_ptr, auth_poll_list.head)
+       RB_DLINK_FOREACH_SAFE(ptr, next_ptr, auth_poll_list.head)
        {
                auth = ptr->data;
 
-               if(auth->timeout < CurrentTime)
+               if(auth->timeout < rb_current_time())
                {
-                       if(auth->fd >= 0)
-                               rb_close(auth->fd);
+                       if(auth->F != NULL)
+                               rb_close(auth->F);
 
                        if(IsDoingAuth(auth))
                        {
                                ClearAuth(auth);
-                               ++ServerStats->is_abad;
+                               ++ServerStats.is_abad;
                                sendheader(auth->client, REPORT_FAIL_ID);
                                auth->client->localClient->auth_request = NULL;
                        }
@@ -456,7 +496,7 @@ timeout_auth_queries_event(void *notused)
                                sendheader(auth->client, REPORT_FAIL_DNS);
                        }
 
-                       auth->client->localClient->lasttime = CurrentTime;
+                       auth->client->localClient->lasttime = rb_current_time();
                        release_auth_client(auth);
                }
        }
@@ -474,45 +514,30 @@ timeout_auth_queries_event(void *notused)
  * problems arise. -avalon
  */
 static void
-auth_connect_callback(int fd, int error, void *data)
+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);
 
        /* Check the error */
-       if(error != COMM_OK)
+       if(error != RB_OK)
        {
                /* We had an error during connection :( */
                auth_error(auth);
                return;
        }
 
-       if(getsockname
-          (auth->client->localClient->F->fd, (struct sockaddr *) &us,
-           (socklen_t *) & ulen)
-          || getpeername(auth->client->localClient->F->fd,
-                         (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);
 
-       if(write(auth->fd, authbuf, strlen(authbuf)) == -1)
+       if(rb_write(auth->F, authbuf, strlen(authbuf)) != strlen(authbuf))
        {
                auth_error(auth);
                return;
        }
        ClearAuthConnect(auth);
        SetAuthPending(auth);
-       read_auth_reply(auth->fd, auth);
+       read_auth_reply(auth->F, auth);
 }
 
 
@@ -525,7 +550,7 @@ auth_connect_callback(int fd, int error, void *data)
 #define AUTH_BUFSIZ 128
 
 static void
-read_auth_reply(int fd, void *data)
+read_auth_reply(rb_fde_t *F, void *data)
 {
        struct AuthRequest *auth = data;
        char *s = NULL;
@@ -534,11 +559,11 @@ read_auth_reply(int fd, void *data)
        int count;
        char buf[AUTH_BUFSIZ + 1];      /* buffer to read auth reply into */
 
-       len = read(auth->fd, buf, AUTH_BUFSIZ);
+       len = rb_read(F, buf, AUTH_BUFSIZ);
 
-       if(len < 0 && ignoreErrno(errno))
+       if(len < 0 && rb_ignore_errno(errno))
        {
-               rb_setselect(fd, FDLIST_IDLECLIENT, COMM_SELECT_READ, read_auth_reply, auth, 0);
+               rb_setselect(F, RB_SELECT_READ, read_auth_reply, auth);
                return;
        }
 
@@ -569,20 +594,20 @@ read_auth_reply(int fd, void *data)
                }
        }
 
-       rb_close(auth->fd);
-       auth->fd = -1;
+       rb_close(auth->F);
+       auth->F = NULL;
        ClearAuth(auth);
 
        if(s == NULL)
        {
-               ++ServerStats->is_abad;
+               ++ServerStats.is_abad;
                strcpy(auth->client->username, "unknown");
                sendheader(auth->client, REPORT_FAIL_ID);
        }
        else
        {
                sendheader(auth->client, REPORT_FIN_ID);
-               ++ServerStats->is_asuc;
+               ++ServerStats.is_asuc;
                SetGotId(auth->client);
        }
 
@@ -610,8 +635,8 @@ delete_auth_queries(struct Client *target_p)
        if(IsDNSPending(auth))
                delete_resolver_queries(&auth->dns_query);
 
-       if(auth->fd >= 0)
-               rb_close(auth->fd);
+       if(auth->F != NULL)
+               rb_close(auth->F);
                
        rb_dlinkDelete(&auth->node, &auth_poll_list);
        free_auth_request(auth);