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