home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2684 / authuser.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-07  |  3.4 KB  |  163 lines

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