⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 key_call.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
字号:
/* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part.  Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. *  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. *  * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. *  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. *  * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. *  * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California  94043 *//* * Copyright (c) 1986-1991 by Sun Microsystems Inc.  * * $FreeBSD: src/lib/libc/rpc/key_call.c,v 1.3 2000/01/27 23:06:39 jasone Exp $ */#ident	"@(#)key_call.c	1.25	94/04/24 SMI"/* * key_call.c, Interface to keyserver * * setsecretkey(key) - set your secret key * encryptsessionkey(agent, deskey) - encrypt a session key to talk to agent * decryptsessionkey(agent, deskey) - decrypt ditto * gendeskey(deskey) - generate a secure des key */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <rpc/rpc.h>#include <rpc/auth.h>#include <rpc/auth_unix.h>#include <rpc/key_prot.h>#include <string.h>#include <sys/utsname.h>#include <stdlib.h>#include <signal.h>#include <sys/wait.h>#include <sys/fcntl.h>#define	KEY_TIMEOUT	5	/* per-try timeout in seconds */#define	KEY_NRETRY	12	/* number of retries */#ifdef DEBUG#define	debug(msg)	(void) fprintf(stderr, "%s\n", msg);#else#define	debug(msg)#endif /* DEBUG *//* * Hack to allow the keyserver to use AUTH_DES (for authenticated * NIS+ calls, for example).  The only functions that get called * are key_encryptsession_pk, key_decryptsession_pk, and key_gendes. * * The approach is to have the keyserver fill in pointers to local * implementations of these functions, and to call those in key_call(). */cryptkeyres *(*__key_encryptsession_pk_LOCAL)() = 0;cryptkeyres *(*__key_decryptsession_pk_LOCAL)() = 0;des_block *(*__key_gendes_LOCAL)() = 0;static int key_call __P(( u_long, xdrproc_t, char *, xdrproc_t, char * ));intkey_setsecret(secretkey)	const char *secretkey;{	keystatus status;	if (!key_call((u_long) KEY_SET, xdr_keybuf, (char *) secretkey,			xdr_keystatus, (char *)&status)) {		return (-1);	}	if (status != KEY_SUCCESS) {		debug("set status is nonzero");		return (-1);	}	return (0);}/* key_secretkey_is_set() returns 1 if the keyserver has a secret key * stored for the caller's effective uid; it returns 0 otherwise * * N.B.:  The KEY_NET_GET key call is undocumented.  Applications shouldn't * be using it, because it allows them to get the user's secret key. */intkey_secretkey_is_set(void){	struct key_netstres 	kres;	memset((void*)&kres, 0, sizeof (kres));	if (key_call((u_long) KEY_NET_GET, xdr_void, (char *)NULL,			xdr_key_netstres, (char *) &kres) &&	    (kres.status == KEY_SUCCESS) &&	    (kres.key_netstres_u.knet.st_priv_key[0] != 0)) {		/* avoid leaving secret key in memory */		memset(kres.key_netstres_u.knet.st_priv_key, 0, HEXKEYBYTES);		return (1);	}	return (0);}intkey_encryptsession_pk(remotename, remotekey, deskey)	char *remotename;	netobj *remotekey;	des_block *deskey;{	cryptkeyarg2 arg;	cryptkeyres res;	arg.remotename = remotename;	arg.remotekey = *remotekey;	arg.deskey = *deskey;	if (!key_call((u_long)KEY_ENCRYPT_PK, xdr_cryptkeyarg2, (char *)&arg,			xdr_cryptkeyres, (char *)&res)) {		return (-1);	}	if (res.status != KEY_SUCCESS) {		debug("encrypt status is nonzero");		return (-1);	}	*deskey = res.cryptkeyres_u.deskey;	return (0);}intkey_decryptsession_pk(remotename, remotekey, deskey)	char *remotename;	netobj *remotekey;	des_block *deskey;{	cryptkeyarg2 arg;	cryptkeyres res;	arg.remotename = remotename;	arg.remotekey = *remotekey;	arg.deskey = *deskey;	if (!key_call((u_long)KEY_DECRYPT_PK, xdr_cryptkeyarg2, (char *)&arg,			xdr_cryptkeyres, (char *)&res)) {		return (-1);	}	if (res.status != KEY_SUCCESS) {		debug("decrypt status is nonzero");		return (-1);	}	*deskey = res.cryptkeyres_u.deskey;	return (0);}intkey_encryptsession(remotename, deskey)	const char *remotename;	des_block *deskey;{	cryptkeyarg arg;	cryptkeyres res;	arg.remotename = (char *) remotename;	arg.deskey = *deskey;	if (!key_call((u_long)KEY_ENCRYPT, xdr_cryptkeyarg, (char *)&arg,			xdr_cryptkeyres, (char *)&res)) {		return (-1);	}	if (res.status != KEY_SUCCESS) {		debug("encrypt status is nonzero");		return (-1);	}	*deskey = res.cryptkeyres_u.deskey;	return (0);}intkey_decryptsession(remotename, deskey)	const char *remotename;	des_block *deskey;{	cryptkeyarg arg;	cryptkeyres res;	arg.remotename = (char *) remotename;	arg.deskey = *deskey;	if (!key_call((u_long)KEY_DECRYPT, xdr_cryptkeyarg, (char *)&arg,			xdr_cryptkeyres, (char *)&res)) {		return (-1);	}	if (res.status != KEY_SUCCESS) {		debug("decrypt status is nonzero");		return (-1);	}	*deskey = res.cryptkeyres_u.deskey;	return (0);}intkey_gendes(key)	des_block *key;{	if (!key_call((u_long)KEY_GEN, xdr_void, (char *)NULL,			xdr_des_block, (char *)key)) {		return (-1);	}	return (0);}intkey_setnet(arg)struct netstarg *arg;{	keystatus status;	if (!key_call((u_long) KEY_NET_PUT, xdr_key_netstarg, (char *) arg,		xdr_keystatus, (char *) &status)){		return (-1);	}	if (status != KEY_SUCCESS) {		debug("key_setnet status is nonzero");		return (-1);	}	return (1);}intkey_get_conv(pkey, deskey)	char *pkey;	des_block *deskey;{	cryptkeyres res;	if (!key_call((u_long) KEY_GET_CONV, xdr_keybuf, pkey,		xdr_cryptkeyres, (char *)&res)) {		return (-1);	}	if (res.status != KEY_SUCCESS) {		debug("get_conv status is nonzero");		return (-1);	}	*deskey = res.cryptkeyres_u.deskey;	return (0);}struct  key_call_private {	CLIENT	*client;	/* Client handle */	pid_t	pid;		/* process-id at moment of creation */	uid_t	uid;		/* user-id at last authorization */};static struct key_call_private *key_call_private_main = NULL;#ifdef foostatic voidkey_call_destroy(void *vp){	register struct key_call_private *kcp = (struct key_call_private *)vp;	if (kcp) {		if (kcp->client)			clnt_destroy(kcp->client);		free(kcp);	}}#endif/* * Keep the handle cached.  This call may be made quite often. */static CLIENT *getkeyserv_handle(vers)int	vers;{	struct key_call_private *kcp = key_call_private_main;	struct timeval wait_time;	int fd;	struct sockaddr_un name;	int namelen = sizeof(struct sockaddr_un);#define	TOTAL_TIMEOUT	30	/* total timeout talking to keyserver */#define	TOTAL_TRIES	5	/* Number of tries */	if (kcp == (struct key_call_private *)NULL) {		kcp = (struct key_call_private *)malloc(sizeof (*kcp));		if (kcp == (struct key_call_private *)NULL) {			return ((CLIENT *) NULL);		}		key_call_private_main = kcp;		kcp->client = NULL;	}	/* if pid has changed, destroy client and rebuild */	if (kcp->client != NULL && kcp->pid != getpid()) {		clnt_destroy(kcp->client);		kcp->client = NULL;	}	if (kcp->client != NULL) {		/* if other side closed socket, build handle again */		clnt_control(kcp->client, CLGET_FD, (char *)&fd);		if (getpeername(fd,(struct sockaddr *)&name,&namelen) == -1) {			auth_destroy(kcp->client->cl_auth);			clnt_destroy(kcp->client);			kcp->client = NULL;		}	}	if (kcp->client != NULL) {		/* if uid has changed, build client handle again */		if (kcp->uid != geteuid()) {			kcp->uid = geteuid();			auth_destroy(kcp->client->cl_auth);			kcp->client->cl_auth =				authsys_create("", kcp->uid, 0, 0, NULL);			if (kcp->client->cl_auth == NULL) {				clnt_destroy(kcp->client);				kcp->client = NULL;				return ((CLIENT *) NULL);			}		}		/* Change the version number to the new one */		clnt_control(kcp->client, CLSET_VERS, (void *)&vers);		return (kcp->client);	}	if ((kcp->client == (CLIENT *) NULL))		/* Use the AF_UNIX transport */		kcp->client = clnt_create("/var/run/keyservsock", KEY_PROG,							vers, "unix");	if (kcp->client == (CLIENT *) NULL) {		return ((CLIENT *) NULL);	}	kcp->uid = geteuid();	kcp->pid = getpid();	kcp->client->cl_auth = authsys_create("", kcp->uid, 0, 0, NULL);	if (kcp->client->cl_auth == NULL) {		clnt_destroy(kcp->client);		kcp->client = NULL;		return ((CLIENT *) NULL);	}	wait_time.tv_sec = TOTAL_TIMEOUT/TOTAL_TRIES;	wait_time.tv_usec = 0;	(void) clnt_control(kcp->client, CLSET_RETRY_TIMEOUT,		(char *)&wait_time);	if (clnt_control(kcp->client, CLGET_FD, (char *)&fd))		_fcntl(fd, F_SETFD, 1);	/* make it "close on exec" */	return (kcp->client);}/* returns  0 on failure, 1 on success */static intkey_call(proc, xdr_arg, arg, xdr_rslt, rslt)	u_long proc;	xdrproc_t xdr_arg;	char *arg;	xdrproc_t xdr_rslt;	char *rslt;{	CLIENT *clnt;	struct timeval wait_time;	if (proc == KEY_ENCRYPT_PK && __key_encryptsession_pk_LOCAL) {		cryptkeyres *res;		res = (*__key_encryptsession_pk_LOCAL)(geteuid(), arg);		*(cryptkeyres*)rslt = *res;		return (1);	} else if (proc == KEY_DECRYPT_PK && __key_decryptsession_pk_LOCAL) {		cryptkeyres *res;		res = (*__key_decryptsession_pk_LOCAL)(geteuid(), arg);		*(cryptkeyres*)rslt = *res;		return (1);	} else if (proc == KEY_GEN && __key_gendes_LOCAL) {		des_block *res;		res = (*__key_gendes_LOCAL)(geteuid(), 0);		*(des_block*)rslt = *res;		return (1);	}	if ((proc == KEY_ENCRYPT_PK) || (proc == KEY_DECRYPT_PK) ||	    (proc == KEY_NET_GET) || (proc == KEY_NET_PUT) ||	    (proc == KEY_GET_CONV))		clnt = getkeyserv_handle(2); /* talk to version 2 */	else		clnt = getkeyserv_handle(1); /* talk to version 1 */	if (clnt == NULL) {		return (0);	}	wait_time.tv_sec = TOTAL_TIMEOUT;	wait_time.tv_usec = 0;	if (clnt_call(clnt, proc, xdr_arg, arg, xdr_rslt, rslt,		wait_time) == RPC_SUCCESS) {		return (1);	} else {		return (0);	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -