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