authd - RFC 931 (Authentication Server) implementation

Dan Bernstein brnstnd at kramden.acf.nyu.edu
Thu Feb 7 15:54:40 AEST 1991


If host X supports RFC 931, and if joe at X and sally at Y are connected
through TCP, then sally can find out the name of joe. This package
includes authd, an RFC 931 server. Once you've installed it, your users
can't escape the authentication: if they telnet or rlogin or send mail
or do whatever to another host, that host can find out the username.

This package also includes a library that acts as an RFC 931 client. You
don't need privileges to use the library, which should compile and run
without trouble on any BSD-derived system. (authd is not so portable;
although it works without changes under SunOS and Ultrix, it might not
work on other systems. The package includes a couple of test programs.)

I've placed this code into the public domain because I think that
everyone should support at least this level of security. I'm sick of
seeing people forge mail and spoof NNTP and attack systems anonymously
through the network. Now they won't be able to, because every connection
will be tagged with the username with at least as much security as the
TCP host address in each packet. I hope that every site will do its part
to contribute to network security (and to help CERT trace intruders).

It should take approximately 10 minutes to read the instructions and
compile, install, and test authd on a new machine. It should take
approximately 2 minutes on each new machine once you're familiar with
the instructions. Send comments on these estimates to brnstnd at nyu.edu,
cc the Office of Management and Budget, Paperwork Reduction Division.

---Dan

#! /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:  FILES README FORMLETTER CHANGES INSTALL Makefile authd.8
#   authuser.3 tcpuid.8 tcpuname.8 authd.c authuser.h authuser.c
#   test.c netstatuid rfc931
# Wrapped by brnstnd at kramden on Wed Feb  6 23:19:18 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'FILES' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'FILES'\"
else
echo shar: Extracting \"'FILES'\" \(143 characters\)
sed "s/^X//" >'FILES' <<'END_OF_FILE'
XFILES
XREADME
XFORMLETTER
XCHANGES
XINSTALL
XMakefile
Xauthd.8
Xauthuser.3
Xtcpuid.8
Xtcpuname.8
Xauthd.c
Xauthuser.h
Xauthuser.c
Xtest.c
Xnetstatuid
Xrfc931
END_OF_FILE
if test 143 -ne `wc -c <'FILES'`; then
    echo shar: \"'FILES'\" unpacked with wrong size!
