1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * University Copyright- Copyright (c) 1982, 1986, 1988 32 * The Regents of the University of California 33 * All Rights Reserved 34 * 35 * University Acknowledgment- Portions of this document are derived from 36 * software developed by the University of California, Berkeley, and its 37 * contributors. 38 */ 39 40 #pragma ident "%Z%%M% %I% %E% SMI" 41 42 /* 43 * keyserv - server for storing private encryption keys 44 * keyserv(1M) performs multiple functions: it stores secret keys per uid; it 45 * performs public key encryption and decryption operations; and it generates 46 * "random" keys. keyserv(1M) will talk to no one but a local root process on 47 * the local transport only. 48 */ 49 50 #include <stdio.h> 51 #include <stdlib.h> 52 #include <sys/types.h> 53 #include <sys/stat.h> 54 #include <sys/uio.h> 55 #include <unistd.h> 56 #include <string.h> 57 #include <deflt.h> 58 #include <rpc/rpc.h> 59 #include <sys/param.h> 60 #include <sys/file.h> 61 #include <sys/resource.h> 62 #include <pwd.h> 63 #include <rpc/des_crypt.h> 64 #include <rpc/key_prot.h> 65 #include <thread.h> 66 #include "rpc/svc_mt.h" 67 #include <rpcsvc/nis_dhext.h> 68 #include <syslog.h> 69 #include <libscf.h> 70 71 #include "debug.h" 72 #include "keyserv_cache.h" 73 74 #ifdef KEYSERV_RANDOM 75 extern long random(); 76 #endif 77 78 extern keystatus pk_setkey(); 79 extern keystatus pk_encrypt(); 80 extern keystatus pk_decrypt(); 81 extern keystatus pk_netput(); 82 extern keystatus pk_netget(); 83 extern keystatus pk_get_conv_key(); 84 extern bool_t svc_get_local_cred(); 85 86 extern keystatus pk_setkey3(); 87 extern keystatus pk_encrypt3(); 88 extern keystatus pk_decrypt3(); 89 extern keystatus pk_netput3(); 90 extern keystatus pk_netget3(); 91 extern keystatus pk_get_conv_key3(); 92 extern keystatus pk_clear3(); 93 94 extern int init_mechs(); 95 extern int addmasterkey(); 96 extern int storeotherrootkeys(); 97 extern int setdeskeyarray(); 98 99 extern int getdomainname(); 100 101 static void randomize(); 102 static void usage(); 103 static void defaults(); 104 static int getrootkey(); 105 static int get_cache_size(char *); 106 static bool_t get_auth(); 107 108 #ifdef DEBUG 109 extern int test_debug(); 110 extern int real_debug(); 111 int debugging = 1; 112 #else 113 int debugging = 0; 114 #endif 115 116 static void keyprogram(); 117 static des_block masterkey; 118 char *getenv(); 119 static char ROOTKEY[] = "/etc/.rootkey"; 120 121 static char *defaults_file = "/etc/default/keyserv"; 122 static int use_nobody_keys = TRUE; 123 124 /* 125 * Hack to allow the keyserver to use AUTH_DES (for authenticated 126 * NIS+ calls, for example). The only functions that get called 127 * are key_encryptsession_pk, key_decryptsession_pk, and key_gendes. 128 * 129 * The approach is to have the keyserver fill in pointers to local 130 * implementations of these functions, and to call those in key_call(). 131 */ 132 133 bool_t __key_encrypt_pk_2_svc(); 134 bool_t __key_decrypt_pk_2_svc(); 135 bool_t __key_gen_1_svc(); 136 137 extern bool_t (*__key_encryptsession_pk_LOCAL)(); 138 extern bool_t (*__key_decryptsession_pk_LOCAL)(); 139 extern bool_t (*__key_gendes_LOCAL)(); 140 141 static int nthreads = 32; 142 143 /* Disk caching of common keys on by default */ 144 int disk_caching = 1; 145 146 mechanism_t **mechs; 147 148 /* 149 * The default size for all types of mech. 150 * positive integers denote multiples of 1MB 151 * negative integers denote number of entries 152 * same goes for non-null entries in cache_size 153 */ 154 static int default_cache = 1; 155 156 int *cache_size; 157 char **cache_options; 158 159 int 160 main(int argc, char *argv[]) 161 { 162 int sflag = 0, s1flag = 0, s2flag = 0, nflag = 0, dflag = 0, eflag = 0; 163 char *options, *value; 164 extern char *optarg; 165 extern int optind; 166 int c, d; 167 struct rlimit rl; 168 int mode = RPC_SVC_MT_AUTO; 169 int maxrecsz = RPC_MAXDATASIZE; 170 171 void detachfromtty(void); 172 int setmodulus(); 173 int pk_nodefaultkeys(); 174 int svc_create_local_service(); 175 176 char domainname[MAXNETNAMELEN + 1]; 177 178 /* 179 * Set our allowed number of file descriptors to the max 180 * of what the system will allow, limited by FD_SETSIZE. 181 */ 182 if (getrlimit(RLIMIT_NOFILE, &rl) == 0) { 183 rlim_t limit; 184 185 if ((limit = rl.rlim_max) > FD_SETSIZE) 186 limit = FD_SETSIZE; 187 rl.rlim_cur = limit; 188 (void) setrlimit(RLIMIT_NOFILE, &rl); 189 } 190 191 __key_encryptsession_pk_LOCAL = &__key_encrypt_pk_2_svc; 192 __key_decryptsession_pk_LOCAL = &__key_decrypt_pk_2_svc; 193 __key_gendes_LOCAL = &__key_gen_1_svc; 194 195 /* 196 * Pre-option initialisation 197 */ 198 (void) umask(066); /* paranoia */ 199 if (geteuid() != 0) { 200 (void) fprintf(stderr, "%s must be run as root\n", argv[0]); 201 exit(1); 202 } 203 setmodulus(HEXMODULUS); 204 openlog("keyserv", LOG_PID, LOG_DAEMON); 205 206 /* 207 * keyserv will not work with a null domainname. 208 */ 209 if (getdomainname(domainname, MAXNETNAMELEN+1) || 210 (domainname[0] == '\0')) { 211 syslog(LOG_ERR, "could not get a valid domainname.\n"); 212 exit(SMF_EXIT_ERR_CONFIG); 213 } 214 215 /* 216 * Initialise security mechanisms 217 */ 218 cache_size = NULL; 219 cache_options = NULL; 220 if (init_mechs() == -1) { 221 disk_caching = 0; 222 } 223 224 defaults(); 225 226 while ((c = getopt(argc, argv, "ndDet:cs:")) != -1) 227 switch (c) { 228 case 'n': 229 nflag++; 230 break; 231 case 'd': 232 dflag++; 233 use_nobody_keys = FALSE; 234 break; 235 case 'e': 236 eflag++; 237 use_nobody_keys = TRUE; 238 break; 239 case 'D': 240 debugging = 1; 241 break; 242 case 't': 243 nthreads = atoi(optarg); 244 break; 245 case 'c': 246 disk_caching = 0; 247 break; 248 case 's': 249 if (!disk_caching) { 250 fprintf(stderr, "missing configuration file"); 251 fprintf(stderr, " or -c option specified\n"); 252 usage(); 253 } 254 sflag++; 255 /* 256 * Which version of [-s] do we have...? 257 */ 258 if (strchr((const char *) optarg, '=') == NULL) { 259 /* 260 * -s <size> 261 */ 262 if (s1flag) { 263 fprintf(stderr, "duplicate [-s <size>]\n"); 264 usage(); 265 } 266 s1flag++; 267 default_cache = get_cache_size(optarg); 268 break; 269 } 270 /* 271 * -s <mechtype>=<size>[,...] 272 */ 273 s2flag++; 274 options = optarg; 275 while (*options != '\0') { 276 d = getsubopt(&options, cache_options, &value); 277 if (d == -1) { 278 /* Ignore unknown mechtype */ 279 continue; 280 } 281 if (value == NULL) { 282 fprintf(stderr, 283 "missing cache size for mechtype %s\n", 284 cache_options[d]); 285 usage(); 286 } 287 cache_size[d] = get_cache_size(value); 288 } 289 break; 290 default: 291 usage(); 292 break; 293 } 294 295 296 if (dflag && eflag) { 297 (void) fprintf(stderr, "specify only one of -d and -e\n"); 298 usage(); 299 } 300 301 if (use_nobody_keys == FALSE) { 302 pk_nodefaultkeys(); 303 } 304 305 if (optind != argc) { 306 usage(); 307 } 308 309 if (!disk_caching && sflag) { 310 fprintf(stderr, "missing configuration file"); 311 fprintf(stderr, " or -c option specified\n"); 312 usage(); 313 } 314 315 if (debugging) { 316 if (disk_caching) { 317 char **cpp = cache_options; 318 int *ip = cache_size; 319 (void) fprintf(stderr, "default disk cache size: "); 320 if (default_cache < 0) { 321 (void) fprintf(stderr, "%d entries\n", 322 abs(default_cache)); 323 } else { 324 (void) fprintf(stderr, "%dMB\n", default_cache); 325 } 326 327 (void) fprintf(stderr, "supported mechanisms:\n"); 328 (void) fprintf(stderr, "\talias\t\tdisk cache size\n"); 329 (void) fprintf(stderr, "\t=====\t\t===============\n"); 330 while (*cpp != NULL) { 331 (void) fprintf(stderr, "\t%s\t\t", *cpp++); 332 if (*ip < 0) { 333 (void) fprintf(stderr, "%d entries\n", 334 abs(*ip)); 335 } else { 336 (void) fprintf(stderr, "%dMB\n", *ip); 337 } 338 ip++; 339 } 340 } else { 341 (void) fprintf(stderr, 342 "common key disk caching disabled\n"); 343 } 344 } 345 /* 346 * Post-option initialisation 347 */ 348 if (disk_caching) { 349 int i; 350 for (i = 0; mechs[i]; i++) { 351 if ((AUTH_DES_COMPAT_CHK(mechs[i])) || 352 (mechs[i]->keylen < 0) || (mechs[i]->algtype < 0)) 353 continue; 354 create_cache_file(mechs[i]->keylen, mechs[i]->algtype, 355 cache_size[i] ? cache_size[i] : default_cache); 356 } 357 } 358 getrootkey(&masterkey, nflag); 359 360 /* 361 * Set MT mode 362 */ 363 if (nthreads > 0) { 364 (void) rpc_control(RPC_SVC_MTMODE_SET, &mode); 365 (void) rpc_control(RPC_SVC_THRMAX_SET, &nthreads); 366 } 367 368 /* 369 * Enable non-blocking mode and maximum record size checks for 370 * connection oriented transports. 371 */ 372 if (!rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrecsz)) { 373 syslog(LOG_INFO, "unable to set max RPC record size"); 374 } 375 376 if (svc_create_local_service(keyprogram, KEY_PROG, KEY_VERS, 377 "netpath", "keyserv") == 0) { 378 syslog(LOG_ERR, 379 "%s: unable to create service for version %d\n", 380 argv[0], KEY_VERS); 381 exit(1); 382 } 383 384 if (svc_create_local_service(keyprogram, KEY_PROG, KEY_VERS2, 385 "netpath", "keyserv") == 0) { 386 syslog(LOG_ERR, 387 "%s: unable to create service for version %d\n", 388 argv[0], KEY_VERS2); 389 exit(1); 390 } 391 392 if (svc_create_local_service(keyprogram, KEY_PROG, KEY_VERS3, 393 "netpath", "keyserv") == 0) { 394 syslog(LOG_ERR, 395 "%s: unable to create service for version %d\n", 396 argv[0], KEY_VERS3); 397 exit(1); 398 } 399 400 if (!debugging) { 401 detachfromtty(); 402 } 403 404 if (svc_create(keyprogram, KEY_PROG, KEY_VERS, "door") == 0) { 405 syslog(LOG_ERR, 406 "%s: unable to create service over doors for version %d\n", 407 argv[0], KEY_VERS); 408 exit(1); 409 } 410 411 if (svc_create(keyprogram, KEY_PROG, KEY_VERS2, "door") == 0) { 412 syslog(LOG_ERR, 413 "%s: unable to create service over doors for version %d\n", 414 argv[0], KEY_VERS2); 415 exit(1); 416 } 417 418 if (svc_create(keyprogram, KEY_PROG, KEY_VERS3, "door") == 0) { 419 syslog(LOG_ERR, 420 "%s: unable to create service over doors for version %d\n", 421 argv[0], KEY_VERS3); 422 exit(1); 423 } 424 425 svc_run(); 426 abort(); 427 /* NOTREACHED */ 428 return (0); 429 } 430 431 432 /* 433 * In the event that we don't get a root password, we try to 434 * randomize the master key the best we can 435 */ 436 static void 437 randomize(master) 438 des_block *master; 439 { 440 int i; 441 int seed; 442 struct timeval tv; 443 int shift; 444 445 seed = 0; 446 for (i = 0; i < 1024; i++) { 447 (void) gettimeofday(&tv, (struct timezone *)NULL); 448 shift = i % 8 * sizeof (int); 449 seed ^= (tv.tv_usec << shift) | (tv.tv_usec >> (32 - shift)); 450 } 451 #ifdef KEYSERV_RANDOM 452 srandom(seed); 453 master->key.low = random(); 454 master->key.high = random(); 455 srandom(seed); 456 #else 457 /* use stupid dangerous bad rand() */ 458 srand(seed); 459 master->key.low = rand(); 460 master->key.high = rand(); 461 srand(seed); 462 #endif 463 } 464 465 static char * 466 fgets_ignorenul(char *s, int n, FILE *stream) 467 { 468 int fildes = fileno(stream); 469 int i = 0; 470 int rs = 0; 471 char c; 472 473 if (fildes < 0) 474 return (NULL); 475 476 while (i < n - 1) { 477 rs = read(fildes, &c, 1); 478 switch (rs) { 479 case 1: 480 break; 481 case 0: 482 /* EOF */ 483 if (i > 0) 484 s[i] = '\0'; 485 return (NULL); 486 break; 487 default: 488 return (NULL); 489 } 490 switch (c) { 491 case '\0': 492 break; 493 case '\n': 494 s[i] = c; 495 s[++i] = '\0'; 496 return (s); 497 default: 498 if (c != '\0') 499 s[i++] = c; 500 } 501 } 502 s[i] = '\0'; 503 return (s); 504 } 505 506 /* Should last until 16384-bit DH keys */ 507 #define MAXROOTKEY_LINE_LEN 4224 508 #define MAXROOTKEY_LEN 4096 509 #define ROOTKEY_FILE "/etc/.rootkey" 510 511 static int 512 getotherrootkeys(char *name) 513 { 514 FILE *rootkey; 515 char line[MAXROOTKEY_LINE_LEN]; 516 char key[MAXROOTKEY_LEN]; 517 algtype_t algtype; 518 int count = 0; 519 520 if (!(rootkey = fopen(ROOTKEY, "r"))) 521 return (0); 522 523 while (fgets_ignorenul(line, MAXROOTKEY_LINE_LEN, rootkey)) { 524 debug(KEYSERV_DEBUG0, ("ROOTKEY %d: %s\n", count, line)); 525 count++; 526 sscanf(line, "%s %d", key, &algtype); 527 528 if (!strlen(key)) 529 continue; 530 addmasterkey(key, name, algtype); 531 } 532 fclose(rootkey); 533 return (1); 534 } 535 536 /* 537 * Try to get root's secret key, by prompting if terminal is a tty, else trying 538 * from standard input. 539 * Returns 1 on success. 540 */ 541 static int 542 getrootkey(master, prompt) 543 des_block *master; 544 int prompt; 545 { 546 char *passwd; 547 char name[MAXNETNAMELEN + 1]; 548 char secret[HEXKEYBYTES + 1]; 549 FILE *fp; 550 int passwd2des(); 551 int retval; 552 553 randomize(master); 554 if (!getnetname(name)) { 555 (void) fprintf(stderr, "keyserv: \ 556 failed to generate host's netname when establishing root's key.\n"); 557 return (0); 558 } 559 if (!prompt) { 560 return (getotherrootkeys(name)); 561 } 562 /* 563 * Decrypt yellow pages publickey entry to get secret key 564 */ 565 passwd = getpass("root password:"); 566 passwd2des(passwd, master); 567 if (!getsecretkey(name, secret, passwd)) { 568 (void) fprintf(stderr, 569 "Can't find %s's secret key\n", name); 570 return (0); 571 } 572 if (secret[0] == 0) { 573 (void) fprintf(stderr, 574 "Password does not decrypt secret key for %s\n", name); 575 return (0); 576 } 577 if ((fp = fopen(ROOTKEY, "w")) == NULL) { 578 (void) fprintf(stderr, 579 "Cannot open %s for write\n", ROOTKEY); 580 return (0); 581 } 582 retval = storeotherrootkeys(fp, name, passwd, secret); 583 fclose(fp); 584 return (retval); 585 } 586 587 /* 588 * Procedures to implement RPC service. These procedures are named 589 * differently from the definitions in key_prot.h (generated by rpcgen) 590 * because they take different arguments. 591 */ 592 char * 593 strstatus(status) 594 keystatus status; 595 { 596 switch (status) { 597 case KEY_SUCCESS: 598 return ("KEY_SUCCESS"); 599 case KEY_NOSECRET: 600 return ("KEY_NOSECRET"); 601 case KEY_UNKNOWN: 602 return ("KEY_UNKNOWN"); 603 case KEY_SYSTEMERR: 604 return ("KEY_SYSTEMERR"); 605 case KEY_BADALG: 606 return ("KEY_BADALG"); 607 case KEY_BADLEN: 608 return ("KEY_BADLEN"); 609 default: 610 return ("(bad result code)"); 611 } 612 } 613 614 bool_t 615 __key_set_1_svc(uid, key, status) 616 uid_t uid; 617 keybuf key; 618 keystatus *status; 619 { 620 if (debugging) { 621 (void) fprintf(stderr, "set(%d, %.*s) = ", uid, 622 sizeof (keybuf), key); 623 } 624 *status = pk_setkey(uid, key); 625 if (debugging) { 626 (void) fprintf(stderr, "%s\n", strstatus(*status)); 627 (void) fflush(stderr); 628 } 629 return (TRUE); 630 } 631 632 bool_t 633 __key_encrypt_pk_2_svc(uid, arg, res) 634 uid_t uid; 635 cryptkeyarg2 *arg; 636 cryptkeyres *res; 637 { 638 639 if (debugging) { 640 (void) fprintf(stderr, "encrypt(%d, %s, %08x%08x) = ", uid, 641 arg->remotename, arg->deskey.key.high, 642 arg->deskey.key.low); 643 } 644 res->cryptkeyres_u.deskey = arg->deskey; 645 res->status = pk_encrypt(uid, arg->remotename, &(arg->remotekey), 646 &res->cryptkeyres_u.deskey); 647 if (debugging) { 648 if (res->status == KEY_SUCCESS) { 649 (void) fprintf(stderr, "%08x%08x\n", 650 res->cryptkeyres_u.deskey.key.high, 651 res->cryptkeyres_u.deskey.key.low); 652 } else { 653 (void) fprintf(stderr, "%s\n", strstatus(res->status)); 654 } 655 (void) fflush(stderr); 656 } 657 return (TRUE); 658 } 659 660 bool_t 661 __key_decrypt_pk_2_svc(uid, arg, res) 662 uid_t uid; 663 cryptkeyarg2 *arg; 664 cryptkeyres *res; 665 { 666 667 if (debugging) { 668 (void) fprintf(stderr, "decrypt(%d, %s, %08x%08x) = ", uid, 669 arg->remotename, arg->deskey.key.high, 670 arg->deskey.key.low); 671 } 672 res->cryptkeyres_u.deskey = arg->deskey; 673 res->status = pk_decrypt(uid, arg->remotename, &(arg->remotekey), 674 &res->cryptkeyres_u.deskey); 675 if (debugging) { 676 if (res->status == KEY_SUCCESS) { 677 (void) fprintf(stderr, "%08x%08x\n", 678 res->cryptkeyres_u.deskey.key.high, 679 res->cryptkeyres_u.deskey.key.low); 680 } else { 681 (void) fprintf(stderr, "%s\n", strstatus(res->status)); 682 } 683 (void) fflush(stderr); 684 } 685 return (TRUE); 686 } 687 688 bool_t 689 __key_net_put_2_svc(uid, arg, status) 690 uid_t uid; 691 key_netstarg *arg; 692 keystatus *status; 693 { 694 695 if (debugging) { 696 (void) fprintf(stderr, "net_put(%s, %.*s, %.*s) = ", 697 arg->st_netname, sizeof (arg->st_pub_key), 698 arg->st_pub_key, sizeof (arg->st_priv_key), 699 arg->st_priv_key); 700 }; 701 702 *status = pk_netput(uid, arg); 703 704 if (debugging) { 705 (void) fprintf(stderr, "%s\n", strstatus(*status)); 706 (void) fflush(stderr); 707 } 708 709 return (TRUE); 710 } 711 712 /* ARGSUSED */ 713 bool_t 714 __key_net_get_2_svc(uid, arg, keynetname) 715 uid_t uid; 716 void *arg; 717 key_netstres *keynetname; 718 { 719 720 if (debugging) 721 (void) fprintf(stderr, "net_get(%d) = ", uid); 722 723 keynetname->status = pk_netget(uid, &keynetname->key_netstres_u.knet); 724 if (debugging) { 725 if (keynetname->status == KEY_SUCCESS) { 726 fprintf(stderr, "<%s, %.*s, %.*s>\n", 727 keynetname->key_netstres_u.knet.st_netname, 728 sizeof (keynetname->key_netstres_u.knet.st_pub_key), 729 keynetname->key_netstres_u.knet.st_pub_key, 730 sizeof (keynetname->key_netstres_u.knet.st_priv_key), 731 keynetname->key_netstres_u.knet.st_priv_key); 732 } else { 733 (void) fprintf(stderr, "NOT FOUND\n"); 734 } 735 (void) fflush(stderr); 736 } 737 738 return (TRUE); 739 740 } 741 742 bool_t 743 __key_get_conv_2_svc(uid, arg, res) 744 uid_t uid; 745 keybuf arg; 746 cryptkeyres *res; 747 { 748 749 if (debugging) 750 (void) fprintf(stderr, "get_conv(%d, %.*s) = ", uid, 751 sizeof (arg), arg); 752 753 754 res->status = pk_get_conv_key(uid, arg, res); 755 756 if (debugging) { 757 if (res->status == KEY_SUCCESS) { 758 (void) fprintf(stderr, "%08x%08x\n", 759 res->cryptkeyres_u.deskey.key.high, 760 res->cryptkeyres_u.deskey.key.low); 761 } else { 762 (void) fprintf(stderr, "%s\n", strstatus(res->status)); 763 } 764 (void) fflush(stderr); 765 } 766 return (TRUE); 767 } 768 769 770 bool_t 771 __key_encrypt_1_svc(uid, arg, res) 772 uid_t uid; 773 cryptkeyarg *arg; 774 cryptkeyres *res; 775 { 776 777 if (debugging) { 778 (void) fprintf(stderr, "encrypt(%d, %s, %08x%08x) = ", uid, 779 arg->remotename, arg->deskey.key.high, 780 arg->deskey.key.low); 781 } 782 res->cryptkeyres_u.deskey = arg->deskey; 783 res->status = pk_encrypt(uid, arg->remotename, NULL, 784 &res->cryptkeyres_u.deskey); 785 if (debugging) { 786 if (res->status == KEY_SUCCESS) { 787 (void) fprintf(stderr, "%08x%08x\n", 788 res->cryptkeyres_u.deskey.key.high, 789 res->cryptkeyres_u.deskey.key.low); 790 } else { 791 (void) fprintf(stderr, "%s\n", strstatus(res->status)); 792 } 793 (void) fflush(stderr); 794 } 795 return (TRUE); 796 } 797 798 bool_t 799 __key_decrypt_1_svc(uid, arg, res) 800 uid_t uid; 801 cryptkeyarg *arg; 802 cryptkeyres *res; 803 { 804 if (debugging) { 805 (void) fprintf(stderr, "decrypt(%d, %s, %08x%08x) = ", uid, 806 arg->remotename, arg->deskey.key.high, 807 arg->deskey.key.low); 808 } 809 res->cryptkeyres_u.deskey = arg->deskey; 810 res->status = pk_decrypt(uid, arg->remotename, NULL, 811 &res->cryptkeyres_u.deskey); 812 if (debugging) { 813 if (res->status == KEY_SUCCESS) { 814 (void) fprintf(stderr, "%08x%08x\n", 815 res->cryptkeyres_u.deskey.key.high, 816 res->cryptkeyres_u.deskey.key.low); 817 } else { 818 (void) fprintf(stderr, "%s\n", strstatus(res->status)); 819 } 820 (void) fflush(stderr); 821 } 822 return (TRUE); 823 } 824 825 /* ARGSUSED */ 826 bool_t 827 __key_gen_1_svc(v, s, key) 828 void *v; 829 struct svc_req *s; 830 des_block *key; 831 { 832 struct timeval time; 833 static des_block keygen; 834 static mutex_t keygen_mutex = DEFAULTMUTEX; 835 int r; 836 837 (void) gettimeofday(&time, (struct timezone *)NULL); 838 (void) mutex_lock(&keygen_mutex); 839 keygen.key.high += (time.tv_sec ^ time.tv_usec); 840 keygen.key.low += (time.tv_sec ^ time.tv_usec); 841 r = ecb_crypt((char *)&masterkey, (char *)&keygen, sizeof (keygen), 842 DES_ENCRYPT | DES_HW); 843 if (r != DESERR_NONE && r != DESERR_NOHWDEVICE) { 844 mutex_unlock(&keygen_mutex); 845 return (FALSE); 846 } 847 *key = keygen; 848 mutex_unlock(&keygen_mutex); 849 850 des_setparity_g(key); 851 if (debugging) { 852 (void) fprintf(stderr, "gen() = %08x%08x\n", key->key.high, 853 key->key.low); 854 (void) fflush(stderr); 855 } 856 return (TRUE); 857 } 858 859 /* ARGSUSED */ 860 bool_t 861 __key_getcred_1_svc(uid, name, res) 862 uid_t uid; 863 netnamestr *name; 864 getcredres *res; 865 { 866 struct unixcred *cred; 867 868 cred = &res->getcredres_u.cred; 869 if (!netname2user(*name, (uid_t *)&cred->uid, (gid_t *)&cred->gid, 870 (int *)&cred->gids.gids_len, 871 (gid_t *)cred->gids.gids_val)) { 872 res->status = KEY_UNKNOWN; 873 } else { 874 res->status = KEY_SUCCESS; 875 } 876 if (debugging) { 877 (void) fprintf(stderr, "getcred(%s) = ", *name); 878 if (res->status == KEY_SUCCESS) { 879 (void) fprintf(stderr, "uid=%d, gid=%d, grouplen=%d\n", 880 cred->uid, cred->gid, cred->gids.gids_len); 881 } else { 882 (void) fprintf(stderr, "%s\n", strstatus(res->status)); 883 } 884 (void) fflush(stderr); 885 } 886 return (TRUE); 887 } 888 889 /* 890 * Version 3 procedures follow... 891 */ 892 893 static bool_t 894 __key_set_3_svc(uid_t uid, setkeyarg3 *arg, keystatus *status) 895 { 896 debug(KEYSERV_DEBUG, ("__key_set_3_svc(%d, %d, %d)", 897 uid, arg->algtype, arg->keylen)); 898 *status = pk_setkey3(uid, arg); 899 debug(KEYSERV_DEBUG, ("__key_set_3_svc %s", strstatus(*status))); 900 return (TRUE); 901 } 902 903 static bool_t 904 __key_encrypt_3_svc(uid_t uid, cryptkeyarg3 *arg, cryptkeyres3 *res) 905 { 906 int len, i; 907 des_block *dp; 908 909 debug(KEYSERV_DEBUG, ("encrypt_3(%d %d %s)", uid, 910 arg->deskey.deskeyarray_len, arg->remotename)); 911 res->status = pk_encrypt3(uid, arg, &res->cryptkeyres3_u.deskey); 912 len = res->cryptkeyres3_u.deskey.deskeyarray_len; 913 dp = res->cryptkeyres3_u.deskey.deskeyarray_val; 914 for (i = 0; i < len; i++) { 915 debug(KEYSERV_DEBUG0, ("encrypt_3 retval[%d] == (%x,%x)", 916 i, dp->key.high, dp->key.low)); 917 dp++; 918 } 919 debug(KEYSERV_DEBUG, ("encrypt_3 returned %s", strstatus(res->status))); 920 return (TRUE); 921 } 922 923 static bool_t 924 __key_decrypt_3_svc(uid_t uid, cryptkeyarg3 *arg, cryptkeyres3 *res) 925 { 926 int len, i; 927 des_block *dp; 928 929 debug(KEYSERV_DEBUG, ("decrypt_3(%d, %d, %s)", uid, 930 arg->deskey.deskeyarray_len, arg->remotename)); 931 res->status = pk_decrypt3(uid, arg, &res->cryptkeyres3_u.deskey); 932 len = res->cryptkeyres3_u.deskey.deskeyarray_len; 933 dp = res->cryptkeyres3_u.deskey.deskeyarray_val; 934 for (i = 0; i < len; i++) { 935 debug(KEYSERV_DEBUG0, ("decrypt_3 retval[%d] == (%x,%x)", 936 i, dp->key.high, dp->key.low)); 937 dp++; 938 } 939 debug(KEYSERV_DEBUG, ("decrypt_3 returned %s", strstatus(res->status))); 940 return (TRUE); 941 } 942 943 /* ARGSUSED */ 944 static bool_t 945 __key_gen_3_svc(void *v, keynum_t *kp, deskeyarray *res) 946 { 947 int i; 948 keynum_t keynum = *kp; 949 950 debug(KEYSERV_DEBUG, ("gen_3(%d %x)", keynum, res)); 951 res->deskeyarray_val = 0; 952 if (!setdeskeyarray(res, keynum)) { 953 return (FALSE); 954 } 955 for (i = 0; i < keynum; i++) { 956 debug(KEYSERV_DEBUG, ("gen_3 calling gen_1 %x", 957 res->deskeyarray_val+i)); 958 __key_gen_1_svc((void *) NULL, (struct svc_req *)NULL, 959 res->deskeyarray_val+i); 960 debug(KEYSERV_DEBUG, ("gen_3 val %d %x", 961 i, *(int *)(res->deskeyarray_val+i))); 962 } 963 return (TRUE); 964 } 965 966 static void 967 __key_gen_3_svc_free(deskeyarray *dp) 968 { 969 free(dp->deskeyarray_val); 970 } 971 972 static bool_t 973 __key_getcred_3_svc(uid_t uid, netnamestr *name, getcredres3 *res) 974 { 975 return (__key_getcred_1_svc(uid, name, (getcredres *)res)); 976 } 977 978 static bool_t 979 __key_encrypt_pk_3_svc(uid_t uid, cryptkeyarg3 *arg, cryptkeyres3 *res) 980 { 981 debug(KEYSERV_DEBUG, ("encrypt_pk_3(%d, %s)", uid, arg->remotename)); 982 res->status = pk_encrypt3(uid, arg, &res->cryptkeyres3_u.deskey); 983 debug(KEYSERV_DEBUG, ("encrypt returned %s", strstatus(res->status))); 984 return (TRUE); 985 } 986 987 static void 988 __key_encrypt_pk_3_svc_free(cryptkeyres3 *res) 989 { 990 if (res->status == KEY_SUCCESS) { 991 free(res->cryptkeyres3_u.deskey.deskeyarray_val); 992 } 993 } 994 995 static bool_t 996 __key_decrypt_pk_3(uid_t uid, cryptkeyarg3 *arg, cryptkeyres3 *res) 997 { 998 debug(KEYSERV_DEBUG, ("decrypt_pk_3(%d, %s)", uid, arg->remotename)); 999 res->status = pk_decrypt3(uid, arg, &res->cryptkeyres3_u.deskey); 1000 debug(KEYSERV_DEBUG, ("encrypt returned %s", strstatus(res->status))); 1001 return (TRUE); 1002 } 1003 1004 static void 1005 __key_decrypt_pk_3_free(cryptkeyres3 *res) 1006 { 1007 if (res->status == KEY_SUCCESS) { 1008 free(res->cryptkeyres3_u.deskey.deskeyarray_val); 1009 } 1010 } 1011 1012 static bool_t 1013 __key_net_put_3_svc(uid_t uid, key_netstarg3 *arg, keystatus *status) 1014 { 1015 debug(KEYSERV_DEBUG, ("net_put_3 (%d, %x)", uid, arg)); 1016 *status = pk_netput3(uid, arg); 1017 debug(KEYSERV_DEBUG, ("net_put_3 ret %s", strstatus(*status))); 1018 return (TRUE); 1019 } 1020 1021 static bool_t 1022 __key_net_get_3_svc(uid_t uid, mechtype *arg, key_netstres3 *keynetname) 1023 { 1024 debug(KEYSERV_DEBUG, ("net_get_3 (%d, %x)", uid, arg)); 1025 keynetname->status = pk_netget3(uid, 1026 arg, &keynetname->key_netstres3_u.knet); 1027 debug(KEYSERV_DEBUG, 1028 ("net_get_3 ret %s", strstatus(keynetname->status))); 1029 return (TRUE); 1030 } 1031 1032 static void 1033 __key_net_get_3_svc_free(key_netstres3 *keynetname) 1034 { 1035 if (keynetname->status == KEY_SUCCESS) { 1036 free(keynetname->key_netstres3_u.knet.st_priv_key.keybuf3_val); 1037 free(keynetname->key_netstres3_u.knet.st_pub_key.keybuf3_val); 1038 free(keynetname->key_netstres3_u.knet.st_netname); 1039 } 1040 } 1041 1042 static bool_t 1043 __key_get_conv_3_svc(uid_t uid, deskeyarg3 *arg, cryptkeyres3 *res) 1044 { 1045 debug(KEYSERV_DEBUG, ("get_conv_3(%d %x %x)", uid, arg, res)); 1046 res->status = pk_get_conv_key3(uid, arg, res); 1047 debug(KEYSERV_DEBUG, 1048 ("get_conv_3 ret %s", strstatus(res->status))); 1049 return (TRUE); 1050 } 1051 1052 /* ARGSUSED */ 1053 static bool_t 1054 __key_clear_3_svc(uid_t uid, void *arg, keystatus *status) 1055 { 1056 debug(KEYSERV_DEBUG, ("clear_3(%d)", uid)); 1057 *status = pk_clear3(uid); 1058 debug(KEYSERV_DEBUG, ("clear_3 ret %s", strstatus(*status))); 1059 return (TRUE); 1060 } 1061 1062 /* 1063 * RPC boilerplate 1064 */ 1065 static void 1066 keyprogram(rqstp, transp) 1067 struct svc_req *rqstp; 1068 SVCXPRT *transp; 1069 { 1070 union { 1071 keybuf key_set_1_arg; 1072 cryptkeyarg key_encrypt_1_arg; 1073 cryptkeyarg key_decrypt_1_arg; 1074 netnamestr key_getcred_1_arg; 1075 cryptkeyarg key_encrypt_2_arg; 1076 cryptkeyarg key_decrypt_2_arg; 1077 netnamestr key_getcred_2_arg; 1078 cryptkeyarg2 key_encrypt_pk_2_arg; 1079 cryptkeyarg2 key_decrypt_pk_2_arg; 1080 key_netstarg key_net_put_2_arg; 1081 netobj key_get_conv_2_arg; 1082 keybuf3 key_set_3_arg; 1083 cryptkeyarg3 key_encrypt_3_arg; 1084 cryptkeyarg3 key_decrypt_3_arg; 1085 cryptkeyarg3 key_encrypt_pk_3_arg; 1086 cryptkeyarg3 key_decrypt_pk_3_arg; 1087 keynum_t key_gen_3_arg; 1088 netnamestr key_getcred_3_arg; 1089 key_netstarg3 key_net_put_3_arg; 1090 key_netstarg3 key_net_get_3_arg; 1091 deskeyarg3 key_get_conv_3_arg; 1092 } argument; 1093 union { 1094 keystatus status; 1095 cryptkeyres cres; 1096 des_block key; 1097 getcredres gres; 1098 key_netstres keynetname; 1099 cryptkeyres3 cres3; 1100 deskeyarray keyarray; 1101 getcredres3 gres3; 1102 key_netstres3 keynetname3; 1103 } result; 1104 uint_t gids[MAXGIDS]; 1105 char netname_str[MAXNETNAMELEN + 1]; 1106 bool_t (*xdr_argument)(), (*xdr_result)(); 1107 bool_t (*local)(); 1108 void (*local_free)() = NULL; 1109 bool_t retval; 1110 uid_t uid; 1111 int check_auth; 1112 1113 switch (rqstp->rq_proc) { 1114 case NULLPROC: 1115 svc_sendreply(transp, xdr_void, (char *)NULL); 1116 return; 1117 1118 case KEY_SET: 1119 xdr_argument = xdr_keybuf; 1120 xdr_result = xdr_int; 1121 local = __key_set_1_svc; 1122 check_auth = 1; 1123 break; 1124 1125 case KEY_ENCRYPT: 1126 xdr_argument = xdr_cryptkeyarg; 1127 xdr_result = xdr_cryptkeyres; 1128 local = __key_encrypt_1_svc; 1129 check_auth = 1; 1130 break; 1131 1132 case KEY_DECRYPT: 1133 xdr_argument = xdr_cryptkeyarg; 1134 xdr_result = xdr_cryptkeyres; 1135 local = __key_decrypt_1_svc; 1136 check_auth = 1; 1137 break; 1138 1139 case KEY_GEN: 1140 xdr_argument = xdr_void; 1141 xdr_result = xdr_des_block; 1142 local = __key_gen_1_svc; 1143 check_auth = 0; 1144 break; 1145 1146 case KEY_GETCRED: 1147 xdr_argument = xdr_netnamestr; 1148 xdr_result = xdr_getcredres; 1149 local = __key_getcred_1_svc; 1150 result.gres.getcredres_u.cred.gids.gids_val = gids; 1151 check_auth = 0; 1152 break; 1153 1154 case KEY_ENCRYPT_PK: 1155 xdr_argument = xdr_cryptkeyarg2; 1156 xdr_result = xdr_cryptkeyres; 1157 local = __key_encrypt_pk_2_svc; 1158 check_auth = 1; 1159 break; 1160 1161 case KEY_DECRYPT_PK: 1162 xdr_argument = xdr_cryptkeyarg2; 1163 xdr_result = xdr_cryptkeyres; 1164 local = __key_decrypt_pk_2_svc; 1165 check_auth = 1; 1166 break; 1167 1168 1169 case KEY_NET_PUT: 1170 xdr_argument = xdr_key_netstarg; 1171 xdr_result = xdr_keystatus; 1172 local = __key_net_put_2_svc; 1173 check_auth = 1; 1174 break; 1175 1176 case KEY_NET_GET: 1177 xdr_argument = (xdrproc_t)xdr_void; 1178 xdr_result = xdr_key_netstres; 1179 local = __key_net_get_2_svc; 1180 result.keynetname.key_netstres_u.knet.st_netname = netname_str; 1181 check_auth = 1; 1182 break; 1183 1184 case KEY_GET_CONV: 1185 xdr_argument = (xdrproc_t)xdr_keybuf; 1186 xdr_result = xdr_cryptkeyres; 1187 local = __key_get_conv_2_svc; 1188 check_auth = 1; 1189 break; 1190 1191 /* 1192 * Version 3 procedures follow... 1193 */ 1194 1195 case KEY_SET_3: 1196 xdr_argument = (xdrproc_t)xdr_setkeyarg3; 1197 xdr_result = xdr_keystatus; 1198 local = __key_set_3_svc; 1199 check_auth = 1; 1200 break; 1201 1202 case KEY_ENCRYPT_3: 1203 xdr_argument = (xdrproc_t)xdr_cryptkeyarg3; 1204 xdr_result = xdr_cryptkeyres3; 1205 local = __key_encrypt_3_svc; 1206 check_auth = 1; 1207 break; 1208 1209 case KEY_DECRYPT_3: 1210 xdr_argument = (xdrproc_t)xdr_cryptkeyarg3; 1211 xdr_result = xdr_cryptkeyres3; 1212 local = __key_decrypt_3_svc; 1213 check_auth = 1; 1214 break; 1215 1216 case KEY_GEN_3: 1217 xdr_argument = (xdrproc_t)xdr_keynum_t; 1218 xdr_result = xdr_deskeyarray; 1219 local = __key_gen_3_svc; 1220 local_free = __key_gen_3_svc_free; 1221 check_auth = 0; 1222 break; 1223 1224 case KEY_GETCRED_3: 1225 xdr_argument = (xdrproc_t)xdr_netnamestr; 1226 xdr_result = xdr_getcredres3; 1227 local = __key_getcred_3_svc; 1228 check_auth = 0; 1229 break; 1230 1231 case KEY_ENCRYPT_PK_3: 1232 xdr_argument = (xdrproc_t)xdr_cryptkeyarg3; 1233 xdr_result = xdr_cryptkeyres3; 1234 local = __key_encrypt_pk_3_svc; 1235 local_free = __key_encrypt_pk_3_svc_free; 1236 check_auth = 1; 1237 break; 1238 1239 case KEY_DECRYPT_PK_3: 1240 xdr_argument = (xdrproc_t)xdr_cryptkeyarg3; 1241 xdr_result = xdr_cryptkeyres3; 1242 local = __key_decrypt_pk_3; 1243 local_free = __key_decrypt_pk_3_free; 1244 check_auth = 1; 1245 break; 1246 1247 case KEY_NET_PUT_3: 1248 xdr_argument = (xdrproc_t)xdr_key_netstarg3; 1249 xdr_result = xdr_keystatus; 1250 local = __key_net_put_3_svc; 1251 check_auth = 1; 1252 break; 1253 1254 case KEY_NET_GET_3: 1255 xdr_argument = (xdrproc_t)xdr_mechtype; 1256 xdr_result = xdr_key_netstres3; 1257 local = __key_net_get_3_svc; 1258 local_free = __key_net_get_3_svc_free; 1259 check_auth = 1; 1260 break; 1261 1262 case KEY_GET_CONV_3: 1263 xdr_argument = (xdrproc_t)xdr_deskeyarg3; 1264 xdr_result = xdr_cryptkeyres3; 1265 local = __key_get_conv_3_svc; 1266 check_auth = 1; 1267 break; 1268 1269 case KEY_CLEAR_3: 1270 xdr_argument = (xdrproc_t)xdr_void; 1271 xdr_result = xdr_keystatus; 1272 local = __key_clear_3_svc; 1273 check_auth = 1; 1274 break; 1275 1276 default: 1277 svcerr_noproc(transp); 1278 return; 1279 } 1280 if (check_auth) { 1281 if (!get_auth(transp, rqstp, &uid)) { 1282 if (debugging) { 1283 (void) fprintf(stderr, 1284 "not local privileged process\n"); 1285 } 1286 svcerr_weakauth(transp); 1287 return; 1288 } 1289 } 1290 1291 memset((char *)&argument, 0, sizeof (argument)); 1292 if (!svc_getargs(transp, xdr_argument, (caddr_t)&argument)) { 1293 svcerr_decode(transp); 1294 return; 1295 } 1296 retval = (*local)(uid, &argument, &result); 1297 if (retval && !svc_sendreply(transp, xdr_result, (char *)&result)) { 1298 if (debugging) 1299 (void) fprintf(stderr, "unable to reply\n"); 1300 svcerr_systemerr(transp); 1301 } 1302 if (!svc_freeargs(transp, xdr_argument, (caddr_t)&argument)) { 1303 if (debugging) 1304 (void) fprintf(stderr, 1305 "unable to free arguments\n"); 1306 exit(1); 1307 } 1308 if (local_free) { 1309 (*local_free)(&result); 1310 } 1311 } 1312 1313 static bool_t 1314 get_auth(trans, rqstp, uid) 1315 SVCXPRT *trans; 1316 struct svc_req *rqstp; 1317 uid_t *uid; 1318 { 1319 svc_local_cred_t cred; 1320 1321 if (!svc_get_local_cred(trans, &cred)) { 1322 if (debugging) 1323 fprintf(stderr, "svc_get_local_cred failed %s %s\n", 1324 trans->xp_netid, trans->xp_tp); 1325 return (FALSE); 1326 } 1327 if (debugging) 1328 fprintf(stderr, "local_uid %d\n", cred.euid); 1329 if (rqstp->rq_cred.oa_flavor == AUTH_SYS || 1330 rqstp->rq_cred.oa_flavor == AUTH_LOOPBACK) { 1331 /* LINTED pointer alignment */ 1332 *uid = ((struct authunix_parms *)rqstp->rq_clntcred)->aup_uid; 1333 return (*uid == cred.euid || cred.euid == 0); 1334 } else { 1335 *uid = cred.euid; 1336 return (TRUE); 1337 } 1338 } 1339 1340 static int 1341 get_cache_size(size) 1342 char *size; 1343 { 1344 int csize, len; 1345 1346 len = (int)strlen(size); 1347 if (len == 0) { 1348 usage(); 1349 } 1350 1351 if (size[len-1] == 'M' || size[len-1] == 'm') { 1352 /* 1353 * cache size in MB 1354 */ 1355 size[len-1] = '\0'; 1356 csize = atoi(size); 1357 } else { 1358 csize = atoi(size); 1359 /* 1360 * negative size indicates number of entries in cache 1361 */ 1362 csize = 0 - csize; 1363 } 1364 1365 if (csize == 0) { 1366 (void) fprintf(stderr, "invalid cache size: %s\n", size); 1367 usage(); 1368 } 1369 1370 return (csize); 1371 } 1372 1373 static void 1374 usage() 1375 { 1376 (void) fprintf(stderr, "usage: \n"); 1377 (void) fprintf(stderr, "keyserv [-c]|[-s "); 1378 (void) fprintf(stderr, "<size>|<mechtype>=<size>[,...]] [-n] [-D] "); 1379 (void) fprintf(stderr, "[-d | -e] "); 1380 (void) fprintf(stderr, "[-t threads]\n"); 1381 (void) fprintf(stderr, "-d disables the use of default keys\n"); 1382 (void) fprintf(stderr, "-e enables the use of default keys\n"); 1383 exit(1); 1384 } 1385 1386 static void 1387 defaults(void) 1388 { 1389 register int flags; 1390 register char *ptr; 1391 1392 if (defopen(defaults_file) == 0) { 1393 /* 1394 * ignore case 1395 */ 1396 flags = defcntl(DC_GETFLAGS, 0); 1397 TURNOFF(flags, DC_CASE); 1398 defcntl(DC_SETFLAGS, flags); 1399 1400 if ((ptr = defread("ENABLE_NOBODY_KEYS=")) != NULL) { 1401 if (strcasecmp(ptr, "NO") == 0) { 1402 use_nobody_keys = FALSE; 1403 } 1404 } 1405 1406 (void) defopen((char *)NULL); 1407 } 1408 } 1409