home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 4 / CDPD_IV.bin / networking / tcpip / amitcp-support / wustl-ftpdaemon / support / authuser.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-29  |  3.6 KB  |  161 lines

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