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

##### Functions

    sock_host         X
    sock_hostaddr     X
    sock_hostname     X

##### Macros

    gethostbyname     X

       1:  /*
       2:   * This module determines the type of socket (datagram, stream), the client
       3:   * socket address and port, the server socket address and port. In addition,
       4:   * it provides methods to map a transport address to a printable host name
       5:   * or address. Socket address information results are in static memory.
       6:   *
       7:   * The result from the hostname lookup method is STRING_PARANOID when a host
       8:   * pretends to have someone elses name, or when a host name is available but
       9:   * could not be verified.
      10:   *
      11:   * When lookup or conversion fails the result is set to STRING_UNKNOWN.
      12:   *
      13:   * Diagnostics are reported through syslog(3).
      14:   *
      15:   * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
      16:   */
      17:
      18: #ifndef lint
      19: static char sccsid[] = "@(#) socket.c 1.14 95/01/30 19:51:50";
      20: #endif
      21:
      22: /* System libraries. */
      23:
      24: #include <sys/types.h>
      25: #include <sys/param.h>
      26: #include <sys/socket.h>
      27: #include <netinet/in.h>
      28: #include <netdb.h>
      29: #include <stdio.h>
      30: #include <syslog.h>
      31: #include <string.h>
      32:
      33: extern char *inet_ntoa();
      34:
      35: /* Local stuff. */
      36:
      37: #include "tcpd.h"
      38:
      39: /* Forward declarations. */
      40:
      41: static void sock_sink();
      42:
      43: #ifdef APPEND_DOT
      44:
      45:  /*
      46:   * Speed up DNS lookups by terminating the host name with a dot. Should be
      47:   * done with care. The speedup can give problems with lookups from sources
      48:   * that lack DNS-style trailing dot magic, such as local files or NIS maps.
      49:   */
      50:
      51: static struct hostent *gethostbyname_dot(name)
      52: char   *name;
      53: {
      54:     char    dot_name[MAXHOSTNAMELEN + 1];
      55:
      56:     /*
      57:      * Don't append dots to unqualified names. Such names are likely to come
      58:      * from local hosts files or from NIS.
      59:      */
      60:
      61:     if (strchr(name, '.') == 0 || strlen(name) >= MAXHOSTNAMELEN - 1) {
      62:     return (gethostbyname(name));
      63:     } else {
      64:     sprintf(dot_name, "%s.", name);
      65:     return (gethostbyname(dot_name));
      66:     }
      67: }
      68:
      69: #define gethostbyname gethostbyname_dot
      70: #endif
      71:
      72: /* sock_host - look up endpoint addresses and install conversion methods */
      73:
      74: void    sock_host(request)
      75: struct request_info *request;
      76: {
      77:     static struct sockaddr_in client;
      78:     static struct sockaddr_in server;
      79:     int     len;
      80:     char    buf[BUFSIZ];
      81:     int     fd = request->fd;
      82:
      83:     sock_methods(request);
      84:
      85:     /*
      86:      * Look up the client host address. Hal R. Brand <BRAND@addvax.llnl.gov>
      87:      * suggested how to get the client host info in case of UDP connections:
      88:      * peek at the first message without actually looking at its contents. We
      89:      * really should verify that client.sin_family gets the value AF_INET,
      90:      * but this program has already caused too much grief on systems with
      91:      * broken library code.
      92:      */
      93:
      94:     len = sizeof(client);
      95:     if (getpeername(fd, (struct sockaddr *) & client, &len) < 0) {
      96:     request->sink = sock_sink;
      97:     len = sizeof(client);
      98:     if (recvfrom(fd, buf, sizeof(buf), MSG_PEEK,
      99:              (struct sockaddr *) & client, &len) < 0) {
     100:         tcpd_warn("can't get client address: %m");
     101:         return;             /* give up */
     102:     }
     103: #ifdef really_paranoid
     104:     memset(buf, 0 sizeof(buf));
     105: #endif
     106:     }
     107:     request->client->sin = &client;
     108:
     109:     /*
     110:      * Determine the server binding. This is used for client username
     111:      * lookups, and for access control rules that trigger on the server
     112:      * address or name.
     113:      */
     114:
     115:     len = sizeof(server);
     116:     if (getsockname(fd, (struct sockaddr *) & server, &len) < 0) {
     117:     tcpd_warn("getsockname: %m");
     118:     return;
     119:     }
     120:     request->server->sin = &server;
     121: }
     122:
     123: /* sock_hostaddr - map endpoint address to printable form */
     124:
     125: void    sock_hostaddr(host)
     126: struct host_info *host;
     127: {
     128:     struct sockaddr_in *sin = host->sin;
     129:
     130:     if (sin != 0)
     131:     STRN_CPY(host->addr, inet_ntoa(sin->sin_addr), sizeof(host->addr));
     132: }
     133:
     134: /* sock_hostname - map endpoint address to host name */
     135:
     136: void    sock_hostname(host)
     137: struct host_info *host;
     138: {
     139:     struct sockaddr_in *sin = host->sin;
     140:     struct hostent *hp;
     141:     int     i;
     142:
     143:     /*
     144:      * On some systems, for example Solaris 2.3, gethostbyaddr(0.0.0.0) does
     145:      * not fail. Instead it returns "INADDR_ANY". Unfortunately, this does
     146:      * not work the other way around: gethostbyname("INADDR_ANY") fails. We
     147:      * have to special-case 0.0.0.0, in order to avoid false alerts from the
     148:      * host name/address checking code below.
     149:      */
     150:     if (sin != 0 && sin->sin_addr.s_addr != 0
     151:     && (hp = gethostbyaddr((char *) &(sin->sin_addr),
     152:                    sizeof(sin->sin_addr), AF_INET)) != 0) {
     153:
     154:     STRN_CPY(host->name, hp->h_name, sizeof(host->name));
     155:
     156:     /*
     157: 	 * Verify that the address is a member of the address list returned
     158: 	 * by gethostbyname(hostname).
     159: 	 *
     160: 	 * Verify also that gethostbyaddr() and gethostbyname() return the same
     161: 	 * hostname, or rshd and rlogind may still end up being spoofed.
     162: 	 *
     163: 	 * On some sites, gethostbyname("localhost") returns "localhost.domain".
     164: 	 * This is a DNS artefact. We treat it as a special case. When we
     165: 	 * can't believe the address list from gethostbyname("localhost")
     166: 	 * we're in big trouble anyway.
     167: 	 */
     168:
     169:     if ((hp = gethostbyname(host->name)) == 0) {
     170:
     171:         /*
     172: 	     * Unable to verify that the host name matches the address. This
     173: 	     * may be a transient problem or a botched name server setup.
     174: 	     */
     175:
     176:         tcpd_warn("can't verify hostname: gethostbyname(%s) failed",
     177:               host->name);
     178:
     179:     } else if (STR_NE(host->name, hp->h_name)
     180:            && STR_NE(host->name, "localhost")) {
     181:
     182:         /*
     183: 	     * The gethostbyaddr() and gethostbyname() calls did not return
     184: 	     * the same hostname. This could be a nameserver configuration
     185: 	     * problem. It could also be that someone is trying to spoof us.
     186: 	     */
     187:
     188:         tcpd_warn("host name/name mismatch: %s != %s",
     189:               host->name, hp->h_name);
     190:
     191:     } else {
     192:
     193:         /*
     194: 	     * The address should be a member of the address list returned by
     195: 	     * gethostbyname(). We should first verify that the h_addrtype
     196: 	     * field is AF_INET, but this program has already caused too much
     197: 	     * grief on systems with broken library code.
     198: 	     */
     199:
     200:         for (i = 0; hp->h_addr_list[i]; i++) {
     201:         if (memcmp(hp->h_addr_list[i],
     202:                (char *) &sin->sin_addr,
     203:                sizeof(sin->sin_addr)) == 0)
     204:             return;         /* name is good, keep it */
     205:         }
     206:
     207:         /*
     208: 	     * The host name does not map to the initial address. Perhaps
     209: 	     * someone has messed up. Perhaps someone compromised a name
     210: 	     * server.
     211: 	     */
     212:
     213:         tcpd_warn("host name/address mismatch: %s != %s",
     214:               inet_ntoa(sin->sin_addr), hp->h_name);
     215:     }
     216:     strcpy(host->name, paranoid);       /* name is bad, clobber it */
     217:     }
     218: }
     219:
     220: /* sock_sink - absorb unreceived IP datagram */
     221:
     222: static void sock_sink(fd)
     223: int     fd;
     224: {
     225:     char    buf[BUFSIZ];
     226:     struct sockaddr_in sin;
     227:     int     size = sizeof(sin);
     228:
     229:     /*
     230:      * Eat up the not-yet received datagram. Some systems insist on a
     231:      * non-zero source address argument in the recvfrom() call below.
     232:      */
     233:
     234:     (void) recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *) & sin, &size);
     235: }

#### Defined functions

gethostbyname_dot defined in line 51; used 1 times

- in line 69

sock_host defined in line 74; used 3 times

- in /usr/src/libexec/tcpd/fromhost.c line 48
- in /usr/src/libexec/tcpd/ptx.c line 74
- in /usr/src/libexec/tcpd/tcpd.h line 130

sock_hostaddr defined in line 125; used 2 times

- in /usr/src/libexec/tcpd/tcpd.h line 132-134(2)

sock_hostname defined in line 136; used 2 times

- in /usr/src/libexec/tcpd/tcpd.h line 131-134(2)

sock_sink defined in line 222; used 2 times

- in line 41, 96

#### Defined variables

sccsid defined in line 19; never used

#### Defined macros

gethostbyname defined in line 69; used 3 times

- in line 62-65(2), 169

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