home *** CD-ROM | disk | FTP | other *** search
/ The Net: Ultimate Internet Guide / WWLCD1.ISO / pc / java / in4wjcxu / other / irc / ircd / s_auth.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-14  |  6.8 KB  |  245 lines

  1. /************************************************************************
  2.  *   IRC - Internet Relay Chat, ircd/s_auth.c
  3.  *   Copyright (C) 1992 Darren Reed
  4.  *
  5.  *   This program is free software; you can redistribute it and/or modify
  6.  *   it under the terms of the GNU General Public License as published by
  7.  *   the Free Software Foundation; either version 1, or (at your option)
  8.  *   any later version.
  9.  *
  10.  *   This program is distributed in the hope that it will be useful,
  11.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *   GNU General Public License for more details.
  14.  *
  15.  *   You should have received a copy of the GNU General Public License
  16.  *   along with this program; if not, write to the Free Software
  17.  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19.  
  20. #ifndef lint
  21. static  char sccsid[] = "@(#)s_auth.c    1.18 4/18/94 (C) 1992 Darren Reed";
  22. #endif
  23.  
  24. #include "struct.h"
  25. #include "common.h"
  26. #include "sys.h"
  27. #include "res.h"
  28. #include "numeric.h"
  29. #include "patchlevel.h"
  30. #include <sys/socket.h>
  31. #include <sys/file.h>
  32. #include <sys/ioctl.h>
  33. #ifdef    UNIXPORT
  34. # include <sys/un.h>
  35. #endif
  36. #if defined(__hpux)
  37. # include "inet.h"
  38. #endif
  39. #include <fcntl.h>
  40. #include "sock.h"    /* If FD_ZERO isn't define up to this point,  */
  41.             /* define it (BSD4.2 needs this) */
  42. #include "h.h"
  43.  
  44. /*
  45.  * start_auth
  46.  *
  47.  * Flag the client to show that an attempt to contact the ident server on
  48.  * the client's host.  The connect and subsequently the socket are all put
  49.  * into 'non-blocking' mode.  Should the connect or any later phase of the
  50.  * identifing process fail, it is aborted and the user is given a username
  51.  * of "unknown".
  52.  */
  53. void    start_auth(cptr)
  54. Reg1    aClient    *cptr;
  55. {
  56.     struct    sockaddr_in    sock;
  57.  
  58.     Debug((DEBUG_NOTICE,"start_auth(%x) fd %d status %d",
  59.         cptr, cptr->fd, cptr->status));
  60.     if ((cptr->authfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
  61.         {
  62. #ifdef    USE_SYSLOG
  63.         syslog(LOG_ERR, "Unable to create auth socket for %s:%m",
  64.             get_client_name(cptr, TRUE));
  65. #endif
  66.         Debug((DEBUG_ERROR, "Unable to create auth socket for %s:%s",
  67.             get_client_name(cptr, TRUE),
  68.             strerror(get_sockerr(cptr))));
  69.         if (!DoingDNS(cptr))
  70.             SetAccess(cptr);
  71.         ircstp->is_abad++;
  72.         return;
  73.         }
  74.     if (cptr->authfd >= (MAXCONNECTIONS-2))
  75.         {
  76.         sendto_ops("Can't allocate fd for auth on %s",
  77.                get_client_name(cptr, TRUE));
  78.         (void)close(cptr->authfd);
  79.         return;
  80.         }
  81.  
  82.     set_non_blocking(cptr->authfd, cptr);
  83.  
  84.     bcopy((char *)&cptr->ip, (char *)&sock.sin_addr,
  85.         sizeof(struct in_addr));
  86.  
  87.     sock.sin_port = htons(113);
  88.     sock.sin_family = AF_INET;
  89.  
  90.     (void)alarm((unsigned)4);
  91.     if (connect(cptr->authfd, (struct sockaddr *)&sock,
  92.             sizeof(sock)) == -1 && errno != EINPROGRESS)
  93.         {
  94.         ircstp->is_abad++;
  95.         /*
  96.          * No error report from this...
  97.          */
  98.         (void)alarm((unsigned)0);
  99.         (void)close(cptr->authfd);
  100.         cptr->authfd = -1;
  101.         if (!DoingDNS(cptr))
  102.             SetAccess(cptr);
  103.         return;
  104.         }
  105.     (void)alarm((unsigned)0);
  106.     cptr->flags |= (FLAGS_WRAUTH|FLAGS_AUTH);
  107.     if (cptr->authfd > highest_fd)
  108.         highest_fd = cptr->authfd;
  109.     return;
  110. }
  111.  
  112. /*
  113.  * send_authports
  114.  *
  115.  * Send the ident server a query giving "theirport , ourport".
  116.  * The write is only attempted *once* so it is deemed to be a fail if the
  117.  * entire write doesn't write all the data given.  This shouldnt be a
  118.  * problem since the socket should have a write buffer far greater than
  119.  * this message to store it in should problems arise. -avalon
  120.  */
  121. void    send_authports(cptr)
  122. aClient    *cptr;
  123. {
  124.     struct    sockaddr_in    us, them;
  125.     char    authbuf[32];
  126.     int    ulen, tlen;
  127.  
  128.     Debug((DEBUG_NOTICE,"write_authports(%x) fd %d authfd %d stat %d",
  129.         cptr, cptr->fd, cptr->authfd, cptr->status));
  130.     tlen = ulen = sizeof(us);
  131.     if (getsockname(cptr->fd, (struct sockaddr *)&us, &ulen) ||
  132.         getpeername(cptr->fd, (struct sockaddr *)&them, &tlen))
  133.         {
  134. #ifdef    USE_SYSLOG
  135.         syslog(LOG_ERR, "auth get{sock,peer}name error for %s:%m",
  136.             get_client_name(cptr, TRUE));
  137. #endif
  138.         goto authsenderr;
  139.         }
  140.  
  141.     (void)sprintf(authbuf, "%u , %u\r\n",
  142.         (unsigned int)ntohs(them.sin_port),
  143.         (unsigned int)ntohs(us.sin_port));
  144.  
  145.     Debug((DEBUG_SEND, "sending [%s] to auth port %s.113",
  146.         authbuf, inetntoa((char *)&them.sin_addr)));
  147.     if (write(cptr->authfd, authbuf, strlen(authbuf)) != strlen(authbuf))
  148.         {
  149. authsenderr:
  150.         ircstp->is_abad++;
  151.         (void)close(cptr->authfd);
  152.         if (cptr->authfd == highest_fd)
  153.             while (!local[highest_fd])
  154.                 highest_fd--;
  155.         cptr->authfd = -1;
  156.         cptr->flags &= ~FLAGS_AUTH;
  157.         if (!DoingDNS(cptr))
  158.             SetAccess(cptr);
  159.         }
  160.     cptr->flags &= ~FLAGS_WRAUTH;
  161.     return;
  162. }
  163.  
  164. /*
  165.  * read_authports
  166.  *
  167.  * read the reply (if any) from the ident server we connected to.
  168.  * The actual read processijng here is pretty weak - no handling of the reply
  169.  * if it is fragmented by IP.
  170.  */
  171. void    read_authports(cptr)
  172. Reg1    aClient    *cptr;
  173. {
  174.     Reg1    char    *s, *t;
  175.     Reg2    int    len;
  176.     char    ruser[USERLEN+1], system[8];
  177.     u_short    remp = 0, locp = 0;
  178.  
  179.     *system = *ruser = '\0';
  180.     Debug((DEBUG_NOTICE,"read_authports(%x) fd %d authfd %d stat %d",
  181.         cptr, cptr->fd, cptr->authfd, cptr->status));
  182.     /*
  183.      * Nasty.  Cant allow any other reads from client fd while we're
  184.      * waiting on the authfd to return a full valid string.  Use the
  185.      * client's input buffer to buffer the authd reply.
  186.      * Oh. this is needed because an authd reply may come back in more
  187.      * than 1 read! -avalon
  188.      */
  189.     if ((len = read(cptr->authfd, cptr->buffer + cptr->count,
  190.             sizeof(cptr->buffer) - 1 - cptr->count)) >= 0)
  191.         {
  192.         cptr->count += len;
  193.         cptr->buffer[cptr->count] = '\0';
  194.         }
  195.  
  196.     cptr->lasttime = time(NULL);
  197.     if ((len > 0) && (cptr->count != (sizeof(cptr->buffer) - 1)) &&
  198.         (sscanf(cptr->buffer, "%hd , %hd : USERID : %*[^:]: %10s",
  199.             &remp, &locp, ruser) == 3))
  200.         {
  201.         s = rindex(cptr->buffer, ':');
  202.         *s++ = '\0';
  203.         for (t = (rindex(cptr->buffer, ':') + 1); *t; t++)
  204.             if (!isspace(*t))
  205.                 break;
  206.         strncpyzt(system, t, sizeof(system));
  207.         for (t = ruser; *s && (t < ruser + sizeof(ruser)); s++)
  208.             if (!isspace(*s) && *s != ':')
  209.                 *t++ = *s;
  210.         *t = '\0';
  211.         Debug((DEBUG_INFO,"auth reply ok [%s] [%s]", system, ruser));
  212.         }
  213.     else if (len != 0)
  214.         {
  215.         if (!index(cptr->buffer, '\n') && !index(cptr->buffer, '\r'))
  216.             return;
  217.         Debug((DEBUG_ERROR,"local %d remote %d s %x", locp, remp, s));
  218.         Debug((DEBUG_ERROR,"bad auth reply in [%s]", cptr->buffer));
  219.         *ruser = '\0';
  220.         }
  221.     (void)close(cptr->authfd);
  222.     if (cptr->authfd == highest_fd)
  223.         while (!local[highest_fd])
  224.             highest_fd--;
  225.     cptr->count = 0;
  226.     cptr->authfd = -1;
  227.     ClearAuth(cptr);
  228.     if (!DoingDNS(cptr))
  229.         SetAccess(cptr);
  230.     if (len > 0)
  231.         Debug((DEBUG_INFO,"ident reply: [%s]", cptr->buffer));
  232.  
  233.     if (!locp || !remp || !*ruser)
  234.         {
  235.         ircstp->is_abad++;
  236.         return;
  237.         }
  238.     ircstp->is_asuc++;
  239.     strncpyzt(cptr->username, ruser, USERLEN+1);
  240.     if (strncmp(system, "OTHER", 5))
  241.         cptr->flags |= FLAGS_GOTID;
  242.     Debug((DEBUG_INFO, "got username [%s]", ruser));
  243.     return;
  244. }
  245.