/[svn]/branches/newio/src/s_auth.c
ViewVC logotype

Diff of /branches/newio/src/s_auth.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2407 by michael, Wed Jul 17 20:29:02 2013 UTC revision 2408 by michael, Thu Jul 18 19:57:58 2013 UTC
# Line 38  Line 38 
38  #include "stdinc.h"  #include "stdinc.h"
39  #include "list.h"  #include "list.h"
40  #include "ircd_defs.h"  #include "ircd_defs.h"
41    #include "ioengine.h"
42  #include "s_auth.h"  #include "s_auth.h"
43  #include "conf.h"  #include "conf.h"
44  #include "client.h"  #include "client.h"
 #include "ioengine.h"  
45  #include "hook.h"  #include "hook.h"
46  #include "irc_string.h"  #include "irc_string.h"
47  #include "ircd.h"  #include "ircd.h"
# Line 51  Line 51 
51  #include "log.h"  #include "log.h"
52  #include "send.h"  #include "send.h"
53  #include "mempool.h"  #include "mempool.h"
54    #include "memory.h"
55    #include "s_user.h"
56    
57    
58  static const char *HeaderMessages[] = {  static void auth_timeout_callback(struct Event *);
59    
60    static const char *HeaderMessages[] =
61    {
62    ":%s NOTICE AUTH :*** Looking up your hostname...",    ":%s NOTICE AUTH :*** Looking up your hostname...",
63    ":%s NOTICE AUTH :*** Found your hostname",    ":%s NOTICE AUTH :*** Found your hostname",
64    ":%s NOTICE AUTH :*** Couldn't look up your hostname",    ":%s NOTICE AUTH :*** Couldn't look up your hostname",
# Line 64  static const char *HeaderMessages[] = { Line 69  static const char *HeaderMessages[] = {
69    ":%s NOTICE AUTH :*** Invalid hostname"    ":%s NOTICE AUTH :*** Invalid hostname"
70  };  };
71    
72  enum {  enum
73    {
74    REPORT_DO_DNS,    REPORT_DO_DNS,
75    REPORT_FIN_DNS,    REPORT_FIN_DNS,
76    REPORT_FAIL_DNS,    REPORT_FAIL_DNS,
# Line 75  enum { Line 81  enum {
81    REPORT_INVAL_DNS    REPORT_INVAL_DNS
82  };  };
83    
84  #define sendheader(c, i) sendto_one((c), HeaderMessages[(i)], me.name)  #define sendheader(c, i)  sendto_one((c), HeaderMessages[(i)], me.name)
85    
86    
87  /** Timeout a given auth request.  /*
88   * @param ev A timer event whose associated data is the expired struct   * make_auth_request - allocate a new auth request
  * AuthRequest.  
89   */   */
90  static void  static struct AuthRequest *
91  auth_timeout_callback(struct Event *ev)  make_auth_request(struct Client *client)
92  {  {
93    struct AuthRequest *auth = NULL;    struct AuthRequest *auth = MyMalloc(sizeof(struct AuthRequest)); /* XXX MEMPOOL */
   
   assert(ev_timer(ev));  
   assert(t_data(ev_timer(ev)));  
94    
95    auth = t_data(ev_timer(ev));    auth->flags            = AM_TIMEOUT;
96      auth->fd               = -1;
97    if (ev_type(ev) == ET_DESTROY)    auth->client           = client;
98    {    client->localClient->auth = auth;
99      /* Being destroyed */    timer_add(timer_init(&auth->timeout), auth_timeout_callback, auth,
100      auth->flags &= ~AM_TIMEOUT;              TT_RELATIVE, CONNECTTIMEOUT);
101    
102      if (!(auth->flags & AM_FREE_MASK))    return auth;
     {  
       ilog(LOG_TYPE_DEBUG, "Freeing auth from timeout callback; %p [%p]", auth,  
            ev_timer(ev));  
       MyFree(auth);  /* Done with it, finally */  
     }  
   }  
   else  
   {  
     assert(ev_type(ev) == ET_EXPIRE);  
     destroy_auth_request(auth, 1);  
   }  
103  }  }
104    
105  /** Handle socket I/O activity.  /** Clean up auth request allocations (event loop objects, etc).
106   * @param ev A socket event whos associated data is the active struct   * @param auth The request to clean up.
  * AuthRequest.  
107   */   */
108  static void  static void
109  auth_socket_callback(struct Event *ev)  free_auth_request(struct AuthRequest *auth)
110  {  {
111    struct AuthRequest *auth = NULL;    if (auth->fd > -1)
   
   assert(ev_socket(ev));  
   assert(s_data(ev_socket(ev)));  
   
   auth = s_data(ev_socket(ev));  
   
   switch (ev_type(ev))  
112    {    {
113      case ET_DESTROY:  /* Being destroyed */      close(auth->fd);
114        auth->flags &= ~AM_SOCKET;      ilog(LOG_TYPE_DEBUG, "Deleting auth socket for %p", auth->client);
115        socket_del(&auth->socket);
       if (!(auth->flags & AM_FREE_MASK))  
       {  
         ilog(LOG_TYPE_DEBUG, "Freeing auth from sock callback; %p [%p]", auth,  
              ev_socket(ev));  
         MyFree(auth);  /* Done with it finally */  
       }  
   
       break;  
   
     case ET_CONNECT:  /* Socket connection completed */  
       ilog(LOG_TYPE_DEBUG, "Connection completed for auth %p [%p]; sending query",  
            auth, ev_socket(ev));  
       socket_state(&auth->socket, SS_CONNECTED);  
       send_auth_query(auth);  
       break;  
   
     case ET_READ:  /* Socket is readable */  
     case ET_EOF:  /* End of file on socket */  
     case ET_ERROR:  /* Error on socket */  
       ilog(LOG_TYPE_DEBUG, "Auth socket %p [%p] readable", auth, ev_socket(ev));  
       read_auth_reply(auth);  
       break;  
   
     default:  
       assert(0 && "Unrecognized event in auth_socket_callback().");  
       break;  
116    }    }
117    
118      ilog(LOG_TYPE_DEBUG, "Deleting auth timeout timer for %p", auth->client);
119      timer_del(&auth->timeout);
120  }  }
121    
122  /** Stop an auth request completely.  /** Stop an auth request completely.
# Line 199  destroy_auth_request(struct AuthRequest Line 159  destroy_auth_request(struct AuthRequest
159  }  }
160    
161  /*  /*
  * make_auth_request - allocate a new auth request  
  */  
 static struct AuthRequest *  
 make_auth_request(struct Client *client)  
 {  
   struct AuthRequest *request = MyMalloc(sizeof(struct AuthRequest)); /* XXX MEMPOOL */  
   
   request->flags            = AM_TIMEOUT;  
   request->fd               = -1;  
   request->client           = client;  
   client->localClient->auth = auth;  
   timer_add(timer_init(&auth->timeout), auth_timeout_callback, auth,  
             TT_RELATIVE, CONNECTTIMEOUT);  
   
   return request;  
 }  
   
 /** Clean up auth request allocations (event loop objects, etc).  
  * @param auth The request to clean up.  
  */  
 void  
 free_auth_request(struct AuthRequest *auth)  
 {  
   if (auth->fd > -1)  
   {  
     close(auth->fd);  
     ilog(LOG_TYPE_DEBUG, "Deleting auth socket for %p", auth->client);  
     socket_del(&auth->socket);  
   }  
   
   ilog(LOG_TYPE_DEBUG, "Deleting auth timeout timer for %p", auth->client);  
   timer_del(&auth->timeout);  
 }  
   
 /*  
162   * release_auth_client - release auth client from auth system   * release_auth_client - release auth client from auth system
163   * this adds the client into the local client lists so it can be read by   * this adds the client into the local client lists so it can be read by
164   * the main io processing loop   * the main io processing loop
# Line 359  start_auth_query(struct AuthRequest *aut Line 284  start_auth_query(struct AuthRequest *aut
284    socklen_t locallen = sizeof(struct irc_ssaddr);    socklen_t locallen = sizeof(struct irc_ssaddr);
285    struct sockaddr_in6 *v6;    struct sockaddr_in6 *v6;
286    
287    #ifdef XXX__
288    /* open a socket of the same type as the client socket */    /* open a socket of the same type as the client socket */
289    if (comm_open(&auth->fd, auth->client->localClient->ip.ss.ss_family,    if (comm_open(&auth->fd, auth->client->localClient->ip.ss.ss_family,
290                  SOCK_STREAM, 0, "ident") == -1)                  SOCK_STREAM, 0, "ident") == -1)
# Line 370  start_auth_query(struct AuthRequest *aut Line 296  start_auth_query(struct AuthRequest *aut
296      ++ServerStats.is_abad;      ++ServerStats.is_abad;
297      return 0;      return 0;
298    }    }
299    #endif
300    sendheader(auth->client, REPORT_DO_ID);    sendheader(auth->client, REPORT_DO_ID);
301    
302    /*    /*
# Line 381  start_auth_query(struct AuthRequest *aut Line 307  start_auth_query(struct AuthRequest *aut
307     * and machines with multiple IP addresses are common now     * and machines with multiple IP addresses are common now
308     */     */
309    memset(&localaddr, 0, locallen);    memset(&localaddr, 0, locallen);
310    getsockname(auth->client->localClient->fd.fd, (struct sockaddr*)&localaddr,    getsockname(s_fd(&auth->client->localClient->socket), (struct sockaddr *)&localaddr,
311        &locallen);        &locallen);
312    
313    remove_ipv6_mapping(&localaddr);    remove_ipv6_mapping(&localaddr);
# Line 389  start_auth_query(struct AuthRequest *aut Line 315  start_auth_query(struct AuthRequest *aut
315    v6->sin6_port = htons(0);    v6->sin6_port = htons(0);
316    localaddr.ss_port = htons(0);    localaddr.ss_port = htons(0);
317    
318    #ifdef XXX__
319    comm_connect_tcp(&auth->fd, auth->client->sockhost, 113,    comm_connect_tcp(&auth->fd, auth->client->sockhost, 113,
320        (struct sockaddr *)&localaddr, localaddr.ss_len, auth_connect_callback,        (struct sockaddr *)&localaddr, localaddr.ss_len, auth_connect_callback,
321        auth, auth->client->localClient->ip.ss.ss_family,        auth, auth->client->localClient->ip.ss.ss_family,
322        GlobalSetOptions.ident_timeout);        GlobalSetOptions.ident_timeout);
323    #endif
324    return 1; /* We suceed here for now */    return 1; /* We suceed here for now */
325  }  }
326    
# Line 522  start_auth(struct Client *client) Line 450  start_auth(struct Client *client)
450    }    }
451  }  }
452    
453  /*  /** Send the ident server a query giving "theirport , ourport". The
454   * auth_connect_callback() - deal with the result of comm_connect_tcp()   * write is only attempted *once* so it is deemed to be a fail if the
455   *   * entire write doesn't write all the data given.  This shouldn't be a
456   * If the connection failed, we simply close the auth fd and report   * problem since the socket should have a write buffer far greater
457   * a failure. If the connection suceeded send the ident server a query   * than this message to store it in should problems arise. -avalon
458   * giving "theirport , ourport". The write is only attempted *once* so   * @param auth The request to send.
  * it is deemed to be a fail if the entire write doesn't write all the  
  * data given.  This shouldnt be a problem since the socket should have  
  * a write buffer far greater than this message to store it in should  
  * problems arise. -avalon  
459   */   */
460  static void  static void
461  auth_connect_callback(fde_t *fd, int error, void *data)  send_auth_query(struct AuthRequest *auth)
462  {  {
   struct AuthRequest *auth = data;  
463    struct irc_ssaddr us;    struct irc_ssaddr us;
464    struct irc_ssaddr them;    struct irc_ssaddr them;
465    char authbuf[32];    char authbuf[32];
# Line 544  auth_connect_callback(fde_t *fd, int err Line 467  auth_connect_callback(fde_t *fd, int err
467    socklen_t tlen = sizeof(struct irc_ssaddr);    socklen_t tlen = sizeof(struct irc_ssaddr);
468    uint16_t uport, tport;    uint16_t uport, tport;
469    struct sockaddr_in6 *v6;    struct sockaddr_in6 *v6;
470      unsigned int count = 0;
471    
472    if (error != COMM_OK)    if (getsockname(s_fd(&auth->client->localClient->socket), (struct sockaddr *)&us, &ulen) ||
473    {        getpeername(s_fd(&auth->client->localClient->socket), (struct sockaddr *)&them, &tlen))
     auth_error(auth);  
     return;  
   }  
   
   if (getsockname(auth->client->localClient->fd.fd, (struct sockaddr *)&us,  
       &ulen) ||  
       getpeername(auth->client->localClient->fd.fd, (struct sockaddr *)&them,  
       &tlen))  
474    {    {
475      ilog(LOG_TYPE_IRCD, "auth get{sock,peer}name error for %s",      ilog(LOG_TYPE_IRCD, "auth get{sock,peer}name error for %s",
476          get_client_name(auth->client, SHOW_IP));          get_client_name(auth->client, SHOW_IP));
# Line 573  auth_connect_callback(fde_t *fd, int err Line 489  auth_connect_callback(fde_t *fd, int err
489        
490    snprintf(authbuf, sizeof(authbuf), "%u , %u\r\n", tport, uport);    snprintf(authbuf, sizeof(authbuf), "%u , %u\r\n", tport, uport);
491    
492    if (send(fd->fd, authbuf, strlen(authbuf), 0) == -1)    if (os_send_nonb(auth->fd, authbuf, strlen(authbuf), &count) == IO_SUCCESS)
493    {    {
494      auth_error(auth);      ClearAuthConnect(auth);
495      return;      SetAuthPending(auth);
496    }    }
497      else
498    read_auth_reply(&auth->fd, auth);      auth_error(auth);
499  }  }
500    
501  /** Read the reply (if any) from the ident server we connected to.  We  /** Read the reply (if any) from the ident server we connected to.  We
# Line 619  read_auth_reply(struct AuthRequest *auth Line 535  read_auth_reply(struct AuthRequest *auth
535    {    {
536      strlcpy(auth->client->username, username, sizeof(auth->client->username));      strlcpy(auth->client->username, username, sizeof(auth->client->username));
537      SetGotId(auth->client);      SetGotId(auth->client);
538      ++ServerStats->is_asuc;      ++ServerStats.is_asuc;
539    
540      sendheader(auth->client, REPORT_FIN_ID);      sendheader(auth->client, REPORT_FIN_ID);
541    }    }
542    else    else
543    {    {
544      ++ServerStats->is_abad;      ++ServerStats.is_abad;
545      sendheader(auth->client, REPORT_FAIL_ID);      sendheader(auth->client, REPORT_FAIL_ID);
546    }    }
547    
# Line 635  read_auth_reply(struct AuthRequest *auth Line 551  read_auth_reply(struct AuthRequest *auth
551      free_auth_request(auth);      free_auth_request(auth);
552    }    }
553  }  }
554    
555    /** Timeout a given auth request.
556     * @param ev A timer event whose associated data is the expired struct
557     * AuthRequest.
558     */
559    static void
560    auth_timeout_callback(struct Event *ev)
561    {
562      struct AuthRequest *auth = NULL;
563    
564      assert(ev_timer(ev));
565      assert(t_data(ev_timer(ev)));
566    
567      auth = t_data(ev_timer(ev));
568    
569      if (ev_type(ev) == ET_DESTROY)
570      {
571        /* Being destroyed */
572        auth->flags &= ~AM_TIMEOUT;
573    
574        if (!(auth->flags & AM_FREE_MASK))
575        {
576          ilog(LOG_TYPE_DEBUG, "Freeing auth from timeout callback; %p [%p]", auth,
577               ev_timer(ev));
578          MyFree(auth);  /* Done with it, finally */
579        }
580      }
581      else
582      {
583        assert(ev_type(ev) == ET_EXPIRE);
584        destroy_auth_request(auth, 1);
585      }
586    }
587    
588    /** Handle socket I/O activity.
589     * @param ev A socket event whos associated data is the active struct
590     * AuthRequest.
591     */
592    static void
593    auth_socket_callback(struct Event *ev)
594    {
595      struct AuthRequest *auth = NULL;
596    
597      assert(ev_socket(ev));
598      assert(s_data(ev_socket(ev)));
599    
600      auth = s_data(ev_socket(ev));
601    
602      switch (ev_type(ev))
603      {
604        case ET_DESTROY:  /* Being destroyed */
605          auth->flags &= ~AM_SOCKET;
606    
607          if (!(auth->flags & AM_FREE_MASK))
608          {
609            ilog(LOG_TYPE_DEBUG, "Freeing auth from sock callback; %p [%p]", auth,
610                 ev_socket(ev));
611            MyFree(auth);  /* Done with it finally */
612          }
613    
614          break;
615    
616        case ET_CONNECT:  /* Socket connection completed */
617          ilog(LOG_TYPE_DEBUG, "Connection completed for auth %p [%p]; sending query",
618               auth, ev_socket(ev));
619          socket_state(&auth->socket, SS_CONNECTED);
620          send_auth_query(auth);
621          break;
622    
623        case ET_READ:  /* Socket is readable */
624        case ET_EOF:  /* End of file on socket */
625        case ET_ERROR:  /* Error on socket */
626          ilog(LOG_TYPE_DEBUG, "Auth socket %p [%p] readable", auth, ev_socket(ev));
627          read_auth_reply(auth);
628          break;
629    
630        default:
631          assert(0 && "Unrecognized event in auth_socket_callback().");
632          break;
633      }
634    }

Legend:
Removed from v.2407  
changed lines
  Added in v.2408

svnadmin@ircd-hybrid.org
ViewVC Help
Powered by ViewVC 1.1.28