aboutsummaryrefslogtreecommitdiff
path: root/sunrpc
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1997-08-29 21:01:47 +0000
committerUlrich Drepper <drepper@redhat.com>1997-08-29 21:01:47 +0000
commit800d775e426b9c0af63f711b79b09bf540c97456 (patch)
treeff7858571c81f2e6077c5e35b465494052984876 /sunrpc
parentUpdate. (diff)
downloadglibc-800d775e426b9c0af63f711b79b09bf540c97456.tar.gz
glibc-800d775e426b9c0af63f711b79b09bf540c97456.tar.bz2
glibc-800d775e426b9c0af63f711b79b09bf540c97456.zip
1997-08-29 21:45 Ulrich Drepper <drepper@cygnus.com> * sunrpc/auth_des.c: New file. Copied from former secure_rpc add-on. * sunrpc/authdes_prot.c: New file. Likewise. * sunrpc/des.h: New file. Likewise. * sunrpc/des_crypt.c: New file. Likewise. * sunrpc/des_soft.c: New file. Likewise. * sunrpc/key_call.c: New file. Likewise. * sunrpc/key_prot.c: New file. Likewise. * sunrpc/netname.c: New file. Likewise. * sunrpc/openchild.c: New file. Likewise. * sunrpc/rtime.c: New file. Likewise. * sunrpc/svc_auth.c: New file. Likewise. * sunrpc/svcauth_des.c: New file. Likewise. * sunrpc/xcrypt.c: New file. Likewise. * sunrpc/rpc/auth.h: New file. Likewise. * sunrpc/rpc/auth_des.h: New file. Likewise. * sunrpc/rpc/des_crypt.h: New file. Likewise. * sunrpc/rpc/key_prot.h: New file. Likewise. * sunrpc/rpcsvc/key_prot.x: New file. Likewise. * sysdeps/generic/svc_auth.h: Removed. * sysdeps/generic/rpc/auth.h: Removed. * sysdeps/generic/rpc/auth_des.h: Removed. * sysdeps/stub/des_impl.c: New file. Stub version for DES. * sunrpc/Makefile (rpcsvc): Add keyprot.x. (headers): Add des_crypt.h and key_prot.h. (routines): Add auth_des, authdes_prot, des_crypt, des_impl, des_soft, key_call, key_prot, netname, openchild, rtime, svcauth_des, xcrypt. (distribute): Add des.h. * db2/Makefile: Add all headers and other files to distribute. (others): Add db_printlog. * sysdeps/mach/hurd/Dist: Add net/* headers. * sysdeps/mach/hurd/mips/Dist: New file. * sysdeps/powerpc/Dist: Add fe_nomask.c and t_sqrt.c. * sysdeps/sparc/Dist: Add sys/trap.h. * sysdeps/sparc/sparc32/Dist: Remove sys/trap.h. * sysdeps/sparc/sparc32/sparcv8/Dist: New file. * sysdeps/unix/sysv/linux/mips/Dist: Add sgidefs.h. * sysdeps/unix/sysv/linux/sparc/Dist: Add sys/trap.h. * sysdeps/unix/sysv/linux/sparc/sparc32/Dist: Remove sys/trap.h. Add previously missing assembler files for PPC. * sysdeps/powerpc/add_n.s: New file. * sysdeps/powerpc/addmul_1.s: New file. * sysdeps/powerpc/lshift.s: New file. * sysdeps/powerpc/memset.s: New file. * sysdeps/powerpc/mul_1.s: New file. * sysdeps/powerpc/rshift.s: New file. * sysdeps/powerpc/strchr.s: New file. * sysdeps/powerpc/strcmp.s: New file. * sysdeps/powerpc/sub_n.s: New file. * sysdeps/powerpc/submul_1.s: New file. 1997-08-28 18:42 Thorsten Kukuk <kukuk@uni-paderborn.de> * nis/nis_server.c: Rewritten to fix a lot of bugs. 1997-08-28 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * md5-crypt/Makefile (LDFLAGS-md5crypt.so, libmd5crypt-map): New variables. in NLSPATH environment variable. Patch by HJ Lu <hjl@gnu.ai.mit.edu>.
Diffstat (limited to 'sunrpc')
-rw-r--r--sunrpc/Makefile11
-rw-r--r--sunrpc/auth_des.c459
-rw-r--r--sunrpc/authdes_prot.c81
-rw-r--r--sunrpc/des.h83
-rw-r--r--sunrpc/des_crypt.c120
-rw-r--r--sunrpc/des_soft.c68
-rw-r--r--sunrpc/key_call.c363
-rw-r--r--sunrpc/key_prot.c161
-rw-r--r--sunrpc/netname.c201
-rw-r--r--sunrpc/openchild.c112
-rw-r--r--sunrpc/rpc/auth.h210
-rw-r--r--sunrpc/rpc/auth_des.h104
-rw-r--r--sunrpc/rpc/des_crypt.h97
-rw-r--r--sunrpc/rpc/key_prot.h345
-rw-r--r--sunrpc/rpcsvc/key_prot.x284
-rw-r--r--sunrpc/rtime.c146
-rw-r--r--sunrpc/svc_auth.c119
-rw-r--r--sunrpc/svcauth_des.c548
-rw-r--r--sunrpc/xcrypt.c180
19 files changed, 3688 insertions, 4 deletions
diff --git a/sunrpc/Makefile b/sunrpc/Makefile
index b7c86d4f84..baee72e85b 100644
--- a/sunrpc/Makefile
+++ b/sunrpc/Makefile
@@ -47,10 +47,11 @@ subdir := sunrpc
rpcsvc = bootparam.x nlm_prot.x rstat.x \
yppasswd.x klm_prot.x rex.x sm_inter.x mount.x \
- rusers.x spray.x nfs_prot.x rquota.x
+ rusers.x spray.x nfs_prot.x rquota.x key_prot.x
headers = $(addprefix rpc/,auth.h auth_unix.h clnt.h netdb.h pmap_clnt.h \
pmap_prot.h pmap_rmt.h rpc.h rpc_msg.h svc.h \
- svc_auth.h types.h xdr.h auth_des.h) \
+ svc_auth.h types.h xdr.h auth_des.h \
+ des_crypt.h key_prot.h) \
$(rpcsvc:%=rpcsvc/%)
install-others = $(inst_sysconfdir)/rpc
generated = $(rpcsvc:%.x=rpcsvc/%.h) $(rpcsvc:%.x=x%.c) \
@@ -64,7 +65,9 @@ routines := auth_none auth_unix authuxprot bindrsvprt \
pmap_prot2 pmap_rmt rpc_prot rpc_common rpc_cmsg \
svc svc_auth svc_authux svc_raw svc_run svc_simple \
svc_tcp svc_udp xdr xdr_array xdr_float xdr_mem \
- xdr_rec xdr_ref xdr_stdio publickey xdr_sizeof
+ xdr_rec xdr_ref xdr_stdio publickey xdr_sizeof \
+ auth_des authdes_prot des_crypt des_impl des_soft \
+ key_call key_prot netname openchild rtime svcauth_des xcrypt
others := rpcinfo
install-bin := rpcgen
@@ -73,7 +76,7 @@ rpcgen-objs = rpc_main.o rpc_hout.o rpc_cout.o rpc_parse.o \
rpc_scan.o rpc_util.o rpc_svcout.o rpc_clntout.o \
rpc_tblout.o rpc_sample.o
# These headers are part of rpcgen.
-distribute := proto.h rpc_util.h rpc_parse.h rpc_scan.h \
+distribute := proto.h rpc_util.h rpc_parse.h rpc_scan.h des.h \
$(rpcgen-objs:.o=.c) etc.rpc
extra-objs = $(rpcgen-objs)
diff --git a/sunrpc/auth_des.c b/sunrpc/auth_des.c
new file mode 100644
index 0000000000..4ea6391c6e
--- /dev/null
+++ b/sunrpc/auth_des.c
@@ -0,0 +1,459 @@
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)auth_des.c 2.2 88/07/29 4.0 RPCSRC; from 1.9 88/02/08 SMI";
+#endif
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+/*
+ * Copyright (c) 1988 by Sun Microsystems, Inc.
+ */
+/*
+ * auth_des.c, client-side implementation of DES authentication
+ */
+
+#include <string.h>
+#include <rpc/des_crypt.h>
+#include <rpc/types.h>
+#include <rpc/auth.h>
+#include <rpc/auth_des.h>
+#include <rpc/xdr.h>
+#include <netinet/in.h> /* XXX: just to get htonl() and ntohl() */
+#include <sys/socket.h>
+
+#define MILLION 1000000L
+#define RTIME_TIMEOUT 5 /* seconds to wait for sync */
+
+#define AUTH_PRIVATE(auth) (struct ad_private *) auth->ah_private
+#define ALLOC(object_type) (object_type *) mem_alloc(sizeof(object_type))
+#define FREE(ptr, size) mem_free((char *)(ptr), (int) size)
+#define ATTEMPT(xdr_op) if (!(xdr_op)) return (FALSE)
+
+#define debug(msg) /* printf("%s\n", msg) */
+
+extern int rtime (struct sockaddr_in *, struct timeval *, struct timeval *);
+extern bool_t xdr_authdes_cred (XDR *, struct authdes_cred *);
+extern bool_t xdr_authdes_verf (XDR *, struct authdes_verf *);
+
+/*
+ * DES authenticator operations vector
+ */
+AUTH *authdes_create (const char *, u_int, struct sockaddr *,
+ des_block *);
+AUTH *authdes_pk_create (const char *, netobj *, u_int,
+ struct sockaddr *, des_block *);
+static void authdes_nextverf (AUTH *);
+static bool_t authdes_marshal (AUTH *, XDR *);
+static bool_t authdes_validate (AUTH *, struct opaque_auth *);
+static bool_t authdes_refresh (AUTH *);
+static void authdes_destroy (AUTH *);
+static bool_t synchronize (struct sockaddr *, struct timeval *);
+
+static struct auth_ops authdes_ops =
+{
+ authdes_nextverf,
+ authdes_marshal,
+ authdes_validate,
+ authdes_refresh,
+ authdes_destroy
+};
+
+
+/*
+ * This struct is pointed to by the ah_private field of an "AUTH *"
+ */
+struct ad_private
+ {
+ char *ad_fullname; /* client's full name */
+ u_int ad_fullnamelen; /* length of name, rounded up */
+ char *ad_servername; /* server's full name */
+ u_int ad_servernamelen; /* length of name, rounded up */
+ u_int ad_window; /* client specified window */
+ bool_t ad_dosync; /* synchronize? */
+ struct sockaddr ad_syncaddr; /* remote host to synch with */
+ struct timeval ad_timediff; /* server's time - client's time */
+ u_long ad_nickname; /* server's nickname for client */
+ struct authdes_cred ad_cred; /* storage for credential */
+ struct authdes_verf ad_verf; /* storage for verifier */
+ struct timeval ad_timestamp; /* timestamp sent */
+ des_block ad_xkey; /* encrypted conversation key */
+ u_char ad_pkey[1024]; /* Servers actual public key */
+ };
+
+
+/*
+ * Create the client des authentication object
+ */
+AUTH *
+authdes_create (const char *servername, u_int window,
+ struct sockaddr *syncaddr, des_block * ckey)
+ /* servername - network name of server */
+ /* window - time to live */
+ /* syncaddr - optional addr of host to sync with */
+ /* ckey - optional conversation key to use */
+{
+ u_char pkey_data[1024];
+ netobj pkey;
+
+ if (!getpublickey (servername, pkey_data))
+ return (NULL);
+
+ pkey.n_bytes = (char *) pkey_data;
+ pkey.n_len = strlen ((char *) pkey_data) + 1;
+ return authdes_pk_create (servername, &pkey, window, syncaddr, ckey);
+}
+
+AUTH *
+authdes_pk_create (const char *servername, netobj * pkey, u_int window,
+ struct sockaddr * syncaddr, des_block * ckey)
+{
+ AUTH *auth;
+ struct ad_private *ad;
+ char namebuf[MAXNETNAMELEN + 1];
+
+ /*
+ * Allocate everything now
+ */
+ auth = ALLOC (AUTH);
+ ad = ALLOC (struct ad_private);
+ memcpy (ad->ad_pkey, pkey->n_bytes, pkey->n_len);
+ if (!getnetname (namebuf))
+ goto failed;
+ ad->ad_fullnamelen = RNDUP (strlen (namebuf));
+ ad->ad_fullname = mem_alloc (ad->ad_fullnamelen + 1);
+
+ ad->ad_servernamelen = strlen (servername);
+ ad->ad_servername = mem_alloc (ad->ad_servernamelen + 1);
+
+ if (auth == NULL || ad == NULL || ad->ad_fullname == NULL ||
+ ad->ad_servername == NULL)
+ {
+ debug ("authdes_create: out of memory");
+ goto failed;
+ }
+
+ /*
+ * Set up private data
+ */
+ bcopy (namebuf, ad->ad_fullname, ad->ad_fullnamelen + 1);
+ bcopy (servername, ad->ad_servername, ad->ad_servernamelen + 1);
+ if (syncaddr != NULL)
+ {
+ ad->ad_syncaddr = *syncaddr;
+ ad->ad_dosync = TRUE;
+ }
+ else
+ ad->ad_dosync = FALSE;
+
+ ad->ad_window = window;
+ if (ckey == NULL)
+ {
+ if (key_gendes (&auth->ah_key) < 0)
+ {
+ debug ("authdes_create: unable to gen conversation key");
+ return (NULL);
+ }
+ }
+ else
+ auth->ah_key = *ckey;
+
+ /*
+ * Set up auth handle
+ */
+ auth->ah_cred.oa_flavor = AUTH_DES;
+ auth->ah_verf.oa_flavor = AUTH_DES;
+ auth->ah_ops = &authdes_ops;
+ auth->ah_private = (caddr_t) ad;
+
+ if (!authdes_refresh (auth))
+ goto failed;
+
+ return (auth);
+
+failed:
+ if (auth != NULL)
+ FREE (auth, sizeof (AUTH));
+ if (ad != NULL)
+ FREE (ad, sizeof (struct ad_private));
+ if (ad->ad_fullname != NULL)
+ FREE (ad->ad_fullname, ad->ad_fullnamelen + 1);
+ if (ad->ad_servername != NULL)
+ FREE (ad->ad_servername, ad->ad_servernamelen + 1);
+ return (NULL);
+}
+
+/*
+ * Implement the five authentication operations
+ */
+
+
+/*
+ * 1. Next Verifier
+ */
+/*ARGSUSED */
+static void
+authdes_nextverf (AUTH * auth)
+{
+ /* what the heck am I supposed to do??? */
+}
+
+
+
+/*
+ * 2. Marshal
+ */
+static bool_t
+authdes_marshal (AUTH * auth, XDR * xdrs)
+{
+ struct ad_private *ad = AUTH_PRIVATE (auth);
+ struct authdes_cred *cred = &ad->ad_cred;
+ struct authdes_verf *verf = &ad->ad_verf;
+ des_block cryptbuf[2];
+ des_block ivec;
+ int status;
+ int len;
+ register long *ixdr;
+
+ /*
+ * Figure out the "time", accounting for any time difference
+ * with the server if necessary.
+ */
+ gettimeofday (&ad->ad_timestamp, (struct timezone *) NULL);
+ ad->ad_timestamp.tv_sec += ad->ad_timediff.tv_sec;
+ ad->ad_timestamp.tv_usec += ad->ad_timediff.tv_usec;
+ if (ad->ad_timestamp.tv_usec >= MILLION)
+ {
+ ad->ad_timestamp.tv_usec -= MILLION;
+ ad->ad_timestamp.tv_sec += 1;
+ }
+
+ /*
+ * XDR the timestamp and possibly some other things, then
+ * encrypt them.
+ */
+ ixdr = (long *) cryptbuf;
+ IXDR_PUT_LONG (ixdr, ad->ad_timestamp.tv_sec);
+ IXDR_PUT_LONG (ixdr, ad->ad_timestamp.tv_usec);
+ if (ad->ad_cred.adc_namekind == ADN_FULLNAME)
+ {
+ IXDR_PUT_U_LONG (ixdr, ad->ad_window);
+ IXDR_PUT_U_LONG (ixdr, ad->ad_window - 1);
+ ivec.key.high = ivec.key.low = 0;
+ status = cbc_crypt ((char *) &auth->ah_key, (char *) cryptbuf,
+ 2 * sizeof (des_block), DES_ENCRYPT | DES_HW, (char *) &ivec);
+ }
+ else
+ {
+ status = ecb_crypt ((char *) &auth->ah_key, (char *) cryptbuf,
+ sizeof (des_block), DES_ENCRYPT | DES_HW);
+ }
+ if (DES_FAILED (status))
+ {
+ debug ("authdes_marshal: DES encryption failure");
+ return (FALSE);
+ }
+ ad->ad_verf.adv_xtimestamp = cryptbuf[0];
+ if (ad->ad_cred.adc_namekind == ADN_FULLNAME)
+ {
+ ad->ad_cred.adc_fullname.window = cryptbuf[1].key.high;
+ ad->ad_verf.adv_winverf = cryptbuf[1].key.low;
+ }
+ else
+ {
+ ad->ad_cred.adc_nickname = ad->ad_nickname;
+ ad->ad_verf.adv_winverf = 0;
+ }
+
+ /*
+ * Serialize the credential and verifier into opaque
+ * authentication data.
+ */
+ if (ad->ad_cred.adc_namekind == ADN_FULLNAME)
+ {
+ len = ((1 + 1 + 2 + 1) * BYTES_PER_XDR_UNIT + ad->ad_fullnamelen);
+ }
+ else
+ {
+ len = (1 + 1) * BYTES_PER_XDR_UNIT;
+ }
+
+ if ((ixdr = xdr_inline (xdrs, 2 * BYTES_PER_XDR_UNIT)) != NULL)
+ {
+ IXDR_PUT_LONG (ixdr, AUTH_DES);
+ IXDR_PUT_LONG (ixdr, len);
+ }
+ else
+ {
+ ATTEMPT (xdr_putlong (xdrs, (long *)&auth->ah_cred.oa_flavor));
+ ATTEMPT (xdr_putlong (xdrs, (long *)&len));
+ }
+ ATTEMPT (xdr_authdes_cred (xdrs, cred));
+
+ len = (2 + 1) * BYTES_PER_XDR_UNIT;
+ if ((ixdr = xdr_inline (xdrs, 2 * BYTES_PER_XDR_UNIT)) != NULL)
+ {
+ IXDR_PUT_LONG (ixdr, AUTH_DES);
+ IXDR_PUT_LONG (ixdr, len);
+ }
+ else
+ {
+ ATTEMPT (xdr_putlong (xdrs, (long *)&auth->ah_verf.oa_flavor));
+ ATTEMPT (xdr_putlong (xdrs, (long *)&len));
+ }
+ ATTEMPT (xdr_authdes_verf (xdrs, verf));
+ return (TRUE);
+}
+
+
+/*
+ * 3. Validate
+ */
+static bool_t
+authdes_validate (AUTH * auth, struct opaque_auth *rverf)
+{
+ struct ad_private *ad = AUTH_PRIVATE (auth);
+ struct authdes_verf verf;
+ int status;
+ register u_long *ixdr;
+
+ if (rverf->oa_length != (2 + 1) * BYTES_PER_XDR_UNIT)
+ return (FALSE);
+
+ ixdr = (u_long *) rverf->oa_base;
+ verf.adv_xtimestamp.key.high = (u_long) * ixdr++;
+ verf.adv_xtimestamp.key.low = (u_long) * ixdr++;
+ verf.adv_int_u = (u_long) * ixdr++; /* nickname not XDR'd ! */
+
+ /*
+ * Decrypt the timestamp
+ */
+ status = ecb_crypt ((char *) &auth->ah_key, (char *) &verf.adv_xtimestamp,
+ sizeof (des_block), DES_DECRYPT | DES_HW);
+
+ if (DES_FAILED (status))
+ {
+ debug ("authdes_validate: DES decryption failure");
+ return (FALSE);
+ }
+
+ /*
+ * xdr the decrypted timestamp
+ */
+ ixdr = (u_long *) verf.adv_xtimestamp.c;
+ verf.adv_timestamp.tv_sec = IXDR_GET_LONG (ixdr) + 1;
+ verf.adv_timestamp.tv_usec = IXDR_GET_LONG (ixdr);
+
+ /*
+ * validate
+ */
+ if (bcmp ((char *) &ad->ad_timestamp, (char *) &verf.adv_timestamp,
+ sizeof (struct timeval)) != 0)
+ {
+ debug ("authdes_validate: verifier mismatch\n");
+ return (FALSE);
+ }
+
+ /*
+ * We have a nickname now, let's use it
+ */
+ ad->ad_nickname = verf.adv_nickname;
+ ad->ad_cred.adc_namekind = ADN_NICKNAME;
+ return (TRUE);
+}
+
+/*
+ * 4. Refresh
+ */
+static bool_t
+authdes_refresh (AUTH * auth)
+{
+ netobj pkey;
+ struct ad_private *ad = AUTH_PRIVATE (auth);
+ struct authdes_cred *cred = &ad->ad_cred;
+
+ if (ad->ad_dosync &&
+ !synchronize (&ad->ad_syncaddr, &ad->ad_timediff))
+ {
+ /*
+ * Hope the clocks are synced!
+ */
+ ad->ad_timediff.tv_sec = ad->ad_timediff.tv_usec = 0;
+ debug ("authdes_refresh: unable to synchronize with server");
+ }
+ ad->ad_xkey = auth->ah_key;
+ pkey.n_bytes = (char *) (ad->ad_pkey);
+ pkey.n_len = strlen ((char *) ad->ad_pkey) + 1;
+ if (key_encryptsession_pk (ad->ad_servername, &pkey, &ad->ad_xkey) < 0)
+ {
+ debug ("authdes_create: unable to encrypt conversation key");
+ return (FALSE);
+ }
+ cred->adc_fullname.key = ad->ad_xkey;
+ cred->adc_namekind = ADN_FULLNAME;
+ cred->adc_fullname.name = ad->ad_fullname;
+ return (TRUE);
+}
+
+/*
+ * 5. Destroy
+ */
+static void
+authdes_destroy (AUTH * auth)
+{
+ struct ad_private *ad = AUTH_PRIVATE (auth);
+
+ FREE (ad->ad_fullname, ad->ad_fullnamelen + 1);
+ FREE (ad->ad_servername, ad->ad_servernamelen + 1);
+ FREE (ad, sizeof (struct ad_private));
+ FREE (auth, sizeof (AUTH));
+}
+
+/*
+ * Synchronize with the server at the given address, that is,
+ * adjust timep to reflect the delta between our clocks
+ */
+static bool_t
+synchronize (struct sockaddr *syncaddr, struct timeval *timep)
+{
+ struct timeval mytime;
+ struct timeval timeout;
+
+ timeout.tv_sec = RTIME_TIMEOUT;
+ timeout.tv_usec = 0;
+ if (rtime ((struct sockaddr_in *) syncaddr, timep, &timeout) < 0)
+ return (FALSE);
+
+ gettimeofday (&mytime, (struct timezone *) NULL);
+ timep->tv_sec -= mytime.tv_sec;
+ if (mytime.tv_usec > timep->tv_usec)
+ {
+ timep->tv_sec -= 1;
+ timep->tv_usec += MILLION;
+ }
+ timep->tv_usec -= mytime.tv_usec;
+ return (TRUE);
+}
diff --git a/sunrpc/authdes_prot.c b/sunrpc/authdes_prot.c
new file mode 100644
index 0000000000..3c6eacced6
--- /dev/null
+++ b/sunrpc/authdes_prot.c
@@ -0,0 +1,81 @@
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)authdes_prot.c 2.1 88/07/29 4.0 RPCSRC; from 1.6 88/02/08 SMI";
+#endif
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+/*
+ * Copyright (c) 1988 by Sun Microsystems, Inc.
+ */
+
+/*
+ * authdes_prot.c, XDR routines for DES authentication
+ */
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#include <rpc/auth_des.h>
+
+#define ATTEMPT(xdr_op) if (!(xdr_op)) return (FALSE)
+
+bool_t
+xdr_authdes_cred (XDR * xdrs, struct authdes_cred *cred)
+{
+ /*
+ * Unrolled xdr
+ */
+ ATTEMPT (xdr_enum (xdrs, (enum_t *) & cred->adc_namekind));
+ switch (cred->adc_namekind)
+ {
+ case ADN_FULLNAME:
+ ATTEMPT (xdr_string (xdrs, &cred->adc_fullname.name, MAXNETNAMELEN));
+ ATTEMPT (xdr_opaque (xdrs, (caddr_t) & cred->adc_fullname.key, sizeof (des_block)));
+ ATTEMPT (xdr_opaque (xdrs, (caddr_t) & cred->adc_fullname.window, sizeof (cred->adc_fullname.window)));
+ return (TRUE);
+ case ADN_NICKNAME:
+ ATTEMPT (xdr_opaque (xdrs, (caddr_t) & cred->adc_nickname, sizeof (cred->adc_nickname)));
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+
+bool_t
+xdr_authdes_verf (register XDR * xdrs, register struct authdes_verf * verf)
+{
+ /*
+ * Unrolled xdr
+ */
+ ATTEMPT (xdr_opaque (xdrs, (caddr_t) & verf->adv_xtimestamp,
+ sizeof (des_block)));
+ ATTEMPT (xdr_opaque (xdrs, (caddr_t) & verf->adv_int_u,
+ sizeof (verf->adv_int_u)));
+ return TRUE;
+}
diff --git a/sunrpc/des.h b/sunrpc/des.h
new file mode 100644
index 0000000000..68bd7c47ab
--- /dev/null
+++ b/sunrpc/des.h
@@ -0,0 +1,83 @@
+/* @(#)des.h 2.2 88/08/10 4.0 RPCSRC; from 2.7 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+/*
+ * Generic DES driver interface
+ * Keep this file hardware independent!
+ * Copyright (c) 1986 by Sun Microsystems, Inc.
+ */
+
+#ifndef _DES_H
+#define _DES_H
+
+#include <sys/types.h>
+
+#define DES_MAXLEN 65536 /* maximum # of bytes to encrypt */
+#define DES_QUICKLEN 16 /* maximum # of bytes to encrypt quickly */
+
+enum desdir
+ {
+ ENCRYPT, DECRYPT
+ };
+enum desmode
+ {
+ CBC, ECB
+ };
+
+/*
+ * parameters to ioctl call
+ */
+struct desparams
+ {
+ u_char des_key[8]; /* key (with low bit parity) */
+ enum desdir des_dir; /* direction */
+ enum desmode des_mode; /* mode */
+ u_char des_ivec[8]; /* input vector */
+ unsigned des_len; /* number of bytes to crypt */
+ union
+ {
+ u_char UDES_data[DES_QUICKLEN];
+ u_char *UDES_buf;
+ }
+ UDES;
+#define des_data UDES.UDES_data /* direct data here if quick */
+#define des_buf UDES.UDES_buf /* otherwise, pointer to data */
+ };
+
+/*
+ * Encrypt an arbitrary sized buffer
+ */
+#define DESIOCBLOCK _IOWR(d, 6, struct desparams)
+
+/*
+ * Encrypt of small amount of data, quickly
+ */
+#define DESIOCQUICK _IOWR(d, 7, struct desparams)
+
+#endif
diff --git a/sunrpc/des_crypt.c b/sunrpc/des_crypt.c
new file mode 100644
index 0000000000..7a4bc5d6cf
--- /dev/null
+++ b/sunrpc/des_crypt.c
@@ -0,0 +1,120 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+#if !defined(lint) && defined(SCCSID)
+static char sccsid[] = "@(#)des_crypt.c 2.2 88/08/10 4.0 RPCSRC; from 1.13 88/02/08 SMI";
+#endif
+/*
+ * des_crypt.c, DES encryption library routines
+ * Copyright (C) 1986, Sun Microsystems, Inc.
+ */
+
+#include <sys/types.h>
+#include <rpc/des_crypt.h>
+#include "des.h"
+
+extern int _des_crypt (char *, unsigned, struct desparams *);
+
+/*
+ * Copy 8 bytes
+ */
+#define COPY8(src, dst) { \
+ register char *a = (char *) dst; \
+ register char *b = (char *) src; \
+ *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
+ *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
+}
+
+/*
+ * Copy multiple of 8 bytes
+ */
+#define DESCOPY(src, dst, len) { \
+ register char *a = (char *) dst; \
+ register char *b = (char *) src; \
+ register int i; \
+ for (i = (int) len; i > 0; i -= 8) { \
+ *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
+ *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
+ } \
+}
+
+/*
+ * Common code to cbc_crypt() & ecb_crypt()
+ */
+static int
+common_crypt (char *key, char *buf, register unsigned len,
+ unsigned mode, register struct desparams *desp)
+{
+ register int desdev;
+
+ if ((len % 8) != 0 || len > DES_MAXDATA)
+ return DESERR_BADPARAM;
+
+ desp->des_dir =
+ ((mode & DES_DIRMASK) == DES_ENCRYPT) ? ENCRYPT : DECRYPT;
+
+ desdev = mode & DES_DEVMASK;
+ COPY8 (key, desp->des_key);
+ /*
+ * software
+ */
+ if (!_des_crypt (buf, len, desp))
+ return DESERR_HWERROR;
+
+ return desdev == DES_SW ? DESERR_NONE : DESERR_NOHWDEVICE;
+}
+
+/*
+ * CBC mode encryption
+ */
+int
+cbc_crypt (char *key, char *buf, unsigned int len, unsigned int mode,
+ char *ivec)
+{
+ int err;
+ struct desparams dp;
+
+ dp.des_mode = CBC;
+ COPY8 (ivec, dp.des_ivec);
+ err = common_crypt (key, buf, len, mode, &dp);
+ COPY8 (dp.des_ivec, ivec);
+ return err;
+}
+
+
+/*
+ * ECB mode encryption
+ */
+int
+ecb_crypt (char *key, char *buf, unsigned int len, unsigned int mode)
+{
+ struct desparams dp;
+
+ dp.des_mode = ECB;
+ return common_crypt (key, buf, len, mode, &dp);
+}
diff --git a/sunrpc/des_soft.c b/sunrpc/des_soft.c
new file mode 100644
index 0000000000..ae12d7b0a6
--- /dev/null
+++ b/sunrpc/des_soft.c
@@ -0,0 +1,68 @@
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)des_soft.c 2.2 88/08/10 4.0 RPCSRC; from 1.13 88/02/08 SMI";
+#endif
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+/*
+ * Table giving odd parity in the low bit for ASCII characters
+ */
+static char partab[128] =
+{
+ 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x07, 0x07,
+ 0x08, 0x08, 0x0b, 0x0b, 0x0d, 0x0d, 0x0e, 0x0e,
+ 0x10, 0x10, 0x13, 0x13, 0x15, 0x15, 0x16, 0x16,
+ 0x19, 0x19, 0x1a, 0x1a, 0x1c, 0x1c, 0x1f, 0x1f,
+ 0x20, 0x20, 0x23, 0x23, 0x25, 0x25, 0x26, 0x26,
+ 0x29, 0x29, 0x2a, 0x2a, 0x2c, 0x2c, 0x2f, 0x2f,
+ 0x31, 0x31, 0x32, 0x32, 0x34, 0x34, 0x37, 0x37,
+ 0x38, 0x38, 0x3b, 0x3b, 0x3d, 0x3d, 0x3e, 0x3e,
+ 0x40, 0x40, 0x43, 0x43, 0x45, 0x45, 0x46, 0x46,
+ 0x49, 0x49, 0x4a, 0x4a, 0x4c, 0x4c, 0x4f, 0x4f,
+ 0x51, 0x51, 0x52, 0x52, 0x54, 0x54, 0x57, 0x57,
+ 0x58, 0x58, 0x5b, 0x5b, 0x5d, 0x5d, 0x5e, 0x5e,
+ 0x61, 0x61, 0x62, 0x62, 0x64, 0x64, 0x67, 0x67,
+ 0x68, 0x68, 0x6b, 0x6b, 0x6d, 0x6d, 0x6e, 0x6e,
+ 0x70, 0x70, 0x73, 0x73, 0x75, 0x75, 0x76, 0x76,
+ 0x79, 0x79, 0x7a, 0x7a, 0x7c, 0x7c, 0x7f, 0x7f,
+};
+
+/*
+ * Add odd parity to low bit of 8 byte key
+ */
+void
+des_setparity (char *p)
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ {
+ *p = partab[*p & 0x7f];
+ p++;
+ }
+}
diff --git a/sunrpc/key_call.c b/sunrpc/key_call.c
new file mode 100644
index 0000000000..ba1c2638fb
--- /dev/null
+++ b/sunrpc/key_call.c
@@ -0,0 +1,363 @@
+/*
+ * Copyright (c) 1988 by Sun Microsystems, Inc.
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * The original source is from the RPCSRC 4.0 package from Sun Microsystems.
+ * The Interface to keyserver protocoll 2 was added by
+ * Thorsten Kukuk <kukuk@vt.uni-paderborn.de>
+ */
+
+#include <stdio.h>
+#include <signal.h>
+#include <unistd.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <rpc/auth.h>
+#include <sys/wait.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <rpc/key_prot.h>
+
+#define KEY_TIMEOUT 5 /* per-try timeout in seconds */
+#define KEY_NRETRY 12 /* number of retries */
+
+#define debug(msg) /* turn off debugging */
+
+extern int _openchild (char *command, FILE ** fto, FILE ** ffrom);
+
+
+static int key_call (u_long, xdrproc_t xdr_arg, char *,
+ xdrproc_t xdr_rslt, char *);
+
+static struct timeval trytimeout = {KEY_TIMEOUT, 0};
+static struct timeval tottimeout = {KEY_TIMEOUT * KEY_NRETRY, 0};
+
+int
+key_setsecret (char *secretkey)
+{
+ keystatus status;
+
+ if (!key_call ((u_long) KEY_SET, (xdrproc_t) xdr_keybuf, secretkey,
+ (xdrproc_t) xdr_keystatus, (char *) &status))
+ return -1;
+ if (status != KEY_SUCCESS)
+ {
+ debug ("set status is nonzero");
+ return -1;
+ }
+ return 0;
+}
+
+/* key_secretkey_is_set() returns 1 if the keyserver has a secret key
+ * stored for the caller's effective uid; it returns 0 otherwise
+ *
+ * N.B.: The KEY_NET_GET key call is undocumented. Applications shouldn't
+ * be using it, because it allows them to get the user's secret key.
+ */
+int
+key_secretkey_is_set (void)
+{
+ struct key_netstres kres;
+
+ memset (&kres, 0, sizeof (kres));
+ if (key_call ((u_long) KEY_NET_GET, (xdrproc_t) xdr_void, (char *) NULL,
+ (xdrproc_t) xdr_key_netstres, (char *) &kres) &&
+ (kres.status == KEY_SUCCESS) &&
+ (kres.key_netstres_u.knet.st_priv_key[0] != 0))
+ {
+ /* avoid leaving secret key in memory */
+ memset (kres.key_netstres_u.knet.st_priv_key, 0, HEXKEYBYTES);
+ return 1;
+ }
+ return 0;
+}
+
+int
+key_encryptsession (char *remotename, des_block * deskey)
+{
+ cryptkeyarg arg;
+ cryptkeyres res;
+
+ arg.remotename = remotename;
+ arg.deskey = *deskey;
+ if (!key_call ((u_long) KEY_ENCRYPT, (xdrproc_t) xdr_cryptkeyarg,
+ (char *) &arg, (xdrproc_t) xdr_cryptkeyres, (char *) &res))
+ return -1;
+
+ if (res.status != KEY_SUCCESS)
+ {
+ debug ("encrypt status is nonzero");
+ return -1;
+ }
+ *deskey = res.cryptkeyres_u.deskey;
+ return 0;
+}
+
+int
+key_decryptsession (char *remotename, des_block * deskey)
+{
+ cryptkeyarg arg;
+ cryptkeyres res;
+
+ arg.remotename = remotename;
+ arg.deskey = *deskey;
+ if (!key_call ((u_long) KEY_DECRYPT, (xdrproc_t) xdr_cryptkeyarg,
+ (char *) &arg, (xdrproc_t) xdr_cryptkeyres, (char *) &res))
+ return -1;
+ if (res.status != KEY_SUCCESS)
+ {
+ debug ("decrypt status is nonzero");
+ return -1;
+ }
+ *deskey = res.cryptkeyres_u.deskey;
+ return 0;
+}
+
+int
+key_encryptsession_pk (char *remotename, netobj * remotekey,
+ des_block * deskey)
+{
+ cryptkeyarg2 arg;
+ cryptkeyres res;
+
+ arg.remotename = remotename;
+ arg.remotekey = *remotekey;
+ arg.deskey = *deskey;
+ if (!key_call ((u_long) KEY_ENCRYPT_PK, (xdrproc_t) xdr_cryptkeyarg2,
+ (char *) &arg, (xdrproc_t) xdr_cryptkeyres, (char *) &res))
+ return -1;
+
+ if (res.status != KEY_SUCCESS)
+ {
+ debug ("encrypt status is nonzero");
+ return -1;
+ }
+ *deskey = res.cryptkeyres_u.deskey;
+ return 0;
+}
+
+int
+key_decryptsession_pk (char *remotename, netobj * remotekey,
+ des_block * deskey)
+{
+ cryptkeyarg2 arg;
+ cryptkeyres res;
+
+ arg.remotename = remotename;
+ arg.remotekey = *remotekey;
+ arg.deskey = *deskey;
+ if (!key_call ((u_long) KEY_DECRYPT_PK, (xdrproc_t) xdr_cryptkeyarg2,
+ (char *) &arg, (xdrproc_t) xdr_cryptkeyres, (char *) &res))
+ return -1;
+
+ if (res.status != KEY_SUCCESS)
+ {
+ debug ("decrypt status is nonzero");
+ return -1;
+ }
+ *deskey = res.cryptkeyres_u.deskey;
+ return 0;
+}
+
+int
+key_gendes (des_block * key)
+{
+ struct sockaddr_in sin;
+ CLIENT *client;
+ int socket;
+ enum clnt_stat stat;
+
+ sin.sin_family = AF_INET;
+ sin.sin_port = 0;
+ sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+ bzero (sin.sin_zero, sizeof (sin.sin_zero));
+ socket = RPC_ANYSOCK;
+ client = clntudp_bufcreate (&sin, (u_long) KEY_PROG, (u_long) KEY_VERS,
+ trytimeout, &socket, RPCSMALLMSGSIZE,
+ RPCSMALLMSGSIZE);
+ if (client == NULL)
+ return -1;
+
+ stat = clnt_call (client, KEY_GEN, (xdrproc_t) xdr_void, NULL,
+ (xdrproc_t) xdr_des_block, (caddr_t) key, tottimeout);
+ clnt_destroy (client);
+ close (socket);
+ if (stat != RPC_SUCCESS)
+ return -1;
+
+ return 0;
+}
+
+int
+key_setnet (struct key_netstarg *arg)
+{
+ keystatus status;
+
+ if (!key_call ((u_long) KEY_NET_PUT, (xdrproc_t) xdr_key_netstarg,
+ (char *) arg,(xdrproc_t) xdr_keystatus, (char *) &status))
+ return -1;
+
+ if (status != KEY_SUCCESS)
+ {
+ debug ("key_setnet status is nonzero");
+ return -1;
+ }
+ return 1;
+}
+
+int
+key_get_conv (char *pkey, des_block * deskey)
+{
+ cryptkeyres res;
+
+ if (!key_call ((u_long) KEY_GET_CONV, (xdrproc_t) xdr_keybuf, pkey,
+ (xdrproc_t) xdr_cryptkeyres, (char *) &res))
+ return -1;
+
+ if (res.status != KEY_SUCCESS)
+ {
+ debug ("get_conv status is nonzero");
+ return -1;
+ }
+ *deskey = res.cryptkeyres_u.deskey;
+ return 0;
+}
+
+/*
+ * Hack to allow the keyserver to use AUTH_DES (for authenticated
+ * NIS+ calls, for example). The only functions that get called
+ * are key_encryptsession_pk, key_decryptsession_pk, and key_gendes.
+ *
+ * The approach is to have the keyserver fill in pointers to local
+ * implementations of these functions, and to call those in key_call().
+ */
+
+cryptkeyres *(*__key_encryptsession_pk_LOCAL) (uid_t, char *) = 0;
+cryptkeyres *(*__key_decryptsession_pk_LOCAL) (uid_t, char *) = 0;
+des_block *(*__key_gendes_LOCAL) (uid_t, char *) = 0;
+
+static int
+key_call (u_long proc, xdrproc_t xdr_arg, char *arg,
+ xdrproc_t xdr_rslt, char *rslt)
+{
+ XDR xdrargs;
+ XDR xdrrslt;
+ FILE *fargs;
+ FILE *frslt;
+ void (*osigchild) (int);
+ union wait status;
+ int pid;
+ int success;
+ uid_t ruid;
+ uid_t euid;
+ static char MESSENGER[] = "/usr/etc/keyenvoy";
+
+ success = 1;
+ osigchild = signal (SIGCHLD, SIG_IGN);
+
+ if (proc == KEY_ENCRYPT_PK && __key_encryptsession_pk_LOCAL)
+ {
+ cryptkeyres *res;
+ res = (*__key_encryptsession_pk_LOCAL) (geteuid (), arg);
+ *(cryptkeyres *) rslt = *res;
+ return 1;
+ }
+ else if (proc == KEY_DECRYPT_PK && __key_decryptsession_pk_LOCAL)
+ {
+ cryptkeyres *res;
+ res = (*__key_decryptsession_pk_LOCAL) (geteuid (), arg);
+ *(cryptkeyres *) rslt = *res;
+ return 1;
+ }
+ else if (proc == KEY_GEN && __key_gendes_LOCAL)
+ {
+ des_block *res;
+ res = (*__key_gendes_LOCAL) (geteuid (), 0);
+ *(des_block *) rslt = *res;
+ return 1;
+ }
+
+ /*
+ * We are going to exec a set-uid program which makes our effective uid
+ * zero, and authenticates us with our real uid. We need to make the
+ * effective uid be the real uid for the setuid program, and
+ * the real uid be the effective uid so that we can change things back.
+ */
+ euid = geteuid ();
+ ruid = getuid ();
+ setreuid (euid, ruid);
+ pid = _openchild (MESSENGER, &fargs, &frslt);
+ setreuid (ruid, euid);
+ if (pid < 0)
+ {
+ debug ("open_streams");
+ return (0);
+ }
+ xdrstdio_create (&xdrargs, fargs, XDR_ENCODE);
+ xdrstdio_create (&xdrrslt, frslt, XDR_DECODE);
+
+ if (!xdr_u_long (&xdrargs, &proc) || !(*xdr_arg) (&xdrargs, arg))
+ {
+ debug ("xdr args");
+ success = 0;
+ }
+ fclose (fargs);
+
+ if (success && !(*xdr_rslt) (&xdrrslt, rslt))
+ {
+ debug ("xdr rslt");
+ success = 0;
+ }
+
+#ifdef NOTDEF
+ /*
+ * WARNING! XXX
+ * The original code appears first. wait4 returns only after the process
+ * with the requested pid terminates. The effect of using wait() instead
+ * has not been determined.
+ */
+ fclose (frslt);
+ if (wait4 (pid, &status, 0, NULL) < 0 || status.w_retcode != 0)
+ {
+ debug ("wait4");
+ success = 0;
+ }
+#endif /* def NOTDEF */
+ if (wait (&status) < 0 || status.w_retcode != 0)
+ {
+ debug ("wait");
+ success = 0;
+ }
+ signal (SIGCHLD, osigchild);
+
+ return (success);
+}
diff --git a/sunrpc/key_prot.c b/sunrpc/key_prot.c
new file mode 100644
index 0000000000..5de8e25420
--- /dev/null
+++ b/sunrpc/key_prot.c
@@ -0,0 +1,161 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+#pragma ident "@(#)key_prot.x 1.7 94/04/29 SMI"
+
+/* Copyright (c) 1990, 1991 Sun Microsystems, Inc. */
+
+#include "rpc/key_prot.h"
+
+bool_t
+xdr_keystatus (XDR * xdrs, keystatus * objp)
+{
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+
+ return TRUE;
+}
+
+bool_t
+xdr_keybuf (XDR * xdrs, keybuf objp)
+{
+ if (!xdr_opaque (xdrs, objp, HEXKEYBYTES))
+ return FALSE;
+
+ return TRUE;
+}
+
+bool_t
+xdr_netnamestr (XDR * xdrs, netnamestr * objp)
+{
+ if (!xdr_string (xdrs, objp, MAXNETNAMELEN))
+ return FALSE;
+
+ return TRUE;
+}
+
+bool_t
+xdr_cryptkeyarg (XDR * xdrs, cryptkeyarg * objp)
+{
+ if (!xdr_netnamestr (xdrs, &objp->remotename))
+ return FALSE;
+
+ if (!xdr_des_block (xdrs, &objp->deskey))
+ return FALSE;
+
+ return TRUE;
+}
+
+bool_t
+xdr_cryptkeyarg2 (XDR * xdrs, cryptkeyarg2 * objp)
+{
+ if (!xdr_netnamestr (xdrs, &objp->remotename))
+ return FALSE;
+ if (!xdr_netobj (xdrs, &objp->remotekey))
+ return FALSE;
+ if (!xdr_des_block (xdrs, &objp->deskey))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_cryptkeyres (XDR * xdrs, cryptkeyres * objp)
+{
+ if (!xdr_keystatus (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status)
+ {
+ case KEY_SUCCESS:
+ if (!xdr_des_block (xdrs, &objp->cryptkeyres_u.deskey))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_unixcred (XDR * xdrs, unixcred * objp)
+{
+ if (!xdr_u_int (xdrs, &objp->uid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->gid))
+ return FALSE;
+ if (!xdr_array (xdrs, (char **) &objp->gids.gids_val,
+ (u_int *) & objp->gids.gids_len, MAXGIDS,
+ sizeof (u_int), (xdrproc_t) xdr_u_int))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_getcredres (XDR * xdrs, getcredres * objp)
+{
+ if (!xdr_keystatus (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status)
+ {
+ case KEY_SUCCESS:
+ if (!xdr_unixcred (xdrs, &objp->getcredres_u.cred))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_key_netstarg (XDR * xdrs, key_netstarg * objp)
+{
+ if (!xdr_keybuf (xdrs, objp->st_priv_key))
+ return FALSE;
+ if (!xdr_keybuf (xdrs, objp->st_pub_key))
+ return FALSE;
+ if (!xdr_netnamestr (xdrs, &objp->st_netname))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_key_netstres (XDR * xdrs, key_netstres * objp)
+{
+ if (!xdr_keystatus (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status)
+ {
+ case KEY_SUCCESS:
+ if (!xdr_key_netstarg (xdrs, &objp->key_netstres_u.knet))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
diff --git a/sunrpc/netname.c b/sunrpc/netname.c
new file mode 100644
index 0000000000..be6c2f2ae1
--- /dev/null
+++ b/sunrpc/netname.c
@@ -0,0 +1,201 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <rpc/rpc.h>
+
+#include "nsswitch.h"
+
+#define OPSYS_LEN 4
+#define MAXIPRINT (11) /* max length of printed integer */
+static const char *OPSYS = "unix";
+
+int
+user2netname (char netname[MAXNETNAMELEN + 1], const uid_t uid,
+ const char *domain)
+{
+ char dfltdom[MAXNETNAMELEN + 1];
+ size_t i;
+
+ if (domain == NULL)
+ {
+ if (getdomainname (dfltdom, sizeof (dfltdom)) < 0)
+ return 0;
+ }
+ else
+ {
+ strncpy (dfltdom, domain, MAXNETNAMELEN);
+ dfltdom[MAXNETNAMELEN] = '\0';
+ }
+
+ if ((strlen (dfltdom) + OPSYS_LEN + 3 + MAXIPRINT) > (size_t) MAXNETNAMELEN)
+ return 0;
+
+ sprintf (netname, "%s.%d@%s", OPSYS, uid, dfltdom);
+ i = strlen (netname);
+ if (netname[i - 1] == '.')
+ netname[i - 1] = '\0';
+ return 1;
+}
+
+int
+host2netname (char netname[MAXNETNAMELEN + 1], const char *host,
+ const char *domain)
+{
+ char *p;
+ char hostname[MAXHOSTNAMELEN + 1];
+ char domainname[MAXHOSTNAMELEN + 1];
+ char *dot_in_host;
+ size_t i;
+
+ netname[0] = '\0'; /* make null first (no need for memset) */
+
+ if (host == NULL)
+ gethostname (hostname, MAXHOSTNAMELEN);
+ else
+ {
+ strncpy (hostname, host, MAXHOSTNAMELEN);
+ hostname[MAXHOSTNAMELEN] = '\0';
+ }
+
+ dot_in_host = strchr (hostname, '.');
+ if (domain == NULL)
+ {
+ p = dot_in_host;
+ if (p)
+ {
+ strncpy (domainname, p, MAXHOSTNAMELEN);
+ domainname[MAXHOSTNAMELEN] = '\0';
+ }
+ else
+ {
+ domainname[0] = 0;
+ getdomainname (domainname, MAXHOSTNAMELEN);
+ }
+ }
+ else
+ {
+ strncpy (domainname, domain, MAXHOSTNAMELEN);
+ domainname[MAXHOSTNAMELEN] = '\0';
+ }
+
+ i = strlen (domainname);
+ if (i == 0)
+ /* No domainname */
+ return 0;
+ if (domainname[i - 1] == '.')
+ domainname[i - 1] = 0;
+
+ if (dot_in_host) /* strip off rest of name */
+ *dot_in_host = '\0';
+
+ if ((strlen (domainname) + strlen (hostname) + OPSYS_LEN + 3)
+ > MAXNETNAMELEN)
+ return 0;
+
+ sprintf (netname, "%s.%s@%s", OPSYS, hostname, domainname);
+ return 1;
+}
+
+int
+getnetname (char name[MAXNETNAMELEN + 1])
+{
+ uid_t uid;
+ int dummy;
+
+ uid = geteuid ();
+ if (uid == 0)
+ dummy = host2netname (name, NULL, NULL);
+ else
+ dummy = user2netname (name, uid, NULL);
+ return (dummy);
+}
+
+/* Type of the lookup function for netname2user. */
+typedef int (*netname2user_function) (const char netname[MAXNETNAMELEN + 1],
+ uid_t *, gid_t *, int *, gid_t *);
+/* The lookup function for the first entry of this service. */
+extern int __nss_publickey_lookup (service_user ** nip, const char *name,
+ void **fctp);
+
+int
+netname2user (const char netname[MAXNETNAMELEN + 1], uid_t * uidp, gid_t * gidp,
+ int *gidlenp, gid_t * gidlist)
+{
+ static service_user *startp = NULL;
+ static netname2user_function start_fct;
+ service_user *nip;
+ netname2user_function fct;
+ enum nss_status status = NSS_STATUS_UNAVAIL;
+ int no_more;
+
+ if (startp == NULL)
+ {
+ no_more = __nss_publickey_lookup (&nip, "netname2user", (void **) &fct);
+ if (no_more)
+ startp = (service_user *) - 1;
+ else
+ {
+ startp = nip;
+ start_fct = fct;
+ }
+ }
+ else
+ {
+ fct = start_fct;
+ no_more = (nip = startp) == (service_user *) - 1;
+ }
+
+ while (!no_more)
+ {
+ status = (*fct) (netname, uidp, gidp, gidlenp, gidlist);
+
+ no_more = __nss_next (&nip, "netname2user", (void **) &fct, status, 0);
+ }
+
+ return status == NSS_STATUS_SUCCESS;
+}
+
+int
+netname2host (const char netname[MAXNETNAMELEN + 1], char *hostname,
+ const int hostlen)
+{
+ char *p1, *p2;
+ char buffer[MAXNETNAMELEN + 1];
+
+ p1 = strchr (buffer, '.');
+ if (p1 == NULL)
+ return 0;
+ p1++;
+
+ p2 = strchr (p1, '@');
+ if (p2 == NULL)
+ return 0;
+ *p2 = '\0';
+
+ if (hostlen > MAXNETNAMELEN)
+ return 0;
+
+ strncpy (hostname, p1, hostlen);
+ hostname[hostlen] = '\0';
+
+ return 1;
+}
diff --git a/sunrpc/openchild.c b/sunrpc/openchild.c
new file mode 100644
index 0000000000..2fa26fae45
--- /dev/null
+++ b/sunrpc/openchild.c
@@ -0,0 +1,112 @@
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)openchild.c 2.3 88/08/15 4.0 RPCSRC; from 1.7 88/02/08 SMI";
+#endif
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * Copyright (c) 1988 by Sun Microsystems, Inc.
+ */
+
+/*
+ * Open two pipes to a child process, one for reading, one for writing.
+ * The pipes are accessed by FILE pointers. This is NOT a public
+ * interface, but for internal use only!
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <rpc/clnt.h>
+
+static char SHELL[] = "/bin/sh";
+
+/*
+ * returns pid, or -1 for failure
+ */
+int
+_openchild (char *command, FILE ** fto, FILE ** ffrom)
+{
+ int i;
+ int pid;
+ int pdto[2];
+ int pdfrom[2];
+ char *com;
+
+ if (pipe (pdto) < 0)
+ goto error1;
+ if (pipe (pdfrom) < 0)
+ goto error2;
+ switch (pid = vfork ())
+ {
+ case -1:
+ goto error3;
+
+ case 0:
+ /*
+ * child: read from pdto[0], write into pdfrom[1]
+ */
+ close (0);
+ dup (pdto[0]);
+ close (1);
+ dup (pdfrom[1]);
+ for (i = _rpc_dtablesize () - 1; i >= 3; i--)
+ close (i);
+ com = malloc (strlen (command) + 6);
+ if (com == NULL)
+ _exit (~0);
+ sprintf (com, "exec %s", command);
+ execl (SHELL, basename (SHELL), "-c", com, NULL);
+ _exit (~0);
+
+ default:
+ /*
+ * parent: write into pdto[1], read from pdfrom[0]
+ */
+ *fto = fdopen (pdto[1], "w");
+ close (pdto[0]);
+ *ffrom = fdopen (pdfrom[0], "r");
+ close (pdfrom[1]);
+ break;
+ }
+ return pid;
+
+ /*
+ * error cleanup and return
+ */
+error3:
+ close (pdfrom[0]);
+ close (pdfrom[1]);
+error2:
+ close (pdto[0]);
+ close (pdto[1]);
+error1:
+ return -1;
+}
diff --git a/sunrpc/rpc/auth.h b/sunrpc/rpc/auth.h
new file mode 100644
index 0000000000..22174193d4
--- /dev/null
+++ b/sunrpc/rpc/auth.h
@@ -0,0 +1,210 @@
+/* @(#)auth.h 2.3 88/08/07 4.0 RPCSRC; from 1.17 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * auth.h, Authentication interface.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * The data structures are completely opaque to the client. The client
+ * is required to pass a AUTH * to routines that create rpc
+ * "sessions".
+ */
+
+#ifndef _RPC_AUTH_H
+
+#define _RPC_AUTH_H 1
+#include <features.h>
+#include <rpc/xdr.h>
+
+__BEGIN_DECLS
+
+#define MAX_AUTH_BYTES 400
+#define MAXNETNAMELEN 255 /* maximum length of network user's name */
+
+/*
+ * Status returned from authentication check
+ */
+enum auth_stat {
+ AUTH_OK=0,
+ /*
+ * failed at remote end
+ */
+ AUTH_BADCRED=1, /* bogus credentials (seal broken) */
+ AUTH_REJECTEDCRED=2, /* client should begin new session */
+ AUTH_BADVERF=3, /* bogus verifier (seal broken) */
+ AUTH_REJECTEDVERF=4, /* verifier expired or was replayed */
+ AUTH_TOOWEAK=5, /* rejected due to security reasons */
+ /*
+ * failed locally
+ */
+ AUTH_INVALIDRESP=6, /* bogus response verifier */
+ AUTH_FAILED=7 /* some unknown reason */
+};
+
+union des_block {
+ struct {
+ u_int32_t high;
+ u_int32_t low;
+ } key;
+ char c[8];
+};
+typedef union des_block des_block;
+extern bool_t xdr_des_block __P ((XDR *__xdrs, des_block *__blkp));
+
+/*
+ * Authentication info. Opaque to client.
+ */
+struct opaque_auth {
+ enum_t oa_flavor; /* flavor of auth */
+ caddr_t oa_base; /* address of more auth stuff */
+ u_int oa_length; /* not to exceed MAX_AUTH_BYTES */
+};
+
+/*
+ * Auth handle, interface to client side authenticators.
+ */
+typedef struct AUTH AUTH;
+struct AUTH {
+ struct opaque_auth ah_cred;
+ struct opaque_auth ah_verf;
+ union des_block ah_key;
+ struct auth_ops {
+ void (*ah_nextverf) __P ((AUTH *));
+ int (*ah_marshal) __P ((AUTH *, XDR *)); /* nextverf & serialize */
+ int (*ah_validate) __P ((AUTH *, struct opaque_auth *));
+ /* validate verifier */
+ int (*ah_refresh) __P ((AUTH *)); /* refresh credentials */
+ void (*ah_destroy) __P ((AUTH *)); /* destroy this structure */
+ } *ah_ops;
+ caddr_t ah_private;
+};
+
+
+/*
+ * Authentication ops.
+ * The ops and the auth handle provide the interface to the authenticators.
+ *
+ * AUTH *auth;
+ * XDR *xdrs;
+ * struct opaque_auth verf;
+ */
+#define AUTH_NEXTVERF(auth) \
+ ((*((auth)->ah_ops->ah_nextverf))(auth))
+#define auth_nextverf(auth) \
+ ((*((auth)->ah_ops->ah_nextverf))(auth))
+
+#define AUTH_MARSHALL(auth, xdrs) \
+ ((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
+#define auth_marshall(auth, xdrs) \
+ ((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
+
+#define AUTH_VALIDATE(auth, verfp) \
+ ((*((auth)->ah_ops->ah_validate))((auth), verfp))
+#define auth_validate(auth, verfp) \
+ ((*((auth)->ah_ops->ah_validate))((auth), verfp))
+
+#define AUTH_REFRESH(auth) \
+ ((*((auth)->ah_ops->ah_refresh))(auth))
+#define auth_refresh(auth) \
+ ((*((auth)->ah_ops->ah_refresh))(auth))
+
+#define AUTH_DESTROY(auth) \
+ ((*((auth)->ah_ops->ah_destroy))(auth))
+#define auth_destroy(auth) \
+ ((*((auth)->ah_ops->ah_destroy))(auth))
+
+
+extern struct opaque_auth _null_auth;
+
+
+/*
+ * These are the various implementations of client side authenticators.
+ */
+
+/*
+ * Unix style authentication
+ * AUTH *authunix_create(machname, uid, gid, len, aup_gids)
+ * char *machname;
+ * int uid;
+ * int gid;
+ * int len;
+ * int *aup_gids;
+ */
+extern AUTH *authunix_create __P ((char *__machname, __uid_t __uid,
+ __gid_t __gid, int __len,
+ __gid_t *__aup_gids));
+extern AUTH *authunix_create_default __P ((void));
+extern AUTH *authnone_create __P ((void));
+extern AUTH *authdes_create __P ((const char *__servername, u_int __window,
+ struct sockaddr *__syncaddr,
+ des_block *__ckey));
+
+#define AUTH_NONE 0 /* no authentication */
+#define AUTH_NULL 0 /* backward compatibility */
+#define AUTH_SYS 1 /* unix style (uid, gids) */
+#define AUTH_UNIX AUTH_SYS
+#define AUTH_SHORT 2 /* short hand unix style */
+#define AUTH_DES 3 /* des style (encrypted timestamps) */
+#define AUTH_KERB 4 /* kerberos style */
+
+/*
+ * Netname manipulating functions
+ *
+ */
+extern int getnetname __P ((char *));
+extern int host2netname __P ((char *, __const char *, __const char *));
+extern int user2netname __P ((char *, __const uid_t, __const char *));
+extern int netname2user __P ((__const char *, uid_t *, gid_t *, int *,
+ gid_t *));
+extern int netname2host __P ((__const char *, char *, __const int));
+
+/*
+ *
+ * These routines interface to the keyserv daemon
+ *
+ */
+extern int key_decryptsession __P ((char *, des_block *));
+extern int key_decryptsession_pk __P ((char *, netobj *, des_block *));
+extern int key_encryptsession __P ((char *, des_block *));
+extern int key_encryptsession_pk __P ((char *, netobj *, des_block *));
+extern int key_gendes __P ((des_block *));
+extern int key_setsecret __P ((char *));
+extern int key_secretkey_is_set __P ((void));
+extern int key_get_conv __P ((char *, des_block *));
+
+__END_DECLS
+
+/* This is for compiling the glibc NIS+ code with DES auth. */
+#ifdef _LIBC
+#define HAVE_SECURE_RPC 1
+#endif
+
+#endif /* rpc/auth.h */
diff --git a/sunrpc/rpc/auth_des.h b/sunrpc/rpc/auth_des.h
new file mode 100644
index 0000000000..87fb8f0e99
--- /dev/null
+++ b/sunrpc/rpc/auth_des.h
@@ -0,0 +1,104 @@
+/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifndef _RPC_AUTH_DES_H
+
+#define _RPC_AUTH_DES_H 1
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+/* There are two kinds of "names": fullnames and nicknames */
+enum authdes_namekind
+ {
+ ADN_FULLNAME,
+ ADN_NICKNAME
+ };
+
+/* A fullname contains the network name of the client,
+ a conversation key and the window */
+struct authdes_fullname
+ {
+ char *name; /* network name of client, up to MAXNETNAMELEN */
+ des_block key; /* conversation key */
+ u_long window; /* associated window */
+ };
+
+/* A credential */
+struct authdes_cred
+ {
+ enum authdes_namekind adc_namekind;
+ struct authdes_fullname adc_fullname;
+ u_long adc_nickname;
+ };
+
+/* A des authentication verifier */
+struct authdes_verf
+ {
+ union
+ {
+ struct timeval adv_ctime; /* clear time */
+ des_block adv_xtime; /* crypt time */
+ }
+ adv_time_u;
+ u_long adv_int_u;
+ };
+
+/* des authentication verifier: client variety
+
+ adv_timestamp is the current time.
+ adv_winverf is the credential window + 1.
+ Both are encrypted using the conversation key. */
+#define adv_timestamp adv_time_u.adv_ctime
+#define adv_xtimestamp adv_time_u.adv_xtime
+#define adv_winverf adv_int_u
+
+/* des authentication verifier: server variety
+
+ adv_timeverf is the client's timestamp + client's window
+ adv_nickname is the server's nickname for the client.
+ adv_timeverf is encrypted using the conversation key. */
+#define adv_timeverf adv_time_u.adv_ctime
+#define adv_xtimeverf adv_time_u.adv_xtime
+#define adv_nickname adv_int_u
+
+/* Map a des credential into a unix cred. */
+extern int authdes_getucred __P ((__const struct authdes_cred * __adc,
+ uid_t * __uid, gid_t * __gid,
+ short *__grouplen, gid_t * __groups));
+
+/* Get the public key for NAME and place it in KEY. NAME can only be
+ up to MAXNETNAMELEN bytes long and the destination buffer KEY should
+ have HEXKEYBATES + 1 bytes long to fit all characters from the key. */
+extern int getpublickey __P ((__const char *__name, char *__key));
+
+/* Get the secret key for NAME and place it in KEY. PASSWD is used to
+ decrypt the encrypted key stored in the database. NAME can only be
+ up to MAXNETNAMELEN bytes long and the destination buffer KEY
+ should have HEXKEYBATES + 1 bytes long to fit all characters from
+ the key. */
+extern int getsecretkey __P ((__const char *__name, char *__key,
+ __const char *__passwd));
+
+extern int rtime __P ((struct sockaddr_in *__addrp, struct timeval *__timep,
+ struct timeval *__timeout));
+
+__END_DECLS
+
+
+#endif /* rpc/auth_des.h */
diff --git a/sunrpc/rpc/des_crypt.h b/sunrpc/rpc/des_crypt.h
new file mode 100644
index 0000000000..e20cc38243
--- /dev/null
+++ b/sunrpc/rpc/des_crypt.h
@@ -0,0 +1,97 @@
+/*
+ * @(#)des_crypt.h 2.1 88/08/11 4.0 RPCSRC; from 1.4 88/02/08 (C) 1986 SMI
+ *
+ * des_crypt.h, des library routine interface
+ * Copyright (C) 1986, Sun Microsystems, Inc.
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#ifndef __DES_CRYPT_H__
+#define __DES_CRYPT_H__ 1
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+#define DES_MAXDATA 8192 /* max bytes encrypted in one call */
+#define DES_DIRMASK (1 << 0)
+#define DES_ENCRYPT (0*DES_DIRMASK) /* Encrypt */
+#define DES_DECRYPT (1*DES_DIRMASK) /* Decrypt */
+
+
+#define DES_DEVMASK (1 << 1)
+#define DES_HW (0*DES_DEVMASK) /* Use hardware device */
+#define DES_SW (1*DES_DEVMASK) /* Use software device */
+
+
+#define DESERR_NONE 0 /* succeeded */
+#define DESERR_NOHWDEVICE 1 /* succeeded, but hw device not available */
+#define DESERR_HWERROR 2 /* failed, hardware/driver error */
+#define DESERR_BADPARAM 3 /* failed, bad parameter to call */
+
+#define DES_FAILED(err) \
+ ((err) > DESERR_NOHWDEVICE)
+
+/*
+ * cbc_crypt()
+ * ecb_crypt()
+ *
+ * Encrypt (or decrypt) len bytes of a buffer buf.
+ * The length must be a multiple of eight.
+ * The key should have odd parity in the low bit of each byte.
+ * ivec is the input vector, and is updated to the new one (cbc only).
+ * The mode is created by oring together the appropriate parameters.
+ * DESERR_NOHWDEVICE is returned if DES_HW was specified but
+ * there was no hardware to do it on (the data will still be
+ * encrypted though, in software).
+ */
+
+
+/*
+ * Cipher Block Chaining mode
+ */
+extern int cbc_crypt __P ((char *__key, char *__buf, unsigned __len,
+ unsigned __mode, char *__ivec));
+
+/*
+ * Electronic Code Book mode
+ */
+extern int ecb_crypt __P ((char *__key, char *__buf, unsigned __len,
+ unsigned __mode));
+
+/*
+ * Set des parity for a key.
+ * DES parity is odd and in the low bit of each byte
+ */
+extern void des_setparity __P ((char *__key));
+
+__END_DECLS
+
+#endif
diff --git a/sunrpc/rpc/key_prot.h b/sunrpc/rpc/key_prot.h
new file mode 100644
index 0000000000..a23f2cd21b
--- /dev/null
+++ b/sunrpc/rpc/key_prot.h
@@ -0,0 +1,345 @@
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#ifndef _KEY_PROT_H_RPCGEN
+#define _KEY_PROT_H_RPCGEN
+
+#include <rpc/rpc.h>
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+#pragma ident "@(#)key_prot.x 1.7 94/04/29 SMI"
+
+/* Copyright (c) 1990, 1991 Sun Microsystems, Inc. */
+
+/*
+ * Compiled from key_prot.x using rpcgen.
+ * DO NOT EDIT THIS FILE!
+ * This is NOT source code!
+ */
+#define PROOT 3
+#define HEXMODULUS "d4a0ba0250b6fd2ec626e7efd637df76c716e22d0944b88b"
+#define HEXKEYBYTES 48
+#define KEYSIZE 192
+#define KEYBYTES 24
+#define KEYCHECKSUMSIZE 16
+
+enum keystatus {
+ KEY_SUCCESS = 0,
+ KEY_NOSECRET = 1,
+ KEY_UNKNOWN = 2,
+ KEY_SYSTEMERR = 3,
+};
+typedef enum keystatus keystatus;
+#ifdef __cplusplus
+extern "C" bool_t xdr_keystatus(XDR *, keystatus*);
+#elif __STDC__
+extern bool_t xdr_keystatus(XDR *, keystatus*);
+#else /* Old Style C */
+bool_t xdr_keystatus();
+#endif /* Old Style C */
+
+
+typedef char keybuf[HEXKEYBYTES];
+#ifdef __cplusplus
+extern "C" bool_t xdr_keybuf(XDR *, keybuf);
+#elif __STDC__
+extern bool_t xdr_keybuf(XDR *, keybuf);
+#else /* Old Style C */
+bool_t xdr_keybuf();
+#endif /* Old Style C */
+
+
+typedef char *netnamestr;
+#ifdef __cplusplus
+extern "C" bool_t xdr_netnamestr(XDR *, netnamestr*);
+#elif __STDC__
+extern bool_t xdr_netnamestr(XDR *, netnamestr*);
+#else /* Old Style C */
+bool_t xdr_netnamestr();
+#endif /* Old Style C */
+
+
+struct cryptkeyarg {
+ netnamestr remotename;
+ des_block deskey;
+};
+typedef struct cryptkeyarg cryptkeyarg;
+#ifdef __cplusplus
+extern "C" bool_t xdr_cryptkeyarg(XDR *, cryptkeyarg*);
+#elif __STDC__
+extern bool_t xdr_cryptkeyarg(XDR *, cryptkeyarg*);
+#else /* Old Style C */
+bool_t xdr_cryptkeyarg();
+#endif /* Old Style C */
+
+
+struct cryptkeyarg2 {
+ netnamestr remotename;
+ netobj remotekey;
+ des_block deskey;
+};
+typedef struct cryptkeyarg2 cryptkeyarg2;
+#ifdef __cplusplus
+extern "C" bool_t xdr_cryptkeyarg2(XDR *, cryptkeyarg2*);
+#elif __STDC__
+extern bool_t xdr_cryptkeyarg2(XDR *, cryptkeyarg2*);
+#else /* Old Style C */
+bool_t xdr_cryptkeyarg2();
+#endif /* Old Style C */
+
+
+struct cryptkeyres {
+ keystatus status;
+ union {
+ des_block deskey;
+ } cryptkeyres_u;
+};
+typedef struct cryptkeyres cryptkeyres;
+#ifdef __cplusplus
+extern "C" bool_t xdr_cryptkeyres(XDR *, cryptkeyres*);
+#elif __STDC__
+extern bool_t xdr_cryptkeyres(XDR *, cryptkeyres*);
+#else /* Old Style C */
+bool_t xdr_cryptkeyres();
+#endif /* Old Style C */
+
+#define MAXGIDS 16
+
+struct unixcred {
+ u_int uid;
+ u_int gid;
+ struct {
+ u_int gids_len;
+ u_int *gids_val;
+ } gids;
+};
+typedef struct unixcred unixcred;
+#ifdef __cplusplus
+extern "C" bool_t xdr_unixcred(XDR *, unixcred*);
+#elif __STDC__
+extern bool_t xdr_unixcred(XDR *, unixcred*);
+#else /* Old Style C */
+bool_t xdr_unixcred();
+#endif /* Old Style C */
+
+
+struct getcredres {
+ keystatus status;
+ union {
+ unixcred cred;
+ } getcredres_u;
+};
+typedef struct getcredres getcredres;
+#ifdef __cplusplus
+extern "C" bool_t xdr_getcredres(XDR *, getcredres*);
+#elif __STDC__
+extern bool_t xdr_getcredres(XDR *, getcredres*);
+#else /* Old Style C */
+bool_t xdr_getcredres();
+#endif /* Old Style C */
+
+
+struct key_netstarg {
+ keybuf st_priv_key;
+ keybuf st_pub_key;
+ netnamestr st_netname;
+};
+typedef struct key_netstarg key_netstarg;
+#ifdef __cplusplus
+extern "C" bool_t xdr_key_netstarg(XDR *, key_netstarg*);
+#elif __STDC__
+extern bool_t xdr_key_netstarg(XDR *, key_netstarg*);
+#else /* Old Style C */
+bool_t xdr_key_netstarg();
+#endif /* Old Style C */
+
+
+struct key_netstres {
+ keystatus status;
+ union {
+ key_netstarg knet;
+ } key_netstres_u;
+};
+typedef struct key_netstres key_netstres;
+#ifdef __cplusplus
+extern "C" bool_t xdr_key_netstres(XDR *, key_netstres*);
+#elif __STDC__
+extern bool_t xdr_key_netstres(XDR *, key_netstres*);
+#else /* Old Style C */
+bool_t xdr_key_netstres();
+#endif /* Old Style C */
+
+
+#ifndef opaque
+#define opaque char
+#endif
+
+
+#define KEY_PROG ((u_long)100029)
+#define KEY_VERS ((u_long)1)
+
+#ifdef __cplusplus
+#define KEY_SET ((u_long)1)
+extern "C" keystatus * key_set_1(opaque *, CLIENT *);
+extern "C" keystatus * key_set_1_svc(opaque *, struct svc_req *);
+#define KEY_ENCRYPT ((u_long)2)
+extern "C" cryptkeyres * key_encrypt_1(cryptkeyarg *, CLIENT *);
+extern "C" cryptkeyres * key_encrypt_1_svc(cryptkeyarg *, struct svc_req *);
+#define KEY_DECRYPT ((u_long)3)
+extern "C" cryptkeyres * key_decrypt_1(cryptkeyarg *, CLIENT *);
+extern "C" cryptkeyres * key_decrypt_1_svc(cryptkeyarg *, struct svc_req *);
+#define KEY_GEN ((u_long)4)
+extern "C" des_block * key_gen_1(void *, CLIENT *);
+extern "C" des_block * key_gen_1_svc(void *, struct svc_req *);
+#define KEY_GETCRED ((u_long)5)
+extern "C" getcredres * key_getcred_1(netnamestr *, CLIENT *);
+extern "C" getcredres * key_getcred_1_svc(netnamestr *, struct svc_req *);
+
+#elif __STDC__
+#define KEY_SET ((u_long)1)
+extern keystatus * key_set_1(opaque *, CLIENT *);
+extern keystatus * key_set_1_svc(opaque *, struct svc_req *);
+#define KEY_ENCRYPT ((u_long)2)
+extern cryptkeyres * key_encrypt_1(cryptkeyarg *, CLIENT *);
+extern cryptkeyres * key_encrypt_1_svc(cryptkeyarg *, struct svc_req *);
+#define KEY_DECRYPT ((u_long)3)
+extern cryptkeyres * key_decrypt_1(cryptkeyarg *, CLIENT *);
+extern cryptkeyres * key_decrypt_1_svc(cryptkeyarg *, struct svc_req *);
+#define KEY_GEN ((u_long)4)
+extern des_block * key_gen_1(void *, CLIENT *);
+extern des_block * key_gen_1_svc(void *, struct svc_req *);
+#define KEY_GETCRED ((u_long)5)
+extern getcredres * key_getcred_1(netnamestr *, CLIENT *);
+extern getcredres * key_getcred_1_svc(netnamestr *, struct svc_req *);
+
+#else /* Old Style C */
+#define KEY_SET ((u_long)1)
+extern keystatus * key_set_1();
+extern keystatus * key_set_1_svc();
+#define KEY_ENCRYPT ((u_long)2)
+extern cryptkeyres * key_encrypt_1();
+extern cryptkeyres * key_encrypt_1_svc();
+#define KEY_DECRYPT ((u_long)3)
+extern cryptkeyres * key_decrypt_1();
+extern cryptkeyres * key_decrypt_1_svc();
+#define KEY_GEN ((u_long)4)
+extern des_block * key_gen_1();
+extern des_block * key_gen_1_svc();
+#define KEY_GETCRED ((u_long)5)
+extern getcredres * key_getcred_1();
+extern getcredres * key_getcred_1_svc();
+#endif /* Old Style C */
+#define KEY_VERS2 ((u_long)2)
+
+#ifdef __cplusplus
+extern "C" keystatus * key_set_2(opaque *, CLIENT *);
+extern "C" keystatus * key_set_2_svc(opaque *, struct svc_req *);
+extern "C" cryptkeyres * key_encrypt_2(cryptkeyarg *, CLIENT *);
+extern "C" cryptkeyres * key_encrypt_2_svc(cryptkeyarg *, struct svc_req *);
+extern "C" cryptkeyres * key_decrypt_2(cryptkeyarg *, CLIENT *);
+extern "C" cryptkeyres * key_decrypt_2_svc(cryptkeyarg *, struct svc_req *);
+extern "C" des_block * key_gen_2(void *, CLIENT *);
+extern "C" des_block * key_gen_2_svc(void *, struct svc_req *);
+extern "C" getcredres * key_getcred_2(netnamestr *, CLIENT *);
+extern "C" getcredres * key_getcred_2_svc(netnamestr *, struct svc_req *);
+#define KEY_ENCRYPT_PK ((u_long)6)
+extern "C" cryptkeyres * key_encrypt_pk_2(cryptkeyarg2 *, CLIENT *);
+extern "C" cryptkeyres * key_encrypt_pk_2_svc(cryptkeyarg2 *, struct svc_req *);
+#define KEY_DECRYPT_PK ((u_long)7)
+extern "C" cryptkeyres * key_decrypt_pk_2(cryptkeyarg2 *, CLIENT *);
+extern "C" cryptkeyres * key_decrypt_pk_2_svc(cryptkeyarg2 *, struct svc_req *);
+#define KEY_NET_PUT ((u_long)8)
+extern "C" keystatus * key_net_put_2(key_netstarg *, CLIENT *);
+extern "C" keystatus * key_net_put_2_svc(key_netstarg *, struct svc_req *);
+#define KEY_NET_GET ((u_long)9)
+extern "C" key_netstres * key_net_get_2(void *, CLIENT *);
+extern "C" key_netstres * key_net_get_2_svc(void *, struct svc_req *);
+#define KEY_GET_CONV ((u_long)10)
+extern "C" cryptkeyres * key_get_conv_2(opaque *, CLIENT *);
+extern "C" cryptkeyres * key_get_conv_2_svc(opaque *, struct svc_req *);
+
+#elif __STDC__
+extern keystatus * key_set_2(opaque *, CLIENT *);
+extern keystatus * key_set_2_svc(opaque *, struct svc_req *);
+extern cryptkeyres * key_encrypt_2(cryptkeyarg *, CLIENT *);
+extern cryptkeyres * key_encrypt_2_svc(cryptkeyarg *, struct svc_req *);
+extern cryptkeyres * key_decrypt_2(cryptkeyarg *, CLIENT *);
+extern cryptkeyres * key_decrypt_2_svc(cryptkeyarg *, struct svc_req *);
+extern des_block * key_gen_2(void *, CLIENT *);
+extern des_block * key_gen_2_svc(void *, struct svc_req *);
+extern getcredres * key_getcred_2(netnamestr *, CLIENT *);
+extern getcredres * key_getcred_2_svc(netnamestr *, struct svc_req *);
+#define KEY_ENCRYPT_PK ((u_long)6)
+extern cryptkeyres * key_encrypt_pk_2(cryptkeyarg2 *, CLIENT *);
+extern cryptkeyres * key_encrypt_pk_2_svc(cryptkeyarg2 *, struct svc_req *);
+#define KEY_DECRYPT_PK ((u_long)7)
+extern cryptkeyres * key_decrypt_pk_2(cryptkeyarg2 *, CLIENT *);
+extern cryptkeyres * key_decrypt_pk_2_svc(cryptkeyarg2 *, struct svc_req *);
+#define KEY_NET_PUT ((u_long)8)
+extern keystatus * key_net_put_2(key_netstarg *, CLIENT *);
+extern keystatus * key_net_put_2_svc(key_netstarg *, struct svc_req *);
+#define KEY_NET_GET ((u_long)9)
+extern key_netstres * key_net_get_2(void *, CLIENT *);
+extern key_netstres * key_net_get_2_svc(void *, struct svc_req *);
+#define KEY_GET_CONV ((u_long)10)
+extern cryptkeyres * key_get_conv_2(opaque *, CLIENT *);
+extern cryptkeyres * key_get_conv_2_svc(opaque *, struct svc_req *);
+
+#else /* Old Style C */
+extern keystatus * key_set_2();
+extern keystatus * key_set_2_svc();
+extern cryptkeyres * key_encrypt_2();
+extern cryptkeyres * key_encrypt_2_svc();
+extern cryptkeyres * key_decrypt_2();
+extern cryptkeyres * key_decrypt_2_svc();
+extern des_block * key_gen_2();
+extern des_block * key_gen_2_svc();
+extern getcredres * key_getcred_2();
+extern getcredres * key_getcred_2_svc();
+#define KEY_ENCRYPT_PK ((u_long)6)
+extern cryptkeyres * key_encrypt_pk_2();
+extern cryptkeyres * key_encrypt_pk_2_svc();
+#define KEY_DECRYPT_PK ((u_long)7)
+extern cryptkeyres * key_decrypt_pk_2();
+extern cryptkeyres * key_decrypt_pk_2_svc();
+#define KEY_NET_PUT ((u_long)8)
+extern keystatus * key_net_put_2();
+extern keystatus * key_net_put_2_svc();
+#define KEY_NET_GET ((u_long)9)
+extern key_netstres * key_net_get_2();
+extern key_netstres * key_net_get_2_svc();
+#define KEY_GET_CONV ((u_long)10)
+extern cryptkeyres * key_get_conv_2();
+extern cryptkeyres * key_get_conv_2_svc();
+#endif /* Old Style C */
+
+#endif /* !_KEY_PROT_H_RPCGEN */
diff --git a/sunrpc/rpcsvc/key_prot.x b/sunrpc/rpcsvc/key_prot.x
new file mode 100644
index 0000000000..af22a208c5
--- /dev/null
+++ b/sunrpc/rpcsvc/key_prot.x
@@ -0,0 +1,284 @@
+%/*
+% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+% * unrestricted use provided that this legend is included on all tape
+% * media and as a part of the software program in whole or part. Users
+% * may copy or modify Sun RPC without charge, but are not authorized
+% * to license or distribute it to anyone else except as part of a product or
+% * program developed by the user.
+% *
+% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+% *
+% * Sun RPC is provided with no support and without any obligation on the
+% * part of Sun Microsystems, Inc. to assist in its use, correction,
+% * modification or enhancement.
+% *
+% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+% * OR ANY PART THEREOF.
+% *
+% * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+% * or profits or other special, indirect and consequential damages, even if
+% * Sun has been advised of the possibility of such damages.
+% *
+% * Sun Microsystems, Inc.
+% * 2550 Garcia Avenue
+% * Mountain View, California 94043
+% */
+/*
+ * Key server protocol definition
+ * Copyright (C) 1990, 1991 Sun Microsystems, Inc.
+ *
+ * The keyserver is a public key storage/encryption/decryption service
+ * The encryption method used is based on the Diffie-Hellman exponential
+ * key exchange technology.
+ *
+ * The key server is local to each machine, akin to the portmapper.
+ * Under TI-RPC, communication with the keyserver is through the
+ * loopback transport.
+ *
+ * NOTE: This .x file generates the USER level headers for the keyserver.
+ * the KERNEL level headers are created by hand as they kernel has special
+ * requirements.
+ */
+
+%#pragma ident "@(#)key_prot.x 1.7 94/04/29 SMI"
+%
+%/* Copyright (c) 1990, 1991 Sun Microsystems, Inc. */
+%
+%/*
+% * Compiled from key_prot.x using rpcgen.
+% * DO NOT EDIT THIS FILE!
+% * This is NOT source code!
+% */
+
+/*
+ * PROOT and MODULUS define the way the Diffie-Hellman key is generated.
+ *
+ * MODULUS should be chosen as a prime of the form: MODULUS == 2*p + 1,
+ * where p is also prime.
+ *
+ * PROOT satisfies the following two conditions:
+ * (1) (PROOT ** 2) % MODULUS != 1
+ * (2) (PROOT ** p) % MODULUS != 1
+ *
+ */
+
+const PROOT = 3;
+const HEXMODULUS = "d4a0ba0250b6fd2ec626e7efd637df76c716e22d0944b88b";
+
+const HEXKEYBYTES = 48; /* HEXKEYBYTES == strlen(HEXMODULUS) */
+const KEYSIZE = 192; /* KEYSIZE == bit length of key */
+const KEYBYTES = 24; /* byte length of key */
+
+/*
+ * The first 16 hex digits of the encrypted secret key are used as
+ * a checksum in the database.
+ */
+const KEYCHECKSUMSIZE = 16;
+
+/*
+ * status of operation
+ */
+enum keystatus {
+ KEY_SUCCESS, /* no problems */
+ KEY_NOSECRET, /* no secret key stored */
+ KEY_UNKNOWN, /* unknown netname */
+ KEY_SYSTEMERR /* system error (out of memory, encryption failure) */
+};
+
+typedef opaque keybuf[HEXKEYBYTES]; /* store key in hex */
+
+typedef string netnamestr<MAXNETNAMELEN>;
+
+/*
+ * Argument to ENCRYPT or DECRYPT
+ */
+struct cryptkeyarg {
+ netnamestr remotename;
+ des_block deskey;
+};
+
+/*
+ * Argument to ENCRYPT_PK or DECRYPT_PK
+ */
+struct cryptkeyarg2 {
+ netnamestr remotename;
+ netobj remotekey; /* Contains a length up to 1024 bytes */
+ des_block deskey;
+};
+
+
+/*
+ * Result of ENCRYPT, DECRYPT, ENCRYPT_PK, and DECRYPT_PK
+ */
+union cryptkeyres switch (keystatus status) {
+case KEY_SUCCESS:
+ des_block deskey;
+default:
+ void;
+};
+
+const MAXGIDS = 16; /* max number of gids in gid list */
+
+/*
+ * Unix credential
+ */
+struct unixcred {
+ u_int uid;
+ u_int gid;
+ u_int gids<MAXGIDS>;
+};
+
+/*
+ * Result returned from GETCRED
+ */
+union getcredres switch (keystatus status) {
+case KEY_SUCCESS:
+ unixcred cred;
+default:
+ void;
+};
+/*
+ * key_netstarg;
+ */
+
+struct key_netstarg {
+ keybuf st_priv_key;
+ keybuf st_pub_key;
+ netnamestr st_netname;
+};
+
+union key_netstres switch (keystatus status){
+case KEY_SUCCESS:
+ key_netstarg knet;
+default:
+ void;
+};
+
+#ifdef RPC_HDR
+%
+%#ifndef opaque
+%#define opaque char
+%#endif
+%
+#endif
+program KEY_PROG {
+ version KEY_VERS {
+
+ /*
+ * This is my secret key.
+ * Store it for me.
+ */
+ keystatus
+ KEY_SET(keybuf) = 1;
+
+ /*
+ * I want to talk to X.
+ * Encrypt a conversation key for me.
+ */
+ cryptkeyres
+ KEY_ENCRYPT(cryptkeyarg) = 2;
+
+ /*
+ * X just sent me a message.
+ * Decrypt the conversation key for me.
+ */
+ cryptkeyres
+ KEY_DECRYPT(cryptkeyarg) = 3;
+
+ /*
+ * Generate a secure conversation key for me
+ */
+ des_block
+ KEY_GEN(void) = 4;
+
+ /*
+ * Get me the uid, gid and group-access-list associated
+ * with this netname (for kernel which cannot use NIS)
+ */
+ getcredres
+ KEY_GETCRED(netnamestr) = 5;
+ } = 1;
+ version KEY_VERS2 {
+
+ /*
+ * #######
+ * Procedures 1-5 are identical to version 1
+ * #######
+ */
+
+ /*
+ * This is my secret key.
+ * Store it for me.
+ */
+ keystatus
+ KEY_SET(keybuf) = 1;
+
+ /*
+ * I want to talk to X.
+ * Encrypt a conversation key for me.
+ */
+ cryptkeyres
+ KEY_ENCRYPT(cryptkeyarg) = 2;
+
+ /*
+ * X just sent me a message.
+ * Decrypt the conversation key for me.
+ */
+ cryptkeyres
+ KEY_DECRYPT(cryptkeyarg) = 3;
+
+ /*
+ * Generate a secure conversation key for me
+ */
+ des_block
+ KEY_GEN(void) = 4;
+
+ /*
+ * Get me the uid, gid and group-access-list associated
+ * with this netname (for kernel which cannot use NIS)
+ */
+ getcredres
+ KEY_GETCRED(netnamestr) = 5;
+
+ /*
+ * I want to talk to X. and I know X's public key
+ * Encrypt a conversation key for me.
+ */
+ cryptkeyres
+ KEY_ENCRYPT_PK(cryptkeyarg2) = 6;
+
+ /*
+ * X just sent me a message. and I know X's public key
+ * Decrypt the conversation key for me.
+ */
+ cryptkeyres
+ KEY_DECRYPT_PK(cryptkeyarg2) = 7;
+
+ /*
+ * Store my public key, netname and private key.
+ */
+ keystatus
+ KEY_NET_PUT(key_netstarg) = 8;
+
+ /*
+ * Retrieve my public key, netname and private key.
+ */
+ key_netstres
+ KEY_NET_GET(void) = 9;
+
+ /*
+ * Return me the conversation key that is constructed
+ * from my secret key and this publickey.
+ */
+
+ cryptkeyres
+ KEY_GET_CONV(keybuf) = 10;
+
+
+ } = 2;
+} = 100029;
+
+
diff --git a/sunrpc/rtime.c b/sunrpc/rtime.c
new file mode 100644
index 0000000000..baaced0d5d
--- /dev/null
+++ b/sunrpc/rtime.c
@@ -0,0 +1,146 @@
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)rtime.c 2.2 88/08/10 4.0 RPCSRC; from 1.8 88/02/08 SMI";
+#endif
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * Copyright (c) 1988 by Sun Microsystems, Inc.
+ */
+/*
+ * rtime - get time from remote machine
+ *
+ * gets time, obtaining value from host
+ * on the udp/time socket. Since timeserver returns
+ * with time of day in seconds since Jan 1, 1900, must
+ * subtract seconds before Jan 1, 1970 to get
+ * what unix uses.
+ */
+#include <stdio.h>
+#include <unistd.h>
+#include <rpc/rpc.h>
+#include <rpc/clnt.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <rpc/auth_des.h>
+#include <errno.h>
+#include <netinet/in.h>
+
+#define NYEARS (u_long)(1970 - 1900)
+#define TOFFSET (u_long)(60*60*24*(365*NYEARS + (NYEARS/4)))
+
+static void do_close (int);
+
+static void
+do_close (int s)
+{
+ int save;
+
+ save = errno;
+ close (s);
+ __set_errno (save);
+}
+
+int
+rtime (struct sockaddr_in *addrp, struct timeval *timep,
+ struct timeval *timeout)
+{
+ int s;
+ fd_set readfds;
+ int res;
+ unsigned long thetime;
+ struct sockaddr_in from;
+ int fromlen;
+ int type;
+
+ if (timeout == NULL)
+ type = SOCK_STREAM;
+ else
+ type = SOCK_DGRAM;
+
+ s = socket (AF_INET, type, 0);
+ if (s < 0)
+ return (-1);
+
+ addrp->sin_family = AF_INET;
+ addrp->sin_port = htons (IPPORT_TIMESERVER);
+ if (type == SOCK_DGRAM)
+ {
+ res = sendto (s, (char *) &thetime, sizeof (thetime), 0,
+ (struct sockaddr *) addrp, sizeof (*addrp));
+ if (res < 0)
+ {
+ do_close (s);
+ return -1;
+ }
+ do
+ {
+ FD_ZERO (&readfds);
+ FD_SET (s, &readfds);
+ res = select (_rpc_dtablesize (), &readfds, (void *) NULL,
+ (void *) NULL, timeout);
+ }
+ while (res < 0 && errno == EINTR);
+ if (res <= 0)
+ {
+ if (res == 0)
+ __set_errno (ETIMEDOUT);
+ do_close (s);
+ return (-1);
+ }
+ fromlen = sizeof (from);
+ res = recvfrom (s, (char *) &thetime, sizeof (thetime), 0,
+ (struct sockaddr *) &from, &fromlen);
+ do_close (s);
+ if (res < 0)
+ return -1;
+ }
+ else
+ {
+ if (connect (s, (struct sockaddr *) addrp, sizeof (*addrp)) < 0)
+ {
+ do_close (s);
+ return -1;
+ }
+ res = read (s, (char *) &thetime, sizeof (thetime));
+ do_close (s);
+ if (res < 0)
+ return (-1);
+ }
+ if (res != sizeof (thetime))
+ {
+ __set_errno (EIO);
+ return -1;
+ }
+ thetime = ntohl (thetime);
+ timep->tv_sec = thetime - TOFFSET;
+ timep->tv_usec = 0;
+ return 0;
+}
diff --git a/sunrpc/svc_auth.c b/sunrpc/svc_auth.c
new file mode 100644
index 0000000000..f0aebd5358
--- /dev/null
+++ b/sunrpc/svc_auth.c
@@ -0,0 +1,119 @@
+/* @(#)svc_auth.c 2.4 88/08/15 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)svc_auth.c 1.19 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * svc_auth.c, Server-side rpc authenticator interface.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/rpc.h>
+#include <rpc/svc.h>
+#include <rpc/svc_auth.h>
+
+/*
+ * svcauthsw is the bdevsw of server side authentication.
+ *
+ * Server side authenticators are called from authenticate by
+ * using the client auth struct flavor field to index into svcauthsw.
+ * The server auth flavors must implement a routine that looks
+ * like:
+ *
+ * enum auth_stat
+ * flavorx_auth(rqst, msg)
+ * register struct svc_req *rqst;
+ * register struct rpc_msg *msg;
+ *
+ */
+
+static enum auth_stat _svcauth_null (struct svc_req *, struct rpc_msg *);
+ /* no authentication */
+extern enum auth_stat _svcauth_unix (struct svc_req *, struct rpc_msg *);
+ /* unix style (uid, gids) */
+extern enum auth_stat _svcauth_short (struct svc_req *, struct rpc_msg *);
+ /* short hand unix style */
+extern enum auth_stat _svcauth_des (struct svc_req *, struct rpc_msg *);
+ /* des style */
+
+static const struct
+ {
+ enum auth_stat (*authenticator) (struct svc_req *, struct rpc_msg *);
+ }
+svcauthsw[] =
+{
+ { _svcauth_null }, /* AUTH_NULL */
+ { _svcauth_unix }, /* AUTH_UNIX */
+ { _svcauth_short }, /* AUTH_SHORT */
+ { _svcauth_des } /* AUTH_DES */
+};
+#define AUTH_MAX 3 /* HIGHEST AUTH NUMBER */
+
+
+/*
+ * The call rpc message, msg has been obtained from the wire. The msg contains
+ * the raw form of credentials and verifiers. authenticate returns AUTH_OK
+ * if the msg is successfully authenticated. If AUTH_OK then the routine also
+ * does the following things:
+ * set rqst->rq_xprt->verf to the appropriate response verifier;
+ * sets rqst->rq_client_cred to the "cooked" form of the credentials.
+ *
+ * NB: rqst->rq_cxprt->verf must be pre-allocated;
+ * its length is set appropriately.
+ *
+ * The caller still owns and is responsible for msg->u.cmb.cred and
+ * msg->u.cmb.verf. The authentication system retains ownership of
+ * rqst->rq_client_cred, the cooked credentials.
+ *
+ * There is an assumption that any flavour less than AUTH_NULL is
+ * invalid.
+ */
+enum auth_stat
+_authenticate (register struct svc_req *rqst, struct rpc_msg *msg)
+{
+ register int cred_flavor;
+
+ rqst->rq_cred = msg->rm_call.cb_cred;
+ rqst->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor;
+ rqst->rq_xprt->xp_verf.oa_length = 0;
+ cred_flavor = rqst->rq_cred.oa_flavor;
+ if ((cred_flavor <= AUTH_MAX) && (cred_flavor >= AUTH_NULL))
+ return (*(svcauthsw[cred_flavor].authenticator)) (rqst, msg);
+
+ return AUTH_REJECTEDCRED;
+}
+
+static enum auth_stat
+_svcauth_null (struct svc_req *rqst, struct rpc_msg *msg)
+{
+ return AUTH_OK;
+}
diff --git a/sunrpc/svcauth_des.c b/sunrpc/svcauth_des.c
new file mode 100644
index 0000000000..3547830267
--- /dev/null
+++ b/sunrpc/svcauth_des.c
@@ -0,0 +1,548 @@
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)svcauth_des.c 2.3 89/07/11 4.0 RPCSRC; from 1.15 88/02/08 SMI";
+#endif
+
+/*
+ * Copyright (c) 1988 by Sun Microsystems, Inc.
+ */
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * svcauth_des.c, server-side des authentication
+ *
+ * We insure for the service the following:
+ * (1) The timestamp microseconds do not exceed 1 million.
+ * (2) The timestamp plus the window is less than the current time.
+ * (3) The timestamp is not less than the one previously
+ * seen in the current session.
+ *
+ * It is up to the server to determine if the window size is
+ * too small .
+ *
+ */
+
+#include <string.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#include <rpc/auth_des.h>
+#include <rpc/svc_auth.h>
+#include <rpc/svc.h>
+#include <rpc/des_crypt.h>
+
+#define debug(msg) /*printf("svcauth_des: %s\n", msg) */
+
+#define USEC_PER_SEC ((u_long) 1000000L)
+#define BEFORE(t1, t2) timercmp(t1, t2, <)
+
+/*
+ * LRU cache of conversation keys and some other useful items.
+ */
+#define AUTHDES_CACHESZ 64
+struct cache_entry
+ {
+ des_block key; /* conversation key */
+ char *rname; /* client's name */
+ u_int window; /* credential lifetime window */
+ struct timeval laststamp; /* detect replays of creds */
+ char *localcred; /* generic local credential */
+ };
+static struct cache_entry *authdes_cache /* [AUTHDES_CACHESZ] */ ;
+static short *authdes_lru /* [AUTHDES_CACHESZ] */ ;
+
+static void cache_init (void); /* initialize the cache */
+static short cache_spot (des_block *, char *, struct timeval *);
+ /* find an entry in the cache */
+static void cache_ref (short sid); /* note that sid was ref'd */
+
+static void invalidate (char *cred); /* invalidate entry in cache */
+
+/*
+ * cache statistics
+ */
+struct
+ {
+ u_long ncachehits; /* times cache hit, and is not replay */
+ u_long ncachereplays; /* times cache hit, and is replay */
+ u_long ncachemisses; /* times cache missed */
+ }
+svcauthdes_stats;
+
+/*
+ * Service side authenticator for AUTH_DES
+ */
+enum auth_stat
+_svcauth_des (register struct svc_req *rqst, register struct rpc_msg *msg)
+{
+ register long *ixdr;
+ des_block cryptbuf[2];
+ register struct authdes_cred *cred;
+ struct authdes_verf verf;
+ int status;
+ register struct cache_entry *entry;
+ short sid = 0;
+ des_block *sessionkey;
+ des_block ivec;
+ u_int window;
+ struct timeval timestamp;
+ u_long namelen;
+ struct area
+ {
+ struct authdes_cred area_cred;
+ char area_netname[MAXNETNAMELEN + 1];
+ }
+ *area;
+
+ if (authdes_cache == NULL)
+ cache_init ();
+
+ area = (struct area *) rqst->rq_clntcred;
+ cred = (struct authdes_cred *) &area->area_cred;
+
+ /*
+ * Get the credential
+ */
+ ixdr = (long *) msg->rm_call.cb_cred.oa_base;
+ cred->adc_namekind = IXDR_GET_ENUM (ixdr, enum authdes_namekind);
+ switch (cred->adc_namekind)
+ {
+ case ADN_FULLNAME:
+ namelen = IXDR_GET_U_LONG (ixdr);
+ if (namelen > MAXNETNAMELEN)
+ {
+ return AUTH_BADCRED;
+ }
+ cred->adc_fullname.name = area->area_netname;
+ bcopy ((char *) ixdr, cred->adc_fullname.name,
+ (u_int) namelen);
+ cred->adc_fullname.name[namelen] = 0;
+ ixdr += (RNDUP (namelen) / BYTES_PER_XDR_UNIT);
+ cred->adc_fullname.key.key.high = (u_long) * ixdr++;
+ cred->adc_fullname.key.key.low = (u_long) * ixdr++;
+ cred->adc_fullname.window = (u_long) * ixdr++;
+ break;
+ case ADN_NICKNAME:
+ cred->adc_nickname = (u_long) * ixdr++;
+ break;
+ default:
+ return AUTH_BADCRED;
+ }
+
+ /*
+ * Get the verifier
+ */
+ ixdr = (long *) msg->rm_call.cb_verf.oa_base;
+ verf.adv_xtimestamp.key.high = (u_long) * ixdr++;
+ verf.adv_xtimestamp.key.low = (u_long) * ixdr++;
+ verf.adv_int_u = (u_long) * ixdr++;
+
+
+ /*
+ * Get the conversation key
+ */
+ if (cred->adc_namekind == ADN_FULLNAME)
+ {
+ sessionkey = &cred->adc_fullname.key;
+ if (key_decryptsession (cred->adc_fullname.name,
+ sessionkey) < 0)
+ {
+ debug ("decryptsessionkey");
+ return AUTH_BADCRED; /* key not found */
+ }
+ }
+ else
+ { /* ADN_NICKNAME */
+ sid = (short) cred->adc_nickname;
+ if (sid >= AUTHDES_CACHESZ)
+ {
+ debug ("bad nickname");
+ return AUTH_BADCRED; /* garbled credential */
+ }
+ sessionkey = &authdes_cache[sid].key;
+ }
+
+
+ /*
+ * Decrypt the timestamp
+ */
+ cryptbuf[0] = verf.adv_xtimestamp;
+ if (cred->adc_namekind == ADN_FULLNAME)
+ {
+ cryptbuf[1].key.high = cred->adc_fullname.window;
+ cryptbuf[1].key.low = verf.adv_winverf;
+ ivec.key.high = ivec.key.low = 0;
+ status = cbc_crypt ((char *) sessionkey, (char *) cryptbuf,
+ 2 * sizeof (des_block), DES_DECRYPT | DES_HW,
+ (char *) &ivec);
+ }
+ else
+ {
+ status = ecb_crypt ((char *) sessionkey, (char *) cryptbuf,
+ sizeof (des_block), DES_DECRYPT | DES_HW);
+ }
+ if (DES_FAILED (status))
+ {
+ debug ("decryption failure");
+ return AUTH_FAILED; /* system error */
+ }
+
+ /*
+ * XDR the decrypted timestamp
+ */
+ ixdr = (long *) cryptbuf;
+ timestamp.tv_sec = IXDR_GET_LONG (ixdr);
+ timestamp.tv_usec = IXDR_GET_LONG (ixdr);
+
+ /*
+ * Check for valid credentials and verifiers.
+ * They could be invalid because the key was flushed
+ * out of the cache, and so a new session should begin.
+ * Be sure and send AUTH_REJECTED{CRED, VERF} if this is the case.
+ */
+ {
+ struct timeval current;
+ int nick;
+ u_int winverf;
+
+ if (cred->adc_namekind == ADN_FULLNAME)
+ {
+ window = IXDR_GET_U_LONG (ixdr);
+ winverf = IXDR_GET_U_LONG (ixdr);
+ if (winverf != window - 1)
+ {
+ debug ("window verifier mismatch");
+ return AUTH_BADCRED; /* garbled credential */
+ }
+ sid = cache_spot (sessionkey, cred->adc_fullname.name,
+ &timestamp);
+ if (sid < 0)
+ {
+ debug ("replayed credential");
+ return AUTH_REJECTEDCRED; /* replay */
+ }
+ nick = 0;
+ }
+ else
+ { /* ADN_NICKNAME */
+ window = authdes_cache[sid].window;
+ nick = 1;
+ }
+
+ if ((u_long) timestamp.tv_usec >= USEC_PER_SEC)
+ {
+ debug ("invalid usecs");
+ /* cached out (bad key), or garbled verifier */
+ return nick ? AUTH_REJECTEDVERF : AUTH_BADVERF;
+ }
+ if (nick && BEFORE (&timestamp,
+ &authdes_cache[sid].laststamp))
+ {
+ debug ("timestamp before last seen");
+ return (AUTH_REJECTEDVERF); /* replay */
+ }
+ gettimeofday (&current, (struct timezone *) NULL);
+ current.tv_sec -= window; /* allow for expiration */
+ if (!BEFORE (&current, &timestamp))
+ {
+ debug ("timestamp expired");
+ /* replay, or garbled credential */
+ return nick ? AUTH_REJECTEDVERF : AUTH_BADCRED;
+ }
+ }
+
+ /*
+ * Set up the reply verifier
+ */
+ verf.adv_nickname = (u_long) sid;
+
+ /*
+ * xdr the timestamp before encrypting
+ */
+ ixdr = (long *) cryptbuf;
+ IXDR_PUT_LONG (ixdr, timestamp.tv_sec - 1);
+ IXDR_PUT_LONG (ixdr, timestamp.tv_usec);
+
+ /*
+ * encrypt the timestamp
+ */
+ status = ecb_crypt ((char *) sessionkey, (char *) cryptbuf,
+ sizeof (des_block), DES_ENCRYPT | DES_HW);
+ if (DES_FAILED (status))
+ {
+ debug ("encryption failure");
+ return AUTH_FAILED; /* system error */
+ }
+ verf.adv_xtimestamp = cryptbuf[0];
+
+ /*
+ * Serialize the reply verifier, and update rqst
+ */
+ ixdr = (long *) msg->rm_call.cb_verf.oa_base;
+ *ixdr++ = (long) verf.adv_xtimestamp.key.high;
+ *ixdr++ = (long) verf.adv_xtimestamp.key.low;
+ *ixdr++ = (long) verf.adv_int_u;
+
+ rqst->rq_xprt->xp_verf.oa_flavor = AUTH_DES;
+ rqst->rq_xprt->xp_verf.oa_base = msg->rm_call.cb_verf.oa_base;
+ rqst->rq_xprt->xp_verf.oa_length =
+ (char *) ixdr - msg->rm_call.cb_verf.oa_base;
+
+ /*
+ * We succeeded, commit the data to the cache now and
+ * finish cooking the credential.
+ */
+ entry = &authdes_cache[sid];
+ entry->laststamp = timestamp;
+ cache_ref (sid);
+ if (cred->adc_namekind == ADN_FULLNAME)
+ {
+ cred->adc_fullname.window = window;
+ cred->adc_nickname = (u_long) sid; /* save nickname */
+ if (entry->rname != NULL)
+ {
+ mem_free (entry->rname, strlen (entry->rname) + 1);
+ }
+ entry->rname = mem_alloc ((u_int) strlen (cred->adc_fullname.name)
+ + 1);
+ if (entry->rname != NULL)
+ {
+ strcpy (entry->rname, cred->adc_fullname.name);
+ }
+ else
+ {
+ debug ("out of memory");
+ }
+ entry->key = *sessionkey;
+ entry->window = window;
+ invalidate (entry->localcred); /* mark any cached cred invalid */
+ }
+ else
+ { /* ADN_NICKNAME */
+ /*
+ * nicknames are cooked into fullnames
+ */
+ cred->adc_namekind = ADN_FULLNAME;
+ cred->adc_fullname.name = entry->rname;
+ cred->adc_fullname.key = entry->key;
+ cred->adc_fullname.window = entry->window;
+ }
+ return AUTH_OK; /* we made it! */
+}
+
+
+/*
+ * Initialize the cache
+ */
+static void
+cache_init (void)
+{
+ register int i;
+
+ authdes_cache = (struct cache_entry *)
+ mem_alloc (sizeof (struct cache_entry) * AUTHDES_CACHESZ);
+ bzero ((char *) authdes_cache,
+ sizeof (struct cache_entry) * AUTHDES_CACHESZ);
+
+ authdes_lru = (short *) mem_alloc (sizeof (short) * AUTHDES_CACHESZ);
+ /*
+ * Initialize the lru list
+ */
+ for (i = 0; i < AUTHDES_CACHESZ; i++)
+ {
+ authdes_lru[i] = i;
+ }
+}
+
+
+/*
+ * Find the lru victim
+ */
+static short
+cache_victim (void)
+{
+ return (authdes_lru[AUTHDES_CACHESZ - 1]);
+}
+
+/*
+ * Note that sid was referenced
+ */
+static void
+cache_ref (register short sid)
+{
+ register int i;
+ register short curr;
+ register short prev;
+
+ prev = authdes_lru[0];
+ authdes_lru[0] = sid;
+ for (i = 1; prev != sid; i++)
+ {
+ curr = authdes_lru[i];
+ authdes_lru[i] = prev;
+ prev = curr;
+ }
+}
+
+
+/*
+ * Find a spot in the cache for a credential containing
+ * the items given. Return -1 if a replay is detected, otherwise
+ * return the spot in the cache.
+ */
+static short
+cache_spot (register des_block * key, char *name, struct timeval *timestamp)
+{
+ register struct cache_entry *cp;
+ register int i;
+ register u_long hi;
+
+ hi = key->key.high;
+ for (cp = authdes_cache, i = 0; i < AUTHDES_CACHESZ; i++, cp++)
+ {
+ if (cp->key.key.high == hi &&
+ cp->key.key.low == key->key.low &&
+ cp->rname != NULL &&
+ bcmp (cp->rname, name, strlen (name) + 1) == 0)
+ {
+ if (BEFORE (timestamp, &cp->laststamp))
+ {
+ svcauthdes_stats.ncachereplays++;
+ return -1; /* replay */
+ }
+ svcauthdes_stats.ncachehits++;
+ return i; /* refresh */
+ }
+ }
+ svcauthdes_stats.ncachemisses++;
+ return cache_victim (); /* new credential */
+}
+
+
+/*
+ * Local credential handling stuff.
+ * NOTE: bsd unix dependent.
+ * Other operating systems should put something else here.
+ */
+#define UNKNOWN -2 /* grouplen, if cached cred is unknown user */
+#define INVALID -1 /* grouplen, if cache entry is invalid */
+
+struct bsdcred
+{
+ uid_t uid; /* cached uid */
+ gid_t gid; /* cached gid */
+ short grouplen; /* length of cached groups */
+ gid_t groups[NGROUPS]; /* cached groups */
+};
+
+/*
+ * Map a des credential into a unix cred.
+ * We cache the credential here so the application does
+ * not have to make an rpc call every time to interpret
+ * the credential.
+ */
+int
+authdes_getucred (const struct authdes_cred *adc, uid_t * uid, gid_t * gid,
+ short *grouplen, gid_t * groups)
+{
+ unsigned sid;
+ register int i;
+ uid_t i_uid;
+ gid_t i_gid;
+ int i_grouplen;
+ struct bsdcred *cred;
+
+ sid = adc->adc_nickname;
+ if (sid >= AUTHDES_CACHESZ)
+ {
+ debug ("invalid nickname");
+ return 0;
+ }
+ cred = (struct bsdcred *) authdes_cache[sid].localcred;
+ if (cred == NULL)
+ {
+ cred = (struct bsdcred *) mem_alloc (sizeof (struct bsdcred));
+ authdes_cache[sid].localcred = (char *) cred;
+ cred->grouplen = INVALID;
+ }
+ if (cred->grouplen == INVALID)
+ {
+ /*
+ * not in cache: lookup
+ */
+ if (!netname2user (adc->adc_fullname.name, &i_uid, &i_gid,
+ &i_grouplen, groups))
+ {
+ debug ("unknown netname");
+ cred->grouplen = UNKNOWN; /* mark as lookup up, but not found */
+ return 0;
+ }
+ debug ("missed ucred cache");
+ *uid = cred->uid = i_uid;
+ *gid = cred->gid = i_gid;
+ *grouplen = cred->grouplen = i_grouplen;
+ for (i = i_grouplen - 1; i >= 0; i--)
+ {
+ cred->groups[i] = groups[i]; /* int to short */
+ }
+ return 1;
+ }
+ else if (cred->grouplen == UNKNOWN)
+ {
+ /*
+ * Already lookup up, but no match found
+ */
+ return 0;
+ }
+
+ /*
+ * cached credentials
+ */
+ *uid = cred->uid;
+ *gid = cred->gid;
+ *grouplen = cred->grouplen;
+ for (i = cred->grouplen - 1; i >= 0; i--)
+ {
+ groups[i] = cred->groups[i]; /* short to int */
+ }
+ return 1;
+}
+
+static void
+invalidate (char *cred)
+{
+ if (cred == NULL)
+ {
+ return;
+ }
+ ((struct bsdcred *) cred)->grouplen = INVALID;
+}
diff --git a/sunrpc/xcrypt.c b/sunrpc/xcrypt.c
new file mode 100644
index 0000000000..97c30d149f
--- /dev/null
+++ b/sunrpc/xcrypt.c
@@ -0,0 +1,180 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * Copyright (c) 1986-1991 by Sun Microsystems Inc.
+ */
+
+#ident "@(#)xcrypt.c 1.11 94/08/23 SMI"
+
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)xcrypt.c 1.3 89/03/24 Copyr 1986 Sun Micro";
+#endif
+
+/*
+ * xcrypt.c: Hex encryption/decryption and utility routines
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <rpc/des_crypt.h>
+
+static char hex[16] =
+{
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
+};
+
+static char hexval (char);
+static void hex2bin (int, char *, char *);
+static void bin2hex (int, unsigned char *, char *);
+void passwd2des (char *pw, char *key);
+
+/*
+ * Encrypt a secret key given passwd
+ * The secret key is passed and returned in hex notation.
+ * Its length must be a multiple of 16 hex digits (64 bits).
+ */
+int
+xencrypt (char *secret, char *passwd)
+{
+ char key[8];
+ char ivec[8];
+ char *buf;
+ int err;
+ int len;
+
+ len = strlen (secret) / 2;
+ buf = malloc ((unsigned) len);
+ hex2bin (len, secret, buf);
+ passwd2des (passwd, key);
+ memset (ivec, 0, 8);
+
+ err = cbc_crypt (key, buf, len, DES_ENCRYPT | DES_HW, ivec);
+ if (DES_FAILED (err))
+ {
+ free (buf);
+ return 0;
+ }
+ bin2hex (len, (unsigned char *) buf, secret);
+ free (buf);
+ return 1;
+}
+
+/*
+ * Decrypt secret key using passwd
+ * The secret key is passed and returned in hex notation.
+ * Once again, the length is a multiple of 16 hex digits
+ */
+int
+xdecrypt (char *secret, char *passwd)
+{
+ char key[8];
+ char ivec[8];
+ char *buf;
+ int err;
+ int len;
+
+ len = strlen (secret) / 2;
+ buf = malloc ((unsigned) len);
+
+ hex2bin (len, secret, buf);
+ passwd2des (passwd, key);
+ memset (ivec, 0, 8);
+
+ err = cbc_crypt (key, buf, len, DES_DECRYPT | DES_HW, ivec);
+ if (DES_FAILED (err))
+ {
+ free (buf);
+ return 0;
+ }
+ bin2hex (len, (unsigned char *) buf, secret);
+ free (buf);
+ return 1;
+}
+
+/*
+ * Turn password into DES key
+ */
+void
+passwd2des (char *pw, char *key)
+{
+ int i;
+
+ memset (key, 0, 8);
+ for (i = 0; *pw; i = (i + 1) % 8)
+ key[i] ^= *pw++ << 1;
+
+ des_setparity (key);
+}
+
+/*
+ * Hex to binary conversion
+ */
+static void
+hex2bin (int len, char *hexnum, char *binnum)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ *binnum++ = 16 * hexval (hexnum[2 * i]) + hexval (hexnum[2 * i + 1]);
+}
+
+/*
+ * Binary to hex conversion
+ */
+static void
+bin2hex (int len, unsigned char *binnum, char *hexnum)
+{
+ int i;
+ unsigned val;
+
+ for (i = 0; i < len; i++)
+ {
+ val = binnum[i];
+ hexnum[i * 2] = hex[val >> 4];
+ hexnum[i * 2 + 1] = hex[val & 0xf];
+ }
+ hexnum[len * 2] = 0;
+}
+
+static char
+hexval (char c)
+{
+ if (c >= '0' && c <= '9')
+ return (c - '0');
+ else if (c >= 'a' && c <= 'z')
+ return (c - 'a' + 10);
+ else if (c >= 'A' && c <= 'Z')
+ return (c - 'A' + 10);
+ else
+ return -1;
+}