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 $
31 * $DragonFly: src/usr.sbin/keyserv/keyserv.c,v 1.6 2004/12/18 22:48:03 swildner Exp $
35 * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
40 * Store secret keys per uid. Do public key encryption and decryption
41 * operations. Generate "random" keys.
42 * Do not talk to anything but a local root
43 * process on the local transport only
53 #include <sys/types.h>
55 #include <sys/param.h>
57 #include <rpc/des_crypt.h>
59 #include <rpc/key_prot.h>
60 #include <rpcsvc/crypt.h>
68 #define KEYSERVSOCK "/var/run/keyservsock"
71 static void randomize( des_block
* );
72 static void usage( void );
73 static int getrootkey( des_block
*, int );
74 static int root_auth( SVCXPRT
*, struct svc_req
* );
77 static int debugging
= 1;
79 static int debugging
= 0;
82 static void keyprogram();
83 static des_block masterkey
;
85 static char ROOTKEY
[] = "/etc/.rootkey";
88 * Hack to allow the keyserver to use AUTH_DES (for authenticated
89 * NIS+ calls, for example). The only functions that get called
90 * are key_encryptsession_pk, key_decryptsession_pk, and key_gendes.
92 * The approach is to have the keyserver fill in pointers to local
93 * implementations of these functions, and to call those in key_call().
96 extern cryptkeyres
*(*__key_encryptsession_pk_LOCAL
)();
97 extern cryptkeyres
*(*__key_decryptsession_pk_LOCAL
)();
98 extern des_block
*(*__key_gendes_LOCAL
)();
99 extern int (*__des_crypt_LOCAL
)();
101 cryptkeyres
*key_encrypt_pk_2_svc_prog( uid_t
, cryptkeyarg2
* );
102 cryptkeyres
*key_decrypt_pk_2_svc_prog( uid_t
, cryptkeyarg2
* );
103 des_block
*key_gen_1_svc_prog( void *, struct svc_req
* );
106 main(int argc
, char **argv
)
114 struct netconfig
*nconf
= NULL
;
116 __key_encryptsession_pk_LOCAL
= &key_encrypt_pk_2_svc_prog
;
117 __key_decryptsession_pk_LOCAL
= &key_decrypt_pk_2_svc_prog
;
118 __key_gendes_LOCAL
= &key_gen_1_svc_prog
;
120 while ((c
= getopt(argc
, argv
, "ndDvp:")) != -1)
141 load_des(warn
, path
);
142 __des_crypt_LOCAL
= _my_crypt
;
143 if (svc_auth_reg(AUTH_DES
, _svcauth_des
) == -1)
144 errx(1, "failed to register AUTH_DES authenticator");
146 if (optind
!= argc
) {
153 umask(S_IXUSR
|S_IXGRP
|S_IXOTH
);
155 errx(1, "keyserv must be run as root");
156 setmodulus(HEXMODULUS
);
157 getrootkey(&masterkey
, nflag
);
159 rpcb_unset(KEY_PROG
, KEY_VERS
, NULL
);
160 rpcb_unset(KEY_PROG
, KEY_VERS2
, NULL
);
162 if (svc_create(keyprogram
, KEY_PROG
, KEY_VERS
,
164 fprintf(stderr
, "%s: unable to create service\n", argv
[0]);
168 if (svc_create(keyprogram
, KEY_PROG
, KEY_VERS2
,
170 fprintf(stderr
, "%s: unable to create service\n", argv
[0]);
174 localhandle
= setnetconfig();
175 while ((nconf
= getnetconfig(localhandle
)) != NULL
) {
176 if (nconf
->nc_protofmly
!= NULL
&&
177 strcmp(nconf
->nc_protofmly
, NC_LOOPBACK
) == 0)
182 errx(1, "getnetconfig: %s", nc_sperror());
185 rpcb_unset(CRYPT_PROG
, CRYPT_VERS
, nconf
);
186 transp
= svcunix_create(RPC_ANYSOCK
, 0, 0, KEYSERVSOCK
);
188 errx(1, "cannot create AF_LOCAL service");
189 if (!svc_reg(transp
, KEY_PROG
, KEY_VERS
, keyprogram
, nconf
))
190 errx(1, "unable to register (KEY_PROG, KEY_VERS, unix)");
191 if (!svc_reg(transp
, KEY_PROG
, KEY_VERS2
, keyprogram
, nconf
))
192 errx(1, "unable to register (KEY_PROG, KEY_VERS2, unix)");
193 if (!svc_reg(transp
, CRYPT_PROG
, CRYPT_VERS
, crypt_prog_1
, nconf
))
194 errx(1, "unable to register (CRYPT_PROG, CRYPT_VERS, unix)");
196 endnetconfig(localhandle
);
198 umask(066); /* paranoia */
204 signal(SIGPIPE
, SIG_IGN
);
212 * In the event that we don't get a root password, we try to
213 * randomize the master key the best we can
216 randomize(des_block
*master
)
218 #ifdef KEYSERV_RANDOM
219 master
->key
.low
= arc4random();
220 master
->key
.high
= arc4random();
222 /* use stupid dangerous bad rand() */
224 master
->key
.low
= rand();
225 master
->key
.high
= rand();
230 * Try to get root's secret key, by prompting if terminal is a tty, else trying
231 * from standard input.
232 * Returns 1 on success.
235 getrootkey(des_block
*master
, int prompt
)
238 char name
[MAXNETNAMELEN
+ 1];
239 char secret
[HEXKEYBYTES
];
240 key_netstarg netstore
;
245 * Read secret key out of ROOTKEY
247 fd
= open(ROOTKEY
, O_RDONLY
, 0);
252 if (read(fd
, secret
, HEXKEYBYTES
) < HEXKEYBYTES
) {
253 warnx("the key read from %s was too short", ROOTKEY
);
258 if (!getnetname(name
)) {
260 "failed to generate host's netname when establishing root's key");
263 memcpy(netstore
.st_priv_key
, secret
, HEXKEYBYTES
);
264 memset(netstore
.st_pub_key
, 0, HEXKEYBYTES
);
265 netstore
.st_netname
= name
;
266 if (pk_netput(0, &netstore
) != KEY_SUCCESS
) {
267 warnx("could not set root's key and netname");
273 * Decrypt yellow pages publickey entry to get secret key
275 passwd
= getpass("root password:");
276 passwd2des(passwd
, (char *)master
);
278 if (!getsecretkey(name
, secret
, passwd
)) {
279 warnx("can't find %s's secret key", name
);
282 if (secret
[0] == 0) {
283 warnx("password does not decrypt secret key for %s", name
);
286 pk_setkey(0, secret
);
288 * Store it for future use in $ROOTKEY, if possible
290 fd
= open(ROOTKEY
, O_WRONLY
|O_TRUNC
|O_CREAT
, 0);
294 write(fd
, secret
, strlen(secret
));
295 write(fd
, &newline
, sizeof (newline
));
302 * Procedures to implement RPC service
305 strstatus(keystatus status
)
309 return ("KEY_SUCCESS");
311 return ("KEY_NOSECRET");
313 return ("KEY_UNKNOWN");
315 return ("KEY_SYSTEMERR");
317 return ("(bad result code)");
322 key_set_1_svc_prog(uid_t uid
, keybuf key
)
324 static keystatus status
;
327 fprintf(stderr
, "set(%ld, %.*s) = ", uid
,
328 (int) sizeof (keybuf
), key
);
330 status
= pk_setkey(uid
, key
);
332 fprintf(stderr
, "%s\n", strstatus(status
));
339 key_encrypt_pk_2_svc_prog(uid_t uid
, cryptkeyarg2
*arg
)
341 static cryptkeyres res
;
344 fprintf(stderr
, "encrypt(%ld, %s, %08x%08x) = ", uid
,
345 arg
->remotename
, arg
->deskey
.key
.high
,
346 arg
->deskey
.key
.low
);
348 res
.cryptkeyres_u
.deskey
= arg
->deskey
;
349 res
.status
= pk_encrypt(uid
, arg
->remotename
, &(arg
->remotekey
),
350 &res
.cryptkeyres_u
.deskey
);
352 if (res
.status
== KEY_SUCCESS
) {
353 fprintf(stderr
, "%08x%08x\n",
354 res
.cryptkeyres_u
.deskey
.key
.high
,
355 res
.cryptkeyres_u
.deskey
.key
.low
);
357 fprintf(stderr
, "%s\n", strstatus(res
.status
));
365 key_decrypt_pk_2_svc_prog(uid_t uid
, cryptkeyarg2
*arg
)
367 static cryptkeyres res
;
370 fprintf(stderr
, "decrypt(%ld, %s, %08x%08x) = ", uid
,
371 arg
->remotename
, arg
->deskey
.key
.high
,
372 arg
->deskey
.key
.low
);
374 res
.cryptkeyres_u
.deskey
= arg
->deskey
;
375 res
.status
= pk_decrypt(uid
, arg
->remotename
, &(arg
->remotekey
),
376 &res
.cryptkeyres_u
.deskey
);
378 if (res
.status
== KEY_SUCCESS
) {
379 fprintf(stderr
, "%08x%08x\n",
380 res
.cryptkeyres_u
.deskey
.key
.high
,
381 res
.cryptkeyres_u
.deskey
.key
.low
);
383 fprintf(stderr
, "%s\n", strstatus(res
.status
));
391 key_net_put_2_svc_prog(uid_t uid
, key_netstarg
*arg
)
393 static keystatus status
;
396 fprintf(stderr
, "net_put(%s, %.*s, %.*s) = ",
397 arg
->st_netname
, (int)sizeof (arg
->st_pub_key
),
398 arg
->st_pub_key
, (int)sizeof (arg
->st_priv_key
),
402 status
= pk_netput(uid
, arg
);
405 fprintf(stderr
, "%s\n", strstatus(status
));
413 key_net_get_2_svc_prog(uid_t uid
, void *arg
)
415 static key_netstres keynetname
;
418 fprintf(stderr
, "net_get(%ld) = ", uid
);
420 keynetname
.status
= pk_netget(uid
, &keynetname
.key_netstres_u
.knet
);
422 if (keynetname
.status
== KEY_SUCCESS
) {
423 fprintf(stderr
, "<%s, %.*s, %.*s>\n",
424 keynetname
.key_netstres_u
.knet
.st_netname
,
425 (int)sizeof (keynetname
.key_netstres_u
.knet
.st_pub_key
),
426 keynetname
.key_netstres_u
.knet
.st_pub_key
,
427 (int)sizeof (keynetname
.key_netstres_u
.knet
.st_priv_key
),
428 keynetname
.key_netstres_u
.knet
.st_priv_key
);
430 fprintf(stderr
, "NOT FOUND\n");
435 return (&keynetname
);
440 key_get_conv_2_svc_prog(uid_t uid
, keybuf arg
)
442 static cryptkeyres res
;
445 fprintf(stderr
, "get_conv(%ld, %.*s) = ", uid
,
446 (int)sizeof (arg
), arg
);
449 res
.status
= pk_get_conv_key(uid
, arg
, &res
);
452 if (res
.status
== KEY_SUCCESS
) {
453 fprintf(stderr
, "%08x%08x\n",
454 res
.cryptkeyres_u
.deskey
.key
.high
,
455 res
.cryptkeyres_u
.deskey
.key
.low
);
457 fprintf(stderr
, "%s\n", strstatus(res
.status
));
466 key_encrypt_1_svc_prog(uid_t uid
, cryptkeyarg
*arg
)
468 static cryptkeyres res
;
471 fprintf(stderr
, "encrypt(%ld, %s, %08x%08x) = ", uid
,
472 arg
->remotename
, arg
->deskey
.key
.high
,
473 arg
->deskey
.key
.low
);
475 res
.cryptkeyres_u
.deskey
= arg
->deskey
;
476 res
.status
= pk_encrypt(uid
, arg
->remotename
, NULL
,
477 &res
.cryptkeyres_u
.deskey
);
479 if (res
.status
== KEY_SUCCESS
) {
480 fprintf(stderr
, "%08x%08x\n",
481 res
.cryptkeyres_u
.deskey
.key
.high
,
482 res
.cryptkeyres_u
.deskey
.key
.low
);
484 fprintf(stderr
, "%s\n", strstatus(res
.status
));
492 key_decrypt_1_svc_prog(uid_t uid
, cryptkeyarg
*arg
)
494 static cryptkeyres res
;
497 fprintf(stderr
, "decrypt(%ld, %s, %08x%08x) = ", uid
,
498 arg
->remotename
, arg
->deskey
.key
.high
,
499 arg
->deskey
.key
.low
);
501 res
.cryptkeyres_u
.deskey
= arg
->deskey
;
502 res
.status
= pk_decrypt(uid
, arg
->remotename
, NULL
,
503 &res
.cryptkeyres_u
.deskey
);
505 if (res
.status
== KEY_SUCCESS
) {
506 fprintf(stderr
, "%08x%08x\n",
507 res
.cryptkeyres_u
.deskey
.key
.high
,
508 res
.cryptkeyres_u
.deskey
.key
.low
);
510 fprintf(stderr
, "%s\n", strstatus(res
.status
));
519 key_gen_1_svc_prog(void *v
, struct svc_req
*s
)
522 static des_block keygen
;
523 static des_block key
;
525 gettimeofday(&time
, NULL
);
526 keygen
.key
.high
+= (time
.tv_sec
^ time
.tv_usec
);
527 keygen
.key
.low
+= (time
.tv_sec
^ time
.tv_usec
);
528 ecb_crypt((char *)&masterkey
, (char *)&keygen
, sizeof (keygen
),
529 DES_ENCRYPT
| DES_HW
);
531 des_setparity((char *)&key
);
533 fprintf(stderr
, "gen() = %08x%08x\n", key
.key
.high
,
541 key_getcred_1_svc_prog(uid_t uid
, netnamestr
*name
)
543 static getcredres res
;
544 static u_int gids
[NGROUPS
];
545 struct unixcred
*cred
;
547 cred
= &res
.getcredres_u
.cred
;
548 cred
->gids
.gids_val
= gids
;
549 if (!netname2user(*name
, (uid_t
*) &cred
->uid
, (gid_t
*) &cred
->gid
,
550 (int *)&cred
->gids
.gids_len
, (gid_t
*)gids
)) {
551 res
.status
= KEY_UNKNOWN
;
553 res
.status
= KEY_SUCCESS
;
556 fprintf(stderr
, "getcred(%s) = ", *name
);
557 if (res
.status
== KEY_SUCCESS
) {
558 fprintf(stderr
, "uid=%d, gid=%d, grouplen=%d\n",
559 cred
->uid
, cred
->gid
, cred
->gids
.gids_len
);
561 fprintf(stderr
, "%s\n", strstatus(res
.status
));
572 keyprogram(struct svc_req
*rqstp
, SVCXPRT
*transp
)
575 keybuf key_set_1_arg
;
576 cryptkeyarg key_encrypt_1_arg
;
577 cryptkeyarg key_decrypt_1_arg
;
578 netnamestr key_getcred_1_arg
;
579 cryptkeyarg key_encrypt_2_arg
;
580 cryptkeyarg key_decrypt_2_arg
;
581 netnamestr key_getcred_2_arg
;
582 cryptkeyarg2 key_encrypt_pk_2_arg
;
583 cryptkeyarg2 key_decrypt_pk_2_arg
;
584 key_netstarg key_net_put_2_arg
;
585 netobj key_get_conv_2_arg
;
588 xdrproc_t xdr_argument
, xdr_result
;
593 switch (rqstp
->rq_proc
) {
595 svc_sendreply(transp
, (xdrproc_t
)xdr_void
, NULL
);
599 xdr_argument
= (xdrproc_t
)xdr_keybuf
;
600 xdr_result
= (xdrproc_t
)xdr_int
;
601 local
= (char *(*)()) key_set_1_svc_prog
;
606 xdr_argument
= (xdrproc_t
)xdr_cryptkeyarg
;
607 xdr_result
= (xdrproc_t
)xdr_cryptkeyres
;
608 local
= (char *(*)()) key_encrypt_1_svc_prog
;
613 xdr_argument
= (xdrproc_t
)xdr_cryptkeyarg
;
614 xdr_result
= (xdrproc_t
)xdr_cryptkeyres
;
615 local
= (char *(*)()) key_decrypt_1_svc_prog
;
620 xdr_argument
= (xdrproc_t
)xdr_void
;
621 xdr_result
= (xdrproc_t
)xdr_des_block
;
622 local
= (char *(*)()) key_gen_1_svc_prog
;
627 xdr_argument
= (xdrproc_t
)xdr_netnamestr
;
628 xdr_result
= (xdrproc_t
)xdr_getcredres
;
629 local
= (char *(*)()) key_getcred_1_svc_prog
;
634 xdr_argument
= (xdrproc_t
)xdr_cryptkeyarg2
;
635 xdr_result
= (xdrproc_t
)xdr_cryptkeyres
;
636 local
= (char *(*)()) key_encrypt_pk_2_svc_prog
;
641 xdr_argument
= (xdrproc_t
)xdr_cryptkeyarg2
;
642 xdr_result
= (xdrproc_t
)xdr_cryptkeyres
;
643 local
= (char *(*)()) key_decrypt_pk_2_svc_prog
;
649 xdr_argument
= (xdrproc_t
)xdr_key_netstarg
;
650 xdr_result
= (xdrproc_t
)xdr_keystatus
;
651 local
= (char *(*)()) key_net_put_2_svc_prog
;
656 xdr_argument
= (xdrproc_t
) xdr_void
;
657 xdr_result
= (xdrproc_t
)xdr_key_netstres
;
658 local
= (char *(*)()) key_net_get_2_svc_prog
;
663 xdr_argument
= (xdrproc_t
) xdr_keybuf
;
664 xdr_result
= (xdrproc_t
)xdr_cryptkeyres
;
665 local
= (char *(*)()) key_get_conv_2_svc_prog
;
670 svcerr_noproc(transp
);
674 if (root_auth(transp
, rqstp
) == 0) {
677 "not local privileged process\n");
679 svcerr_weakauth(transp
);
682 if (rqstp
->rq_cred
.oa_flavor
!= AUTH_SYS
) {
684 fprintf(stderr
, "not unix authentication\n");
686 svcerr_weakauth(transp
);
689 uid
= ((struct authsys_parms
*)rqstp
->rq_clntcred
)->aup_uid
;
692 memset(&argument
, 0, sizeof (argument
));
693 if (!svc_getargs(transp
, xdr_argument
, &argument
)) {
694 svcerr_decode(transp
);
697 result
= (*local
) (uid
, &argument
);
698 if (!svc_sendreply(transp
, xdr_result
, result
)) {
700 fprintf(stderr
, "unable to reply\n");
701 svcerr_systemerr(transp
);
703 if (!svc_freeargs(transp
, xdr_argument
, &argument
)) {
705 fprintf(stderr
, "unable to free arguments\n");
712 root_auth(SVCXPRT
*trans
, struct svc_req
*rqstp
)
715 struct sockaddr
*remote
;
717 remote
= svc_getrpccaller(trans
)->buf
;
718 if (remote
->sa_family
!= AF_UNIX
) {
720 fprintf(stderr
, "client didn't use AF_UNIX\n");
724 if (__rpc_get_local_uid(trans
, &uid
) < 0) {
726 fprintf(stderr
, "__rpc_get_local_uid failed\n");
731 fprintf(stderr
, "local_uid %ld\n", uid
);
734 if (rqstp
->rq_cred
.oa_flavor
== AUTH_SYS
) {
735 if (((uid_t
) ((struct authunix_parms
*)
736 rqstp
->rq_clntcred
)->aup_uid
)
742 "local_uid %ld mismatches auth %ld\n", uid
,
743 ((uid_t
) ((struct authunix_parms
*)rqstp
->rq_clntcred
)->aup_uid
));
748 fprintf(stderr
, "Not auth sys\n");
756 fprintf(stderr
, "usage: keyserv [-n] [-D] [-d] [-v] [-p path]\n");
757 fprintf(stderr
, "-d disables the use of default keys\n");