home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 3 / Meeting_Pearls_III.iso / Pearls / tcp / Networking / TCP / Server / wu-ftpd / src / authuser.c < prev    next >
C/C++ Source or Header  |  1994-08-08  |  4KB  |  164 lines

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