1:  /*
   2:   * rfc931() speaks a common subset of the RFC 931, AUTH, TAP, IDENT and RFC
   3:   * 1413 protocols. It queries an RFC 931 etc. compatible daemon on a remote
   4:   * host to look up the owner of a connection. The information should not be
   5:   * used for authentication purposes. This routine intercepts alarm signals.
   6:   *
   7:   * Diagnostics are reported through syslog(3).
   8:   *
   9:   * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  10:   */
  11: 
  12: #ifndef lint
  13: static char sccsid[] = "@(#) rfc931.c 1.10 95/01/02 16:11:34";
  14: #endif
  15: 
  16: /* System libraries. */
  17: 
  18: #include <stdio.h>
  19: #include <syslog.h>
  20: #include <sys/types.h>
  21: #include <sys/socket.h>
  22: #include <netinet/in.h>
  23: #include <setjmp.h>
  24: #include <signal.h>
  25: #include <string.h>
  26: 
  27: /* Local stuff. */
  28: 
  29: #include "tcpd.h"
  30: 
  31: #define RFC931_PORT 113     /* Semi-well-known port */
  32: #define ANY_PORT    0       /* Any old port will do */
  33: 
  34: int     rfc931_timeout = RFC931_TIMEOUT;/* Global so it can be changed */
  35: 
  36: static jmp_buf timebuf;
  37: 
  38: /* fsocket - open stdio stream on top of socket */
  39: 
  40: static FILE *fsocket(domain, type, protocol)
  41: int     domain;
  42: int     type;
  43: int     protocol;
  44: {
  45:     int     s;
  46:     FILE   *fp;
  47: 
  48:     if ((s = socket(domain, type, protocol)) < 0) {
  49:     tcpd_warn("socket: %m");
  50:     return (0);
  51:     } else {
  52:     if ((fp = fdopen(s, "r+")) == 0) {
  53:         tcpd_warn("fdopen: %m");
  54:         close(s);
  55:     }
  56:     return (fp);
  57:     }
  58: }
  59: 
  60: /* timeout - handle timeouts */
  61: 
  62: static void timeout(sig)
  63: int     sig;
  64: {
  65:     longjmp(timebuf, sig);
  66: }
  67: 
  68: /* rfc931 - return remote user name, given socket structures */
  69: 
  70: void    rfc931(rmt_sin, our_sin, dest)
  71: struct sockaddr_in *rmt_sin;
  72: struct sockaddr_in *our_sin;
  73: char   *dest;
  74: {
  75:     unsigned rmt_port;
  76:     unsigned our_port;
  77:     struct sockaddr_in rmt_query_sin;
  78:     struct sockaddr_in our_query_sin;
  79:     char    user[256];          /* XXX */
  80:     char    buffer[512];        /* XXX */
  81:     char   *cp;
  82:     char   *result = unknown;
  83:     FILE   *fp;
  84: 
  85:     /*
  86:      * Use one unbuffered stdio stream for writing to and for reading from
  87:      * the RFC931 etc. server. This is done because of a bug in the SunOS
  88:      * 4.1.x stdio library. The bug may live in other stdio implementations,
  89:      * too. When we use a single, buffered, bidirectional stdio stream ("r+"
  90:      * or "w+" mode) we read our own output. Such behaviour would make sense
  91:      * with resources that support random-access operations, but not with
  92:      * sockets.
  93:      */
  94: 
  95:     if ((fp = fsocket(AF_INET, SOCK_STREAM, 0)) != 0) {
  96:     setbuf(fp, (char *) 0);
  97: 
  98:     /*
  99: 	 * Set up a timer so we won't get stuck while waiting for the server.
 100: 	 */
 101: 
 102:     if (setjmp(timebuf) == 0) {
 103:         signal(SIGALRM, timeout);
 104:         alarm(rfc931_timeout);
 105: 
 106:         /*
 107: 	     * Bind the local and remote ends of the query socket to the same
 108: 	     * IP addresses as the connection under investigation. We go
 109: 	     * through all this trouble because the local or remote system
 110: 	     * might have more than one network address. The RFC931 etc.
 111: 	     * client sends only port numbers; the server takes the IP
 112: 	     * addresses from the query socket.
 113: 	     */
 114: 
 115:         our_query_sin = *our_sin;
 116:         our_query_sin.sin_port = htons(ANY_PORT);
 117:         rmt_query_sin = *rmt_sin;
 118:         rmt_query_sin.sin_port = htons(RFC931_PORT);
 119: 
 120:         if (bind(fileno(fp), (struct sockaddr *) & our_query_sin,
 121:              sizeof(our_query_sin)) >= 0 &&
 122:         connect(fileno(fp), (struct sockaddr *) & rmt_query_sin,
 123:             sizeof(rmt_query_sin)) >= 0) {
 124: 
 125:         /*
 126: 		 * Send query to server. Neglect the risk that a 13-byte
 127: 		 * write would have to be fragmented by the local system and
 128: 		 * cause trouble with buggy System V stdio libraries.
 129: 		 */
 130: 
 131:         fprintf(fp, "%u,%u\r\n",
 132:             ntohs(rmt_sin->sin_port),
 133:             ntohs(our_sin->sin_port));
 134:         fflush(fp);
 135: 
 136:         /*
 137: 		 * Read response from server. Use fgets()/sscanf() so we can
 138: 		 * work around System V stdio libraries that incorrectly
 139: 		 * assume EOF when a read from a socket returns less than
 140: 		 * requested.
 141: 		 */
 142: 
 143:         if (fgets(buffer, sizeof(buffer), fp) != 0
 144:             && ferror(fp) == 0 && feof(fp) == 0
 145:             && sscanf(buffer, "%u , %u : USERID :%*[^:]:%255s",
 146:                   &rmt_port, &our_port, user) == 3
 147:             && ntohs(rmt_sin->sin_port) == rmt_port
 148:             && ntohs(our_sin->sin_port) == our_port) {
 149: 
 150:             /*
 151: 		     * Strip trailing carriage return. It is part of the
 152: 		     * protocol, not part of the data.
 153: 		     */
 154: 
 155:             if (cp = strchr(user, '\r'))
 156:             *cp = 0;
 157:             result = user;
 158:         }
 159:         }
 160:         alarm(0);
 161:     }
 162:     fclose(fp);
 163:     }
 164:     STRN_CPY(dest, result, STRING_LENGTH);
 165: }

Defined functions

fsocket defined in line 40; used 1 times
  • in line 95
rfc931 defined in line 70; used 2 times
timeout defined in line 62; used 1 times

Defined variables

rfc931_timeout defined in line 34; used 2 times
sccsid defined in line 13; never used
timebuf defined in line 36; used 2 times

Defined macros

ANY_PORT defined in line 32; used 1 times
RFC931_PORT defined in line 31; used 1 times
Last modified: 1995-01-02
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2801
Valid CSS Valid XHTML 1.0 Strict