From mtc@ATHENA.MIT.EDU  Tue Jun  3 17:14:23 1986
To: geer, bcn, spm
Cc: charlie, saltzer, noah, jis
Subject: Kerberos Support for Remote Services, Project Description (long)
Date: Tue, 03 Jun 86 17:12:41 -0500
From: Mark Colan <mtc@ATHENA.MIT.EDU>


Introduction

	I have been asked to put Kerberos support into the remote services
	rlogin, rsh, and rcp.  The task has evolved as I have proceeded;
	therefore, the purpose of this project is to document what I'm
	doing with this project, to identify and resolve conflicts with what 
	other people think should be done, and to give a status report on
	the project.  
	
	Comments on this report are encouraged.

	A feature of my approach is that it requires a new port number for
	the Kerberos-authenticated services.  These port numbers should
	be assigned by SRI-NIC so that they can become "well-known"; if
	we do not do this, it may break rlogin to foreign hosts (ie, if
	the host thinks the port means something other than Kerberos).


The Problem

	In the Athena environment we lose control over the administration of
	individual workstations.  This fact allows a workstation user to
	capitalize on a hole in the rlogin (etc) "host trusting" mechanism,
	possibly to destructive ends, assuming that the user has the root 
	password for the workstation, which is likely.

	For example, I (mtc) have the machines I use regularly set up to
	trust each other.  "menelaus" is a VAX750 and "goanna" is my uVax II
	workstation.  If goanna goes down, it creates an opportunity for an
	evil hacker to use any workstation to masquerade as mtc logged in on
	goanna: all he has to do is name the workstation "goanna" and create
	an account for "mtc", then rlogin to menelaus.  Menelaus cannot tell
	that the hacker is not me, and because of the way I have trusting set
	up, allows the hacker full access to my menelaus resources.  The only
	alternative to this security hole that exists now is removal of 
	"trusting" from my ~/.rhosts file; this causes the nuisance of having 
	to type my password each time I begin an rlogin session.


The Solution

	Kerberos can be used to prevent this kind of illicit access.  To
	start an authenticated rlogin session, a user creates a set of encrypted 
	tickets (via vxlogin) that absolutely identify him to a remote host.
	With this kind of security, it is possible to trust a session, since
	Kerberos can detect tampering, re-use, etc, of the tickets.


Goals of the Project

	The services to be modified to use Kerberos authentication are rlogin,
	rsh, and rcp.  The changes must be made in such a way as to not break
	the existing function for use without Kerberos.  For example, for the
	rlogin service:

	1) An external user (eg, on a client without Kerberos) must still
	   be able to rlogin to a Kerberos host, provided that that host
	   is set up to allow the access.
	
	2) A user of a Kerberos host must be able to rlogin to a host 
	   that does not support Kerberos.
	
	A change to the format of the ~/.rhosts and /etc/hosts.equiv files
	have been proposed to allow some new flexibility in tailoring the
	Kerberos environment; these changes are described later.

	Since these services make use of a few common routines for setting up
	the connection, changes should be made to those routines which can be
	used by all targeted services.  The changes will be the minimum required
	to support authentication, to avoid breaking any other existing functions.


Changes to Permission Control Files

	Steve Miller suggested some changes to the format of the files ~/.rhosts
	and /etc/hosts.equiv for better tailoring to the Kerberos environment.
	These files allow users to rlogin without typing their password for
	each session.  Currently, the files can contain two types of specification:

	host				trust all users from the specified host
	host username		trust username from the specified host

	The proposed extensions use a special cookie, "*krb*", to indicate that
	the control applies to Kerberos logins:

	*krb*				allow Kerberos-authenticated logins from any
						user on any host.
	host *krb*			allow Kerberos-authenticated logins from any
						user on the specified host.
	host user *krb*		allow Kerberos-authenticated logins from the
						specified user on the specified host.

	At the moment, an authenticated rlogin now works without these extensions; 
	it is governed by the same restrictions as a non-kerberos login.  The main 
	difference between the authenticated and non-authenticated login is that 
	we have closed the hole of doubt as to the clients true identity.  However,
	a remote user can still gain access without authentication by using the
	standard version of rlogin.

	What the proposed extensions provide is flexibility in restricting access.
	For example, a workstation in building E40 might be willing to trust any
	workstation or host in E40 with or without Kerberos authentication, but 
	require others to authenticate their sessions.  The /etc/hosts.equiv file 
	spec is:

	*krb*
	menelaus
	goanna
	(other hosts and workstations)


Changes to rlogin protocol

	Continue to support the normal rlogin protocol:

		lusername<0>
		rusername<0>
		terminal_info<0>
	
	Add alternate protocol for Kerberos support:

		KTEXT object		# count in text form, a space, and count chars
							# of the Kerberos text string.
		rusername<0>
		terminal_info<0>

	Note that the Kerberos protocol does not explicitly supply the 
	lusername; this is taken from the authenticated data enclosed in the
	KTEXT structure.


Changes to rcmd.c

	Added a new argument, a pointer to a KTEXT object, which controls
	the type of protocol used by remote services.  If the pointer is NULL, 
	use the normal protocol; if it points to a KTEXT object, use the
	Kerberos protocol via SendKerberosTicket().

	New routine SendKerberosTicket() sends a KTEXT structure across the
	connection from the client to the server.

	New routine GetKerberosData() snarfs the KTEXT sent by SendKerberosTicket()
	and uses rd_ap_req to extract the AUTH_DAT from the KTEXT object.
	The remote username (ie client's local username) is translated by
	antoln and returned.

	ruserok() (and its subordinate routines) will be changed to extend
	the function of /etc/hosts.equiv and ~/.rhosts, as described earlier.

Changes to rlogin.c

	Find the port number for a Kerberos login session (from /etc/services).  
	If not found, punt the Kerberos login session and try normal rlogin.  
	Otherwise, create a KTEXT object and fill it in (via mk_ap_req).

	Attempt connection to the remote host using the Kerberos port, by
	means of rcmd() with a pointer to the KTEXT object.  If the connection 
	fails, punt the Kerberos login session, release the KTEXT object, and 
	try the normal login.

	If the Kerberos login failed, find the port number for a normal
	login session.  Attempt the connection via rcmd(), using NULL for
	the KTEXT object.


Changes to rlogind.c

	Look at the command name.  If its "rlogind", spawn "login -r fromhost"
	as before.  If its "klogind", spawn "login -k fromhost" to get
	login to expect the Kerberos protocol.


Changes to login.c

	Check for the presence of "-k".  Allow only one of: "-r -h or -k"
	(instead of the first two only).  If "-r" is found, call doremotelogin()
	as before.  If "-k" is found, call doKerberosLogin() instead, to use
	the modified rlogin protocol.

	Add new routine doKerberosLogin().  It snarfs a KTEXT object off of
	the connection stream via GetKerberosData() (see rcmd.c).  Then gets
	the lusername (ie, rusername sent by rlogin) and terminal characteristics.
	ruserok() is called as before (for the time being, until the Kerberos
	extensions to /etc/hosts.equiv are implemented), but using the lusername
	enclosed in the KTEXT, which is known to be authentic.


Changes to rsh.c

	Will be changed analogous to the changes to rlogin.c.


Changes to rshd.c

	Will be changed analogous to the changes to rlogind.c and login.c.


Changes to rcp.c

	Will be changed analogous to the changes to rlogin.c.
	

Current Status

	rlogin now works with Kerberos authentication, and does not break
	existing function.  It is complete except for the changes to ruserok.

	Work remaining: modify rsh, rshd and rcp to use the new version
	of rcmd() etc.