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

Comparing:
ircd-hybrid-7.2/src/s_auth.c (file contents), Revision 397 by nenolod, Fri Feb 3 22:08:10 2006 UTC vs.
ircd-hybrid-8/src/s_auth.c (file contents), Revision 1309 by michael, Sun Mar 25 11:24:18 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 "balloc.h"
43   #include "client.h"
41 #include "common.h"
44   #include "event.h"
43 #include "fdlist.h"              /* fdlist_add */
45   #include "hook.h"
46   #include "irc_string.h"
46 #include "sprintf_irc.h"
47   #include "ircd.h"
48 #include "numeric.h"
48   #include "packet.h"
49   #include "irc_res.h"
50   #include "s_bsd.h"
51 < #include "s_log.h"
53 < #include "s_stats.h"
51 > #include "log.h"
52   #include "send.h"
53 < #include "memory.h"
53 >
54  
55   static const char *HeaderMessages[] = {
56    ":%s NOTICE AUTH :*** Looking up your hostname...",
# Line 78 | Line 76 | enum {
76  
77   #define sendheader(c, i) sendto_one((c), HeaderMessages[(i)], me.name)
78  
79 < /*
80 < * 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 };
79 > static BlockHeap *auth_heap = NULL;
80 > static dlink_list auth_doing_list = { NULL, NULL, 0 };
81  
82   static EVH timeout_auth_queries_event;
83  
# Line 102 | Line 94 | struct Callback *auth_cb = NULL;
94   void
95   init_auth(void)
96   {
97 +  auth_heap = BlockHeapCreate("auth", sizeof(struct AuthRequest), AUTH_HEAP_SIZE);
98    auth_cb = register_callback("start_auth", start_auth);
99    eventAddIsh("timeout_auth_queries_event", timeout_auth_queries_event, NULL, 1);
100   }
# Line 112 | 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 = BlockHeapAlloc(auth_heap);
109  
110 <  request->client  = client;
111 <  request->timeout = CurrentTime + CONNECTTIMEOUT;
110 >  client->localClient->auth = request;
111 >  request->client           = client;
112 >  request->timeout          = CurrentTime + CONNECTTIMEOUT;
113  
114 <  return (request);
114 >  return request;
115   }
116  
117   /*
# Line 126 | Line 120 | make_auth_request(struct Client *client)
120   * the main io processing loop
121   */
122   void
123 < release_auth_client(struct Client *client)
123 > release_auth_client(struct AuthRequest *auth)
124   {
125 +  struct Client *client = auth->client;
126 +
127 +  if (IsDoingAuth(auth) || IsDNSPending(auth))
128 +    return;
129 +
130 +  client->localClient->auth = NULL;
131 +  dlinkDelete(&auth->node, &auth_doing_list);
132 +  BlockHeapFree(auth_heap, auth);
133 +
134    /*
135     * When a client has auth'ed, we want to start reading what it sends
136     * us. This is what read_packet() does.
# Line 135 | Line 138 | release_auth_client(struct Client *clien
138     */
139    client->localClient->allow_read = MAX_FLOOD;
140    comm_setflush(&client->localClient->fd, 1000, flood_recalc, client);
141 <  if ((client->node.prev != NULL) || (client->node.next != NULL))
142 <  {
143 <    sendto_realops_flags(UMODE_ALL, L_OPER,
144 <                         "already linked %s at %s:%d", client->name,
145 <                         __FILE__, __LINE__);
146 <    ilog(L_ERROR, "already linked %s at %s:%d", client->name,
147 <         __FILE__, __LINE__);
148 <    assert(0==5);
146 <  }
147 <  else
148 <    dlinkAdd(client, &client->node, &global_client_list);
141 >
142 >  dlinkAdd(client, &client->node, &global_client_list);
143 >
144 >  client->localClient->since     = CurrentTime;
145 >  client->localClient->lasttime  = CurrentTime;
146 >  client->localClient->firsttime = CurrentTime;
147 >  client->flags |= FLAGS_FINISHED_AUTH;
148 >
149    read_packet(&client->localClient->fd, client);
150   }
151  
152   /*
153   * auth_dns_callback - called when resolver query finishes
154 < * if the query resulted in a successful search, hp will contain
155 < * a non-null pointer, otherwise hp will be null.
154 > * if the query resulted in a successful search, name will contain
155 > * a non-NULL pointer, otherwise name will be NULL.
156   * set the client on it's way to a connection completion, regardless
157   * of success of failure
158   */
159   static void
160 < auth_dns_callback(void *vptr, struct DNSReply *reply)
160 > auth_dns_callback(void *vptr, const struct irc_ssaddr *addr, const char *name)
161   {
162 <  struct AuthRequest *auth = (struct AuthRequest *)vptr;
162 >  struct AuthRequest *auth = vptr;
163  
164  dlinkDelete(&auth->dns_node, &auth_doing_dns_list);
164    ClearDNSPending(auth);
165  
166 <  if (reply != NULL)
166 >  if (name != NULL)
167    {
168 <    struct sockaddr_in *v4, *v4dns;
168 >    const struct sockaddr_in *v4, *v4dns;
169   #ifdef IPV6
170 <    struct sockaddr_in6 *v6, *v6dns;
170 >    const struct sockaddr_in6 *v6, *v6dns;
171   #endif
172      int good = 1;
173  
174   #ifdef IPV6
175      if (auth->client->localClient->ip.ss.ss_family == AF_INET6)
176      {
177 <      v6 = (struct sockaddr_in6 *)&auth->client->localClient->ip;
178 <      v6dns = (struct sockaddr_in6 *)&reply->addr;
177 >      v6 = (const struct sockaddr_in6 *)&auth->client->localClient->ip;
178 >      v6dns = (const struct sockaddr_in6 *)addr;
179        if (memcmp(&v6->sin6_addr, &v6dns->sin6_addr, sizeof(struct in6_addr)) != 0)
180        {
181          sendheader(auth->client, REPORT_IP_MISMATCH);
# Line 186 | Line 185 | auth_dns_callback(void *vptr, struct DNS
185      else
186   #endif
187      {
188 <      v4 = (struct sockaddr_in *)&auth->client->localClient->ip;
189 <      v4dns = (struct sockaddr_in *)&reply->addr;
188 >      v4 = (const struct sockaddr_in *)&auth->client->localClient->ip;
189 >      v4dns = (const struct sockaddr_in *)addr;
190        if(v4->sin_addr.s_addr != v4dns->sin_addr.s_addr)
191        {
192          sendheader(auth->client, REPORT_IP_MISMATCH);
193          good = 0;
194        }
195      }
196 <    if (good && strlen(reply->h_name) <= HOSTLEN)
196 >    if (good && strlen(name) <= HOSTLEN)
197      {
198 <      strlcpy(auth->client->host, reply->h_name,
198 >      strlcpy(auth->client->host, name,
199                sizeof(auth->client->host));
200        sendheader(auth->client, REPORT_FIN_DNS);
201      }
202 <    else if (strlen(reply->h_name) > HOSTLEN)
202 >    else if (strlen(name) > HOSTLEN)
203        sendheader(auth->client, REPORT_HOST_TOOLONG);
204    }
205    else
206 <      sendheader(auth->client, REPORT_FAIL_DNS);
208 <
209 <  MyFree(auth->client->localClient->dns_query);
210 <  auth->client->localClient->dns_query = NULL;
206 >    sendheader(auth->client, REPORT_FAIL_DNS);
207  
208 <  if (!IsDoingAuth(auth))
213 <  {
214 <    struct Client *client_p = auth->client;
215 <    MyFree(auth);
216 <    release_auth_client(client_p);
217 <  }
208 >  release_auth_client(auth);
209   }
210  
211   /*
# Line 223 | Line 214 | auth_dns_callback(void *vptr, struct DNS
214   static void
215   auth_error(struct AuthRequest *auth)
216   {
217 <  ++ServerStats->is_abad;
217 >  ++ServerStats.is_abad;
218  
219    fd_close(&auth->fd);
220  
230  dlinkDelete(&auth->ident_node, &auth_doing_ident_list);
221    ClearAuth(auth);
222  
223    sendheader(auth->client, REPORT_FAIL_ID);
224  
225 <  if (!IsDNSPending(auth) && !IsCrit(auth))
236 <  {
237 <    release_auth_client(auth->client);
238 <    MyFree(auth);
239 <  }
225 >  release_auth_client(auth);
226   }
227  
228   /*
# Line 264 | Line 250 | start_auth_query(struct AuthRequest *aut
250    {
251      report_error(L_ALL, "creating auth stream socket %s:%s",
252          get_client_name(auth->client, SHOW_IP), errno);
253 <    ilog(L_ERROR, "Unable to create auth socket for %s",
253 >    ilog(LOG_TYPE_IRCD, "Unable to create auth socket for %s",
254          get_client_name(auth->client, SHOW_IP));
255 <    ++ServerStats->is_abad;
255 >    ++ServerStats.is_abad;
256      return 0;
257    }
258  
# Line 294 | Line 280 | start_auth_query(struct AuthRequest *aut
280   #endif
281    localaddr.ss_port = htons(0);
282  
297  SetDoingAuth(auth);
298  dlinkAdd(auth, &auth->ident_node, &auth_doing_ident_list);
299
283    comm_connect_tcp(&auth->fd, auth->client->sockhost, 113,
284        (struct sockaddr *)&localaddr, localaddr.ss_len, auth_connect_callback,
285        auth, auth->client->localClient->ip.ss.ss_family,
# Line 388 | Line 371 | start_auth(va_list args)
371    assert(client != NULL);
372  
373    auth = make_auth_request(client);
374 <  SetCrit(auth);
392 <
393 <  client->localClient->dns_query = MyMalloc(sizeof(struct DNSQuery));
394 <  client->localClient->dns_query->ptr = auth;
395 <  client->localClient->dns_query->callback = auth_dns_callback;
374 >  dlinkAdd(auth, &auth->node, &auth_doing_list);
375  
376    sendheader(client, REPORT_DO_DNS);
377  
378 +  SetDNSPending(auth);
379 +
380    if (ConfigFileEntry.disable_auth == 0)
381 +  {
382 +    SetDoingAuth(auth);
383      start_auth_query(auth);
384 +  }
385  
386 <  /* auth order changed, before gethost_byaddr can immediately call
403 <   * dns callback under win32 when the lookup cannot be started.
404 <   * And that would do MyFree(auth) etc -adx */
405 <  SetDNSPending(auth);
406 <  dlinkAdd(auth, &auth->dns_node, &auth_doing_dns_list);
407 <  ClearCrit(auth);
408 <  gethost_byaddr(&client->localClient->ip, client->localClient->dns_query);
386 >  gethost_byaddr(auth_dns_callback, auth, &client->localClient->ip);
387  
388    return NULL;
389   }
# Line 417 | Line 395 | start_auth(va_list args)
395   static void
396   timeout_auth_queries_event(void *notused)
397   {
398 <  dlink_node *ptr;
421 <  dlink_node *next_ptr;
422 <  struct AuthRequest* auth;
398 >  dlink_node *ptr = NULL, *next_ptr = NULL;
399  
400 <  DLINK_FOREACH_SAFE(ptr, next_ptr, auth_doing_ident_list.head)
400 >  DLINK_FOREACH_SAFE(ptr, next_ptr, auth_doing_list.head)
401    {
402 <    auth = ptr->data;
402 >    struct AuthRequest *auth = ptr->data;
403  
404 <    if (auth->timeout <= CurrentTime)
405 <    {
430 <      fd_close(&auth->fd);
404 >    if (auth->timeout > CurrentTime)
405 >      continue;
406  
407 <      ++ServerStats->is_abad;
407 >    if (IsDoingAuth(auth))
408 >    {  
409 >      ++ServerStats.is_abad;
410 >      fd_close(&auth->fd);
411 >      ClearAuth(auth);
412        sendheader(auth->client, REPORT_FAIL_ID);
413 +    }
414  
415 <      if (IsDNSPending(auth))
416 <      {
417 <        struct Client *client_p = auth->client;
418 <
419 <        dlinkDelete(&auth->dns_node, &auth_doing_dns_list);
440 <        if (client_p->localClient->dns_query != NULL)
441 <        {
442 <          delete_resolver_queries(client_p->localClient->dns_query);
443 <          MyFree(client_p->localClient->dns_query);
444 <        }
445 <        auth->client->localClient->dns_query = NULL;
446 <        sendheader(client_p, REPORT_FAIL_DNS);
447 <      }
448 <
449 <      ilog(L_INFO, "DNS/AUTH timeout %s",
450 <           get_client_name(auth->client, SHOW_IP));
451 <
452 <      dlinkDelete(&auth->ident_node, &auth_doing_ident_list);
453 <      release_auth_client(auth->client);
454 <      MyFree(auth);
415 >    if (IsDNSPending(auth))
416 >    {
417 >      delete_resolver_queries(auth);
418 >      ClearDNSPending(auth);
419 >      sendheader(auth->client, REPORT_FAIL_DNS);
420      }
421 +
422 +    ilog(LOG_TYPE_IRCD, "DNS/AUTH timeout %s",
423 +         get_client_name(auth->client, SHOW_IP));
424 +    release_auth_client(auth);
425    }
426   }
427  
# Line 476 | Line 445 | auth_connect_callback(fde_t *fd, int err
445    char authbuf[32];
446    socklen_t ulen = sizeof(struct irc_ssaddr);
447    socklen_t tlen = sizeof(struct irc_ssaddr);
448 <  u_int16_t uport, tport;
448 >  uint16_t uport, tport;
449   #ifdef IPV6
450    struct sockaddr_in6 *v6;
451   #else
# Line 489 | Line 458 | auth_connect_callback(fde_t *fd, int err
458      return;
459    }
460  
461 <  if (getsockname(auth->client->localClient->fd.fd, (struct sockaddr *) &us,
462 <      (socklen_t *) &ulen) ||
463 <      getpeername(auth->client->localClient->fd.fd, (struct sockaddr *) &them,
464 <      (socklen_t *) &tlen))
461 >  if (getsockname(auth->client->localClient->fd.fd, (struct sockaddr *)&us,
462 >      &ulen) ||
463 >      getpeername(auth->client->localClient->fd.fd, (struct sockaddr *)&them,
464 >      &tlen))
465    {
466 <    ilog(L_INFO, "auth get{sock,peer}name error for %s",
466 >    ilog(LOG_TYPE_IRCD, "auth get{sock,peer}name error for %s",
467          get_client_name(auth->client, SHOW_IP));
468      auth_error(auth);
469      return;
# Line 516 | Line 485 | auth_connect_callback(fde_t *fd, int err
485    them.ss_len = tlen;
486   #endif
487    
488 <  ircsprintf(authbuf, "%u , %u\r\n", tport, uport);
488 >  snprintf(authbuf, sizeof(authbuf), "%u , %u\r\n", tport, uport);
489  
490    if (send(fd->fd, authbuf, strlen(authbuf), 0) == -1)
491    {
492      auth_error(auth);
493      return;
494    }
495 +
496    read_auth_reply(&auth->fd, auth);
497   }
498  
# Line 555 | Line 525 | read_auth_reply(fde_t *fd, void *data)
525     *
526     *    --nenolod
527     */
558 #ifndef _WIN32
528    len = read(fd->fd, buf, AUTH_BUFSIZ);
529 < #else
561 <  len = recv(fd->fd, buf, AUTH_BUFSIZ, 0);
562 < #endif
563 <  
529 >
530    if (len < 0)
531    {
566 #ifdef _WIN32
567    errno = WSAGetLastError();
568 #endif
532      if (ignoreErrno(errno))
533        comm_setselect(fd, COMM_SELECT_READ, read_auth_reply, auth, 0);
534      else
# Line 601 | Line 564 | read_auth_reply(fde_t *fd, void *data)
564  
565    fd_close(fd);
566  
604  dlinkDelete(&auth->ident_node, &auth_doing_ident_list);  
567    ClearAuth(auth);
568  
569    if (s == NULL)
570    {
571      sendheader(auth->client, REPORT_FAIL_ID);
572 <    ++ServerStats->is_abad;
572 >    ++ServerStats.is_abad;
573    }
574    else
575    {
576      sendheader(auth->client, REPORT_FIN_ID);
577 <    ++ServerStats->is_asuc;
577 >    ++ServerStats.is_asuc;
578      SetGotId(auth->client);
579    }
580  
581 <  if (!IsDNSPending(auth) && !IsCrit(auth))
620 <  {
621 <    release_auth_client(auth->client);
622 <    MyFree(auth);
623 <  }
581 >  release_auth_client(auth);
582   }
583  
584   /*
585   * delete_auth()
586   */
587   void
588 < delete_auth(struct Client *target_p)
588 > delete_auth(struct AuthRequest *auth)
589   {
590 <  dlink_node *ptr;
591 <  dlink_node *next_ptr;
634 <  struct AuthRequest *auth;
590 >  if (IsDNSPending(auth))
591 >    delete_resolver_queries(auth);
592  
593 <  if (!IsUnknown(target_p))
594 <    return;
593 >  if (IsDoingAuth(auth))
594 >    fd_close(&auth->fd);
595  
596 <  if (target_p->localClient->dns_query != NULL)
597 <    DLINK_FOREACH_SAFE(ptr, next_ptr, auth_doing_dns_list.head)
641 <    {
642 <      auth = ptr->data;
643 <
644 <      if (auth->client == target_p)
645 <      {
646 <        delete_resolver_queries(target_p->localClient->dns_query);
647 <
648 <        dlinkDelete(&auth->dns_node, &auth_doing_dns_list);
649 <        if (!IsDoingAuth(auth))
650 <        {
651 <          MyFree(auth);
652 <          return;
653 <        }
654 <      }
655 <    }
656 <
657 <  DLINK_FOREACH_SAFE(ptr, next_ptr, auth_doing_ident_list.head)
658 <  {
659 <    auth = ptr->data;
660 <
661 <    if (auth->client == target_p)
662 <    {
663 <      fd_close(&auth->fd);
664 <
665 <      dlinkDelete(&auth->ident_node, &auth_doing_ident_list);
666 <      MyFree(auth);
667 <    }
668 <  }
596 >  dlinkDelete(&auth->node, &auth_doing_list);
597 >  BlockHeapFree(auth_heap, auth);
598   }

Diff Legend

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