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