home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3298 / authuser.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-07  |  3.5 KB  |  168 lines

  1. /*
  2. 5/6/91 DJB baseline authuser 3.1. Public domain.
  3. */
  4.  
  5. #include <stdio.h>
  6. #include <sys/types.h>
  7. #include <sys/socket.h>
  8. #include <netinet/in.h>
  9. #include <arpa/inet.h>
  10. #include <netdb.h>
  11. #include <errno.h>
  12. #include <ctype.h>
  13. extern int errno;
  14. #include "authuser.h"
  15.  
  16. unsigned short auth_tcpport = 113;
  17.  
  18. #define SIZ 500 /* various buffers */
  19.  
  20. static int usercmp(u,v)
  21. register char *u;
  22. register char *v;
  23. {
  24.  /* is it correct to consider Foo and fOo the same user? yes */
  25.  /* but the function of this routine may change later */
  26.  while (*u && *v)
  27.    if (tolower(*u) != tolower(*v))
  28.      return tolower(*u) - tolower(*v);
  29.    else
  30.      ++u,++v;
  31.  return *u || *v;
  32. }
  33.  
  34. static char authline[SIZ];
  35.  
  36. char *auth_xline(user,fd,in)
  37. register char *user; /* the supposed name of the user, NULL if unknown */
  38. register int fd; /* the file descriptor of the connection */
  39. register unsigned long *in;
  40. {
  41.  unsigned short local;
  42.  unsigned short remote;
  43.  register char *ruser;
  44.  
  45.  if (auth_fd(fd,in,&local,&remote) == -1)
  46.    return 0;
  47.  ruser = auth_tcpuser(*in,local,remote);
  48.  if (!ruser)
  49.    return 0;
  50.  if (!user)
  51.    user = ruser; /* forces X-Auth-User */
  52.  (void) sprintf(authline,
  53.      (usercmp(ruser,user) ? "X-Forgery-By: %s" : "X-Auth-User: %s"),
  54.      ruser);
  55.  return authline;
  56. }
  57.  
  58. int auth_fd(fd,in,local,remote)
  59. register int fd;
  60. register unsigned long *in;
  61. register unsigned short *local;
  62. register unsigned short *remote;
  63. {
  64.  struct sockaddr_in sa;
  65.  int dummy;
  66.  
  67.  dummy = sizeof(sa);
  68.  if (getsockname(fd,&sa,&dummy) == -1)
  69.    return -1;
  70.  if (sa.sin_family != AF_INET)
  71.   {
  72.    errno = EAFNOSUPPORT;
  73.    return -1;
  74.   }
  75.  *local = ntohs(sa.sin_port);
  76.  dummy = sizeof(sa);
  77.  if (getpeername(fd,&sa,&dummy) == -1)
  78.    return -1;
  79.  *remote = ntohs(sa.sin_port);
  80.  *in = sa.sin_addr.s_addr;
  81.  return 0;
  82. }
  83.  
  84. static char ruser[SIZ];
  85. static char realbuf[SIZ];
  86. static char *buf;
  87.  
  88. char *auth_tcpuser(in,local,remote)
  89. register unsigned long in;
  90. register unsigned short local;
  91. register unsigned short remote;
  92. {
  93.  struct sockaddr_in sa;
  94.  register int s;
  95.  register int buflen;
  96.  register int w;
  97.  register int saveerrno;
  98.  char ch;
  99.  unsigned short rlocal;
  100.  unsigned short rremote;
  101.  
  102.  if ((s = socket(AF_INET,SOCK_STREAM,0)) == -1)
  103.    return 0;
  104.  sa.sin_family = AF_INET;
  105.  sa.sin_port = htons(auth_tcpport);
  106.  sa.sin_addr.s_addr = in;
  107.  if (connect(s,&sa,sizeof(sa)) == -1)
  108.   {
  109.    saveerrno = errno;
  110.    (void) close(s);
  111.    errno = saveerrno;
  112.    return 0;
  113.   }
  114.  
  115.  buf = realbuf;
  116.  (void) sprintf(buf,"%u , %u\r\n",(unsigned int) remote,(unsigned int) local);
  117.  /* note the reversed order---the example in the RFC is misleading */
  118.  buflen = strlen(buf);
  119.  while ((w = write(s,buf,buflen)) < buflen)
  120.    if (w == -1) /* should we worry about 0 as well? */
  121.     {
  122.      saveerrno = errno;
  123.      (void) close(s);
  124.      errno = saveerrno;
  125.      return 0;
  126.     }
  127.    else
  128.     {
  129.      buf += w;
  130.      buflen -= w;
  131.     }
  132.  buf = realbuf;
  133.  while ((w = read(s,&ch,1)) == 1)
  134.   {
  135.    *buf = ch;
  136.    if ((ch != ' ') && (ch != '\t') && (ch != '\r'))
  137.      ++buf;
  138.    if ((buf - realbuf == sizeof(realbuf) - 1) || (ch == '\n'))
  139.      break;
  140.   }
  141.  if (w == -1)
  142.   {
  143.    saveerrno = errno;
  144.    (void) close(s);
  145.    errno = saveerrno;
  146.    return 0;
  147.   }
  148.  *buf = '\0';
  149.  
  150.  if (sscanf(realbuf,"%hd,%hd: USERID :%*[^:]:%s",&rremote,&rlocal,ruser) < 3)
  151.   {
  152.    (void) close(s);
  153.    errno = EIO;
  154.    /* makes sense, right? well, not when USERID failed to match ERROR */
  155.    /* but there's no good error to return in that case */
  156.    return 0;
  157.   }
  158.  if ((remote != rremote) || (local != rlocal))
  159.   {
  160.    (void) close(s);
  161.    errno = EIO;
  162.    return 0;
  163.   }
  164.  /* XXX: we're not going to do any backslash processing */
  165.  (void) close(s);
  166.  return ruser;
  167. }
  168.