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.3.2.2 2001/07/19 10:58:22 roam 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 <rpc/pmap_clnt.h>
56 #include <sys/param.h>
58 #include <rpc/des_crypt.h>
60 #include <rpc/key_prot.h>
61 #include <rpcsvc/crypt.h>
69 #define KEYSERVSOCK "/var/run/keyservsock"
72 static void randomize( des_block
* );
73 static void usage( void );
74 static int getrootkey( des_block
*, int );
75 static int root_auth( SVCXPRT
*, struct svc_req
* );
78 static int debugging
= 1;
80 static int debugging
= 0;
83 static void keyprogram();
84 static des_block masterkey
;
86 static char ROOTKEY
[] = "/etc/.rootkey";
89 * Hack to allow the keyserver to use AUTH_DES (for authenticated
90 * NIS+ calls, for example). The only functions that get called
91 * are key_encryptsession_pk, key_decryptsession_pk, and key_gendes.
93 * The approach is to have the keyserver fill in pointers to local
94 * implementations of these functions, and to call those in key_call().
97 extern cryptkeyres
*(*__key_encryptsession_pk_LOCAL
)();
98 extern cryptkeyres
*(*__key_decryptsession_pk_LOCAL
)();
99 extern des_block
*(*__key_gendes_LOCAL
)();
100 extern int (*__des_crypt_LOCAL
)();
102 cryptkeyres
*key_encrypt_pk_2_svc_prog( uid_t
, cryptkeyarg2
* );
103 cryptkeyres
*key_decrypt_pk_2_svc_prog( uid_t
, cryptkeyarg2
* );
104 des_block
*key_gen_1_svc_prog( void *, struct svc_req
* );
107 main(int argc
, char **argv
)
112 int sock
= RPC_ANYSOCK
;
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(066); /* paranoia */
155 errx(1, "keyserv must be run as root");
156 setmodulus(HEXMODULUS
);
157 getrootkey(&masterkey
, nflag
);
160 /* Create services. */
162 pmap_unset(KEY_PROG
, KEY_VERS
);
163 pmap_unset(KEY_PROG
, KEY_VERS2
);
166 transp
= svcudp_create(RPC_ANYSOCK
);
168 errx(1, "cannot create udp service");
169 if (!svc_register(transp
, KEY_PROG
, KEY_VERS
, keyprogram
, IPPROTO_UDP
))
170 errx(1, "unable to register (KEY_PROG, KEY_VERS, udp)");
171 if (!svc_register(transp
, KEY_PROG
, KEY_VERS2
, keyprogram
, IPPROTO_UDP
))
172 errx(1, "unable to register (KEY_PROG, KEY_VERS2, udp)");
174 transp
= svctcp_create(RPC_ANYSOCK
, 0, 0);
176 errx(1, "cannot create tcp service");
177 if (!svc_register(transp
, KEY_PROG
, KEY_VERS
, keyprogram
, IPPROTO_TCP
))
178 errx(1, "unable to register (KEY_PROG, KEY_VERS, tcp)");
179 if (!svc_register(transp
, KEY_PROG
, KEY_VERS2
, keyprogram
, IPPROTO_TCP
))
180 errx(1, "unable to register (KEY_PROG, KEY_VERS2, tcp)");
182 transp
= svcunix_create(sock
, 0, 0, KEYSERVSOCK
);
183 chmod(KEYSERVSOCK
, 0666);
185 errx(1, "cannot create AF_UNIX service");
186 if (!svc_register(transp
, KEY_PROG
, KEY_VERS
, keyprogram
, 0))
187 errx(1, "unable to register (KEY_PROG, KEY_VERS, unix)");
188 if (!svc_register(transp
, KEY_PROG
, KEY_VERS2
, keyprogram
, 0))
189 errx(1, "unable to register (KEY_PROG, KEY_VERS2, unix)");
190 if (!svc_register(transp
, CRYPT_PROG
, CRYPT_VERS
, crypt_prog_1
, 0))
191 errx(1, "unable to register (CRYPT_PROG, CRYPT_VERS, unix)");
197 signal(SIGPIPE
, SIG_IGN
);
205 * In the event that we don't get a root password, we try to
206 * randomize the master key the best we can
209 randomize(des_block
*master
)
217 for (i
= 0; i
< 1024; i
++) {
218 gettimeofday(&tv
, (struct timezone
*) NULL
);
219 shift
= i
% 8 * sizeof (int);
220 seed
^= (tv
.tv_usec
<< shift
) | (tv
.tv_usec
>> (32 - shift
));
222 #ifdef KEYSERV_RANDOM
224 master
->key
.low
= random();
225 master
->key
.high
= random();
228 /* use stupid dangerous bad rand() */
230 master
->key
.low
= rand();
231 master
->key
.high
= rand();
237 * Try to get root's secret key, by prompting if terminal is a tty, else trying
238 * from standard input.
239 * Returns 1 on success.
242 getrootkey(des_block
*master
, int prompt
)
245 char name
[MAXNETNAMELEN
+ 1];
246 char secret
[HEXKEYBYTES
];
247 key_netstarg netstore
;
252 * Read secret key out of ROOTKEY
254 fd
= open(ROOTKEY
, O_RDONLY
, 0);
259 if (read(fd
, secret
, HEXKEYBYTES
) < HEXKEYBYTES
) {
260 warnx("the key read from %s was too short", ROOTKEY
);
265 if (!getnetname(name
)) {
267 "failed to generate host's netname when establishing root's key");
270 memcpy(netstore
.st_priv_key
, secret
, HEXKEYBYTES
);
271 memset(netstore
.st_pub_key
, 0, HEXKEYBYTES
);
272 netstore
.st_netname
= name
;
273 if (pk_netput(0, &netstore
) != KEY_SUCCESS
) {
274 warnx("could not set root's key and netname");
280 * Decrypt yellow pages publickey entry to get secret key
282 passwd
= getpass("root password:");
283 passwd2des(passwd
, (char *)master
);
285 if (!getsecretkey(name
, secret
, passwd
)) {
286 warnx("can't find %s's secret key", name
);
289 if (secret
[0] == 0) {
290 warnx("password does not decrypt secret key for %s", name
);
293 pk_setkey(0, secret
);
295 * Store it for future use in $ROOTKEY, if possible
297 fd
= open(ROOTKEY
, O_WRONLY
|O_TRUNC
|O_CREAT
, 0);
301 write(fd
, secret
, strlen(secret
));
302 write(fd
, &newline
, sizeof (newline
));
309 * Procedures to implement RPC service
312 strstatus(keystatus status
)
316 return ("KEY_SUCCESS");
318 return ("KEY_NOSECRET");
320 return ("KEY_UNKNOWN");
322 return ("KEY_SYSTEMERR");
324 return ("(bad result code)");
329 key_set_1_svc_prog(uid_t uid
, keybuf key
)
331 static keystatus status
;
334 fprintf(stderr
, "set(%ld, %.*s) = ", uid
,
335 (int) sizeof (keybuf
), key
);
337 status
= pk_setkey(uid
, key
);
339 fprintf(stderr
, "%s\n", strstatus(status
));
346 key_encrypt_pk_2_svc_prog(uid_t uid
, cryptkeyarg2
*arg
)
348 static cryptkeyres res
;
351 fprintf(stderr
, "encrypt(%ld, %s, %08x%08x) = ", uid
,
352 arg
->remotename
, arg
->deskey
.key
.high
,
353 arg
->deskey
.key
.low
);
355 res
.cryptkeyres_u
.deskey
= arg
->deskey
;
356 res
.status
= pk_encrypt(uid
, arg
->remotename
, &(arg
->remotekey
),
357 &res
.cryptkeyres_u
.deskey
);
359 if (res
.status
== KEY_SUCCESS
) {
360 fprintf(stderr
, "%08x%08x\n",
361 res
.cryptkeyres_u
.deskey
.key
.high
,
362 res
.cryptkeyres_u
.deskey
.key
.low
);
364 fprintf(stderr
, "%s\n", strstatus(res
.status
));
372 key_decrypt_pk_2_svc_prog(uid_t uid
, cryptkeyarg2
*arg
)
374 static cryptkeyres res
;
377 fprintf(stderr
, "decrypt(%ld, %s, %08x%08x) = ", uid
,
378 arg
->remotename
, arg
->deskey
.key
.high
,
379 arg
->deskey
.key
.low
);
381 res
.cryptkeyres_u
.deskey
= arg
->deskey
;
382 res
.status
= pk_decrypt(uid
, arg
->remotename
, &(arg
->remotekey
),
383 &res
.cryptkeyres_u
.deskey
);
385 if (res
.status
== KEY_SUCCESS
) {
386 fprintf(stderr
, "%08x%08x\n",
387 res
.cryptkeyres_u
.deskey
.key
.high
,
388 res
.cryptkeyres_u
.deskey
.key
.low
);
390 fprintf(stderr
, "%s\n", strstatus(res
.status
));
398 key_net_put_2_svc_prog(uid_t uid
, key_netstarg
*arg
)
400 static keystatus status
;
403 fprintf(stderr
, "net_put(%s, %.*s, %.*s) = ",
404 arg
->st_netname
, (int)sizeof (arg
->st_pub_key
),
405 arg
->st_pub_key
, (int)sizeof (arg
->st_priv_key
),
409 status
= pk_netput(uid
, arg
);
412 fprintf(stderr
, "%s\n", strstatus(status
));
420 key_net_get_2_svc_prog(uid_t uid
, void *arg
)
422 static key_netstres keynetname
;
425 fprintf(stderr
, "net_get(%ld) = ", uid
);
427 keynetname
.status
= pk_netget(uid
, &keynetname
.key_netstres_u
.knet
);
429 if (keynetname
.status
== KEY_SUCCESS
) {
430 fprintf(stderr
, "<%s, %.*s, %.*s>\n",
431 keynetname
.key_netstres_u
.knet
.st_netname
,
432 (int)sizeof (keynetname
.key_netstres_u
.knet
.st_pub_key
),
433 keynetname
.key_netstres_u
.knet
.st_pub_key
,
434 (int)sizeof (keynetname
.key_netstres_u
.knet
.st_priv_key
),
435 keynetname
.key_netstres_u
.knet
.st_priv_key
);
437 fprintf(stderr
, "NOT FOUND\n");
442 return (&keynetname
);
447 key_get_conv_2_svc_prog(uid_t uid
, keybuf arg
)
449 static cryptkeyres res
;
452 fprintf(stderr
, "get_conv(%ld, %.*s) = ", uid
,
453 (int)sizeof (arg
), arg
);
456 res
.status
= pk_get_conv_key(uid
, arg
, &res
);
459 if (res
.status
== KEY_SUCCESS
) {
460 fprintf(stderr
, "%08x%08x\n",
461 res
.cryptkeyres_u
.deskey
.key
.high
,
462 res
.cryptkeyres_u
.deskey
.key
.low
);
464 fprintf(stderr
, "%s\n", strstatus(res
.status
));
473 key_encrypt_1_svc_prog(uid_t uid
, cryptkeyarg
*arg
)
475 static cryptkeyres res
;
478 fprintf(stderr
, "encrypt(%ld, %s, %08x%08x) = ", uid
,
479 arg
->remotename
, arg
->deskey
.key
.high
,
480 arg
->deskey
.key
.low
);
482 res
.cryptkeyres_u
.deskey
= arg
->deskey
;
483 res
.status
= pk_encrypt(uid
, arg
->remotename
, NULL
,
484 &res
.cryptkeyres_u
.deskey
);
486 if (res
.status
== KEY_SUCCESS
) {
487 fprintf(stderr
, "%08x%08x\n",
488 res
.cryptkeyres_u
.deskey
.key
.high
,
489 res
.cryptkeyres_u
.deskey
.key
.low
);
491 fprintf(stderr
, "%s\n", strstatus(res
.status
));
499 key_decrypt_1_svc_prog(uid_t uid
, cryptkeyarg
*arg
)
501 static cryptkeyres res
;
504 fprintf(stderr
, "decrypt(%ld, %s, %08x%08x) = ", uid
,
505 arg
->remotename
, arg
->deskey
.key
.high
,
506 arg
->deskey
.key
.low
);
508 res
.cryptkeyres_u
.deskey
= arg
->deskey
;
509 res
.status
= pk_decrypt(uid
, arg
->remotename
, NULL
,
510 &res
.cryptkeyres_u
.deskey
);
512 if (res
.status
== KEY_SUCCESS
) {
513 fprintf(stderr
, "%08x%08x\n",
514 res
.cryptkeyres_u
.deskey
.key
.high
,
515 res
.cryptkeyres_u
.deskey
.key
.low
);
517 fprintf(stderr
, "%s\n", strstatus(res
.status
));
526 key_gen_1_svc_prog(void *v
, struct svc_req
*s
)
529 static des_block keygen
;
530 static des_block key
;
532 gettimeofday(&time
, (struct timezone
*) NULL
);
533 keygen
.key
.high
+= (time
.tv_sec
^ time
.tv_usec
);
534 keygen
.key
.low
+= (time
.tv_sec
^ time
.tv_usec
);
535 ecb_crypt((char *)&masterkey
, (char *)&keygen
, sizeof (keygen
),
536 DES_ENCRYPT
| DES_HW
);
538 des_setparity((char *)&key
);
540 fprintf(stderr
, "gen() = %08x%08x\n", key
.key
.high
,
548 key_getcred_1_svc_prog(uid_t uid
, netnamestr
*name
)
550 static getcredres res
;
551 static u_int gids
[NGROUPS
];
552 struct unixcred
*cred
;
554 cred
= &res
.getcredres_u
.cred
;
555 cred
->gids
.gids_val
= gids
;
556 if (!netname2user(*name
, (uid_t
*) &cred
->uid
, (gid_t
*) &cred
->gid
,
557 (int *)&cred
->gids
.gids_len
, (gid_t
*)gids
)) {
558 res
.status
= KEY_UNKNOWN
;
560 res
.status
= KEY_SUCCESS
;
563 fprintf(stderr
, "getcred(%s) = ", *name
);
564 if (res
.status
== KEY_SUCCESS
) {
565 fprintf(stderr
, "uid=%d, gid=%d, grouplen=%d\n",
566 cred
->uid
, cred
->gid
, cred
->gids
.gids_len
);
568 fprintf(stderr
, "%s\n", strstatus(res
.status
));
579 keyprogram(struct svc_req
*rqstp
, SVCXPRT
*transp
)
582 keybuf key_set_1_arg
;
583 cryptkeyarg key_encrypt_1_arg
;
584 cryptkeyarg key_decrypt_1_arg
;
585 netnamestr key_getcred_1_arg
;
586 cryptkeyarg key_encrypt_2_arg
;
587 cryptkeyarg key_decrypt_2_arg
;
588 netnamestr key_getcred_2_arg
;
589 cryptkeyarg2 key_encrypt_pk_2_arg
;
590 cryptkeyarg2 key_decrypt_pk_2_arg
;
591 key_netstarg key_net_put_2_arg
;
592 netobj key_get_conv_2_arg
;
595 bool_t(*xdr_argument
)(), (*xdr_result
)();
600 switch (rqstp
->rq_proc
) {
602 svc_sendreply(transp
, xdr_void
, (char *)NULL
);
606 xdr_argument
= xdr_keybuf
;
607 xdr_result
= xdr_int
;
608 local
= (char *(*)()) key_set_1_svc_prog
;
613 xdr_argument
= xdr_cryptkeyarg
;
614 xdr_result
= xdr_cryptkeyres
;
615 local
= (char *(*)()) key_encrypt_1_svc_prog
;
620 xdr_argument
= xdr_cryptkeyarg
;
621 xdr_result
= xdr_cryptkeyres
;
622 local
= (char *(*)()) key_decrypt_1_svc_prog
;
627 xdr_argument
= xdr_void
;
628 xdr_result
= xdr_des_block
;
629 local
= (char *(*)()) key_gen_1_svc_prog
;
634 xdr_argument
= xdr_netnamestr
;
635 xdr_result
= xdr_getcredres
;
636 local
= (char *(*)()) key_getcred_1_svc_prog
;
641 xdr_argument
= xdr_cryptkeyarg2
;
642 xdr_result
= xdr_cryptkeyres
;
643 local
= (char *(*)()) key_encrypt_pk_2_svc_prog
;
648 xdr_argument
= xdr_cryptkeyarg2
;
649 xdr_result
= xdr_cryptkeyres
;
650 local
= (char *(*)()) key_decrypt_pk_2_svc_prog
;
656 xdr_argument
= xdr_key_netstarg
;
657 xdr_result
= xdr_keystatus
;
658 local
= (char *(*)()) key_net_put_2_svc_prog
;
663 xdr_argument
= (xdrproc_t
) xdr_void
;
664 xdr_result
= xdr_key_netstres
;
665 local
= (char *(*)()) key_net_get_2_svc_prog
;
670 xdr_argument
= (xdrproc_t
) xdr_keybuf
;
671 xdr_result
= xdr_cryptkeyres
;
672 local
= (char *(*)()) key_get_conv_2_svc_prog
;
677 svcerr_noproc(transp
);
681 if (root_auth(transp
, rqstp
) == 0) {
684 "not local privileged process\n");
686 svcerr_weakauth(transp
);
689 if (rqstp
->rq_cred
.oa_flavor
!= AUTH_SYS
) {
691 fprintf(stderr
, "not unix authentication\n");
693 svcerr_weakauth(transp
);
696 uid
= ((struct authsys_parms
*)rqstp
->rq_clntcred
)->aup_uid
;
699 memset((char *) &argument
, 0, sizeof (argument
));
700 if (!svc_getargs(transp
, xdr_argument
, (caddr_t
)&argument
)) {
701 svcerr_decode(transp
);
704 result
= (*local
) (uid
, &argument
);
705 if (!svc_sendreply(transp
, xdr_result
, (char *) result
)) {
707 fprintf(stderr
, "unable to reply\n");
708 svcerr_systemerr(transp
);
710 if (!svc_freeargs(transp
, xdr_argument
, (caddr_t
)&argument
)) {
712 fprintf(stderr
, "unable to free arguments\n");
719 root_auth(SVCXPRT
*trans
, struct svc_req
*rqstp
)
722 struct sockaddr_in
*remote
;
724 remote
= svc_getcaller(trans
);
725 if (remote
->sin_family
== AF_INET
) {
727 fprintf(stderr
, "client didn't use AF_UNIX\n");
731 if (__rpc_get_local_uid(&uid
, trans
) < 0) {
733 fprintf(stderr
, "__rpc_get_local_uid failed\n");
738 fprintf(stderr
, "local_uid %ld\n", uid
);
741 if (rqstp
->rq_cred
.oa_flavor
== AUTH_SYS
) {
742 if (((uid_t
) ((struct authunix_parms
*)
743 rqstp
->rq_clntcred
)->aup_uid
)
749 "local_uid %ld mismatches auth %ld\n", uid
,
750 ((uid_t
) ((struct authunix_parms
*)rqstp
->rq_clntcred
)->aup_uid
));
755 fprintf(stderr
, "Not auth sys\n");
763 fprintf(stderr
, "usage: keyserv [-n] [-D] [-d] [-v] [-p path]\n");
764 fprintf(stderr
, "-d disables the use of default keys\n");