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.3/src/s_auth.c (file contents), Revision 1124 by michael, Mon Feb 7 11:45:27 2011 UTC vs.
ircd-hybrid/trunk/src/s_auth.c (file contents), Revision 3322 by michael, Tue Apr 15 16:11:11 2014 UTC

# Line 1 | Line 1
1   /*
2 < *  ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 < *  s_auth.c: Functions for querying a users ident.
2 > *  ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3   *
4 < *  Copyright (C) 2002 by the past and present ircd coders, and others.
4 > *  Copyright (c) 1997-2014 ircd-hybrid development team
5   *
6   *  This program is free software; you can redistribute it and/or modify
7   *  it under the terms of the GNU General Public License as published by
# Line 18 | Line 17
17   *  along with this program; if not, write to the Free Software
18   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
19   *  USA
20 < *
21 < *  $Id$
20 > */
21 >
22 > /*! \file s_auth.c
23 > * \brief Functions for querying a users ident.
24 > * \version $Id$
25   */
26  
27   /*
# Line 32 | Line 34
34   *     any messages from it.
35   *     --Bleep  Thomas Helvey <tomh@inxpress.net>
36   */
37 +
38   #include "stdinc.h"
39   #include "list.h"
40   #include "ircd_defs.h"
41   #include "fdlist.h"
42   #include "s_auth.h"
43 < #include "s_conf.h"
41 < #include "balloc.h"
43 > #include "conf.h"
44   #include "client.h"
43 #include "common.h"
45   #include "event.h"
45 #include "hook.h"
46   #include "irc_string.h"
47   #include "ircd.h"
48   #include "packet.h"
49 < #include "irc_res.h"
49 > #include "res.h"
50   #include "s_bsd.h"
51 < #include "s_log.h"
51 > #include "log.h"
52   #include "send.h"
53 + #include "mempool.h"
54  
55  
56 < static const char *HeaderMessages[] = {
57 <  ":%s NOTICE AUTH :*** Looking up your hostname...",
58 <  ":%s NOTICE AUTH :*** Found your hostname",
59 <  ":%s NOTICE AUTH :*** Couldn't look up your hostname",
60 <  ":%s NOTICE AUTH :*** Checking Ident",
61 <  ":%s NOTICE AUTH :*** Got Ident response",
62 <  ":%s NOTICE AUTH :*** No Ident response",
63 <  ":%s NOTICE AUTH :*** Your forward and reverse DNS do not match, ignoring hostname.",
64 <  ":%s NOTICE AUTH :*** Your hostname is too long, ignoring hostname"
56 > static const char *HeaderMessages[] =
57 > {
58 >  ":*** Looking up your hostname...",
59 >  ":*** Found your hostname",
60 >  ":*** Couldn't look up your hostname",
61 >  ":*** Checking Ident",
62 >  ":*** Got Ident response",
63 >  ":*** No Ident response",
64 >  ":*** Your forward and reverse DNS do not match, ignoring hostname.",
65 >  ":*** Your hostname is too long, ignoring hostname"
66   };
67  
68 < enum {
68 > enum
69 > {
70    REPORT_DO_DNS,
71    REPORT_FIN_DNS,
72    REPORT_FAIL_DNS,
# Line 74 | Line 77 | enum {
77    REPORT_HOST_TOOLONG
78   };
79  
80 < #define sendheader(c, i) sendto_one((c), HeaderMessages[(i)], me.name)
80 > #define sendheader(c, i) sendto_one_notice((c), &me, HeaderMessages[(i)])
81  
79 static BlockHeap *auth_heap = NULL;
82   static dlink_list auth_doing_list = { NULL, NULL, 0 };
83  
84   static EVH timeout_auth_queries_event;
85  
86   static PF read_auth_reply;
87   static CNCB auth_connect_callback;
86 static CBFUNC start_auth;
87
88 struct Callback *auth_cb = NULL;
88  
89 < /* init_auth()
89 > /* auth_init
90   *
91   * Initialise the auth code
92   */
93   void
94 < init_auth(void)
94 > auth_init(void)
95   {
97  auth_heap = BlockHeapCreate("auth", sizeof(struct AuthRequest), AUTH_HEAP_SIZE);
98  auth_cb = register_callback("start_auth", start_auth);
96    eventAddIsh("timeout_auth_queries_event", timeout_auth_queries_event, NULL, 1);
97   }
98  
# Line 105 | Line 102 | init_auth(void)
102   static struct AuthRequest *
103   make_auth_request(struct Client *client)
104   {
105 <  struct AuthRequest *request = BlockHeapAlloc(auth_heap);
105 >  struct AuthRequest *request = &client->localClient->auth;
106  
107 <  client->localClient->auth = request;
108 <  request->client           = client;
109 <  request->timeout          = CurrentTime + CONNECTTIMEOUT;
107 >  memset(request, 0, sizeof(*request));
108 >
109 >  request->client  = client;
110 >  request->timeout = CurrentTime + CONNECTTIMEOUT;
111  
112    return request;
113   }
# Line 127 | Line 125 | release_auth_client(struct AuthRequest *
125    if (IsDoingAuth(auth) || IsDNSPending(auth))
126      return;
127  
128 <  client->localClient->auth = NULL;
129 <  dlinkDelete(&auth->node, &auth_doing_list);
130 <  BlockHeapFree(auth_heap, auth);
128 >  if (IsInAuth(auth))
129 >  {
130 >    dlinkDelete(&auth->node, &auth_doing_list);
131 >    ClearInAuth(auth);
132 >  }
133  
134    /*
135     * When a client has auth'ed, we want to start reading what it sends
# Line 141 | Line 141 | release_auth_client(struct AuthRequest *
141  
142    dlinkAdd(client, &client->node, &global_client_list);
143  
144 <  client->since  = client->lasttime = client->firsttime = CurrentTime;
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 <
151 >
152   /*
153   * auth_dns_callback - called when resolver query finishes
154   * if the query resulted in a successful search, name will contain
# Line 161 | Line 163 | auth_dns_callback(void *vptr, const stru
163  
164    ClearDNSPending(auth);
165  
166 <  if (name != NULL)
166 >  if (name)
167    {
168      const struct sockaddr_in *v4, *v4dns;
169   #ifdef IPV6
# Line 174 | Line 176 | auth_dns_callback(void *vptr, const stru
176      {
177        v6 = (const struct sockaddr_in6 *)&auth->client->localClient->ip;
178        v6dns = (const struct sockaddr_in6 *)addr;
179 +
180        if (memcmp(&v6->sin6_addr, &v6dns->sin6_addr, sizeof(struct in6_addr)) != 0)
181        {
182          sendheader(auth->client, REPORT_IP_MISMATCH);
# Line 185 | Line 188 | auth_dns_callback(void *vptr, const stru
188      {
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)
191 >
192 >      if (v4->sin_addr.s_addr != v4dns->sin_addr.s_addr)
193        {
194          sendheader(auth->client, REPORT_IP_MISMATCH);
195          good = 0;
196        }
197      }
198 +
199      if (good && strlen(name) <= HOSTLEN)
200      {
201        strlcpy(auth->client->host, name,
202 <              sizeof(auth->client->host));
202 >              sizeof(auth->client->host));
203        sendheader(auth->client, REPORT_FIN_DNS);
204      }
205      else if (strlen(name) > HOSTLEN)
# Line 224 | Line 229 | auth_error(struct AuthRequest *auth)
229   }
230  
231   /*
232 < * start_auth_query - Flag the client to show that an attempt to
232 > * start_auth_query - Flag the client to show that an attempt to
233   * contact the ident server on
234   * the client's host.  The connect and subsequently the socket are all put
235   * into 'non-blocking' mode.  Should the connect or any later phase of the
# Line 246 | Line 251 | start_auth_query(struct AuthRequest *aut
251    if (comm_open(&auth->fd, auth->client->localClient->ip.ss.ss_family,
252                  SOCK_STREAM, 0, "ident") == -1)
253    {
254 <    report_error(L_ALL, "creating auth stream socket %s:%s",
255 <        get_client_name(auth->client, SHOW_IP), errno);
256 <    ilog(L_ERROR, "Unable to create auth socket for %s",
254 >    report_error(L_ALL, "creating auth stream socket %s:%s",
255 >                 get_client_name(auth->client, SHOW_IP), errno);
256 >    ilog(LOG_TYPE_IRCD, "Unable to create auth socket for %s",
257          get_client_name(auth->client, SHOW_IP));
258      ++ServerStats.is_abad;
259      return 0;
# Line 256 | Line 261 | start_auth_query(struct AuthRequest *aut
261  
262    sendheader(auth->client, REPORT_DO_ID);
263  
264 <  /*
264 >  /*
265     * get the local address of the client and bind to that to
266     * make the auth request.  This used to be done only for
267     * ifdef VIRTUAL_HOST, but needs to be done for all clients
# Line 278 | Line 283 | start_auth_query(struct AuthRequest *aut
283   #endif
284    localaddr.ss_port = htons(0);
285  
286 <  comm_connect_tcp(&auth->fd, auth->client->sockhost, 113,
287 <      (struct sockaddr *)&localaddr, localaddr.ss_len, auth_connect_callback,
288 <      auth, auth->client->localClient->ip.ss.ss_family,
286 >  comm_connect_tcp(&auth->fd, auth->client->sockhost, 113,
287 >      (struct sockaddr *)&localaddr, localaddr.ss_len, auth_connect_callback,
288 >      auth, auth->client->localClient->ip.ss.ss_family,
289        GlobalSetOptions.ident_timeout);
290    return 1; /* We suceed here for now */
291   }
292  
293   /*
294   * GetValidIdent - parse ident query reply from identd server
295 < *
295 > *
296   * Inputs        - pointer to ident buf
297   * Output        - NULL if no valid ident found, otherwise pointer to name
298   * Side effects  -
# Line 320 | Line 325 | GetValidIdent(char *buf)
325  
326    /* All this to get rid of a sscanf() fun. */
327    remotePortString = buf;
328 <  
328 >
329    if ((colon1Ptr = strchr(remotePortString,':')) == NULL)
330      return 0;
331    *colon1Ptr = '\0';
# Line 330 | Line 335 | GetValidIdent(char *buf)
335      return 0;
336    *colon2Ptr = '\0';
337    colon2Ptr++;
338 <  
338 >
339    if ((commaPtr = strchr(remotePortString, ',')) == NULL)
340      return 0;
341    *commaPtr = '\0';
# Line 338 | Line 343 | GetValidIdent(char *buf)
343  
344    if ((remp = atoi(remotePortString)) == 0)
345      return 0;
346 <              
346 >
347    if ((locp = atoi(commaPtr)) == 0)
348      return 0;
349  
# Line 354 | Line 359 | GetValidIdent(char *buf)
359   }
360  
361   /*
362 < * start_auth
362 > * start_auth
363   *
364   * inputs       - pointer to client to auth
365   * output       - NONE
366   * side effects - starts auth (identd) and dns queries for a client
367   */
368 < static void *
369 < start_auth(va_list args)
368 > void
369 > start_auth(struct Client *client_p)
370   {
366  struct Client *client = va_arg(args, struct Client *);
371    struct AuthRequest *auth = NULL;
372  
373 <  assert(client != NULL);
373 >  assert(client_p);
374  
375 <  auth = make_auth_request(client);
376 <  dlinkAdd(auth, &auth->node, &auth_doing_list);
375 >  auth = make_auth_request(client_p);
376 >  SetInAuth(auth);
377 >  dlinkAddTail(auth, &auth->node, &auth_doing_list);
378  
379 <  sendheader(client, REPORT_DO_DNS);
379 >  sendheader(client_p, REPORT_DO_DNS);
380  
381    SetDNSPending(auth);
382  
# Line 381 | Line 386 | start_auth(va_list args)
386      start_auth_query(auth);
387    }
388  
389 <  gethost_byaddr(auth_dns_callback, auth, &client->localClient->ip);
385 <
386 <  return NULL;
389 >  gethost_byaddr(auth_dns_callback, auth, &client_p->localClient->ip);
390   }
391  
392   /*
# Line 393 | Line 396 | start_auth(va_list args)
396   static void
397   timeout_auth_queries_event(void *notused)
398   {
399 <  dlink_node *ptr = NULL, *next_ptr = NULL;
399 >  dlink_node *ptr = NULL, *ptr_next = NULL;
400  
401 <  DLINK_FOREACH_SAFE(ptr, next_ptr, auth_doing_list.head)
401 >  DLINK_FOREACH_SAFE(ptr, ptr_next, auth_doing_list.head)
402    {
403      struct AuthRequest *auth = ptr->data;
404  
405      if (auth->timeout > CurrentTime)
406 <      continue;
406 >      break;
407  
408      if (IsDoingAuth(auth))
409 <    {  
409 >    {
410        ++ServerStats.is_abad;
411        fd_close(&auth->fd);
412        ClearAuth(auth);
# Line 417 | Line 420 | timeout_auth_queries_event(void *notused
420        sendheader(auth->client, REPORT_FAIL_DNS);
421      }
422  
423 <    ilog(L_INFO, "DNS/AUTH timeout %s",
423 >    ilog(LOG_TYPE_IRCD, "DNS/AUTH timeout %s",
424           get_client_name(auth->client, SHOW_IP));
425      release_auth_client(auth);
426    }
# Line 456 | 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 <      &ulen) ||
461 <      getpeername(auth->client->localClient->fd.fd, (struct sockaddr *)&them,
462 <      &tlen))
462 >  if (getsockname(auth->client->localClient->fd.fd, (struct sockaddr *)&us, &ulen) ||
463 >      getpeername(auth->client->localClient->fd.fd, (struct sockaddr *)&them, &tlen))
464    {
465 <    ilog(L_INFO, "auth get{sock,peer}name error for %s",
466 <        get_client_name(auth->client, SHOW_IP));
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;
469    }
# Line 482 | Line 483 | auth_connect_callback(fde_t *fd, int err
483    us.ss_len = ulen;
484    them.ss_len = tlen;
485   #endif
486 <  
486 >
487    snprintf(authbuf, sizeof(authbuf), "%u , %u\r\n", tport, uport);
488  
489    if (send(fd->fd, authbuf, strlen(authbuf), 0) == -1)
# Line 495 | Line 496 | auth_connect_callback(fde_t *fd, int err
496   }
497  
498   /*
499 < * read_auth_reply - read the reply (if any) from the ident server
499 > * read_auth_reply - read the reply (if any) from the ident server
500   * we connected to.
501   * We only give it one shot, if the reply isn't good the first time
502   * fail the authentication entirely. --Bleep
# Line 582 | Line 583 | read_auth_reply(fde_t *fd, void *data)
583   /*
584   * delete_auth()
585   */
586 < void
586 > void
587   delete_auth(struct AuthRequest *auth)
588   {
589    if (IsDNSPending(auth))
# Line 591 | Line 592 | delete_auth(struct AuthRequest *auth)
592    if (IsDoingAuth(auth))
593      fd_close(&auth->fd);
594  
595 <  dlinkDelete(&auth->node, &auth_doing_list);
596 <  BlockHeapFree(auth_heap, auth);
595 >  if (IsInAuth(auth))
596 >  {
597 >    dlinkDelete(&auth->node, &auth_doing_list);
598 >    ClearInAuth(auth);
599 >  }
600   }

Diff Legend

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