[comp.sources.misc] v20i008: log_tcp - Package to monitor and control TCP/IP connections, Part01/01

wietse@wzv.win.tue.nl (Wietse Venema) (05/22/91)

Submitted-by: Wietse Venema <wietse@wzv.win.tue.nl>
Posting-number: Volume 20, Issue 8
Archive-name: log_tcp/part01
Supersedes: log_tcp: Volume 16, Issue 62

This package provides a couple of tiny programs that log all requests
to connection-oriented tcp/ip services (examples: FINGER, SYSTAT, FTP,
TELNET, RLOGIN, RSH, EXEC), with optional access control on the basis
of host (or domain) names, internet addresses (or network numbers) and
daemon process names.

The programs are nothing but small front ends. By default, they just
log the remote host name and then invoke the real daemon. The programs
should not require any changes to existing software or configuration
files.

Enhancements over the previous release are: protection against rlogin
and rsh attacks through compromised domain name servers, optional
netgroup support for systems with NIS (formerly YP), and an extension
of the wild card patterns supported by the access control files.

	Wietse Venema (wietse@wzv.win.tue.nl),
	Eindhoven University of Technology,
	The Netherlands.
---------
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  README miscd.c tcpd.c fromhost.c hosts_access.c Makefile
#   hosts_access.5 strcasecmp.c BLURB
# Wrapped by wietse@wzv on Mon May 20 13:35:39 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f README -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"README\"
else
echo shar: Extracting \"README\" \(8553 characters\)
sed "s/^X//" >README <<'END_OF_README'
X@(#) README 1.4 91/05/20 13:30:17
X
XGeneral description:
X--------------------
X
XWith this package you can monitor connections to the SYSTAT, FINGER,
XFTP, TELNET, RLOGIN, RSH and EXEC network services.  Connections are
Xlogged through the syslog(3) facility. A requirement is that daemons
Xare started by the inetd program or something similar.
X
XThe programs are tiny front ends that just report the remote host name
Xand then invoke the real network daemon.  In the most common case, no
Xchanges should be required to existing software or to configuration
Xfiles.  Just move the vendor-provided daemons to another place and
Xinstall the front ends into their original places. Installation details
Xare given below.
X
XEarly versions of the programs were tested with Ultrix >= 2.2, with
XSunOS >= 3.4 and ISC 2.2. The first official release has been installed
Xon a wide variety of systems (BSD, SYSV, Apollo) without modification.
XThe present release should still run on top of most BSD-style TCP/IP
Ximplementations.
X
XOptional feature:
X-----------------
X
XWhen compiled with -DHOSTS_ACCESS, the front-end programs support a
Xsimple form of access control that is based on host (or domain) names,
Xinternet addresses or network numbers, network daemon process names and
X(optionally) netgroups (a NIS, formerly YP, feature).  Wild cards are
Xsupported.  If a host requests connection to a network daemon, and if
Xthe (daemon, host) pair is matched by an entry in the /etc/hosts.allow
Xfile, access is granted.  Otherwise, if the (daemon, host) pair is
Xmatched by an entry in the /etc/hosts.deny file, access is denied.
XOtherwise, access is granted.  More details are provided in the
Xhosts_access(5) manual page.  This form of access control may be useful
Xif it can not be implemented at a more suitable level (such as an
Xinternet router).
X
XMajor enhancement:
X------------------
X
XIt has been brought to my attention that authentication based on host
Xaddress to host name mapping can easily be spoofed by playing games
Xwith some domain name server.  A little research led me to the conclusion
Xthat many existing rshd and rlogind implementations do not account for
Xthis potential problem.
X
XThe present versions of the front-end programs provide a way to take
Xcare of the problem.  After mapping a client host address to a host
Xname, the front-end programs now verify that the host name maps to the
Xsame host address.  The idea is that it is much easier to compromise
Xthe address->name map of some random name server than to compromise the
Xname->address map that is specific to your domain.  If the source is
Xcompiled with -DPARANOID, the front ends justs drop the connection in
Xcase of a host name/address mismatch. Otherwise, the front ends just
Xignore the bad host name and use the host address when consulting the
Xaccess control files.
X
XMinor enhancements: 
X-------------------
X
XThe host access control files now support more types of wild cards and
X(optionally) allow the use of netgroup names.  Netgroup support is
Xusually available on systems with NIS (formerly YP) software.
X
XRelated software:
X-----------------
X
XVersions of rshd and rlogind, hacked to report the remote user name as
Xwell, are available for anon ftp (ftp.win.tue.nl:/pub/logdaemon.tar.Z).  
XThat archive also contains a tftpd source that logs the remote host
Xname (nice if you want to know who is interested in your /etc/passwd
Xfile).  All those programs have been tested only with SunOS >= 4.0.
X
XAnother way to manage access to tcp/ip services is illustrated by the
Xservers provided with the authutil package (comp.sources.unix volume
X22). This has the advantage that one will get the remote username from
Xany host supporting RFC 931 security.  By installing the auth package
X(same volume) one supports RFC 931 security too (but you will have to
Xbelieve what the remote host tells you).  Eventually one can start
Xcutting off unauthenticated connections. This is obviously a much more
Xadvanced approach than what my front-end programs provide. The present
Xpackage is more suitable for those who lack the resources to install
Xanything that requires more than just renaming a couple of executables.
X
XConfiguration and installation (the easy way):
X----------------------------------------------
X
XAn advanced installation recipe is given lateron. The "easy way" recipe
Xrequires no changes to existing software or configuration files.
X
XIf you don't run Ultrix, you don't need the miscd front-end program.
XThe Ultrix miscd daemon implements among others the SYSTAT service,
Xwhich pipes the output from the WHO command to standard output.
X
XBy default, the front-end programs assume that the vendor-provided
Xdaemons will be moved to the "/usr/etc/..." directory.  If you want
Xsomething else, adjust the REAL_DAEMON and the REAL_DAEMON_DIR macros
Xin the files miscd.c and tcpd.c.
X
XBy default, connections are logged to the same place where the sendmail
Xlog entries go.  If connections should be logged elsewhere, adjust the
XLOG_MAIL macro in the miscd.c and tcpd.c files, and update your syslog
Xconfiguration file (usually, /etc/syslog.conf).  Most Ultrix versions 
Xdo not provide this flexibility, though.
X
XBy default, the front-end programs support host access control.  Access
Xcontrol is turned off when the /etc/hosts.{allow,deny} files do not
Xexist. If you do not need support for host access control, adjust the
Xmakefile so that the programs are compiled without -DHOSTS_ACCESS.
XNote:  the host access control facility requires the strchr(), strspn()
Xand strtok() routines.
X
XIf your C library does not provide the strcasecmp() routine, adjust the
XAUX_OBJ macro in the Makefile so that it uses the strcasecmp() version
Xprovided with this package.
X
XIn the Makefile, add -Dmemcmp=bcmp to the CFLAGS macro if your system
Xdoes not have memcmp(), and add -DNETGROUP to the CFLAGS macro if your
Xsystem supports netgroups.
X
XCompile with -DPARANOID if you want to drop connections when a remote
Xhost name does not agree with the remote host address. This helps 
Xagainst attacks through compromised domain name servers, but may
Xoccasionally cause a perfectly legal connection to be refused due to
Xtransient name server lookup problems.
X
XThe tcpd program is intended for monitoring connections to the telnet,
Xfinger, ftp, exec, rsh and rlogin services. Decide which services you
Xwant to be monitored. Move the vendor-provided daemon programs to the
Xlocation specified by the REAL_DAEMON_DIR macro in the file tcpd.c, and
Xcopy the tcpd front end to the locations where the vendor-provided
Xdaemons used to be. That is, one copy of the tcpd front end for each
Xservice that you want to monitor.
X
XUltrix only: if you want to monitor connections to the SYSTAT service,
Xmove the vendor-provided miscd daemon to the location specified by the
XREAL_DAEMON macro in the miscd.c file, and install the miscd front end
Xinto the original miscd location.
X
XConfiguration and installation (the advanced way):
X--------------------------------------------------
X
XInstead of moving the vendor-provided daemons to another directory,
Xdefine the REAL_DAEMON_DIR to reflect the present location of those
Xdaemons, and install the tcpd command in the same directory. Then do
Xthe following edits to the inetd configuration file (usually in
X/etc/inetd.conf):
X
X    telnet  stream  tcp     nowait  root    /usr/etc/in.telnetd     in.telnetd
X
Xbecomes:
X
X    telnet  stream  tcp     nowait  root    /usr/etc/tcpd           in.telnetd
X
X(the example applies to SunOS 4.x; other UNIX implementations should
Xnot differ much). Similar changes will be needed for the other services
Xthat are to be covered by the tcpd front-end program.
X
XApollo UNIX users will want to install the front end under a different
Xname because tcpd is the name of an already existing command. A suitable 
Xname for the front-end program would be "frontd".
X
XThe same trick can be played with the Ultrix miscd daemon but then the
Xdaemon front end will have to be installed under a different name.
X
XAcknowledgements:
X-----------------
X
XThanks to Brendan Kehoe (brendan@cs.widener.edu), Heimir Sverrisson
X(heimir@hafro.is) and Dan Bernstein (brnstnd@kramden.acf.nyu.edu) for
Xfeedback on an earlier release of this product.  Thanks to John Kimball
X(jkimball@src.honeywell.com) for suggesting the host name to host
Xaddress mapping check. Willem-Jan Withagen (wjw@eb.ele.tue.nl) provided
Xuseful information on how to deal with the Apollo UNIX environment.
X
X	Wietse Venema (wietse@wzv.win.tue.nl),
X	Mathematics and Computing Science,
X	Eindhoven University of Technology,
X	The Netherlands.
END_OF_README
if test 8553 -ne `wc -c <README`; then
    echo shar: \"README\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f miscd.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"miscd.c\"
else
echo shar: Extracting \"miscd.c\" \(1709 characters\)
sed "s/^X//" >miscd.c <<'END_OF_miscd.c'
X /*
X  * Front end to the ULTRIX miscd service. The front end logs the remote host
X  * name and then invokes the real miscd daemon. Install as "/usr/etc/miscd",
X  * after moving the real miscd daemon to the "/usr/etc/..." directory.
X  * Connections and diagnostics are logged through syslog(3).
X  * 
X  * The Ultrix miscd program implements the systat service, which pipes the
X  * output from who(1) to stdout. This information is potentially useful to
X  * systems crackers.
X  * 
X  * Compile with -DHOSTS_ACCESS in order to enable access control. See the
X  * hosts_access(5) manual page for details.
X  * 
X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
X  */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#) miscd.c 1.1 91/01/06 22:30:32";
X#endif
X
X#include <stdio.h>
X#include <syslog.h>
X
X/* The following specifies where the vendor-provided daemon should go. */
X
X#define REAL_DAEMON	"/usr/etc/.../miscd"
X
Xmain(argc, argv)
Xint     argc;
Xchar  **argv;
X{
X    char   *fromhost();
X    char   *host_name;
X
X    /*
X     * Open a channel to the syslog daemon. Older versions of openlog()
X     * require only two arguments.
X     */
X
X#ifdef LOG_MAIL
X    (void) openlog(argv[0], LOG_PID, LOG_MAIL);
X#else
X    (void) openlog(argv[0], LOG_PID);
X#endif
X
X    /* Find out and report the remote host name. */
X
X    if ((host_name = fromhost()) == 0)
X	host_name = "unknown";
X    syslog(LOG_INFO, "connect from %s", host_name);
X
X    /* Check whether this host can access the service in argv[0]. */
X
X#ifdef HOSTS_ACCESS
X    hosts_access(argv[0], host_name);
X#endif
X
X    /* Invoke the real daemon program. */
X
X    (void) execv(REAL_DAEMON, argv);
X    syslog(LOG_ERR, "%s: %m", REAL_DAEMON);
X    return (1);
X}
END_OF_miscd.c
if test 1709 -ne `wc -c <miscd.c`; then
    echo shar: \"miscd.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f tcpd.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"tcpd.c\"
else
echo shar: Extracting \"tcpd.c\" \(1873 characters\)
sed "s/^X//" >tcpd.c <<'END_OF_tcpd.c'
X /*
X  * General front end for connection-oriented tcp/ip services. This program
X  * logs the remote host name and then invokes the real daemon. For example,
X  * install as /usr/etc/{fingerd,telnetd,ftpd,rlogind,rshd,rexecd}, after
X  * saving the real daemons in the directory "/usr/etc/...". This arrangement
X  * requires that the network daemons are started by inetd or something
X  * similar. Connections and diagnostics are logged through syslog(3).
X  * 
X  * Compile with -DHOSTS_ACCESS in order to enable access control. See the
X  * hosts_access(5) manual page for details.
X  * 
X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
X  */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#) tcpd.c 1.1 91/01/06 22:30:36";
X#endif
X
X#include <stdio.h>
X#include <syslog.h>
X#include <sys/types.h>
X#include <sys/param.h>
X#ifndef MAXPATHNAMELEN
X#define MAXPATHNAMELEN	BUFSIZ
X#endif
X
X/* The following specifies where the vendor-provided daemons should go. */
X
X#define REAL_DAEMON_DIR	"/usr/etc/..."
X
Xmain(argc, argv)
Xint     argc;
Xchar  **argv;
X{
X    char   *fromhost();
X    char   *host_name;
X    char    path[MAXPATHNAMELEN];
X
X    /*
X     * Open a channel to the syslog daemon. Older versions of openlog()
X     * require only two arguments.
X     */
X
X#ifdef LOG_MAIL
X    (void) openlog(argv[0], LOG_PID, LOG_MAIL);
X#else
X    (void) openlog(argv[0], LOG_PID);
X#endif
X
X    /* Find out and report the remote host name. */
X
X    if ((host_name = fromhost()) == 0)
X	host_name = "unknown";
X    syslog(LOG_INFO, "connect from %s", host_name);
X
X    /* Check whether this host can access the service in argv[0]. */
X
X#ifdef HOSTS_ACCESS
X    hosts_access(argv[0], host_name);
X#endif
X
X    /* Invoke the real daemon program. */
X
X    (void) sprintf(path, "%s/%s", REAL_DAEMON_DIR, argv[0]);
X    (void) execv(path, argv);
X    syslog(LOG_ERR, "%s: %m", path);
X    return (1);
X}
END_OF_tcpd.c
if test 1873 -ne `wc -c <tcpd.c`; then
    echo shar: \"tcpd.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f fromhost.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"fromhost.c\"
else
echo shar: Extracting \"fromhost.c\" \(3982 characters\)
sed "s/^X//" >fromhost.c <<'END_OF_fromhost.c'
X /*
X  * fromhost() returns the name of the host at the other end of standard
X  * input, the host address if name lookup fails, "stdin" if it is connected
X  * to a terminal, or a null pointer in all other cases.
X  * 
X  * Protection against spoofing of naive rsh and rlogind implementations:
X  * 
X  * Initially, all we have is the remote host address. If the host address->name
X  * mapping is available, fromhost() verifies that the host name->address
X  * mapping yields the original host address. The idea is that it is much
X  * easier to compromise some random address->name map (because there is one
X  * for almost every network), than to compromise the name->address map that
X  * is unique for your internet domain.
X  * 
X  * Anyway, if the test fails, fromhost() either drops the connection (when
X  * compiled with -DPARANOID) or just returns the remote host address instead
X  * of the bad remote host name (not compiled with -DPARANOID).
X  * 
X  * Diagnostics are reported through syslog(3).
X  * 
X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
X  */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#) fromhost.c 1.2 91/05/20 13:28:01";
X#endif
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/param.h>
X#include <sys/socket.h>
X#include <syslog.h>
X#include <netinet/in.h>
X#include <netdb.h>
X
X#ifndef MAXHOSTNAMELEN
X#define MAXHOSTNAMELEN	BUFSIZ
X#endif
X
X/* The following are to be used in assignment context, not in comparisons */
X
X#define	GOOD	1
X#define	BAD	0
X
X/* fromhost - find out what is at the other end of standard input */
X
Xchar   *fromhost()
X{
X    struct sockaddr sa;
X    struct sockaddr_in *sin = (struct sockaddr_in *) (&sa);
X    struct hostent *hp;
X    int     sockt = fileno(stdin);
X    int     length = sizeof(sa);
X    static char remotehost[MAXHOSTNAMELEN + 1];
X    char   *inet_ntoa();
X    char   *strncpy();
X
X    /* Try to be smart if standard input is not connected to a socket. */
X
X    if (getpeername(sockt, &sa, &length) < 0) {
X	if (isatty(sockt)) {
X	    return ("stdin");
X	} else {
X	    syslog(LOG_ERR, "getpeername: %m");
X	    return (0);
X	}
X    }
X    if (sa.sa_family != AF_INET) {
X	syslog(LOG_ERR, "unknown address family %ld", (long) sa.sa_family);
X	return (0);
X    }
X    /* Look up the remote host name. Use its address if name lookup fails. */
X
X    if ((hp = gethostbyaddr((char *) &sin->sin_addr.s_addr,
X			    sizeof(sin->sin_addr.s_addr),
X			    AF_INET)) == 0) {
X	return (inet_ntoa(sin->sin_addr));
X    }
X    /* Save the host name before the gethostbyxxx() routines clobber it. */
X
X    (void) strncpy(remotehost, hp->h_name, sizeof(remotehost) - 1);
X    remotehost[sizeof(remotehost) - 1] = 0;
X
X    /*
X     * Decide what to do if the host name does not match the address or if we
X     * are unable to verify that the host name matches the address.
X     */
X
X    if (matchname(remotehost, sin)) {
X	return (remotehost);
X    } else {
X#ifdef	PARANOID
X	exit(0);
X#else
X	return (inet_ntoa(sin->sin_addr));
X#endif
X    }
X}
X
X/* matchname - determine if host name matches address */
X
Xstatic int matchname(remotehost, sin)
Xchar   *remotehost;
Xstruct sockaddr_in *sin;
X{
X    struct hostent *hp;
X    int     i;
X
X    if ((hp = gethostbyname(remotehost)) == 0) {
X
X	/*
X	 * Unable to verify that the host name matches the address. This may be
X	 * a transient problem or a botched name server setup.
X	 */
X
X	syslog(LOG_ERR, "gethostbyname(%s): lookup failure", remotehost);
X	return (BAD);
X    } else {
X
X	/* Look up the host address in the address list we just got. */
X
X	for (i = 0; hp->h_addr_list[i]; i++) {
X	    if (memcmp(hp->h_addr_list[i], (caddr_t) & sin->sin_addr,
X		       sizeof(sin->sin_addr)) == 0)
X		return (GOOD);
X	}
X
X	/*
X	 * The host name does not map to the host address. Perhaps someone
X	 * has compromised a name server. More likely someone botched it, but
X	 * that could be dangerous, too.
X	 */
X
X	syslog(LOG_ERR, "host name/address mismatch: %s != %s",
X	       inet_ntoa(sin->sin_addr), hp->h_name);
X	return (BAD);
X    }
X}
END_OF_fromhost.c
if test 3982 -ne `wc -c <fromhost.c`; then
    echo shar: \"fromhost.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f hosts_access.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"hosts_access.c\"
else
echo shar: Extracting \"hosts_access.c\" \(4992 characters\)
sed "s/^X//" >hosts_access.c <<'END_OF_hosts_access.c'
X#ifdef HOSTS_ACCESS
X
X /*
X  * This module implements a simple but effective form of access control
X  * based on host (or domain) names, netgroup, internet addresses (or network
X  * numbers) and daemon process names, with wild card support.
X  * 
X  * Diagnostics are reported through syslog(3).
X  * 
X  * Compile with -DHOSTS_ACCESS in order to enable access control. See the
X  * hosts_access(5) manual page for details.
X  * 
X  * Compile with -DNETGROUP if your library provides support for netgroups.
X  * 
X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
X  */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#) hosts_access.c 1.5 91/05/20 13:28:03";
X#endif
X
X#include <stdio.h>
X#include <syslog.h>
X#include <ctype.h>
X
Xextern char *fgets();
Xextern char *strchr();
Xextern char *strtok();
Xextern void exit();
X
X /* Path names of the access control files. */
X
X#define HOSTS_ALLOW	"/etc/hosts.allow"
X#define HOSTS_DENY	"/etc/hosts.deny"
X
X /* Delimiters for lists of daemons or clients. */
X
Xstatic char sep[] = ", \t";
X
X /* Constants to be used in assignments only, not in comparisons... */
X
X#define	YES		1
X#define	NO		0
X
X/* hosts_access - host access control facility */
X
Xhosts_access(daemon, client)
Xchar   *daemon;
Xchar   *client;
X{
X
X    /*
X     * If the (daemon, client) pair is matched by an entry in the file
X     * /etc/hosts.allow, access is granted. Otherwise, if the (daemon,
X     * client) pair is matched by an entry in /etc/hosts.deny, access is
X     * denied. Otherwise, access is granted.
X     * 
X     * If a connection is refused, we write a syslog record, but do not notify
X     * the client.
X     */
X
X    if (table_match(HOSTS_ALLOW, daemon, client))
X	return;
X    if (table_match(HOSTS_DENY, daemon, client)) {
X	syslog(LOG_WARNING, "refused connect from %s", client);
X	exit(0);
X    }
X}
X
X/* table_match - match table entries with (daemon, client) pair */
X
Xint     table_match(table, daemon, client)
Xchar   *table;
Xchar   *daemon;
Xchar   *client;
X{
X    FILE   *fp;
X    char    sv_list[BUFSIZ];		/* becomes list of daemons */
X    char   *cl_list;			/* becomes list of clients */
X    int     match = NO;
X    int     end;
X
X    /*
X     * Process the table one line at a time. Lines that begin with a '#'
X     * character are ignored. Non-comment lines are broken at the ':'
X     * character (we complain if there is none). The left part is matched
X     * against the daemon process name (argv[0]), the right part against the
X     * host name. A non-existing table is treated as if it were an empty
X     * table.
X     */
X
X    if (fp = fopen(table, "r")) {
X	while (!match && fgets(sv_list, sizeof(sv_list), fp)) {
X	    if (sv_list[end = strlen(sv_list) - 1] != '\n') {
X		syslog(LOG_ERR, "%s: line exceeds STDIO buffer size", table);
X	    } else {
X		sv_list[end] = '\0';		/* strip trailing newline */
X	    }
X	    if (sv_list[0] == '#') {		/* skip comments */
X		continue;
X	    } else if ((cl_list = strchr(sv_list, ':')) == 0) {
X		syslog(LOG_ERR, "%s: malformed entry: \"%s\"", table, sv_list);
X		continue;
X	    } else {
X		*cl_list++ = '\0';		/* break line at ":" */
X		match = (list_match(sv_list, daemon)
X			 && list_match(cl_list, client));
X	    }
X	}
X	(void) fclose(fp);
X    }
X    return (match);
X}
X
X/* list_match - match a string against a list of tokens */
X
Xint     list_match(list, string)
Xchar   *list;
Xchar   *string;
X{
X    char   *tok;
X    int     tok_len;
X    int     str_len;
X
X    /*
X     * Process tokens one at a time. If a token has the magic value "ALL" the
X     * match always succeeds. If the token is a domain name, return YES if it
X     * matches the last fields of the string. If the token has the magic
X     * value "LOCAL", return YES if the string does not contain a "."
X     * character. If the token is a network number, return YES if it matches
X     * the head of the string. If the token looks like a netgroup name,
X     * return YES if the string is a (host) member of the netgroup.
X     * Otherwise, return YES if the token fully matches the string. Note: we
X     * assume that a daemon process name never begins or ends with a "." or
X     * "@" character.
X     */
X
X    for (tok = strtok(list, sep); tok; tok = strtok((char *) 0, sep)) {
X	if (tok[0] == '.') {			/* domain: match last fields */
X	    if ((str_len = strlen(string)) > (tok_len = strlen(tok))
X		&& strcasecmp(tok, string + str_len - tok_len) == 0)
X		return (YES);
X#ifdef	NETGROUP
X	} else if (tok[0] == '@') {		/* netgroup: look it up */
X	    if (innetgr(tok + 1, string, (char *) 0, (char *) 0))
X		return (YES);
X#endif
X	} else if (strcasecmp(tok, "ALL") == 0) {	/* all: match any */
X	    return (YES);
X	} else if (strcasecmp(tok, "LOCAL") == 0) {	/* local: no dots */
X	    if (strchr(string, '.') == 0)
X		return (YES);
X	} else if (!strcasecmp(tok, string)) {	/* match host name or address */
X	    return (YES);
X	} else if (tok[(tok_len = strlen(tok)) - 1] == '.'	/* net number */
X		   && strncmp(tok, string, tok_len) == 0) {
X	    return (YES);
X	}
X    }
X    return (NO);
X}
X
X#endif
END_OF_hosts_access.c
if test 4992 -ne `wc -c <hosts_access.c`; then
    echo shar: \"hosts_access.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Makefile -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"Makefile\"
else
echo shar: Extracting \"Makefile\" \(1484 characters\)
sed "s/^X//" >Makefile <<'END_OF_Makefile'
X# @(#) Makefile 1.2 91/05/20 13:28:06
X
X## Begin configuration options
X
X# If you want to enable host access control, define the HOST_ACCESS macro
X# in the  CFLAGS line. For example,
X#
X# CFLAGS = -O -DHOSTS_ACCESS 
X#
X# Note: host access control requires the strtok() and strchr() routines.
X#
X# If your library supports NIS-style netgroups, compile with -DNETGROUP
X#
X# If your C library does not have memcmp(3), compile with -Dmemcmp=bcmp.
X#
X# Compile with -DPARANOID if you want to refuse connections from hosts
X# with names that do not match their address.
X
XCFLAGS	= -O -DHOSTS_ACCESS -DNETGROUP -DPARANOID
X
X# Include the file strcasecmp.o if it is not provided by your C library.
X
XAUX_OBJ	= # strcasecmp.o
X
X# Some System-V versions require that you explicitly specify the networking
X# libraries.
X
XLIBS	=
X
X## End configuration options
X
XTCPD_OBJ= tcpd.o fromhost.o hosts_access.o
XMISC_OBJ= miscd.o fromhost.o hosts_access.o
X
Xall:	tcpd miscd
X
Xtcpd:	$(TCPD_OBJ) $(AUX_OBJ)
X	$(CC) $(CFLAGS) -o $@ $(TCPD_OBJ) $(AUX_OBJ) $(LIBS)
X
Xmiscd:	$(MISC_OBJ) $(AUX_OBJ)
X	$(CC) $(CFLAGS) -o $@ $(MISC_OBJ) $(AUX_OBJ) $(LIBS)
X
Xshar:	
X	@shar README miscd.c tcpd.c fromhost.c hosts_access.c Makefile \
X	hosts_access.5 strcasecmp.c BLURB
X
Xarchive:
X	$(ARCHIVE) README miscd.c tcpd.c fromhost.c hosts_access.c Makefile \
X	hosts_access.5 strcasecmp.c BLURB
X
Xclean:
X	rm -f tcpd miscd *.o core
X
Xlint:
X	lint -DHOSTS_ACCESS tcpd.c fromhost.c hosts_access.c
X	lint -DHOSTS_ACCESS miscd.c fromhost.c hosts_access.c
END_OF_Makefile
if test 1484 -ne `wc -c <Makefile`; then
    echo shar: \"Makefile\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f hosts_access.5 -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"hosts_access.5\"
else
echo shar: Extracting \"hosts_access.5\" \(3901 characters\)
sed "s/^X//" >hosts_access.5 <<'END_OF_hosts_access.5'
X.TH HOSTS_ACCESS 5
X.ad
X.fi
X.SH NAME
Xhosts_access \- host access control files
X.SH DESCRIPTION
X.ad
X.fi
XThis manual page describes a simple, but effective, access control
Xfacility that is based on host (or domain) names, netgroups, internet
Xaddresses (or network numbers) and on network daemon process names.
X.PP
XIn the following text, \fIdaemon\fP is the the process name (argv[0]
Xvalue) of a network daemon process, and \fIclient\fP is the name or
Xinternet address of a host.
X.IP o
XAccess will be granted if a (daemon,client) pair is matched by an
Xentry in the \fI/etc/hosts.allow\fP file.
X.IP o
XIf the previous test fails (perhaps because the \fIhosts.allow\fP file
Xdoes not exist), access will be denied if a (daemon,client) pair is
Xmatched by an entry in the \fI/etc/hosts.deny\fP file.
X.IP o
XIf the previous test fails (perhaps because the \fIhosts.deny\fP file
Xdoes not exist), access will be granted.
X.PP
XA non-existing access control file is treated as if it were an empty
Xfile. Thus, access control can be turned off by providing no access
Xcontrol files.
X.PP
XThe format of the access control files is as follows.
X.IP o
XLines that begin with a `#' character are ignored.
X.IP o
XOther lines should have the format:
X.sp
X.ti +5
Xdaemon_list : client_list
X.LP
X\fIdaemon_list\fP is a list of one or more daemon process names
X(argv[0] values); \fIclient_list\fP is a list of one or more host
Xnames, domain names, netgroups, internet addresses or internet network
Xnumbers.  List elements should be separated by blanks or commas.  With
Xthe exception of netgroup lookups, all access control code is case
Xinsensitive.
X.PP
XClient_list fields that specify a \fIdomain name\fP should begin with a
X`.' character (see example below). Internet \fInetwork numbers\fP (as
Xopposed to internet \fIhost numbers\fP) should be terminated with a `.'
Xcharacter. A \fInetgroup\fP name should begin with the `@' character.
XNetgroups are usually supported on systems with NIS (formerly YP)
Xdata bases.
X.PP
XSpecial meaning is given to the magic token \fIALL\fP.  If it appears
Xin the \fIdaemon_list\fP part of a line, this token matches all network
Xdaemon process names.  If the magic token appears in the
X\fIclient_list\fP part of a line, it matches all clients.
X.PP
XAnother token that receives special treatment is \fILOCAL\fP. It
Xmatches any string that does not contain a dot character.
X.SH EXAMPLES
XThe following example restricts all services to hosts within the local
Xdomain (no `.' character in the host name), \fIhost.dom.ain\fP, and all
Xhosts below the \fI.some.domain\fP:
X.PP
X/etc/hosts.allow:
X.in +5
XALL: LOCAL, host.dom.ain, .some.domain
X.PP
X/etc/hosts.deny:
X.in +5
XALL: ALL
X.PP
XA similar example, but using netgroup names:
X.PP
X/etc/hosts.allow:
X.in +5
XALL: @netgroupname
X.PP
X/etc/hosts.deny:
X.in +5
XALL: ALL
X.PP
XIn order to deny some hosts all services, except ftp:
X.PP
X/etc/hosts.allow:
X.in +5
Xin.ftpd: ALL
X.PP
X/etc/hosts.deny
X.in +5
XALL: some.host.name, .some.domain
X.SH DIAGNOSTICS
X.ad
X.fi
XA syslog record is produced when a connection is refused; when a syntax
Xerror is found in a host access control file; when the length of a line
Xin a host access control file exceeds the stdio(3) buffer size.
X.SH FILES
X.na
X.nf
X/etc/hosts.allow, (daemon,client) pairs that are granted access.
X/etc/hosts.deny, (daemon,client) pairs that are denied access.
X.SH BUGS
X.ad
X.fi
XIf there are problems with a name server, the access control software
Xwill use a host\'s address instead of its name.  A workaround is to
Xalso list internet addresses and network numbers in the access-control
Xfiles.
X.PP
XDomain name server lookups are case insensitive; NIS (formerly YP)
Xnetgroup lookups are case sensitive.
X.SH AUTHOR
X.na
X.nf
XWietse Venema
XEindhoven University of Technology
XDepartment of Mathematics and Computer Science
XDen Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
X\" @(#) hosts_access.5 1.7 91/05/20 13:28:08
END_OF_hosts_access.5
if test 3901 -ne `wc -c <hosts_access.5`; then
    echo shar: \"hosts_access.5\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f strcasecmp.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"strcasecmp.c\"
else
echo shar: Extracting \"strcasecmp.c\" \(3767 characters\)
sed "s/^X//" >strcasecmp.c <<'END_OF_strcasecmp.c'
X/*
X * Copyright (c) 1987 Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by the University of California, Berkeley.  The name of the
X * University may not be used to endorse or promote products derived
X * from this software without specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X */
X
X#if defined(LIBC_SCCS) && !defined(lint)
Xstatic char sccsid[] = "@(#)strcasecmp.c	5.6 (Berkeley) 6/27/88";
X#endif /* LIBC_SCCS and not lint */
X
X#include <sys/types.h>
X
X/*
X * This array is designed for mapping upper and lower case letter
X * together for a case independent comparison.  The mappings are
X * based upon ascii character sequences.
X */
Xstatic u_char charmap[] = {
X	'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
X	'\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
X	'\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
X	'\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
X	'\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
X	'\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
X	'\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
X	'\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
X	'\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
X	'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
X	'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
X	'\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
X	'\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
X	'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
X	'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
X	'\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
X	'\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
X	'\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
X	'\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
X	'\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
X	'\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
X	'\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
X	'\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
X	'\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
X	'\300', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
X	'\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
X	'\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
X	'\370', '\371', '\372', '\333', '\334', '\335', '\336', '\337',
X	'\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
X	'\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
X	'\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
X	'\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
X};
X
Xstrcasecmp(s1, s2)
X	char *s1, *s2;
X{
X	register u_char	*cm = charmap,
X			*us1 = (u_char *)s1,
X			*us2 = (u_char *)s2;
X
X	while (cm[*us1] == cm[*us2++])
X		if (*us1++ == '\0')
X			return(0);
X	return(cm[*us1] - cm[*--us2]);
X}
X
Xstrncasecmp(s1, s2, n)
X	char *s1, *s2;
X	register int n;
X{
X	register u_char	*cm = charmap,
X			*us1 = (u_char *)s1,
X			*us2 = (u_char *)s2;
X
X	while (--n >= 0 && cm[*us1] == cm[*us2++])
X		if (*us1++ == '\0')
X			return(0);
X	return(n < 0 ? 0 : cm[*us1] - cm[*--us2]);
X}
END_OF_strcasecmp.c
if test 3767 -ne `wc -c <strcasecmp.c`; then
    echo shar: \"strcasecmp.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f BLURB -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"BLURB\"
else
echo shar: Extracting \"BLURB\" \(1412 characters\)
sed "s/^X//" >BLURB <<'END_OF_BLURB'
X@(#) BLURB 1.3 91/05/20 13:28:10
X
XThis package provides a couple of tiny programs that log all requests
Xto connection-oriented tcp/ip services (examples: FINGER, SYSTAT, FTP,
XTELNET, RLOGIN, RSH, EXEC), with optional access control on the basis
Xof host (or domain) names, internet addresses (or network numbers) and
Xdaemon process names.
X
XThe programs are nothing but small front ends. By default, they just
Xlog the remote host name and then invoke the real daemon. The programs
Xshould not require any changes to existing software or configuration
Xfiles.
X
XConnections are reported through the syslog(3) facility. Each record
Xcontains a time stamp, the remote host name and the name of the service
Xrequested. Such information can be useful to detect break-in attempts
Xor other undesirable activities, especially when logfile information
Xfrom several hosts is merged.
X
XThe optional access-control facility may be useful when, for whatever
Xreason, it is not possible to handle access control at a more suitable
Xlevel (such as an internet router).
X
XEnhancements over the previous release are: protection against rlogin
Xand rsh attacks through compromised domain name servers, optional
Xnetgroup support for systems with NIS (formerly YP), and an extension
Xof the wild card patterns supported by the access control files.
X
X	Wietse Venema (wietse@wzv.win.tue.nl),
X	Eindhoven University of Technology,
X	The Netherlands.
END_OF_BLURB
if test 1412 -ne `wc -c <BLURB`; then
    echo shar: \"BLURB\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0

exit 0 # Just in case...
-- 
Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD           UUCP:     uunet!sparky!kent
Phone:    (402) 291-8300         FAX:      (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.