The system of authentication and encryption of data going between
clients and servers is very close to that employed by Kerberos 5, see
The key ingredients in the mechanisms are as follows:
- Shared secret cryptography: in the protocols it is assumed
in numerous places that the two principals on a connection share
a "secret" key, allowing the sender to encrypt data and the receiver
to decrypt it. The acquisition of shared keys is involved since they
cannot be sent over the net in the clear.
- Establishing secure connections: this comprises a
mechanisms to establish a secure connections if the two parties share
a secret key and a public
ClientIdent. Secure means
authenticated and encrypted.
- Authentication protocol: this protocol is a variant of the
Needham Schroeder authentication protocol. It allows the generation
of a shared secret, called a session or handshake key for use between
client and fileserver based on communication with an
authentication server. The result of the an authetication
session is that the client acquires a session key on the basis of
supplying a correct password. This key is initially only known to the
authentication server and client.
- The authentication server and the fileserver share a secret and
can communicate the session keys for certain clients securely. In
this way the fileserver can set up a secure connection with the
Let us look at the details.
The files rpc2.h and secure.c in the RPC2 package contain the
cryptographic routines. For export reasons only RPC2_XOR is in use,
but it would be easy to use DES too.
A bit of cleanup seems to be needed, also in the random number
RPC2 allows to bind to a server (i.e. set up a connection) in 4 ways:
neither authenticated nor encrypted
authenticated but not encrypted
authenticated and headers of RPC packets are
authenticated and RPC packets are encrypted.
The security implications for the different types of connections are
discussed in Satya's paper, as well as the algorithm employed in the
bind routine (RPC2_NewBinding, rpc2a.c).
Of interest here is that the encryption type is given to the bind
routine as a variable. A small amount of cleanup in secure.c should
help to make DES encryption an easy switch. It would be interesting
to measure the effect of encryption on performance.
In the preceeding two subsections we did not explain how a shared
secret between the server and client can be established. The
following three methods of acquiring such a secret are in place:
- upon authentication the auth server and the client can share
the password of the user to establish a secure connection
- in the final stages of authentication the auth server can send
the client a session key, which it also shares with the server
- venus and the server use the session key from the
authentication protocol to establish a secure connection
Let us go into detail for case 1. Coda employs the clog program to
get a session key. clog looks up the username in
and tries a secure binding with the auth server using the username as
ClientIdent and the password, which it got from the user, as the
Secret. It then executes a standard bind request to the auth server.
The auth server receives this request (using RPC2_GetRequest in
auth2.cc) which points to the routine PWGetKeys as a means to acquire
the shared secret for the bind routine.
PWGetKeys is the heart of password authentication. The viceid for the
user is looked up (see the documentation regarding the protection
database) and password file auth2.pw is opened to find her
password. The password can be decrypted with the FileKey ("dreuss ").
At this moment PWGetKeys returns and the client and server share a
secret. (XXX: the routines copying passwords copy buffers of a fixed
length and might not deal with passwords which are too short
It tries a host listed as an argument to clog to find an auth server
or cycles through the hosts in vstab. If the binding is successful
this is taken as a guarantee that the password was correct, and clog
proceeds by placing the AuthGetTokens rpc. The server
The next rpc which clog makes invokes AuthGetTokens which sets the
last used time one the ui component of the clientident and returns two
tokens to the client:
Of course this information is returned over the connection secured by
the users password.
- The clear token (
- the handshake key (also called the session key)
- an authhandle (always -1)
- a begin time (always 0)
- a final time (always
- the viceid for the user
- the secret token (
The secret token is encrypted with the TokenKey which is obtained from
- the above information
- random fields
We now enter the last stage of clog: it must tell Venus what about the
two keys it acquired for the user. This is the routine
U_SetLocalTokens, avenus.cc. This routine passes the two tokens to
Venus through a pioctl. (similar routines get the tokens or remove
- There seems to be a problem with the handling of
U_SetLocalTokens in vproc_pioctl.cc (VIOCSETTOK): it gets the ue for
which it enters the token from the packet passed up by pioctl. This
is wrong. The tokens were acquired for the user listed as an argument
to clog and these are not necessarily the same. Remove the mess and
let the routine get the user entry from the clear token (and perhaps
an extra parameter passed with the pioctl).
- GetPathName in avenus.cc should return /coda by default not
- Clean up the code a bit
- Check that the cycling through hosts in vstab is working
- Figure out if the encryption of passwords works with variable
- Check that passwords can be of variable length
- Check that clog uses the username (not the client userid) and
that if it uses the id a translation localuid to viceid is maintained
appropiately. This will need some modifications in venus too, but is
important for cells and system administration.
- in GetPWKeys the statting of the auth.pw file is done at the
- the "feature" that auth2 checks for the presence of "new" auth2
/vice/bin/auth2 seems over the top and causes system
administration nightmares. This code should just be removed.
- It seems pretty mysterious that the "direct assigment of fields
doesn't work" (user.cc in coda-src/venus). I would like to know why.
- user.cc contains some routines that call abort. In fact these
routines should be removed so that the compiler can check if those
culprits are ever called.