summaryrefslogtreecommitdiff
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
parent39e16978c3b4ac8eaf2201fac56316623910d9da (diff)
downloadglibc-800d775e426b9c0af63f711b79b09bf540c97456.tar.gz
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>.
-rw-r--r--ChangeLog66
-rw-r--r--db2/Makefile22
-rw-r--r--md5-crypt/Makefile5
-rw-r--r--nis/nis_server.c81
-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.h (renamed from sysdeps/generic/rpc/auth.h)35
-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.c (renamed from sysdeps/generic/svc_auth.c)8
-rw-r--r--sunrpc/svcauth_des.c548
-rw-r--r--sunrpc/xcrypt.c180
-rw-r--r--sysdeps/generic/rpc/auth_des.h46
-rw-r--r--sysdeps/mach/hurd/Dist9
-rw-r--r--sysdeps/mach/hurd/mips/Dist3
-rw-r--r--sysdeps/powerpc/Dist2
-rw-r--r--sysdeps/powerpc/add_n.s68
-rw-r--r--sysdeps/powerpc/addmul_1.s50
-rw-r--r--sysdeps/powerpc/lshift.s479
-rw-r--r--sysdeps/powerpc/memset.s202
-rw-r--r--sysdeps/powerpc/mul_1.s47
-rw-r--r--sysdeps/powerpc/rshift.s59
-rw-r--r--sysdeps/powerpc/strchr.s118
-rw-r--r--sysdeps/powerpc/strcmp.s273
-rw-r--r--sysdeps/powerpc/sub_n.s69
-rw-r--r--sysdeps/powerpc/submul_1.s52
-rw-r--r--sysdeps/sparc/Dist1
-rw-r--r--sysdeps/sparc/sparc32/Dist1
-rw-r--r--sysdeps/sparc/sparc32/sparcv8/Dist6
-rw-r--r--sysdeps/stub/des_impl.c27
-rw-r--r--sysdeps/unix/sysv/linux/mips/Dist1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/Dist1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/Dist1
44 files changed, 4968 insertions, 127 deletions
diff --git a/ChangeLog b/ChangeLog
index 86a662f7ff..b7d78e243e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,67 @@
+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.
+
1997-08-29 02:36 Ulrich Drepper <drepper@cygnus.com>
* Makefile (version-info.h): Use ISO form for the date.
@@ -35,7 +99,7 @@
1997-08-28 17:30 Ulrich Drepper <drepper@cygnus.com>
* catgets/catgets.c (catopen): Correctly determine length of string
- in NLSPATH evironment variable. Patch by HJ Lu <hjl@gnu.ai.mit.edu>.
+ in NLSPATH environment variable. Patch by HJ Lu <hjl@gnu.ai.mit.edu>.
1997-08-27 23:19 Richard Henderson <rth@cygnus.com>
diff --git a/db2/Makefile b/db2/Makefile
index 24d74cc3d8..a7521b6580 100644
--- a/db2/Makefile
+++ b/db2/Makefile
@@ -30,6 +30,24 @@ subdir-dirs = btree common db db185 dbm hash lock log mp mutex os txn \
progs/db_dump progs/db_dump185 progs/db_load progs/db_printlog \
progs/db_recover progs/db_stat clib
+headers = db.h db_185.h
+
+distribute = db_int.h config.h compat.h clib/getlong.c btree/btree.src \
+ db/db.src db185/db185_int.src hash/hash.src log/log.src \
+ txn/txn.src \
+ $(addprefix include/,btree.h btree_auto.h btree_ext.h \
+ clib_ext.h common_ext.h cxx_int.h \
+ db.h.src db_185.h.src db_am.h db_auto.h \
+ db_cxx.h db_dispatch.h db_ext.h \
+ db_int.h.src db_page.h db_shash.h db_swap.h \
+ hash.h hash_auto.h hash_ext.h lock.h \
+ lock_ext.h log.h log_auto.h log_ext.h \
+ mp.h mp_ext.h mutex_ext.h os_ext.h queue.h \
+ shqueue.h txn.h txn_auto.h txn_ext.h) \
+ $(addprefix mutex/,x86.gcc uts4.cc.s sparc.gcc parisc.hp \
+ parisc.gcc alpha.gcc alpha.dec README \
+ 68020.gcc)
+
vpath %.c $(subdir-dirs)
extra-libs := libdb
@@ -52,9 +70,9 @@ libdb-routines := bt_close bt_compare bt_conv bt_cursor bt_delete \
txn_rec dbm db185
others := makedb db_dump185 db_archive db_checkpoint db_deadlock \
- db_dump db_load db_recover db_stat
+ db_dump db_load db_recover db_stat db_printlog
install-bin := makedb db_dump185 db_archive db_checkpoint db_deadlock \
- db_dump db_load db_recover db_stat
+ db_dump db_load db_recover db_stat db_printlog
include ../Rules
diff --git a/md5-crypt/Makefile b/md5-crypt/Makefile
index b52e1ef012..ab054ce8a6 100644
--- a/md5-crypt/Makefile
+++ b/md5-crypt/Makefile
@@ -63,6 +63,11 @@ libmd5crypt: $(foreach o,$(object-suffixes), \
$(addprefix $(objpfx),$(patsubst %,$(libtype$o),md5crypt)))
ifeq ($(build-shared),yes)
libmd5crypt: $(objpfx)libmd5crypt.so
+# Use the same soname as the real libcrypt, so that it can be used as a
+# drop in replacement.
+LDFLAGS-md5crypt.so = -Wl,-soname=lib$(libprefix)crypt.so$(libcrypt.so-version)
+# We also use the same version script.
+libmd5crypt-map := libcrypt.map
endif
define o-iterator-doit
diff --git a/nis/nis_server.c b/nis/nis_server.c
index 5274a3bfc4..0df608a153 100644
--- a/nis/nis_server.c
+++ b/nis/nis_server.c
@@ -19,7 +19,6 @@
#include <string.h>
#include <rpcsvc/nis.h>
-#include <rpcsvc/nislib.h>
#include "nis_intern.h"
nis_error
@@ -29,42 +28,21 @@ nis_servstate (const nis_server *serv, const nis_tag *tags,
nis_taglist taglist;
nis_taglist tagres;
+ *result = 0;
tagres.tags.tags_len = 0;
tagres.tags.tags_val = NULL;
- *result = NULL;
taglist.tags.tags_len = numtags;
taglist.tags.tags_val = (nis_tag *) tags;
if (serv == NULL)
- {
- if (__do_niscall (NULL, NIS_SERVSTATE, (xdrproc_t) xdr_nis_taglist,
- (caddr_t) &taglist, (xdrproc_t) xdr_nis_taglist,
- (caddr_t) &tagres, 0) != RPC_SUCCESS)
- return NIS_RPCERROR;
- }
- else
- {
- if (__do_niscall2 (serv, 1, NIS_SERVSTATE, (xdrproc_t) xdr_nis_taglist,
- (caddr_t) &taglist, (xdrproc_t) xdr_nis_taglist,
- (caddr_t) &tagres, 0) != RPC_SUCCESS)
- return NIS_RPCERROR;
- }
- if (tagres.tags.tags_len > 0)
- {
- u_long i;
-
- result = malloc (sizeof (nis_tag *) * tagres.tags.tags_len);
- if (result == NULL)
- return NIS_NOMEMORY;
- for (i = 0; i < tagres.tags.tags_len; ++i)
- {
- result[i] = malloc (sizeof (nis_tag));
- if (result[i] == NULL)
- return NIS_NOMEMORY;
- result[i]->tag_val = strdup (tagres.tags.tags_val[i].tag_val);
- result[i]->tag_type = tagres.tags.tags_val[i].tag_type;
- }
- }
+ return NIS_BADOBJECT;
+
+ if (__do_niscall2 (serv, 1, NIS_SERVSTATE, (xdrproc_t) xdr_nis_taglist,
+ (caddr_t) &taglist, (xdrproc_t) xdr_nis_taglist,
+ (caddr_t) &tagres, 0) != RPC_SUCCESS)
+ return NIS_RPCERROR;
+
+ *result = tagres.tags.tags_val;
return NIS_SUCCESS;
}
@@ -76,42 +54,21 @@ nis_stats (const nis_server *serv, const nis_tag *tags,
nis_taglist taglist;
nis_taglist tagres;
+ *result = NULL;
tagres.tags.tags_len = 0;
tagres.tags.tags_val = NULL;
- *result = NULL;
taglist.tags.tags_len = numtags;
taglist.tags.tags_val = (nis_tag *) tags;
if (serv == NULL)
- {
- if (__do_niscall (NULL, NIS_STATUS, (xdrproc_t) xdr_nis_taglist,
- (caddr_t) &taglist, (xdrproc_t) xdr_nis_taglist,
- (caddr_t) &tagres, 0) != RPC_SUCCESS)
- return NIS_RPCERROR;
- }
- else
- {
- if (__do_niscall2 (serv, 1, NIS_STATUS, (xdrproc_t) xdr_nis_taglist,
- (caddr_t) &taglist, (xdrproc_t) xdr_nis_taglist,
- (caddr_t) &tagres, 0) != RPC_SUCCESS)
- return NIS_RPCERROR;
- }
- if (tagres.tags.tags_len > 0)
- {
- u_long i;
-
- result = malloc (sizeof (nis_tag *) * tagres.tags.tags_len);
- if (result == NULL)
- return NIS_NOMEMORY;
- for (i = 0; i < tagres.tags.tags_len; ++i)
- {
- result[i] = malloc (sizeof (nis_tag));
- if (result[i] == NULL)
- return NIS_NOMEMORY;
- result[i]->tag_val = strdup (tagres.tags.tags_val[i].tag_val);
- result[i]->tag_type = tagres.tags.tags_val[i].tag_type;
- }
- }
+ return NIS_BADOBJECT;
+
+ if (__do_niscall2 (serv, 1, NIS_STATUS, (xdrproc_t) xdr_nis_taglist,
+ (caddr_t) &taglist, (xdrproc_t) xdr_nis_taglist,
+ (caddr_t) &tagres, 0) != RPC_SUCCESS)
+ return NIS_RPCERROR;
+
+ *result = tagres.tags.tags_val;
return NIS_SUCCESS;
}
@@ -122,6 +79,6 @@ nis_freetags (nis_tag *tags, const int numtags)
int i;
for (i = 0; i < numtags; ++i)
- free (tags->tag_val);
+ free (tags[i].tag_val);
free (tags);
}
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/sysdeps/generic/rpc/auth.h b/sunrpc/rpc/auth.h
index b4022853d5..22174193d4 100644
--- a/sysdeps/generic/rpc/auth.h
+++ b/sunrpc/rpc/auth.h
@@ -42,8 +42,6 @@
#define _RPC_AUTH_H 1
#include <features.h>
-#include <sys/types.h>
-#include <rpc/types.h>
#include <rpc/xdr.h>
__BEGIN_DECLS
@@ -101,7 +99,7 @@ struct AUTH {
struct auth_ops {
void (*ah_nextverf) __P ((AUTH *));
int (*ah_marshal) __P ((AUTH *, XDR *)); /* nextverf & serialize */
- int (*ah_validate) __P ((AUTH *, struct opaque_auth *));
+ 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 */
@@ -165,7 +163,7 @@ extern AUTH *authunix_create __P ((char *__machname, __uid_t __uid,
__gid_t *__aup_gids));
extern AUTH *authunix_create_default __P ((void));
extern AUTH *authnone_create __P ((void));
-extern AUTH *authdes_create __P ((char *__servername, u_int __window,
+extern AUTH *authdes_create __P ((const char *__servername, u_int __window,
struct sockaddr *__syncaddr,
des_block *__ckey));
@@ -178,10 +176,35 @@ extern AUTH *authdes_create __P ((char *__servername, u_int __window,
#define AUTH_KERB 4 /* kerberos style */
/*
- * XDR an opaque authentication struct.
+ * Netname manipulating functions
+ *
*/
-extern bool_t xdr_opaque_auth __P ((XDR *__xdrs, struct opaque_auth *__ap));
+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/sysdeps/generic/svc_auth.c b/sunrpc/svc_auth.c
index 9f7ed5eca6..f0aebd5358 100644
--- a/sysdeps/generic/svc_auth.c
+++ b/sunrpc/svc_auth.c
@@ -33,7 +33,6 @@ static char sccsid[] = "@(#)svc_auth.c 1.19 87/08/11 Copyr 1984 Sun Micro";
/*
* svc_auth.c, Server-side rpc authenticator interface.
- * *WITHOUT* DES authentication.
*
* Copyright (C) 1984, Sun Microsystems, Inc.
*/
@@ -63,6 +62,8 @@ 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
{
@@ -72,9 +73,10 @@ svcauthsw[] =
{
{ _svcauth_null }, /* AUTH_NULL */
{ _svcauth_unix }, /* AUTH_UNIX */
- { _svcauth_short } /* AUTH_SHORT */
+ { _svcauth_short }, /* AUTH_SHORT */
+ { _svcauth_des } /* AUTH_DES */
};
-#define AUTH_MAX 2 /* HIGHEST AUTH NUMBER */
+#define AUTH_MAX 3 /* HIGHEST AUTH NUMBER */
/*
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;
+}
diff --git a/sysdeps/generic/rpc/auth_des.h b/sysdeps/generic/rpc/auth_des.h
deleted file mode 100644
index 8c2f794691..0000000000
--- a/sysdeps/generic/rpc/auth_des.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* 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
-
-/* This is no complete version of this header. More definitions with
- the real authentication stuff will come in 1997. For now we only
- need to define the function for handling public keys. */
-
-
-/* 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));
-
-__END_DECLS
-
-#endif /* rpc/auth_des.h */
diff --git a/sysdeps/mach/hurd/Dist b/sysdeps/mach/hurd/Dist
index e6067b8a73..084c314649 100644
--- a/sysdeps/mach/hurd/Dist
+++ b/sysdeps/mach/hurd/Dist
@@ -1,4 +1,11 @@
-errnos.awk err_hurd.sub
+errnos.awk
+err_hurd.sub
libc-ldscript
libc_p-ldscript
cthreads.c
+net/ethernet.h
+net/if.h
+net/if_arp.h
+net/if_ether.h
+net/if_ppp.h
+net/route.h
diff --git a/sysdeps/mach/hurd/mips/Dist b/sysdeps/mach/hurd/mips/Dist
new file mode 100644
index 0000000000..b6f3ffa4c3
--- /dev/null
+++ b/sysdeps/mach/hurd/mips/Dist
@@ -0,0 +1,3 @@
+longjmp-ctx.c
+init-fault.c
+dl-machine.c
diff --git a/sysdeps/powerpc/Dist b/sysdeps/powerpc/Dist
index 282cf1394e..a3de7b3c96 100644
--- a/sysdeps/powerpc/Dist
+++ b/sysdeps/powerpc/Dist
@@ -1,3 +1,5 @@
fenv_const.c
fenv_libc.h
quad_float.h
+fe_nomask.c
+t_sqrt.c
diff --git a/sysdeps/powerpc/add_n.s b/sysdeps/powerpc/add_n.s
new file mode 100644
index 0000000000..609f0a502a
--- /dev/null
+++ b/sysdeps/powerpc/add_n.s
@@ -0,0 +1,68 @@
+ # Add two limb vectors of equal, non-zero length for PowerPC.
+ # Copyright (C) 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.
+
+ # mp_limb_t mpn_add_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr,
+ # mp_size_t size)
+ # Calculate s1+s2 and put result in res_ptr; return carry, 0 or 1.
+
+ # Note on optimisation: This code is optimal for the 601. Almost every other
+ # possible 2-unrolled inner loop will not be. Also, watch out for the
+ # alignment...
+
+ .align 3
+ .globl __mpn_add_n
+ .type __mpn_add_n,@function
+__mpn_add_n:
+ # Set up for loop below.
+ mtcrf 0x01,%r6
+ srwi. %r7,%r6,1
+ li %r10,0
+ mtctr %r7
+ bt 31,2f
+
+ # Clear the carry.
+ addic %r0,%r0,0
+ # Adjust pointers for loop.
+ addi %r3,%r3,-4
+ addi %r4,%r4,-4
+ addi %r5,%r5,-4
+ b 0f
+
+2: lwz %r7,0(%r5)
+ lwz %r6,0(%r4)
+ addc %r6,%r6,%r7
+ stw %r6,0(%r3)
+ beq 1f
+
+ # The loop.
+
+ # Align start of loop to an odd word boundary to guarantee that the
+ # last two words can be fetched in one access (for 601).
+0: lwz %r9,4(%r4)
+ lwz %r8,4(%r5)
+ lwzu %r6,8(%r4)
+ lwzu %r7,8(%r5)
+ adde %r8,%r9,%r8
+ stw %r8,4(%r3)
+ adde %r6,%r6,%r7
+ stwu %r6,8(%r3)
+ bdnz 0b
+ # return the carry
+1: addze %r3,%r10
+ blr
diff --git a/sysdeps/powerpc/addmul_1.s b/sysdeps/powerpc/addmul_1.s
new file mode 100644
index 0000000000..cf8fd2a555
--- /dev/null
+++ b/sysdeps/powerpc/addmul_1.s
@@ -0,0 +1,50 @@
+ # Multiply a limb vector by a single limb, for PowerPC.
+ # Copyright (C) 1993, 1994, 1995, 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.
+
+ # mp_limb_t mpn_addmul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
+ # mp_size_t s1_size, mp_limb_t s2_limb)
+ # Calculate res+s1*s2 and put result back in res; return carry.
+
+ .align 2
+ .globl __mpn_addmul_1
+ .type __mpn_addmul_1,@function
+__mpn_addmul_1:
+ mtctr %r5
+
+ lwz %r0,0(%r4)
+ mullw %r7,%r0,%r6
+ mulhwu %r10,%r0,%r6
+ lwz %r9,0(%r3)
+ addc %r8,%r7,%r9
+ addi %r3,%r3,-4 # adjust res_ptr
+ bdz Lend
+
+Loop: lwzu %r0,4(%r4)
+ stwu %r8,4(%r3)
+ mullw %r8,%r0,%r6
+ adde %r7,%r8,%r10
+ mulhwu %r10,%r0,%r6
+ lwz %r9,4(%r3)
+ addze %r10,%r10
+ addc %r8,%r7,%r9
+ bdnz Loop
+
+Lend: stw %r8,4(%r3)
+ addze %r3,%r10
+ blr
diff --git a/sysdeps/powerpc/lshift.s b/sysdeps/powerpc/lshift.s
new file mode 100644
index 0000000000..9612a3dbec
--- /dev/null
+++ b/sysdeps/powerpc/lshift.s
@@ -0,0 +1,479 @@
+ # Shift a limb left, low level routine.
+ # 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.
+
+ # mp_limb_t mpn_lshift (mp_ptr wp, mp_srcptr up, mp_size_t usize,
+ # unsigned int cnt)
+
+ .align 3
+ .globl __mpn_lshift
+ .type __mpn_lshift,@function
+__mpn_lshift:
+ mtctr %r5 # copy size into CTR
+ cmplwi %cr0,%r5,16 # is size < 16
+ slwi %r0,%r5,2
+ add %r7,%r3,%r0 # make r7 point at end of res
+ add %r4,%r4,%r0 # make r4 point at end of s1
+ lwzu %r11,-4(%r4) # load first s1 limb
+ subfic %r8,%r6,32
+ srw %r3,%r11,%r8 # compute function return value
+ bge %cr0,Lbig # branch if size >= 16
+
+ bdz Lend1
+
+Loop: lwzu %r10,-4(%r4)
+ slw %r9,%r11,%r6
+ srw %r12,%r10,%r8
+ or %r9,%r9,%r12
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slw %r9,%r10,%r6
+ srw %r12,%r11,%r8
+ or %r9,%r9,%r12
+ stwu %r9,-4(%r7)
+ bdnz Loop
+ b Lend1
+
+ # Guaranteed not to succeed.
+LBoom: tweq %r0,%r0
+
+ # We imitate a case statement, by using (yuk!) fixed-length code chunks,
+ # of size 4*12 bytes. We have to do this (or something) to make this PIC.
+Lbig: mflr %r9
+ bltl %cr0,LBoom # Never taken, only used to set LR.
+ slwi %r10,%r6,4
+ mflr %r12
+ add %r10,%r12,%r10
+ slwi %r8,%r6,5
+ add %r10,%r8,%r10
+ mtctr %r10
+ addi %r5,%r5,-1
+ mtlr %r9
+ bctr
+
+Lend1: slw %r0,%r11,%r6
+ stw %r0,-4(%r7)
+ blr
+
+ mtctr %r5
+Loop1: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,1
+ inslwi %r9,%r10,1,31
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,1
+ inslwi %r9,%r11,1,31
+ stwu %r9,-4(%r7)
+ bdnz Loop1
+ b Lend1
+
+ mtctr %r5
+Loop2: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,2
+ inslwi %r9,%r10,2,30
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,2
+ inslwi %r9,%r11,2,30
+ stwu %r9,-4(%r7)
+ bdnz Loop2
+ b Lend1
+
+ mtctr %r5
+Loop3: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,3
+ inslwi %r9,%r10,3,29
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,3
+ inslwi %r9,%r11,3,29
+ stwu %r9,-4(%r7)
+ bdnz Loop3
+ b Lend1
+
+ mtctr %r5
+Loop4: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,4
+ inslwi %r9,%r10,4,28
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,4
+ inslwi %r9,%r11,4,28
+ stwu %r9,-4(%r7)
+ bdnz Loop4
+ b Lend1
+
+ mtctr %r5
+Loop5: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,5
+ inslwi %r9,%r10,5,27
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,5
+ inslwi %r9,%r11,5,27
+ stwu %r9,-4(%r7)
+ bdnz Loop5
+ b Lend1
+
+ mtctr %r5
+Loop6: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,6
+ inslwi %r9,%r10,6,26
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,6
+ inslwi %r9,%r11,6,26
+ stwu %r9,-4(%r7)
+ bdnz Loop6
+ b Lend1
+
+ mtctr %r5
+Loop7: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,7
+ inslwi %r9,%r10,7,25
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,7
+ inslwi %r9,%r11,7,25
+ stwu %r9,-4(%r7)
+ bdnz Loop7
+ b Lend1
+
+ mtctr %r5
+Loop8: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,8
+ inslwi %r9,%r10,8,24
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,8
+ inslwi %r9,%r11,8,24
+ stwu %r9,-4(%r7)
+ bdnz Loop8
+ b Lend1
+
+ mtctr %r5
+Loop9: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,9
+ inslwi %r9,%r10,9,23
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,9
+ inslwi %r9,%r11,9,23
+ stwu %r9,-4(%r7)
+ bdnz Loop9
+ b Lend1
+
+ mtctr %r5
+Loop10: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,10
+ inslwi %r9,%r10,10,22
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,10
+ inslwi %r9,%r11,10,22
+ stwu %r9,-4(%r7)
+ bdnz Loop10
+ b Lend1
+
+ mtctr %r5
+Loop11: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,11
+ inslwi %r9,%r10,11,21
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,11
+ inslwi %r9,%r11,11,21
+ stwu %r9,-4(%r7)
+ bdnz Loop11
+ b Lend1
+
+ mtctr %r5
+Loop12: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,12
+ inslwi %r9,%r10,12,20
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,12
+ inslwi %r9,%r11,12,20
+ stwu %r9,-4(%r7)
+ bdnz Loop12
+ b Lend1
+
+ mtctr %r5
+Loop13: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,13
+ inslwi %r9,%r10,13,19
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,13
+ inslwi %r9,%r11,13,19
+ stwu %r9,-4(%r7)
+ bdnz Loop13
+ b Lend1
+
+ mtctr %r5
+Loop14: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,14
+ inslwi %r9,%r10,14,18
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,14
+ inslwi %r9,%r11,14,18
+ stwu %r9,-4(%r7)
+ bdnz Loop14
+ b Lend1
+
+ mtctr %r5
+Loop15: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,15
+ inslwi %r9,%r10,15,17
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,15
+ inslwi %r9,%r11,15,17
+ stwu %r9,-4(%r7)
+ bdnz Loop15
+ b Lend1
+
+ mtctr %r5
+Loop16: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,16
+ inslwi %r9,%r10,16,16
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,16
+ inslwi %r9,%r11,16,16
+ stwu %r9,-4(%r7)
+ bdnz Loop16
+ b Lend1
+
+ mtctr %r5
+Loop17: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,17
+ inslwi %r9,%r10,17,15
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,17
+ inslwi %r9,%r11,17,15
+ stwu %r9,-4(%r7)
+ bdnz Loop17
+ b Lend1
+
+ mtctr %r5
+Loop18: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,18
+ inslwi %r9,%r10,18,14
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,18
+ inslwi %r9,%r11,18,14
+ stwu %r9,-4(%r7)
+ bdnz Loop18
+ b Lend1
+
+ mtctr %r5
+Loop19: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,19
+ inslwi %r9,%r10,19,13
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,19
+ inslwi %r9,%r11,19,13
+ stwu %r9,-4(%r7)
+ bdnz Loop19
+ b Lend1
+
+ mtctr %r5
+Loop20: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,20
+ inslwi %r9,%r10,20,12
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,20
+ inslwi %r9,%r11,20,12
+ stwu %r9,-4(%r7)
+ bdnz Loop20
+ b Lend1
+
+ mtctr %r5
+Loop21: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,21
+ inslwi %r9,%r10,21,11
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,21
+ inslwi %r9,%r11,21,11
+ stwu %r9,-4(%r7)
+ bdnz Loop21
+ b Lend1
+
+ mtctr %r5
+Loop22: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,22
+ inslwi %r9,%r10,22,10
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,22
+ inslwi %r9,%r11,22,10
+ stwu %r9,-4(%r7)
+ bdnz Loop22
+ b Lend1
+
+ mtctr %r5
+Loop23: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,23
+ inslwi %r9,%r10,23,9
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,23
+ inslwi %r9,%r11,23,9
+ stwu %r9,-4(%r7)
+ bdnz Loop23
+ b Lend1
+
+ mtctr %r5
+Loop24: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,24
+ inslwi %r9,%r10,24,8
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,24
+ inslwi %r9,%r11,24,8
+ stwu %r9,-4(%r7)
+ bdnz Loop24
+ b Lend1
+
+ mtctr %r5
+Loop25: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,25
+ inslwi %r9,%r10,25,7
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,25
+ inslwi %r9,%r11,25,7
+ stwu %r9,-4(%r7)
+ bdnz Loop25
+ b Lend1
+
+ mtctr %r5
+Loop26: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,26
+ inslwi %r9,%r10,26,6
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,26
+ inslwi %r9,%r11,26,6
+ stwu %r9,-4(%r7)
+ bdnz Loop26
+ b Lend1
+
+ mtctr %r5
+Loop27: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,27
+ inslwi %r9,%r10,27,5
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,27
+ inslwi %r9,%r11,27,5
+ stwu %r9,-4(%r7)
+ bdnz Loop27
+ b Lend1
+
+ mtctr %r5
+Loop28: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,28
+ inslwi %r9,%r10,28,4
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,28
+ inslwi %r9,%r11,28,4
+ stwu %r9,-4(%r7)
+ bdnz Loop28
+ b Lend1
+
+ mtctr %r5
+Loop29: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,29
+ inslwi %r9,%r10,29,3
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,29
+ inslwi %r9,%r11,29,3
+ stwu %r9,-4(%r7)
+ bdnz Loop29
+ b Lend1
+
+ mtctr %r5
+Loop30: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,30
+ inslwi %r9,%r10,30,2
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,30
+ inslwi %r9,%r11,30,2
+ stwu %r9,-4(%r7)
+ bdnz Loop30
+ b Lend1
+
+ mtctr %r5
+Loop31: lwzu %r10,-4(%r4)
+ slwi %r9,%r11,31
+ inslwi %r9,%r10,31,1
+ stwu %r9,-4(%r7)
+ bdz Lend2
+ lwzu %r11,-4(%r4)
+ slwi %r9,%r10,31
+ inslwi %r9,%r11,31,1
+ stwu %r9,-4(%r7)
+ bdnz Loop31
+ b Lend1
+
+Lend2: slw %r0,%r10,%r6
+ stw %r0,-4(%r7)
+ blr
diff --git a/sysdeps/powerpc/memset.s b/sysdeps/powerpc/memset.s
new file mode 100644
index 0000000000..4c8bf8c6b4
--- /dev/null
+++ b/sysdeps/powerpc/memset.s
@@ -0,0 +1,202 @@
+ # Optimized memset implementation for PowerPC.
+ # Copyright (C) 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.
+
+ .section ".text"
+ .align 5
+ nop
+
+ .globl memset
+ .type memset,@function
+memset:
+ # __ptr_t [r3] memset (__ptr_t s [r3], int c [r4], size_t n [r5]));
+ # Returns 's'.
+
+ # The memset is done in three sizes: byte (8 bits), word (32 bits),
+ # cache line (256 bits). There is a special case for setting cache lines
+ # to 0, to take advantage of the dcbz instruction.
+ # r6: current address we are storing at
+ # r7: number of bytes we are setting now (when aligning)
+
+ # take care of case for size <= 4
+ cmplwi %cr1,%r5,4
+ andi. %r7,%r3,3
+ mr %r6,%r3
+ ble- %cr1,small
+ # align to word boundary
+ cmplwi %cr5,%r5,31
+ rlwimi %r4,%r4,8,16,23
+ beq+ aligned # 8th instruction from .align
+ mtcrf 0x01,%r3
+ subfic %r7,%r7,4
+ add %r6,%r6,%r7
+ sub %r5,%r5,%r7
+ bf+ 31,0f
+ stb %r4,0(%r3)
+ bt 30,aligned
+0: sth %r4,-2(%r6) # 16th instruction from .align
+ # take care of case for size < 31
+aligned:
+ mtcrf 0x01,%r5
+ rlwimi %r4,%r4,16,0,15
+ ble %cr5,medium
+ # align to cache line boundary...
+ andi. %r7,%r6,0x1C
+ subfic %r7,%r7,0x20
+ beq caligned
+ mtcrf 0x01,%r7
+ add %r6,%r6,%r7
+ sub %r5,%r5,%r7
+ cmplwi %cr1,%r7,0x10
+ mr %r8,%r6
+ bf 28,1f
+ stw %r4,-4(%r8)
+ stwu %r4,-8(%r8)
+1: blt %cr1,2f
+ stw %r4,-4(%r8) # 32nd instruction from .align
+ stw %r4,-8(%r8)
+ stw %r4,-12(%r8)
+ stwu %r4,-16(%r8)
+2: bf 29,caligned
+ stw %r4,-4(%r8)
+ # now aligned to a cache line.
+caligned:
+ cmplwi %cr1,%r4,0
+ clrrwi. %r7,%r5,5
+ mtcrf 0x01,%r5 # 40th instruction from .align
+ beq %cr1,zloopstart # special case for clearing memory using dcbz
+ srwi %r0,%r7,5
+ mtctr %r0
+ beq medium # we may not actually get to do a full line
+ clrlwi. %r5,%r5,27
+ add %r6,%r6,%r7
+0: li %r8,-0x40
+ bdz cloopdone # 48th instruction from .align
+
+cloop: dcbz %r8,%r6
+ stw %r4,-4(%r6)
+ stw %r4,-8(%r6)
+ stw %r4,-12(%r6)
+ stw %r4,-16(%r6)
+ nop # let 601 fetch last 4 instructions of loop
+ stw %r4,-20(%r6)
+ stw %r4,-24(%r6) # 56th instruction from .align
+ nop # let 601 fetch first 8 instructions of loop
+ stw %r4,-28(%r6)
+ stwu %r4,-32(%r6)
+ bdnz cloop
+cloopdone:
+ stw %r4,-4(%r6)
+ stw %r4,-8(%r6)
+ stw %r4,-12(%r6)
+ stw %r4,-16(%r6) # 64th instruction from .align
+ stw %r4,-20(%r6)
+ cmplwi %cr1,%r5,16
+ stw %r4,-24(%r6)
+ stw %r4,-28(%r6)
+ stwu %r4,-32(%r6)
+ beqlr
+ add %r6,%r6,%r7
+ b medium_tail2 # 72nd instruction from .align
+
+ .align 5
+ nop
+# clear lines of memory in 128-byte chunks.
+zloopstart:
+ clrlwi %r5,%r5,27
+ mtcrf 0x02,%r7
+ srwi. %r0,%r7,7
+ mtctr %r0
+ li %r7,0x20
+ li %r8,-0x40
+ cmplwi %cr1,%r5,16 # 8
+ bf 26,0f
+ dcbz 0,%r6
+ addi %r6,%r6,0x20
+0: li %r9,-0x20
+ bf 25,1f
+ dcbz 0,%r6
+ dcbz %r7,%r6
+ addi %r6,%r6,0x40 # 16
+1: cmplwi %cr5,%r5,0
+ beq medium
+zloop:
+ dcbz 0,%r6
+ dcbz %r7,%r6
+ addi %r6,%r6,0x80
+ dcbz %r8,%r6
+ dcbz %r9,%r6
+ bdnz zloop
+ beqlr %cr5
+ b medium_tail2
+
+ .align 5
+small:
+ # Memset of 4 bytes or less.
+ cmplwi %cr5,%r5,1
+ cmplwi %cr1,%r5,3
+ bltlr %cr5
+ stb %r4,0(%r6)
+ beqlr %cr5
+ nop
+ stb %r4,1(%r6)
+ bltlr %cr1
+ stb %r4,2(%r6)
+ beqlr %cr1
+ nop
+ stb %r4,3(%r6)
+ blr
+
+# memset of 0-31 bytes
+ .align 5
+medium:
+ cmplwi %cr1,%r5,16
+medium_tail2:
+ add %r6,%r6,%r5
+medium_tail:
+ bt- 31,medium_31t
+ bt- 30,medium_30t
+medium_30f:
+ bt- 29,medium_29t
+medium_29f:
+ bge- %cr1,medium_27t
+ bflr- 28
+ stw %r4,-4(%r6) # 8th instruction from .align
+ stw %r4,-8(%r6)
+ blr
+
+medium_31t:
+ stbu %r4,-1(%r6)
+ bf- 30,medium_30f
+medium_30t:
+ sthu %r4,-2(%r6)
+ bf- 29,medium_29f
+medium_29t:
+ stwu %r4,-4(%r6)
+ blt- %cr1,medium_27f # 16th instruction from .align
+medium_27t:
+ stw %r4,-4(%r6)
+ stw %r4,-8(%r6)
+ stw %r4,-12(%r6)
+ stwu %r4,-16(%r6)
+medium_27f:
+ bflr- 28
+medium_28t:
+ stw %r4,-4(%r6)
+ stw %r4,-8(%r6)
+ blr
diff --git a/sysdeps/powerpc/mul_1.s b/sysdeps/powerpc/mul_1.s
new file mode 100644
index 0000000000..d6eb623bd4
--- /dev/null
+++ b/sysdeps/powerpc/mul_1.s
@@ -0,0 +1,47 @@
+ # Multiply a limb vector by a limb, for PowerPC.
+ # Copyright (C) 1993, 1994, 1995, 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.
+
+ # mp_limb_t mpn_mul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
+ # mp_size_t s1_size, mp_limb_t s2_limb)
+ # Calculate s1*s2 and put result in res_ptr; return carry.
+
+ .align 2
+ .globl __mpn_mul_1
+ .type __mpn_mul_1,@function
+
+__mpn_mul_1:
+ mtctr %r5
+
+ lwz %r0,0(%r4)
+ mullw %r7,%r0,%r6
+ mulhwu %r10,%r0,%r6
+ addi %r3,%r3,-4 # adjust res_ptr
+ addic %r5,%r5,0 # clear cy with dummy insn
+ bdz Lend
+
+Loop: lwzu %r0,4(%r4)
+ stwu %r7,4(%r3)
+ mullw %r8,%r0,%r6
+ adde %r7,%r8,%r10
+ mulhwu %r10,%r0,%r6
+ bdnz Loop
+
+Lend: stw %r7,4(%r3)
+ addze %r3,%r10
+ blr
diff --git a/sysdeps/powerpc/rshift.s b/sysdeps/powerpc/rshift.s
new file mode 100644
index 0000000000..20f09ad86a
--- /dev/null
+++ b/sysdeps/powerpc/rshift.s
@@ -0,0 +1,59 @@
+# PowerPC-32 __mpn_rshift --
+
+# Copyright (C) 1995 Free Software Foundation, Inc.
+
+# This file is part of the GNU MP Library.
+
+# The GNU MP 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 MP 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 MP 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.
+
+
+# INPUT PARAMETERS
+# res_ptr r3
+# s1_ptr r4
+# size r5
+# cnt r6
+
+ .align 3
+ .globl __mpn_rshift
+ .type __mpn_rshift,@function
+__mpn_rshift:
+ mtctr 5 # copy size into CTR
+ addi 7,3,-4 # move adjusted res_ptr to free return reg
+ subfic 8,6,32
+ lwz 11,0(4) # load first s1 limb
+ slw 3,11,8 # compute function return value
+ bdz Lend1
+
+Loop: lwzu 10,4(4)
+ srw 9,11,6
+ slw 12,10,8
+ or 9,9,12
+ stwu 9,4(7)
+ bdz Lend2
+ lwzu 11,4(4)
+ srw 9,10,6
+ slw 12,11,8
+ or 9,9,12
+ stwu 9,4(7)
+ bdnz Loop
+
+Lend1: srw 0,11,6
+ stw 0,4(7)
+ blr
+
+Lend2: srw 0,10,6
+ stw 0,4(7)
+ blr
diff --git a/sysdeps/powerpc/strchr.s b/sysdeps/powerpc/strchr.s
new file mode 100644
index 0000000000..c1df66f8dc
--- /dev/null
+++ b/sysdeps/powerpc/strchr.s
@@ -0,0 +1,118 @@
+ # Optimized strchr implementation for PowerPC.
+ # Copyright (C) 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.
+
+ # See strlen.s for comments on how this works.
+
+ .section ".text"
+ .align 2
+ .globl strchr
+ .type strchr,@function
+strchr:
+ # char * [r3] strchr (const char *s [r3] , int c [r4] )
+
+ # r0: a temporary
+ # r3: our return result.
+ # r4: byte we're looking for, spread over the whole word
+ # r5: the current word
+ # r6: the constant 0xfefefeff (-0x01010101)
+ # r7: the constant 0x7f7f7f7f
+ # r8: pointer to the current word.
+ # r9: a temporary
+ # r10: the number of bits we should ignore in the first word
+ # r11: a mask with the bits to ignore set to 0
+ # r12: a temporary
+
+ rlwimi %r4,%r4,8,16,23
+ li %r11,-1
+ rlwimi %r4,%r4,16,0,15
+ lis %r6,0xfeff
+ lis %r7,0x7f7f
+ clrrwi %r8,%r3,2
+ addi %r7,%r7,0x7f7f
+ addi %r6,%r6,0xfffffeff
+ rlwinm %r10,%r3,3,27,28
+ # Test the first (partial?) word.
+ lwz %r5,0(%r8)
+ srw %r11,%r11,%r10
+ orc %r5,%r5,%r11
+ add %r0,%r6,%r5
+ nor %r9,%r7,%r5
+ and. %r0,%r0,%r9
+ xor %r12,%r4,%r5
+ orc %r12,%r12,%r11
+ b loopentry
+
+ # The loop.
+
+loop: lwzu %r5,4(%r8)
+ and. %r0,%r0,%r9
+ # Test for 0
+ add %r0,%r6,%r5
+ nor %r9,%r7,%r5
+ bne foundit
+ and. %r0,%r0,%r9
+ # Start test for the bytes we're looking for
+ xor %r12,%r4,%r5
+loopentry:
+ add %r0,%r6,%r12
+ nor %r9,%r7,%r12
+ beq loop
+ # There is a zero byte in the word, but may also be a matching byte (either
+ # before or after the zero byte). In fact, we may be looking for a
+ # zero byte, in which case we return a match. We guess that this hasn't
+ # happened, though.
+missed:
+ and. %r0,%r0,%r9
+ li %r3,0
+ beqlr
+ # It did happen. Decide which one was first...
+ # I'm not sure if this is actually faster than a sequence of
+ # rotates, compares, and branches (we use it anyway because it's shorter).
+ and %r6,%r7,%r5
+ or %r11,%r7,%r5
+ and %r0,%r7,%r12
+ or %r10,%r7,%r12
+ add %r6,%r6,%r7
+ add %r0,%r0,%r7
+ nor %r5,%r11,%r6
+ nor %r9,%r10,%r0
+ cmplw %r5,%r9
+ bgtlr
+ cntlzw %r4,%r9
+ srwi %r4,%r4,3
+ add %r3,%r8,%r4
+ blr
+
+foundit:
+ and %r0,%r7,%r12
+ or %r10,%r7,%r12
+ add %r0,%r0,%r7
+ nor %r9,%r10,%r0
+ cntlzw %r4,%r9
+ subi %r8,%r8,4
+ srwi %r4,%r4,3
+ add %r3,%r8,%r4
+ blr
+
+0:
+ .size strchr,0b-strchr
+
+ .globl index
+ .weak index
+ .set index,strchr
diff --git a/sysdeps/powerpc/strcmp.s b/sysdeps/powerpc/strcmp.s
new file mode 100644
index 0000000000..f901b82ab1
--- /dev/null
+++ b/sysdeps/powerpc/strcmp.s
@@ -0,0 +1,273 @@
+ # Optimized strcmp implementation for PowerPC.
+ # Copyright (C) 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.
+
+ # See strlen.s for comments on how the end-of-string testing works.
+
+ .section ".text"
+ .align 3
+ .globl strcmp
+ .type strcmp,@function
+strcmp:
+ # int [r3] strcmp (const char *p1 [r3], const char *p2 [r4])
+
+ # General register assignments:
+ # r0: temporary
+ # r3: pointer to previous word in s1
+ # r4: pointer to previous word in s2
+ # r5: current first word in s1
+ # r6: current first word in s2 (after re-alignment)
+ # r7: 0xfefefeff
+ # r8: 0x7f7f7f7f
+ # r9: ~(word in s1 | 0x7f7f7f7f)
+
+ # Register assignments in the prologue:
+ # r10: low 2 bits of p2-p1
+ # r11: mask to orc with r5/r6
+
+ subf. %r10,%r4,%r3
+ beq- equal
+ andi. %r10,%r10,3
+ cmpi %cr1,%r10,2
+ beq- %cr1,align2
+ lis %r7,0xfeff
+ lis %r8,0x7f7f
+ addi %r8,%r8,0x7f7f
+ addi %r7,%r7,0xfffffeff
+ bgt- %cr1,align3
+strcmp3:
+ rlwinm %r0,%r3,3,27,28
+ li %r11,-1
+ srw %r11,%r11,%r0
+ clrrwi %r3,%r3,2
+ clrrwi %r4,%r4,2
+ lwz %r5,0(%r3)
+ lwz %r6,0(%r4)
+ bne- align1
+
+ # The loop, case when both strings are aligned the same.
+ # on entry, cr1.eq must be 1.
+ # r10: second word in s1
+ # r11: second word in s2 OR mask to orc with first two words.
+align0:
+ andi. %r0,%r3,4
+ orc %r5,%r5,%r11
+ orc %r6,%r6,%r11
+ beq+ a0start
+ add %r0,%r7,%r5
+ nor %r9,%r8,%r5
+ and. %r0,%r0,%r9
+ cmplw %cr1,%r5,%r6
+ subi %r3,%r3,4
+ bne- endstringeq
+ subi %r4,%r4,4
+ bne- %cr1,difference
+
+loopalign0:
+ lwzu %r5,8(%r3)
+ bne- %cr1,difference2
+ lwzu %r6,8(%r4)
+a0start:
+ add %r0,%r7,%r5
+ nor %r9,%r8,%r5
+ and. %r0,%r0,%r9
+ cmplw %cr1,%r5,%r6
+ lwz %r10,4(%r3)
+ bne- endstringeq
+ add %r0,%r7,%r10
+ bne- %cr1,difference
+ nor %r9,%r8,%r10
+ lwz %r11,4(%r4)
+ and. %r0,%r0,%r9
+ cmplw %cr1,%r10,%r11
+ beq+ loopalign0
+
+ mr %r5,%r10
+ mr %r6,%r11
+
+ # fall through to...
+
+endstringeq:
+ # (like 'endstring', but an equality code is in cr1)
+ beq %cr1,equal
+endstring:
+ # OK. We've hit the end of the string. We need to be careful that
+ # we don't compare two strings as different because of gunk beyond
+ # the end of the strings. We do it like this...
+ and %r0,%r8,%r5
+ add %r0,%r0,%r8
+ xor. %r10,%r5,%r6
+ andc %r9,%r9,%r0
+ cntlzw %r10,%r10
+ cntlzw %r9,%r9
+ addi %r9,%r9,7
+ cmpw %cr1,%r9,%r10
+ blt %cr1,equal
+ sub %r3,%r5,%r6
+ bgelr+
+ mr %r3,%r6
+ blr
+equal: li %r3,0
+ blr
+
+ # The loop, case when s2 is aligned 1 char behind s1.
+ # r10: current word in s2 (before re-alignment)
+
+align1:
+ cmpwi %cr1,%r0,0
+ orc %r5,%r5,%r11
+ bne %cr1,align1_123
+ # When s1 is aligned to a word boundary, the startup processing is special.
+ slwi. %r6,%r6,24
+ bne+ a1entry_0
+ nor %r9,%r8,%r5
+ b endstring
+
+align1_123:
+ # Otherwise (s1 not aligned to a word boundary):
+ mr %r10,%r6
+ add %r0,%r7,%r5
+ nor %r9,%r8,%r5
+ and. %r0,%r0,%r9
+ srwi %r6,%r6,8
+ orc %r6,%r6,%r11
+ cmplw %cr1,%r5,%r6
+ bne- endstringeq
+ bne- %cr1,difference
+
+loopalign1:
+ slwi. %r6,%r10,24
+ bne- %cr1,a1difference
+ lwzu %r5,4(%r3)
+ beq- endstring1
+a1entry_0:
+ lwzu %r10,4(%r4)
+a1entry_123:
+ add %r0,%r7,%r5
+ nor %r9,%r8,%r5
+ and. %r0,%r0,%r9
+ rlwimi %r6,%r10,24,8,31
+ cmplw %cr1,%r5,%r6
+ beq+ loopalign1
+ b endstringeq
+
+endstring1:
+ srwi %r3,%r5,24
+ blr
+
+a1difference:
+ lbz %r6,-1(%r4)
+ slwi %r6,%r6,24
+ rlwimi %r6,%r10,24,8,31
+
+ # fall through to...
+
+difference:
+ # The idea here is that we could just return '%r5 - %r6', except
+ # that the result might overflow. Overflow can only happen when %r5
+ # and %r6 have different signs (thus the xor), in which case we want to
+ # return negative iff %r6 has its high bit set so %r5 < %r6.
+ # A branch-free implementation of this is
+ # xor %r0,%r5,%r6
+ # rlwinm %r0,%r0,1,31,31
+ # rlwnm %r5,%r5,%r0,1,31
+ # rlwnm %r6,%r6,%r0,1,31
+ # sub %r3,%r5,%r6
+ # blr
+ # but this is usually more expensive.
+ xor. %r0,%r5,%r6
+ sub %r3,%r5,%r6
+ bgelr+
+ mr %r3,%r6
+ blr
+
+difference2:
+ # As for 'difference', but use registers r10 and r11 instead of r5 and r6.
+ xor. %r0,%r10,%r11
+ sub %r3,%r10,%r11
+ bgelr+
+ mr %r3,%r11
+ blr
+
+ # For the case when s2 is aligned 3 chars behind s1, we switch
+ # s1 and s2...
+ # r10: used by 'align2' (see below)
+ # r11: used by 'align2' (see below)
+ # r12: saved link register
+ # cr0.eq: must be left as 1.
+
+align3: mflr %r12
+ mr %r0,%r3
+ mr %r3,%r4
+ mr %r4,%r0
+ bl strcmp3
+ mtlr %r12
+ neg %r3,%r3
+ blr
+
+ # The loop, case when s2 and s1's alignments differ by 2
+ # This is the ugly case...
+ # FIXME: on a 601, the loop takes 7 cycles instead of the 6 you'd expect,
+ # because there are too many branches. This loop should probably be
+ # coded like the align1 case.
+
+a2even: lhz %r5,0(%r3)
+ lhz %r6,0(%r4)
+ b a2entry
+
+align2:
+ andi. %r0,%r3,1
+ beq+ a2even
+ subi %r3,%r3,1
+ subi %r4,%r4,1
+ lbz %r5,1(%r3)
+ lbz %r6,1(%r4)
+ cmpwi %cr0,%r5,0
+ cmpw %cr1,%r5,%r6
+ beq- align2end2
+ lhzu %r5,2(%r3)
+ beq+ %cr1,a2entry1
+ lbz %r5,-1(%r3)
+ sub %r3,%r5,%r6
+ blr
+
+loopalign2:
+ cmpw %cr1,%r5,%r6
+ beq- align2end2
+ lhzu %r5,2(%r3)
+ bne- %cr1,align2different
+a2entry1:
+ lhzu %r6,2(%r4)
+a2entry:
+ cmpwi %cr5,%r5,0x00ff
+ andi. %r0,%r5,0x00ff
+ bgt+ %cr5,loopalign2
+
+align2end:
+ andi. %r3,%r6,0xff00
+ neg %r3,%r3
+ blr
+
+align2different:
+ lhzu %r5,-2(%r3)
+align2end2:
+ sub %r3,%r5,%r6
+ blr
+
+0:
+ .size strcmp,0b-strcmp
diff --git a/sysdeps/powerpc/sub_n.s b/sysdeps/powerpc/sub_n.s
new file mode 100644
index 0000000000..8711bf9a40
--- /dev/null
+++ b/sysdeps/powerpc/sub_n.s
@@ -0,0 +1,69 @@
+ # Subtract two limb vectors of equal, non-zero length for PowerPC.
+ # Copyright (C) 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.
+
+ # mp_limb_t mpn_sub_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr,
+ # mp_size_t size)
+ # Calculate s1-s2 and put result in res_ptr; return borrow, 0 or 1.
+
+ # Note on optimisation: This code is optimal for the 601. Almost every other
+ # possible 2-unrolled inner loop will not be. Also, watch out for the
+ # alignment...
+
+ .align 3
+ .globl __mpn_sub_n
+ .type __mpn_sub_n,@function
+ nop
+__mpn_sub_n:
+ # Set up for loop below.
+ mtcrf 0x01,%r6
+ srwi. %r7,%r6,1
+ mtctr %r7
+ bt 31,2f
+
+ # Set the carry (clear the borrow).
+ subfc %r0,%r0,%r0
+ # Adjust pointers for loop.
+ addi %r3,%r3,-4
+ addi %r4,%r4,-4
+ addi %r5,%r5,-4
+ b 0f
+
+2: lwz %r7,0(%r5)
+ lwz %r6,0(%r4)
+ subfc %r6,%r7,%r6
+ stw %r6,0(%r3)
+ beq 1f
+
+ # Align start of loop to an odd word boundary to guarantee that the
+ # last two words can be fetched in one access (for 601). This turns
+ # out to be important.
+0:
+ lwz %r9,4(%r4)
+ lwz %r8,4(%r5)
+ lwzu %r6,8(%r4)
+ lwzu %r7,8(%r5)
+ subfe %r8,%r8,%r9
+ stw %r8,4(%r3)
+ subfe %r6,%r7,%r6
+ stwu %r6,8(%r3)
+ bdnz 0b
+ # return the borrow
+1: subfe %r3,%r3,%r3
+ neg %r3,%r3
+ blr
diff --git a/sysdeps/powerpc/submul_1.s b/sysdeps/powerpc/submul_1.s
new file mode 100644
index 0000000000..999430d744
--- /dev/null
+++ b/sysdeps/powerpc/submul_1.s
@@ -0,0 +1,52 @@
+ # Multiply a limb vector by a single limb, for PowerPC.
+ # Copyright (C) 1993, 1994, 1995, 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.
+
+ # mp_limb_t mpn_submul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
+ # mp_size_t s1_size, mp_limb_t s2_limb)
+ # Calculate res-s1*s2 and put result back in res; return carry.
+
+ .align 2
+ .globl __mpn_submul_1
+ .type __mpn_submul_1,@function
+__mpn_submul_1:
+ mtctr %r5
+
+ lwz %r0,0(%r4)
+ mullw %r7,%r0,%r6
+ mulhwu %r10,%r0,%r6
+ lwz %r9,0(%r3)
+ subf %r8,%r7,%r9
+ addc %r7,%r7,%r8 # invert cy (r7 is junk)
+ addi %r3,%r3,-4 # adjust res_ptr
+ bdz Lend
+
+Loop: lwzu %r0,4(%r4)
+ stwu %r8,4(%r3)
+ mullw %r8,%r0,%r6
+ adde %r7,%r8,%r10
+ mulhwu %r10,%r0,%r6
+ lwz %r9,4(%r3)
+ addze %r10,%r10
+ subf %r8,%r7,%r9
+ addc %r7,%r7,%r8 # invert cy (r7 is junk)
+ bdnz Loop
+
+Lend: stw %r8,4(%r3)
+ addze %r3,%r10
+ blr
diff --git a/sysdeps/sparc/Dist b/sysdeps/sparc/Dist
new file mode 100644
index 0000000000..7832507772
--- /dev/null
+++ b/sysdeps/sparc/Dist
@@ -0,0 +1 @@
+sys/trap.h
diff --git a/sysdeps/sparc/sparc32/Dist b/sysdeps/sparc/sparc32/Dist
index 6c3b23baa5..8bd3729740 100644
--- a/sysdeps/sparc/sparc32/Dist
+++ b/sysdeps/sparc/sparc32/Dist
@@ -1,4 +1,3 @@
dotmul.S umul.S
divrem.m4 sdiv.S udiv.S rem.S urem.S
alloca.S
-sys/trap.h
diff --git a/sysdeps/sparc/sparc32/sparcv8/Dist b/sysdeps/sparc/sparc32/sparcv8/Dist
new file mode 100644
index 0000000000..6318172684
--- /dev/null
+++ b/sysdeps/sparc/sparc32/sparcv8/Dist
@@ -0,0 +1,6 @@
+urem.S
+umul.S
+udiv.S
+sdiv.S
+rem.S
+dotmul.S
diff --git a/sysdeps/stub/des_impl.c b/sysdeps/stub/des_impl.c
new file mode 100644
index 0000000000..b6a4a8eb13
--- /dev/null
+++ b/sysdeps/stub/des_impl.c
@@ -0,0 +1,27 @@
+/* Copyright (C) 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. */
+
+/* We must not distribute the DES implementation as part of the glibc.
+ So we have to provide a dummy version here. */
+int
+_des_crypt (char *buf, unsigned len, struct desparams *desp)
+{
+ return 0;
+}
+
+stub_warning (_des_crypt)
diff --git a/sysdeps/unix/sysv/linux/mips/Dist b/sysdeps/unix/sysv/linux/mips/Dist
index 6be6876fe7..0f106cf8fa 100644
--- a/sysdeps/unix/sysv/linux/mips/Dist
+++ b/sysdeps/unix/sysv/linux/mips/Dist
@@ -6,6 +6,7 @@ kernel_termios.h
entry.h
regdef.h
fpregdef.h
+sgidefs.h
sys/acct.h
sys/asm.h
sys/cachectl.h
diff --git a/sysdeps/unix/sysv/linux/sparc/Dist b/sysdeps/unix/sysv/linux/sparc/Dist
new file mode 100644
index 0000000000..7832507772
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/Dist
@@ -0,0 +1 @@
+sys/trap.h
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/Dist b/sysdeps/unix/sysv/linux/sparc/sparc32/Dist
index 9729f0709b..ed8fc080c1 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/Dist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/Dist
@@ -5,4 +5,3 @@ pipe.S
fork.S
kernel_stat.h
init-first.h
-sys/trap.h