fi
# end of 'FILES'
fi
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(5011 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
Xauthd - authentication server daemon
Xtcpuid, tcpuname - find out which user owns a connection
Xauthuser - remote authentication library
X
Xauthd is a kernel-level implementation of RFC 931, the Authentication
XServer. RFC 931 provides the name of the user owning a TCP connection.
XThis helps network security: unless TCP itself is compromised, it is
Ximpossible to forge mail or news between computers supporting RFC 931.
XIt also becomes much easier to trace attackers than in the current,
Xlargely anonymous, network. authd requires no changes to current code:
Xevery connect() and accept() is authenticated automatically, with no
Xloss of efficiency.
X
Xtcpuid and tcpuname are the same program, but more suitable for local
Xuse from the command line by a user or system administrator. They show
Xwhich local user created a given TCP connection.
X
Xauthuser is a library encapsulating client use of RFC 931. It talks to a
Xremote Authentication Server to find out the username on the other side
Xof a given connection.
X
XOnly root can install authd. However, most current systems are insecure
Xenough that any user can run tcpuid and tcpuname. authuser is meant for
Xuse by any program.
X
X
X
Xauthd version 3.0, February 5, 1991.
XPlaced into the public domain by Daniel J. Bernstein.
XSome of the code in authd was inspired by code written by
XVic Abell, abe at mace.cc.purdue.edu, for the ofiles program.
X
X
XOrganization of README:
X
X1. Files
X2. Requirements
X3. How to configure authd
X4. How to compile authd
X5. How to install authd
X6. TODO list
X
X
X1. Files:
X
XREADME          this file
XFORMLETTER      form letter to send to the author
XFILES           file list
XINSTALL         friendly installation script
XCHANGES         description of changes since first distributed version
XMakefile        compilation commands
Xauthd.c         the authd program
Xauthuser.h      the authuser include file
Xauthuser.c      the authuser library
Xauthd.8         documentation for authd
Xtcpuid.8        documentation for tcpuid
Xtcpuname.8      documentation for tcpuname
Xauthuser.3      documentation for authuser
Xtest.c          program to test authuser and authd
Xnetstatuid      shell script to test tcpuname
Xrfc931          RFC 931, Authentication Server
X
X
X
X2. Requirements
X
Xauthd requires netstat, and it pokes around in several BSD-specific
Xkernel structures. It is not inherently portable code. Nevertheless, it
Xhas been compiled under Ultrix, SunOS, and Convex UNIX, and it probably
Xdoesn't take much work to get running under pretty much any BSD system.
Xauthuser should compile and run without trouble on any BSD system.
X
XYou must be root to install authd. However, authd's sister utilities,
Xtcpuid and tcpuname, will probably work anyway if /dev/kmem is readable.
XAny program can use the authuser library.
X
Xauthd and authuser have been tested on the following systems.
X
X  Sun 4/280, SunOS 4.0.3
X  VAX 8650, Ultrix 4.1
X  DECsystem-5820, Ultrix 4.0
X  DECStation-5400, Ultrix 4.0
X
XIf your machine isn't in this list, and you get the programs working,
X*please* send a note to me at brnstnd at nyu.edu on the Internet describing
Xwhat you had to do to make the programs compile. (Of course, please also
Xlet me know if you have trouble, or if you have comments, questions, or
Xsuggestions.) I'd rather be flooded with reports and be able to compile
Xa more comprehensive list than have no feedback because everyone assumes
Xsomeone else has talked to me first. Use FORMLETTER if you want. Thanks
Xfor being a good sport.
X
X
X
X3. How to configure authd
X
XEither authd.c has the right magic to compile and run on your system, or
Xit doesn't. In the first case you don't have to configure anything, and
Xin the second case automatic configuration would be pretty much
Xhopeless. (If authd doesn't compile, you might try sending me the
Xcompiler output to see if I can figure out how to make it work on your
Xmachine.) The authuser library should compile without trouble in any
Xcase.
X
XYou can change CC or CCOPTS in Makefile if you want. If you want authd
Xto record connections through syslog at LOG_DEBUG, define -DUSE_SYSLOG
Xin the Makefile.
X
X
X
X4. How to compile authd
X
XJust make. This will create authd, tcpuid, tcpuname, authuser.o, and
Xtest.
X
X
X
X5. How to install authd
X
XIf you don't have privileges, skip this part.
X
XBy default, authd, tcpuid, and tcpuname are installed in /etc,
Xauthuser.o is installed as /usr/lib/libauthuser.a, authuser.3 is
Xinstalled in /usr/man/man3, and authd.8, tcpuid.8, and tcpuname.8 are
Xinstalled in /usr/man/man8. The binaries are installed setgid to group
Xkmem. If you want to change these defaults, edit INSTALL.
X
XThen run INSTALL in a root shell; the script will check every action
Xwith you before doing it.
X
XTo test tcpuname, make sure it is in your path, and run netstatuid. You
Xshould get a report of all active network connections including
Xusernames.
X
XTo test authuser and authd, run ./test. You should get an ``everything
Xlooks okay'' message.
X
X
X
X6. TODO list
X
Xfast multiple-connection version of tcpuid/tcpuname, like netstatuid?
END_OF_FILE
if test 5011 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'FORMLETTER' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'FORMLETTER'\"
else
echo shar: Extracting \"'FORMLETTER'\" \(418 characters\)
sed "s/^X//" >'FORMLETTER' <<'END_OF_FILE'
XTo: brnstnd at nyu.edu
XFrom: 
XDate: 
X
XPackage: authd 3.0
XObtained from (e.g., uunet.uu.net): 
XObtained by (e.g., ftp): 
X
X1. Machine architecture (e.g., Sun 4/280): 
X2. Operating system (e.g., SunOS 4.1): 
X3. OS vendor (e.g., Sun): 
X4. Does authd work on your machine so far (yes/no)? 
X5. Describe any problems you've had with authd, tcpuid, or tcpuname.
X
X
X6. Any further questions, comments, or suggestions?
X
X
XYour name:
END_OF_FILE
if test 418 -ne `wc -c <'FORMLETTER'`; then
    echo shar: \"'FORMLETTER'\" unpacked with wrong size!
fi
# end of 'FORMLETTER'
fi
if test -f 'CHANGES' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'CHANGES'\"
else
echo shar: Extracting \"'CHANGES'\" \(43 characters\)
sed "s/^X//" >'CHANGES' <<'END_OF_FILE'
XChange file for authd
X
X
X2/5/91: authd 3.0.
END_OF_FILE
if test 43 -ne `wc -c <'CHANGES'`; then
    echo shar: \"'CHANGES'\" unpacked with wrong size!
fi
# end of 'CHANGES'
fi
if test -f 'INSTALL' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'INSTALL'\"
else
echo shar: Extracting \"'INSTALL'\" \(3474 characters\)
sed "s/^X//" >'INSTALL' <<'END_OF_FILE'
X#!/bin/sh
X
X# Change kmem to staff and mode to 0755 if you don't have a kmem group,
X# or if you don't want normal users to be able to use these utilities.
XMEM=kmem
XMODE=02755
X
X# These must all be in the same filesystem.
XAUTHD=/etc/authd
XTCPUID=/etc/tcpuid
XTCPUNAME=/etc/tcpuname
X
XAUTHUSER=/usr/lib/libauthuser.a
X
X# Man pages.
XMAUTHUSER=/usr/man/man3/authuser.3
XMAUTHD=/usr/man/man8/authd.8
XMTCPUID=/usr/man/man8/tcpuid.8
XMTCPUNAME=/usr/man/man8/tcpuname.8
X
X# Name of port 113 in /etc/services.
XPORTNAME=auth
X
Xecho "Each action will be printed before it is run. Press return to proceed."
X
Xecho "1. Install authd, tcpuid, and tcpuname."
Xecho "! install -c -g $MEM -m $MODE authd $AUTHD: " | tr -d '\012'
Xread line
Xinstall -c -g "$MEM" -m "$MODE" authd "$AUTHD"
X
Xecho "! rm -f $TCPUID; ln $AUTHD $TCPUID: " | tr -d '\012'
Xread line
Xrm -f "$TCPUID"; ln "$AUTHD" "$TCPUID"
X
Xecho "! rm -f $TCPUNAME; ln $AUTHD $TCPUNAME: " | tr -d '\012'
Xread line
Xrm -f "$TCPUNAME"; ln "$AUTHD" "$TCPUNAME"
X
Xecho "2. Install the authuser library."
Xecho "! ar rv $AUTHUSER authuser.o: " | tr -d '\012'
Xread line
Xar rv "$AUTHUSER" authuser.o
X
Xecho "! ranlib $AUTHUSER: " | tr -d '\012'
Xread line
Xranlib "$AUTHUSER"
X
Xecho "! chmod 644 $AUTHUSER: " | tr -d '\012'
Xread line
Xchmod 644 "$AUTHUSER"
X
Xecho "3. Make the man pages available."
Xecho "! install -c -m 0444 authuser.3 $MAUTHUSER: " | tr -d '\012'
Xread line
Xinstall -c -m 0444 authuser.3 "$MAUTHUSER"
X
Xecho "! install -c -m 0444 authd.8 $MAUTHD: " | tr -d '\012'
Xread line
Xinstall -c -m 0444 authd.8 "$MAUTHD"
X
Xecho "! install -c -m 0444 tcpuid.8 $MTCPUID: " | tr -d '\012'
Xread line
Xinstall -c -m 0444 tcpuid.8 "$MTCPUID"
X
Xecho "! install -c -m 0444 tcpuname.8 $MTCPUNAME: " | tr -d '\012'
Xread line
Xinstall -c -m 0444 tcpuname.8 "$MTCPUNAME"
X
Xecho "4. Make sure an auth port is in /etc/services."
Xecho "Let me glance at /etc/services for you..."
Xif grep '^'$PORTNAME'[ 	]*113/tcp' /etc/services >/dev/null 2>&1
Xthen echo "Okay, you have it already. Let's continue."
Xelse echo "Nope, it's not there."
X     echo "Let me check that you don't have a different auth port..."
X     if grep '^'$PORTNAME'[ 	][ 	]*' /etc/services >/dev/null 2>&1
X     then echo "Aaack! $PORTNAME is already used in /etc/services. Exiting."
X	  exit 1
X     fi
X     echo "! echo $PORTNAME'	113/tcp' >> /etc/services: " | tr -d '\012'
X     read line
X     echo "$PORTNAME"'		113/tcp' >> /etc/services
Xfi
X
Xecho "5. Enable auth in /etc/inetd.conf."
Xecho "Let me glance at /etc/inetd.conf for you..."
Xif grep '^'"$PORTNAME"'[ 	]' /etc/inetd.conf >/dev/null 2>&1
Xthen echo "Okay, it's already there. That's it!"
X     exit 0
Xfi
Xif grep 'telnet.*root' /etc/inetd.conf >/dev/null 2>&1
Xthen echo "It's not there yet. Hmmm, looks like you have a Sun-style inetd."
X     echo "! echo $PORTNAME' stream tcp nowait root '$AUTHD' authd' >> /etc/inetd.conf: " | tr -d '\012'
X     read line
X     echo "$PORTNAME"'	stream	tcp	nowait	root	'"$AUTHD"'	authd' >> /etc/inetd.conf
Xelse echo "It's not there yet."
X     echo "! echo $PORTNAME' stream tcp nowait '$AUTHD' authd' >> /etc/inetd.conf: " | tr -d '\012'
X     read line
X     echo "$PORTNAME"'	stream	tcp	nowait	'"$AUTHD"'	authd' >> /etc/inetd.conf
Xfi
X
Xecho "6. Let inetd know about the new service."
Xecho "On most machines you have to % kill -HUP nn"
Xecho "where nn is the number of the inetd process."
Xecho "Here's what ps augx shows about inetd:"
Xps augx | sed -n -e 1p -e /inetd/p
Xecho "I'll leave this step to you. That's it!"
X
Xexit 0
END_OF_FILE
if test 3474 -ne `wc -c <'INSTALL'`; then
    echo shar: \"'INSTALL'\" unpacked with wrong size!
fi
chmod +x 'INSTALL'
# end of 'INSTALL'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(569 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
XCC=cc
XCCOPTS=-g
X
Xdefault: all
X
Xshar: authd.shar
X
Xall: authd tcpuid tcpuname authuser.o test
X
Xauthd: authd.c Makefile
X	$(CC) $(CCOPTS) -o authd authd.c
X
Xtcpuid: authd Makefile
X	rm -f tcpuid
X	ln authd tcpuid
X
Xtcpuname: authd Makefile
X	rm -f tcpuname
X	ln authd tcpuname
X
Xauthuser.o: authuser.c authuser.h Makefile
X	$(CC) $(CCOPTS) -c authuser.c
X
Xtest: authuser.o authuser.h test.c Makefile
X	$(CC) $(CCOPTS) -o test test.c authuser.o
X
Xauthd.shar: FILES
X	shar `cat FILES` > authd.shar
X	chmod 400 authd.shar
X
Xinstall:
X	echo 'Run the INSTALL shell script.'
X
Xclean:
X	rm -f *.o
END_OF_FILE
if test 569 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'authd.8' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'authd.8'\"
else
echo shar: Extracting \"'authd.8'\" \(1531 characters\)
sed "s/^X//" >'authd.8' <<'END_OF_FILE'
X.TH authd 8
X.SH NAME
Xauthd \- Authentication Server daemon
X.SH SYNTAX
Xauthd
X.SH DESCRIPTION
X.I authd
Xis a daemon implementing the
XRFC 931 Authentication Server protocol.
XIt should be invoked by a network server,
Xsuch as
X.I attachport(1)
Xor
X.I inetd(8),
Xfor connections to TCP port 113 (auth).
X.PP
XThe client host
Xgives
X.I authd
Xtwo numbers separated by a comma.
X.I authd
Xinterprets the numbers as TCP port numbers
Xfor the local and remote sides respectively
Xof a TCP connection between this host and the client host.
XIt returns a line of the form
X.EX
Xlocalport, remoteport: USERID: UNIX: username
X.EE
Xwhere username
Xis the name of the user on this side of
Xthe specified connection.
XIf
X.I authd
Xdoes not have an authentication entry for that connection,
Xit returns a line of the form
X.EX
Xlocalport, remoteport: ERROR: UNKNOWN-ERROR.
X.EE
X.PP
X.SH DIAGNOSTICS
X.TP
XNone.
X.SH BUGS
XNone known.
X.SH VERSION
Xauthd version 3.0, February 5, 1991.
X.SH AUTHOR
XPlaced into the public domain by Daniel J. Bernstein.
XPartially inspired by code written by Vic Abell for ofiles.
X.SH REFERENCES
XThe authentication server is more secure than passwords
Xin some ways, but less secure than passwords in many ways.
X(It's certainly better than no password at all---e.g., for
Xmail or news.)
XIt is not the final solution.
XFor an excellent discussion of security problems within
Xthe TCP/IP protocol suite, see
XSteve Bellovin's article
X``Security Problems in the TCP/IP Protocol Suite.''
X.SH "SEE ALSO"
Xauthtcp(1),
Xattachport(1),
Xauthuser(3),
Xtcp(4),
Xinetd(8)
END_OF_FILE
if test 1531 -ne `wc -c <'authd.8'`; then
    echo shar: \"'authd.8'\" unpacked with wrong size!
fi
# end of 'authd.8'
fi
if test -f 'authuser.3' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'authuser.3'\"
else
echo shar: Extracting \"'authuser.3'\" \(3354 characters\)
sed "s/^X//" >'authuser.3' <<'END_OF_FILE'
X.TH authuser 3
X.SH NAME
Xauthuser \- remote authentication library using the Authentication Server
X.SH SYNTAX
X.B #include <authuser.h>
X.PP
X.B unsigned short auth_tcpport;
X.PP
X.B char *auth_xline(user,fd,&in);
X.PP
X.B int auth_fd(fd,&in,&local,&remote);
X.PP
X.B char *auth_tcpuser(in,local,remote);
X.PP
X.B char *user;
X.br
X.B int fd;
X.br
X.B unsigned long in;
X.br
X.B unsigned short local;
X.br
X.B unsigned short remote;
X.SH DESCRIPTION
XThe
X.I authuser
Xlibrary provides a simple interface for
Xfinding out the remote identity
Xof a connection through the
XAuthentication Server
Xas specified by RFC 931.
XUse the -lauthuser loader option
Xto compile a program with this library.
X.PP
X.B auth_xline(user,fd,&in)
Xreturns a line of the form X-Auth-User: user or X-Forgery-By: username,
Xdepending upon what the host on the other side of
X.B fd
Xthinks of the user.
XThis is particularly appropriate for
Xmail and news headers.
X.PP
XIf the remote host reports that
X.B user
Xowns the connection on that side,
X.B auth_xline
Xwill return X-Auth-User: user.
XIf the remote host reports that a different
X.B username
Xowns the connection,
X.B auth_xline
Xwill return X-Forgery-By: username.
XIf user is NULL,
Xit returns X-Auth-User: username
Xwith the username reported by the remote host.
XIf 
X.B fd
Xis not a TCP connection
Xor authentication is impossible,
X.B auth_xline
Xreturns NULL, setting errno appropriately.
X.PP
XThe line is not cr-lf terminated.
XIt is stored in a static area
Xwhich is overwritten on each call to
X.B auth_xline.
X.B auth_xline
Xplaces the Internet address of the other host into in.
X.PP
X.B auth_fd(fd,&in,&local,&remote)
Xretrieves address information from the connection in socket
X.B fd.
XIt places the
XInternet address of the host on other side into
X.B in
Xand the local and remote
XTCP ports into 
X.B local
Xand 
X.B remote.
X.B auth_fd
Xreturns -1 upon error, setting errno appropriately.
X.PP
X.B auth_tcpuser(in,local,remote)
Xreturns the name of the user on the other end of the TCP connection
Xbetween
X.B remote at in
Xand
X.B local.
XIf authentication is impossible,
X.B auth_tcpuser
Xreturns
XNULL, setting errno appropriately.
XThe user name is stored in a static area
Xwhich is overwritten on each call to
X.B auth_tcpuser
Xand
X.B auth_xline.
X.PP
XThe authentication routines check with the
Xremote Authentication Server on port
X.B auth_tcpport,
Xwhich defaults to 113
Xas specified by RFC 931.
XYou can set
X.B auth_tcpport
Xto other values
Xfor nonstandard implementations.
X.PP
X.SH RESTRICTIONS
X.I authuser
Xdoes no backslash interpretation
Xupon the remote user name.
XHopefully the next revision of RFC 931
Xwill make clear exactly what backslash
Xinterpretation should be going on.
X.PP
X.I authuser
Xdoes not use the operating system type
Xinformation provided by the Authentication Server.
X.SH VERSION
Xauthuser version 3.0, February 5, 1991.
X.SH AUTHOR
XPlaced into the public domain by Daniel J. Bernstein.
X.SH REFERENCES
XThe authentication server is more secure than passwords
Xin some ways, but less secure than passwords in many ways.
X(It's certainly better than no password at all---e.g., for
Xmail or news.)
XIt is not the final solution.
XFor an excellent discussion of security problems within
Xthe TCP/IP protocol suite, see
XSteve Bellovin's article
X``Security Problems in the TCP/IP Protocol Suite.''
X.SH "SEE ALSO"
Xauthtcp(1),
Xattachport(1),
Xgetpeername(3),
Xgetsockname(3),
Xtcp(4),
Xauthd(8)
END_OF_FILE
if test 3354 -ne `wc -c <'authuser.3'`; then
    echo shar: \"'authuser.3'\" unpacked with wrong size!
fi
# end of 'authuser.3'
fi
if test -f 'tcpuid.8' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tcpuid.8'\"
else
echo shar: Extracting \"'tcpuid.8'\" \(617 characters\)
sed "s/^X//" >'tcpuid.8' <<'END_OF_FILE'
X.TH tcpuid 8
X.SH NAME
Xtcpuid \- show the user id that created a network connection
X.SH SYNTAX
Xtcpuid
X.I rem.ote.in.addr
X.I remport
X.I loc.al.in.addr
X.I locport
X.SH DESCRIPTION
X.I tcpuid
Xprints the numeric user id of
Xthe user who created
Xthe network connection specified by its arguments.
X.PP
X.SH DIAGNOSTICS
X.TP
XLots, none of which should happen if the specified
Xconnection is valid.
X.SH BUGS
XNone known.
X.SH VERSION
Xtcpuid version 3.0, February 5, 1991.
X.SH AUTHOR
XPlaced into the public domain by Daniel J. Bernstein.
XPartially inspired by code written by Vic Abell for ofiles.
X.SH "SEE ALSO"
Xauthd(8),
Xtcpuname(8)
END_OF_FILE
if test 617 -ne `wc -c <'tcpuid.8'`; then
    echo shar: \"'tcpuid.8'\" unpacked with wrong size!
fi
# end of 'tcpuid.8'
fi
if test -f 'tcpuname.8' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tcpuname.8'\"
else
echo shar: Extracting \"'tcpuname.8'\" \(620 characters\)
sed "s/^X//" >'tcpuname.8' <<'END_OF_FILE'
X.TH tcpuname 8
X.SH NAME
Xtcpuname \- show the user name that created a network connection
X.SH SYNTAX
Xtcpuname
X.I rem.ote.in.addr
X.I remport
X.I loc.al.in.addr
X.I locport
X.SH DESCRIPTION
X.I tcpuname
Xprints the username of
Xthe user who created
Xthe network connection specified by its arguments.
X.PP
X.SH DIAGNOSTICS
X.TP
XLots, none of which should happen if the specified
Xconnection is valid.
X.SH BUGS
XNone known.
X.SH VERSION
Xtcpuname version 3.0, February 5, 1991.
X.SH AUTHOR
XPlaced into the public domain by Daniel J. Bernstein.
XPartially inspired by code written by Vic Abell for ofiles.
X.SH "SEE ALSO"
Xauthd(8),
Xtcpuid(8)
END_OF_FILE
if test 620 -ne `wc -c <'tcpuname.8'`; then
    echo shar: \"'tcpuname.8'\" unpacked with wrong size!
fi
# end of 'tcpuname.8'
fi
if test -f 'authd.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'authd.c'\"
else
echo shar: Extracting \"'authd.c'\" \(7872 characters\)
sed "s/^X//" >'authd.c' <<'END_OF_FILE'
X#define KMEM "/dev/kmem"
X#define VMUNIX "/vmunix"
X#define NETSTAT "/usr/ucb/netstat -n -A -f inet"
X#define NETSTATBUF 200 /* 80 would suffice */
X#define NETSTATREMOTE 49
X#define NETSTATWIDTH 17
X#define REMOTESIZE 100 /* guaranteed to be enough */
X
X#include <stdio.h>
X#include <ctype.h>
X#ifdef USE_SYSLOG
X#include <syslog.h>
X#endif
X#include <sys/types.h>
X#include <sys/param.h>
X#include <sys/dir.h>
X#include <sys/user.h>
X#ifdef convex
X#include <sys/ucred.h> /* dorks */
X#define FCRED_ISNOT_POINTER
X#endif
X#define KERNEL
X#include <sys/file.h>
X#undef KERNEL
X#ifdef BSD
X#include <limits.h>
X#endif
X#include <nlist.h>
X#include <sys/socket.h>
X#include <sys/socketvar.h>
X#ifdef convex
X#include <sys/mbuf.h>
X#endif
X#include <net/route.h>
X#include <netinet/in.h>
X#include <netinet/in_pcb.h>
X#include <netinet/tcp.h>
X#include <netinet/tcp_fsm.h>
X#include <netinet/tcp_timer.h>
X#include <netinet/tcp_var.h>
X#include <arpa/inet.h>
X#include <pwd.h>
Xextern char *calloc();
Xextern long lseek();
X
X#define ZAP(x,err) if (x) if (flagauthd) \
X{printf("%s, %s: ERROR: UNKNOWN-ERROR\r\n",localport,remoteport);exit(37);} \
Xelse { fprintf(stderr,"%s: fatal: %s\n",argv[0],err); exit(37); }
X/* Reporting errors honestly to a remote host could damage security. */
X
Xstatic struct nlist nl[] = { { "_file" }, { "_nfile" }, { "" } };
X#define SFIL 0
X#define SNFILE 1
X
Xstatic char s[NETSTATBUF];
Xstatic char remote[REMOTESIZE];
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X register struct file *xfile;
X register struct file *fp;
X register char *sockloc;
X int nfile;
X struct tcpcb tcp;
X struct inpcb inp;
X struct socket sock;
X struct ucred uc;
X struct file *ftp;
X FILE *fi;
X int fd;
X unsigned long pcbl;
X int pcb;
X int r1; int r2; int r3; int r4; int rp;
X int l1; int l2; int l3; int l4; int lp;
X int uid;
X struct passwd *pw;
X int flagpwnam = 0;
X int flagauthd = 0;
X char localport[10];
X char remoteport[10];
X 
X if ((!strcmp(argv[0],"authd"))
X  || ((strlen(argv[0]) >= 6)
X   && (!strcmp(argv[0] + strlen(argv[0]) - 6,"/authd"))))
X   flagauthd = flagpwnam = 1;
X else
X   if ((!strcmp(argv[0],"tcpuname"))
X    || ((strlen(argv[0]) >= 9)
X     && (!strcmp(argv[0] + strlen(argv[0]) - 9,"/tcpuname"))))
X     flagpwnam = 1;
X
X if (flagauthd)
X  {
X   int ch;
X   int localportlen;
X   int remoteportlen;
X   int loop;
X   struct sockaddr_in sa;
X   int salen;
X
X   localportlen = remoteportlen = loop = 0;
X
X   while ((ch = getchar()) != ',')
X    {
X     if (isascii(ch) && isdigit(ch)) localport[localportlen++] = ch;
X     if (localportlen == 6) /* tough luck! */ exit(2);
X     if ((++loop) > 1000) /* tough luck! */ exit(3);
X    }
X   while ((ch = getchar()) != '\n')
X    {
X     if (isascii(ch) && isdigit(ch)) remoteport[remoteportlen++] = ch;
X     if (remoteportlen == 6) /* tough luck! */ exit(4);
X     if ((++loop) > 1000) /* tough luck! */ exit(5);
X    }
X
X   localport[localportlen] = remoteport[remoteportlen] = 0;
X   lp = atoi(localport);
X   rp = atoi(remoteport);
X
X   salen = sizeof(sa);
X   if (getpeername(0,&sa,&salen) == -1)
X    {
X     printf("%s, %s: ERROR: UNKNOWN-ERROR\r\n",localport,remoteport);
X     exit(6);
X    }
X   r1 = (int) (unsigned int) ((unsigned char *) &sa.sin_addr)[0];
X   r2 = (int) (unsigned int) ((unsigned char *) &sa.sin_addr)[1];
X   r3 = (int) (unsigned int) ((unsigned char *) &sa.sin_addr)[2];
X   r4 = (int) (unsigned int) ((unsigned char *) &sa.sin_addr)[3];
X
X   salen = sizeof(sa);
X   if (getsockname(0,&sa,&salen) == -1)
X    {
X     printf("%s, %s: ERROR: UNKNOWN-ERROR\r\n",localport,remoteport);
X     exit(6);
X    }
X   l1 = (int) (unsigned int) ((unsigned char *) &sa.sin_addr)[0];
X   l2 = (int) (unsigned int) ((unsigned char *) &sa.sin_addr)[1];
X   l3 = (int) (unsigned int) ((unsigned char *) &sa.sin_addr)[2];
X   l4 = (int) (unsigned int) ((unsigned char *) &sa.sin_addr)[3];
X  }
X else
X  {
X   ZAP(argc < 4,"need four arguments")
X   ZAP(sscanf(argv[1],"%d.%d.%d.%d",&r1,&r2,&r3,&r4)<4,"arg 1 must be a.b.c.d")
X   ZAP(sscanf(argv[2],"%d",&rp) < 1,"arg 2 must be integer")
X   ZAP(sscanf(argv[3],"%d.%d.%d.%d",&l1,&l2,&l3,&l4)<4,"arg 3 must be a.b.c.d")
X   ZAP(sscanf(argv[4],"%d",&lp) < 1,"arg 4 must be integer")
X  }
X
X (void) sprintf(remote,"%d.%d.%d.%d.%d                    ",r1,r2,r3,r4,rp);
X
X#ifdef USE_SYSLOG
X /* This isn't worth the time for the procedure call, but if you want... */
X syslog(LOG_DEBUG,"authd: checking up on %d.%d.%d.%d %d %d.%d.%d.%d %d\n",
X   r1,r2,r3,r4,rp,l1,l2,l3,l4,lp);
X#endif
X
X nlist(VMUNIX,nl);
X ZAP(!(nl[SNFILE].n_value),"cannot nlist _nfile")
X ZAP(!(nl[SFIL].n_value),"cannot nlist _file")
X fd = open(KMEM,O_RDONLY);
X ZAP(fd == -1,"cannot open kernel memory")
X ZAP(lseek(fd,(long) (nl[SNFILE].n_value),0) == -1,"cannot seek to _nfile")
X ZAP(read(fd,(char *) &nfile,sizeof(nfile)) < sizeof(nfile),"cannot read _nfile")
X
X ZAP(lseek(fd,(long) nl[SFIL].n_value,0) == 1,"cannot seek to _file")
X ZAP(read(fd,(char *) &ftp,sizeof(ftp)) < sizeof(ftp),"cannot read _file")
X ZAP(lseek(fd,(long) ftp,0),"cannot lseek to file table")
X xfile = (struct file *) calloc((unsigned) nfile,sizeof(struct file));
X ZAP(!xfile,"cannot allocate space for copy of file table")
X ZAP(read(fd,(char *) xfile,nfile * sizeof(struct file)) < nfile * sizeof(struct file),"cannot read file table")
X
X fi = popen(NETSTAT,"r");
X ZAP(!fi,"cannot execute netstat")
X ZAP(!fgets(s,sizeof(s),fi),"cannot read netstat header line 1")
X ZAP(!fgets(s,sizeof(s),fi),"cannot read netstat header line 2")
X while (fgets(s,sizeof(s),fi))
X  {
X   ZAP(sscanf(s,"%8x",&pcb) != 1,"cannot scan netstat pcb address")
X   pcbl = pcb;
X   if (!strncmp(s + NETSTATREMOTE,remote,NETSTATWIDTH))
X    {
X     ZAP(lseek(fd,(long) pcbl,0) == -1,"cannot seek to pcb address")
X     ZAP(read(fd,(char *) &tcp,sizeof(tcp)) < sizeof(tcp),"cannot read tcp buffer")
X     ZAP(!tcp.t_inpcb,"tcp buffer unlinked")
X     ZAP(lseek(fd,(long) tcp.t_inpcb,0) == -1,"cannot seek to inpcb address")
X     ZAP(read(fd,(char *) &inp,sizeof(inp)) < sizeof(inp),"cannot read inpcb buffer")
X     ZAP(inp.inp_ppcb != (char *) pcbl,"inpcb not linked to pcb")
X
X/* Cursed be Convex and the other manufacturers who make this code */
X/* nearly impossible to write with any pretense of portability. */
X     if((((char *) &inp.inp_faddr)[0] == (char) r1)
X      &&(((char *) &inp.inp_faddr)[1] == (char) r2)
X      &&(((char *) &inp.inp_faddr)[2] == (char) r3)
X      &&(((char *) &inp.inp_faddr)[3] == (char) r4)
X      &&(inp.inp_fport == htons((unsigned short) rp))
X      &&(((char *) &inp.inp_laddr)[0] == (char) l1)
X      &&(((char *) &inp.inp_laddr)[1] == (char) l2)
X      &&(((char *) &inp.inp_laddr)[2] == (char) l3)
X      &&(((char *) &inp.inp_laddr)[3] == (char) l4)
X      &&(inp.inp_lport == htons((unsigned short) lp))
X     )
X      {
X       sockloc = (char *) inp.inp_socket;
X       ZAP(!sockloc,"inp not linked to socket")
X       ZAP(lseek(fd,(long) sockloc,0) == -1,"cannot seek to socket address")
X       ZAP(read(fd,(char *) &sock,sizeof(sock)) < sizeof(sock),"cannot read socket buffer")
X       ZAP(sock.so_pcb != (char *) tcp.t_inpcb,"socket not linked to inpcb")
X       for (fp = xfile;fp < xfile + nfile;++fp)
X	 if (fp->f_count && (fp->f_type == DTYPE_SOCKET))
X	   if (fp->f_data == sockloc)
X	     break;
X       if (fp != xfile + nfile)
X	{
X#ifdef FCRED_ISNOT_POINTER
X         uid = (int) fp->f_cred.cr_ruid;
X#else
X         ZAP(lseek(fd,(long) (fp->f_cred),0) == -1,"cannot seek to credentials")
X         ZAP(read(fd,(char *) &uc,sizeof(uc)) < sizeof(uc),"cannot read credentials")
X         uid = (int) uc.cr_ruid;
X#endif
X	 if (flagpwnam)
X	  {
X	   pw = getpwuid(uid);
X	   ZAP(!pw,"cannot get password entry")
X	   if (flagauthd)
X	     /* UNIX is a trademark of AT&T. :-) */
X             printf("%s, %s: USERID: UNIX: %s\r\n"
X		    ,localport,remoteport,pw->pw_name);
X	   else
X	     printf("%s\n",pw->pw_name);
X	  }
X	 else
X	   printf("%d\n",uid);
X         exit(0);
X	}
X      }
X    }
X  }
X ZAP(1,"no such TCP connection")
X exit(1);
X}
END_OF_FILE
if test 7872 -ne `wc -c <'authd.c'`; then
    echo shar: \"'authd.c'\" unpacked with wrong size!
