# 2.11BSD#431 - /usr/src/libexec/tcpd/rfc931.c

##### Functions

    rfc931            X

##### Variables

    rfc931_timeout    X

##### Macros

    ANY_PORT          X
    RFC931_PORT       X

       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

- in /usr/src/libexec/tcpd/eval.c line 51
- in /usr/src/libexec/tcpd/tcpd.h line 72

timeout defined in line 62; used 1 times

- in line 103

#### Defined variables

rfc931_timeout defined in line 34; used 2 times

- in line 104
- in /usr/src/libexec/tcpd/tcpdmatch.c line 292

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

- in line 65, 102

#### Defined macros

ANY_PORT defined in line 32; used 1 times

- in line 116

RFC931_PORT defined in line 31; used 1 times

- in line 118

Last modified: 1995-01-02 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 780 |