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 650 by michael, Thu Jun 8 07:00:17 2006 UTC vs.
ircd-hybrid-8/src/s_auth.c (file contents), Revision 1247 by michael, Sat Oct 1 07:54:24 2011 UTC

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

Diff Legend

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