fi
# end of 'authd.c'
fi
if test -f 'authuser.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'authuser.h'\"
else
echo shar: Extracting \"'authuser.h'\" \(161 characters\)
sed "s/^X//" >'authuser.h' <<'END_OF_FILE'
X#ifndef AUTHUSER_H
X#define AUTHUSER_H
X
Xextern unsigned short auth_tcpport;
Xextern char *auth_xline();
Xextern int auth_fd();
Xextern char *auth_tcpuser();
X
X#endif
END_OF_FILE
if test 161 -ne `wc -c <'authuser.h'`; then
    echo shar: \"'authuser.h'\" unpacked with wrong size!
fi
# end of 'authuser.h'
fi
if test -f 'authuser.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'authuser.c'\"
else
echo shar: Extracting \"'authuser.c'\" \(3519 characters\)
sed "s/^X//" >'authuser.c' <<'END_OF_FILE'
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/socket.h>
X#include <netinet/in.h>
X#include <arpa/inet.h>
X#include <netdb.h>
X#include <errno.h>
X#include <ctype.h>
Xextern int errno;
X#include "authuser.h"
X
Xunsigned short auth_tcpport = 113;
X
X#define SIZ 500 /* various buffers */
X
Xstatic int auth_casecmp(u,v)
Xregister char *u;
Xregister char *v;
X{
X /* is it correct to consider Foo and fOo the same user? yes */
X while (*u && *v)
X   if (tolower(*u) != tolower(*v))
X     return tolower(*u) - tolower(*v);
X   else
X     ++u,++v;
X return *u || *v;
X}
X
Xstatic char authline[SIZ];
X
Xchar *auth_xline(user,fd,in)
Xregister char *user; /* the supposed name of the user, NULL if unknown */
Xregister int fd; /* the file descriptor of the connection */
Xregister unsigned long *in;
X{
X unsigned short local;
X unsigned short remote;
X register char *ruser;
X
X if (auth_fd(fd,in,&local,&remote) == -1)
X   return 0;
X ruser = auth_tcpuser(*in,local,remote);
X if (!ruser)
X   return 0;
X if (!user)
X   user = ruser; /* forces X-Auth-User */
X (void) sprintf(authline,
X	 (auth_casecmp(ruser,user) ? "X-Forgery-By: %s" : "X-Auth-User: %s"),
X	 ruser);
X return authline;
X}
X
Xint auth_fd(fd,in,local,remote)
Xregister int fd;
Xregister unsigned long *in;
Xregister unsigned short *local;
Xregister unsigned short *remote;
X{
X struct sockaddr_in sa;
X int dummy;
X
X dummy = sizeof(sa);
X if (getsockname(fd,&sa,&dummy) == -1)
X   return -1;
X if (sa.sin_family != AF_INET)
X  {
X   errno = EAFNOSUPPORT;
X   return -1;
X  }
X *local = ntohs(sa.sin_port);
X dummy = sizeof(sa);
X if (getpeername(fd,&sa,&dummy) == -1)
X   return -1;
X *remote = ntohs(sa.sin_port);
X *in = sa.sin_addr.s_addr;
X return 0;
X}
X
Xstatic char ruser[SIZ];
Xstatic char realbuf[SIZ];
Xstatic char *buf;
X
Xchar *auth_tcpuser(in,local,remote)
Xregister unsigned long in;
Xregister unsigned short local;
Xregister unsigned short remote;
X{
X struct sockaddr_in sa;
X register int s;
X register int buflen;
X register int w;
X register int saveerrno;
X char ch;
X unsigned short rlocal;
X unsigned short rremote;
X
X if ((s = socket(AF_INET,SOCK_STREAM,0)) == -1)
X   return 0;
X sa.sin_family = AF_INET;
X sa.sin_port = htons(auth_tcpport);
X sa.sin_addr.s_addr = in;
X if (connect(s,&sa,sizeof(sa)) == -1)
X  {
X   saveerrno = errno;
X   (void) close(s);
X   errno = saveerrno;
X   return 0;
X  }
X
X buf = realbuf;
X (void) sprintf(buf,"%u , %u\r\n",(unsigned int) remote,(unsigned int) local);
X /* note the reversed order---the example in the RFC is misleading */
X buflen = strlen(buf);
X while ((w = write(s,buf,buflen)) < buflen)
X   if (w == -1) /* should we worry about 0 as well? */
X    {
X     saveerrno = errno;
X     (void) close(s);
X     errno = saveerrno;
X     return 0;
X    }
X   else
X    {
X     buf += w;
X     buflen -= w;
X    }
X buf = realbuf;
X while ((w = read(s,&ch,1)) == 1)
X  {
X   *buf = ch;
X   if ((ch != ' ') && (ch != '\t') && (ch != '\r'))
X     ++buf;
X   if ((buf - realbuf == sizeof(realbuf) - 1) || (ch == '\n'))
X     break;
X  }
X if (w == -1)
X  {
X   saveerrno = errno;
X   (void) close(s);
X   errno = saveerrno;
X   return 0;
X  }
X *buf = '\0';
X
X if (sscanf(realbuf,"%hd,%hd: USERID :%*[^:]:%s",&rremote,&rlocal,ruser) < 3)
X  {
X   (void) close(s);
X   errno = EIO;
X   /* makes sense, right? well, not when USERID failed to match ERROR */
X   /* but there's no good error to return in that case */
X   return 0;
X  }
X if ((remote != rremote) || (local != rlocal))
X  {
X   (void) close(s);
X   errno = EIO;
X   return 0;
X  }
X /* XXX: we're not going to do any backslash processing */
X (void) close(s);
X return ruser;
X}
END_OF_FILE
if test 3519 -ne `wc -c <'authuser.c'`; then
    echo shar: \"'authuser.c'\" unpacked with wrong size!
