home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / UNIX / Networking / wu-ftpd-2.4.2b13-MIHS / support / arpa / authuser.c next >
Encoding:
C/C++ Source or Header  |  1997-03-03  |  4.3 KB  |  190 lines

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