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
5*cb620785Sraf * Common Development and Distribution License (the "License").
6*cb620785Sraf * 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 */
2161961e0fSrobinson
227c478bd9Sstevel@tonic-gate /*
23*cb620785Sraf * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
247c478bd9Sstevel@tonic-gate * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate */
26e8031f0aSraf
277c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
287c478bd9Sstevel@tonic-gate /* All Rights Reserved */
297c478bd9Sstevel@tonic-gate /*
307c478bd9Sstevel@tonic-gate * Portions of this source code were derived from Berkeley
317c478bd9Sstevel@tonic-gate * 4.3 BSD under license from the Regents of the University of
327c478bd9Sstevel@tonic-gate * California.
337c478bd9Sstevel@tonic-gate */
347c478bd9Sstevel@tonic-gate
357c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
367c478bd9Sstevel@tonic-gate
377c478bd9Sstevel@tonic-gate /*
38e8031f0aSraf * Interface to keyserver
397c478bd9Sstevel@tonic-gate *
407c478bd9Sstevel@tonic-gate * setsecretkey(key) - set your secret key
417c478bd9Sstevel@tonic-gate * encryptsessionkey(agent, deskey) - encrypt a session key to talk to agent
427c478bd9Sstevel@tonic-gate * decryptsessionkey(agent, deskey) - decrypt ditto
437c478bd9Sstevel@tonic-gate * gendeskey(deskey) - generate a secure des key
447c478bd9Sstevel@tonic-gate */
457c478bd9Sstevel@tonic-gate
467c478bd9Sstevel@tonic-gate #include "mt.h"
477c478bd9Sstevel@tonic-gate #include "rpc_mt.h"
487c478bd9Sstevel@tonic-gate #include <errno.h>
497c478bd9Sstevel@tonic-gate #include <rpc/rpc.h>
507c478bd9Sstevel@tonic-gate #include <rpc/key_prot.h>
517c478bd9Sstevel@tonic-gate #include <stdio.h>
527c478bd9Sstevel@tonic-gate #include <syslog.h>
537c478bd9Sstevel@tonic-gate #include <string.h>
547c478bd9Sstevel@tonic-gate #include <stdlib.h>
557c478bd9Sstevel@tonic-gate #include <unistd.h>
567c478bd9Sstevel@tonic-gate #include <sys/types.h>
577c478bd9Sstevel@tonic-gate #include <sys/stat.h>
587c478bd9Sstevel@tonic-gate
597c478bd9Sstevel@tonic-gate #define CLASSIC_PK_DH(k, a) (((k) == 192) && ((a) == 0))
607c478bd9Sstevel@tonic-gate
617c478bd9Sstevel@tonic-gate #ifdef DEBUG
627c478bd9Sstevel@tonic-gate #define debug(msg) (void) fprintf(stderr, "%s\n", msg);
637c478bd9Sstevel@tonic-gate #else
647c478bd9Sstevel@tonic-gate #define debug(msg)
657c478bd9Sstevel@tonic-gate #endif /* DEBUG */
667c478bd9Sstevel@tonic-gate
677c478bd9Sstevel@tonic-gate int key_call(rpcproc_t, xdrproc_t, char *, xdrproc_t, char *);
687c478bd9Sstevel@tonic-gate int key_call_ext(rpcproc_t, xdrproc_t, char *, xdrproc_t, char *, int);
697c478bd9Sstevel@tonic-gate int key_setnet(struct key_netstarg *);
707c478bd9Sstevel@tonic-gate
717c478bd9Sstevel@tonic-gate /*
727c478bd9Sstevel@tonic-gate * Hack to allow the keyserver to use AUTH_DES (for authenticated
737c478bd9Sstevel@tonic-gate * NIS+ calls, for example). The only functions that get called
747c478bd9Sstevel@tonic-gate * are key_encryptsession_pk, key_decryptsession_pk, and key_gendes.
757c478bd9Sstevel@tonic-gate *
767c478bd9Sstevel@tonic-gate * The approach is to have the keyserver fill in pointers to local
777c478bd9Sstevel@tonic-gate * implementations of these functions, and to call those in key_call().
787c478bd9Sstevel@tonic-gate */
797c478bd9Sstevel@tonic-gate
807c478bd9Sstevel@tonic-gate bool_t (*__key_encryptsession_pk_LOCAL)() = NULL;
817c478bd9Sstevel@tonic-gate bool_t (*__key_decryptsession_pk_LOCAL)() = NULL;
827c478bd9Sstevel@tonic-gate bool_t (*__key_gendes_LOCAL)() = NULL;
837c478bd9Sstevel@tonic-gate
847c478bd9Sstevel@tonic-gate
857c478bd9Sstevel@tonic-gate int
key_setsecret(const char * secretkey)8661961e0fSrobinson key_setsecret(const char *secretkey)
877c478bd9Sstevel@tonic-gate {
887c478bd9Sstevel@tonic-gate char netName[MAXNETNAMELEN+1];
897c478bd9Sstevel@tonic-gate struct key_netstarg netst;
907c478bd9Sstevel@tonic-gate int ret;
917c478bd9Sstevel@tonic-gate
927c478bd9Sstevel@tonic-gate if (getnetname(netName) == 0) {
937c478bd9Sstevel@tonic-gate debug("getnetname failed");
947c478bd9Sstevel@tonic-gate return (-1);
957c478bd9Sstevel@tonic-gate }
967c478bd9Sstevel@tonic-gate
9761961e0fSrobinson (void) memcpy(netst.st_priv_key, secretkey, HEXKEYBYTES);
987c478bd9Sstevel@tonic-gate netst.st_pub_key[0] = 0;
997c478bd9Sstevel@tonic-gate netst.st_netname = netName;
1007c478bd9Sstevel@tonic-gate
1017c478bd9Sstevel@tonic-gate /*
1027c478bd9Sstevel@tonic-gate * Actual key login
1037c478bd9Sstevel@tonic-gate * We perform the KEY_NET_PUT instead of the SET_KEY
1047c478bd9Sstevel@tonic-gate * rpc call because key_secretkey_is_set function uses
1057c478bd9Sstevel@tonic-gate * the KEY_NET_GET call which expects the netname to be
1067c478bd9Sstevel@tonic-gate * set along with the key. Keylogin also uses KEY_NET_PUT.
1077c478bd9Sstevel@tonic-gate */
1087c478bd9Sstevel@tonic-gate ret = key_setnet(&netst);
1097c478bd9Sstevel@tonic-gate
1107c478bd9Sstevel@tonic-gate /* erase our copy of the secret key */
11161961e0fSrobinson (void) memset(netst.st_priv_key, '\0', HEXKEYBYTES);
1127c478bd9Sstevel@tonic-gate
1137c478bd9Sstevel@tonic-gate if (ret == 1)
1147c478bd9Sstevel@tonic-gate return (0);
1157c478bd9Sstevel@tonic-gate
1167c478bd9Sstevel@tonic-gate return (-1);
1177c478bd9Sstevel@tonic-gate }
1187c478bd9Sstevel@tonic-gate
1197c478bd9Sstevel@tonic-gate int
key_setsecret_g(char * secretkey,keylen_t keylen,algtype_t algtype,des_block userkey)1207c478bd9Sstevel@tonic-gate key_setsecret_g(
1217c478bd9Sstevel@tonic-gate char *secretkey,
1227c478bd9Sstevel@tonic-gate keylen_t keylen,
1237c478bd9Sstevel@tonic-gate algtype_t algtype,
1247c478bd9Sstevel@tonic-gate des_block userkey)
1257c478bd9Sstevel@tonic-gate {
1267c478bd9Sstevel@tonic-gate setkeyarg3 arg;
1277c478bd9Sstevel@tonic-gate keystatus status;
1287c478bd9Sstevel@tonic-gate
12961961e0fSrobinson if (CLASSIC_PK_DH(keylen, algtype))
1307c478bd9Sstevel@tonic-gate return (key_setsecret(secretkey));
1317c478bd9Sstevel@tonic-gate arg.key.keybuf3_len = keylen/4 + 1;
1327c478bd9Sstevel@tonic-gate arg.key.keybuf3_val = secretkey;
1337c478bd9Sstevel@tonic-gate arg.algtype = algtype;
1347c478bd9Sstevel@tonic-gate arg.keylen = keylen;
1357c478bd9Sstevel@tonic-gate arg.userkey = userkey;
1367c478bd9Sstevel@tonic-gate if (!key_call((rpcproc_t)KEY_SET_3, xdr_setkeyarg3, (char *)&arg,
13761961e0fSrobinson xdr_keystatus, (char *)&status))
1387c478bd9Sstevel@tonic-gate return (-1);
1397c478bd9Sstevel@tonic-gate if (status != KEY_SUCCESS) {
1407c478bd9Sstevel@tonic-gate debug("set3 status is nonzero");
1417c478bd9Sstevel@tonic-gate return (-1);
1427c478bd9Sstevel@tonic-gate }
1437c478bd9Sstevel@tonic-gate return (0);
1447c478bd9Sstevel@tonic-gate }
1457c478bd9Sstevel@tonic-gate
1467c478bd9Sstevel@tonic-gate int
key_removesecret_g_ext(int use_uid)1477c478bd9Sstevel@tonic-gate key_removesecret_g_ext(int use_uid)
1487c478bd9Sstevel@tonic-gate {
1497c478bd9Sstevel@tonic-gate keystatus status;
1507c478bd9Sstevel@tonic-gate
15161961e0fSrobinson if (!key_call_ext((rpcproc_t)KEY_CLEAR_3, xdr_void, NULL,
1527c478bd9Sstevel@tonic-gate xdr_keystatus, (char *)&status, use_uid)) {
1537c478bd9Sstevel@tonic-gate debug("remove secret key call failed");
1547c478bd9Sstevel@tonic-gate return (-1);
1557c478bd9Sstevel@tonic-gate }
1567c478bd9Sstevel@tonic-gate if (status != KEY_SUCCESS) {
1577c478bd9Sstevel@tonic-gate debug("remove secret status is nonzero");
1587c478bd9Sstevel@tonic-gate return (-1);
1597c478bd9Sstevel@tonic-gate }
1607c478bd9Sstevel@tonic-gate return (0);
1617c478bd9Sstevel@tonic-gate }
1627c478bd9Sstevel@tonic-gate
1637c478bd9Sstevel@tonic-gate /*
1647c478bd9Sstevel@tonic-gate * Use effective uid.
1657c478bd9Sstevel@tonic-gate */
1667c478bd9Sstevel@tonic-gate int
key_removesecret_g(void)16761961e0fSrobinson key_removesecret_g(void)
1687c478bd9Sstevel@tonic-gate {
1697c478bd9Sstevel@tonic-gate return (key_removesecret_g_ext(0));
1707c478bd9Sstevel@tonic-gate }
1717c478bd9Sstevel@tonic-gate
1727c478bd9Sstevel@tonic-gate /*
1737c478bd9Sstevel@tonic-gate * Use real uid.
1747c478bd9Sstevel@tonic-gate */
1757c478bd9Sstevel@tonic-gate int
key_removesecret_g_ruid(void)17661961e0fSrobinson key_removesecret_g_ruid(void)
1777c478bd9Sstevel@tonic-gate {
1787c478bd9Sstevel@tonic-gate return (key_removesecret_g_ext(1));
1797c478bd9Sstevel@tonic-gate }
1807c478bd9Sstevel@tonic-gate
1817c478bd9Sstevel@tonic-gate /*
1827c478bd9Sstevel@tonic-gate * key_secretkey_is_set() returns 1 if the keyserver has a secret key
1837c478bd9Sstevel@tonic-gate * stored for the caller's effective uid if use_ruid is 0 or
1847c478bd9Sstevel@tonic-gate * stored for the caller's real uid if use_ruid is 1.
1857c478bd9Sstevel@tonic-gate * it returns 0 otherwise.
1867c478bd9Sstevel@tonic-gate *
1877c478bd9Sstevel@tonic-gate * N.B.: The KEY_NET_GET key call is undocumented. Applications shouldn't
1887c478bd9Sstevel@tonic-gate * be using it, because it allows them to get the user's secret key.
1897c478bd9Sstevel@tonic-gate *
1907c478bd9Sstevel@tonic-gate */
1917c478bd9Sstevel@tonic-gate int
key_secretkey_is_set_ext(int use_ruid)1927c478bd9Sstevel@tonic-gate key_secretkey_is_set_ext(int use_ruid)
1937c478bd9Sstevel@tonic-gate {
1947c478bd9Sstevel@tonic-gate struct key_netstres kres;
1957c478bd9Sstevel@tonic-gate
19661961e0fSrobinson (void) memset(&kres, 0, sizeof (kres));
19761961e0fSrobinson if (key_call_ext((rpcproc_t)KEY_NET_GET, xdr_void, NULL,
1987c478bd9Sstevel@tonic-gate xdr_key_netstres, (char *)&kres, use_ruid) &&
1997c478bd9Sstevel@tonic-gate (kres.status == KEY_SUCCESS) &&
2007c478bd9Sstevel@tonic-gate (kres.key_netstres_u.knet.st_priv_key[0] != 0)) {
2017c478bd9Sstevel@tonic-gate /* avoid leaving secret key in memory */
20261961e0fSrobinson (void) memset(kres.key_netstres_u.knet.st_priv_key, 0,
20361961e0fSrobinson HEXKEYBYTES);
2047c478bd9Sstevel@tonic-gate xdr_free(xdr_key_netstres, (char *)&kres);
2057c478bd9Sstevel@tonic-gate return (1);
2067c478bd9Sstevel@tonic-gate }
2077c478bd9Sstevel@tonic-gate return (0);
2087c478bd9Sstevel@tonic-gate }
2097c478bd9Sstevel@tonic-gate
2107c478bd9Sstevel@tonic-gate /*
2117c478bd9Sstevel@tonic-gate * Use effective uid.
2127c478bd9Sstevel@tonic-gate */
2137c478bd9Sstevel@tonic-gate int
key_secretkey_is_set(void)2147c478bd9Sstevel@tonic-gate key_secretkey_is_set(void)
2157c478bd9Sstevel@tonic-gate {
2167c478bd9Sstevel@tonic-gate return (key_secretkey_is_set_ext(0));
2177c478bd9Sstevel@tonic-gate }
2187c478bd9Sstevel@tonic-gate
2197c478bd9Sstevel@tonic-gate /*
2207c478bd9Sstevel@tonic-gate * Use real uid.
2217c478bd9Sstevel@tonic-gate */
2227c478bd9Sstevel@tonic-gate int
key_secretkey_is_set_ruid(void)2237c478bd9Sstevel@tonic-gate key_secretkey_is_set_ruid(void)
2247c478bd9Sstevel@tonic-gate {
2257c478bd9Sstevel@tonic-gate return (key_secretkey_is_set_ext(1));
2267c478bd9Sstevel@tonic-gate }
2277c478bd9Sstevel@tonic-gate
2287c478bd9Sstevel@tonic-gate /*
2297c478bd9Sstevel@tonic-gate * key_secretkey_is_set_g_ext() returns 1 if the keyserver has a secret key
2307c478bd9Sstevel@tonic-gate * stored for the caller's uid, it returns 0 otherwise.
2317c478bd9Sstevel@tonic-gate * If (use_ruid == 0), for the caller's effective uid.
2327c478bd9Sstevel@tonic-gate * If (use_ruid == 1), for the caller's real uid.
2337c478bd9Sstevel@tonic-gate *
2347c478bd9Sstevel@tonic-gate * N.B.: The KEY_NET_GET_3 key call is undocumented. Applications shouldn't
2357c478bd9Sstevel@tonic-gate * be using it, because it allows them to get the user's secret key.
2367c478bd9Sstevel@tonic-gate */
2377c478bd9Sstevel@tonic-gate int
key_secretkey_is_set_g_ext(keylen_t keylen,algtype_t algtype,int use_ruid)2387c478bd9Sstevel@tonic-gate key_secretkey_is_set_g_ext(keylen_t keylen, algtype_t algtype, int use_ruid)
2397c478bd9Sstevel@tonic-gate {
2407c478bd9Sstevel@tonic-gate mechtype arg;
2417c478bd9Sstevel@tonic-gate key_netstres3 kres;
2427c478bd9Sstevel@tonic-gate
2437c478bd9Sstevel@tonic-gate /*
2447c478bd9Sstevel@tonic-gate * key_secretkey_is_set_g_ext is tricky because keylen == 0
2457c478bd9Sstevel@tonic-gate * means check if any key exists for the caller (old/new, 192/1024 ...)
2467c478bd9Sstevel@tonic-gate * Rather than handle this on the server side, we call the old
2477c478bd9Sstevel@tonic-gate * routine if keylen == 0 and try the newer stuff only if that fails
2487c478bd9Sstevel@tonic-gate */
24961961e0fSrobinson if ((keylen == 0) && key_secretkey_is_set_ext(use_ruid))
2507c478bd9Sstevel@tonic-gate return (1);
25161961e0fSrobinson if (CLASSIC_PK_DH(keylen, algtype))
2527c478bd9Sstevel@tonic-gate return (key_secretkey_is_set_ext(use_ruid));
2537c478bd9Sstevel@tonic-gate arg.keylen = keylen;
2547c478bd9Sstevel@tonic-gate arg.algtype = algtype;
25561961e0fSrobinson (void) memset(&kres, 0, sizeof (kres));
2567c478bd9Sstevel@tonic-gate if (key_call_ext((rpcproc_t)KEY_NET_GET_3, xdr_mechtype, (char *)&arg,
2577c478bd9Sstevel@tonic-gate xdr_key_netstres3, (char *)&kres, use_ruid) &&
2587c478bd9Sstevel@tonic-gate (kres.status == KEY_SUCCESS) &&
2597c478bd9Sstevel@tonic-gate (kres.key_netstres3_u.knet.st_priv_key.keybuf3_len != 0)) {
2607c478bd9Sstevel@tonic-gate /* avoid leaving secret key in memory */
26161961e0fSrobinson (void) memset(kres.key_netstres3_u.knet.st_priv_key.keybuf3_val,
26261961e0fSrobinson 0, kres.key_netstres3_u.knet.st_priv_key.keybuf3_len);
2637c478bd9Sstevel@tonic-gate xdr_free(xdr_key_netstres3, (char *)&kres);
2647c478bd9Sstevel@tonic-gate return (1);
2657c478bd9Sstevel@tonic-gate }
2667c478bd9Sstevel@tonic-gate return (0);
2677c478bd9Sstevel@tonic-gate }
2687c478bd9Sstevel@tonic-gate
2697c478bd9Sstevel@tonic-gate /*
2707c478bd9Sstevel@tonic-gate * Use effective uid.
2717c478bd9Sstevel@tonic-gate */
2727c478bd9Sstevel@tonic-gate int
key_secretkey_is_set_g(keylen_t keylen,algtype_t algtype)2737c478bd9Sstevel@tonic-gate key_secretkey_is_set_g(keylen_t keylen, algtype_t algtype)
2747c478bd9Sstevel@tonic-gate {
2757c478bd9Sstevel@tonic-gate return (key_secretkey_is_set_g_ext(keylen, algtype, 0));
2767c478bd9Sstevel@tonic-gate }
2777c478bd9Sstevel@tonic-gate
2787c478bd9Sstevel@tonic-gate /*
2797c478bd9Sstevel@tonic-gate * Use real uid.
2807c478bd9Sstevel@tonic-gate */
2817c478bd9Sstevel@tonic-gate int
key_secretkey_is_set_g_ruid(keylen_t keylen,algtype_t algtype)2827c478bd9Sstevel@tonic-gate key_secretkey_is_set_g_ruid(keylen_t keylen, algtype_t algtype)
2837c478bd9Sstevel@tonic-gate {
2847c478bd9Sstevel@tonic-gate return (key_secretkey_is_set_g_ext(keylen, algtype, 1));
2857c478bd9Sstevel@tonic-gate }
2867c478bd9Sstevel@tonic-gate
2877c478bd9Sstevel@tonic-gate
2887c478bd9Sstevel@tonic-gate int
key_encryptsession_pk(const char * remotename,netobj * remotekey,des_block * deskey)28961961e0fSrobinson key_encryptsession_pk(const char *remotename, netobj *remotekey,
29061961e0fSrobinson des_block *deskey)
2917c478bd9Sstevel@tonic-gate {
2927c478bd9Sstevel@tonic-gate cryptkeyarg2 arg;
2937c478bd9Sstevel@tonic-gate cryptkeyres res;
2947c478bd9Sstevel@tonic-gate
29561961e0fSrobinson arg.remotename = (char *)remotename;
2967c478bd9Sstevel@tonic-gate arg.remotekey = *remotekey;
2977c478bd9Sstevel@tonic-gate arg.deskey = *deskey;
2987c478bd9Sstevel@tonic-gate if (!key_call((rpcproc_t)KEY_ENCRYPT_PK, xdr_cryptkeyarg2, (char *)&arg,
29961961e0fSrobinson xdr_cryptkeyres, (char *)&res))
3007c478bd9Sstevel@tonic-gate return (-1);
3017c478bd9Sstevel@tonic-gate if (res.status != KEY_SUCCESS) {
3027c478bd9Sstevel@tonic-gate debug("encrypt status is nonzero");
3037c478bd9Sstevel@tonic-gate return (-1);
3047c478bd9Sstevel@tonic-gate }
3057c478bd9Sstevel@tonic-gate *deskey = res.cryptkeyres_u.deskey;
3067c478bd9Sstevel@tonic-gate return (0);
3077c478bd9Sstevel@tonic-gate }
3087c478bd9Sstevel@tonic-gate
3097c478bd9Sstevel@tonic-gate int
key_encryptsession_pk_g(const char * remotename,const char * remotekey,keylen_t remotekeylen,algtype_t algtype,des_block deskey[],keynum_t keynum)3107c478bd9Sstevel@tonic-gate key_encryptsession_pk_g(
3117c478bd9Sstevel@tonic-gate const char *remotename,
3127c478bd9Sstevel@tonic-gate const char *remotekey,
3137c478bd9Sstevel@tonic-gate keylen_t remotekeylen,
3147c478bd9Sstevel@tonic-gate algtype_t algtype,
3157c478bd9Sstevel@tonic-gate des_block deskey[],
3167c478bd9Sstevel@tonic-gate keynum_t keynum
3177c478bd9Sstevel@tonic-gate )
3187c478bd9Sstevel@tonic-gate {
3197c478bd9Sstevel@tonic-gate cryptkeyarg3 arg;
3207c478bd9Sstevel@tonic-gate cryptkeyres3 res;
3217c478bd9Sstevel@tonic-gate
3227c478bd9Sstevel@tonic-gate if (CLASSIC_PK_DH(remotekeylen, algtype)) {
3237c478bd9Sstevel@tonic-gate int i;
3247c478bd9Sstevel@tonic-gate netobj npk;
3257c478bd9Sstevel@tonic-gate
3267c478bd9Sstevel@tonic-gate npk.n_len = remotekeylen/4 + 1;
3277c478bd9Sstevel@tonic-gate npk.n_bytes = (char *)remotekey;
3287c478bd9Sstevel@tonic-gate for (i = 0; i < keynum; i++) {
32961961e0fSrobinson if (key_encryptsession_pk(remotename, &npk, &deskey[i]))
3307c478bd9Sstevel@tonic-gate return (-1);
3317c478bd9Sstevel@tonic-gate }
3327c478bd9Sstevel@tonic-gate return (0);
3337c478bd9Sstevel@tonic-gate }
3347c478bd9Sstevel@tonic-gate arg.remotename = (char *)remotename;
3357c478bd9Sstevel@tonic-gate arg.remotekey.keybuf3_len = remotekeylen/4 + 1;
3367c478bd9Sstevel@tonic-gate arg.remotekey.keybuf3_val = (char *)remotekey;
3377c478bd9Sstevel@tonic-gate arg.keylen = remotekeylen;
3387c478bd9Sstevel@tonic-gate arg.algtype = algtype;
3397c478bd9Sstevel@tonic-gate arg.deskey.deskeyarray_len = keynum;
3407c478bd9Sstevel@tonic-gate arg.deskey.deskeyarray_val = deskey;
34161961e0fSrobinson (void) memset(&res, 0, sizeof (res));
3427c478bd9Sstevel@tonic-gate res.cryptkeyres3_u.deskey.deskeyarray_val = deskey;
3437c478bd9Sstevel@tonic-gate if (!key_call((rpcproc_t)KEY_ENCRYPT_PK_3,
3447c478bd9Sstevel@tonic-gate xdr_cryptkeyarg3, (char *)&arg,
34561961e0fSrobinson xdr_cryptkeyres3, (char *)&res))
3467c478bd9Sstevel@tonic-gate return (-1);
3477c478bd9Sstevel@tonic-gate if (res.status != KEY_SUCCESS) {
3487c478bd9Sstevel@tonic-gate debug("encrypt3 status is nonzero");
3497c478bd9Sstevel@tonic-gate return (-1);
3507c478bd9Sstevel@tonic-gate }
3517c478bd9Sstevel@tonic-gate if (res.cryptkeyres3_u.deskey.deskeyarray_len != keynum) {
3527c478bd9Sstevel@tonic-gate debug("number of keys don't match");
3537c478bd9Sstevel@tonic-gate return (-1);
3547c478bd9Sstevel@tonic-gate }
3557c478bd9Sstevel@tonic-gate return (0);
3567c478bd9Sstevel@tonic-gate }
3577c478bd9Sstevel@tonic-gate
3587c478bd9Sstevel@tonic-gate int
key_decryptsession_pk(const char * remotename,netobj * remotekey,des_block * deskey)35961961e0fSrobinson key_decryptsession_pk(const char *remotename, netobj *remotekey,
36061961e0fSrobinson des_block *deskey)
3617c478bd9Sstevel@tonic-gate {
3627c478bd9Sstevel@tonic-gate cryptkeyarg2 arg;
3637c478bd9Sstevel@tonic-gate cryptkeyres res;
3647c478bd9Sstevel@tonic-gate
36561961e0fSrobinson arg.remotename = (char *)remotename;
3667c478bd9Sstevel@tonic-gate arg.remotekey = *remotekey;
3677c478bd9Sstevel@tonic-gate arg.deskey = *deskey;
3687c478bd9Sstevel@tonic-gate if (!key_call((rpcproc_t)KEY_DECRYPT_PK, xdr_cryptkeyarg2, (char *)&arg,
36961961e0fSrobinson xdr_cryptkeyres, (char *)&res))
3707c478bd9Sstevel@tonic-gate return (-1);
3717c478bd9Sstevel@tonic-gate if (res.status != KEY_SUCCESS) {
3727c478bd9Sstevel@tonic-gate debug("decrypt status is nonzero");
3737c478bd9Sstevel@tonic-gate return (-1);
3747c478bd9Sstevel@tonic-gate }
3757c478bd9Sstevel@tonic-gate *deskey = res.cryptkeyres_u.deskey;
3767c478bd9Sstevel@tonic-gate return (0);
3777c478bd9Sstevel@tonic-gate }
3787c478bd9Sstevel@tonic-gate
3797c478bd9Sstevel@tonic-gate int
key_decryptsession_pk_g(const char * remotename,const char * remotekey,keylen_t remotekeylen,algtype_t algtype,des_block deskey[],keynum_t keynum)3807c478bd9Sstevel@tonic-gate key_decryptsession_pk_g(
3817c478bd9Sstevel@tonic-gate const char *remotename,
3827c478bd9Sstevel@tonic-gate const char *remotekey,
3837c478bd9Sstevel@tonic-gate keylen_t remotekeylen,
3847c478bd9Sstevel@tonic-gate algtype_t algtype,
3857c478bd9Sstevel@tonic-gate des_block deskey[],
3867c478bd9Sstevel@tonic-gate keynum_t keynum
3877c478bd9Sstevel@tonic-gate )
3887c478bd9Sstevel@tonic-gate {
3897c478bd9Sstevel@tonic-gate cryptkeyarg3 arg;
3907c478bd9Sstevel@tonic-gate cryptkeyres3 res;
3917c478bd9Sstevel@tonic-gate
3927c478bd9Sstevel@tonic-gate if (CLASSIC_PK_DH(remotekeylen, algtype)) {
3937c478bd9Sstevel@tonic-gate int i;
3947c478bd9Sstevel@tonic-gate netobj npk;
3957c478bd9Sstevel@tonic-gate
3967c478bd9Sstevel@tonic-gate npk.n_len = remotekeylen/4 + 1;
3977c478bd9Sstevel@tonic-gate npk.n_bytes = (char *)remotekey;
3987c478bd9Sstevel@tonic-gate for (i = 0; i < keynum; i++) {
39961961e0fSrobinson if (key_decryptsession_pk(remotename,
4007c478bd9Sstevel@tonic-gate &npk, &deskey[i]))
4017c478bd9Sstevel@tonic-gate return (-1);
4027c478bd9Sstevel@tonic-gate }
4037c478bd9Sstevel@tonic-gate return (0);
4047c478bd9Sstevel@tonic-gate }
4057c478bd9Sstevel@tonic-gate arg.remotename = (char *)remotename;
4067c478bd9Sstevel@tonic-gate arg.remotekey.keybuf3_len = remotekeylen/4 + 1;
4077c478bd9Sstevel@tonic-gate arg.remotekey.keybuf3_val = (char *)remotekey;
4087c478bd9Sstevel@tonic-gate arg.deskey.deskeyarray_len = keynum;
4097c478bd9Sstevel@tonic-gate arg.deskey.deskeyarray_val = deskey;
4107c478bd9Sstevel@tonic-gate arg.algtype = algtype;
4117c478bd9Sstevel@tonic-gate arg.keylen = remotekeylen;
41261961e0fSrobinson (void) memset(&res, 0, sizeof (res));
4137c478bd9Sstevel@tonic-gate res.cryptkeyres3_u.deskey.deskeyarray_val = deskey;
4147c478bd9Sstevel@tonic-gate if (!key_call((rpcproc_t)KEY_DECRYPT_PK_3,
4157c478bd9Sstevel@tonic-gate xdr_cryptkeyarg3, (char *)&arg,
41661961e0fSrobinson xdr_cryptkeyres3, (char *)&res))
4177c478bd9Sstevel@tonic-gate return (-1);
4187c478bd9Sstevel@tonic-gate if (res.status != KEY_SUCCESS) {
4197c478bd9Sstevel@tonic-gate debug("decrypt3 status is nonzero");
4207c478bd9Sstevel@tonic-gate return (-1);
4217c478bd9Sstevel@tonic-gate }
4227c478bd9Sstevel@tonic-gate if (res.cryptkeyres3_u.deskey.deskeyarray_len != keynum) {
4237c478bd9Sstevel@tonic-gate debug("number of keys don't match");
4247c478bd9Sstevel@tonic-gate return (-1);
4257c478bd9Sstevel@tonic-gate }
4267c478bd9Sstevel@tonic-gate return (0);
4277c478bd9Sstevel@tonic-gate }
4287c478bd9Sstevel@tonic-gate
4297c478bd9Sstevel@tonic-gate int
key_encryptsession(const char * remotename,des_block * deskey)43061961e0fSrobinson key_encryptsession(const char *remotename, des_block *deskey)
4317c478bd9Sstevel@tonic-gate {
4327c478bd9Sstevel@tonic-gate cryptkeyarg arg;
4337c478bd9Sstevel@tonic-gate cryptkeyres res;
4347c478bd9Sstevel@tonic-gate
4357c478bd9Sstevel@tonic-gate arg.remotename = (char *)remotename;
4367c478bd9Sstevel@tonic-gate arg.deskey = *deskey;
4377c478bd9Sstevel@tonic-gate if (!key_call((rpcproc_t)KEY_ENCRYPT, xdr_cryptkeyarg, (char *)&arg,
43861961e0fSrobinson xdr_cryptkeyres, (char *)&res))
4397c478bd9Sstevel@tonic-gate return (-1);
4407c478bd9Sstevel@tonic-gate if (res.status != KEY_SUCCESS) {
4417c478bd9Sstevel@tonic-gate debug("encrypt status is nonzero");
4427c478bd9Sstevel@tonic-gate return (-1);
4437c478bd9Sstevel@tonic-gate }
4447c478bd9Sstevel@tonic-gate *deskey = res.cryptkeyres_u.deskey;
4457c478bd9Sstevel@tonic-gate return (0);
4467c478bd9Sstevel@tonic-gate }
4477c478bd9Sstevel@tonic-gate
4487c478bd9Sstevel@tonic-gate int
key_encryptsession_g(const char * remotename,keylen_t keylen,algtype_t algtype,des_block deskey[],keynum_t keynum)4497c478bd9Sstevel@tonic-gate key_encryptsession_g(
4507c478bd9Sstevel@tonic-gate const char *remotename,
4517c478bd9Sstevel@tonic-gate keylen_t keylen,
4527c478bd9Sstevel@tonic-gate algtype_t algtype,
4537c478bd9Sstevel@tonic-gate des_block deskey[],
4547c478bd9Sstevel@tonic-gate keynum_t keynum
4557c478bd9Sstevel@tonic-gate )
4567c478bd9Sstevel@tonic-gate {
4577c478bd9Sstevel@tonic-gate cryptkeyarg3 arg;
4587c478bd9Sstevel@tonic-gate cryptkeyres3 res;
4597c478bd9Sstevel@tonic-gate
46061961e0fSrobinson if (CLASSIC_PK_DH(keylen, algtype))
4617c478bd9Sstevel@tonic-gate return (key_encryptsession(remotename, deskey));
4627c478bd9Sstevel@tonic-gate arg.remotename = (char *)remotename;
4637c478bd9Sstevel@tonic-gate arg.algtype = algtype;
4647c478bd9Sstevel@tonic-gate arg.keylen = keylen;
4657c478bd9Sstevel@tonic-gate arg.deskey.deskeyarray_len = keynum;
4667c478bd9Sstevel@tonic-gate arg.deskey.deskeyarray_val = deskey;
4677c478bd9Sstevel@tonic-gate arg.remotekey.keybuf3_len = 0;
46861961e0fSrobinson (void) memset(&res, 0, sizeof (res));
4697c478bd9Sstevel@tonic-gate res.cryptkeyres3_u.deskey.deskeyarray_val = deskey;
4707c478bd9Sstevel@tonic-gate if (!key_call((rpcproc_t)KEY_ENCRYPT_3, xdr_cryptkeyarg3, (char *)&arg,
47161961e0fSrobinson xdr_cryptkeyres3, (char *)&res))
4727c478bd9Sstevel@tonic-gate return (-1);
4737c478bd9Sstevel@tonic-gate if (res.status != KEY_SUCCESS) {
4747c478bd9Sstevel@tonic-gate debug("encrypt3 status is nonzero");
4757c478bd9Sstevel@tonic-gate return (-1);
4767c478bd9Sstevel@tonic-gate }
4777c478bd9Sstevel@tonic-gate if (res.cryptkeyres3_u.deskey.deskeyarray_len != keynum) {
4787c478bd9Sstevel@tonic-gate debug("encrypt3 didn't return same number of keys");
4797c478bd9Sstevel@tonic-gate return (-1);
4807c478bd9Sstevel@tonic-gate }
4817c478bd9Sstevel@tonic-gate return (0);
4827c478bd9Sstevel@tonic-gate }
4837c478bd9Sstevel@tonic-gate
4847c478bd9Sstevel@tonic-gate
4857c478bd9Sstevel@tonic-gate int
key_decryptsession(const char * remotename,des_block * deskey)48661961e0fSrobinson key_decryptsession(const char *remotename, des_block *deskey)
4877c478bd9Sstevel@tonic-gate {
4887c478bd9Sstevel@tonic-gate cryptkeyarg arg;
4897c478bd9Sstevel@tonic-gate cryptkeyres res;
4907c478bd9Sstevel@tonic-gate
4917c478bd9Sstevel@tonic-gate arg.remotename = (char *)remotename;
4927c478bd9Sstevel@tonic-gate arg.deskey = *deskey;
4937c478bd9Sstevel@tonic-gate if (!key_call((rpcproc_t)KEY_DECRYPT, xdr_cryptkeyarg, (char *)&arg,
49461961e0fSrobinson xdr_cryptkeyres, (char *)&res))
4957c478bd9Sstevel@tonic-gate return (-1);
4967c478bd9Sstevel@tonic-gate if (res.status != KEY_SUCCESS) {
4977c478bd9Sstevel@tonic-gate debug("decrypt status is nonzero");
4987c478bd9Sstevel@tonic-gate return (-1);
4997c478bd9Sstevel@tonic-gate }
5007c478bd9Sstevel@tonic-gate *deskey = res.cryptkeyres_u.deskey;
5017c478bd9Sstevel@tonic-gate return (0);
5027c478bd9Sstevel@tonic-gate }
5037c478bd9Sstevel@tonic-gate
5047c478bd9Sstevel@tonic-gate int
key_decryptsession_g(const char * remotename,keylen_t keylen,algtype_t algtype,des_block deskey[],keynum_t keynum)5057c478bd9Sstevel@tonic-gate key_decryptsession_g(
5067c478bd9Sstevel@tonic-gate const char *remotename,
5077c478bd9Sstevel@tonic-gate keylen_t keylen,
5087c478bd9Sstevel@tonic-gate algtype_t algtype,
5097c478bd9Sstevel@tonic-gate des_block deskey[],
5107c478bd9Sstevel@tonic-gate keynum_t keynum
5117c478bd9Sstevel@tonic-gate )
5127c478bd9Sstevel@tonic-gate {
5137c478bd9Sstevel@tonic-gate cryptkeyarg3 arg;
5147c478bd9Sstevel@tonic-gate cryptkeyres3 res;
5157c478bd9Sstevel@tonic-gate
51661961e0fSrobinson if (CLASSIC_PK_DH(keylen, algtype))
5177c478bd9Sstevel@tonic-gate return (key_decryptsession(remotename, deskey));
5187c478bd9Sstevel@tonic-gate arg.remotename = (char *)remotename;
5197c478bd9Sstevel@tonic-gate arg.algtype = algtype;
5207c478bd9Sstevel@tonic-gate arg.keylen = keylen;
5217c478bd9Sstevel@tonic-gate arg.deskey.deskeyarray_len = keynum;
5227c478bd9Sstevel@tonic-gate arg.deskey.deskeyarray_val = deskey;
5237c478bd9Sstevel@tonic-gate arg.remotekey.keybuf3_len = 0;
52461961e0fSrobinson (void) memset(&res, 0, sizeof (res));
5257c478bd9Sstevel@tonic-gate res.cryptkeyres3_u.deskey.deskeyarray_val = deskey;
5267c478bd9Sstevel@tonic-gate if (!key_call((rpcproc_t)KEY_DECRYPT_3, xdr_cryptkeyarg3, (char *)&arg,
52761961e0fSrobinson xdr_cryptkeyres3, (char *)&res))
5287c478bd9Sstevel@tonic-gate return (-1);
5297c478bd9Sstevel@tonic-gate if (res.status != KEY_SUCCESS) {
5307c478bd9Sstevel@tonic-gate debug("decrypt3 status is nonzero");
5317c478bd9Sstevel@tonic-gate return (-1);
5327c478bd9Sstevel@tonic-gate }
5337c478bd9Sstevel@tonic-gate if (res.cryptkeyres3_u.deskey.deskeyarray_len != keynum) {
5347c478bd9Sstevel@tonic-gate debug("decrypt3 didn't return same number of keys");
5357c478bd9Sstevel@tonic-gate return (-1);
5367c478bd9Sstevel@tonic-gate }
5377c478bd9Sstevel@tonic-gate return (0);
5387c478bd9Sstevel@tonic-gate }
5397c478bd9Sstevel@tonic-gate
5407c478bd9Sstevel@tonic-gate int
key_gendes(des_block * key)54161961e0fSrobinson key_gendes(des_block *key)
5427c478bd9Sstevel@tonic-gate {
54361961e0fSrobinson if (!key_call((rpcproc_t)KEY_GEN, xdr_void, NULL,
54461961e0fSrobinson xdr_des_block, (char *)key))
5457c478bd9Sstevel@tonic-gate return (-1);
5467c478bd9Sstevel@tonic-gate return (0);
5477c478bd9Sstevel@tonic-gate }
5487c478bd9Sstevel@tonic-gate
5497c478bd9Sstevel@tonic-gate int
key_gendes_g(des_block deskey[],keynum_t keynum)5507c478bd9Sstevel@tonic-gate key_gendes_g(
5517c478bd9Sstevel@tonic-gate des_block deskey[],
5527c478bd9Sstevel@tonic-gate keynum_t keynum
5537c478bd9Sstevel@tonic-gate )
5547c478bd9Sstevel@tonic-gate {
5557c478bd9Sstevel@tonic-gate deskeyarray res;
5567c478bd9Sstevel@tonic-gate
5577c478bd9Sstevel@tonic-gate res.deskeyarray_val = deskey;
5587c478bd9Sstevel@tonic-gate if (!key_call((rpcproc_t)KEY_GEN_3, xdr_keynum_t, (char *)&keynum,
55961961e0fSrobinson xdr_deskeyarray, (char *)&res))
5607c478bd9Sstevel@tonic-gate return (-1);
5617c478bd9Sstevel@tonic-gate if (res.deskeyarray_len != keynum) {
5627c478bd9Sstevel@tonic-gate debug("return length doesn't match\n");
5637c478bd9Sstevel@tonic-gate return (-1);
5647c478bd9Sstevel@tonic-gate }
5657c478bd9Sstevel@tonic-gate return (0);
5667c478bd9Sstevel@tonic-gate }
5677c478bd9Sstevel@tonic-gate
5687c478bd9Sstevel@tonic-gate /*
5697c478bd9Sstevel@tonic-gate * Call KEY_NET_PUT Operation to the keyserv.
5707c478bd9Sstevel@tonic-gate *
5717c478bd9Sstevel@tonic-gate * If use_ruid == 0, use effective uid.
5727c478bd9Sstevel@tonic-gate * If use_ruid == 1, use real uid.
5737c478bd9Sstevel@tonic-gate */
5747c478bd9Sstevel@tonic-gate int
key_setnet_ext(struct key_netstarg * arg,int use_ruid)5757c478bd9Sstevel@tonic-gate key_setnet_ext(struct key_netstarg *arg, int use_ruid)
5767c478bd9Sstevel@tonic-gate {
5777c478bd9Sstevel@tonic-gate keystatus status;
5787c478bd9Sstevel@tonic-gate
5797c478bd9Sstevel@tonic-gate if (!key_call_ext((rpcproc_t)KEY_NET_PUT, xdr_key_netstarg,
58061961e0fSrobinson (char *)arg, xdr_keystatus, (char *)&status, use_ruid))
5817c478bd9Sstevel@tonic-gate return (-1);
5827c478bd9Sstevel@tonic-gate
5837c478bd9Sstevel@tonic-gate if (status != KEY_SUCCESS) {
5847c478bd9Sstevel@tonic-gate debug("key_setnet status is nonzero");
5857c478bd9Sstevel@tonic-gate return (-1);
5867c478bd9Sstevel@tonic-gate }
5877c478bd9Sstevel@tonic-gate return (1);
5887c478bd9Sstevel@tonic-gate }
5897c478bd9Sstevel@tonic-gate
5907c478bd9Sstevel@tonic-gate /*
5917c478bd9Sstevel@tonic-gate * Use effective uid.
5927c478bd9Sstevel@tonic-gate */
5937c478bd9Sstevel@tonic-gate int
key_setnet(struct key_netstarg * arg)5947c478bd9Sstevel@tonic-gate key_setnet(struct key_netstarg *arg)
5957c478bd9Sstevel@tonic-gate {
5967c478bd9Sstevel@tonic-gate return (key_setnet_ext(arg, 0));
5977c478bd9Sstevel@tonic-gate }
5987c478bd9Sstevel@tonic-gate
5997c478bd9Sstevel@tonic-gate /*
6007c478bd9Sstevel@tonic-gate * Use real uid.
6017c478bd9Sstevel@tonic-gate */
6027c478bd9Sstevel@tonic-gate int
key_setnet_ruid(struct key_netstarg * arg)6037c478bd9Sstevel@tonic-gate key_setnet_ruid(struct key_netstarg *arg)
6047c478bd9Sstevel@tonic-gate {
6057c478bd9Sstevel@tonic-gate return (key_setnet_ext(arg, 1));
6067c478bd9Sstevel@tonic-gate }
6077c478bd9Sstevel@tonic-gate
6087c478bd9Sstevel@tonic-gate /*
6097c478bd9Sstevel@tonic-gate * Input netname, secret and public keys (hex string representation)
6107c478bd9Sstevel@tonic-gate * of length skeylen/pkeylen (bits), and algorithm type. One, but not
6117c478bd9Sstevel@tonic-gate * both, of skey or pkey may have zero length. If both lengths are
6127c478bd9Sstevel@tonic-gate * specified, they must be the same.
6137c478bd9Sstevel@tonic-gate *
6147c478bd9Sstevel@tonic-gate * Call KEY_NET_PUT_3 Operation to the keyserv.
6157c478bd9Sstevel@tonic-gate * Stores the specified netname/pkey/skey triplet in the keyserv.
6167c478bd9Sstevel@tonic-gate *
6177c478bd9Sstevel@tonic-gate * If (use_ruid == 1), use real uid.
6187c478bd9Sstevel@tonic-gate * If (use_ruid == 0), use effective uid.
6197c478bd9Sstevel@tonic-gate */
6207c478bd9Sstevel@tonic-gate int
key_setnet_g_ext(const char * netname,const char * skey,keylen_t skeylen,const char * pkey,keylen_t pkeylen,algtype_t algtype,int use_ruid)6217c478bd9Sstevel@tonic-gate key_setnet_g_ext(
6227c478bd9Sstevel@tonic-gate const char *netname,
6237c478bd9Sstevel@tonic-gate const char *skey,
6247c478bd9Sstevel@tonic-gate keylen_t skeylen,
6257c478bd9Sstevel@tonic-gate const char *pkey,
6267c478bd9Sstevel@tonic-gate keylen_t pkeylen,
6277c478bd9Sstevel@tonic-gate algtype_t algtype,
6287c478bd9Sstevel@tonic-gate int use_ruid)
6297c478bd9Sstevel@tonic-gate {
6307c478bd9Sstevel@tonic-gate key_netstarg3 arg;
6317c478bd9Sstevel@tonic-gate keystatus status;
6327c478bd9Sstevel@tonic-gate
6337c478bd9Sstevel@tonic-gate arg.st_netname = (char *)netname;
6347c478bd9Sstevel@tonic-gate arg.algtype = algtype;
6357c478bd9Sstevel@tonic-gate if (skeylen == 0) {
6367c478bd9Sstevel@tonic-gate arg.st_priv_key.keybuf3_len = 0;
6377c478bd9Sstevel@tonic-gate } else {
6387c478bd9Sstevel@tonic-gate arg.st_priv_key.keybuf3_len = skeylen/4 + 1;
6397c478bd9Sstevel@tonic-gate }
6407c478bd9Sstevel@tonic-gate arg.st_priv_key.keybuf3_val = (char *)skey;
6417c478bd9Sstevel@tonic-gate if (pkeylen == 0) {
6427c478bd9Sstevel@tonic-gate arg.st_pub_key.keybuf3_len = 0;
6437c478bd9Sstevel@tonic-gate } else {
6447c478bd9Sstevel@tonic-gate arg.st_pub_key.keybuf3_len = pkeylen/4 + 1;
6457c478bd9Sstevel@tonic-gate }
6467c478bd9Sstevel@tonic-gate arg.st_pub_key.keybuf3_val = (char *)pkey;
6477c478bd9Sstevel@tonic-gate if (skeylen == 0) {
6487c478bd9Sstevel@tonic-gate if (pkeylen == 0) {
6497c478bd9Sstevel@tonic-gate debug("keylens are both 0");
6507c478bd9Sstevel@tonic-gate return (-1);
6517c478bd9Sstevel@tonic-gate }
6527c478bd9Sstevel@tonic-gate arg.keylen = pkeylen;
6537c478bd9Sstevel@tonic-gate } else {
6547c478bd9Sstevel@tonic-gate if ((pkeylen != 0) && (skeylen != pkeylen)) {
6557c478bd9Sstevel@tonic-gate debug("keylens don't match");
6567c478bd9Sstevel@tonic-gate return (-1);
6577c478bd9Sstevel@tonic-gate }
6587c478bd9Sstevel@tonic-gate arg.keylen = skeylen;
6597c478bd9Sstevel@tonic-gate }
6607c478bd9Sstevel@tonic-gate if (CLASSIC_PK_DH(arg.keylen, arg.algtype)) {
6617c478bd9Sstevel@tonic-gate key_netstarg tmp;
6627c478bd9Sstevel@tonic-gate
6637c478bd9Sstevel@tonic-gate if (skeylen != 0) {
66461961e0fSrobinson (void) memcpy(&tmp.st_priv_key, skey,
6657c478bd9Sstevel@tonic-gate sizeof (tmp.st_priv_key));
6667c478bd9Sstevel@tonic-gate } else {
66761961e0fSrobinson (void) memset(&tmp.st_priv_key, 0,
66861961e0fSrobinson sizeof (tmp.st_priv_key));
6697c478bd9Sstevel@tonic-gate }
6707c478bd9Sstevel@tonic-gate if (pkeylen != 0) {
67161961e0fSrobinson (void) memcpy(&tmp.st_pub_key, skey,
67261961e0fSrobinson sizeof (tmp.st_pub_key));
6737c478bd9Sstevel@tonic-gate } else {
67461961e0fSrobinson (void) memset(&tmp.st_pub_key, 0,
67561961e0fSrobinson sizeof (tmp.st_pub_key));
6767c478bd9Sstevel@tonic-gate }
6777c478bd9Sstevel@tonic-gate tmp.st_netname = (char *)netname;
6787c478bd9Sstevel@tonic-gate return (key_setnet(&tmp));
6797c478bd9Sstevel@tonic-gate }
6807c478bd9Sstevel@tonic-gate if (!key_call_ext((rpcproc_t)KEY_NET_PUT_3,
6817c478bd9Sstevel@tonic-gate xdr_key_netstarg3, (char *)&arg,
6827c478bd9Sstevel@tonic-gate xdr_keystatus, (char *)&status, use_ruid)) {
6837c478bd9Sstevel@tonic-gate return (-1);
6847c478bd9Sstevel@tonic-gate }
6857c478bd9Sstevel@tonic-gate
6867c478bd9Sstevel@tonic-gate if (status != KEY_SUCCESS) {
6877c478bd9Sstevel@tonic-gate debug("key_setnet3 status is nonzero");
6887c478bd9Sstevel@tonic-gate return (-1);
6897c478bd9Sstevel@tonic-gate }
6907c478bd9Sstevel@tonic-gate return (0);
6917c478bd9Sstevel@tonic-gate }
6927c478bd9Sstevel@tonic-gate
6937c478bd9Sstevel@tonic-gate /*
6947c478bd9Sstevel@tonic-gate * Use effective uid.
6957c478bd9Sstevel@tonic-gate */
6967c478bd9Sstevel@tonic-gate int
key_setnet_g(const char * netname,const char * skey,keylen_t skeylen,const char * pkey,keylen_t pkeylen,algtype_t algtype)6977c478bd9Sstevel@tonic-gate key_setnet_g(const char *netname, const char *skey, keylen_t skeylen,
6987c478bd9Sstevel@tonic-gate const char *pkey, keylen_t pkeylen, algtype_t algtype)
6997c478bd9Sstevel@tonic-gate {
7007c478bd9Sstevel@tonic-gate return (key_setnet_g_ext(netname, skey, skeylen, pkey, pkeylen,
7017c478bd9Sstevel@tonic-gate algtype, 0));
7027c478bd9Sstevel@tonic-gate }
7037c478bd9Sstevel@tonic-gate
7047c478bd9Sstevel@tonic-gate /*
7057c478bd9Sstevel@tonic-gate * Use real uid.
7067c478bd9Sstevel@tonic-gate */
7077c478bd9Sstevel@tonic-gate int
key_setnet_g_ruid(const char * netname,const char * skey,keylen_t skeylen,const char * pkey,keylen_t pkeylen,algtype_t algtype)7087c478bd9Sstevel@tonic-gate key_setnet_g_ruid(const char *netname, const char *skey, keylen_t skeylen,
7097c478bd9Sstevel@tonic-gate const char *pkey, keylen_t pkeylen, algtype_t algtype)
7107c478bd9Sstevel@tonic-gate {
7117c478bd9Sstevel@tonic-gate return (key_setnet_g_ext(netname, skey, skeylen, pkey, pkeylen,
7127c478bd9Sstevel@tonic-gate algtype, 1));
7137c478bd9Sstevel@tonic-gate }
7147c478bd9Sstevel@tonic-gate
7157c478bd9Sstevel@tonic-gate int
key_get_conv(char * pkey,des_block * deskey)71661961e0fSrobinson key_get_conv(char *pkey, des_block *deskey)
7177c478bd9Sstevel@tonic-gate {
7187c478bd9Sstevel@tonic-gate cryptkeyres res;
7197c478bd9Sstevel@tonic-gate
7207c478bd9Sstevel@tonic-gate if (!key_call((rpcproc_t)KEY_GET_CONV, xdr_keybuf, pkey,
72161961e0fSrobinson xdr_cryptkeyres, (char *)&res))
7227c478bd9Sstevel@tonic-gate return (-1);
7237c478bd9Sstevel@tonic-gate if (res.status != KEY_SUCCESS) {
7247c478bd9Sstevel@tonic-gate debug("get_conv status is nonzero");
7257c478bd9Sstevel@tonic-gate return (-1);
7267c478bd9Sstevel@tonic-gate }
7277c478bd9Sstevel@tonic-gate *deskey = res.cryptkeyres_u.deskey;
7287c478bd9Sstevel@tonic-gate return (0);
7297c478bd9Sstevel@tonic-gate }
7307c478bd9Sstevel@tonic-gate
7317c478bd9Sstevel@tonic-gate int
key_get_conv_g(const char * pkey,keylen_t pkeylen,algtype_t algtype,des_block deskey[],keynum_t keynum)7327c478bd9Sstevel@tonic-gate key_get_conv_g(
7337c478bd9Sstevel@tonic-gate const char *pkey,
7347c478bd9Sstevel@tonic-gate keylen_t pkeylen,
7357c478bd9Sstevel@tonic-gate algtype_t algtype,
7367c478bd9Sstevel@tonic-gate des_block deskey[],
7377c478bd9Sstevel@tonic-gate keynum_t keynum
7387c478bd9Sstevel@tonic-gate )
7397c478bd9Sstevel@tonic-gate {
7407c478bd9Sstevel@tonic-gate deskeyarg3 arg;
7417c478bd9Sstevel@tonic-gate cryptkeyres3 res;
7427c478bd9Sstevel@tonic-gate
74361961e0fSrobinson if (CLASSIC_PK_DH(pkeylen, algtype))
7447c478bd9Sstevel@tonic-gate return (key_get_conv((char *)pkey, deskey));
7457c478bd9Sstevel@tonic-gate arg.pub_key.keybuf3_len = pkeylen/4 + 1;
7467c478bd9Sstevel@tonic-gate arg.pub_key.keybuf3_val = (char *)pkey;
7477c478bd9Sstevel@tonic-gate arg.nkeys = keynum;
7487c478bd9Sstevel@tonic-gate arg.algtype = algtype;
7497c478bd9Sstevel@tonic-gate arg.keylen = pkeylen;
75061961e0fSrobinson (void) memset(&res, 0, sizeof (res));
7517c478bd9Sstevel@tonic-gate res.cryptkeyres3_u.deskey.deskeyarray_val = deskey;
7527c478bd9Sstevel@tonic-gate if (!key_call((rpcproc_t)KEY_GET_CONV_3, xdr_deskeyarg3, (char *)&arg,
75361961e0fSrobinson xdr_cryptkeyres3, (char *)&res))
7547c478bd9Sstevel@tonic-gate return (-1);
7557c478bd9Sstevel@tonic-gate if (res.status != KEY_SUCCESS) {
7567c478bd9Sstevel@tonic-gate debug("get_conv3 status is nonzero");
7577c478bd9Sstevel@tonic-gate return (-1);
7587c478bd9Sstevel@tonic-gate }
7597c478bd9Sstevel@tonic-gate if (res.cryptkeyres3_u.deskey.deskeyarray_len != keynum) {
7607c478bd9Sstevel@tonic-gate debug("get_conv3 number of keys dont match");
7617c478bd9Sstevel@tonic-gate return (-1);
7627c478bd9Sstevel@tonic-gate }
7637c478bd9Sstevel@tonic-gate return (0);
7647c478bd9Sstevel@tonic-gate }
7657c478bd9Sstevel@tonic-gate
7667c478bd9Sstevel@tonic-gate struct key_call_private {
7677c478bd9Sstevel@tonic-gate CLIENT *client; /* Client handle */
7687c478bd9Sstevel@tonic-gate pid_t pid; /* process-id at moment of creation */
7697c478bd9Sstevel@tonic-gate int fd; /* client handle fd */
7707c478bd9Sstevel@tonic-gate dev_t rdev; /* device client handle is using */
7717c478bd9Sstevel@tonic-gate };
7727c478bd9Sstevel@tonic-gate
7737c478bd9Sstevel@tonic-gate static void set_rdev(struct key_call_private *);
7747c478bd9Sstevel@tonic-gate static int check_rdev(struct key_call_private *);
7757c478bd9Sstevel@tonic-gate
7767c478bd9Sstevel@tonic-gate static void
key_call_destroy(void * vp)7777c478bd9Sstevel@tonic-gate key_call_destroy(void *vp)
7787c478bd9Sstevel@tonic-gate {
7797c478bd9Sstevel@tonic-gate struct key_call_private *kcp = (struct key_call_private *)vp;
7807c478bd9Sstevel@tonic-gate
7817c478bd9Sstevel@tonic-gate if (kcp != NULL && kcp->client != NULL) {
78261961e0fSrobinson (void) check_rdev(kcp);
7837c478bd9Sstevel@tonic-gate clnt_destroy(kcp->client);
7847c478bd9Sstevel@tonic-gate free(kcp);
7857c478bd9Sstevel@tonic-gate }
7867c478bd9Sstevel@tonic-gate }
7877c478bd9Sstevel@tonic-gate
788*cb620785Sraf static pthread_key_t key_call_key = PTHREAD_ONCE_KEY_NP;
7897c478bd9Sstevel@tonic-gate
7907c478bd9Sstevel@tonic-gate void
_key_call_fini(void)7917c478bd9Sstevel@tonic-gate _key_call_fini(void)
7927c478bd9Sstevel@tonic-gate {
793*cb620785Sraf struct key_call_private *kcp;
7947c478bd9Sstevel@tonic-gate
795*cb620785Sraf if ((kcp = pthread_getspecific(key_call_key)) != NULL) {
7967c478bd9Sstevel@tonic-gate key_call_destroy(kcp);
7977c478bd9Sstevel@tonic-gate (void) pthread_setspecific(key_call_key, NULL);
7987c478bd9Sstevel@tonic-gate }
7997c478bd9Sstevel@tonic-gate }
8007c478bd9Sstevel@tonic-gate
8017c478bd9Sstevel@tonic-gate /*
8027c478bd9Sstevel@tonic-gate * Keep the handle cached. This call may be made quite often.
8037c478bd9Sstevel@tonic-gate */
8047c478bd9Sstevel@tonic-gate static CLIENT *
getkeyserv_handle(int vers,int stale)8057c478bd9Sstevel@tonic-gate getkeyserv_handle(int vers, int stale)
8067c478bd9Sstevel@tonic-gate {
8077c478bd9Sstevel@tonic-gate struct key_call_private *kcp = NULL;
8087c478bd9Sstevel@tonic-gate int _update_did();
8097c478bd9Sstevel@tonic-gate
8107c478bd9Sstevel@tonic-gate kcp = thr_get_storage(&key_call_key, sizeof (*kcp), key_call_destroy);
8117c478bd9Sstevel@tonic-gate if (kcp == NULL) {
8127c478bd9Sstevel@tonic-gate syslog(LOG_CRIT, "getkeyserv_handle: out of memory");
8137c478bd9Sstevel@tonic-gate return (NULL);
8147c478bd9Sstevel@tonic-gate }
8157c478bd9Sstevel@tonic-gate
8167c478bd9Sstevel@tonic-gate /*
8177c478bd9Sstevel@tonic-gate * if pid has changed, destroy client and rebuild
8187c478bd9Sstevel@tonic-gate * or if stale is '1' then destroy client and rebuild
8197c478bd9Sstevel@tonic-gate */
8207c478bd9Sstevel@tonic-gate if (kcp->client &&
8217c478bd9Sstevel@tonic-gate (!check_rdev(kcp) || kcp->pid != getpid() || stale)) {
8227c478bd9Sstevel@tonic-gate clnt_destroy(kcp->client);
8237c478bd9Sstevel@tonic-gate kcp->client = NULL;
8247c478bd9Sstevel@tonic-gate }
8257c478bd9Sstevel@tonic-gate if (kcp->client) {
8267c478bd9Sstevel@tonic-gate int fd;
8277c478bd9Sstevel@tonic-gate /*
8287c478bd9Sstevel@tonic-gate * Change the version number to the new one.
8297c478bd9Sstevel@tonic-gate */
8307c478bd9Sstevel@tonic-gate clnt_control(kcp->client, CLSET_VERS, (void *)&vers);
8317c478bd9Sstevel@tonic-gate if (!_update_did(kcp->client, vers)) {
8327c478bd9Sstevel@tonic-gate if (rpc_createerr.cf_stat == RPC_SYSTEMERROR)
8337c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, "getkeyserv_handle: "
8347c478bd9Sstevel@tonic-gate "out of memory!");
8357c478bd9Sstevel@tonic-gate return (NULL);
8367c478bd9Sstevel@tonic-gate }
8377c478bd9Sstevel@tonic-gate /* Update fd in kcp because it was reopened in _update_did */
8387c478bd9Sstevel@tonic-gate if (clnt_control(kcp->client, CLGET_FD, (void *)&fd) &&
8397c478bd9Sstevel@tonic-gate (fd >= 0))
840e8031f0aSraf (void) fcntl(fd, F_SETFD, FD_CLOEXEC); /* close exec */
8417c478bd9Sstevel@tonic-gate kcp->fd = fd;
8427c478bd9Sstevel@tonic-gate return (kcp->client);
8437c478bd9Sstevel@tonic-gate }
8447c478bd9Sstevel@tonic-gate
8457c478bd9Sstevel@tonic-gate if ((kcp->client = clnt_door_create(KEY_PROG, vers, 0)) == NULL)
8467c478bd9Sstevel@tonic-gate return (NULL);
8477c478bd9Sstevel@tonic-gate
8487c478bd9Sstevel@tonic-gate kcp->pid = getpid();
8497c478bd9Sstevel@tonic-gate set_rdev(kcp);
850e8031f0aSraf (void) fcntl(kcp->fd, F_SETFD, FD_CLOEXEC); /* close on exec */
8517c478bd9Sstevel@tonic-gate
8527c478bd9Sstevel@tonic-gate return (kcp->client);
8537c478bd9Sstevel@tonic-gate }
8547c478bd9Sstevel@tonic-gate
8557c478bd9Sstevel@tonic-gate /*
8567c478bd9Sstevel@tonic-gate * RPC calls to the keyserv.
8577c478bd9Sstevel@tonic-gate *
8587c478bd9Sstevel@tonic-gate * If (use_ruid == 1), use real uid.
8597c478bd9Sstevel@tonic-gate * If (use_ruid == 0), use effective uid.
8607c478bd9Sstevel@tonic-gate * Returns 0 on failure, 1 on success
8617c478bd9Sstevel@tonic-gate */
8627c478bd9Sstevel@tonic-gate int
key_call_ext(rpcproc_t proc,xdrproc_t xdr_arg,char * arg,xdrproc_t xdr_rslt,char * rslt,int use_ruid)86361961e0fSrobinson key_call_ext(rpcproc_t proc, xdrproc_t xdr_arg, char *arg, xdrproc_t xdr_rslt,
86461961e0fSrobinson char *rslt, int use_ruid)
8657c478bd9Sstevel@tonic-gate {
8667c478bd9Sstevel@tonic-gate CLIENT *clnt;
8677c478bd9Sstevel@tonic-gate struct timeval wait_time = {0, 0};
8687c478bd9Sstevel@tonic-gate enum clnt_stat status;
8697c478bd9Sstevel@tonic-gate int vers;
8707c478bd9Sstevel@tonic-gate
8717c478bd9Sstevel@tonic-gate if (proc == KEY_ENCRYPT_PK && __key_encryptsession_pk_LOCAL) {
8727c478bd9Sstevel@tonic-gate cryptkeyres res;
8737c478bd9Sstevel@tonic-gate bool_t r;
8747c478bd9Sstevel@tonic-gate r = (*__key_encryptsession_pk_LOCAL)(geteuid(), arg, &res);
8757c478bd9Sstevel@tonic-gate if (r == TRUE) {
8767c478bd9Sstevel@tonic-gate /* LINTED pointer alignment */
8777c478bd9Sstevel@tonic-gate *(cryptkeyres*)rslt = res;
8787c478bd9Sstevel@tonic-gate return (1);
8797c478bd9Sstevel@tonic-gate }
8807c478bd9Sstevel@tonic-gate return (0);
8817c478bd9Sstevel@tonic-gate }
8827c478bd9Sstevel@tonic-gate if (proc == KEY_DECRYPT_PK && __key_decryptsession_pk_LOCAL) {
8837c478bd9Sstevel@tonic-gate cryptkeyres res;
8847c478bd9Sstevel@tonic-gate bool_t r;
8857c478bd9Sstevel@tonic-gate r = (*__key_decryptsession_pk_LOCAL)(geteuid(), arg, &res);
8867c478bd9Sstevel@tonic-gate if (r == TRUE) {
8877c478bd9Sstevel@tonic-gate /* LINTED pointer alignment */
8887c478bd9Sstevel@tonic-gate *(cryptkeyres*)rslt = res;
8897c478bd9Sstevel@tonic-gate return (1);
8907c478bd9Sstevel@tonic-gate }
8917c478bd9Sstevel@tonic-gate return (0);
8927c478bd9Sstevel@tonic-gate }
8937c478bd9Sstevel@tonic-gate if (proc == KEY_GEN && __key_gendes_LOCAL) {
8947c478bd9Sstevel@tonic-gate des_block res;
8957c478bd9Sstevel@tonic-gate bool_t r;
8967c478bd9Sstevel@tonic-gate r = (*__key_gendes_LOCAL)(geteuid(), 0, &res);
8977c478bd9Sstevel@tonic-gate if (r == TRUE) {
8987c478bd9Sstevel@tonic-gate /* LINTED pointer alignment */
8997c478bd9Sstevel@tonic-gate *(des_block*)rslt = res;
9007c478bd9Sstevel@tonic-gate return (1);
9017c478bd9Sstevel@tonic-gate }
9027c478bd9Sstevel@tonic-gate return (0);
9037c478bd9Sstevel@tonic-gate }
9047c478bd9Sstevel@tonic-gate
9057c478bd9Sstevel@tonic-gate if ((proc == KEY_ENCRYPT_PK) || (proc == KEY_DECRYPT_PK) ||
9067c478bd9Sstevel@tonic-gate (proc == KEY_NET_GET) || (proc == KEY_NET_PUT) ||
9077c478bd9Sstevel@tonic-gate (proc == KEY_GET_CONV))
9087c478bd9Sstevel@tonic-gate vers = 2; /* talk to version 2 */
9097c478bd9Sstevel@tonic-gate else
9107c478bd9Sstevel@tonic-gate vers = 1; /* talk to version 1 */
9117c478bd9Sstevel@tonic-gate
9127c478bd9Sstevel@tonic-gate clnt = getkeyserv_handle(vers, 0);
9137c478bd9Sstevel@tonic-gate if (clnt == NULL)
9147c478bd9Sstevel@tonic-gate return (0);
9157c478bd9Sstevel@tonic-gate
9167c478bd9Sstevel@tonic-gate auth_destroy(clnt->cl_auth);
9177c478bd9Sstevel@tonic-gate if (use_ruid)
9187c478bd9Sstevel@tonic-gate clnt->cl_auth = authsys_create_ruid();
9197c478bd9Sstevel@tonic-gate else
9207c478bd9Sstevel@tonic-gate clnt->cl_auth = authnone_create();
9217c478bd9Sstevel@tonic-gate
9227c478bd9Sstevel@tonic-gate status = CLNT_CALL(clnt, proc, xdr_arg, arg, xdr_rslt,
9237c478bd9Sstevel@tonic-gate rslt, wait_time);
9247c478bd9Sstevel@tonic-gate
9257c478bd9Sstevel@tonic-gate switch (status) {
9267c478bd9Sstevel@tonic-gate case RPC_SUCCESS:
9277c478bd9Sstevel@tonic-gate return (1);
9287c478bd9Sstevel@tonic-gate
9297c478bd9Sstevel@tonic-gate case RPC_CANTRECV:
9307c478bd9Sstevel@tonic-gate /*
9317c478bd9Sstevel@tonic-gate * keyserv was probably restarted, so we'll try once more
9327c478bd9Sstevel@tonic-gate */
9337c478bd9Sstevel@tonic-gate if ((clnt = getkeyserv_handle(vers, 1)) == NULL)
9347c478bd9Sstevel@tonic-gate return (0);
9357c478bd9Sstevel@tonic-gate
9367c478bd9Sstevel@tonic-gate auth_destroy(clnt->cl_auth);
9377c478bd9Sstevel@tonic-gate if (use_ruid)
9387c478bd9Sstevel@tonic-gate clnt->cl_auth = authsys_create_ruid();
9397c478bd9Sstevel@tonic-gate else
9407c478bd9Sstevel@tonic-gate clnt->cl_auth = authnone_create();
9417c478bd9Sstevel@tonic-gate
9427c478bd9Sstevel@tonic-gate
9437c478bd9Sstevel@tonic-gate if (CLNT_CALL(clnt, proc, xdr_arg, arg, xdr_rslt, rslt,
9447c478bd9Sstevel@tonic-gate wait_time) == RPC_SUCCESS)
9457c478bd9Sstevel@tonic-gate return (1);
9467c478bd9Sstevel@tonic-gate return (0);
9477c478bd9Sstevel@tonic-gate
9487c478bd9Sstevel@tonic-gate default:
9497c478bd9Sstevel@tonic-gate return (0);
9507c478bd9Sstevel@tonic-gate }
9517c478bd9Sstevel@tonic-gate }
9527c478bd9Sstevel@tonic-gate
9537c478bd9Sstevel@tonic-gate /*
9547c478bd9Sstevel@tonic-gate * Use effective uid.
9557c478bd9Sstevel@tonic-gate */
9567c478bd9Sstevel@tonic-gate int
key_call(rpcproc_t proc,xdrproc_t xdr_arg,char * arg,xdrproc_t xdr_rslt,char * rslt)9577c478bd9Sstevel@tonic-gate key_call(rpcproc_t proc, xdrproc_t xdr_arg, char *arg, xdrproc_t xdr_rslt,
9587c478bd9Sstevel@tonic-gate char *rslt)
9597c478bd9Sstevel@tonic-gate {
9607c478bd9Sstevel@tonic-gate return (key_call_ext(proc, xdr_arg, arg, xdr_rslt, rslt, 0));
9617c478bd9Sstevel@tonic-gate }
9627c478bd9Sstevel@tonic-gate
9637c478bd9Sstevel@tonic-gate /*
9647c478bd9Sstevel@tonic-gate * Use real uid.
9657c478bd9Sstevel@tonic-gate */
9667c478bd9Sstevel@tonic-gate int
key_call_ruid(rpcproc_t proc,xdrproc_t xdr_arg,char * arg,xdrproc_t xdr_rslt,char * rslt)9677c478bd9Sstevel@tonic-gate key_call_ruid(rpcproc_t proc, xdrproc_t xdr_arg, char *arg,
9687c478bd9Sstevel@tonic-gate xdrproc_t xdr_rslt, char *rslt)
9697c478bd9Sstevel@tonic-gate {
9707c478bd9Sstevel@tonic-gate return (key_call_ext(proc, xdr_arg, arg, xdr_rslt, rslt, 1));
9717c478bd9Sstevel@tonic-gate }
9727c478bd9Sstevel@tonic-gate
97361961e0fSrobinson static void
set_rdev(struct key_call_private * kcp)97461961e0fSrobinson set_rdev(struct key_call_private *kcp)
9757c478bd9Sstevel@tonic-gate {
9767c478bd9Sstevel@tonic-gate int fd;
9777c478bd9Sstevel@tonic-gate struct stat stbuf;
9787c478bd9Sstevel@tonic-gate
9797c478bd9Sstevel@tonic-gate if (clnt_control(kcp->client, CLGET_FD, (char *)&fd) != TRUE ||
980e8031f0aSraf fstat(fd, &stbuf) == -1) {
9817c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, "keyserv_client: can't get info");
9827c478bd9Sstevel@tonic-gate kcp->fd = -1;
9837c478bd9Sstevel@tonic-gate return;
9847c478bd9Sstevel@tonic-gate }
9857c478bd9Sstevel@tonic-gate kcp->fd = fd;
9867c478bd9Sstevel@tonic-gate kcp->rdev = stbuf.st_rdev;
9877c478bd9Sstevel@tonic-gate }
9887c478bd9Sstevel@tonic-gate
98961961e0fSrobinson static int
check_rdev(struct key_call_private * kcp)99061961e0fSrobinson check_rdev(struct key_call_private *kcp)
9917c478bd9Sstevel@tonic-gate {
9927c478bd9Sstevel@tonic-gate struct stat stbuf;
9937c478bd9Sstevel@tonic-gate
9947c478bd9Sstevel@tonic-gate if (kcp->fd == -1)
9957c478bd9Sstevel@tonic-gate return (1); /* can't check it, assume it is okay */
9967c478bd9Sstevel@tonic-gate
997e8031f0aSraf if (fstat(kcp->fd, &stbuf) == -1) {
9987c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, "keyserv_client: can't stat %d", kcp->fd);
9997c478bd9Sstevel@tonic-gate /* could be because file descriptor was closed */
10007c478bd9Sstevel@tonic-gate /* it's not our file descriptor, so don't try to close it */
100161961e0fSrobinson clnt_control(kcp->client, CLSET_FD_NCLOSE, NULL);
10027c478bd9Sstevel@tonic-gate
10037c478bd9Sstevel@tonic-gate return (0);
10047c478bd9Sstevel@tonic-gate }
10057c478bd9Sstevel@tonic-gate if (kcp->rdev != stbuf.st_rdev) {
10067c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG,
10077c478bd9Sstevel@tonic-gate "keyserv_client: fd %d changed, old=0x%x, new=0x%x",
10087c478bd9Sstevel@tonic-gate kcp->fd, kcp->rdev, stbuf.st_rdev);
10097c478bd9Sstevel@tonic-gate /* it's not our file descriptor, so don't try to close it */
101061961e0fSrobinson clnt_control(kcp->client, CLSET_FD_NCLOSE, NULL);
10117c478bd9Sstevel@tonic-gate return (0);
10127c478bd9Sstevel@tonic-gate }
10137c478bd9Sstevel@tonic-gate return (1); /* fd is okay */
10147c478bd9Sstevel@tonic-gate }
1015