fi
# end of 'authuser.c'
fi
if test -f 'test.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'test.c'\"
else
echo shar: Extracting \"'test.c'\" \(2640 characters\)
sed "s/^X//" >'test.c' <<'END_OF_FILE'
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/file.h>
X#ifdef sun
X#include <sys/fcntl.h>
X#endif
X#include <sys/socket.h>
X#include <netinet/in.h>
X#include <arpa/inet.h>
X#include <pwd.h>
X#include <errno.h>
Xextern int errno;
X#include "authuser.h"
X
Xmain()
X{
X int s;
X int t;
X int u;
X struct sockaddr_in sa;
X int salen;
X int localport;
X unsigned long in;
X unsigned short local;
X unsigned short remote;
X char *user;
X struct passwd *pw;
X int ok;
X
X ok = 1;
X
X#define ZOT(x) { fprintf(stderr,"test: fatal: %s\n",x); exit(37); }
X
X s = socket(AF_INET,SOCK_STREAM,0);
X if (s == -1)
X   ZOT("cannot create server socket")
X
X localport = 0; /* meaning pick a port, we don't care which */
X
X sa.sin_family = AF_INET;
X sa.sin_port = htons(localport);
X sa.sin_addr.s_addr = INADDR_ANY;
X
X if (bind(s,&sa,sizeof(sa)) == -1)
X   ZOT("cannot bind server socket")
X
X salen = sizeof(sa);
X if (getsockname(s,&sa,&salen) == -1)
X   ZOT("cannot get name of server socket")
X
X if (listen(s,5) == -1)
X   ZOT("cannot listen for connections") /* XXX: impossible */
X
X u = socket(AF_INET,SOCK_STREAM,0);
X if (u == -1)
X   ZOT("cannot create client socket")
X
X /* we could bind now if we wanted to pick a local port, or to know */
X /* our local port before connection */
X
X /* if connect() blocked then we'd never get a chance to accept() */
X if (fcntl(u,F_SETFL,O_NDELAY) == -1) /* XXX: FNDELAY? */
X   ZOT("cannot set client socket to non-blocking mode")
X
X /* sa is already initialized above to the address we want to connect to */
X if (connect(u,&sa,sizeof(sa)) != -1)
X   ; /* XXX: this is slightly screwy, though common, behavior */
X else
X   if (errno != EINPROGRESS)
X     ZOT("connect failed") /* XXX: should retry if EINTR */
X
X salen = sizeof(sa);
X if ((t = accept(s,&sa,&salen)) == -1)
X   ZOT("cannot accept connection")
X
X printf("system says host is %s\n",inet_ntoa(sa.sin_addr));
X
X /* now let's see what the server can figure out about the client */
X
X if (auth_fd(t,&in,&local,&remote) == -1)
X   ZOT("authuser cannot figure out connection information")
X
X if (sa.sin_addr.s_addr != in)
X  {
X   ok = 0;
X   sa.sin_addr.s_addr = in;
X  }
X printf("authuser says host is %s\n",inet_ntoa(sa.sin_addr));
X
X pw = getpwuid(getuid());
X if (pw)
X   printf("system says username is %s\n",pw->pw_name);
X else
X  {
X   ok = 0;
X   printf("system cannot figure out your username\n");
X  }
X
X user = auth_tcpuser(in,local,remote);
X if (user)
X   printf("authd says username is %s\n",user);
X else
X  {
X   ok = 0;
X   printf("authd cannot figure out your username\n");
X  }
X
X if (ok)
X   if (!strcmp(user,pw->pw_name))
X     printf("Everything looks okay to me.\n");
X   else
X     ok = 1;
X
X exit(!ok);
X}
END_OF_FILE
if test 2640 -ne `wc -c <'test.c'`; then
    echo shar: \"'test.c'\" unpacked with wrong size!
