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 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 27 #include <fcntl.h> 28 #include <stdio.h> 29 #include <stdlib.h> 30 #include <strings.h> 31 #include <unistd.h> 32 #include <locale.h> 33 #include <libgen.h> 34 #include <sys/types.h> 35 #include <zone.h> 36 #include <sys/crypto/ioctladmin.h> 37 #include <cryptoutil.h> 38 #include "cryptoadm.h" 39 40 #define REQ_ARG_CNT 2 41 42 /* subcommand index */ 43 enum subcommand_index { 44 CRYPTO_LIST, 45 CRYPTO_DISABLE, 46 CRYPTO_ENABLE, 47 CRYPTO_INSTALL, 48 CRYPTO_UNINSTALL, 49 CRYPTO_UNLOAD, 50 CRYPTO_REFRESH, 51 CRYPTO_START, 52 CRYPTO_STOP, 53 CRYPTO_HELP }; 54 55 /* 56 * TRANSLATION_NOTE 57 * Command keywords are not to be translated. 58 */ 59 static char *cmd_table[] = { 60 "list", 61 "disable", 62 "enable", 63 "install", 64 "uninstall", 65 "unload", 66 "refresh", 67 "start", 68 "stop", 69 "--help" }; 70 71 /* provider type */ 72 enum provider_type_index { 73 PROV_UEF_LIB, 74 PROV_KEF_SOFT, 75 PROV_KEF_HARD, 76 METASLOT, 77 PROV_BADNAME }; 78 79 typedef struct { 80 char cp_name[MAXPATHLEN]; 81 enum provider_type_index cp_type; 82 } cryptoadm_provider_t; 83 84 /* 85 * TRANSLATION_NOTE 86 * Operand keywords are not to be translated. 87 */ 88 static const char *KN_PROVIDER = "provider="; 89 static const char *KN_MECH = "mechanism="; 90 static const char *KN_ALL = "all"; 91 static const char *KN_TOKEN = "token="; 92 static const char *KN_SLOT = "slot="; 93 static const char *KN_DEFAULT_KS = "default-keystore"; 94 static const char *KN_AUTO_KEY_MIGRATE = "auto-key-migrate"; 95 96 /* static variables */ 97 static boolean_t allflag = B_FALSE; 98 static boolean_t rndflag = B_FALSE; 99 static mechlist_t *mecharglist = NULL; 100 101 /* static functions */ 102 static void usage(void); 103 static int get_provider_type(char *); 104 static int process_mech_operands(int, char **, boolean_t); 105 static int do_list(int, char **); 106 static int do_disable(int, char **); 107 static int do_enable(int, char **); 108 static int do_install(int, char **); 109 static int do_uninstall(int, char **); 110 static int do_unload(int, char **); 111 static int do_refresh(int); 112 static int do_start(int); 113 static int do_stop(int); 114 static int list_simple_for_all(boolean_t); 115 static int list_mechlist_for_all(boolean_t); 116 static int list_policy_for_all(void); 117 118 int 119 main(int argc, char *argv[]) 120 { 121 char *subcmd; 122 int cmdnum; 123 int cmd_index = 0; 124 int rc = SUCCESS; 125 126 (void) setlocale(LC_ALL, ""); 127 128 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 129 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ 130 #endif 131 (void) textdomain(TEXT_DOMAIN); 132 133 cryptodebug_init(basename(argv[0])); 134 135 if (argc < REQ_ARG_CNT) { 136 usage(); 137 return (ERROR_USAGE); 138 } 139 140 /* get the subcommand index */ 141 cmd_index = 0; 142 subcmd = argv[1]; 143 cmdnum = sizeof (cmd_table)/sizeof (cmd_table[0]); 144 145 while ((cmd_index < cmdnum) && 146 (strcmp(subcmd, cmd_table[cmd_index]) != 0)) { 147 cmd_index++; 148 } 149 if (cmd_index >= cmdnum) { 150 usage(); 151 return (ERROR_USAGE); 152 } 153 154 /* do the subcommand */ 155 switch (cmd_index) { 156 case CRYPTO_LIST: 157 rc = do_list(argc, argv); 158 break; 159 case CRYPTO_DISABLE: 160 rc = do_disable(argc, argv); 161 break; 162 case CRYPTO_ENABLE: 163 rc = do_enable(argc, argv); 164 break; 165 case CRYPTO_INSTALL: 166 rc = do_install(argc, argv); 167 break; 168 case CRYPTO_UNINSTALL: 169 rc = do_uninstall(argc, argv); 170 break; 171 case CRYPTO_UNLOAD: 172 rc = do_unload(argc, argv); 173 break; 174 case CRYPTO_REFRESH: 175 rc = do_refresh(argc); 176 break; 177 case CRYPTO_START: 178 rc = do_start(argc); 179 break; 180 case CRYPTO_STOP: 181 rc = do_stop(argc); 182 break; 183 case CRYPTO_HELP: 184 usage(); 185 rc = SUCCESS; 186 break; 187 default: /* should not come here */ 188 usage(); 189 rc = ERROR_USAGE; 190 break; 191 } 192 return (rc); 193 } 194 195 196 static void 197 usage(void) 198 { 199 /* 200 * TRANSLATION_NOTE 201 * Command usage is not to be translated. Only the word "Usage:" 202 * along with localized expressions indicating what kind of value 203 * is expected for arguments. 204 */ 205 (void) fprintf(stderr, gettext("Usage:\n")); 206 (void) fprintf(stderr, 207 " cryptoadm list [-mpv] [provider=<%s> | metaslot]" 208 " [mechanism=<%s>]\n", 209 gettext("provider-name"), gettext("mechanism-list")); 210 (void) fprintf(stderr, 211 " cryptoadm disable provider=<%s>" 212 " mechanism=<%s> | random | all\n", 213 gettext("provider-name"), gettext("mechanism-list")); 214 (void) fprintf(stderr, 215 " cryptoadm disable metaslot" 216 " [auto-key-migrate] [mechanism=<%s>]\n", 217 gettext("mechanism-list")); 218 (void) fprintf(stderr, 219 " cryptoadm enable provider=<%s>" 220 " mechanism=<%s> | random | all\n", 221 gettext("provider-name"), gettext("mechanism-list")); 222 (void) fprintf(stderr, 223 " cryptoadm enable metaslot [mechanism=<%s>]" 224 " [[token=<%s>] [slot=<%s>]" 225 " | [default-keystore]] | [auto-key-migrate]\n", 226 gettext("mechanism-list"), gettext("token-label"), 227 gettext("slot-description")); 228 (void) fprintf(stderr, 229 " cryptoadm install provider=<%s>\n", 230 gettext("provider-name")); 231 (void) fprintf(stderr, 232 " cryptoadm install provider=<%s> [mechanism=<%s>]\n", 233 gettext("provider-name"), gettext("mechanism-list")); 234 (void) fprintf(stderr, 235 " cryptoadm uninstall provider=<%s>\n", 236 gettext("provider-name")); 237 (void) fprintf(stderr, 238 " cryptoadm unload provider=<%s>\n", 239 gettext("provider-name")); 240 (void) fprintf(stderr, 241 " cryptoadm refresh\n" 242 " cryptoadm start\n" 243 " cryptoadm stop\n" 244 " cryptoadm --help\n"); 245 } 246 247 248 /* 249 * Get the provider type. This function returns 250 * - PROV_UEF_LIB if provname contains an absolute path name 251 * - PROV_KEF_SOFT if provname is a base name only 252 * - PROV_KEF_HARD if provname contains one slash only and the slash is not 253 * the 1st character. 254 * - PROV_BADNAME otherwise. 255 */ 256 static int 257 get_provider_type(char *provname) 258 { 259 char *pslash1; 260 char *pslash2; 261 262 if (provname == NULL) { 263 return (FAILURE); 264 } 265 266 if (provname[0] == '/') { 267 return (PROV_UEF_LIB); 268 } else if ((pslash1 = strchr(provname, SEP_SLASH)) == NULL) { 269 /* no slash */ 270 return (PROV_KEF_SOFT); 271 } else { 272 pslash2 = strrchr(provname, SEP_SLASH); 273 if (pslash1 == pslash2) { 274 return (PROV_KEF_HARD); 275 } else { 276 return (PROV_BADNAME); 277 } 278 } 279 } 280 281 /* 282 * Get the provider structure. This function returns NULL if no valid 283 * provider= is found in argv[], otherwise a cryptoadm_provider_t is returned. 284 * If provider= is found but has no argument, then a cryptoadm_provider_t 285 * with cp_type = PROV_BADNAME is returned. 286 */ 287 static cryptoadm_provider_t * 288 get_provider(int argc, char **argv) 289 { 290 int c = 0; 291 boolean_t found = B_FALSE; 292 cryptoadm_provider_t *provider = NULL; 293 char *provstr = NULL, *savstr; 294 boolean_t is_metaslot = B_FALSE; 295 296 while (!found && ++c < argc) { 297 if (strncmp(argv[c], METASLOT_KEYWORD, 298 strlen(METASLOT_KEYWORD)) == 0) { 299 is_metaslot = B_TRUE; 300 found = B_TRUE; 301 } else if (strncmp(argv[c], KN_PROVIDER, 302 strlen(KN_PROVIDER)) == 0 && 303 strlen(argv[c]) > strlen(KN_PROVIDER)) { 304 if ((provstr = strdup(argv[c])) == NULL) { 305 int err = errno; 306 /* 307 * TRANSLATION_NOTE 308 * "get_provider" is a function name and should 309 * not be translated. 310 */ 311 cryptoerror(LOG_STDERR, "get_provider: %s.", 312 strerror(err)); 313 return (NULL); 314 } 315 found = B_TRUE; 316 } 317 } 318 if (!found) 319 return (NULL); 320 321 provider = malloc(sizeof (cryptoadm_provider_t)); 322 if (provider == NULL) { 323 cryptoerror(LOG_STDERR, gettext("out of memory.")); 324 if (provstr) { 325 free(provstr); 326 } 327 return (NULL); 328 } 329 330 if (is_metaslot) { 331 (void) strlcpy(provider->cp_name, METASLOT_KEYWORD, 332 strlen(METASLOT_KEYWORD)); 333 provider->cp_type = METASLOT; 334 } else { 335 336 savstr = provstr; 337 (void) strtok(provstr, "="); 338 provstr = strtok(NULL, "="); 339 if (provstr == NULL) { 340 cryptoerror(LOG_STDERR, gettext("bad provider name.")); 341 provider->cp_type = PROV_BADNAME; 342 free(savstr); 343 return (provider); 344 } 345 346 (void) strlcpy(provider->cp_name, provstr, 347 sizeof (provider->cp_name)); 348 provider->cp_type = get_provider_type(provider->cp_name); 349 350 free(savstr); 351 } 352 return (provider); 353 } 354 355 /* 356 * Process the "feature" operands. 357 * 358 * "argc" and "argv" contain values specified on the command line. 359 * All other arguments are used for returning parsing results. 360 * If any of these arguments are NULL, that keyword is not expected, 361 * and FAILURE will be returned. 362 */ 363 static int 364 process_metaslot_operands(int argc, char **argv, char **meta_ks_token, 365 char **meta_ks_slot, boolean_t *use_default, 366 boolean_t *auto_key_migrate_flag) 367 { 368 int c = 2; 369 int rc = SUCCESS; 370 371 while (++c < argc) { 372 if ((strncmp(argv[c], KN_MECH, strlen(KN_MECH)) == 0) && 373 strlen(argv[c]) > strlen(KN_MECH)) { 374 375 /* process mechanism operands */ 376 if ((rc = process_mech_operands(argc, argv, B_TRUE)) 377 != SUCCESS) { 378 goto finish; 379 } 380 381 } else if ((strncmp(argv[c], KN_TOKEN, 382 strlen(KN_TOKEN)) == 0) && 383 strlen(argv[c]) > strlen(KN_TOKEN)) { 384 if ((meta_ks_token) && (strtok(argv[c], "=") != NULL)) { 385 char *tmp; 386 if ((tmp = strtok(NULL, "=")) != NULL) { 387 *meta_ks_token = strdup(tmp); 388 } else { 389 return (FAILURE); 390 } 391 } else { 392 return (FAILURE); 393 } 394 395 } else if ((strncmp(argv[c], KN_SLOT, 396 strlen(KN_SLOT)) == 0) && 397 strlen(argv[c]) > strlen(KN_SLOT)) { 398 399 if ((meta_ks_slot) && (strtok(argv[c], "=") != NULL)) { 400 char *tmp; 401 if ((tmp = strtok(NULL, "=")) != NULL) { 402 *meta_ks_slot = strdup(tmp); 403 } else { 404 return (FAILURE); 405 } 406 } else { 407 return (FAILURE); 408 } 409 410 } else if (strncmp(argv[c], KN_DEFAULT_KS, 411 strlen(KN_DEFAULT_KS)) == 0) { 412 413 if (use_default) { 414 *use_default = B_TRUE; 415 } else { 416 return (FAILURE); 417 } 418 } else if (strncmp(argv[c], KN_AUTO_KEY_MIGRATE, 419 strlen(KN_AUTO_KEY_MIGRATE)) == 0) { 420 421 if (auto_key_migrate_flag) { 422 *auto_key_migrate_flag = B_TRUE; 423 } else { 424 return (FAILURE); 425 } 426 } else { 427 return (FAILURE); 428 } 429 } 430 finish: 431 return (rc); 432 } 433 434 /* 435 * Process the "feature" operands. 436 */ 437 static int 438 process_feature_operands(int argc, char **argv) 439 { 440 int c = 2; 441 442 while (++c < argc) { 443 if (strcmp(argv[c], KN_ALL) == 0) { 444 allflag = B_TRUE; 445 rndflag = B_TRUE; /* all includes random also. */ 446 } else if (strcmp(argv[c], RANDOM) == 0) { 447 rndflag = B_TRUE; 448 } 449 } 450 return (SUCCESS); 451 } 452 453 /* 454 * Process the mechanism operands for the disable, enable and install 455 * subcommands. This function sets the static variable allflag to be B_TRUE 456 * if the keyword "all" is specified, otherwise builds a link list of the 457 * mechanism operands and save it in the static variable mecharglist. 458 * 459 * This function returns 460 * ERROR_USAGE: mechanism operand is missing. 461 * FAILURE: out of memory. 462 * SUCCESS: otherwise. 463 */ 464 static int 465 process_mech_operands(int argc, char **argv, boolean_t quiet) 466 { 467 mechlist_t *pmech; 468 mechlist_t *pcur = NULL; 469 mechlist_t *phead = NULL; 470 boolean_t found = B_FALSE; 471 char *mechliststr = NULL; 472 char *curmech = NULL; 473 int c = -1; 474 int rc = SUCCESS; 475 476 while (!found && ++c < argc) { 477 if ((strncmp(argv[c], KN_MECH, strlen(KN_MECH)) == 0) && 478 strlen(argv[c]) > strlen(KN_MECH)) { 479 found = B_TRUE; 480 } 481 } 482 if (!found) { 483 if (!quiet) 484 /* 485 * TRANSLATION_NOTE 486 * "mechanism" could be either a literal keyword 487 * and hence not to be translated, or a descriptive 488 * word and translatable. A choice was made to 489 * view it as a literal keyword. 490 */ 491 cryptoerror(LOG_STDERR, 492 gettext("the %s operand is missing.\n"), 493 "mechanism"); 494 return (ERROR_USAGE); 495 } 496 (void) strtok(argv[c], "="); 497 mechliststr = strtok(NULL, "="); 498 499 if (strcmp(mechliststr, "all") == 0) { 500 allflag = B_TRUE; 501 mecharglist = NULL; 502 return (SUCCESS); 503 } 504 505 curmech = strtok(mechliststr, ","); 506 do { 507 if ((pmech = create_mech(curmech)) == NULL) { 508 rc = FAILURE; 509 break; 510 } else { 511 if (phead == NULL) { 512 phead = pcur = pmech; 513 } else { 514 pcur->next = pmech; 515 pcur = pmech; 516 } 517 } 518 } while ((curmech = strtok(NULL, ",")) != NULL); 519 520 if (rc == FAILURE) { 521 cryptoerror(LOG_STDERR, gettext("out of memory.")); 522 free_mechlist(phead); 523 } else { 524 mecharglist = phead; 525 rc = SUCCESS; 526 } 527 return (rc); 528 } 529 530 531 532 /* 533 * The top level function for the list subcommand and options. 534 */ 535 static int 536 do_list(int argc, char **argv) 537 { 538 boolean_t mflag = B_FALSE; 539 boolean_t pflag = B_FALSE; 540 boolean_t vflag = B_FALSE; 541 char ch; 542 cryptoadm_provider_t *prov = NULL; 543 int rc = SUCCESS; 544 545 argc -= 1; 546 argv += 1; 547 548 if (argc == 1) { 549 rc = list_simple_for_all(B_FALSE); 550 goto out; 551 } 552 553 /* 554 * [-v] [-m] [-p] [provider=<>] [mechanism=<>] 555 */ 556 if (argc > 5) { 557 usage(); 558 return (rc); 559 } 560 561 while ((ch = getopt(argc, argv, "mpv")) != EOF) { 562 switch (ch) { 563 case 'm': 564 mflag = B_TRUE; 565 if (pflag) { 566 rc = ERROR_USAGE; 567 } 568 break; 569 case 'p': 570 pflag = B_TRUE; 571 if (mflag || vflag) { 572 rc = ERROR_USAGE; 573 } 574 break; 575 case 'v': 576 vflag = B_TRUE; 577 if (pflag) 578 rc = ERROR_USAGE; 579 break; 580 default: 581 rc = ERROR_USAGE; 582 break; 583 } 584 } 585 586 if (rc == ERROR_USAGE) { 587 usage(); 588 return (rc); 589 } 590 591 if ((rc = process_feature_operands(argc, argv)) != SUCCESS) { 592 goto out; 593 } 594 595 prov = get_provider(argc, argv); 596 597 if (mflag || vflag) { 598 if (argc > 0) { 599 rc = process_mech_operands(argc, argv, B_TRUE); 600 if (rc == FAILURE) 601 goto out; 602 /* "-m" is implied when a mechanism list is given */ 603 if (mecharglist != NULL || allflag) 604 mflag = B_TRUE; 605 } 606 } 607 608 if (prov == NULL) { 609 if (mflag) { 610 rc = list_mechlist_for_all(vflag); 611 } else if (pflag) { 612 rc = list_policy_for_all(); 613 } else if (vflag) { 614 rc = list_simple_for_all(vflag); 615 } 616 } else if (prov->cp_type == METASLOT) { 617 if ((!mflag) && (!vflag) && (!pflag)) { 618 /* no flag is specified, just list metaslot status */ 619 rc = list_metaslot_info(mflag, vflag, mecharglist); 620 } else if (mflag || vflag) { 621 rc = list_metaslot_info(mflag, vflag, mecharglist); 622 } else if (pflag) { 623 rc = list_metaslot_policy(); 624 } else { 625 /* error message */ 626 usage(); 627 rc = ERROR_USAGE; 628 } 629 } else if (prov->cp_type == PROV_BADNAME) { 630 usage(); 631 rc = ERROR_USAGE; 632 goto out; 633 } else { /* do the listing for a provider only */ 634 if (mflag || vflag) { 635 if (vflag) 636 (void) printf(gettext("Provider: %s\n"), 637 prov->cp_name); 638 switch (prov->cp_type) { 639 case PROV_UEF_LIB: 640 rc = list_mechlist_for_lib(prov->cp_name, 641 mecharglist, NULL, B_FALSE, 642 vflag, mflag); 643 break; 644 case PROV_KEF_SOFT: 645 rc = list_mechlist_for_soft(prov->cp_name); 646 break; 647 case PROV_KEF_HARD: 648 rc = list_mechlist_for_hard(prov->cp_name); 649 break; 650 default: /* should not come here */ 651 rc = FAILURE; 652 break; 653 } 654 } else if (pflag) { 655 switch (prov->cp_type) { 656 case PROV_UEF_LIB: 657 rc = list_policy_for_lib(prov->cp_name); 658 break; 659 case PROV_KEF_SOFT: 660 if (getzoneid() == GLOBAL_ZONEID) { 661 rc = list_policy_for_soft( 662 prov->cp_name); 663 } else { 664 /* 665 * TRANSLATION_NOTE 666 * "global" is keyword and not to 667 * be translated. 668 */ 669 cryptoerror(LOG_STDERR, gettext( 670 "policy information for kernel " 671 "providers is available " 672 "in the %s zone only"), "global"); 673 rc = FAILURE; 674 } 675 break; 676 case PROV_KEF_HARD: 677 if (getzoneid() == GLOBAL_ZONEID) { 678 rc = list_policy_for_hard( 679 prov->cp_name); 680 } else { 681 /* 682 * TRANSLATION_NOTE 683 * "global" is keyword and not to 684 * be translated. 685 */ 686 cryptoerror(LOG_STDERR, gettext( 687 "policy information for kernel " 688 "providers is available " 689 "in the %s zone only"), "global"); 690 rc = FAILURE; 691 } 692 693 break; 694 default: /* should not come here */ 695 rc = FAILURE; 696 break; 697 } 698 } else { 699 /* error message */ 700 usage(); 701 rc = ERROR_USAGE; 702 } 703 } 704 705 out: 706 if (prov != NULL) 707 free(prov); 708 709 if (mecharglist != NULL) 710 free_mechlist(mecharglist); 711 return (rc); 712 } 713 714 715 /* 716 * The top level function for the disable subcommand. 717 */ 718 static int 719 do_disable(int argc, char **argv) 720 { 721 cryptoadm_provider_t *prov = NULL; 722 int rc = SUCCESS; 723 boolean_t auto_key_migrate_flag = B_FALSE; 724 725 if ((argc < 3) || (argc > 5)) { 726 usage(); 727 return (ERROR_USAGE); 728 } 729 730 prov = get_provider(argc, argv); 731 if (prov == NULL) { 732 usage(); 733 return (ERROR_USAGE); 734 } 735 if (prov->cp_type == PROV_BADNAME) { 736 return (FAILURE); 737 } 738 739 if ((rc = process_feature_operands(argc, argv)) != SUCCESS) { 740 goto out; 741 } 742 743 /* 744 * If allflag or rndflag has already been set there is no reason to 745 * process mech= 746 */ 747 if (prov->cp_type == METASLOT) { 748 if ((argc > 3) && 749 (rc = process_metaslot_operands(argc, argv, 750 NULL, NULL, NULL, &auto_key_migrate_flag)) != SUCCESS) { 751 usage(); 752 return (rc); 753 } 754 } else if (!allflag && !rndflag && 755 (rc = process_mech_operands(argc, argv, B_FALSE)) != SUCCESS) { 756 return (rc); 757 } 758 759 switch (prov->cp_type) { 760 case METASLOT: 761 rc = disable_metaslot(mecharglist, allflag, 762 auto_key_migrate_flag); 763 break; 764 case PROV_UEF_LIB: 765 rc = disable_uef_lib(prov->cp_name, rndflag, allflag, 766 mecharglist); 767 break; 768 case PROV_KEF_SOFT: 769 if (rndflag && !allflag) { 770 if ((mecharglist = create_mech(RANDOM)) == NULL) { 771 rc = FAILURE; 772 break; 773 } 774 } 775 if (getzoneid() == GLOBAL_ZONEID) { 776 rc = disable_kef_software(prov->cp_name, rndflag, 777 allflag, mecharglist); 778 } else { 779 /* 780 * TRANSLATION_NOTE 781 * "disable" could be either a literal keyword 782 * and hence not to be translated, or a verb and 783 * translatable. A choice was made to view it as 784 * a literal keyword. "global" is keyword and not 785 * to be translated. 786 */ 787 cryptoerror(LOG_STDERR, gettext("%1$s for kernel " 788 "providers is supported in the %2$s zone only"), 789 "disable", "global"); 790 rc = FAILURE; 791 } 792 break; 793 case PROV_KEF_HARD: 794 if (rndflag && !allflag) { 795 if ((mecharglist = create_mech(RANDOM)) == NULL) { 796 rc = FAILURE; 797 break; 798 } 799 } 800 if (getzoneid() == GLOBAL_ZONEID) { 801 rc = disable_kef_hardware(prov->cp_name, rndflag, 802 allflag, mecharglist); 803 } else { 804 /* 805 * TRANSLATION_NOTE 806 * "disable" could be either a literal keyword 807 * and hence not to be translated, or a verb and 808 * translatable. A choice was made to view it as 809 * a literal keyword. "global" is keyword and not 810 * to be translated. 811 */ 812 cryptoerror(LOG_STDERR, gettext("%1$s for kernel " 813 "providers is supported in the %2$s zone only"), 814 "disable", "global"); 815 rc = FAILURE; 816 } 817 break; 818 default: /* should not come here */ 819 rc = FAILURE; 820 break; 821 } 822 823 out: 824 free(prov); 825 if (mecharglist != NULL) { 826 free_mechlist(mecharglist); 827 } 828 return (rc); 829 } 830 831 832 /* 833 * The top level function fo the enable subcommand. 834 */ 835 static int 836 do_enable(int argc, char **argv) 837 { 838 cryptoadm_provider_t *prov = NULL; 839 int rc = SUCCESS; 840 char *alt_token = NULL, *alt_slot = NULL; 841 boolean_t use_default = B_FALSE, auto_key_migrate_flag = B_FALSE; 842 843 if ((argc < 3) || (argc > 6)) { 844 usage(); 845 return (ERROR_USAGE); 846 } 847 848 prov = get_provider(argc, argv); 849 if (prov == NULL) { 850 usage(); 851 return (ERROR_USAGE); 852 } 853 if ((prov->cp_type != METASLOT) && (argc != 4)) { 854 usage(); 855 return (ERROR_USAGE); 856 } 857 if (prov->cp_type == PROV_BADNAME) { 858 rc = FAILURE; 859 goto out; 860 } 861 862 863 if (prov->cp_type == METASLOT) { 864 if ((rc = process_metaslot_operands(argc, argv, &alt_token, 865 &alt_slot, &use_default, &auto_key_migrate_flag)) 866 != SUCCESS) { 867 usage(); 868 goto out; 869 } 870 if ((alt_slot || alt_token) && use_default) { 871 usage(); 872 rc = FAILURE; 873 goto out; 874 } 875 } else { 876 if ((rc = process_feature_operands(argc, argv)) != SUCCESS) { 877 goto out; 878 } 879 880 /* 881 * If allflag or rndflag has already been set there is 882 * no reason to process mech= 883 */ 884 if (!allflag && !rndflag && 885 (rc = process_mech_operands(argc, argv, B_FALSE)) 886 != SUCCESS) { 887 goto out; 888 } 889 } 890 891 switch (prov->cp_type) { 892 case METASLOT: 893 rc = enable_metaslot(alt_token, alt_slot, use_default, 894 mecharglist, allflag, auto_key_migrate_flag); 895 break; 896 case PROV_UEF_LIB: 897 rc = enable_uef_lib(prov->cp_name, rndflag, allflag, 898 mecharglist); 899 break; 900 case PROV_KEF_SOFT: 901 case PROV_KEF_HARD: 902 if (rndflag && !allflag) { 903 if ((mecharglist = create_mech(RANDOM)) == NULL) { 904 rc = FAILURE; 905 break; 906 } 907 } 908 if (getzoneid() == GLOBAL_ZONEID) { 909 rc = enable_kef(prov->cp_name, rndflag, allflag, 910 mecharglist); 911 } else { 912 /* 913 * TRANSLATION_NOTE 914 * "enable" could be either a literal keyword 915 * and hence not to be translated, or a verb and 916 * translatable. A choice was made to view it as 917 * a literal keyword. "global" is keyword and not 918 * to be translated. 919 */ 920 cryptoerror(LOG_STDERR, gettext("%1$s for kernel " 921 "providers is supported in the %2$s zone only"), 922 "enable", "global"); 923 rc = FAILURE; 924 } 925 break; 926 default: /* should not come here */ 927 rc = FAILURE; 928 break; 929 } 930 out: 931 free(prov); 932 if (mecharglist != NULL) { 933 free_mechlist(mecharglist); 934 } 935 if (alt_token != NULL) { 936 free(alt_token); 937 } 938 if (alt_slot != NULL) { 939 free(alt_slot); 940 } 941 return (rc); 942 } 943 944 945 946 /* 947 * The top level function fo the install subcommand. 948 */ 949 static int 950 do_install(int argc, char **argv) 951 { 952 cryptoadm_provider_t *prov = NULL; 953 int rc; 954 955 if (argc < 3) { 956 usage(); 957 return (ERROR_USAGE); 958 } 959 960 prov = get_provider(argc, argv); 961 if (prov == NULL || 962 prov->cp_type == PROV_BADNAME || prov->cp_type == PROV_KEF_HARD) { 963 /* 964 * TRANSLATION_NOTE 965 * "install" could be either a literal keyword and hence 966 * not to be translated, or a verb and translatable. A 967 * choice was made to view it as a literal keyword. 968 */ 969 cryptoerror(LOG_STDERR, 970 gettext("bad provider name for %s."), "install"); 971 rc = FAILURE; 972 goto out; 973 } 974 975 if (prov->cp_type == PROV_UEF_LIB) { 976 rc = install_uef_lib(prov->cp_name); 977 goto out; 978 } 979 980 /* It is the PROV_KEF_SOFT type now */ 981 982 /* check if there are mechanism operands */ 983 if (argc < 4) { 984 /* 985 * TRANSLATION_NOTE 986 * "mechanism" could be either a literal keyword and hence 987 * not to be translated, or a descriptive word and 988 * translatable. A choice was made to view it as a literal 989 * keyword. 990 */ 991 cryptoerror(LOG_STDERR, 992 gettext("need %s operands for installing a" 993 " kernel software provider."), "mechanism"); 994 rc = ERROR_USAGE; 995 goto out; 996 } 997 998 if ((rc = process_mech_operands(argc, argv, B_FALSE)) != SUCCESS) { 999 goto out; 1000 } 1001 1002 if (allflag == B_TRUE) { 1003 /* 1004 * TRANSLATION_NOTE 1005 * "all", "mechanism", and "install" are all keywords and 1006 * not to be translated. 1007 */ 1008 cryptoerror(LOG_STDERR, 1009 gettext("can not use the %1$s keyword for %2$s " 1010 "in the %3$s subcommand."), "all", "mechanism", "install"); 1011 rc = ERROR_USAGE; 1012 goto out; 1013 } 1014 1015 if (getzoneid() == GLOBAL_ZONEID) { 1016 rc = install_kef(prov->cp_name, mecharglist); 1017 } else { 1018 /* 1019 * TRANSLATION_NOTE 1020 * "install" could be either a literal keyword and hence 1021 * not to be translated, or a verb and translatable. A 1022 * choice was made to view it as a literal keyword. 1023 * "global" is keyword and not to be translated. 1024 */ 1025 cryptoerror(LOG_STDERR, gettext("%1$s for kernel providers " 1026 "is supported in the %2$s zone only"), "install", "global"); 1027 rc = FAILURE; 1028 } 1029 out: 1030 free(prov); 1031 return (rc); 1032 } 1033 1034 1035 1036 /* 1037 * The top level function for the uninstall subcommand. 1038 */ 1039 static int 1040 do_uninstall(int argc, char **argv) 1041 { 1042 cryptoadm_provider_t *prov = NULL; 1043 int rc = SUCCESS; 1044 1045 if (argc != 3) { 1046 usage(); 1047 return (ERROR_USAGE); 1048 } 1049 1050 prov = get_provider(argc, argv); 1051 if (prov == NULL || 1052 prov->cp_type == PROV_BADNAME || prov->cp_type == PROV_KEF_HARD) { 1053 /* 1054 * TRANSLATION_NOTE 1055 * "uninstall" could be either a literal keyword and hence 1056 * not to be translated, or a verb and translatable. A 1057 * choice was made to view it as a literal keyword. 1058 */ 1059 cryptoerror(LOG_STDERR, 1060 gettext("bad provider name for %s."), "uninstall"); 1061 free(prov); 1062 return (FAILURE); 1063 } 1064 1065 if (prov->cp_type == PROV_UEF_LIB) { 1066 rc = uninstall_uef_lib(prov->cp_name); 1067 } else if (prov->cp_type == PROV_KEF_SOFT) { 1068 if (getzoneid() == GLOBAL_ZONEID) { 1069 rc = uninstall_kef(prov->cp_name); 1070 } else { 1071 /* 1072 * TRANSLATION_NOTE 1073 * "uninstall" could be either a literal keyword and 1074 * hence not to be translated, or a verb and 1075 * translatable. A choice was made to view it as a 1076 * literal keyword. "global" is keyword and not to 1077 * be translated. 1078 */ 1079 cryptoerror(LOG_STDERR, gettext("%1$s for kernel " 1080 "providers is supported in the %2$s zone only"), 1081 "uninstall", "global"); 1082 rc = FAILURE; 1083 } 1084 } 1085 1086 free(prov); 1087 return (rc); 1088 } 1089 1090 1091 /* 1092 * The top level function for the unload subcommand. 1093 */ 1094 static int 1095 do_unload(int argc, char **argv) 1096 { 1097 cryptoadm_provider_t *prov = NULL; 1098 entry_t *pent; 1099 boolean_t is_active; 1100 int rc = SUCCESS; 1101 1102 if (argc != 3) { 1103 usage(); 1104 return (ERROR_USAGE); 1105 } 1106 1107 /* check if it is a kernel software provider */ 1108 prov = get_provider(argc, argv); 1109 if (prov == NULL) { 1110 cryptoerror(LOG_STDERR, 1111 gettext("unable to determine provider name.")); 1112 goto out; 1113 } 1114 if (prov->cp_type != PROV_KEF_SOFT) { 1115 cryptoerror(LOG_STDERR, 1116 gettext("%s is not a valid kernel software provider."), 1117 prov->cp_name); 1118 rc = FAILURE; 1119 goto out; 1120 } 1121 1122 if (getzoneid() != GLOBAL_ZONEID) { 1123 /* 1124 * TRANSLATION_NOTE 1125 * "unload" could be either a literal keyword and hence 1126 * not to be translated, or a verb and translatable. 1127 * A choice was made to view it as a literal keyword. 1128 * "global" is keyword and not to be translated. 1129 */ 1130 cryptoerror(LOG_STDERR, gettext("%1$s for kernel providers " 1131 "is supported in the %2$s zone only"), "unload", "global"); 1132 rc = FAILURE; 1133 goto out; 1134 } 1135 1136 /* Check if it is in the kcf.conf file first */ 1137 if ((pent = getent_kef(prov->cp_name)) == NULL) { 1138 cryptoerror(LOG_STDERR, 1139 gettext("provider %s does not exist."), prov->cp_name); 1140 rc = FAILURE; 1141 goto out; 1142 } 1143 free_entry(pent); 1144 1145 /* If it is unloaded already, return */ 1146 if (check_active_for_soft(prov->cp_name, &is_active) == FAILURE) { 1147 cryptodebug("internal error"); 1148 cryptoerror(LOG_STDERR, 1149 gettext("failed to unload %s."), prov->cp_name); 1150 rc = FAILURE; 1151 goto out; 1152 } 1153 1154 if (is_active == B_FALSE) { /* unloaded already */ 1155 rc = SUCCESS; 1156 goto out; 1157 } else if (unload_kef_soft(prov->cp_name, B_TRUE) == FAILURE) { 1158 cryptoerror(LOG_STDERR, 1159 gettext("failed to unload %s."), prov->cp_name); 1160 rc = FAILURE; 1161 } else { 1162 rc = SUCCESS; 1163 } 1164 out: 1165 free(prov); 1166 return (rc); 1167 } 1168 1169 1170 1171 /* 1172 * The top level function for the refresh subcommand. 1173 */ 1174 static int 1175 do_refresh(int argc) 1176 { 1177 if (argc != 2) { 1178 usage(); 1179 return (ERROR_USAGE); 1180 } 1181 1182 /* 1183 * Note: in non-global zone, this must silently return SUCCESS 1184 * due to integration with SMF, for "svcadm refresh cryptosvc" 1185 */ 1186 if (getzoneid() != GLOBAL_ZONEID) 1187 return (SUCCESS); 1188 1189 return (refresh()); 1190 } 1191 1192 1193 /* 1194 * The top level function for the start subcommand. 1195 */ 1196 static int 1197 do_start(int argc) 1198 { 1199 int ret; 1200 1201 if (argc != 2) { 1202 usage(); 1203 return (ERROR_USAGE); 1204 } 1205 1206 ret = do_refresh(argc); 1207 if (ret != SUCCESS) 1208 return (ret); 1209 1210 return (start_daemon()); 1211 } 1212 1213 /* 1214 * The top level function for the stop subcommand. 1215 */ 1216 static int 1217 do_stop(int argc) 1218 { 1219 if (argc != 2) { 1220 usage(); 1221 return (ERROR_USAGE); 1222 } 1223 1224 return (stop_daemon()); 1225 } 1226 1227 1228 1229 /* 1230 * List all the providers. 1231 */ 1232 static int 1233 list_simple_for_all(boolean_t verbose) 1234 { 1235 uentrylist_t *pliblist; 1236 uentrylist_t *plibptr; 1237 entrylist_t *pdevlist_conf; 1238 entrylist_t *psoftlist_conf; 1239 entrylist_t *pdevlist_zone; 1240 entrylist_t *psoftlist_zone; 1241 entrylist_t *ptr; 1242 crypto_get_dev_list_t *pdevlist_kernel = NULL; 1243 boolean_t is_active; 1244 int ru = SUCCESS; 1245 int rs = SUCCESS; 1246 int rd = SUCCESS; 1247 int i; 1248 1249 /* get user-level providers */ 1250 (void) printf(gettext("\nUser-level providers:\n")); 1251 if (get_pkcs11conf_info(&pliblist) != SUCCESS) { 1252 cryptoerror(LOG_STDERR, gettext( 1253 "failed to retrieve the list of user-level providers.")); 1254 ru = FAILURE; 1255 } 1256 plibptr = pliblist; 1257 while (plibptr != NULL) { 1258 if (strcmp(plibptr->puent->name, METASLOT_KEYWORD) != 0) { 1259 (void) printf(gettext("Provider: %s\n"), 1260 plibptr->puent->name); 1261 if (verbose) { 1262 (void) list_mechlist_for_lib( 1263 plibptr->puent->name, mecharglist, NULL, 1264 B_FALSE, verbose, B_FALSE); 1265 (void) printf("\n"); 1266 } 1267 } 1268 plibptr = plibptr->next; 1269 } 1270 free_uentrylist(pliblist); 1271 1272 /* get kernel software providers */ 1273 (void) printf(gettext("\nKernel software providers:\n")); 1274 1275 if (getzoneid() == GLOBAL_ZONEID) { 1276 /* use kcf.conf for kernel software providers in global zone */ 1277 pdevlist_conf = NULL; 1278 psoftlist_conf = NULL; 1279 1280 if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf) != 1281 SUCCESS) { 1282 cryptoerror(LOG_STDERR, 1283 gettext("failed to retrieve the " 1284 "list of kernel software providers.\n")); 1285 rs = FAILURE; 1286 } 1287 1288 ptr = psoftlist_conf; 1289 while (ptr != NULL) { 1290 if (check_active_for_soft(ptr->pent->name, &is_active) 1291 == FAILURE) { 1292 rs = FAILURE; 1293 cryptoerror(LOG_STDERR, gettext("failed to " 1294 "get the state of a kernel software " 1295 "providers.\n")); 1296 break; 1297 } 1298 1299 (void) printf("\t%s", ptr->pent->name); 1300 if (is_active == B_FALSE) { 1301 (void) printf(gettext(" (inactive)\n")); 1302 } else { 1303 (void) printf("\n"); 1304 } 1305 ptr = ptr->next; 1306 } 1307 1308 free_entrylist(pdevlist_conf); 1309 free_entrylist(psoftlist_conf); 1310 } else { 1311 /* kcf.conf not there in non-global zone, use /dev/cryptoadm */ 1312 pdevlist_zone = NULL; 1313 psoftlist_zone = NULL; 1314 1315 if (get_admindev_info(&pdevlist_zone, &psoftlist_zone) != 1316 SUCCESS) { 1317 cryptoerror(LOG_STDERR, 1318 gettext("failed to retrieve the " 1319 "list of kernel software providers.\n")); 1320 rs = FAILURE; 1321 } 1322 1323 ptr = psoftlist_zone; 1324 while (ptr != NULL) { 1325 (void) printf("\t%s\n", ptr->pent->name); 1326 ptr = ptr->next; 1327 } 1328 1329 free_entrylist(pdevlist_zone); 1330 free_entrylist(psoftlist_zone); 1331 } 1332 1333 /* get kernel hardware providers */ 1334 (void) printf(gettext("\nKernel hardware providers:\n")); 1335 if (get_dev_list(&pdevlist_kernel) == FAILURE) { 1336 cryptoerror(LOG_STDERR, gettext("failed to retrieve " 1337 "the list of kernel hardware providers.\n")); 1338 rd = FAILURE; 1339 } else { 1340 for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) { 1341 (void) printf("\t%s/%d\n", 1342 pdevlist_kernel->dl_devs[i].le_dev_name, 1343 pdevlist_kernel->dl_devs[i].le_dev_instance); 1344 } 1345 } 1346 free(pdevlist_kernel); 1347 1348 if (ru == FAILURE || rs == FAILURE || rd == FAILURE) { 1349 return (FAILURE); 1350 } else { 1351 return (SUCCESS); 1352 } 1353 } 1354 1355 1356 1357 /* 1358 * List all the providers. And for each provider, list the mechanism list. 1359 */ 1360 static int 1361 list_mechlist_for_all(boolean_t verbose) 1362 { 1363 crypto_get_dev_list_t *pdevlist_kernel; 1364 uentrylist_t *pliblist; 1365 uentrylist_t *plibptr; 1366 entrylist_t *pdevlist_conf; 1367 entrylist_t *psoftlist_conf; 1368 entrylist_t *pdevlist_zone; 1369 entrylist_t *psoftlist_zone; 1370 entrylist_t *ptr; 1371 mechlist_t *pmechlist; 1372 boolean_t is_active; 1373 char provname[MAXNAMELEN]; 1374 char devname[MAXNAMELEN]; 1375 int inst_num; 1376 int count; 1377 int i; 1378 int rv; 1379 int rc = SUCCESS; 1380 1381 /* get user-level providers */ 1382 (void) printf(gettext("\nUser-level providers:\n")); 1383 /* 1384 * TRANSLATION_NOTE 1385 * Strictly for appearance's sake, this line should be as long as 1386 * the length of the translated text above. 1387 */ 1388 (void) printf(gettext("=====================\n")); 1389 if (get_pkcs11conf_info(&pliblist) != SUCCESS) { 1390 cryptoerror(LOG_STDERR, gettext("failed to retrieve " 1391 "the list of user-level providers.\n")); 1392 rc = FAILURE; 1393 } 1394 1395 plibptr = pliblist; 1396 while (plibptr != NULL) { 1397 /* skip metaslot entry */ 1398 if (strcmp(plibptr->puent->name, METASLOT_KEYWORD) != 0) { 1399 (void) printf(gettext("\nProvider: %s\n"), 1400 plibptr->puent->name); 1401 rv = list_mechlist_for_lib(plibptr->puent->name, 1402 mecharglist, NULL, B_FALSE, verbose, B_TRUE); 1403 if (rv == FAILURE) { 1404 rc = FAILURE; 1405 } 1406 } 1407 plibptr = plibptr->next; 1408 } 1409 free_uentrylist(pliblist); 1410 1411 /* get kernel software providers */ 1412 (void) printf(gettext("\nKernel software providers:\n")); 1413 /* 1414 * TRANSLATION_NOTE 1415 * Strictly for appearance's sake, this line should be as long as 1416 * the length of the translated text above. 1417 */ 1418 (void) printf(gettext("==========================\n")); 1419 if (getzoneid() == GLOBAL_ZONEID) { 1420 /* use kcf.conf for kernel software providers in global zone */ 1421 pdevlist_conf = NULL; 1422 psoftlist_conf = NULL; 1423 1424 if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf) != 1425 SUCCESS) { 1426 cryptoerror(LOG_STDERR, gettext("failed to retrieve " 1427 "the list of kernel software providers.\n")); 1428 rc = FAILURE; 1429 } 1430 1431 ptr = psoftlist_conf; 1432 while (ptr != NULL) { 1433 if (check_active_for_soft(ptr->pent->name, &is_active) 1434 == SUCCESS) { 1435 if (is_active) { 1436 rv = list_mechlist_for_soft( 1437 ptr->pent->name); 1438 if (rv == FAILURE) { 1439 rc = FAILURE; 1440 } 1441 } else { 1442 (void) printf(gettext( 1443 "%s: (inactive)\n"), 1444 ptr->pent->name); 1445 } 1446 } else { 1447 /* should not happen */ 1448 (void) printf(gettext( 1449 "%s: failed to get the mechanism list.\n"), 1450 ptr->pent->name); 1451 rc = FAILURE; 1452 } 1453 ptr = ptr->next; 1454 } 1455 1456 free_entrylist(pdevlist_conf); 1457 free_entrylist(psoftlist_conf); 1458 } else { 1459 /* kcf.conf not there in non-global zone, use /dev/cryptoadm */ 1460 pdevlist_zone = NULL; 1461 psoftlist_zone = NULL; 1462 1463 if (get_admindev_info(&pdevlist_zone, &psoftlist_zone) != 1464 SUCCESS) { 1465 cryptoerror(LOG_STDERR, gettext("failed to retrieve " 1466 "the list of kernel software providers.\n")); 1467 rc = FAILURE; 1468 } 1469 1470 ptr = psoftlist_zone; 1471 while (ptr != NULL) { 1472 rv = list_mechlist_for_soft(ptr->pent->name); 1473 if (rv == FAILURE) { 1474 (void) printf(gettext( 1475 "%s: failed to get the mechanism list.\n"), 1476 ptr->pent->name); 1477 rc = FAILURE; 1478 } 1479 ptr = ptr->next; 1480 } 1481 1482 free_entrylist(pdevlist_zone); 1483 free_entrylist(psoftlist_zone); 1484 } 1485 1486 /* Get kernel hardware providers and their mechanism lists */ 1487 (void) printf(gettext("\nKernel hardware providers:\n")); 1488 /* 1489 * TRANSLATION_NOTE 1490 * Strictly for appearance's sake, this line should be as long as 1491 * the length of the translated text above. 1492 */ 1493 (void) printf(gettext("==========================\n")); 1494 if (get_dev_list(&pdevlist_kernel) != SUCCESS) { 1495 cryptoerror(LOG_STDERR, gettext("failed to retrieve " 1496 "the list of hardware providers.\n")); 1497 return (FAILURE); 1498 } 1499 1500 for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) { 1501 (void) strlcpy(devname, 1502 pdevlist_kernel->dl_devs[i].le_dev_name, MAXNAMELEN); 1503 inst_num = pdevlist_kernel->dl_devs[i].le_dev_instance; 1504 count = pdevlist_kernel->dl_devs[i].le_mechanism_count; 1505 (void) snprintf(provname, sizeof (provname), "%s/%d", devname, 1506 inst_num); 1507 if (get_dev_info(devname, inst_num, count, &pmechlist) == 1508 SUCCESS) { 1509 (void) filter_mechlist(&pmechlist, RANDOM); 1510 print_mechlist(provname, pmechlist); 1511 free_mechlist(pmechlist); 1512 } else { 1513 (void) printf(gettext("%s: failed to get the mechanism" 1514 " list.\n"), provname); 1515 rc = FAILURE; 1516 } 1517 } 1518 free(pdevlist_kernel); 1519 return (rc); 1520 } 1521 1522 1523 /* 1524 * List all the providers. And for each provider, list the policy information. 1525 */ 1526 static int 1527 list_policy_for_all(void) 1528 { 1529 crypto_get_dev_list_t *pdevlist_kernel; 1530 uentrylist_t *pliblist; 1531 uentrylist_t *plibptr; 1532 entrylist_t *pdevlist_conf; 1533 entrylist_t *psoftlist_conf; 1534 entrylist_t *ptr; 1535 entrylist_t *phead; 1536 boolean_t found; 1537 char provname[MAXNAMELEN]; 1538 int i; 1539 int rc = SUCCESS; 1540 1541 /* Get user-level providers */ 1542 (void) printf(gettext("\nUser-level providers:\n")); 1543 /* 1544 * TRANSLATION_NOTE 1545 * Strictly for appearance's sake, this line should be as long as 1546 * the length of the translated text above. 1547 */ 1548 (void) printf(gettext("=====================\n")); 1549 if (get_pkcs11conf_info(&pliblist) == FAILURE) { 1550 cryptoerror(LOG_STDERR, gettext("failed to retrieve " 1551 "the list of user-level providers.\n")); 1552 } else { 1553 plibptr = pliblist; 1554 while (plibptr != NULL) { 1555 /* skip metaslot entry */ 1556 if (strcmp(plibptr->puent->name, 1557 METASLOT_KEYWORD) != 0) { 1558 if (print_uef_policy(plibptr->puent) 1559 == FAILURE) { 1560 rc = FAILURE; 1561 } 1562 } 1563 plibptr = plibptr->next; 1564 } 1565 free_uentrylist(pliblist); 1566 } 1567 1568 /* kernel software providers */ 1569 (void) printf(gettext("\nKernel software providers:\n")); 1570 /* 1571 * TRANSLATION_NOTE 1572 * Strictly for appearance's sake, this line should be as long as 1573 * the length of the translated text above. 1574 */ 1575 (void) printf(gettext("==========================\n")); 1576 1577 /* Get all entries from the kcf.conf file */ 1578 pdevlist_conf = NULL; 1579 if (getzoneid() == GLOBAL_ZONEID) { 1580 /* use kcf.conf for kernel software providers in global zone */ 1581 psoftlist_conf = NULL; 1582 1583 if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf) == 1584 FAILURE) { 1585 cryptoerror(LOG_STDERR, gettext( 1586 "failed to retrieve the list of kernel " 1587 "providers.\n")); 1588 return (FAILURE); 1589 } 1590 1591 ptr = psoftlist_conf; 1592 while (ptr != NULL) { 1593 (void) list_policy_for_soft(ptr->pent->name); 1594 ptr = ptr->next; 1595 } 1596 1597 free_entrylist(psoftlist_conf); 1598 } else { 1599 /* kcf.conf not there in non-global zone, no policy info */ 1600 1601 /* 1602 * TRANSLATION_NOTE 1603 * "global" is keyword and not to be translated. 1604 */ 1605 cryptoerror(LOG_STDERR, gettext( 1606 "policy information for kernel software providers is " 1607 "available in the %s zone only"), "global"); 1608 } 1609 1610 /* Kernel hardware providers */ 1611 (void) printf(gettext("\nKernel hardware providers:\n")); 1612 /* 1613 * TRANSLATION_NOTE 1614 * Strictly for appearance's sake, this line should be as long as 1615 * the length of the translated text above. 1616 */ 1617 (void) printf(gettext("==========================\n")); 1618 1619 if (getzoneid() != GLOBAL_ZONEID) { 1620 /* 1621 * TRANSLATION_NOTE 1622 * "global" is keyword and not to be translated. 1623 */ 1624 cryptoerror(LOG_STDERR, gettext( 1625 "policy information for kernel hardware providers is " 1626 "available in the %s zone only"), "global"); 1627 return (FAILURE); 1628 } 1629 1630 /* Get the hardware provider list from kernel */ 1631 if (get_dev_list(&pdevlist_kernel) != SUCCESS) { 1632 cryptoerror(LOG_STDERR, gettext( 1633 "failed to retrieve the list of hardware providers.\n")); 1634 free_entrylist(pdevlist_conf); 1635 return (FAILURE); 1636 } 1637 1638 /* 1639 * For each hardware provider from kernel, check if it has an entry 1640 * in the config file. If it has an entry, print out the policy from 1641 * config file and remove the entry from the hardware provider list 1642 * of the config file. If it does not have an entry in the config 1643 * file, no mechanisms of it have been disabled. But, we still call 1644 * list_policy_for_hard() to account for the "random" feature. 1645 */ 1646 for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) { 1647 (void) snprintf(provname, sizeof (provname), "%s/%d", 1648 pdevlist_kernel->dl_devs[i].le_dev_name, 1649 pdevlist_kernel->dl_devs[i].le_dev_instance); 1650 found = B_FALSE; 1651 phead = ptr = pdevlist_conf; 1652 while (!found && ptr) { 1653 if (strcmp(ptr->pent->name, provname) == 0) { 1654 found = B_TRUE; 1655 } else { 1656 phead = ptr; 1657 ptr = ptr->next; 1658 } 1659 } 1660 1661 if (found) { 1662 (void) list_policy_for_hard(ptr->pent->name); 1663 if (phead == ptr) { 1664 pdevlist_conf = pdevlist_conf->next; 1665 } else { 1666 phead->next = ptr->next; 1667 } 1668 free_entry(ptr->pent); 1669 free(ptr); 1670 } else { 1671 (void) list_policy_for_hard(provname); 1672 } 1673 } 1674 1675 /* 1676 * If there are still entries left in the pdevlist_conf list from 1677 * the config file, these providers must have been detached. 1678 * Should print out their policy information also. 1679 */ 1680 ptr = pdevlist_conf; 1681 while (ptr != NULL) { 1682 print_kef_policy(ptr->pent, B_FALSE, B_TRUE); 1683 ptr = ptr->next; 1684 } 1685 1686 free_entrylist(pdevlist_conf); 1687 free(pdevlist_kernel); 1688 1689 return (rc); 1690 } 1691