12e322d37SHiroki Sato /*- 22e322d37SHiroki Sato * Copyright (c) 2009, Sun Microsystems, Inc. 32e322d37SHiroki Sato * All rights reserved. 4e8636dfdSBill Paul * 52e322d37SHiroki Sato * Redistribution and use in source and binary forms, with or without 62e322d37SHiroki Sato * modification, are permitted provided that the following conditions are met: 72e322d37SHiroki Sato * - Redistributions of source code must retain the above copyright notice, 82e322d37SHiroki Sato * this list of conditions and the following disclaimer. 92e322d37SHiroki Sato * - Redistributions in binary form must reproduce the above copyright notice, 102e322d37SHiroki Sato * this list of conditions and the following disclaimer in the documentation 112e322d37SHiroki Sato * and/or other materials provided with the distribution. 122e322d37SHiroki Sato * - Neither the name of Sun Microsystems, Inc. nor the names of its 132e322d37SHiroki Sato * contributors may be used to endorse or promote products derived 142e322d37SHiroki Sato * from this software without specific prior written permission. 15e8636dfdSBill Paul * 162e322d37SHiroki Sato * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 172e322d37SHiroki Sato * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 182e322d37SHiroki Sato * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 192e322d37SHiroki Sato * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 202e322d37SHiroki Sato * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 212e322d37SHiroki Sato * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 222e322d37SHiroki Sato * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 232e322d37SHiroki Sato * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 242e322d37SHiroki Sato * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 252e322d37SHiroki Sato * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 262e322d37SHiroki Sato * POSSIBILITY OF SUCH DAMAGE. 27e8636dfdSBill Paul */ 28e8636dfdSBill Paul /* 29e8636dfdSBill Paul * Copyright (c) 1986-1991 by Sun Microsystems Inc. 30e8636dfdSBill Paul */ 31e8636dfdSBill Paul 32e8636dfdSBill Paul #ident "@(#)key_call.c 1.25 94/04/24 SMI" 33d3d20c82SDavid E. O'Brien #include <sys/cdefs.h> 34d3d20c82SDavid E. O'Brien __FBSDID("$FreeBSD$"); 3506fa7267SDavid E. O'Brien 36e8636dfdSBill Paul /* 37e8636dfdSBill Paul * key_call.c, Interface to keyserver 38e8636dfdSBill Paul * 39e8636dfdSBill Paul * setsecretkey(key) - set your secret key 40e8636dfdSBill Paul * encryptsessionkey(agent, deskey) - encrypt a session key to talk to agent 41e8636dfdSBill Paul * decryptsessionkey(agent, deskey) - decrypt ditto 42e8636dfdSBill Paul * gendeskey(deskey) - generate a secure des key 43e8636dfdSBill Paul */ 44e8636dfdSBill Paul 45d201fe46SDaniel Eischen #include "namespace.h" 469f5afc13SIan Dowse #include "reentrant.h" 47e8636dfdSBill Paul #include <stdio.h> 48e8636dfdSBill Paul #include <stdlib.h> 49e8636dfdSBill Paul #include <unistd.h> 50e8636dfdSBill Paul #include <errno.h> 51e8636dfdSBill Paul #include <rpc/rpc.h> 52e8636dfdSBill Paul #include <rpc/auth.h> 53e8636dfdSBill Paul #include <rpc/auth_unix.h> 54e8636dfdSBill Paul #include <rpc/key_prot.h> 55e8636dfdSBill Paul #include <string.h> 568360efbdSAlfred Perlstein #include <netconfig.h> 57e8636dfdSBill Paul #include <sys/utsname.h> 58e8636dfdSBill Paul #include <stdlib.h> 59e8636dfdSBill Paul #include <signal.h> 60e8636dfdSBill Paul #include <sys/wait.h> 61e8636dfdSBill Paul #include <sys/fcntl.h> 62d201fe46SDaniel Eischen #include "un-namespace.h" 63235baf26SDaniel Eischen #include "mt_misc.h" 64e8636dfdSBill Paul 65e8636dfdSBill Paul 66e8636dfdSBill Paul #define KEY_TIMEOUT 5 /* per-try timeout in seconds */ 67e8636dfdSBill Paul #define KEY_NRETRY 12 /* number of retries */ 68e8636dfdSBill Paul 69e8636dfdSBill Paul #ifdef DEBUG 70e8636dfdSBill Paul #define debug(msg) (void) fprintf(stderr, "%s\n", msg); 71e8636dfdSBill Paul #else 72e8636dfdSBill Paul #define debug(msg) 73e8636dfdSBill Paul #endif /* DEBUG */ 74e8636dfdSBill Paul 75e8636dfdSBill Paul /* 76e8636dfdSBill Paul * Hack to allow the keyserver to use AUTH_DES (for authenticated 77e8636dfdSBill Paul * NIS+ calls, for example). The only functions that get called 78e8636dfdSBill Paul * are key_encryptsession_pk, key_decryptsession_pk, and key_gendes. 79e8636dfdSBill Paul * 80e8636dfdSBill Paul * The approach is to have the keyserver fill in pointers to local 81e8636dfdSBill Paul * implementations of these functions, and to call those in key_call(). 82e8636dfdSBill Paul */ 83e8636dfdSBill Paul 84*67903135SCraig Rodrigues cryptkeyres *(*__key_encryptsession_pk_LOCAL)(uid_t, void *arg) = 0; 85*67903135SCraig Rodrigues cryptkeyres *(*__key_decryptsession_pk_LOCAL)(uid_t, void *arg) = 0; 86*67903135SCraig Rodrigues des_block *(*__key_gendes_LOCAL)(uid_t, void *) = 0; 87e8636dfdSBill Paul 88f249dbccSDag-Erling Smørgrav static int key_call( u_long, xdrproc_t, void *, xdrproc_t, void *); 89e8636dfdSBill Paul 90e8636dfdSBill Paul int 9168895e38SCraig Rodrigues key_setsecret(const char *secretkey) 92e8636dfdSBill Paul { 93e8636dfdSBill Paul keystatus status; 94e8636dfdSBill Paul 95c549fd46SAlfred Perlstein if (!key_call((u_long) KEY_SET, (xdrproc_t)xdr_keybuf, 96c549fd46SAlfred Perlstein (void *)secretkey, 97f249dbccSDag-Erling Smørgrav (xdrproc_t)xdr_keystatus, &status)) { 98e8636dfdSBill Paul return (-1); 99e8636dfdSBill Paul } 100e8636dfdSBill Paul if (status != KEY_SUCCESS) { 101e8636dfdSBill Paul debug("set status is nonzero"); 102e8636dfdSBill Paul return (-1); 103e8636dfdSBill Paul } 104e8636dfdSBill Paul return (0); 105e8636dfdSBill Paul } 106e8636dfdSBill Paul 107e8636dfdSBill Paul 108e8636dfdSBill Paul /* key_secretkey_is_set() returns 1 if the keyserver has a secret key 109e8636dfdSBill Paul * stored for the caller's effective uid; it returns 0 otherwise 110e8636dfdSBill Paul * 111e8636dfdSBill Paul * N.B.: The KEY_NET_GET key call is undocumented. Applications shouldn't 112e8636dfdSBill Paul * be using it, because it allows them to get the user's secret key. 113e8636dfdSBill Paul */ 114e8636dfdSBill Paul 115e8636dfdSBill Paul int 116e8636dfdSBill Paul key_secretkey_is_set(void) 117e8636dfdSBill Paul { 118e8636dfdSBill Paul struct key_netstres kres; 119e8636dfdSBill Paul 120e8636dfdSBill Paul memset((void*)&kres, 0, sizeof (kres)); 121f249dbccSDag-Erling Smørgrav if (key_call((u_long) KEY_NET_GET, (xdrproc_t)xdr_void, NULL, 122f249dbccSDag-Erling Smørgrav (xdrproc_t)xdr_key_netstres, &kres) && 123e8636dfdSBill Paul (kres.status == KEY_SUCCESS) && 124e8636dfdSBill Paul (kres.key_netstres_u.knet.st_priv_key[0] != 0)) { 125e8636dfdSBill Paul /* avoid leaving secret key in memory */ 126e8636dfdSBill Paul memset(kres.key_netstres_u.knet.st_priv_key, 0, HEXKEYBYTES); 127e8636dfdSBill Paul return (1); 128e8636dfdSBill Paul } 129e8636dfdSBill Paul return (0); 130e8636dfdSBill Paul } 131e8636dfdSBill Paul 132e8636dfdSBill Paul int 13368895e38SCraig Rodrigues key_encryptsession_pk(char *remotename, netobj *remotekey, des_block *deskey) 134e8636dfdSBill Paul { 135e8636dfdSBill Paul cryptkeyarg2 arg; 136e8636dfdSBill Paul cryptkeyres res; 137e8636dfdSBill Paul 138e8636dfdSBill Paul arg.remotename = remotename; 139e8636dfdSBill Paul arg.remotekey = *remotekey; 140e8636dfdSBill Paul arg.deskey = *deskey; 141f249dbccSDag-Erling Smørgrav if (!key_call((u_long)KEY_ENCRYPT_PK, (xdrproc_t)xdr_cryptkeyarg2, &arg, 142f249dbccSDag-Erling Smørgrav (xdrproc_t)xdr_cryptkeyres, &res)) { 143e8636dfdSBill Paul return (-1); 144e8636dfdSBill Paul } 145e8636dfdSBill Paul if (res.status != KEY_SUCCESS) { 146e8636dfdSBill Paul debug("encrypt status is nonzero"); 147e8636dfdSBill Paul return (-1); 148e8636dfdSBill Paul } 149e8636dfdSBill Paul *deskey = res.cryptkeyres_u.deskey; 150e8636dfdSBill Paul return (0); 151e8636dfdSBill Paul } 152e8636dfdSBill Paul 153e8636dfdSBill Paul int 15468895e38SCraig Rodrigues key_decryptsession_pk(char *remotename, netobj *remotekey, des_block *deskey) 155e8636dfdSBill Paul { 156e8636dfdSBill Paul cryptkeyarg2 arg; 157e8636dfdSBill Paul cryptkeyres res; 158e8636dfdSBill Paul 159e8636dfdSBill Paul arg.remotename = remotename; 160e8636dfdSBill Paul arg.remotekey = *remotekey; 161e8636dfdSBill Paul arg.deskey = *deskey; 162f249dbccSDag-Erling Smørgrav if (!key_call((u_long)KEY_DECRYPT_PK, (xdrproc_t)xdr_cryptkeyarg2, &arg, 163f249dbccSDag-Erling Smørgrav (xdrproc_t)xdr_cryptkeyres, &res)) { 164e8636dfdSBill Paul return (-1); 165e8636dfdSBill Paul } 166e8636dfdSBill Paul if (res.status != KEY_SUCCESS) { 167e8636dfdSBill Paul debug("decrypt status is nonzero"); 168e8636dfdSBill Paul return (-1); 169e8636dfdSBill Paul } 170e8636dfdSBill Paul *deskey = res.cryptkeyres_u.deskey; 171e8636dfdSBill Paul return (0); 172e8636dfdSBill Paul } 173e8636dfdSBill Paul 174e8636dfdSBill Paul int 17568895e38SCraig Rodrigues key_encryptsession(const char *remotename, des_block *deskey) 176e8636dfdSBill Paul { 177e8636dfdSBill Paul cryptkeyarg arg; 178e8636dfdSBill Paul cryptkeyres res; 179e8636dfdSBill Paul 180e8636dfdSBill Paul arg.remotename = (char *) remotename; 181e8636dfdSBill Paul arg.deskey = *deskey; 182f249dbccSDag-Erling Smørgrav if (!key_call((u_long)KEY_ENCRYPT, (xdrproc_t)xdr_cryptkeyarg, &arg, 183f249dbccSDag-Erling Smørgrav (xdrproc_t)xdr_cryptkeyres, &res)) { 184e8636dfdSBill Paul return (-1); 185e8636dfdSBill Paul } 186e8636dfdSBill Paul if (res.status != KEY_SUCCESS) { 187e8636dfdSBill Paul debug("encrypt status is nonzero"); 188e8636dfdSBill Paul return (-1); 189e8636dfdSBill Paul } 190e8636dfdSBill Paul *deskey = res.cryptkeyres_u.deskey; 191e8636dfdSBill Paul return (0); 192e8636dfdSBill Paul } 193e8636dfdSBill Paul 194e8636dfdSBill Paul int 19568895e38SCraig Rodrigues key_decryptsession(const char *remotename, des_block *deskey) 196e8636dfdSBill Paul { 197e8636dfdSBill Paul cryptkeyarg arg; 198e8636dfdSBill Paul cryptkeyres res; 199e8636dfdSBill Paul 200e8636dfdSBill Paul arg.remotename = (char *) remotename; 201e8636dfdSBill Paul arg.deskey = *deskey; 202f249dbccSDag-Erling Smørgrav if (!key_call((u_long)KEY_DECRYPT, (xdrproc_t)xdr_cryptkeyarg, &arg, 203f249dbccSDag-Erling Smørgrav (xdrproc_t)xdr_cryptkeyres, &res)) { 204e8636dfdSBill Paul return (-1); 205e8636dfdSBill Paul } 206e8636dfdSBill Paul if (res.status != KEY_SUCCESS) { 207e8636dfdSBill Paul debug("decrypt status is nonzero"); 208e8636dfdSBill Paul return (-1); 209e8636dfdSBill Paul } 210e8636dfdSBill Paul *deskey = res.cryptkeyres_u.deskey; 211e8636dfdSBill Paul return (0); 212e8636dfdSBill Paul } 213e8636dfdSBill Paul 214e8636dfdSBill Paul int 21568895e38SCraig Rodrigues key_gendes(des_block *key) 216e8636dfdSBill Paul { 217f249dbccSDag-Erling Smørgrav if (!key_call((u_long)KEY_GEN, (xdrproc_t)xdr_void, NULL, 218f249dbccSDag-Erling Smørgrav (xdrproc_t)xdr_des_block, key)) { 219e8636dfdSBill Paul return (-1); 220e8636dfdSBill Paul } 221e8636dfdSBill Paul return (0); 222e8636dfdSBill Paul } 223e8636dfdSBill Paul 224e8636dfdSBill Paul int 22568895e38SCraig Rodrigues key_setnet(struct key_netstarg *arg) 226e8636dfdSBill Paul { 227e8636dfdSBill Paul keystatus status; 228e8636dfdSBill Paul 229e8636dfdSBill Paul 230f249dbccSDag-Erling Smørgrav if (!key_call((u_long) KEY_NET_PUT, (xdrproc_t)xdr_key_netstarg, arg, 231f249dbccSDag-Erling Smørgrav (xdrproc_t)xdr_keystatus, &status)){ 232e8636dfdSBill Paul return (-1); 233e8636dfdSBill Paul } 234e8636dfdSBill Paul 235e8636dfdSBill Paul if (status != KEY_SUCCESS) { 236e8636dfdSBill Paul debug("key_setnet status is nonzero"); 237e8636dfdSBill Paul return (-1); 238e8636dfdSBill Paul } 239e8636dfdSBill Paul return (1); 240e8636dfdSBill Paul } 241e8636dfdSBill Paul 242e8636dfdSBill Paul 243e8636dfdSBill Paul int 24468895e38SCraig Rodrigues key_get_conv(char *pkey, des_block *deskey) 245e8636dfdSBill Paul { 246e8636dfdSBill Paul cryptkeyres res; 247e8636dfdSBill Paul 248f249dbccSDag-Erling Smørgrav if (!key_call((u_long) KEY_GET_CONV, (xdrproc_t)xdr_keybuf, pkey, 249f249dbccSDag-Erling Smørgrav (xdrproc_t)xdr_cryptkeyres, &res)) { 250e8636dfdSBill Paul return (-1); 251e8636dfdSBill Paul } 252e8636dfdSBill Paul if (res.status != KEY_SUCCESS) { 253e8636dfdSBill Paul debug("get_conv status is nonzero"); 254e8636dfdSBill Paul return (-1); 255e8636dfdSBill Paul } 256e8636dfdSBill Paul *deskey = res.cryptkeyres_u.deskey; 257e8636dfdSBill Paul return (0); 258e8636dfdSBill Paul } 259e8636dfdSBill Paul 260e8636dfdSBill Paul struct key_call_private { 261e8636dfdSBill Paul CLIENT *client; /* Client handle */ 262e8636dfdSBill Paul pid_t pid; /* process-id at moment of creation */ 263e8636dfdSBill Paul uid_t uid; /* user-id at last authorization */ 264e8636dfdSBill Paul }; 265e8636dfdSBill Paul static struct key_call_private *key_call_private_main = NULL; 2666f88d2a8SJohn Baldwin static thread_key_t key_call_key; 2676f88d2a8SJohn Baldwin static once_t key_call_once = ONCE_INITIALIZER; 2686f88d2a8SJohn Baldwin static int key_call_key_error; 269e8636dfdSBill Paul 270e8636dfdSBill Paul static void 271e8636dfdSBill Paul key_call_destroy(void *vp) 272e8636dfdSBill Paul { 2738fb3f3f6SDavid E. O'Brien struct key_call_private *kcp = (struct key_call_private *)vp; 274e8636dfdSBill Paul 275e8636dfdSBill Paul if (kcp) { 276e8636dfdSBill Paul if (kcp->client) 277e8636dfdSBill Paul clnt_destroy(kcp->client); 278e8636dfdSBill Paul free(kcp); 279e8636dfdSBill Paul } 280e8636dfdSBill Paul } 281e8636dfdSBill Paul 2826f88d2a8SJohn Baldwin static void 2836f88d2a8SJohn Baldwin key_call_init(void) 2846f88d2a8SJohn Baldwin { 2856f88d2a8SJohn Baldwin 2866f88d2a8SJohn Baldwin key_call_key_error = thr_keycreate(&key_call_key, key_call_destroy); 2876f88d2a8SJohn Baldwin } 2886f88d2a8SJohn Baldwin 289e8636dfdSBill Paul /* 290e8636dfdSBill Paul * Keep the handle cached. This call may be made quite often. 291e8636dfdSBill Paul */ 292e8636dfdSBill Paul static CLIENT * 29368895e38SCraig Rodrigues getkeyserv_handle(int vers) 294e8636dfdSBill Paul { 2958360efbdSAlfred Perlstein void *localhandle; 2968360efbdSAlfred Perlstein struct netconfig *nconf; 2978360efbdSAlfred Perlstein struct netconfig *tpconf; 2980c0349bfSGarrett Wollman struct key_call_private *kcp; 299e8636dfdSBill Paul struct timeval wait_time; 3008360efbdSAlfred Perlstein struct utsname u; 3018360efbdSAlfred Perlstein int main_thread; 302e8636dfdSBill Paul int fd; 303e8636dfdSBill Paul 304e8636dfdSBill Paul #define TOTAL_TIMEOUT 30 /* total timeout talking to keyserver */ 305e8636dfdSBill Paul #define TOTAL_TRIES 5 /* Number of tries */ 306e8636dfdSBill Paul 3078360efbdSAlfred Perlstein if ((main_thread = thr_main())) { 3088360efbdSAlfred Perlstein kcp = key_call_private_main; 3098360efbdSAlfred Perlstein } else { 3106f88d2a8SJohn Baldwin if (thr_once(&key_call_once, key_call_init) != 0 || 3116f88d2a8SJohn Baldwin key_call_key_error != 0) 3126f88d2a8SJohn Baldwin return ((CLIENT *) NULL); 3138360efbdSAlfred Perlstein kcp = (struct key_call_private *)thr_getspecific(key_call_key); 3148360efbdSAlfred Perlstein } 315e8636dfdSBill Paul if (kcp == (struct key_call_private *)NULL) { 316e8636dfdSBill Paul kcp = (struct key_call_private *)malloc(sizeof (*kcp)); 317e8636dfdSBill Paul if (kcp == (struct key_call_private *)NULL) { 318e8636dfdSBill Paul return ((CLIENT *) NULL); 319e8636dfdSBill Paul } 3208360efbdSAlfred Perlstein if (main_thread) 321e8636dfdSBill Paul key_call_private_main = kcp; 3228360efbdSAlfred Perlstein else 3238360efbdSAlfred Perlstein thr_setspecific(key_call_key, (void *) kcp); 324e8636dfdSBill Paul kcp->client = NULL; 325e8636dfdSBill Paul } 326e8636dfdSBill Paul 327e8636dfdSBill Paul /* if pid has changed, destroy client and rebuild */ 328e8636dfdSBill Paul if (kcp->client != NULL && kcp->pid != getpid()) { 329e8636dfdSBill Paul clnt_destroy(kcp->client); 330e8636dfdSBill Paul kcp->client = NULL; 331e8636dfdSBill Paul } 332e8636dfdSBill Paul 333e8636dfdSBill Paul if (kcp->client != NULL) { 334e8636dfdSBill Paul /* if uid has changed, build client handle again */ 335e8636dfdSBill Paul if (kcp->uid != geteuid()) { 336e8636dfdSBill Paul kcp->uid = geteuid(); 337e8636dfdSBill Paul auth_destroy(kcp->client->cl_auth); 338e8636dfdSBill Paul kcp->client->cl_auth = 339e8636dfdSBill Paul authsys_create("", kcp->uid, 0, 0, NULL); 340e8636dfdSBill Paul if (kcp->client->cl_auth == NULL) { 341e8636dfdSBill Paul clnt_destroy(kcp->client); 342e8636dfdSBill Paul kcp->client = NULL; 343e8636dfdSBill Paul return ((CLIENT *) NULL); 344e8636dfdSBill Paul } 345e8636dfdSBill Paul } 346e8636dfdSBill Paul /* Change the version number to the new one */ 347e8636dfdSBill Paul clnt_control(kcp->client, CLSET_VERS, (void *)&vers); 348e8636dfdSBill Paul return (kcp->client); 349e8636dfdSBill Paul } 3508360efbdSAlfred Perlstein if (!(localhandle = setnetconfig())) { 3518360efbdSAlfred Perlstein return ((CLIENT *) NULL); 3528360efbdSAlfred Perlstein } 3538360efbdSAlfred Perlstein tpconf = NULL; 35406fa7267SDavid E. O'Brien #if defined(__FreeBSD__) 3558360efbdSAlfred Perlstein if (uname(&u) == -1) 35606fa7267SDavid E. O'Brien #else 35706fa7267SDavid E. O'Brien #if defined(i386) 35806fa7267SDavid E. O'Brien if (_nuname(&u) == -1) 35906fa7267SDavid E. O'Brien #elif defined(sparc) 36006fa7267SDavid E. O'Brien if (_uname(&u) == -1) 36106fa7267SDavid E. O'Brien #else 36206fa7267SDavid E. O'Brien #error Unknown architecture! 36306fa7267SDavid E. O'Brien #endif 36406fa7267SDavid E. O'Brien #endif 3658360efbdSAlfred Perlstein { 3668360efbdSAlfred Perlstein endnetconfig(localhandle); 3678360efbdSAlfred Perlstein return ((CLIENT *) NULL); 3688360efbdSAlfred Perlstein } 3698d630135SAlfred Perlstein while ((nconf = getnetconfig(localhandle)) != NULL) { 3708360efbdSAlfred Perlstein if (strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) { 3718360efbdSAlfred Perlstein /* 3728360efbdSAlfred Perlstein * We use COTS_ORD here so that the caller can 3738360efbdSAlfred Perlstein * find out immediately if the server is dead. 3748360efbdSAlfred Perlstein */ 3758360efbdSAlfred Perlstein if (nconf->nc_semantics == NC_TPI_COTS_ORD) { 3768360efbdSAlfred Perlstein kcp->client = clnt_tp_create(u.nodename, 3778360efbdSAlfred Perlstein KEY_PROG, vers, nconf); 3788360efbdSAlfred Perlstein if (kcp->client) 3798360efbdSAlfred Perlstein break; 3808360efbdSAlfred Perlstein } else { 3818360efbdSAlfred Perlstein tpconf = nconf; 3828360efbdSAlfred Perlstein } 3838360efbdSAlfred Perlstein } 3848360efbdSAlfred Perlstein } 3858360efbdSAlfred Perlstein if ((kcp->client == (CLIENT *) NULL) && (tpconf)) 3868360efbdSAlfred Perlstein /* Now, try the CLTS or COTS loopback transport */ 3878360efbdSAlfred Perlstein kcp->client = clnt_tp_create(u.nodename, 3888360efbdSAlfred Perlstein KEY_PROG, vers, tpconf); 3898360efbdSAlfred Perlstein endnetconfig(localhandle); 390e8636dfdSBill Paul 391e8636dfdSBill Paul if (kcp->client == (CLIENT *) NULL) { 392e8636dfdSBill Paul return ((CLIENT *) NULL); 393e8636dfdSBill Paul } 394e8636dfdSBill Paul kcp->uid = geteuid(); 395e8636dfdSBill Paul kcp->pid = getpid(); 396e8636dfdSBill Paul kcp->client->cl_auth = authsys_create("", kcp->uid, 0, 0, NULL); 397e8636dfdSBill Paul if (kcp->client->cl_auth == NULL) { 398e8636dfdSBill Paul clnt_destroy(kcp->client); 399e8636dfdSBill Paul kcp->client = NULL; 400e8636dfdSBill Paul return ((CLIENT *) NULL); 401e8636dfdSBill Paul } 402e8636dfdSBill Paul 403e8636dfdSBill Paul wait_time.tv_sec = TOTAL_TIMEOUT/TOTAL_TRIES; 404e8636dfdSBill Paul wait_time.tv_usec = 0; 405e8636dfdSBill Paul (void) clnt_control(kcp->client, CLSET_RETRY_TIMEOUT, 406e8636dfdSBill Paul (char *)&wait_time); 407e8636dfdSBill Paul if (clnt_control(kcp->client, CLGET_FD, (char *)&fd)) 4089233c4d9SJason Evans _fcntl(fd, F_SETFD, 1); /* make it "close on exec" */ 409e8636dfdSBill Paul 410e8636dfdSBill Paul return (kcp->client); 411e8636dfdSBill Paul } 412e8636dfdSBill Paul 413e8636dfdSBill Paul /* returns 0 on failure, 1 on success */ 414e8636dfdSBill Paul 415e8636dfdSBill Paul static int 41668895e38SCraig Rodrigues key_call(u_long proc, xdrproc_t xdr_arg, void *arg, xdrproc_t xdr_rslt, 41768895e38SCraig Rodrigues void *rslt) 418e8636dfdSBill Paul { 419e8636dfdSBill Paul CLIENT *clnt; 420e8636dfdSBill Paul struct timeval wait_time; 421e8636dfdSBill Paul 422e8636dfdSBill Paul if (proc == KEY_ENCRYPT_PK && __key_encryptsession_pk_LOCAL) { 423e8636dfdSBill Paul cryptkeyres *res; 424e8636dfdSBill Paul res = (*__key_encryptsession_pk_LOCAL)(geteuid(), arg); 425e8636dfdSBill Paul *(cryptkeyres*)rslt = *res; 426e8636dfdSBill Paul return (1); 427e8636dfdSBill Paul } else if (proc == KEY_DECRYPT_PK && __key_decryptsession_pk_LOCAL) { 428e8636dfdSBill Paul cryptkeyres *res; 429e8636dfdSBill Paul res = (*__key_decryptsession_pk_LOCAL)(geteuid(), arg); 430e8636dfdSBill Paul *(cryptkeyres*)rslt = *res; 431e8636dfdSBill Paul return (1); 432e8636dfdSBill Paul } else if (proc == KEY_GEN && __key_gendes_LOCAL) { 433e8636dfdSBill Paul des_block *res; 434e8636dfdSBill Paul res = (*__key_gendes_LOCAL)(geteuid(), 0); 435e8636dfdSBill Paul *(des_block*)rslt = *res; 436e8636dfdSBill Paul return (1); 437e8636dfdSBill Paul } 438e8636dfdSBill Paul 439e8636dfdSBill Paul if ((proc == KEY_ENCRYPT_PK) || (proc == KEY_DECRYPT_PK) || 440e8636dfdSBill Paul (proc == KEY_NET_GET) || (proc == KEY_NET_PUT) || 441e8636dfdSBill Paul (proc == KEY_GET_CONV)) 442e8636dfdSBill Paul clnt = getkeyserv_handle(2); /* talk to version 2 */ 443e8636dfdSBill Paul else 444e8636dfdSBill Paul clnt = getkeyserv_handle(1); /* talk to version 1 */ 445e8636dfdSBill Paul 446e8636dfdSBill Paul if (clnt == NULL) { 447e8636dfdSBill Paul return (0); 448e8636dfdSBill Paul } 449e8636dfdSBill Paul 450e8636dfdSBill Paul wait_time.tv_sec = TOTAL_TIMEOUT; 451e8636dfdSBill Paul wait_time.tv_usec = 0; 452e8636dfdSBill Paul 453e8636dfdSBill Paul if (clnt_call(clnt, proc, xdr_arg, arg, xdr_rslt, rslt, 454e8636dfdSBill Paul wait_time) == RPC_SUCCESS) { 455e8636dfdSBill Paul return (1); 456e8636dfdSBill Paul } else { 457e8636dfdSBill Paul return (0); 458e8636dfdSBill Paul } 459e8636dfdSBill Paul } 460