2 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3 * unrestricted use provided that this legend is included on all tape
4 * media and as a part of the software program in whole or part. Users
5 * may copy or modify Sun RPC without charge, but are not authorized
6 * to license or distribute it to anyone else except as part of a product or
7 * program developed by the user.
9 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
10 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
11 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
13 * Sun RPC is provided with no support and without any obligation on the
14 * part of Sun Microsystems, Inc. to assist in its use, correction,
15 * modification or enhancement.
17 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
18 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
19 * OR ANY PART THEREOF.
21 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
22 * or profits or other special, indirect and consequential damages, even if
23 * Sun has been advised of the possibility of such damages.
25 * Sun Microsystems, Inc.
27 * Mountain View, California 94043
29 * @(#)keyserv.c 1.15 94/04/25 SMI
30 * $FreeBSD: src/usr.sbin/keyserv/keyserv.c,v 1.12 2007/11/07 10:53:35 kevlo Exp $
34 * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
39 * Store secret keys per uid. Do public key encryption and decryption
40 * operations. Generate "random" keys.
41 * Do not talk to anything but a local root
42 * process on the local transport only
52 #include <sys/types.h>
54 #include <sys/param.h>
56 #include <rpc/des_crypt.h>
58 #include <rpc/key_prot.h>
59 #include <rpcsvc/crypt.h>
67 #define KEYSERVSOCK "/var/run/keyservsock"
70 static void randomize( des_block
* );
71 static void usage( void );
72 static int getrootkey( des_block
*, int );
73 static int root_auth( SVCXPRT
*, struct svc_req
* );
76 static int debugging
= 1;
78 static int debugging
= 0;
81 static void keyprogram();
82 static des_block masterkey
;
84 static char ROOTKEY
[] = "/etc/.rootkey";
87 * Hack to allow the keyserver to use AUTH_DES (for authenticated
88 * NIS+ calls, for example). The only functions that get called
89 * are key_encryptsession_pk, key_decryptsession_pk, and key_gendes.
91 * The approach is to have the keyserver fill in pointers to local
92 * implementations of these functions, and to call those in key_call().
95 extern cryptkeyres
*(*__key_encryptsession_pk_LOCAL
)();
96 extern cryptkeyres
*(*__key_decryptsession_pk_LOCAL
)();
97 extern des_block
*(*__key_gendes_LOCAL
)();
98 extern int (*__des_crypt_LOCAL
)();
100 cryptkeyres
*key_encrypt_pk_2_svc_prog( uid_t
, cryptkeyarg2
* );
101 cryptkeyres
*key_decrypt_pk_2_svc_prog( uid_t
, cryptkeyarg2
* );
102 des_block
*key_gen_1_svc_prog( void *, struct svc_req
* );
105 main(int argc
, char **argv
)
113 struct netconfig
*nconf
= NULL
;
115 __key_encryptsession_pk_LOCAL
= &key_encrypt_pk_2_svc_prog
;
116 __key_decryptsession_pk_LOCAL
= &key_decrypt_pk_2_svc_prog
;
117 __key_gendes_LOCAL
= &key_gen_1_svc_prog
;
119 while ((c
= getopt(argc
, argv
, "ndDvp:")) != -1)
140 load_des(warn
, path
);
141 __des_crypt_LOCAL
= _my_crypt
;
142 if (svc_auth_reg(AUTH_DES
, _svcauth_des
) == -1)
143 errx(1, "failed to register AUTH_DES authenticator");
145 if (optind
!= argc
) {
152 umask(S_IXUSR
|S_IXGRP
|S_IXOTH
);
154 errx(1, "keyserv must be run as root");
155 setmodulus(HEXMODULUS
);
156 getrootkey(&masterkey
, nflag
);
158 rpcb_unset(KEY_PROG
, KEY_VERS
, NULL
);
159 rpcb_unset(KEY_PROG
, KEY_VERS2
, NULL
);
161 if (svc_create(keyprogram
, KEY_PROG
, KEY_VERS
,
163 fprintf(stderr
, "%s: unable to create service\n", argv
[0]);
167 if (svc_create(keyprogram
, KEY_PROG
, KEY_VERS2
,
169 fprintf(stderr
, "%s: unable to create service\n", argv
[0]);
173 localhandle
= setnetconfig();
174 while ((nconf
= getnetconfig(localhandle
)) != NULL
) {
175 if (nconf
->nc_protofmly
!= NULL
&&
176 strcmp(nconf
->nc_protofmly
, NC_LOOPBACK
) == 0)
181 errx(1, "getnetconfig: %s", nc_sperror());
184 rpcb_unset(CRYPT_PROG
, CRYPT_VERS
, nconf
);
185 transp
= svcunix_create(RPC_ANYSOCK
, 0, 0, KEYSERVSOCK
);
187 errx(1, "cannot create AF_LOCAL service");
188 if (!svc_reg(transp
, KEY_PROG
, KEY_VERS
, keyprogram
, nconf
))
189 errx(1, "unable to register (KEY_PROG, KEY_VERS, unix)");
190 if (!svc_reg(transp
, KEY_PROG
, KEY_VERS2
, keyprogram
, nconf
))
191 errx(1, "unable to register (KEY_PROG, KEY_VERS2, unix)");
192 if (!svc_reg(transp
, CRYPT_PROG
, CRYPT_VERS
, crypt_prog_1
, nconf
))
193 errx(1, "unable to register (CRYPT_PROG, CRYPT_VERS, unix)");
195 endnetconfig(localhandle
);
197 umask(066); /* paranoia */
203 signal(SIGPIPE
, SIG_IGN
);
211 * In the event that we don't get a root password, we try to
212 * randomize the master key the best we can
215 randomize(des_block
*master
)
217 #ifdef KEYSERV_RANDOM
218 master
->key
.low
= arc4random();
219 master
->key
.high
= arc4random();
221 /* use stupid dangerous bad rand() */
223 master
->key
.low
= rand();
224 master
->key
.high
= rand();
229 * Try to get root's secret key, by prompting if terminal is a tty, else trying
230 * from standard input.
231 * Returns 1 on success.
234 getrootkey(des_block
*master
, int prompt
)
237 char name
[MAXNETNAMELEN
+ 1];
238 char secret
[HEXKEYBYTES
];
239 key_netstarg netstore
;
244 * Read secret key out of ROOTKEY
246 fd
= open(ROOTKEY
, O_RDONLY
, 0);
251 if (read(fd
, secret
, HEXKEYBYTES
) < HEXKEYBYTES
) {
252 warnx("the key read from %s was too short", ROOTKEY
);
257 if (!getnetname(name
)) {
259 "failed to generate host's netname when establishing root's key");
262 memcpy(netstore
.st_priv_key
, secret
, HEXKEYBYTES
);
263 memset(netstore
.st_pub_key
, 0, HEXKEYBYTES
);
264 netstore
.st_netname
= name
;
265 if (pk_netput(0, &netstore
) != KEY_SUCCESS
) {
266 warnx("could not set root's key and netname");
272 * Decrypt yellow pages publickey entry to get secret key
274 passwd
= getpass("root password:");
275 passwd2des(passwd
, (char *)master
);
277 if (!getsecretkey(name
, secret
, passwd
)) {
278 warnx("can't find %s's secret key", name
);
281 if (secret
[0] == 0) {
282 warnx("password does not decrypt secret key for %s", name
);
285 pk_setkey(0, secret
);
287 * Store it for future use in $ROOTKEY, if possible
289 fd
= open(ROOTKEY
, O_WRONLY
|O_TRUNC
|O_CREAT
, 0);
293 write(fd
, secret
, strlen(secret
));
294 write(fd
, &newline
, sizeof (newline
));
301 * Procedures to implement RPC service
304 strstatus(keystatus status
)
308 return ("KEY_SUCCESS");
310 return ("KEY_NOSECRET");
312 return ("KEY_UNKNOWN");
314 return ("KEY_SYSTEMERR");
316 return ("(bad result code)");
321 key_set_1_svc_prog(uid_t uid
, keybuf key
)
323 static keystatus status
;
326 fprintf(stderr
, "set(%d, %.*s) = ", uid
,
327 (int) sizeof (keybuf
), key
);
329 status
= pk_setkey(uid
, key
);
331 fprintf(stderr
, "%s\n", strstatus(status
));
338 key_encrypt_pk_2_svc_prog(uid_t uid
, cryptkeyarg2
*arg
)
340 static cryptkeyres res
;
343 fprintf(stderr
, "encrypt(%d, %s, %08x%08x) = ", uid
,
344 arg
->remotename
, arg
->deskey
.key
.high
,
345 arg
->deskey
.key
.low
);
347 res
.cryptkeyres_u
.deskey
= arg
->deskey
;
348 res
.status
= pk_encrypt(uid
, arg
->remotename
, &(arg
->remotekey
),
349 &res
.cryptkeyres_u
.deskey
);
351 if (res
.status
== KEY_SUCCESS
) {
352 fprintf(stderr
, "%08x%08x\n",
353 res
.cryptkeyres_u
.deskey
.key
.high
,
354 res
.cryptkeyres_u
.deskey
.key
.low
);
356 fprintf(stderr
, "%s\n", strstatus(res
.status
));
364 key_decrypt_pk_2_svc_prog(uid_t uid
, cryptkeyarg2
*arg
)
366 static cryptkeyres res
;
369 fprintf(stderr
, "decrypt(%d, %s, %08x%08x) = ", uid
,
370 arg
->remotename
, arg
->deskey
.key
.high
,
371 arg
->deskey
.key
.low
);
373 res
.cryptkeyres_u
.deskey
= arg
->deskey
;
374 res
.status
= pk_decrypt(uid
, arg
->remotename
, &(arg
->remotekey
),
375 &res
.cryptkeyres_u
.deskey
);
377 if (res
.status
== KEY_SUCCESS
) {
378 fprintf(stderr
, "%08x%08x\n",
379 res
.cryptkeyres_u
.deskey
.key
.high
,
380 res
.cryptkeyres_u
.deskey
.key
.low
);
382 fprintf(stderr
, "%s\n", strstatus(res
.status
));
390 key_net_put_2_svc_prog(uid_t uid
, key_netstarg
*arg
)
392 static keystatus status
;
395 fprintf(stderr
, "net_put(%s, %.*s, %.*s) = ",
396 arg
->st_netname
, (int)sizeof (arg
->st_pub_key
),
397 arg
->st_pub_key
, (int)sizeof (arg
->st_priv_key
),
401 status
= pk_netput(uid
, arg
);
404 fprintf(stderr
, "%s\n", strstatus(status
));
412 key_net_get_2_svc_prog(uid_t uid
, void *arg
)
414 static key_netstres keynetname
;
417 fprintf(stderr
, "net_get(%d) = ", uid
);
419 keynetname
.status
= pk_netget(uid
, &keynetname
.key_netstres_u
.knet
);
421 if (keynetname
.status
== KEY_SUCCESS
) {
422 fprintf(stderr
, "<%s, %.*s, %.*s>\n",
423 keynetname
.key_netstres_u
.knet
.st_netname
,
424 (int)sizeof (keynetname
.key_netstres_u
.knet
.st_pub_key
),
425 keynetname
.key_netstres_u
.knet
.st_pub_key
,
426 (int)sizeof (keynetname
.key_netstres_u
.knet
.st_priv_key
),
427 keynetname
.key_netstres_u
.knet
.st_priv_key
);
429 fprintf(stderr
, "NOT FOUND\n");
434 return (&keynetname
);
439 key_get_conv_2_svc_prog(uid_t uid
, keybuf arg
)
441 static cryptkeyres res
;
444 fprintf(stderr
, "get_conv(%d, %.*s) = ", uid
,
445 (int)sizeof (keybuf
), arg
);
448 res
.status
= pk_get_conv_key(uid
, arg
, &res
);
451 if (res
.status
== KEY_SUCCESS
) {
452 fprintf(stderr
, "%08x%08x\n",
453 res
.cryptkeyres_u
.deskey
.key
.high
,
454 res
.cryptkeyres_u
.deskey
.key
.low
);
456 fprintf(stderr
, "%s\n", strstatus(res
.status
));
465 key_encrypt_1_svc_prog(uid_t uid
, cryptkeyarg
*arg
)
467 static cryptkeyres res
;
470 fprintf(stderr
, "encrypt(%d, %s, %08x%08x) = ", uid
,
471 arg
->remotename
, arg
->deskey
.key
.high
,
472 arg
->deskey
.key
.low
);
474 res
.cryptkeyres_u
.deskey
= arg
->deskey
;
475 res
.status
= pk_encrypt(uid
, arg
->remotename
, NULL
,
476 &res
.cryptkeyres_u
.deskey
);
478 if (res
.status
== KEY_SUCCESS
) {
479 fprintf(stderr
, "%08x%08x\n",
480 res
.cryptkeyres_u
.deskey
.key
.high
,
481 res
.cryptkeyres_u
.deskey
.key
.low
);
483 fprintf(stderr
, "%s\n", strstatus(res
.status
));
491 key_decrypt_1_svc_prog(uid_t uid
, cryptkeyarg
*arg
)
493 static cryptkeyres res
;
496 fprintf(stderr
, "decrypt(%d, %s, %08x%08x) = ", uid
,
497 arg
->remotename
, arg
->deskey
.key
.high
,
498 arg
->deskey
.key
.low
);
500 res
.cryptkeyres_u
.deskey
= arg
->deskey
;
501 res
.status
= pk_decrypt(uid
, arg
->remotename
, NULL
,
502 &res
.cryptkeyres_u
.deskey
);
504 if (res
.status
== KEY_SUCCESS
) {
505 fprintf(stderr
, "%08x%08x\n",
506 res
.cryptkeyres_u
.deskey
.key
.high
,
507 res
.cryptkeyres_u
.deskey
.key
.low
);
509 fprintf(stderr
, "%s\n", strstatus(res
.status
));
518 key_gen_1_svc_prog(void *v
, struct svc_req
*s
)
521 static des_block keygen
;
522 static des_block key
;
524 gettimeofday(&time
, NULL
);
525 keygen
.key
.high
+= (time
.tv_sec
^ time
.tv_usec
);
526 keygen
.key
.low
+= (time
.tv_sec
^ time
.tv_usec
);
527 ecb_crypt((char *)&masterkey
, (char *)&keygen
, sizeof (keygen
),
528 DES_ENCRYPT
| DES_HW
);
530 des_setparity((char *)&key
);
532 fprintf(stderr
, "gen() = %08x%08x\n", key
.key
.high
,
540 key_getcred_1_svc_prog(uid_t uid
, netnamestr
*name
)
542 static getcredres res
;
543 static u_int gids
[NGROUPS
];
544 struct unixcred
*cred
;
546 cred
= &res
.getcredres_u
.cred
;
547 cred
->gids
.gids_val
= gids
;
548 if (!netname2user(*name
, (uid_t
*) &cred
->uid
, (gid_t
*) &cred
->gid
,
549 (int *)&cred
->gids
.gids_len
, (gid_t
*)gids
)) {
550 res
.status
= KEY_UNKNOWN
;
552 res
.status
= KEY_SUCCESS
;
555 fprintf(stderr
, "getcred(%s) = ", *name
);
556 if (res
.status
== KEY_SUCCESS
) {
557 fprintf(stderr
, "uid=%d, gid=%d, grouplen=%d\n",
558 cred
->uid
, cred
->gid
, cred
->gids
.gids_len
);
560 fprintf(stderr
, "%s\n", strstatus(res
.status
));
571 keyprogram(struct svc_req
*rqstp
, SVCXPRT
*transp
)
574 keybuf key_set_1_arg
;
575 cryptkeyarg key_encrypt_1_arg
;
576 cryptkeyarg key_decrypt_1_arg
;
577 netnamestr key_getcred_1_arg
;
578 cryptkeyarg key_encrypt_2_arg
;
579 cryptkeyarg key_decrypt_2_arg
;
580 netnamestr key_getcred_2_arg
;
581 cryptkeyarg2 key_encrypt_pk_2_arg
;
582 cryptkeyarg2 key_decrypt_pk_2_arg
;
583 key_netstarg key_net_put_2_arg
;
584 netobj key_get_conv_2_arg
;
587 xdrproc_t xdr_argument
, xdr_result
;
592 switch (rqstp
->rq_proc
) {
594 svc_sendreply(transp
, (xdrproc_t
)xdr_void
, NULL
);
598 xdr_argument
= (xdrproc_t
)xdr_keybuf
;
599 xdr_result
= (xdrproc_t
)xdr_int
;
600 local
= (char *(*)()) key_set_1_svc_prog
;
605 xdr_argument
= (xdrproc_t
)xdr_cryptkeyarg
;
606 xdr_result
= (xdrproc_t
)xdr_cryptkeyres
;
607 local
= (char *(*)()) key_encrypt_1_svc_prog
;
612 xdr_argument
= (xdrproc_t
)xdr_cryptkeyarg
;
613 xdr_result
= (xdrproc_t
)xdr_cryptkeyres
;
614 local
= (char *(*)()) key_decrypt_1_svc_prog
;
619 xdr_argument
= (xdrproc_t
)xdr_void
;
620 xdr_result
= (xdrproc_t
)xdr_des_block
;
621 local
= (char *(*)()) key_gen_1_svc_prog
;
626 xdr_argument
= (xdrproc_t
)xdr_netnamestr
;
627 xdr_result
= (xdrproc_t
)xdr_getcredres
;
628 local
= (char *(*)()) key_getcred_1_svc_prog
;
633 xdr_argument
= (xdrproc_t
)xdr_cryptkeyarg2
;
634 xdr_result
= (xdrproc_t
)xdr_cryptkeyres
;
635 local
= (char *(*)()) key_encrypt_pk_2_svc_prog
;
640 xdr_argument
= (xdrproc_t
)xdr_cryptkeyarg2
;
641 xdr_result
= (xdrproc_t
)xdr_cryptkeyres
;
642 local
= (char *(*)()) key_decrypt_pk_2_svc_prog
;
648 xdr_argument
= (xdrproc_t
)xdr_key_netstarg
;
649 xdr_result
= (xdrproc_t
)xdr_keystatus
;
650 local
= (char *(*)()) key_net_put_2_svc_prog
;
655 xdr_argument
= (xdrproc_t
) xdr_void
;
656 xdr_result
= (xdrproc_t
)xdr_key_netstres
;
657 local
= (char *(*)()) key_net_get_2_svc_prog
;
662 xdr_argument
= (xdrproc_t
) xdr_keybuf
;
663 xdr_result
= (xdrproc_t
)xdr_cryptkeyres
;
664 local
= (char *(*)()) key_get_conv_2_svc_prog
;
669 svcerr_noproc(transp
);
673 if (root_auth(transp
, rqstp
) == 0) {
676 "not local privileged process\n");
678 svcerr_weakauth(transp
);
681 if (rqstp
->rq_cred
.oa_flavor
!= AUTH_SYS
) {
683 fprintf(stderr
, "not unix authentication\n");
685 svcerr_weakauth(transp
);
688 uid
= ((struct authsys_parms
*)rqstp
->rq_clntcred
)->aup_uid
;
691 memset(&argument
, 0, sizeof (argument
));
692 if (!svc_getargs(transp
, xdr_argument
, &argument
)) {
693 svcerr_decode(transp
);
696 result
= (*local
) (uid
, &argument
);
697 if (!svc_sendreply(transp
, xdr_result
, result
)) {
699 fprintf(stderr
, "unable to reply\n");
700 svcerr_systemerr(transp
);
702 if (!svc_freeargs(transp
, xdr_argument
, &argument
)) {
704 fprintf(stderr
, "unable to free arguments\n");
711 root_auth(SVCXPRT
*trans
, struct svc_req
*rqstp
)
714 struct sockaddr
*remote
;
716 remote
= svc_getrpccaller(trans
)->buf
;
717 if (remote
->sa_family
!= AF_UNIX
) {
719 fprintf(stderr
, "client didn't use AF_UNIX\n");
723 if (__rpc_get_local_uid(trans
, &uid
) < 0) {
725 fprintf(stderr
, "__rpc_get_local_uid failed\n");
730 fprintf(stderr
, "local_uid %d\n", uid
);
733 if (rqstp
->rq_cred
.oa_flavor
== AUTH_SYS
) {
734 if (((uid_t
) ((struct authunix_parms
*)
735 rqstp
->rq_clntcred
)->aup_uid
)
741 "local_uid %d mismatches auth %u\n", uid
,
742 ((uid_t
) ((struct authunix_parms
*)rqstp
->rq_clntcred
)->aup_uid
));
747 fprintf(stderr
, "Not auth sys\n");
755 fprintf(stderr
, "usage: keyserv [-n] [-D] [-d] [-v] [-p path]\n");
756 fprintf(stderr
, "-d disables the use of default keys\n");