ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/s_auth.c
(Generate patch)

Comparing:
ircd-hybrid-7.2/src/s_auth.c (file contents), Revision 896 by michael, Sat Nov 3 08:54:09 2007 UTC vs.
ircd-hybrid/trunk/src/s_auth.c (file contents), Revision 1654 by michael, Fri Nov 16 19:39:37 2012 UTC

# Line 32 | Line 32
32   *     any messages from it.
33   *     --Bleep  Thomas Helvey <tomh@inxpress.net>
34   */
35 +
36   #include "stdinc.h"
36 #include "tools.h"
37   #include "list.h"
38 + #include "ircd_defs.h"
39 + #include "fdlist.h"
40   #include "s_auth.h"
41 < #include "s_conf.h"
41 > #include "conf.h"
42   #include "client.h"
41 #include "common.h"
43   #include "event.h"
43 #include "fdlist.h"              /* fdlist_add */
44   #include "hook.h"
45   #include "irc_string.h"
46 #include "sprintf_irc.h"
46   #include "ircd.h"
48 #include "numeric.h"
47   #include "packet.h"
48   #include "irc_res.h"
49   #include "s_bsd.h"
50 < #include "s_log.h"
50 > #include "log.h"
51   #include "send.h"
52 < #include "memory.h"
52 > #include "mempool.h"
53 >
54  
55   static const char *HeaderMessages[] = {
56    ":%s NOTICE AUTH :*** Looking up your hostname...",
# Line 77 | Line 76 | enum {
76  
77   #define sendheader(c, i) sendto_one((c), HeaderMessages[(i)], me.name)
78  
79 < /*
80 < * Ok, the original was confusing.
82 < * Now there are two lists, an auth request can be on both at the same time
83 < * or only on one or the other.
84 < * - Dianora
85 < */
86 < static dlink_list auth_doing_dns_list   = { NULL, NULL, 0 };
87 < static dlink_list auth_doing_ident_list = { NULL, NULL, 0 };
79 > static mp_pool_t *auth_pool = NULL;
80 > static dlink_list auth_doing_list = { NULL, NULL, 0 };
81  
82   static EVH timeout_auth_queries_event;
83  
# Line 101 | Line 94 | struct Callback *auth_cb = NULL;
94   void
95   init_auth(void)
96   {
97 +  auth_pool = mp_pool_new(sizeof(struct AuthRequest), MP_CHUNK_SIZE_AUTH);
98    auth_cb = register_callback("start_auth", start_auth);
99    eventAddIsh("timeout_auth_queries_event", timeout_auth_queries_event, NULL, 1);
100   }
# Line 111 | Line 105 | init_auth(void)
105   static struct AuthRequest *
106   make_auth_request(struct Client *client)
107   {
108 <  struct AuthRequest *request = MyMalloc(sizeof(struct AuthRequest));
108 >  struct AuthRequest *request = mp_pool_get(auth_pool);
109  
110 <  request->client  = client;
111 <  request->timeout = CurrentTime + CONNECTTIMEOUT;
110 >  memset(request, 0, sizeof(*request));
111 >  client->localClient->auth = request;
112 >  request->client           = client;
113 >  request->timeout          = CurrentTime + CONNECTTIMEOUT;
114  
115    return request;
116   }
# Line 125 | Line 121 | make_auth_request(struct Client *client)
121   * the main io processing loop
122   */
123   void
124 < release_auth_client(struct Client *client)
124 > release_auth_client(struct AuthRequest *auth)
125   {
126 +  struct Client *client = auth->client;
127 +
128 +  if (IsDoingAuth(auth) || IsDNSPending(auth))
129 +    return;
130 +
131 +  client->localClient->auth = NULL;
132 +  dlinkDelete(&auth->node, &auth_doing_list);
133 +  mp_pool_release(auth);
134 +
135    /*
136     * When a client has auth'ed, we want to start reading what it sends
137     * us. This is what read_packet() does.
# Line 135 | Line 140 | release_auth_client(struct Client *clien
140    client->localClient->allow_read = MAX_FLOOD;
141    comm_setflush(&client->localClient->fd, 1000, flood_recalc, client);
142  
143 <  if ((client->node.prev != NULL) || (client->node.next != NULL))
139 <  {
140 <    sendto_realops_flags(UMODE_ALL, L_OPER,
141 <                         "already linked %s at %s:%d", client->name,
142 <                         __FILE__, __LINE__);
143 <    ilog(L_ERROR, "already linked %s at %s:%d", client->name,
144 <         __FILE__, __LINE__);
145 <    assert(0==5);
146 <  }
147 <  else
148 <    dlinkAdd(client, &client->node, &global_client_list);
143 >  dlinkAdd(client, &client->node, &global_client_list);
144  
145 <  client->since  = client->lasttime = client->firsttime = CurrentTime;
145 >  client->localClient->since     = CurrentTime;
146 >  client->localClient->lasttime  = CurrentTime;
147 >  client->localClient->firsttime = CurrentTime;
148    client->flags |= FLAGS_FINISHED_AUTH;
149  
150    read_packet(&client->localClient->fd, client);
# Line 155 | Line 152 | release_auth_client(struct Client *clien
152  
153   /*
154   * auth_dns_callback - called when resolver query finishes
155 < * if the query resulted in a successful search, hp will contain
156 < * a non-null pointer, otherwise hp will be null.
155 > * if the query resulted in a successful search, name will contain
156 > * a non-NULL pointer, otherwise name will be NULL.
157   * set the client on it's way to a connection completion, regardless
158   * of success of failure
159   */
160   static void
161 < auth_dns_callback(void *vptr, struct DNSReply *reply)
161 > auth_dns_callback(void *vptr, const struct irc_ssaddr *addr, const char *name)
162   {
163 <  struct AuthRequest *auth = (struct AuthRequest *)vptr;
163 >  struct AuthRequest *auth = vptr;
164  
168  dlinkDelete(&auth->dns_node, &auth_doing_dns_list);
165    ClearDNSPending(auth);
166  
167 <  if (reply != NULL)
167 >  if (name != NULL)
168    {
169 <    struct sockaddr_in *v4, *v4dns;
169 >    const struct sockaddr_in *v4, *v4dns;
170   #ifdef IPV6
171 <    struct sockaddr_in6 *v6, *v6dns;
171 >    const struct sockaddr_in6 *v6, *v6dns;
172   #endif
173      int good = 1;
174  
175   #ifdef IPV6
176      if (auth->client->localClient->ip.ss.ss_family == AF_INET6)
177      {
178 <      v6 = (struct sockaddr_in6 *)&auth->client->localClient->ip;
179 <      v6dns = (struct sockaddr_in6 *)&reply->addr;
178 >      v6 = (const struct sockaddr_in6 *)&auth->client->localClient->ip;
179 >      v6dns = (const struct sockaddr_in6 *)addr;
180        if (memcmp(&v6->sin6_addr, &v6dns->sin6_addr, sizeof(struct in6_addr)) != 0)
181        {
182          sendheader(auth->client, REPORT_IP_MISMATCH);
# Line 190 | Line 186 | auth_dns_callback(void *vptr, struct DNS
186      else
187   #endif
188      {
189 <      v4 = (struct sockaddr_in *)&auth->client->localClient->ip;
190 <      v4dns = (struct sockaddr_in *)&reply->addr;
189 >      v4 = (const struct sockaddr_in *)&auth->client->localClient->ip;
190 >      v4dns = (const struct sockaddr_in *)addr;
191        if(v4->sin_addr.s_addr != v4dns->sin_addr.s_addr)
192        {
193          sendheader(auth->client, REPORT_IP_MISMATCH);
194          good = 0;
195        }
196      }
197 <    if (good && strlen(reply->h_name) <= HOSTLEN)
197 >    if (good && strlen(name) <= HOSTLEN)
198      {
199 <      strlcpy(auth->client->host, reply->h_name,
199 >      strlcpy(auth->client->host, name,
200                sizeof(auth->client->host));
201        sendheader(auth->client, REPORT_FIN_DNS);
202      }
203 <    else if (strlen(reply->h_name) > HOSTLEN)
203 >    else if (strlen(name) > HOSTLEN)
204        sendheader(auth->client, REPORT_HOST_TOOLONG);
205    }
206    else
207 <      sendheader(auth->client, REPORT_FAIL_DNS);
212 <
213 <  MyFree(auth->client->localClient->dns_query);
214 <  auth->client->localClient->dns_query = NULL;
207 >    sendheader(auth->client, REPORT_FAIL_DNS);
208  
209 <  if (!IsDoingAuth(auth))
217 <  {
218 <    struct Client *client_p = auth->client;
219 <    MyFree(auth);
220 <    release_auth_client(client_p);
221 <  }
209 >  release_auth_client(auth);
210   }
211  
212   /*
# Line 231 | Line 219 | auth_error(struct AuthRequest *auth)
219  
220    fd_close(&auth->fd);
221  
234  dlinkDelete(&auth->ident_node, &auth_doing_ident_list);
222    ClearAuth(auth);
223  
224    sendheader(auth->client, REPORT_FAIL_ID);
225  
226 <  if (!IsDNSPending(auth) && !IsCrit(auth))
240 <  {
241 <    release_auth_client(auth->client);
242 <    MyFree(auth);
243 <  }
226 >  release_auth_client(auth);
227   }
228  
229   /*
# Line 268 | Line 251 | start_auth_query(struct AuthRequest *aut
251    {
252      report_error(L_ALL, "creating auth stream socket %s:%s",
253          get_client_name(auth->client, SHOW_IP), errno);
254 <    ilog(L_ERROR, "Unable to create auth socket for %s",
254 >    ilog(LOG_TYPE_IRCD, "Unable to create auth socket for %s",
255          get_client_name(auth->client, SHOW_IP));
256      ++ServerStats.is_abad;
257      return 0;
# Line 298 | Line 281 | start_auth_query(struct AuthRequest *aut
281   #endif
282    localaddr.ss_port = htons(0);
283  
301  SetDoingAuth(auth);
302  dlinkAdd(auth, &auth->ident_node, &auth_doing_ident_list);
303
284    comm_connect_tcp(&auth->fd, auth->client->sockhost, 113,
285        (struct sockaddr *)&localaddr, localaddr.ss_len, auth_connect_callback,
286        auth, auth->client->localClient->ip.ss.ss_family,
# Line 392 | Line 372 | start_auth(va_list args)
372    assert(client != NULL);
373  
374    auth = make_auth_request(client);
375 <  SetCrit(auth);
396 <
397 <  client->localClient->dns_query = MyMalloc(sizeof(struct DNSQuery));
398 <  client->localClient->dns_query->ptr = auth;
399 <  client->localClient->dns_query->callback = auth_dns_callback;
375 >  dlinkAdd(auth, &auth->node, &auth_doing_list);
376  
377    sendheader(client, REPORT_DO_DNS);
378  
379 +  SetDNSPending(auth);
380 +
381    if (ConfigFileEntry.disable_auth == 0)
382 +  {
383 +    SetDoingAuth(auth);
384      start_auth_query(auth);
385 +  }
386  
387 <  /* auth order changed, before gethost_byaddr can immediately call
407 <   * dns callback under win32 when the lookup cannot be started.
408 <   * And that would do MyFree(auth) etc -adx */
409 <  SetDNSPending(auth);
410 <  dlinkAdd(auth, &auth->dns_node, &auth_doing_dns_list);
411 <  ClearCrit(auth);
412 <  gethost_byaddr(&client->localClient->ip, client->localClient->dns_query);
387 >  gethost_byaddr(auth_dns_callback, auth, &client->localClient->ip);
388  
389    return NULL;
390   }
# Line 421 | Line 396 | start_auth(va_list args)
396   static void
397   timeout_auth_queries_event(void *notused)
398   {
399 <  dlink_node *ptr;
425 <  dlink_node *next_ptr;
426 <  struct AuthRequest* auth;
399 >  dlink_node *ptr = NULL, *next_ptr = NULL;
400  
401 <  DLINK_FOREACH_SAFE(ptr, next_ptr, auth_doing_ident_list.head)
401 >  DLINK_FOREACH_SAFE(ptr, next_ptr, auth_doing_list.head)
402    {
403 <    auth = ptr->data;
403 >    struct AuthRequest *auth = ptr->data;
404  
405 <    if (auth->timeout <= CurrentTime)
406 <    {
434 <      fd_close(&auth->fd);
405 >    if (auth->timeout > CurrentTime)
406 >      continue;
407  
408 +    if (IsDoingAuth(auth))
409 +    {  
410        ++ServerStats.is_abad;
411 +      fd_close(&auth->fd);
412 +      ClearAuth(auth);
413        sendheader(auth->client, REPORT_FAIL_ID);
414 +    }
415  
416 <      if (IsDNSPending(auth))
417 <      {
418 <        struct Client *client_p = auth->client;
419 <
420 <        dlinkDelete(&auth->dns_node, &auth_doing_dns_list);
444 <        if (client_p->localClient->dns_query != NULL)
445 <        {
446 <          delete_resolver_queries(client_p->localClient->dns_query);
447 <          MyFree(client_p->localClient->dns_query);
448 <        }
449 <        auth->client->localClient->dns_query = NULL;
450 <        sendheader(client_p, REPORT_FAIL_DNS);
451 <      }
452 <
453 <      ilog(L_INFO, "DNS/AUTH timeout %s",
454 <           get_client_name(auth->client, SHOW_IP));
455 <
456 <      dlinkDelete(&auth->ident_node, &auth_doing_ident_list);
457 <      release_auth_client(auth->client);
458 <      MyFree(auth);
416 >    if (IsDNSPending(auth))
417 >    {
418 >      delete_resolver_queries(auth);
419 >      ClearDNSPending(auth);
420 >      sendheader(auth->client, REPORT_FAIL_DNS);
421      }
422 +
423 +    ilog(LOG_TYPE_IRCD, "DNS/AUTH timeout %s",
424 +         get_client_name(auth->client, SHOW_IP));
425 +    release_auth_client(auth);
426    }
427   }
428  
# Line 480 | Line 446 | auth_connect_callback(fde_t *fd, int err
446    char authbuf[32];
447    socklen_t ulen = sizeof(struct irc_ssaddr);
448    socklen_t tlen = sizeof(struct irc_ssaddr);
449 <  u_int16_t uport, tport;
449 >  uint16_t uport, tport;
450   #ifdef IPV6
451    struct sockaddr_in6 *v6;
452   #else
# Line 493 | Line 459 | auth_connect_callback(fde_t *fd, int err
459      return;
460    }
461  
462 <  if (getsockname(auth->client->localClient->fd.fd, (struct sockaddr *) &us,
463 <      (socklen_t *) &ulen) ||
464 <      getpeername(auth->client->localClient->fd.fd, (struct sockaddr *) &them,
465 <      (socklen_t *) &tlen))
462 >  if (getsockname(auth->client->localClient->fd.fd, (struct sockaddr *)&us,
463 >      &ulen) ||
464 >      getpeername(auth->client->localClient->fd.fd, (struct sockaddr *)&them,
465 >      &tlen))
466    {
467 <    ilog(L_INFO, "auth get{sock,peer}name error for %s",
467 >    ilog(LOG_TYPE_IRCD, "auth get{sock,peer}name error for %s",
468          get_client_name(auth->client, SHOW_IP));
469      auth_error(auth);
470      return;
# Line 520 | Line 486 | auth_connect_callback(fde_t *fd, int err
486    them.ss_len = tlen;
487   #endif
488    
489 <  ircsprintf(authbuf, "%u , %u\r\n", tport, uport);
489 >  snprintf(authbuf, sizeof(authbuf), "%u , %u\r\n", tport, uport);
490  
491    if (send(fd->fd, authbuf, strlen(authbuf), 0) == -1)
492    {
# Line 560 | Line 526 | read_auth_reply(fde_t *fd, void *data)
526     *
527     *    --nenolod
528     */
563 #ifndef _WIN32
529    len = read(fd->fd, buf, AUTH_BUFSIZ);
530 < #else
566 <  len = recv(fd->fd, buf, AUTH_BUFSIZ, 0);
567 < #endif
568 <  
530 >
531    if (len < 0)
532    {
571 #ifdef _WIN32
572    errno = WSAGetLastError();
573 #endif
533      if (ignoreErrno(errno))
534        comm_setselect(fd, COMM_SELECT_READ, read_auth_reply, auth, 0);
535      else
# Line 606 | Line 565 | read_auth_reply(fde_t *fd, void *data)
565  
566    fd_close(fd);
567  
609  dlinkDelete(&auth->ident_node, &auth_doing_ident_list);  
568    ClearAuth(auth);
569  
570    if (s == NULL)
# Line 621 | Line 579 | read_auth_reply(fde_t *fd, void *data)
579      SetGotId(auth->client);
580    }
581  
582 <  if (!IsDNSPending(auth) && !IsCrit(auth))
625 <  {
626 <    release_auth_client(auth->client);
627 <    MyFree(auth);
628 <  }
582 >  release_auth_client(auth);
583   }
584  
585   /*
586   * delete_auth()
587   */
588   void
589 < delete_auth(struct Client *target_p)
589 > delete_auth(struct AuthRequest *auth)
590   {
591 <  dlink_node *ptr;
592 <  dlink_node *next_ptr;
639 <  struct AuthRequest *auth;
640 <
641 <  if (!IsUnknown(target_p))
642 <    return;
591 >  if (IsDNSPending(auth))
592 >    delete_resolver_queries(auth);
593  
594 <  if (target_p->localClient->dns_query != NULL)
595 <    DLINK_FOREACH_SAFE(ptr, next_ptr, auth_doing_dns_list.head)
646 <    {
647 <      auth = ptr->data;
648 <
649 <      if (auth->client == target_p)
650 <      {
651 <        delete_resolver_queries(target_p->localClient->dns_query);
652 <        MyFree(target_p->localClient->dns_query);
653 <        target_p->localClient->dns_query = NULL;
654 <
655 <        dlinkDelete(&auth->dns_node, &auth_doing_dns_list);
656 <
657 <        if (!IsDoingAuth(auth))
658 <        {
659 <          MyFree(auth);
660 <          return;
661 <        }
662 <      }
663 <    }
664 <
665 <  DLINK_FOREACH_SAFE(ptr, next_ptr, auth_doing_ident_list.head)
666 <  {
667 <    auth = ptr->data;
668 <
669 <    if (auth->client == target_p)
670 <    {
671 <      fd_close(&auth->fd);
594 >  if (IsDoingAuth(auth))
595 >    fd_close(&auth->fd);
596  
597 <      dlinkDelete(&auth->ident_node, &auth_doing_ident_list);
598 <      MyFree(auth);
675 <    }
676 <  }
597 >  dlinkDelete(&auth->node, &auth_doing_list);
598 >  mp_pool_release(auth);
599   }

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)