xref: /illumos-gate/usr/src/cmd/keyserv/keyserv.c (revision 004388eb)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5a0368f78Speteh  * Common Development and Distribution License (the "License").
6a0368f78Speteh  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22a0368f78Speteh  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
277c478bd9Sstevel@tonic-gate /*	All Rights Reserved   */
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate /*
307c478bd9Sstevel@tonic-gate  * University Copyright- Copyright (c) 1982, 1986, 1988
317c478bd9Sstevel@tonic-gate  * The Regents of the University of California
327c478bd9Sstevel@tonic-gate  * All Rights Reserved
337c478bd9Sstevel@tonic-gate  *
347c478bd9Sstevel@tonic-gate  * University Acknowledgment- Portions of this document are derived from
357c478bd9Sstevel@tonic-gate  * software developed by the University of California, Berkeley, and its
367c478bd9Sstevel@tonic-gate  * contributors.
377c478bd9Sstevel@tonic-gate  */
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate /*
427c478bd9Sstevel@tonic-gate  * keyserv - server for storing private encryption keys
437c478bd9Sstevel@tonic-gate  *   keyserv(1M) performs multiple functions:  it stores secret keys per uid; it
447c478bd9Sstevel@tonic-gate  *   performs public key encryption and decryption operations; and it generates
457c478bd9Sstevel@tonic-gate  *   "random" keys.  keyserv(1M) will talk to no one but a local root process on
467c478bd9Sstevel@tonic-gate  *   the local transport only.
477c478bd9Sstevel@tonic-gate  */
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate #include <stdio.h>
50*004388ebScasper #include <stdio_ext.h>
517c478bd9Sstevel@tonic-gate #include <stdlib.h>
527c478bd9Sstevel@tonic-gate #include <sys/types.h>
537c478bd9Sstevel@tonic-gate #include <sys/stat.h>
547c478bd9Sstevel@tonic-gate #include <sys/uio.h>
557c478bd9Sstevel@tonic-gate #include <unistd.h>
567c478bd9Sstevel@tonic-gate #include <string.h>
577c478bd9Sstevel@tonic-gate #include <deflt.h>
587c478bd9Sstevel@tonic-gate #include <rpc/rpc.h>
597c478bd9Sstevel@tonic-gate #include <sys/param.h>
607c478bd9Sstevel@tonic-gate #include <sys/file.h>
617c478bd9Sstevel@tonic-gate #include <sys/resource.h>
627c478bd9Sstevel@tonic-gate #include <pwd.h>
637c478bd9Sstevel@tonic-gate #include <rpc/des_crypt.h>
647c478bd9Sstevel@tonic-gate #include <rpc/key_prot.h>
657c478bd9Sstevel@tonic-gate #include <thread.h>
667c478bd9Sstevel@tonic-gate #include "rpc/svc_mt.h"
677c478bd9Sstevel@tonic-gate #include <rpcsvc/nis_dhext.h>
687c478bd9Sstevel@tonic-gate #include <syslog.h>
697c478bd9Sstevel@tonic-gate #include <libscf.h>
707c478bd9Sstevel@tonic-gate 
717c478bd9Sstevel@tonic-gate #include "debug.h"
727c478bd9Sstevel@tonic-gate #include "keyserv_cache.h"
737c478bd9Sstevel@tonic-gate 
747c478bd9Sstevel@tonic-gate #ifdef KEYSERV_RANDOM
757c478bd9Sstevel@tonic-gate extern long random();
767c478bd9Sstevel@tonic-gate #endif
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate extern keystatus pk_setkey();
797c478bd9Sstevel@tonic-gate extern keystatus pk_encrypt();
807c478bd9Sstevel@tonic-gate extern keystatus pk_decrypt();
817c478bd9Sstevel@tonic-gate extern keystatus pk_netput();
827c478bd9Sstevel@tonic-gate extern keystatus pk_netget();
837c478bd9Sstevel@tonic-gate extern keystatus pk_get_conv_key();
847c478bd9Sstevel@tonic-gate extern bool_t svc_get_local_cred();
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate extern keystatus pk_setkey3();
877c478bd9Sstevel@tonic-gate extern keystatus pk_encrypt3();
887c478bd9Sstevel@tonic-gate extern keystatus pk_decrypt3();
897c478bd9Sstevel@tonic-gate extern keystatus pk_netput3();
907c478bd9Sstevel@tonic-gate extern keystatus pk_netget3();
917c478bd9Sstevel@tonic-gate extern keystatus pk_get_conv_key3();
927c478bd9Sstevel@tonic-gate extern keystatus pk_clear3();
937c478bd9Sstevel@tonic-gate 
947c478bd9Sstevel@tonic-gate extern int init_mechs();
957c478bd9Sstevel@tonic-gate extern int addmasterkey();
967c478bd9Sstevel@tonic-gate extern int storeotherrootkeys();
977c478bd9Sstevel@tonic-gate extern int setdeskeyarray();
987c478bd9Sstevel@tonic-gate 
997c478bd9Sstevel@tonic-gate extern int getdomainname();
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate static void randomize();
1027c478bd9Sstevel@tonic-gate static void usage();
1037c478bd9Sstevel@tonic-gate static void defaults();
1047c478bd9Sstevel@tonic-gate static int getrootkey();
1057c478bd9Sstevel@tonic-gate static int get_cache_size(char *);
1067c478bd9Sstevel@tonic-gate static bool_t get_auth();
1077c478bd9Sstevel@tonic-gate 
1087c478bd9Sstevel@tonic-gate #ifdef DEBUG
1097c478bd9Sstevel@tonic-gate extern int test_debug();
1107c478bd9Sstevel@tonic-gate extern int real_debug();
1117c478bd9Sstevel@tonic-gate int debugging = 1;
1127c478bd9Sstevel@tonic-gate #else
1137c478bd9Sstevel@tonic-gate int debugging = 0;
1147c478bd9Sstevel@tonic-gate #endif
1157c478bd9Sstevel@tonic-gate 
1167c478bd9Sstevel@tonic-gate static void keyprogram();
1177c478bd9Sstevel@tonic-gate static des_block masterkey;
1187c478bd9Sstevel@tonic-gate char *getenv();
1197c478bd9Sstevel@tonic-gate static char ROOTKEY[] = "/etc/.rootkey";
1207c478bd9Sstevel@tonic-gate 
1217c478bd9Sstevel@tonic-gate static char *defaults_file = "/etc/default/keyserv";
1227c478bd9Sstevel@tonic-gate static int use_nobody_keys = TRUE;
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate /*
1257c478bd9Sstevel@tonic-gate  * Hack to allow the keyserver to use AUTH_DES (for authenticated
1267c478bd9Sstevel@tonic-gate  * NIS+ calls, for example).  The only functions that get called
1277c478bd9Sstevel@tonic-gate  * are key_encryptsession_pk, key_decryptsession_pk, and key_gendes.
1287c478bd9Sstevel@tonic-gate  *
1297c478bd9Sstevel@tonic-gate  * The approach is to have the keyserver fill in pointers to local
1307c478bd9Sstevel@tonic-gate  * implementations of these functions, and to call those in key_call().
1317c478bd9Sstevel@tonic-gate  */
1327c478bd9Sstevel@tonic-gate 
1337c478bd9Sstevel@tonic-gate bool_t __key_encrypt_pk_2_svc();
1347c478bd9Sstevel@tonic-gate bool_t __key_decrypt_pk_2_svc();
1357c478bd9Sstevel@tonic-gate bool_t __key_gen_1_svc();
1367c478bd9Sstevel@tonic-gate 
1377c478bd9Sstevel@tonic-gate extern bool_t (*__key_encryptsession_pk_LOCAL)();
1387c478bd9Sstevel@tonic-gate extern bool_t (*__key_decryptsession_pk_LOCAL)();
1397c478bd9Sstevel@tonic-gate extern bool_t (*__key_gendes_LOCAL)();
1407c478bd9Sstevel@tonic-gate 
1417c478bd9Sstevel@tonic-gate static int nthreads = 32;
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate /* Disk caching of common keys on by default */
1447c478bd9Sstevel@tonic-gate int disk_caching = 1;
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate mechanism_t **mechs;
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate /*
1497c478bd9Sstevel@tonic-gate  * The default size for all types of mech.
1507c478bd9Sstevel@tonic-gate  * positive integers denote multiples of 1MB
1517c478bd9Sstevel@tonic-gate  * negative integers denote number of entries
1527c478bd9Sstevel@tonic-gate  * same goes for non-null entries in cache_size
1537c478bd9Sstevel@tonic-gate  */
1547c478bd9Sstevel@tonic-gate static int default_cache = 1;
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate int *cache_size;
1577c478bd9Sstevel@tonic-gate char **cache_options;
1587c478bd9Sstevel@tonic-gate 
15949e7ca49Speteh int
16049e7ca49Speteh main(int argc, char *argv[])
1617c478bd9Sstevel@tonic-gate {
1627c478bd9Sstevel@tonic-gate 	int sflag = 0, s1flag = 0, s2flag = 0, nflag = 0, dflag = 0, eflag = 0;
1637c478bd9Sstevel@tonic-gate 	char *options, *value;
1647c478bd9Sstevel@tonic-gate 	extern char *optarg;
1657c478bd9Sstevel@tonic-gate 	extern int optind;
1667c478bd9Sstevel@tonic-gate 	int c, d;
1677c478bd9Sstevel@tonic-gate 	struct rlimit rl;
1687c478bd9Sstevel@tonic-gate 	int mode = RPC_SVC_MT_AUTO;
1697c478bd9Sstevel@tonic-gate 	int maxrecsz = RPC_MAXDATASIZE;
1707c478bd9Sstevel@tonic-gate 
17149e7ca49Speteh 	void detachfromtty(void);
1727c478bd9Sstevel@tonic-gate 	int setmodulus();
1737c478bd9Sstevel@tonic-gate 	int pk_nodefaultkeys();
1747c478bd9Sstevel@tonic-gate 	int svc_create_local_service();
1757c478bd9Sstevel@tonic-gate 
1767c478bd9Sstevel@tonic-gate 	char domainname[MAXNETNAMELEN + 1];
1777c478bd9Sstevel@tonic-gate 
1787c478bd9Sstevel@tonic-gate 	/*
1797c478bd9Sstevel@tonic-gate 	 * Set our allowed number of file descriptors to the max
1807c478bd9Sstevel@tonic-gate 	 * of what the system will allow, limited by FD_SETSIZE.
1817c478bd9Sstevel@tonic-gate 	 */
1827c478bd9Sstevel@tonic-gate 	if (getrlimit(RLIMIT_NOFILE, &rl) == 0) {
1837c478bd9Sstevel@tonic-gate 		rlim_t limit;
1847c478bd9Sstevel@tonic-gate 
1857c478bd9Sstevel@tonic-gate 		if ((limit = rl.rlim_max) > FD_SETSIZE)
1867c478bd9Sstevel@tonic-gate 			limit = FD_SETSIZE;
1877c478bd9Sstevel@tonic-gate 		rl.rlim_cur = limit;
1887c478bd9Sstevel@tonic-gate 		(void) setrlimit(RLIMIT_NOFILE, &rl);
189*004388ebScasper 		(void) enable_extended_FILE_stdio(-1, -1);
1907c478bd9Sstevel@tonic-gate 	}
1917c478bd9Sstevel@tonic-gate 
1927c478bd9Sstevel@tonic-gate 	__key_encryptsession_pk_LOCAL = &__key_encrypt_pk_2_svc;
1937c478bd9Sstevel@tonic-gate 	__key_decryptsession_pk_LOCAL = &__key_decrypt_pk_2_svc;
1947c478bd9Sstevel@tonic-gate 	__key_gendes_LOCAL = &__key_gen_1_svc;
1957c478bd9Sstevel@tonic-gate 
1967c478bd9Sstevel@tonic-gate 	/*
1977c478bd9Sstevel@tonic-gate 	 * Pre-option initialisation
1987c478bd9Sstevel@tonic-gate 	 */
1997c478bd9Sstevel@tonic-gate 	(void) umask(066);	/* paranoia */
2007c478bd9Sstevel@tonic-gate 	if (geteuid() != 0) {
2017c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "%s must be run as root\n", argv[0]);
2027c478bd9Sstevel@tonic-gate 		exit(1);
2037c478bd9Sstevel@tonic-gate 	}
2047c478bd9Sstevel@tonic-gate 	setmodulus(HEXMODULUS);
2057c478bd9Sstevel@tonic-gate 	openlog("keyserv", LOG_PID, LOG_DAEMON);
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate 	/*
2087c478bd9Sstevel@tonic-gate 	 * keyserv will not work with a null domainname.
2097c478bd9Sstevel@tonic-gate 	 */
2107c478bd9Sstevel@tonic-gate 	if (getdomainname(domainname, MAXNETNAMELEN+1) ||
2117c478bd9Sstevel@tonic-gate 	    (domainname[0] == '\0')) {
2127c478bd9Sstevel@tonic-gate 	    syslog(LOG_ERR, "could not get a valid domainname.\n");
2137c478bd9Sstevel@tonic-gate 	    exit(SMF_EXIT_ERR_CONFIG);
2147c478bd9Sstevel@tonic-gate 	}
2157c478bd9Sstevel@tonic-gate 
2167c478bd9Sstevel@tonic-gate 	/*
2177c478bd9Sstevel@tonic-gate 	 * Initialise security mechanisms
2187c478bd9Sstevel@tonic-gate 	 */
2197c478bd9Sstevel@tonic-gate 	cache_size = NULL;
2207c478bd9Sstevel@tonic-gate 	cache_options = NULL;
2217c478bd9Sstevel@tonic-gate 	if (init_mechs() == -1) {
2227c478bd9Sstevel@tonic-gate 		disk_caching = 0;
2237c478bd9Sstevel@tonic-gate 	}
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate 	defaults();
2267c478bd9Sstevel@tonic-gate 
2277c478bd9Sstevel@tonic-gate 	while ((c = getopt(argc, argv, "ndDet:cs:")) != -1)
2287c478bd9Sstevel@tonic-gate 		switch (c) {
2297c478bd9Sstevel@tonic-gate 		case 'n':
2307c478bd9Sstevel@tonic-gate 			nflag++;
2317c478bd9Sstevel@tonic-gate 			break;
2327c478bd9Sstevel@tonic-gate 		case 'd':
2337c478bd9Sstevel@tonic-gate 			dflag++;
2347c478bd9Sstevel@tonic-gate 			use_nobody_keys = FALSE;
2357c478bd9Sstevel@tonic-gate 			break;
2367c478bd9Sstevel@tonic-gate 		case 'e':
2377c478bd9Sstevel@tonic-gate 			eflag++;
2387c478bd9Sstevel@tonic-gate 			use_nobody_keys = TRUE;
2397c478bd9Sstevel@tonic-gate 			break;
2407c478bd9Sstevel@tonic-gate 		case 'D':
2417c478bd9Sstevel@tonic-gate 			debugging = 1;
2427c478bd9Sstevel@tonic-gate 			break;
2437c478bd9Sstevel@tonic-gate 		case 't':
2447c478bd9Sstevel@tonic-gate 			nthreads = atoi(optarg);
2457c478bd9Sstevel@tonic-gate 			break;
2467c478bd9Sstevel@tonic-gate 		case 'c':
2477c478bd9Sstevel@tonic-gate 			disk_caching = 0;
2487c478bd9Sstevel@tonic-gate 			break;
2497c478bd9Sstevel@tonic-gate 		case 's':
2507c478bd9Sstevel@tonic-gate 			if (!disk_caching) {
2517c478bd9Sstevel@tonic-gate 				fprintf(stderr, "missing configuration file");
2527c478bd9Sstevel@tonic-gate 				fprintf(stderr, " or -c option specified\n");
2537c478bd9Sstevel@tonic-gate 				usage();
2547c478bd9Sstevel@tonic-gate 			}
2557c478bd9Sstevel@tonic-gate 			sflag++;
2567c478bd9Sstevel@tonic-gate 			/*
2577c478bd9Sstevel@tonic-gate 			 * Which version of [-s] do we have...?
2587c478bd9Sstevel@tonic-gate 			 */
2597c478bd9Sstevel@tonic-gate 			if (strchr((const char *) optarg, '=') == NULL) {
2607c478bd9Sstevel@tonic-gate 				/*
2617c478bd9Sstevel@tonic-gate 				 * -s <size>
2627c478bd9Sstevel@tonic-gate 				 */
2637c478bd9Sstevel@tonic-gate 				if (s1flag) {
2647c478bd9Sstevel@tonic-gate 				    fprintf(stderr, "duplicate [-s <size>]\n");
2657c478bd9Sstevel@tonic-gate 					usage();
2667c478bd9Sstevel@tonic-gate 				}
2677c478bd9Sstevel@tonic-gate 				s1flag++;
2687c478bd9Sstevel@tonic-gate 				default_cache = get_cache_size(optarg);
2697c478bd9Sstevel@tonic-gate 				break;
2707c478bd9Sstevel@tonic-gate 			}
2717c478bd9Sstevel@tonic-gate 			/*
2727c478bd9Sstevel@tonic-gate 			 * -s <mechtype>=<size>[,...]
2737c478bd9Sstevel@tonic-gate 			 */
2747c478bd9Sstevel@tonic-gate 			s2flag++;
2757c478bd9Sstevel@tonic-gate 			options = optarg;
2767c478bd9Sstevel@tonic-gate 			while (*options != '\0') {
2777c478bd9Sstevel@tonic-gate 				d = getsubopt(&options, cache_options, &value);
2787c478bd9Sstevel@tonic-gate 				if (d == -1) {
2797c478bd9Sstevel@tonic-gate 					/* Ignore unknown mechtype */
2807c478bd9Sstevel@tonic-gate 					continue;
2817c478bd9Sstevel@tonic-gate 				}
2827c478bd9Sstevel@tonic-gate 				if (value == NULL) {
2837c478bd9Sstevel@tonic-gate 					fprintf(stderr,
2847c478bd9Sstevel@tonic-gate 					"missing cache size for mechtype %s\n",
2857c478bd9Sstevel@tonic-gate 					cache_options[d]);
2867c478bd9Sstevel@tonic-gate 					usage();
2877c478bd9Sstevel@tonic-gate 				}
2887c478bd9Sstevel@tonic-gate 				cache_size[d] = get_cache_size(value);
2897c478bd9Sstevel@tonic-gate 			}
2907c478bd9Sstevel@tonic-gate 			break;
2917c478bd9Sstevel@tonic-gate 		default:
2927c478bd9Sstevel@tonic-gate 			usage();
2937c478bd9Sstevel@tonic-gate 			break;
2947c478bd9Sstevel@tonic-gate 		}
2957c478bd9Sstevel@tonic-gate 
2967c478bd9Sstevel@tonic-gate 
2977c478bd9Sstevel@tonic-gate 	if (dflag && eflag) {
2987c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "specify only one of -d and -e\n");
2997c478bd9Sstevel@tonic-gate 		usage();
3007c478bd9Sstevel@tonic-gate 	}
3017c478bd9Sstevel@tonic-gate 
3027c478bd9Sstevel@tonic-gate 	if (use_nobody_keys == FALSE) {
3037c478bd9Sstevel@tonic-gate 		pk_nodefaultkeys();
3047c478bd9Sstevel@tonic-gate 	}
3057c478bd9Sstevel@tonic-gate 
3067c478bd9Sstevel@tonic-gate 	if (optind != argc) {
3077c478bd9Sstevel@tonic-gate 		usage();
3087c478bd9Sstevel@tonic-gate 	}
3097c478bd9Sstevel@tonic-gate 
3107c478bd9Sstevel@tonic-gate 	if (!disk_caching && sflag) {
3117c478bd9Sstevel@tonic-gate 		fprintf(stderr, "missing configuration file");
3127c478bd9Sstevel@tonic-gate 		fprintf(stderr, " or -c option specified\n");
3137c478bd9Sstevel@tonic-gate 		usage();
3147c478bd9Sstevel@tonic-gate 	}
3157c478bd9Sstevel@tonic-gate 
3167c478bd9Sstevel@tonic-gate 	if (debugging) {
3177c478bd9Sstevel@tonic-gate 		if (disk_caching) {
3187c478bd9Sstevel@tonic-gate 			char **cpp = cache_options;
3197c478bd9Sstevel@tonic-gate 			int *ip = cache_size;
3207c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "default disk cache size: ");
3217c478bd9Sstevel@tonic-gate 			if (default_cache < 0) {
3227c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr, "%d entries\n",
3237c478bd9Sstevel@tonic-gate 					abs(default_cache));
3247c478bd9Sstevel@tonic-gate 			} else {
3257c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr, "%dMB\n", default_cache);
3267c478bd9Sstevel@tonic-gate 			}
3277c478bd9Sstevel@tonic-gate 
3287c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "supported mechanisms:\n");
3297c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "\talias\t\tdisk cache size\n");
3307c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "\t=====\t\t===============\n");
3317c478bd9Sstevel@tonic-gate 			while (*cpp != NULL) {
3327c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr, "\t%s\t\t", *cpp++);
3337c478bd9Sstevel@tonic-gate 				if (*ip < 0) {
3347c478bd9Sstevel@tonic-gate 					(void) fprintf(stderr, "%d entries\n",
3357c478bd9Sstevel@tonic-gate 						abs(*ip));
3367c478bd9Sstevel@tonic-gate 				} else {
3377c478bd9Sstevel@tonic-gate 					(void) fprintf(stderr, "%dMB\n", *ip);
3387c478bd9Sstevel@tonic-gate 				}
3397c478bd9Sstevel@tonic-gate 				ip++;
3407c478bd9Sstevel@tonic-gate 			}
3417c478bd9Sstevel@tonic-gate 		} else {
3427c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
3437c478bd9Sstevel@tonic-gate 				"common key disk caching disabled\n");
3447c478bd9Sstevel@tonic-gate 		}
3457c478bd9Sstevel@tonic-gate 	}
3467c478bd9Sstevel@tonic-gate 	/*
3477c478bd9Sstevel@tonic-gate 	 * Post-option initialisation
3487c478bd9Sstevel@tonic-gate 	 */
3497c478bd9Sstevel@tonic-gate 	if (disk_caching) {
3507c478bd9Sstevel@tonic-gate 		int i;
3517c478bd9Sstevel@tonic-gate 		for (i = 0; mechs[i]; i++) {
3527c478bd9Sstevel@tonic-gate 			if ((AUTH_DES_COMPAT_CHK(mechs[i])) ||
3537c478bd9Sstevel@tonic-gate 			    (mechs[i]->keylen < 0) || (mechs[i]->algtype < 0))
3547c478bd9Sstevel@tonic-gate 				continue;
3557c478bd9Sstevel@tonic-gate 			create_cache_file(mechs[i]->keylen, mechs[i]->algtype,
3567c478bd9Sstevel@tonic-gate 				cache_size[i] ? cache_size[i] : default_cache);
3577c478bd9Sstevel@tonic-gate 		}
3587c478bd9Sstevel@tonic-gate 	}
3597c478bd9Sstevel@tonic-gate 	getrootkey(&masterkey, nflag);
3607c478bd9Sstevel@tonic-gate 
3617c478bd9Sstevel@tonic-gate 	/*
3627c478bd9Sstevel@tonic-gate 	 * Set MT mode
3637c478bd9Sstevel@tonic-gate 	 */
3647c478bd9Sstevel@tonic-gate 	if (nthreads > 0) {
3657c478bd9Sstevel@tonic-gate 		(void) rpc_control(RPC_SVC_MTMODE_SET, &mode);
3667c478bd9Sstevel@tonic-gate 		(void) rpc_control(RPC_SVC_THRMAX_SET, &nthreads);
3677c478bd9Sstevel@tonic-gate 	}
3687c478bd9Sstevel@tonic-gate 
3697c478bd9Sstevel@tonic-gate 	/*
3707c478bd9Sstevel@tonic-gate 	 * Enable non-blocking mode and maximum record size checks for
3717c478bd9Sstevel@tonic-gate 	 * connection oriented transports.
3727c478bd9Sstevel@tonic-gate 	 */
3737c478bd9Sstevel@tonic-gate 	if (!rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrecsz)) {
3747c478bd9Sstevel@tonic-gate 		syslog(LOG_INFO, "unable to set max RPC record size");
3757c478bd9Sstevel@tonic-gate 	}
3767c478bd9Sstevel@tonic-gate 
3777c478bd9Sstevel@tonic-gate 	if (svc_create_local_service(keyprogram, KEY_PROG, KEY_VERS,
3787c478bd9Sstevel@tonic-gate 		"netpath", "keyserv") == 0) {
3797c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR,
3807c478bd9Sstevel@tonic-gate 			"%s: unable to create service for version %d\n",
3817c478bd9Sstevel@tonic-gate 			argv[0], KEY_VERS);
3827c478bd9Sstevel@tonic-gate 		exit(1);
3837c478bd9Sstevel@tonic-gate 	}
3847c478bd9Sstevel@tonic-gate 
3857c478bd9Sstevel@tonic-gate 	if (svc_create_local_service(keyprogram, KEY_PROG, KEY_VERS2,
3867c478bd9Sstevel@tonic-gate 		"netpath", "keyserv") == 0) {
3877c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR,
3887c478bd9Sstevel@tonic-gate 			"%s: unable to create service for version %d\n",
3897c478bd9Sstevel@tonic-gate 			argv[0], KEY_VERS2);
3907c478bd9Sstevel@tonic-gate 		exit(1);
3917c478bd9Sstevel@tonic-gate 	}
3927c478bd9Sstevel@tonic-gate 
3937c478bd9Sstevel@tonic-gate 	if (svc_create_local_service(keyprogram, KEY_PROG, KEY_VERS3,
3947c478bd9Sstevel@tonic-gate 		"netpath", "keyserv") == 0) {
3957c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR,
3967c478bd9Sstevel@tonic-gate 			"%s: unable to create service for version %d\n",
3977c478bd9Sstevel@tonic-gate 			argv[0], KEY_VERS3);
3987c478bd9Sstevel@tonic-gate 		exit(1);
3997c478bd9Sstevel@tonic-gate 	}
4007c478bd9Sstevel@tonic-gate 
4017c478bd9Sstevel@tonic-gate 	if (!debugging) {
4027c478bd9Sstevel@tonic-gate 		detachfromtty();
4037c478bd9Sstevel@tonic-gate 	}
4047c478bd9Sstevel@tonic-gate 
4057c478bd9Sstevel@tonic-gate 	if (svc_create(keyprogram, KEY_PROG, KEY_VERS, "door") == 0) {
4067c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR,
4077c478bd9Sstevel@tonic-gate 		"%s: unable to create service over doors for version %d\n",
4087c478bd9Sstevel@tonic-gate 			argv[0], KEY_VERS);
4097c478bd9Sstevel@tonic-gate 		exit(1);
4107c478bd9Sstevel@tonic-gate 	}
4117c478bd9Sstevel@tonic-gate 
4127c478bd9Sstevel@tonic-gate 	if (svc_create(keyprogram, KEY_PROG, KEY_VERS2, "door") == 0) {
4137c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR,
4147c478bd9Sstevel@tonic-gate 		"%s: unable to create service over doors for version %d\n",
4157c478bd9Sstevel@tonic-gate 			argv[0], KEY_VERS2);
4167c478bd9Sstevel@tonic-gate 		exit(1);
4177c478bd9Sstevel@tonic-gate 	}
4187c478bd9Sstevel@tonic-gate 
4197c478bd9Sstevel@tonic-gate 	if (svc_create(keyprogram, KEY_PROG, KEY_VERS3, "door") == 0) {
4207c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR,
4217c478bd9Sstevel@tonic-gate 		"%s: unable to create service over doors for version %d\n",
4227c478bd9Sstevel@tonic-gate 			argv[0], KEY_VERS3);
4237c478bd9Sstevel@tonic-gate 		exit(1);
4247c478bd9Sstevel@tonic-gate 	}
4257c478bd9Sstevel@tonic-gate 
4267c478bd9Sstevel@tonic-gate 	svc_run();
4277c478bd9Sstevel@tonic-gate 	abort();
4287c478bd9Sstevel@tonic-gate 	/* NOTREACHED */
4297c478bd9Sstevel@tonic-gate 	return (0);
4307c478bd9Sstevel@tonic-gate }
4317c478bd9Sstevel@tonic-gate 
4327c478bd9Sstevel@tonic-gate 
4337c478bd9Sstevel@tonic-gate /*
4347c478bd9Sstevel@tonic-gate  * In the event that we don't get a root password, we try to
4357c478bd9Sstevel@tonic-gate  * randomize the master key the best we can
4367c478bd9Sstevel@tonic-gate  */
4377c478bd9Sstevel@tonic-gate static void
4387c478bd9Sstevel@tonic-gate randomize(master)
4397c478bd9Sstevel@tonic-gate 	des_block *master;
4407c478bd9Sstevel@tonic-gate {
4417c478bd9Sstevel@tonic-gate 	int i;
4427c478bd9Sstevel@tonic-gate 	int seed;
4437c478bd9Sstevel@tonic-gate 	struct timeval tv;
4447c478bd9Sstevel@tonic-gate 	int shift;
4457c478bd9Sstevel@tonic-gate 
4467c478bd9Sstevel@tonic-gate 	seed = 0;
4477c478bd9Sstevel@tonic-gate 	for (i = 0; i < 1024; i++) {
4487c478bd9Sstevel@tonic-gate 		(void) gettimeofday(&tv, (struct timezone *)NULL);
4497c478bd9Sstevel@tonic-gate 		shift = i % 8 * sizeof (int);
4507c478bd9Sstevel@tonic-gate 		seed ^= (tv.tv_usec << shift) | (tv.tv_usec >> (32 - shift));
4517c478bd9Sstevel@tonic-gate 	}
4527c478bd9Sstevel@tonic-gate #ifdef KEYSERV_RANDOM
4537c478bd9Sstevel@tonic-gate 	srandom(seed);
4547c478bd9Sstevel@tonic-gate 	master->key.low = random();
4557c478bd9Sstevel@tonic-gate 	master->key.high = random();
4567c478bd9Sstevel@tonic-gate 	srandom(seed);
4577c478bd9Sstevel@tonic-gate #else
4587c478bd9Sstevel@tonic-gate 	/* use stupid dangerous bad rand() */
4597c478bd9Sstevel@tonic-gate 	srand(seed);
4607c478bd9Sstevel@tonic-gate 	master->key.low = rand();
4617c478bd9Sstevel@tonic-gate 	master->key.high = rand();
4627c478bd9Sstevel@tonic-gate 	srand(seed);
4637c478bd9Sstevel@tonic-gate #endif
4647c478bd9Sstevel@tonic-gate }
4657c478bd9Sstevel@tonic-gate 
4667c478bd9Sstevel@tonic-gate static char *
4677c478bd9Sstevel@tonic-gate fgets_ignorenul(char *s, int n, FILE *stream)
4687c478bd9Sstevel@tonic-gate {
4697c478bd9Sstevel@tonic-gate 	int fildes = fileno(stream);
4707c478bd9Sstevel@tonic-gate 	int i = 0;
4717c478bd9Sstevel@tonic-gate 	int rs = 0;
4727c478bd9Sstevel@tonic-gate 	char c;
4737c478bd9Sstevel@tonic-gate 
4747c478bd9Sstevel@tonic-gate 	if (fildes < 0)
4757c478bd9Sstevel@tonic-gate 		return (NULL);
4767c478bd9Sstevel@tonic-gate 
4777c478bd9Sstevel@tonic-gate 	while (i < n - 1) {
4787c478bd9Sstevel@tonic-gate 		rs = read(fildes, &c, 1);
4797c478bd9Sstevel@tonic-gate 		switch (rs) {
4807c478bd9Sstevel@tonic-gate 		case 1:
4817c478bd9Sstevel@tonic-gate 			break;
4827c478bd9Sstevel@tonic-gate 		case 0:
4837c478bd9Sstevel@tonic-gate 			/* EOF */
4847c478bd9Sstevel@tonic-gate 			if (i > 0)
4857c478bd9Sstevel@tonic-gate 				s[i] = '\0';
4867c478bd9Sstevel@tonic-gate 			return (NULL);
4877c478bd9Sstevel@tonic-gate 			break;
4887c478bd9Sstevel@tonic-gate 		default:
4897c478bd9Sstevel@tonic-gate 			return (NULL);
4907c478bd9Sstevel@tonic-gate 		}
4917c478bd9Sstevel@tonic-gate 		switch (c) {
4927c478bd9Sstevel@tonic-gate 		case '\0':
4937c478bd9Sstevel@tonic-gate 			break;
4947c478bd9Sstevel@tonic-gate 		case '\n':
4957c478bd9Sstevel@tonic-gate 			s[i] = c;
4967c478bd9Sstevel@tonic-gate 			s[++i] = '\0';
4977c478bd9Sstevel@tonic-gate 			return (s);
4987c478bd9Sstevel@tonic-gate 		default:
4997c478bd9Sstevel@tonic-gate 		if (c != '\0')
5007c478bd9Sstevel@tonic-gate 			s[i++] = c;
5017c478bd9Sstevel@tonic-gate 		}
5027c478bd9Sstevel@tonic-gate 	}
5037c478bd9Sstevel@tonic-gate 	s[i] = '\0';
5047c478bd9Sstevel@tonic-gate 	return (s);
5057c478bd9Sstevel@tonic-gate }
5067c478bd9Sstevel@tonic-gate 
5077c478bd9Sstevel@tonic-gate /* Should last until 16384-bit DH keys */
5087c478bd9Sstevel@tonic-gate #define	MAXROOTKEY_LINE_LEN	4224
5097c478bd9Sstevel@tonic-gate #define	MAXROOTKEY_LEN		4096
5107c478bd9Sstevel@tonic-gate #define	ROOTKEY_FILE		"/etc/.rootkey"
5117c478bd9Sstevel@tonic-gate 
5127c478bd9Sstevel@tonic-gate static int
5137c478bd9Sstevel@tonic-gate getotherrootkeys(char *name)
5147c478bd9Sstevel@tonic-gate {
5157c478bd9Sstevel@tonic-gate 	FILE		*rootkey;
5167c478bd9Sstevel@tonic-gate 	char		line[MAXROOTKEY_LINE_LEN];
5177c478bd9Sstevel@tonic-gate 	char		key[MAXROOTKEY_LEN];
5187c478bd9Sstevel@tonic-gate 	algtype_t	algtype;
5197c478bd9Sstevel@tonic-gate 	int		count = 0;
5207c478bd9Sstevel@tonic-gate 
5217c478bd9Sstevel@tonic-gate 	if (!(rootkey = fopen(ROOTKEY, "r")))
5227c478bd9Sstevel@tonic-gate 		return (0);
5237c478bd9Sstevel@tonic-gate 
5247c478bd9Sstevel@tonic-gate 	while (fgets_ignorenul(line, MAXROOTKEY_LINE_LEN, rootkey)) {
5257c478bd9Sstevel@tonic-gate 		debug(KEYSERV_DEBUG0, ("ROOTKEY %d: %s\n", count, line));
5267c478bd9Sstevel@tonic-gate 		count++;
527a0368f78Speteh 		if (sscanf(line, "%s %d", key, &algtype) < 2) {
528a0368f78Speteh 			/*
529a0368f78Speteh 			 * No encryption algorithm found in the file
530a0368f78Speteh 			 * (algtype) so default to DES.
531a0368f78Speteh 			 */
532a0368f78Speteh 			algtype = AUTH_DES_ALGTYPE;
533a0368f78Speteh 		}
5347c478bd9Sstevel@tonic-gate 		if (!strlen(key))
5357c478bd9Sstevel@tonic-gate 			continue;
5367c478bd9Sstevel@tonic-gate 		addmasterkey(key, name, algtype);
5377c478bd9Sstevel@tonic-gate 	}
5387c478bd9Sstevel@tonic-gate 	fclose(rootkey);
5397c478bd9Sstevel@tonic-gate 	return (1);
5407c478bd9Sstevel@tonic-gate }
5417c478bd9Sstevel@tonic-gate 
5427c478bd9Sstevel@tonic-gate /*
5437c478bd9Sstevel@tonic-gate  * Try to get root's secret key, by prompting if terminal is a tty, else trying
5447c478bd9Sstevel@tonic-gate  * from standard input.
5457c478bd9Sstevel@tonic-gate  * Returns 1 on success.
5467c478bd9Sstevel@tonic-gate  */
54749e7ca49Speteh static int
5487c478bd9Sstevel@tonic-gate getrootkey(master, prompt)
5497c478bd9Sstevel@tonic-gate 	des_block *master;
5507c478bd9Sstevel@tonic-gate 	int prompt;
5517c478bd9Sstevel@tonic-gate {
5527c478bd9Sstevel@tonic-gate 	char *passwd;
5537c478bd9Sstevel@tonic-gate 	char name[MAXNETNAMELEN + 1];
5547c478bd9Sstevel@tonic-gate 	char secret[HEXKEYBYTES + 1];
5557c478bd9Sstevel@tonic-gate 	FILE *fp;
5567c478bd9Sstevel@tonic-gate 	int passwd2des();
5577c478bd9Sstevel@tonic-gate 	int retval;
5587c478bd9Sstevel@tonic-gate 
5597c478bd9Sstevel@tonic-gate 	randomize(master);
5607c478bd9Sstevel@tonic-gate 	if (!getnetname(name)) {
5617c478bd9Sstevel@tonic-gate 	    (void) fprintf(stderr, "keyserv: \
5627c478bd9Sstevel@tonic-gate failed to generate host's netname when establishing root's key.\n");
5637c478bd9Sstevel@tonic-gate 	    return (0);
5647c478bd9Sstevel@tonic-gate 	}
5657c478bd9Sstevel@tonic-gate 	if (!prompt) {
5667c478bd9Sstevel@tonic-gate 		return (getotherrootkeys(name));
5677c478bd9Sstevel@tonic-gate 	}
5687c478bd9Sstevel@tonic-gate 	/*
5697c478bd9Sstevel@tonic-gate 	 * Decrypt yellow pages publickey entry to get secret key
5707c478bd9Sstevel@tonic-gate 	 */
5717c478bd9Sstevel@tonic-gate 	passwd = getpass("root password:");
5727c478bd9Sstevel@tonic-gate 	passwd2des(passwd, master);
5737c478bd9Sstevel@tonic-gate 	if (!getsecretkey(name, secret, passwd)) {
5747c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
5757c478bd9Sstevel@tonic-gate 		"Can't find %s's secret key\n", name);
5767c478bd9Sstevel@tonic-gate 		return (0);
5777c478bd9Sstevel@tonic-gate 	}
5787c478bd9Sstevel@tonic-gate 	if (secret[0] == 0) {
5797c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
5807c478bd9Sstevel@tonic-gate 	"Password does not decrypt secret key for %s\n", name);
5817c478bd9Sstevel@tonic-gate 		return (0);
5827c478bd9Sstevel@tonic-gate 	}
5837c478bd9Sstevel@tonic-gate 	if ((fp = fopen(ROOTKEY, "w")) == NULL) {
5847c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
5857c478bd9Sstevel@tonic-gate 			"Cannot open %s for write\n", ROOTKEY);
5867c478bd9Sstevel@tonic-gate 		return (0);
5877c478bd9Sstevel@tonic-gate 	}
5887c478bd9Sstevel@tonic-gate 	retval = storeotherrootkeys(fp, name, passwd, secret);
5897c478bd9Sstevel@tonic-gate 	fclose(fp);
5907c478bd9Sstevel@tonic-gate 	return (retval);
5917c478bd9Sstevel@tonic-gate }
5927c478bd9Sstevel@tonic-gate 
5937c478bd9Sstevel@tonic-gate /*
5947c478bd9Sstevel@tonic-gate  * Procedures to implement RPC service.  These procedures are named
5957c478bd9Sstevel@tonic-gate  * differently from the definitions in key_prot.h (generated by rpcgen)
5967c478bd9Sstevel@tonic-gate  * because they take different arguments.
5977c478bd9Sstevel@tonic-gate  */
5987c478bd9Sstevel@tonic-gate char *
5997c478bd9Sstevel@tonic-gate strstatus(status)
6007c478bd9Sstevel@tonic-gate 	keystatus status;
6017c478bd9Sstevel@tonic-gate {
6027c478bd9Sstevel@tonic-gate 	switch (status) {
6037c478bd9Sstevel@tonic-gate 	case KEY_SUCCESS:
6047c478bd9Sstevel@tonic-gate 		return ("KEY_SUCCESS");
6057c478bd9Sstevel@tonic-gate 	case KEY_NOSECRET:
6067c478bd9Sstevel@tonic-gate 		return ("KEY_NOSECRET");
6077c478bd9Sstevel@tonic-gate 	case KEY_UNKNOWN:
6087c478bd9Sstevel@tonic-gate 		return ("KEY_UNKNOWN");
6097c478bd9Sstevel@tonic-gate 	case KEY_SYSTEMERR:
6107c478bd9Sstevel@tonic-gate 		return ("KEY_SYSTEMERR");
6117c478bd9Sstevel@tonic-gate 	case KEY_BADALG:
6127c478bd9Sstevel@tonic-gate 		return ("KEY_BADALG");
6137c478bd9Sstevel@tonic-gate 	case KEY_BADLEN:
6147c478bd9Sstevel@tonic-gate 		return ("KEY_BADLEN");
6157c478bd9Sstevel@tonic-gate 	default:
6167c478bd9Sstevel@tonic-gate 		return ("(bad result code)");
6177c478bd9Sstevel@tonic-gate 	}
6187c478bd9Sstevel@tonic-gate }
6197c478bd9Sstevel@tonic-gate 
6207c478bd9Sstevel@tonic-gate bool_t
6217c478bd9Sstevel@tonic-gate __key_set_1_svc(uid, key, status)
6227c478bd9Sstevel@tonic-gate 	uid_t uid;
6237c478bd9Sstevel@tonic-gate 	keybuf key;
6247c478bd9Sstevel@tonic-gate 	keystatus *status;
6257c478bd9Sstevel@tonic-gate {
6267c478bd9Sstevel@tonic-gate 	if (debugging) {
6277c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "set(%d, %.*s) = ", uid,
6287c478bd9Sstevel@tonic-gate 				sizeof (keybuf), key);
6297c478bd9Sstevel@tonic-gate 	}
6307c478bd9Sstevel@tonic-gate 	*status = pk_setkey(uid, key);
6317c478bd9Sstevel@tonic-gate 	if (debugging) {
6327c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "%s\n", strstatus(*status));
6337c478bd9Sstevel@tonic-gate 		(void) fflush(stderr);
6347c478bd9Sstevel@tonic-gate 	}
6357c478bd9Sstevel@tonic-gate 	return (TRUE);
6367c478bd9Sstevel@tonic-gate }
6377c478bd9Sstevel@tonic-gate 
6387c478bd9Sstevel@tonic-gate bool_t
6397c478bd9Sstevel@tonic-gate __key_encrypt_pk_2_svc(uid, arg, res)
6407c478bd9Sstevel@tonic-gate 	uid_t uid;
6417c478bd9Sstevel@tonic-gate 	cryptkeyarg2 *arg;
6427c478bd9Sstevel@tonic-gate 	cryptkeyres *res;
6437c478bd9Sstevel@tonic-gate {
6447c478bd9Sstevel@tonic-gate 
6457c478bd9Sstevel@tonic-gate 	if (debugging) {
6467c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "encrypt(%d, %s, %08x%08x) = ", uid,
6477c478bd9Sstevel@tonic-gate 				arg->remotename, arg->deskey.key.high,
6487c478bd9Sstevel@tonic-gate 				arg->deskey.key.low);
6497c478bd9Sstevel@tonic-gate 	}
6507c478bd9Sstevel@tonic-gate 	res->cryptkeyres_u.deskey = arg->deskey;
6517c478bd9Sstevel@tonic-gate 	res->status = pk_encrypt(uid, arg->remotename, &(arg->remotekey),
6527c478bd9Sstevel@tonic-gate 				&res->cryptkeyres_u.deskey);
6537c478bd9Sstevel@tonic-gate 	if (debugging) {
6547c478bd9Sstevel@tonic-gate 		if (res->status == KEY_SUCCESS) {
6557c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "%08x%08x\n",
6567c478bd9Sstevel@tonic-gate 					res->cryptkeyres_u.deskey.key.high,
6577c478bd9Sstevel@tonic-gate 					res->cryptkeyres_u.deskey.key.low);
6587c478bd9Sstevel@tonic-gate 		} else {
6597c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "%s\n", strstatus(res->status));
6607c478bd9Sstevel@tonic-gate 		}
6617c478bd9Sstevel@tonic-gate 		(void) fflush(stderr);
6627c478bd9Sstevel@tonic-gate 	}
6637c478bd9Sstevel@tonic-gate 	return (TRUE);
6647c478bd9Sstevel@tonic-gate }
6657c478bd9Sstevel@tonic-gate 
6667c478bd9Sstevel@tonic-gate bool_t
6677c478bd9Sstevel@tonic-gate __key_decrypt_pk_2_svc(uid, arg, res)
6687c478bd9Sstevel@tonic-gate 	uid_t uid;
6697c478bd9Sstevel@tonic-gate 	cryptkeyarg2 *arg;
6707c478bd9Sstevel@tonic-gate 	cryptkeyres *res;
6717c478bd9Sstevel@tonic-gate {
6727c478bd9Sstevel@tonic-gate 
6737c478bd9Sstevel@tonic-gate 	if (debugging) {
6747c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "decrypt(%d, %s, %08x%08x) = ", uid,
6757c478bd9Sstevel@tonic-gate 				arg->remotename, arg->deskey.key.high,
6767c478bd9Sstevel@tonic-gate 				arg->deskey.key.low);
6777c478bd9Sstevel@tonic-gate 	}
6787c478bd9Sstevel@tonic-gate 	res->cryptkeyres_u.deskey = arg->deskey;
6797c478bd9Sstevel@tonic-gate 	res->status = pk_decrypt(uid, arg->remotename, &(arg->remotekey),
6807c478bd9Sstevel@tonic-gate 				&res->cryptkeyres_u.deskey);
6817c478bd9Sstevel@tonic-gate 	if (debugging) {
6827c478bd9Sstevel@tonic-gate 		if (res->status == KEY_SUCCESS) {
6837c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "%08x%08x\n",
6847c478bd9Sstevel@tonic-gate 					res->cryptkeyres_u.deskey.key.high,
6857c478bd9Sstevel@tonic-gate 					res->cryptkeyres_u.deskey.key.low);
6867c478bd9Sstevel@tonic-gate 		} else {
6877c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "%s\n", strstatus(res->status));
6887c478bd9Sstevel@tonic-gate 		}
6897c478bd9Sstevel@tonic-gate 		(void) fflush(stderr);
6907c478bd9Sstevel@tonic-gate 	}
6917c478bd9Sstevel@tonic-gate 	return (TRUE);
6927c478bd9Sstevel@tonic-gate }
6937c478bd9Sstevel@tonic-gate 
6947c478bd9Sstevel@tonic-gate bool_t
6957c478bd9Sstevel@tonic-gate __key_net_put_2_svc(uid, arg, status)
6967c478bd9Sstevel@tonic-gate 	uid_t uid;
6977c478bd9Sstevel@tonic-gate 	key_netstarg *arg;
6987c478bd9Sstevel@tonic-gate 	keystatus *status;
6997c478bd9Sstevel@tonic-gate {
7007c478bd9Sstevel@tonic-gate 
7017c478bd9Sstevel@tonic-gate 	if (debugging) {
7027c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "net_put(%s, %.*s, %.*s) = ",
7037c478bd9Sstevel@tonic-gate 			arg->st_netname, sizeof (arg->st_pub_key),
7047c478bd9Sstevel@tonic-gate 			arg->st_pub_key, sizeof (arg->st_priv_key),
7057c478bd9Sstevel@tonic-gate 			arg->st_priv_key);
7067c478bd9Sstevel@tonic-gate 	};
7077c478bd9Sstevel@tonic-gate 
7087c478bd9Sstevel@tonic-gate 	*status = pk_netput(uid, arg);
7097c478bd9Sstevel@tonic-gate 
7107c478bd9Sstevel@tonic-gate 	if (debugging) {
7117c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "%s\n", strstatus(*status));
7127c478bd9Sstevel@tonic-gate 		(void) fflush(stderr);
7137c478bd9Sstevel@tonic-gate 	}
7147c478bd9Sstevel@tonic-gate 
7157c478bd9Sstevel@tonic-gate 	return (TRUE);
7167c478bd9Sstevel@tonic-gate }
7177c478bd9Sstevel@tonic-gate 
7187c478bd9Sstevel@tonic-gate /* ARGSUSED */
7197c478bd9Sstevel@tonic-gate bool_t
7207c478bd9Sstevel@tonic-gate __key_net_get_2_svc(uid, arg, keynetname)
7217c478bd9Sstevel@tonic-gate 	uid_t uid;
7227c478bd9Sstevel@tonic-gate 	void *arg;
7237c478bd9Sstevel@tonic-gate 	key_netstres *keynetname;
7247c478bd9Sstevel@tonic-gate {
7257c478bd9Sstevel@tonic-gate 
7267c478bd9Sstevel@tonic-gate 	if (debugging)
7277c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "net_get(%d) = ", uid);
7287c478bd9Sstevel@tonic-gate 
7297c478bd9Sstevel@tonic-gate 	keynetname->status = pk_netget(uid, &keynetname->key_netstres_u.knet);
7307c478bd9Sstevel@tonic-gate 	if (debugging) {
7317c478bd9Sstevel@tonic-gate 		if (keynetname->status == KEY_SUCCESS) {
7327c478bd9Sstevel@tonic-gate 			fprintf(stderr, "<%s, %.*s, %.*s>\n",
7337c478bd9Sstevel@tonic-gate 			keynetname->key_netstres_u.knet.st_netname,
7347c478bd9Sstevel@tonic-gate 			sizeof (keynetname->key_netstres_u.knet.st_pub_key),
7357c478bd9Sstevel@tonic-gate 			keynetname->key_netstres_u.knet.st_pub_key,
7367c478bd9Sstevel@tonic-gate 			sizeof (keynetname->key_netstres_u.knet.st_priv_key),
7377c478bd9Sstevel@tonic-gate 			keynetname->key_netstres_u.knet.st_priv_key);
7387c478bd9Sstevel@tonic-gate 		} else {
7397c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "NOT FOUND\n");
7407c478bd9Sstevel@tonic-gate 		}
7417c478bd9Sstevel@tonic-gate 		(void) fflush(stderr);
7427c478bd9Sstevel@tonic-gate 	}
7437c478bd9Sstevel@tonic-gate 
7447c478bd9Sstevel@tonic-gate 	return (TRUE);
7457c478bd9Sstevel@tonic-gate 
7467c478bd9Sstevel@tonic-gate }
7477c478bd9Sstevel@tonic-gate 
7487c478bd9Sstevel@tonic-gate bool_t
7497c478bd9Sstevel@tonic-gate __key_get_conv_2_svc(uid, arg, res)
7507c478bd9Sstevel@tonic-gate 	uid_t uid;
7517c478bd9Sstevel@tonic-gate 	keybuf arg;
7527c478bd9Sstevel@tonic-gate 	cryptkeyres *res;
7537c478bd9Sstevel@tonic-gate {
7547c478bd9Sstevel@tonic-gate 
7557c478bd9Sstevel@tonic-gate 	if (debugging)
7567c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "get_conv(%d, %.*s) = ", uid,
7577c478bd9Sstevel@tonic-gate 			sizeof (arg), arg);
7587c478bd9Sstevel@tonic-gate 
7597c478bd9Sstevel@tonic-gate 
7607c478bd9Sstevel@tonic-gate 	res->status = pk_get_conv_key(uid, arg, res);
7617c478bd9Sstevel@tonic-gate 
7627c478bd9Sstevel@tonic-gate 	if (debugging) {
7637c478bd9Sstevel@tonic-gate 		if (res->status == KEY_SUCCESS) {
7647c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "%08x%08x\n",
7657c478bd9Sstevel@tonic-gate 				res->cryptkeyres_u.deskey.key.high,
7667c478bd9Sstevel@tonic-gate 				res->cryptkeyres_u.deskey.key.low);
7677c478bd9Sstevel@tonic-gate 		} else {
7687c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "%s\n", strstatus(res->status));
7697c478bd9Sstevel@tonic-gate 		}
7707c478bd9Sstevel@tonic-gate 		(void) fflush(stderr);
7717c478bd9Sstevel@tonic-gate 	}
7727c478bd9Sstevel@tonic-gate 	return (TRUE);
7737c478bd9Sstevel@tonic-gate }
7747c478bd9Sstevel@tonic-gate 
7757c478bd9Sstevel@tonic-gate 
7767c478bd9Sstevel@tonic-gate bool_t
7777c478bd9Sstevel@tonic-gate __key_encrypt_1_svc(uid, arg, res)
7787c478bd9Sstevel@tonic-gate 	uid_t uid;
7797c478bd9Sstevel@tonic-gate 	cryptkeyarg *arg;
7807c478bd9Sstevel@tonic-gate 	cryptkeyres *res;
7817c478bd9Sstevel@tonic-gate {
7827c478bd9Sstevel@tonic-gate 
7837c478bd9Sstevel@tonic-gate 	if (debugging) {
7847c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "encrypt(%d, %s, %08x%08x) = ", uid,
7857c478bd9Sstevel@tonic-gate 				arg->remotename, arg->deskey.key.high,
7867c478bd9Sstevel@tonic-gate 				arg->deskey.key.low);
7877c478bd9Sstevel@tonic-gate 	}
7887c478bd9Sstevel@tonic-gate 	res->cryptkeyres_u.deskey = arg->deskey;
7897c478bd9Sstevel@tonic-gate 	res->status = pk_encrypt(uid, arg->remotename, NULL,
7907c478bd9Sstevel@tonic-gate 				&res->cryptkeyres_u.deskey);
7917c478bd9Sstevel@tonic-gate 	if (debugging) {
7927c478bd9Sstevel@tonic-gate 		if (res->status == KEY_SUCCESS) {
7937c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "%08x%08x\n",
7947c478bd9Sstevel@tonic-gate 					res->cryptkeyres_u.deskey.key.high,
7957c478bd9Sstevel@tonic-gate 					res->cryptkeyres_u.deskey.key.low);
7967c478bd9Sstevel@tonic-gate 		} else {
7977c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "%s\n", strstatus(res->status));
7987c478bd9Sstevel@tonic-gate 		}
7997c478bd9Sstevel@tonic-gate 		(void) fflush(stderr);
8007c478bd9Sstevel@tonic-gate 	}
8017c478bd9Sstevel@tonic-gate 	return (TRUE);
8027c478bd9Sstevel@tonic-gate }
8037c478bd9Sstevel@tonic-gate 
8047c478bd9Sstevel@tonic-gate bool_t
8057c478bd9Sstevel@tonic-gate __key_decrypt_1_svc(uid, arg, res)
8067c478bd9Sstevel@tonic-gate 	uid_t uid;
8077c478bd9Sstevel@tonic-gate 	cryptkeyarg *arg;
8087c478bd9Sstevel@tonic-gate 	cryptkeyres *res;
8097c478bd9Sstevel@tonic-gate {
8107c478bd9Sstevel@tonic-gate 	if (debugging) {
8117c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "decrypt(%d, %s, %08x%08x) = ", uid,
8127c478bd9Sstevel@tonic-gate 				arg->remotename, arg->deskey.key.high,
8137c478bd9Sstevel@tonic-gate 				arg->deskey.key.low);
8147c478bd9Sstevel@tonic-gate 	}
8157c478bd9Sstevel@tonic-gate 	res->cryptkeyres_u.deskey = arg->deskey;
8167c478bd9Sstevel@tonic-gate 	res->status = pk_decrypt(uid, arg->remotename, NULL,
8177c478bd9Sstevel@tonic-gate 				&res->cryptkeyres_u.deskey);
8187c478bd9Sstevel@tonic-gate 	if (debugging) {
8197c478bd9Sstevel@tonic-gate 		if (res->status == KEY_SUCCESS) {
8207c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "%08x%08x\n",
8217c478bd9Sstevel@tonic-gate 					res->cryptkeyres_u.deskey.key.high,
8227c478bd9Sstevel@tonic-gate 					res->cryptkeyres_u.deskey.key.low);
8237c478bd9Sstevel@tonic-gate 		} else {
8247c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "%s\n", strstatus(res->status));
8257c478bd9Sstevel@tonic-gate 		}
8267c478bd9Sstevel@tonic-gate 		(void) fflush(stderr);
8277c478bd9Sstevel@tonic-gate 	}
8287c478bd9Sstevel@tonic-gate 	return (TRUE);
8297c478bd9Sstevel@tonic-gate }
8307c478bd9Sstevel@tonic-gate 
8317c478bd9Sstevel@tonic-gate /* ARGSUSED */
8327c478bd9Sstevel@tonic-gate bool_t
8337c478bd9Sstevel@tonic-gate __key_gen_1_svc(v, s, key)
8347c478bd9Sstevel@tonic-gate 	void *v;
8357c478bd9Sstevel@tonic-gate 	struct svc_req *s;
8367c478bd9Sstevel@tonic-gate 	des_block *key;
8377c478bd9Sstevel@tonic-gate {
8387c478bd9Sstevel@tonic-gate 	struct timeval time;
8397c478bd9Sstevel@tonic-gate 	static des_block keygen;
8407c478bd9Sstevel@tonic-gate 	static mutex_t keygen_mutex = DEFAULTMUTEX;
8417c478bd9Sstevel@tonic-gate 	int r;
8427c478bd9Sstevel@tonic-gate 
8437c478bd9Sstevel@tonic-gate 	(void) gettimeofday(&time, (struct timezone *)NULL);
8447c478bd9Sstevel@tonic-gate 	(void) mutex_lock(&keygen_mutex);
8457c478bd9Sstevel@tonic-gate 	keygen.key.high += (time.tv_sec ^ time.tv_usec);
8467c478bd9Sstevel@tonic-gate 	keygen.key.low += (time.tv_sec ^ time.tv_usec);
8477c478bd9Sstevel@tonic-gate 	r = ecb_crypt((char *)&masterkey, (char *)&keygen, sizeof (keygen),
8487c478bd9Sstevel@tonic-gate 		DES_ENCRYPT | DES_HW);
8497c478bd9Sstevel@tonic-gate 	if (r != DESERR_NONE && r != DESERR_NOHWDEVICE) {
8507c478bd9Sstevel@tonic-gate 		mutex_unlock(&keygen_mutex);
8517c478bd9Sstevel@tonic-gate 		return (FALSE);
8527c478bd9Sstevel@tonic-gate 	}
8537c478bd9Sstevel@tonic-gate 	*key = keygen;
8547c478bd9Sstevel@tonic-gate 	mutex_unlock(&keygen_mutex);
8557c478bd9Sstevel@tonic-gate 
8567c478bd9Sstevel@tonic-gate 	des_setparity_g(key);
8577c478bd9Sstevel@tonic-gate 	if (debugging) {
8587c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "gen() = %08x%08x\n", key->key.high,
8597c478bd9Sstevel@tonic-gate 					key->key.low);
8607c478bd9Sstevel@tonic-gate 		(void) fflush(stderr);
8617c478bd9Sstevel@tonic-gate 	}
8627c478bd9Sstevel@tonic-gate 	return (TRUE);
8637c478bd9Sstevel@tonic-gate }
8647c478bd9Sstevel@tonic-gate 
8657c478bd9Sstevel@tonic-gate /* ARGSUSED */
8667c478bd9Sstevel@tonic-gate bool_t
8677c478bd9Sstevel@tonic-gate __key_getcred_1_svc(uid, name, res)
8687c478bd9Sstevel@tonic-gate 	uid_t uid;
8697c478bd9Sstevel@tonic-gate 	netnamestr *name;
8707c478bd9Sstevel@tonic-gate 	getcredres *res;
8717c478bd9Sstevel@tonic-gate {
8727c478bd9Sstevel@tonic-gate 	struct unixcred *cred;
8737c478bd9Sstevel@tonic-gate 
8747c478bd9Sstevel@tonic-gate 	cred = &res->getcredres_u.cred;
8757c478bd9Sstevel@tonic-gate 	if (!netname2user(*name, (uid_t *)&cred->uid, (gid_t *)&cred->gid,
8767c478bd9Sstevel@tonic-gate 			(int *)&cred->gids.gids_len,
8777c478bd9Sstevel@tonic-gate 					(gid_t *)cred->gids.gids_val)) {
8787c478bd9Sstevel@tonic-gate 		res->status = KEY_UNKNOWN;
8797c478bd9Sstevel@tonic-gate 	} else {
8807c478bd9Sstevel@tonic-gate 		res->status = KEY_SUCCESS;
8817c478bd9Sstevel@tonic-gate 	}
8827c478bd9Sstevel@tonic-gate 	if (debugging) {
8837c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "getcred(%s) = ", *name);
8847c478bd9Sstevel@tonic-gate 		if (res->status == KEY_SUCCESS) {
8857c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "uid=%d, gid=%d, grouplen=%d\n",
8867c478bd9Sstevel@tonic-gate 				cred->uid, cred->gid, cred->gids.gids_len);
8877c478bd9Sstevel@tonic-gate 		} else {
8887c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "%s\n", strstatus(res->status));
8897c478bd9Sstevel@tonic-gate 		}
8907c478bd9Sstevel@tonic-gate 		(void) fflush(stderr);
8917c478bd9Sstevel@tonic-gate 	}
8927c478bd9Sstevel@tonic-gate 	return (TRUE);
8937c478bd9Sstevel@tonic-gate }
8947c478bd9Sstevel@tonic-gate 
8957c478bd9Sstevel@tonic-gate /*
8967c478bd9Sstevel@tonic-gate  * Version 3 procedures follow...
8977c478bd9Sstevel@tonic-gate  */
8987c478bd9Sstevel@tonic-gate 
8997c478bd9Sstevel@tonic-gate static bool_t
9007c478bd9Sstevel@tonic-gate __key_set_3_svc(uid_t uid, setkeyarg3 *arg, keystatus *status)
9017c478bd9Sstevel@tonic-gate {
9027c478bd9Sstevel@tonic-gate 	debug(KEYSERV_DEBUG, ("__key_set_3_svc(%d, %d, %d)",
9037c478bd9Sstevel@tonic-gate 		uid, arg->algtype, arg->keylen));
9047c478bd9Sstevel@tonic-gate 	*status = pk_setkey3(uid, arg);
9057c478bd9Sstevel@tonic-gate 	debug(KEYSERV_DEBUG, ("__key_set_3_svc %s", strstatus(*status)));
9067c478bd9Sstevel@tonic-gate 	return (TRUE);
9077c478bd9Sstevel@tonic-gate }
9087c478bd9Sstevel@tonic-gate 
9097c478bd9Sstevel@tonic-gate static bool_t
9107c478bd9Sstevel@tonic-gate __key_encrypt_3_svc(uid_t uid, cryptkeyarg3 *arg, cryptkeyres3 *res)
9117c478bd9Sstevel@tonic-gate {
9127c478bd9Sstevel@tonic-gate 	int len, i;
9137c478bd9Sstevel@tonic-gate 	des_block *dp;
9147c478bd9Sstevel@tonic-gate 
9157c478bd9Sstevel@tonic-gate 	debug(KEYSERV_DEBUG, ("encrypt_3(%d %d %s)", uid,
9167c478bd9Sstevel@tonic-gate 		arg->deskey.deskeyarray_len, arg->remotename));
9177c478bd9Sstevel@tonic-gate 	res->status = pk_encrypt3(uid, arg, &res->cryptkeyres3_u.deskey);
9187c478bd9Sstevel@tonic-gate 	len = res->cryptkeyres3_u.deskey.deskeyarray_len;
9197c478bd9Sstevel@tonic-gate 	dp = res->cryptkeyres3_u.deskey.deskeyarray_val;
9207c478bd9Sstevel@tonic-gate 	for (i = 0; i < len; i++) {
9217c478bd9Sstevel@tonic-gate 		debug(KEYSERV_DEBUG0, ("encrypt_3 retval[%d] == (%x,%x)",
9227c478bd9Sstevel@tonic-gate 			i, dp->key.high, dp->key.low));
9237c478bd9Sstevel@tonic-gate 		dp++;
9247c478bd9Sstevel@tonic-gate 	}
9257c478bd9Sstevel@tonic-gate 	debug(KEYSERV_DEBUG, ("encrypt_3 returned %s", strstatus(res->status)));
9267c478bd9Sstevel@tonic-gate 	return (TRUE);
9277c478bd9Sstevel@tonic-gate }
9287c478bd9Sstevel@tonic-gate 
9297c478bd9Sstevel@tonic-gate static bool_t
9307c478bd9Sstevel@tonic-gate __key_decrypt_3_svc(uid_t uid, cryptkeyarg3 *arg, cryptkeyres3 *res)
9317c478bd9Sstevel@tonic-gate {
9327c478bd9Sstevel@tonic-gate 	int len, i;
9337c478bd9Sstevel@tonic-gate 	des_block *dp;
9347c478bd9Sstevel@tonic-gate 
9357c478bd9Sstevel@tonic-gate 	debug(KEYSERV_DEBUG, ("decrypt_3(%d, %d, %s)", uid,
9367c478bd9Sstevel@tonic-gate 		arg->deskey.deskeyarray_len, arg->remotename));
9377c478bd9Sstevel@tonic-gate 	res->status = pk_decrypt3(uid, arg, &res->cryptkeyres3_u.deskey);
9387c478bd9Sstevel@tonic-gate 	len = res->cryptkeyres3_u.deskey.deskeyarray_len;
9397c478bd9Sstevel@tonic-gate 	dp = res->cryptkeyres3_u.deskey.deskeyarray_val;
9407c478bd9Sstevel@tonic-gate 	for (i = 0; i < len; i++) {
9417c478bd9Sstevel@tonic-gate 		debug(KEYSERV_DEBUG0, ("decrypt_3 retval[%d] == (%x,%x)",
9427c478bd9Sstevel@tonic-gate 			i, dp->key.high, dp->key.low));
9437c478bd9Sstevel@tonic-gate 		dp++;
9447c478bd9Sstevel@tonic-gate 	}
9457c478bd9Sstevel@tonic-gate 	debug(KEYSERV_DEBUG, ("decrypt_3 returned %s", strstatus(res->status)));
9467c478bd9Sstevel@tonic-gate 	return (TRUE);
9477c478bd9Sstevel@tonic-gate }
9487c478bd9Sstevel@tonic-gate 
9497c478bd9Sstevel@tonic-gate /* ARGSUSED */
9507c478bd9Sstevel@tonic-gate static bool_t
9517c478bd9Sstevel@tonic-gate __key_gen_3_svc(void *v, keynum_t *kp, deskeyarray *res)
9527c478bd9Sstevel@tonic-gate {
9537c478bd9Sstevel@tonic-gate 	int i;
9547c478bd9Sstevel@tonic-gate 	keynum_t keynum = *kp;
9557c478bd9Sstevel@tonic-gate 
9567c478bd9Sstevel@tonic-gate 	debug(KEYSERV_DEBUG, ("gen_3(%d %x)", keynum, res));
9577c478bd9Sstevel@tonic-gate 	res->deskeyarray_val = 0;
9587c478bd9Sstevel@tonic-gate 	if (!setdeskeyarray(res, keynum)) {
9597c478bd9Sstevel@tonic-gate 		return (FALSE);
9607c478bd9Sstevel@tonic-gate 	}
9617c478bd9Sstevel@tonic-gate 	for (i = 0; i < keynum; i++) {
9627c478bd9Sstevel@tonic-gate 		debug(KEYSERV_DEBUG, ("gen_3 calling gen_1 %x",
9637c478bd9Sstevel@tonic-gate 			res->deskeyarray_val+i));
9647c478bd9Sstevel@tonic-gate 		__key_gen_1_svc((void *) NULL, (struct svc_req *)NULL,
9657c478bd9Sstevel@tonic-gate 			res->deskeyarray_val+i);
9667c478bd9Sstevel@tonic-gate 		debug(KEYSERV_DEBUG, ("gen_3 val %d %x",
9677c478bd9Sstevel@tonic-gate 			i, *(int *)(res->deskeyarray_val+i)));
9687c478bd9Sstevel@tonic-gate 	}
9697c478bd9Sstevel@tonic-gate 	return (TRUE);
9707c478bd9Sstevel@tonic-gate }
9717c478bd9Sstevel@tonic-gate 
9727c478bd9Sstevel@tonic-gate static void
9737c478bd9Sstevel@tonic-gate __key_gen_3_svc_free(deskeyarray *dp)
9747c478bd9Sstevel@tonic-gate {
9757c478bd9Sstevel@tonic-gate 	free(dp->deskeyarray_val);
9767c478bd9Sstevel@tonic-gate }
9777c478bd9Sstevel@tonic-gate 
9787c478bd9Sstevel@tonic-gate static bool_t
9797c478bd9Sstevel@tonic-gate __key_getcred_3_svc(uid_t uid, netnamestr *name, getcredres3 *res)
9807c478bd9Sstevel@tonic-gate {
9817c478bd9Sstevel@tonic-gate 	return (__key_getcred_1_svc(uid, name, (getcredres *)res));
9827c478bd9Sstevel@tonic-gate }
9837c478bd9Sstevel@tonic-gate 
9847c478bd9Sstevel@tonic-gate static bool_t
9857c478bd9Sstevel@tonic-gate __key_encrypt_pk_3_svc(uid_t uid, cryptkeyarg3 *arg, cryptkeyres3 *res)
9867c478bd9Sstevel@tonic-gate {
9877c478bd9Sstevel@tonic-gate 	debug(KEYSERV_DEBUG, ("encrypt_pk_3(%d, %s)", uid, arg->remotename));
9887c478bd9Sstevel@tonic-gate 	res->status = pk_encrypt3(uid, arg, &res->cryptkeyres3_u.deskey);
9897c478bd9Sstevel@tonic-gate 	debug(KEYSERV_DEBUG, ("encrypt returned %s", strstatus(res->status)));
9907c478bd9Sstevel@tonic-gate 	return (TRUE);
9917c478bd9Sstevel@tonic-gate }
9927c478bd9Sstevel@tonic-gate 
9937c478bd9Sstevel@tonic-gate static void
9947c478bd9Sstevel@tonic-gate __key_encrypt_pk_3_svc_free(cryptkeyres3 *res)
9957c478bd9Sstevel@tonic-gate {
9967c478bd9Sstevel@tonic-gate 	if (res->status == KEY_SUCCESS) {
9977c478bd9Sstevel@tonic-gate 		free(res->cryptkeyres3_u.deskey.deskeyarray_val);
9987c478bd9Sstevel@tonic-gate 	}
9997c478bd9Sstevel@tonic-gate }
10007c478bd9Sstevel@tonic-gate 
10017c478bd9Sstevel@tonic-gate static bool_t
10027c478bd9Sstevel@tonic-gate __key_decrypt_pk_3(uid_t uid, cryptkeyarg3 *arg, cryptkeyres3 *res)
10037c478bd9Sstevel@tonic-gate {
10047c478bd9Sstevel@tonic-gate 	debug(KEYSERV_DEBUG, ("decrypt_pk_3(%d, %s)", uid, arg->remotename));
10057c478bd9Sstevel@tonic-gate 	res->status = pk_decrypt3(uid, arg, &res->cryptkeyres3_u.deskey);
10067c478bd9Sstevel@tonic-gate 	debug(KEYSERV_DEBUG, ("encrypt returned %s", strstatus(res->status)));
10077c478bd9Sstevel@tonic-gate 	return (TRUE);
10087c478bd9Sstevel@tonic-gate }
10097c478bd9Sstevel@tonic-gate 
10107c478bd9Sstevel@tonic-gate static void
10117c478bd9Sstevel@tonic-gate __key_decrypt_pk_3_free(cryptkeyres3 *res)
10127c478bd9Sstevel@tonic-gate {
10137c478bd9Sstevel@tonic-gate 	if (res->status == KEY_SUCCESS) {
10147c478bd9Sstevel@tonic-gate 		free(res->cryptkeyres3_u.deskey.deskeyarray_val);
10157c478bd9Sstevel@tonic-gate 	}
10167c478bd9Sstevel@tonic-gate }
10177c478bd9Sstevel@tonic-gate 
10187c478bd9Sstevel@tonic-gate static bool_t
10197c478bd9Sstevel@tonic-gate __key_net_put_3_svc(uid_t uid, key_netstarg3 *arg, keystatus *status)
10207c478bd9Sstevel@tonic-gate {
10217c478bd9Sstevel@tonic-gate 	debug(KEYSERV_DEBUG, ("net_put_3 (%d, %x)", uid, arg));
10227c478bd9Sstevel@tonic-gate 	*status = pk_netput3(uid, arg);
10237c478bd9Sstevel@tonic-gate 	debug(KEYSERV_DEBUG, ("net_put_3 ret %s", strstatus(*status)));
10247c478bd9Sstevel@tonic-gate 	return (TRUE);
10257c478bd9Sstevel@tonic-gate }
10267c478bd9Sstevel@tonic-gate 
10277c478bd9Sstevel@tonic-gate static bool_t
10287c478bd9Sstevel@tonic-gate __key_net_get_3_svc(uid_t uid, mechtype *arg, key_netstres3 *keynetname)
10297c478bd9Sstevel@tonic-gate {
10307c478bd9Sstevel@tonic-gate 	debug(KEYSERV_DEBUG, ("net_get_3 (%d, %x)", uid, arg));
10317c478bd9Sstevel@tonic-gate 	keynetname->status = pk_netget3(uid,
10327c478bd9Sstevel@tonic-gate 		arg, &keynetname->key_netstres3_u.knet);
10337c478bd9Sstevel@tonic-gate 	debug(KEYSERV_DEBUG,
10347c478bd9Sstevel@tonic-gate 		("net_get_3 ret %s", strstatus(keynetname->status)));
10357c478bd9Sstevel@tonic-gate 	return (TRUE);
10367c478bd9Sstevel@tonic-gate }
10377c478bd9Sstevel@tonic-gate 
10387c478bd9Sstevel@tonic-gate static void
10397c478bd9Sstevel@tonic-gate __key_net_get_3_svc_free(key_netstres3 *keynetname)
10407c478bd9Sstevel@tonic-gate {
10417c478bd9Sstevel@tonic-gate 	if (keynetname->status == KEY_SUCCESS) {
10427c478bd9Sstevel@tonic-gate 		free(keynetname->key_netstres3_u.knet.st_priv_key.keybuf3_val);
10437c478bd9Sstevel@tonic-gate 		free(keynetname->key_netstres3_u.knet.st_pub_key.keybuf3_val);
10447c478bd9Sstevel@tonic-gate 		free(keynetname->key_netstres3_u.knet.st_netname);
10457c478bd9Sstevel@tonic-gate 	}
10467c478bd9Sstevel@tonic-gate }
10477c478bd9Sstevel@tonic-gate 
10487c478bd9Sstevel@tonic-gate static bool_t
10497c478bd9Sstevel@tonic-gate __key_get_conv_3_svc(uid_t uid, deskeyarg3 *arg, cryptkeyres3 *res)
10507c478bd9Sstevel@tonic-gate {
10517c478bd9Sstevel@tonic-gate 	debug(KEYSERV_DEBUG, ("get_conv_3(%d %x %x)", uid, arg, res));
10527c478bd9Sstevel@tonic-gate 	res->status = pk_get_conv_key3(uid, arg, res);
10537c478bd9Sstevel@tonic-gate 	debug(KEYSERV_DEBUG,
10547c478bd9Sstevel@tonic-gate 		("get_conv_3 ret %s", strstatus(res->status)));
10557c478bd9Sstevel@tonic-gate 	return (TRUE);
10567c478bd9Sstevel@tonic-gate }
10577c478bd9Sstevel@tonic-gate 
10587c478bd9Sstevel@tonic-gate /* ARGSUSED */
10597c478bd9Sstevel@tonic-gate static bool_t
10607c478bd9Sstevel@tonic-gate __key_clear_3_svc(uid_t uid, void *arg, keystatus *status)
10617c478bd9Sstevel@tonic-gate {
10627c478bd9Sstevel@tonic-gate 	debug(KEYSERV_DEBUG, ("clear_3(%d)", uid));
10637c478bd9Sstevel@tonic-gate 	*status = pk_clear3(uid);
10647c478bd9Sstevel@tonic-gate 	debug(KEYSERV_DEBUG, ("clear_3 ret %s", strstatus(*status)));
10657c478bd9Sstevel@tonic-gate 	return (TRUE);
10667c478bd9Sstevel@tonic-gate }
10677c478bd9Sstevel@tonic-gate 
10687c478bd9Sstevel@tonic-gate /*
10697c478bd9Sstevel@tonic-gate  * RPC boilerplate
10707c478bd9Sstevel@tonic-gate  */
10717c478bd9Sstevel@tonic-gate static void
10727c478bd9Sstevel@tonic-gate keyprogram(rqstp, transp)
10737c478bd9Sstevel@tonic-gate 	struct svc_req *rqstp;
10747c478bd9Sstevel@tonic-gate 	SVCXPRT *transp;
10757c478bd9Sstevel@tonic-gate {
10767c478bd9Sstevel@tonic-gate 	union {
10777c478bd9Sstevel@tonic-gate 		keybuf key_set_1_arg;
10787c478bd9Sstevel@tonic-gate 		cryptkeyarg key_encrypt_1_arg;
10797c478bd9Sstevel@tonic-gate 		cryptkeyarg key_decrypt_1_arg;
10807c478bd9Sstevel@tonic-gate 		netnamestr key_getcred_1_arg;
10817c478bd9Sstevel@tonic-gate 		cryptkeyarg key_encrypt_2_arg;
10827c478bd9Sstevel@tonic-gate 		cryptkeyarg key_decrypt_2_arg;
10837c478bd9Sstevel@tonic-gate 		netnamestr key_getcred_2_arg;
10847c478bd9Sstevel@tonic-gate 		cryptkeyarg2 key_encrypt_pk_2_arg;
10857c478bd9Sstevel@tonic-gate 		cryptkeyarg2 key_decrypt_pk_2_arg;
10867c478bd9Sstevel@tonic-gate 		key_netstarg key_net_put_2_arg;
10877c478bd9Sstevel@tonic-gate 		netobj  key_get_conv_2_arg;
10887c478bd9Sstevel@tonic-gate 		keybuf3 key_set_3_arg;
10897c478bd9Sstevel@tonic-gate 		cryptkeyarg3 key_encrypt_3_arg;
10907c478bd9Sstevel@tonic-gate 		cryptkeyarg3 key_decrypt_3_arg;
10917c478bd9Sstevel@tonic-gate 		cryptkeyarg3 key_encrypt_pk_3_arg;
10927c478bd9Sstevel@tonic-gate 		cryptkeyarg3 key_decrypt_pk_3_arg;
10937c478bd9Sstevel@tonic-gate 		keynum_t key_gen_3_arg;
10947c478bd9Sstevel@tonic-gate 		netnamestr key_getcred_3_arg;
10957c478bd9Sstevel@tonic-gate 		key_netstarg3 key_net_put_3_arg;
10967c478bd9Sstevel@tonic-gate 		key_netstarg3 key_net_get_3_arg;
10977c478bd9Sstevel@tonic-gate 		deskeyarg3 key_get_conv_3_arg;
10987c478bd9Sstevel@tonic-gate 	} argument;
10997c478bd9Sstevel@tonic-gate 	union {
11007c478bd9Sstevel@tonic-gate 		keystatus status;
11017c478bd9Sstevel@tonic-gate 		cryptkeyres cres;
11027c478bd9Sstevel@tonic-gate 		des_block key;
11037c478bd9Sstevel@tonic-gate 		getcredres gres;
11047c478bd9Sstevel@tonic-gate 		key_netstres keynetname;
11057c478bd9Sstevel@tonic-gate 		cryptkeyres3 cres3;
11067c478bd9Sstevel@tonic-gate 		deskeyarray keyarray;
11077c478bd9Sstevel@tonic-gate 		getcredres3 gres3;
11087c478bd9Sstevel@tonic-gate 		key_netstres3 keynetname3;
11097c478bd9Sstevel@tonic-gate 	} result;
11107c478bd9Sstevel@tonic-gate 	uint_t gids[MAXGIDS];
11117c478bd9Sstevel@tonic-gate 	char netname_str[MAXNETNAMELEN + 1];
11127c478bd9Sstevel@tonic-gate 	bool_t (*xdr_argument)(), (*xdr_result)();
11137c478bd9Sstevel@tonic-gate 	bool_t (*local)();
11147c478bd9Sstevel@tonic-gate 	void (*local_free)() = NULL;
11157c478bd9Sstevel@tonic-gate 	bool_t retval;
11167c478bd9Sstevel@tonic-gate 	uid_t uid;
11177c478bd9Sstevel@tonic-gate 	int check_auth;
11187c478bd9Sstevel@tonic-gate 
11197c478bd9Sstevel@tonic-gate 	switch (rqstp->rq_proc) {
11207c478bd9Sstevel@tonic-gate 	case NULLPROC:
11217c478bd9Sstevel@tonic-gate 		svc_sendreply(transp, xdr_void, (char *)NULL);
11227c478bd9Sstevel@tonic-gate 		return;
11237c478bd9Sstevel@tonic-gate 
11247c478bd9Sstevel@tonic-gate 	case KEY_SET:
11257c478bd9Sstevel@tonic-gate 		xdr_argument = xdr_keybuf;
11267c478bd9Sstevel@tonic-gate 		xdr_result = xdr_int;
11277c478bd9Sstevel@tonic-gate 		local = __key_set_1_svc;
11287c478bd9Sstevel@tonic-gate 		check_auth = 1;
11297c478bd9Sstevel@tonic-gate 		break;
11307c478bd9Sstevel@tonic-gate 
11317c478bd9Sstevel@tonic-gate 	case KEY_ENCRYPT:
11327c478bd9Sstevel@tonic-gate 		xdr_argument = xdr_cryptkeyarg;
11337c478bd9Sstevel@tonic-gate 		xdr_result = xdr_cryptkeyres;
11347c478bd9Sstevel@tonic-gate 		local = __key_encrypt_1_svc;
11357c478bd9Sstevel@tonic-gate 		check_auth = 1;
11367c478bd9Sstevel@tonic-gate 		break;
11377c478bd9Sstevel@tonic-gate 
11387c478bd9Sstevel@tonic-gate 	case KEY_DECRYPT:
11397c478bd9Sstevel@tonic-gate 		xdr_argument = xdr_cryptkeyarg;
11407c478bd9Sstevel@tonic-gate 		xdr_result = xdr_cryptkeyres;
11417c478bd9Sstevel@tonic-gate 		local = __key_decrypt_1_svc;
11427c478bd9Sstevel@tonic-gate 		check_auth = 1;
11437c478bd9Sstevel@tonic-gate 		break;
11447c478bd9Sstevel@tonic-gate 
11457c478bd9Sstevel@tonic-gate 	case KEY_GEN:
11467c478bd9Sstevel@tonic-gate 		xdr_argument = xdr_void;
11477c478bd9Sstevel@tonic-gate 		xdr_result = xdr_des_block;
11487c478bd9Sstevel@tonic-gate 		local = __key_gen_1_svc;
11497c478bd9Sstevel@tonic-gate 		check_auth = 0;
11507c478bd9Sstevel@tonic-gate 		break;
11517c478bd9Sstevel@tonic-gate 
11527c478bd9Sstevel@tonic-gate 	case KEY_GETCRED:
11537c478bd9Sstevel@tonic-gate 		xdr_argument = xdr_netnamestr;
11547c478bd9Sstevel@tonic-gate 		xdr_result = xdr_getcredres;
11557c478bd9Sstevel@tonic-gate 		local = __key_getcred_1_svc;
11567c478bd9Sstevel@tonic-gate 		result.gres.getcredres_u.cred.gids.gids_val = gids;
11577c478bd9Sstevel@tonic-gate 		check_auth = 0;
11587c478bd9Sstevel@tonic-gate 		break;
11597c478bd9Sstevel@tonic-gate 
11607c478bd9Sstevel@tonic-gate 	case KEY_ENCRYPT_PK:
11617c478bd9Sstevel@tonic-gate 		xdr_argument = xdr_cryptkeyarg2;
11627c478bd9Sstevel@tonic-gate 		xdr_result = xdr_cryptkeyres;
11637c478bd9Sstevel@tonic-gate 		local = __key_encrypt_pk_2_svc;
11647c478bd9Sstevel@tonic-gate 		check_auth = 1;
11657c478bd9Sstevel@tonic-gate 		break;
11667c478bd9Sstevel@tonic-gate 
11677c478bd9Sstevel@tonic-gate 	case KEY_DECRYPT_PK:
11687c478bd9Sstevel@tonic-gate 		xdr_argument = xdr_cryptkeyarg2;
11697c478bd9Sstevel@tonic-gate 		xdr_result = xdr_cryptkeyres;
11707c478bd9Sstevel@tonic-gate 		local = __key_decrypt_pk_2_svc;
11717c478bd9Sstevel@tonic-gate 		check_auth = 1;
11727c478bd9Sstevel@tonic-gate 		break;
11737c478bd9Sstevel@tonic-gate 
11747c478bd9Sstevel@tonic-gate 
11757c478bd9Sstevel@tonic-gate 	case KEY_NET_PUT:
11767c478bd9Sstevel@tonic-gate 		xdr_argument = xdr_key_netstarg;
11777c478bd9Sstevel@tonic-gate 		xdr_result = xdr_keystatus;
11787c478bd9Sstevel@tonic-gate 		local = __key_net_put_2_svc;
11797c478bd9Sstevel@tonic-gate 		check_auth = 1;
11807c478bd9Sstevel@tonic-gate 		break;
11817c478bd9Sstevel@tonic-gate 
11827c478bd9Sstevel@tonic-gate 	case KEY_NET_GET:
11837c478bd9Sstevel@tonic-gate 		xdr_argument = (xdrproc_t)xdr_void;
11847c478bd9Sstevel@tonic-gate 		xdr_result = xdr_key_netstres;
11857c478bd9Sstevel@tonic-gate 		local = __key_net_get_2_svc;
11867c478bd9Sstevel@tonic-gate 		result.keynetname.key_netstres_u.knet.st_netname = netname_str;
11877c478bd9Sstevel@tonic-gate 		check_auth = 1;
11887c478bd9Sstevel@tonic-gate 		break;
11897c478bd9Sstevel@tonic-gate 
11907c478bd9Sstevel@tonic-gate 	case KEY_GET_CONV:
11917c478bd9Sstevel@tonic-gate 		xdr_argument = (xdrproc_t)xdr_keybuf;
11927c478bd9Sstevel@tonic-gate 		xdr_result = xdr_cryptkeyres;
11937c478bd9Sstevel@tonic-gate 		local = __key_get_conv_2_svc;
11947c478bd9Sstevel@tonic-gate 		check_auth = 1;
11957c478bd9Sstevel@tonic-gate 		break;
11967c478bd9Sstevel@tonic-gate 
11977c478bd9Sstevel@tonic-gate 	/*
11987c478bd9Sstevel@tonic-gate 	 * Version 3 procedures follow...
11997c478bd9Sstevel@tonic-gate 	 */
12007c478bd9Sstevel@tonic-gate 
12017c478bd9Sstevel@tonic-gate 	case KEY_SET_3:
12027c478bd9Sstevel@tonic-gate 		xdr_argument = (xdrproc_t)xdr_setkeyarg3;
12037c478bd9Sstevel@tonic-gate 		xdr_result = xdr_keystatus;
12047c478bd9Sstevel@tonic-gate 		local = __key_set_3_svc;
12057c478bd9Sstevel@tonic-gate 		check_auth = 1;
12067c478bd9Sstevel@tonic-gate 		break;
12077c478bd9Sstevel@tonic-gate 
12087c478bd9Sstevel@tonic-gate 	case KEY_ENCRYPT_3:
12097c478bd9Sstevel@tonic-gate 		xdr_argument = (xdrproc_t)xdr_cryptkeyarg3;
12107c478bd9Sstevel@tonic-gate 		xdr_result = xdr_cryptkeyres3;
12117c478bd9Sstevel@tonic-gate 		local = __key_encrypt_3_svc;
12127c478bd9Sstevel@tonic-gate 		check_auth = 1;
12137c478bd9Sstevel@tonic-gate 		break;
12147c478bd9Sstevel@tonic-gate 
12157c478bd9Sstevel@tonic-gate 	case KEY_DECRYPT_3:
12167c478bd9Sstevel@tonic-gate 		xdr_argument = (xdrproc_t)xdr_cryptkeyarg3;
12177c478bd9Sstevel@tonic-gate 		xdr_result = xdr_cryptkeyres3;
12187c478bd9Sstevel@tonic-gate 		local = __key_decrypt_3_svc;
12197c478bd9Sstevel@tonic-gate 		check_auth = 1;
12207c478bd9Sstevel@tonic-gate 		break;
12217c478bd9Sstevel@tonic-gate 
12227c478bd9Sstevel@tonic-gate 	case KEY_GEN_3:
12237c478bd9Sstevel@tonic-gate 		xdr_argument = (xdrproc_t)xdr_keynum_t;
12247c478bd9Sstevel@tonic-gate 		xdr_result = xdr_deskeyarray;
12257c478bd9Sstevel@tonic-gate 		local = __key_gen_3_svc;
12267c478bd9Sstevel@tonic-gate 		local_free = __key_gen_3_svc_free;
12277c478bd9Sstevel@tonic-gate 		check_auth = 0;
12287c478bd9Sstevel@tonic-gate 		break;
12297c478bd9Sstevel@tonic-gate 
12307c478bd9Sstevel@tonic-gate 	case KEY_GETCRED_3:
12317c478bd9Sstevel@tonic-gate 		xdr_argument = (xdrproc_t)xdr_netnamestr;
12327c478bd9Sstevel@tonic-gate 		xdr_result = xdr_getcredres3;
12337c478bd9Sstevel@tonic-gate 		local = __key_getcred_3_svc;
12347c478bd9Sstevel@tonic-gate 		check_auth = 0;
12357c478bd9Sstevel@tonic-gate 		break;
12367c478bd9Sstevel@tonic-gate 
12377c478bd9Sstevel@tonic-gate 	case KEY_ENCRYPT_PK_3:
12387c478bd9Sstevel@tonic-gate 		xdr_argument = (xdrproc_t)xdr_cryptkeyarg3;
12397c478bd9Sstevel@tonic-gate 		xdr_result = xdr_cryptkeyres3;
12407c478bd9Sstevel@tonic-gate 		local = __key_encrypt_pk_3_svc;
12417c478bd9Sstevel@tonic-gate 		local_free = __key_encrypt_pk_3_svc_free;
12427c478bd9Sstevel@tonic-gate 		check_auth = 1;
12437c478bd9Sstevel@tonic-gate 		break;
12447c478bd9Sstevel@tonic-gate 
12457c478bd9Sstevel@tonic-gate 	case KEY_DECRYPT_PK_3:
12467c478bd9Sstevel@tonic-gate 		xdr_argument = (xdrproc_t)xdr_cryptkeyarg3;
12477c478bd9Sstevel@tonic-gate 		xdr_result = xdr_cryptkeyres3;
12487c478bd9Sstevel@tonic-gate 		local = __key_decrypt_pk_3;
12497c478bd9Sstevel@tonic-gate 		local_free = __key_decrypt_pk_3_free;
12507c478bd9Sstevel@tonic-gate 		check_auth = 1;
12517c478bd9Sstevel@tonic-gate 		break;
12527c478bd9Sstevel@tonic-gate 
12537c478bd9Sstevel@tonic-gate 	case KEY_NET_PUT_3:
12547c478bd9Sstevel@tonic-gate 		xdr_argument = (xdrproc_t)xdr_key_netstarg3;
12557c478bd9Sstevel@tonic-gate 		xdr_result = xdr_keystatus;
12567c478bd9Sstevel@tonic-gate 		local = __key_net_put_3_svc;
12577c478bd9Sstevel@tonic-gate 		check_auth = 1;
12587c478bd9Sstevel@tonic-gate 		break;
12597c478bd9Sstevel@tonic-gate 
12607c478bd9Sstevel@tonic-gate 	case KEY_NET_GET_3:
12617c478bd9Sstevel@tonic-gate 		xdr_argument = (xdrproc_t)xdr_mechtype;
12627c478bd9Sstevel@tonic-gate 		xdr_result = xdr_key_netstres3;
12637c478bd9Sstevel@tonic-gate 		local = __key_net_get_3_svc;
12647c478bd9Sstevel@tonic-gate 		local_free = __key_net_get_3_svc_free;
12657c478bd9Sstevel@tonic-gate 		check_auth = 1;
12667c478bd9Sstevel@tonic-gate 		break;
12677c478bd9Sstevel@tonic-gate 
12687c478bd9Sstevel@tonic-gate 	case KEY_GET_CONV_3:
12697c478bd9Sstevel@tonic-gate 		xdr_argument = (xdrproc_t)xdr_deskeyarg3;
12707c478bd9Sstevel@tonic-gate 		xdr_result = xdr_cryptkeyres3;
12717c478bd9Sstevel@tonic-gate 		local = __key_get_conv_3_svc;
12727c478bd9Sstevel@tonic-gate 		check_auth = 1;
12737c478bd9Sstevel@tonic-gate 		break;
12747c478bd9Sstevel@tonic-gate 
12757c478bd9Sstevel@tonic-gate 	case KEY_CLEAR_3:
12767c478bd9Sstevel@tonic-gate 		xdr_argument = (xdrproc_t)xdr_void;
12777c478bd9Sstevel@tonic-gate 		xdr_result = xdr_keystatus;
12787c478bd9Sstevel@tonic-gate 		local = __key_clear_3_svc;
12797c478bd9Sstevel@tonic-gate 		check_auth = 1;
12807c478bd9Sstevel@tonic-gate 		break;
12817c478bd9Sstevel@tonic-gate 
12827c478bd9Sstevel@tonic-gate 	default:
12837c478bd9Sstevel@tonic-gate 		svcerr_noproc(transp);
12847c478bd9Sstevel@tonic-gate 		return;
12857c478bd9Sstevel@tonic-gate 	}
12867c478bd9Sstevel@tonic-gate 	if (check_auth) {
12877c478bd9Sstevel@tonic-gate 		if (!get_auth(transp, rqstp, &uid)) {
12887c478bd9Sstevel@tonic-gate 			if (debugging) {
12897c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr,
12907c478bd9Sstevel@tonic-gate 					"not local privileged process\n");
12917c478bd9Sstevel@tonic-gate 			}
12927c478bd9Sstevel@tonic-gate 			svcerr_weakauth(transp);
12937c478bd9Sstevel@tonic-gate 			return;
12947c478bd9Sstevel@tonic-gate 		}
12957c478bd9Sstevel@tonic-gate 	}
12967c478bd9Sstevel@tonic-gate 
12977c478bd9Sstevel@tonic-gate 	memset((char *)&argument, 0, sizeof (argument));
12987c478bd9Sstevel@tonic-gate 	if (!svc_getargs(transp, xdr_argument, (caddr_t)&argument)) {
12997c478bd9Sstevel@tonic-gate 		svcerr_decode(transp);
13007c478bd9Sstevel@tonic-gate 		return;
13017c478bd9Sstevel@tonic-gate 	}
13027c478bd9Sstevel@tonic-gate 	retval = (*local)(uid, &argument, &result);
13037c478bd9Sstevel@tonic-gate 	if (retval && !svc_sendreply(transp, xdr_result, (char *)&result)) {
13047c478bd9Sstevel@tonic-gate 		if (debugging)
13057c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "unable to reply\n");
13067c478bd9Sstevel@tonic-gate 		svcerr_systemerr(transp);
13077c478bd9Sstevel@tonic-gate 	}
13087c478bd9Sstevel@tonic-gate 	if (!svc_freeargs(transp, xdr_argument, (caddr_t)&argument)) {
13097c478bd9Sstevel@tonic-gate 		if (debugging)
13107c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
13117c478bd9Sstevel@tonic-gate 			"unable to free arguments\n");
13127c478bd9Sstevel@tonic-gate 		exit(1);
13137c478bd9Sstevel@tonic-gate 	}
13147c478bd9Sstevel@tonic-gate 	if (local_free) {
13157c478bd9Sstevel@tonic-gate 		(*local_free)(&result);
13167c478bd9Sstevel@tonic-gate 	}
13177c478bd9Sstevel@tonic-gate }
13187c478bd9Sstevel@tonic-gate 
13197c478bd9Sstevel@tonic-gate static bool_t
13207c478bd9Sstevel@tonic-gate get_auth(trans, rqstp, uid)
13217c478bd9Sstevel@tonic-gate 	SVCXPRT *trans;
13227c478bd9Sstevel@tonic-gate 	struct svc_req *rqstp;
13237c478bd9Sstevel@tonic-gate 	uid_t *uid;
13247c478bd9Sstevel@tonic-gate {
13257c478bd9Sstevel@tonic-gate 	svc_local_cred_t cred;
13267c478bd9Sstevel@tonic-gate 
13277c478bd9Sstevel@tonic-gate 	if (!svc_get_local_cred(trans, &cred)) {
13287c478bd9Sstevel@tonic-gate 		if (debugging)
13297c478bd9Sstevel@tonic-gate 			fprintf(stderr, "svc_get_local_cred failed %s %s\n",
13307c478bd9Sstevel@tonic-gate 				trans->xp_netid, trans->xp_tp);
13317c478bd9Sstevel@tonic-gate 		return (FALSE);
13327c478bd9Sstevel@tonic-gate 	}
13337c478bd9Sstevel@tonic-gate 	if (debugging)
13347c478bd9Sstevel@tonic-gate 		fprintf(stderr, "local_uid  %d\n", cred.euid);
13357c478bd9Sstevel@tonic-gate 	if (rqstp->rq_cred.oa_flavor == AUTH_SYS ||
13367c478bd9Sstevel@tonic-gate 	    rqstp->rq_cred.oa_flavor == AUTH_LOOPBACK) {
13377c478bd9Sstevel@tonic-gate /* LINTED pointer alignment */
13387c478bd9Sstevel@tonic-gate 		*uid = ((struct authunix_parms *)rqstp->rq_clntcred)->aup_uid;
13397c478bd9Sstevel@tonic-gate 		return (*uid == cred.euid || cred.euid == 0);
13407c478bd9Sstevel@tonic-gate 	} else {
13417c478bd9Sstevel@tonic-gate 		*uid = cred.euid;
13427c478bd9Sstevel@tonic-gate 		return (TRUE);
13437c478bd9Sstevel@tonic-gate 	}
13447c478bd9Sstevel@tonic-gate }
13457c478bd9Sstevel@tonic-gate 
13467c478bd9Sstevel@tonic-gate static int
13477c478bd9Sstevel@tonic-gate get_cache_size(size)
13487c478bd9Sstevel@tonic-gate char *size;
13497c478bd9Sstevel@tonic-gate {
13507c478bd9Sstevel@tonic-gate 	int csize, len;
13517c478bd9Sstevel@tonic-gate 
13527c478bd9Sstevel@tonic-gate 	len = (int)strlen(size);
13537c478bd9Sstevel@tonic-gate 	if (len == 0) {
13547c478bd9Sstevel@tonic-gate 		usage();
13557c478bd9Sstevel@tonic-gate 	}
13567c478bd9Sstevel@tonic-gate 
13577c478bd9Sstevel@tonic-gate 	if (size[len-1] == 'M' || size[len-1] == 'm') {
13587c478bd9Sstevel@tonic-gate 		/*
13597c478bd9Sstevel@tonic-gate 		 * cache size in MB
13607c478bd9Sstevel@tonic-gate 		 */
13617c478bd9Sstevel@tonic-gate 		size[len-1] = '\0';
13627c478bd9Sstevel@tonic-gate 		csize = atoi(size);
13637c478bd9Sstevel@tonic-gate 	} else {
13647c478bd9Sstevel@tonic-gate 		csize = atoi(size);
13657c478bd9Sstevel@tonic-gate 		/*
13667c478bd9Sstevel@tonic-gate 		 * negative size indicates number of entries in cache
13677c478bd9Sstevel@tonic-gate 		 */
13687c478bd9Sstevel@tonic-gate 		csize = 0 - csize;
13697c478bd9Sstevel@tonic-gate 	}
13707c478bd9Sstevel@tonic-gate 
13717c478bd9Sstevel@tonic-gate 	if (csize == 0) {
13727c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "invalid cache size: %s\n", size);
13737c478bd9Sstevel@tonic-gate 		usage();
13747c478bd9Sstevel@tonic-gate 	}
13757c478bd9Sstevel@tonic-gate 
13767c478bd9Sstevel@tonic-gate 	return (csize);
13777c478bd9Sstevel@tonic-gate }
13787c478bd9Sstevel@tonic-gate 
13797c478bd9Sstevel@tonic-gate static void
13807c478bd9Sstevel@tonic-gate usage()
13817c478bd9Sstevel@tonic-gate {
13827c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "usage: \n");
13837c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "keyserv [-c]|[-s ");
13847c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "<size>|<mechtype>=<size>[,...]] [-n] [-D] ");
13857c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "[-d | -e] ");
13867c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "[-t threads]\n");
13877c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "-d disables the use of default keys\n");
13887c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "-e enables the use of default keys\n");
13897c478bd9Sstevel@tonic-gate 	exit(1);
13907c478bd9Sstevel@tonic-gate }
13917c478bd9Sstevel@tonic-gate 
13927c478bd9Sstevel@tonic-gate static void
13937c478bd9Sstevel@tonic-gate defaults(void)
13947c478bd9Sstevel@tonic-gate {
13957c478bd9Sstevel@tonic-gate 	register int  flags;
13967c478bd9Sstevel@tonic-gate 	register char *ptr;
13977c478bd9Sstevel@tonic-gate 
13987c478bd9Sstevel@tonic-gate 	if (defopen(defaults_file) == 0) {
13997c478bd9Sstevel@tonic-gate 		/*
14007c478bd9Sstevel@tonic-gate 		 * ignore case
14017c478bd9Sstevel@tonic-gate 		 */
14027c478bd9Sstevel@tonic-gate 		flags = defcntl(DC_GETFLAGS, 0);
14037c478bd9Sstevel@tonic-gate 		TURNOFF(flags, DC_CASE);
14047c478bd9Sstevel@tonic-gate 		defcntl(DC_SETFLAGS, flags);
14057c478bd9Sstevel@tonic-gate 
14067c478bd9Sstevel@tonic-gate 		if ((ptr = defread("ENABLE_NOBODY_KEYS=")) != NULL) {
14077c478bd9Sstevel@tonic-gate 			if (strcasecmp(ptr, "NO") == 0) {
14087c478bd9Sstevel@tonic-gate 				use_nobody_keys = FALSE;
14097c478bd9Sstevel@tonic-gate 			}
14107c478bd9Sstevel@tonic-gate 		}
14117c478bd9Sstevel@tonic-gate 
14127c478bd9Sstevel@tonic-gate 		(void) defopen((char *)NULL);
14137c478bd9Sstevel@tonic-gate 	}
14147c478bd9Sstevel@tonic-gate }
1415