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