ONC+ Developer's Guide

AUTH_DES Authentication

Use AUTH_DES authentication for programs that require more security than AUTH_SYS provides. AUTH_SYS authentication is easy to defeat. For example, instead of using authsys_create_default(), a program can call authsys_create() and change the RPC authentication handle to give itself any desired user ID and host name.

AUTH_DES authentication requires keyserv() daemons to be running on both the server and client hosts. The NIS or NIS+ naming service must also be running. Users on these hosts need public/secret key pairs assigned by the network administrator in the publickey() database. The users must also have decrypted their secret keys with the keylogin() command. This decryption is normally done by login() unless the login password and secure-RPC password differ.

To use AUTH_DES authentication, a client must set its authentication handle appropriately, as shown in the following example.

cl->cl_auth = authdes_seccreate(servername, 60, server,
						       (char *)NULL);

The first argument is the network name or “net name” of the owner of the server process. Server processes are usually root processes, and you can get their net names with the following call;

char servername[MAXNETNAMELEN];
host2netname(servername, server, (char *)NULL);

servername points to the receiving string and server is the name of the host the server process is running on. If the server process was run by a non-root user, use the call user2netname() as follows:

char servername[MAXNETNAMELEN];
user2netname(servername, serveruid(), (char *)NULL);

serveruid() is the user ID of the server process. The last argument of both functions is the name of the domain that contains the server. NULL means “use the local domain name.”

The second argument of authdes_seccreate() is the lifetime (known also as the “window”) of the client's credential. In this example, a credential expires 60 seconds after the client makes an RPC call. If a program tries to reuse the credential, the server RPC subsystem recognizes that the credential has expired and does not service the request carrying the expired credential. If any program tries to reuse a credential within its lifetime, the process is rejected, because the server RPC subsystem saves credentials it has seen in the near past and does not serve duplicates.

The third argument of authdes_seccreate() is the name of the timehost used to synchronize clocks. AUTH_DES authentication requires that server and client agree on the time. Example 5–8 specifies synchronization with the server. A (char *)NULL says not to synchronize. Use this syntax only when you are sure that the client and server are already synchronized.

The fourth argument of authdes_seccreate() points to a DES encryption key to encrypt timestamps and data. If this argument is (char *)NULL, as it is in Example 5–8, a random key is chosen. The ah_key field of the authentication handle contains the key.

The server side is simpler than the client. The following example shows the server in Example 5–8 changed to use AUTH_DES.


Example 5–9 AUTH_DES Server

#include <rpc/rpc.h>
	...
	...
nuser(rqstp, transp)
	struct svc_req *rqstp;
	SVCXPRT *transp;
{
	struct authdes_cred *des_cred;
	uid_t uid;
	gid_t gid;
	int gidlen;
	gid_t gidlist[10];
 
	/* NULLPROC should never be authenticated */
	if (rqstp->rq_proc == NULLPROC) {
		/* same as before */
	}
	/* now get the uid */
	switch(rqstp->rq_cred.oa_flavor) {
		case AUTH_DES:
			des_cred = (struct authdes_cred *) rqstp->rq_clntcred;
			if (! netname2user( des_cred->adc_fullname.name, &uid,

			                    &gid, &gidlen, gidlist)) {
				fprintf(stderr, "unknown user: %s\n",
				         des_cred->adc_fullname.name);
				svcerr_systemerr(transp);
				return;
			}
			break;
		default:
			svcerr_weakauth(transp);
			return;
	}
	/* The rest is the same as before */

The routine netname2user() converts a network name, or “net name” of a user, to a local system ID. It also supplies group IDs, which are not used in this example.