1 /* 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. 8 * 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. 12 * 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. 16 * 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. 20 * 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. 24 * 25 * Sun Microsystems, Inc. 26 * 2550 Garcia Avenue 27 * Mountain View, California 94043 28 */ 29 30 #ifndef lint 31 #if 0 32 static char sccsid[] = "@(#)keyserv.c 1.15 94/04/25 SMI"; 33 #endif 34 static const char rcsid[] = 35 "$Id$"; 36 #endif /* not lint */ 37 38 /* 39 * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc. 40 */ 41 42 /* 43 * Keyserver 44 * Store secret keys per uid. Do public key encryption and decryption 45 * operations. Generate "random" keys. 46 * Do not talk to anything but a local root 47 * process on the local transport only 48 */ 49 50 #include <err.h> 51 #include <pwd.h> 52 #include <stdio.h> 53 #include <stdlib.h> 54 #include <string.h> 55 #include <unistd.h> 56 #include <sys/stat.h> 57 #include <sys/types.h> 58 #include <rpc/rpc.h> 59 #include <rpc/pmap_clnt.h> 60 #include <sys/param.h> 61 #include <sys/file.h> 62 #include <rpc/des_crypt.h> 63 #include <rpc/des.h> 64 #include <rpc/key_prot.h> 65 #include <rpcsvc/crypt.h> 66 #include "keyserv.h" 67 68 #ifndef NGROUPS 69 #define NGROUPS 16 70 #endif 71 72 #ifndef KEYSERVSOCK 73 #define KEYSERVSOCK "/var/run/keyservsock" 74 #endif 75 76 static void randomize __P(( des_block * )); 77 static void usage __P(( void )); 78 static int getrootkey __P(( des_block *, int )); 79 static int root_auth __P(( SVCXPRT *, struct svc_req * )); 80 81 #ifdef DEBUG 82 static int debugging = 1; 83 #else 84 static int debugging = 0; 85 #endif 86 87 static void keyprogram(); 88 static des_block masterkey; 89 char *getenv(); 90 static char ROOTKEY[] = "/etc/.rootkey"; 91 92 /* 93 * Hack to allow the keyserver to use AUTH_DES (for authenticated 94 * NIS+ calls, for example). The only functions that get called 95 * are key_encryptsession_pk, key_decryptsession_pk, and key_gendes. 96 * 97 * The approach is to have the keyserver fill in pointers to local 98 * implementations of these functions, and to call those in key_call(). 99 */ 100 101 extern cryptkeyres *(*__key_encryptsession_pk_LOCAL)(); 102 extern cryptkeyres *(*__key_decryptsession_pk_LOCAL)(); 103 extern des_block *(*__key_gendes_LOCAL)(); 104 extern int (*__des_crypt_LOCAL)(); 105 106 cryptkeyres *key_encrypt_pk_2_svc_prog __P(( uid_t, cryptkeyarg2 * )); 107 cryptkeyres *key_decrypt_pk_2_svc_prog __P(( uid_t, cryptkeyarg2 * )); 108 des_block *key_gen_1_svc_prog __P(( void *, struct svc_req * )); 109 110 int 111 main(argc, argv) 112 int argc; 113 char *argv[]; 114 { 115 int nflag = 0; 116 int c; 117 register SVCXPRT *transp; 118 int sock = RPC_ANYSOCK; 119 int warn = 0; 120 char *path = NULL; 121 122 __key_encryptsession_pk_LOCAL = &key_encrypt_pk_2_svc_prog; 123 __key_decryptsession_pk_LOCAL = &key_decrypt_pk_2_svc_prog; 124 __key_gendes_LOCAL = &key_gen_1_svc_prog; 125 126 while ((c = getopt(argc, argv, "ndDvp:")) != -1) 127 switch (c) { 128 case 'n': 129 nflag++; 130 break; 131 case 'd': 132 pk_nodefaultkeys(); 133 break; 134 case 'D': 135 debugging = 1; 136 break; 137 case 'v': 138 warn = 1; 139 break; 140 case 'p': 141 path = optarg; 142 break; 143 default: 144 usage(); 145 } 146 147 load_des(warn, path); 148 __des_crypt_LOCAL = _my_crypt; 149 if (svc_auth_reg(AUTH_DES, _svcauth_des) == -1) 150 errx(1, "failed to register AUTH_DES authenticator"); 151 152 if (optind != argc) { 153 usage(); 154 } 155 156 /* 157 * Initialize 158 */ 159 (void) umask(066); /* paranoia */ 160 if (geteuid() != 0) 161 errx(1, "keyserv must be run as root"); 162 setmodulus(HEXMODULUS); 163 getrootkey(&masterkey, nflag); 164 165 166 /* Create services. */ 167 168 (void) pmap_unset(KEY_PROG, KEY_VERS); 169 (void) pmap_unset(KEY_PROG, KEY_VERS2); 170 unlink(KEYSERVSOCK); 171 172 transp = svcudp_create(RPC_ANYSOCK); 173 if (transp == NULL) 174 errx(1, "cannot create udp service"); 175 if (!svc_register(transp, KEY_PROG, KEY_VERS, keyprogram, IPPROTO_UDP)) 176 errx(1, "unable to register (KEY_PROG, KEY_VERS, udp)"); 177 if (!svc_register(transp, KEY_PROG, KEY_VERS2, keyprogram, IPPROTO_UDP)) 178 errx(1, "unable to register (KEY_PROG, KEY_VERS2, udp)"); 179 180 transp = svctcp_create(RPC_ANYSOCK, 0, 0); 181 if (transp == NULL) 182 errx(1, "cannot create tcp service"); 183 if (!svc_register(transp, KEY_PROG, KEY_VERS, keyprogram, IPPROTO_TCP)) 184 errx(1, "unable to register (KEY_PROG, KEY_VERS, tcp)"); 185 if (!svc_register(transp, KEY_PROG, KEY_VERS2, keyprogram, IPPROTO_TCP)) 186 errx(1, "unable to register (KEY_PROG, KEY_VERS2, tcp)"); 187 188 transp = svcunix_create(sock, 0, 0, KEYSERVSOCK); 189 chmod(KEYSERVSOCK, 0666); 190 if (transp == NULL) 191 errx(1, "cannot create AF_UNIX service"); 192 if (!svc_register(transp, KEY_PROG, KEY_VERS, keyprogram, 0)) 193 errx(1, "unable to register (KEY_PROG, KEY_VERS, unix)"); 194 if (!svc_register(transp, KEY_PROG, KEY_VERS2, keyprogram, 0)) 195 errx(1, "unable to register (KEY_PROG, KEY_VERS2, unix)"); 196 if (!svc_register(transp, CRYPT_PROG, CRYPT_VERS, crypt_prog_1, 0)) 197 errx(1, "unable to register (CRYPT_PROG, CRYPT_VERS, unix)"); 198 199 if (!debugging) { 200 daemon(0,0); 201 } 202 203 signal(SIGPIPE, SIG_IGN); 204 205 svc_run(); 206 abort(); 207 /* NOTREACHED */ 208 } 209 210 /* 211 * In the event that we don't get a root password, we try to 212 * randomize the master key the best we can 213 */ 214 static void 215 randomize(master) 216 des_block *master; 217 { 218 int i; 219 int seed; 220 struct timeval tv; 221 int shift; 222 223 seed = 0; 224 for (i = 0; i < 1024; i++) { 225 (void) gettimeofday(&tv, (struct timezone *) NULL); 226 shift = i % 8 * sizeof (int); 227 seed ^= (tv.tv_usec << shift) | (tv.tv_usec >> (32 - shift)); 228 } 229 #ifdef KEYSERV_RANDOM 230 srandom(seed); 231 master->key.low = random(); 232 master->key.high = random(); 233 srandom(seed); 234 #else 235 /* use stupid dangerous bad rand() */ 236 srand(seed); 237 master->key.low = rand(); 238 master->key.high = rand(); 239 srand(seed); 240 #endif 241 } 242 243 /* 244 * Try to get root's secret key, by prompting if terminal is a tty, else trying 245 * from standard input. 246 * Returns 1 on success. 247 */ 248 static int 249 getrootkey(master, prompt) 250 des_block *master; 251 int prompt; 252 { 253 char *passwd; 254 char name[MAXNETNAMELEN + 1]; 255 char secret[HEXKEYBYTES]; 256 key_netstarg netstore; 257 int fd; 258 259 if (!prompt) { 260 /* 261 * Read secret key out of ROOTKEY 262 */ 263 fd = open(ROOTKEY, O_RDONLY, 0); 264 if (fd < 0) { 265 randomize(master); 266 return (0); 267 } 268 if (read(fd, secret, HEXKEYBYTES) < HEXKEYBYTES) { 269 warnx("the key read from %s was too short", ROOTKEY); 270 (void) close(fd); 271 return (0); 272 } 273 (void) close(fd); 274 if (!getnetname(name)) { 275 warnx( 276 "failed to generate host's netname when establishing root's key"); 277 return (0); 278 } 279 memcpy(netstore.st_priv_key, secret, HEXKEYBYTES); 280 memset(netstore.st_pub_key, 0, HEXKEYBYTES); 281 netstore.st_netname = name; 282 if (pk_netput(0, &netstore) != KEY_SUCCESS) { 283 warnx("could not set root's key and netname"); 284 return (0); 285 } 286 return (1); 287 } 288 /* 289 * Decrypt yellow pages publickey entry to get secret key 290 */ 291 passwd = getpass("root password:"); 292 passwd2des(passwd, (char *)master); 293 getnetname(name); 294 if (!getsecretkey(name, secret, passwd)) { 295 warnx("can't find %s's secret key", name); 296 return (0); 297 } 298 if (secret[0] == 0) { 299 warnx("password does not decrypt secret key for %s", name); 300 return (0); 301 } 302 (void) pk_setkey(0, secret); 303 /* 304 * Store it for future use in $ROOTKEY, if possible 305 */ 306 fd = open(ROOTKEY, O_WRONLY|O_TRUNC|O_CREAT, 0); 307 if (fd > 0) { 308 char newline = '\n'; 309 310 write(fd, secret, strlen(secret)); 311 write(fd, &newline, sizeof (newline)); 312 close(fd); 313 } 314 return (1); 315 } 316 317 /* 318 * Procedures to implement RPC service 319 */ 320 char * 321 strstatus(status) 322 keystatus status; 323 { 324 switch (status) { 325 case KEY_SUCCESS: 326 return ("KEY_SUCCESS"); 327 case KEY_NOSECRET: 328 return ("KEY_NOSECRET"); 329 case KEY_UNKNOWN: 330 return ("KEY_UNKNOWN"); 331 case KEY_SYSTEMERR: 332 return ("KEY_SYSTEMERR"); 333 default: 334 return ("(bad result code)"); 335 } 336 } 337 338 keystatus * 339 key_set_1_svc_prog(uid, key) 340 uid_t uid; 341 keybuf key; 342 { 343 static keystatus status; 344 345 if (debugging) { 346 (void) fprintf(stderr, "set(%ld, %.*s) = ", uid, 347 (int) sizeof (keybuf), key); 348 } 349 status = pk_setkey(uid, key); 350 if (debugging) { 351 (void) fprintf(stderr, "%s\n", strstatus(status)); 352 (void) fflush(stderr); 353 } 354 return (&status); 355 } 356 357 cryptkeyres * 358 key_encrypt_pk_2_svc_prog(uid, arg) 359 uid_t uid; 360 cryptkeyarg2 *arg; 361 { 362 static cryptkeyres res; 363 364 if (debugging) { 365 (void) fprintf(stderr, "encrypt(%ld, %s, %08x%08x) = ", uid, 366 arg->remotename, arg->deskey.key.high, 367 arg->deskey.key.low); 368 } 369 res.cryptkeyres_u.deskey = arg->deskey; 370 res.status = pk_encrypt(uid, arg->remotename, &(arg->remotekey), 371 &res.cryptkeyres_u.deskey); 372 if (debugging) { 373 if (res.status == KEY_SUCCESS) { 374 (void) fprintf(stderr, "%08x%08x\n", 375 res.cryptkeyres_u.deskey.key.high, 376 res.cryptkeyres_u.deskey.key.low); 377 } else { 378 (void) fprintf(stderr, "%s\n", strstatus(res.status)); 379 } 380 (void) fflush(stderr); 381 } 382 return (&res); 383 } 384 385 cryptkeyres * 386 key_decrypt_pk_2_svc_prog(uid, arg) 387 uid_t uid; 388 cryptkeyarg2 *arg; 389 { 390 static cryptkeyres res; 391 392 if (debugging) { 393 (void) fprintf(stderr, "decrypt(%ld, %s, %08x%08x) = ", uid, 394 arg->remotename, arg->deskey.key.high, 395 arg->deskey.key.low); 396 } 397 res.cryptkeyres_u.deskey = arg->deskey; 398 res.status = pk_decrypt(uid, arg->remotename, &(arg->remotekey), 399 &res.cryptkeyres_u.deskey); 400 if (debugging) { 401 if (res.status == KEY_SUCCESS) { 402 (void) fprintf(stderr, "%08x%08x\n", 403 res.cryptkeyres_u.deskey.key.high, 404 res.cryptkeyres_u.deskey.key.low); 405 } else { 406 (void) fprintf(stderr, "%s\n", strstatus(res.status)); 407 } 408 (void) fflush(stderr); 409 } 410 return (&res); 411 } 412 413 keystatus * 414 key_net_put_2_svc_prog(uid, arg) 415 uid_t uid; 416 key_netstarg *arg; 417 { 418 static keystatus status; 419 420 if (debugging) { 421 (void) fprintf(stderr, "net_put(%s, %.*s, %.*s) = ", 422 arg->st_netname, (int)sizeof (arg->st_pub_key), 423 arg->st_pub_key, (int)sizeof (arg->st_priv_key), 424 arg->st_priv_key); 425 }; 426 427 status = pk_netput(uid, arg); 428 429 if (debugging) { 430 (void) fprintf(stderr, "%s\n", strstatus(status)); 431 (void) fflush(stderr); 432 } 433 434 return (&status); 435 } 436 437 key_netstres * 438 key_net_get_2_svc_prog(uid, arg) 439 uid_t uid; 440 void *arg; 441 { 442 static key_netstres keynetname; 443 444 if (debugging) 445 (void) fprintf(stderr, "net_get(%ld) = ", uid); 446 447 keynetname.status = pk_netget(uid, &keynetname.key_netstres_u.knet); 448 if (debugging) { 449 if (keynetname.status == KEY_SUCCESS) { 450 fprintf(stderr, "<%s, %.*s, %.*s>\n", 451 keynetname.key_netstres_u.knet.st_netname, 452 (int)sizeof (keynetname.key_netstres_u.knet.st_pub_key), 453 keynetname.key_netstres_u.knet.st_pub_key, 454 (int)sizeof (keynetname.key_netstres_u.knet.st_priv_key), 455 keynetname.key_netstres_u.knet.st_priv_key); 456 } else { 457 (void) fprintf(stderr, "NOT FOUND\n"); 458 } 459 (void) fflush(stderr); 460 } 461 462 return (&keynetname); 463 464 } 465 466 cryptkeyres * 467 key_get_conv_2_svc_prog(uid, arg) 468 uid_t uid; 469 keybuf arg; 470 { 471 static cryptkeyres res; 472 473 if (debugging) 474 (void) fprintf(stderr, "get_conv(%ld, %.*s) = ", uid, 475 (int)sizeof (arg), arg); 476 477 478 res.status = pk_get_conv_key(uid, arg, &res); 479 480 if (debugging) { 481 if (res.status == KEY_SUCCESS) { 482 (void) fprintf(stderr, "%08x%08x\n", 483 res.cryptkeyres_u.deskey.key.high, 484 res.cryptkeyres_u.deskey.key.low); 485 } else { 486 (void) fprintf(stderr, "%s\n", strstatus(res.status)); 487 } 488 (void) fflush(stderr); 489 } 490 return (&res); 491 } 492 493 494 cryptkeyres * 495 key_encrypt_1_svc_prog(uid, arg) 496 uid_t uid; 497 cryptkeyarg *arg; 498 { 499 static cryptkeyres res; 500 501 if (debugging) { 502 (void) fprintf(stderr, "encrypt(%ld, %s, %08x%08x) = ", uid, 503 arg->remotename, arg->deskey.key.high, 504 arg->deskey.key.low); 505 } 506 res.cryptkeyres_u.deskey = arg->deskey; 507 res.status = pk_encrypt(uid, arg->remotename, NULL, 508 &res.cryptkeyres_u.deskey); 509 if (debugging) { 510 if (res.status == KEY_SUCCESS) { 511 (void) fprintf(stderr, "%08x%08x\n", 512 res.cryptkeyres_u.deskey.key.high, 513 res.cryptkeyres_u.deskey.key.low); 514 } else { 515 (void) fprintf(stderr, "%s\n", strstatus(res.status)); 516 } 517 (void) fflush(stderr); 518 } 519 return (&res); 520 } 521 522 cryptkeyres * 523 key_decrypt_1_svc_prog(uid, arg) 524 uid_t uid; 525 cryptkeyarg *arg; 526 { 527 static cryptkeyres res; 528 529 if (debugging) { 530 (void) fprintf(stderr, "decrypt(%ld, %s, %08x%08x) = ", uid, 531 arg->remotename, arg->deskey.key.high, 532 arg->deskey.key.low); 533 } 534 res.cryptkeyres_u.deskey = arg->deskey; 535 res.status = pk_decrypt(uid, arg->remotename, NULL, 536 &res.cryptkeyres_u.deskey); 537 if (debugging) { 538 if (res.status == KEY_SUCCESS) { 539 (void) fprintf(stderr, "%08x%08x\n", 540 res.cryptkeyres_u.deskey.key.high, 541 res.cryptkeyres_u.deskey.key.low); 542 } else { 543 (void) fprintf(stderr, "%s\n", strstatus(res.status)); 544 } 545 (void) fflush(stderr); 546 } 547 return (&res); 548 } 549 550 /* ARGSUSED */ 551 des_block * 552 key_gen_1_svc_prog(v, s) 553 void *v; 554 struct svc_req *s; 555 { 556 struct timeval time; 557 static des_block keygen; 558 static des_block key; 559 560 (void) gettimeofday(&time, (struct timezone *) NULL); 561 keygen.key.high += (time.tv_sec ^ time.tv_usec); 562 keygen.key.low += (time.tv_sec ^ time.tv_usec); 563 ecb_crypt((char *)&masterkey, (char *)&keygen, sizeof (keygen), 564 DES_ENCRYPT | DES_HW); 565 key = keygen; 566 des_setparity((char *)&key); 567 if (debugging) { 568 (void) fprintf(stderr, "gen() = %08x%08x\n", key.key.high, 569 key.key.low); 570 (void) fflush(stderr); 571 } 572 return (&key); 573 } 574 575 getcredres * 576 key_getcred_1_svc_prog(uid, name) 577 uid_t uid; 578 netnamestr *name; 579 { 580 static getcredres res; 581 static u_int gids[NGROUPS]; 582 struct unixcred *cred; 583 584 cred = &res.getcredres_u.cred; 585 cred->gids.gids_val = gids; 586 if (!netname2user(*name, (uid_t *) &cred->uid, (gid_t *) &cred->gid, 587 (int *)&cred->gids.gids_len, (gid_t *)gids)) { 588 res.status = KEY_UNKNOWN; 589 } else { 590 res.status = KEY_SUCCESS; 591 } 592 if (debugging) { 593 (void) fprintf(stderr, "getcred(%s) = ", *name); 594 if (res.status == KEY_SUCCESS) { 595 (void) fprintf(stderr, "uid=%d, gid=%d, grouplen=%d\n", 596 cred->uid, cred->gid, cred->gids.gids_len); 597 } else { 598 (void) fprintf(stderr, "%s\n", strstatus(res.status)); 599 } 600 (void) fflush(stderr); 601 } 602 return (&res); 603 } 604 605 /* 606 * RPC boilerplate 607 */ 608 static void 609 keyprogram(rqstp, transp) 610 struct svc_req *rqstp; 611 SVCXPRT *transp; 612 { 613 union { 614 keybuf key_set_1_arg; 615 cryptkeyarg key_encrypt_1_arg; 616 cryptkeyarg key_decrypt_1_arg; 617 netnamestr key_getcred_1_arg; 618 cryptkeyarg key_encrypt_2_arg; 619 cryptkeyarg key_decrypt_2_arg; 620 netnamestr key_getcred_2_arg; 621 cryptkeyarg2 key_encrypt_pk_2_arg; 622 cryptkeyarg2 key_decrypt_pk_2_arg; 623 key_netstarg key_net_put_2_arg; 624 netobj key_get_conv_2_arg; 625 } argument; 626 char *result; 627 bool_t(*xdr_argument)(), (*xdr_result)(); 628 char *(*local) (); 629 uid_t uid = -1; 630 int check_auth; 631 632 switch (rqstp->rq_proc) { 633 case NULLPROC: 634 svc_sendreply(transp, xdr_void, (char *)NULL); 635 return; 636 637 case KEY_SET: 638 xdr_argument = xdr_keybuf; 639 xdr_result = xdr_int; 640 local = (char *(*)()) key_set_1_svc_prog; 641 check_auth = 1; 642 break; 643 644 case KEY_ENCRYPT: 645 xdr_argument = xdr_cryptkeyarg; 646 xdr_result = xdr_cryptkeyres; 647 local = (char *(*)()) key_encrypt_1_svc_prog; 648 check_auth = 1; 649 break; 650 651 case KEY_DECRYPT: 652 xdr_argument = xdr_cryptkeyarg; 653 xdr_result = xdr_cryptkeyres; 654 local = (char *(*)()) key_decrypt_1_svc_prog; 655 check_auth = 1; 656 break; 657 658 case KEY_GEN: 659 xdr_argument = xdr_void; 660 xdr_result = xdr_des_block; 661 local = (char *(*)()) key_gen_1_svc_prog; 662 check_auth = 0; 663 break; 664 665 case KEY_GETCRED: 666 xdr_argument = xdr_netnamestr; 667 xdr_result = xdr_getcredres; 668 local = (char *(*)()) key_getcred_1_svc_prog; 669 check_auth = 0; 670 break; 671 672 case KEY_ENCRYPT_PK: 673 xdr_argument = xdr_cryptkeyarg2; 674 xdr_result = xdr_cryptkeyres; 675 local = (char *(*)()) key_encrypt_pk_2_svc_prog; 676 check_auth = 1; 677 break; 678 679 case KEY_DECRYPT_PK: 680 xdr_argument = xdr_cryptkeyarg2; 681 xdr_result = xdr_cryptkeyres; 682 local = (char *(*)()) key_decrypt_pk_2_svc_prog; 683 check_auth = 1; 684 break; 685 686 687 case KEY_NET_PUT: 688 xdr_argument = xdr_key_netstarg; 689 xdr_result = xdr_keystatus; 690 local = (char *(*)()) key_net_put_2_svc_prog; 691 check_auth = 1; 692 break; 693 694 case KEY_NET_GET: 695 xdr_argument = (xdrproc_t) xdr_void; 696 xdr_result = xdr_key_netstres; 697 local = (char *(*)()) key_net_get_2_svc_prog; 698 check_auth = 1; 699 break; 700 701 case KEY_GET_CONV: 702 xdr_argument = (xdrproc_t) xdr_keybuf; 703 xdr_result = xdr_cryptkeyres; 704 local = (char *(*)()) key_get_conv_2_svc_prog; 705 check_auth = 1; 706 break; 707 708 default: 709 svcerr_noproc(transp); 710 return; 711 } 712 if (check_auth) { 713 if (root_auth(transp, rqstp) == 0) { 714 if (debugging) { 715 (void) fprintf(stderr, 716 "not local privileged process\n"); 717 } 718 svcerr_weakauth(transp); 719 return; 720 } 721 if (rqstp->rq_cred.oa_flavor != AUTH_SYS) { 722 if (debugging) { 723 (void) fprintf(stderr, 724 "not unix authentication\n"); 725 } 726 svcerr_weakauth(transp); 727 return; 728 } 729 uid = ((struct authsys_parms *)rqstp->rq_clntcred)->aup_uid; 730 } 731 732 memset((char *) &argument, 0, sizeof (argument)); 733 if (!svc_getargs(transp, xdr_argument, (caddr_t)&argument)) { 734 svcerr_decode(transp); 735 return; 736 } 737 result = (*local) (uid, &argument); 738 if (!svc_sendreply(transp, xdr_result, (char *) result)) { 739 if (debugging) 740 (void) fprintf(stderr, "unable to reply\n"); 741 svcerr_systemerr(transp); 742 } 743 if (!svc_freeargs(transp, xdr_argument, (caddr_t)&argument)) { 744 if (debugging) 745 (void) fprintf(stderr, 746 "unable to free arguments\n"); 747 exit(1); 748 } 749 return; 750 } 751 752 static int 753 root_auth(trans, rqstp) 754 SVCXPRT *trans; 755 struct svc_req *rqstp; 756 { 757 uid_t uid; 758 struct sockaddr_in *remote; 759 760 remote = svc_getcaller(trans); 761 if (remote->sin_family == AF_INET) { 762 if (debugging) 763 fprintf(stderr, "client didn't use AF_UNIX\n"); 764 return (0); 765 } 766 767 if (__rpc_get_local_uid(&uid, trans) < 0) { 768 if (debugging) 769 fprintf(stderr, "__rpc_get_local_uid failed\n"); 770 return (0); 771 } 772 773 if (debugging) 774 fprintf(stderr, "local_uid %ld\n", uid); 775 if (uid == 0) 776 return (1); 777 if (rqstp->rq_cred.oa_flavor == AUTH_SYS) { 778 if (((uid_t) ((struct authunix_parms *) 779 rqstp->rq_clntcred)->aup_uid) 780 == uid) { 781 return (1); 782 } else { 783 if (debugging) 784 fprintf(stderr, 785 "local_uid %ld mismatches auth %ld\n", uid, 786 ((uid_t) ((struct authunix_parms *)rqstp->rq_clntcred)->aup_uid)); 787 return (0); 788 } 789 } else { 790 if (debugging) 791 fprintf(stderr, "Not auth sys\n"); 792 return (0); 793 } 794 } 795 796 static void 797 usage() 798 { 799 (void) fprintf(stderr, 800 "usage: keyserv [-n] [-D] [-d] [-v] [-p path]\n"); 801 (void) fprintf(stderr, "-d disables the use of default keys\n"); 802 exit(1); 803 } 804