fi
# end of 'test.c'
fi
if test -f 'netstatuid' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'netstatuid'\"
else
echo shar: Extracting \"'netstatuid'\" \(319 characters\)
sed "s/^X//" >'netstatuid' <<'END_OF_FILE'
X#!/bin/sh
Xnetstat -n -f inet \
X| sed -n 's+^.....................\([^.]*\.[^.]*\.[^.]*\.[^.]*\)\.\([^ ]*\) *\([^.]*\.[^.]*\.[^.]*\.[^.]*\)\.\([^ ]*\).*$+ echo -n \3 \4 \1 \2" "\; tcpuname \3 \4 \1 \2 2>\&1+p' \
X| sh \
X| awk '!/ fatal:/ { printf "remote %-15s.%-5s   local %-15s.%-5s   user %s\n" , $1, $2, $3, $4, $5 }
END_OF_FILE
if test 319 -ne `wc -c <'netstatuid'`; then
    echo shar: \"'netstatuid'\" unpacked with wrong size!
fi
chmod +x 'netstatuid'
# end of 'netstatuid'
fi
if test -f 'rfc931' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rfc931'\"
else
echo shar: Extracting \"'rfc931'\" \(9196 characters\)
sed "s/^X//" >'rfc931' <<'END_OF_FILE'
X
X
X
X
X
X---------
X
X
X< INC-PROJECT, AUTH-RFC-VER-2.NLS.5, >, 7-Jan-85 17:18-PST JBP
X;;;;
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
XStJohns                                                         [Page 0]
X
X
XNetwork Working Group                                       Mike StJohns
XRequest for Comments: 931                                           TPSC
XSupersedes: RFC 912                                         January 1985
X
X                         Authentication Server
X
X
XSTATUS OF THIS MEMO
X
X   This RFC suggests a proposed protocol for the ARPA-Internet
X   community, and requests discussion and suggestions for improvements.
X   This is the second draft of this proposal (superseding RFC 912) and
X   incorporates a more formal description of the syntax for the request
X   and response dialog, as well as a change to specify the type of user
X   identification returned.  Distribution of this memo is unlimited.
X
XINTRODUCTION
X
X   The Authentication Server Protocol provides a means to determine the
X   identity of a user of a particular TCP connection.  Given a TCP port
X   number pair, it returns a character string which identifies the owner
X   of that connection on the server's system.  Suggested uses include
X   automatic identification and verification of a user during an FTP
X   session, additional verification of a TAC dial up user, and access
X   verification for a generalized network file server.
X
XOVERVIEW
X
X   This is a connection based application on TCP.  A server listens for
X   TCP connections on TCP port 113 (decimal).  Once a connection is
X   established, the server reads one line of data which specifies the
X   connection of interest.  If it exists, the system dependent user
X   identifier of the connection of interest is sent out the connection.
X   The service closes the connection after sending the user identifier.
X
XRESTRICTIONS
X
X   Queries are permitted only for fully specified connections. The
X   local/foreign host pair used to fully specify the connection are
X   taken from the query connection.  This means a user on Host A may
X   only query the server on Host B about connections between A and B.
X
X
X
X
X
X
X
X
X
X
X
X
XStJohns                                                         [Page 1]
X
X
XRFC 931                                                     January 1985
XAuthentication Server
X
X
XQUERY/RESPONSE FORMAT
X
X   The server accepts simple text query requests of the form
X
X      <local-port>, <foreign-port>
X
X   where <local-port> is the TCP port (decimal) on the target (server)
X   system, and <foreign-port> is the TCP port (decimal) on the source
X   (user) system.
X
X      For example:
X
X         23, 6191
X
X   The response is of the form
X
X      <local-port>, <foreign-port> : <response-type> : <additional-info>
X
X   where <local-port>,<foreign-port> are the same pair as the query,
X   <response-type> is a keyword identifying the type of response, and
X   <additional info> is context dependent.
X
X      For example:
X
X         23, 6191 : USERID : MULTICS : StJohns.DODCSC.a
X         23, 6193 : USERID : TAC : MCSJ-MITMUL
X         23, 6195 : ERROR : NO-USER
X
XRESPONSE TYPES
X
X   A response can be one of two types:
X
X   USERID
X
X      In this case, <additional-info> is a string consisting of an
X      operating system name, followed by a ":", followed by user
X      identification string in a format peculiar to the operating system
X      indicated.  Permitted operating system names are specified in
X      RFC-923, "Assigned Numbers" or its successors.  The only other
X      names permitted are "TAC" to specify a BBN Terminal Access
X      Controller, and "OTHER" to specify any other operating system not
X      yet registered with the NIC.
X
X
X
X
X
X
X
XStJohns                                                         [Page 2]
X
X
XRFC 931                                                     January 1985
XAuthentication Server
X
X
X   ERROR
X
X      For some reason the owner of <TCP-port> could not be determined,
X      <additional-info> tells why.  The following are suggested values
X      of <additional-info> and their meanings.
X
X      INVALID-PORT
X
X         Either the local or foreign port was improperly specified.
X
X      NO-USER
X
X         The connection specified by the port pair is not currently in
X         use.
X
X      UNKNOWN-ERROR
X
X         Can't determine connection owner; reason unknown.  Other values
X         may be specified as necessary.
X
XCAVEATS
X
X   Unfortunately, the trustworthiness of the various host systems that
X   might implement an authentication server will vary quite a bit.  It
X   is up to the various applications that will use the server to
X   determine the amount of trust they will place in the returned
X   information.  It may be appropriate in some cases restrict the use of
X   the server to within a locally controlled subnet.
X
XAPPLICATIONS
X
X   1) Automatic user authentication for FTP
X
X      A user-FTP may send a USER command with no argument to the
X      server-FTP to request automatic authentication.  The server-FTP
X      will reply with a 230 (user logged in) if it can use the
X      authentication.  It will reply with a 530 (not logged in) if it
X      cannot authenticate the user.  It will reply with a 500 or 501
X      (syntax or parameter problem) if it does not implement automatic
X      authentication.  Please note that no change is needed to currently
X      implemented servers to handle the request for authentication; they
X      will reject it normally as a parameter problem.  This is a
X      suggested implementation for experimental use only.
X
X   2) Verification for privileged network operations.  For example,
X   having the server start or stop special purpose servers.
X
X
X
XStJohns                                                         [Page 3]
X
X
XRFC 931                                                     January 1985
XAuthentication Server
X
X
X   3) Elimination of "double login" for TAC and other TELNET users.
X
X      This will be implemented as a TELNET option.
X
XFORMAL SYNTAX
X
X   <request>     ::= <port-pair> <CR> <LF>
X
X   <port-pair>   ::= <integer-number> "," <integer-number>
X
X   <reply>       ::= <reply-text> <CR> <LF>
X
X   <reply-text>  ::= <error-reply> | <auth-reply>
X
X   <error-reply> ::= <port-pair> ":" ERROR ":" <error-type>
X
X   <auth-reply>  ::= <port-pair> ":" USERID ":" <opsys> ":" <user-id>
X
X   <error-type>  ::= INVALID-PORT | NO-USER | UNKNOWN-ERROR
X
X   <opsys>       ::= TAC | OTHER | MULTICS | UNIX ...etc.
X                     (See "Assigned Numbers")
X
X   Notes on Syntax:
X
X      1)  White space (blanks and tab characters) between tokens is not
X      important and may be ignored.
X
X      2)  White space, the token separator character (":"), and the port
X      pair separator character (",") must be quoted if used within a
X      token.  The quote character is a back-slash, ASCII 92 (decimal)
X      ("\").  For example, a quoted colon is "\:".  The back-slash must
X      also be quoted if its needed to represent itself ("\\").
X
XNotes on User Identification Format:
X
X   The user identifier returned by the server should be the standard one
X   for the system.  For example, the standard Multics identifier
X   consists of a PERSONID followed by a ".", followed by a PROJECTID,
X   followed by a ".", followed by an INSTANCE TAG of one character.  An
X   instance tag of "a" identifies an interactive user, and instance tag
X   of "m" identifies an absentee job (batch job) user, and an instance
X   tag of "z" identifies a daemon (background) user.
X
X   Each set of operating system users must come to a consensus as to
X
X
X
X
XStJohns                                                         [Page 4]
X
X
XRFC 931                                                     January 1985
XAuthentication Server
X
X
X   what the OFFICIAL user identification for their systems will be.
X   Until they register this information, they must use the "OTHER" tag
X   to specify their user identification.
X
XNotes on User Identification Translation:
X
X   Once you have a user identifier from a remote system, you must then
X   have a way of translating it into an identifier that meaningful on
X   the local system.  The following is a sketchy outline of table driven
X   scheme for doing this.
X
X   The table consists of four columns, the first three are used to match
X   against, the fourth is the result.
X
X      USERID              Opsys     Address     Result
X      MCSJ-MITMUL         TAC       26.*.*.*    StJohns
X      *                   MULTICS   192.5.42.*  =
X      *                   OTHER     10.0.0.42   anonymous
X      MSJ                 ITS       10.3.0.44   StJohns
X
X   The above table is a sample one for a Multics system on MILNET at the
X   Pentagon.  When an authentication is returned, the particular
X   application using the userid simply looks for the first match in the
X   table.  Notice the second line.  It says that any authentication
X   coming from a Multics system on Net 192.5.42 is accepted in the same
X   format.
X
X   Obviously, various users will have to be registered to use this
X   facility, but the registration can be done at the same time the use
X   receives his login identity from the system.
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
XStJohns                                                         [Page 5]
END_OF_FILE
if test 9196 -ne `wc -c <'rfc931'`; then
    echo shar: \"'rfc931'\" unpacked with wrong size!
fi
# end of 'rfc931'
fi
echo shar: End of shell archive.
exit 0



More information about the Alt.sources mailing list