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 (e.g., "aes"). 252 * - PROV_KEF_HARD if provname contains one slash only and the slash is not 253 * the 1st character (e.g., "mca/0"). 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 "cryptoadm 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 * cryptoadm list [-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 char *provname = prov->cp_name; 635 636 if (mflag || vflag) { 637 if (vflag) 638 (void) printf(gettext("Provider: %s\n"), 639 provname); 640 switch (prov->cp_type) { 641 case PROV_UEF_LIB: 642 rc = list_mechlist_for_lib(provname, 643 mecharglist, NULL, B_FALSE, vflag, mflag); 644 break; 645 case PROV_KEF_SOFT: 646 rc = list_mechlist_for_soft(provname, 647 NULL, NULL); 648 break; 649 case PROV_KEF_HARD: 650 rc = list_mechlist_for_hard(provname); 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(provname); 660 break; 661 case PROV_KEF_SOFT: 662 if (getzoneid() == GLOBAL_ZONEID) { 663 rc = list_policy_for_soft(provname, 664 NULL, NULL); 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 provname, NULL, NULL, NULL); 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 "cryptoadm 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 for the "cryptoadm 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; 844 boolean_t auto_key_migrate_flag = B_FALSE; 845 846 if ((argc < 3) || (argc > 6)) { 847 usage(); 848 return (ERROR_USAGE); 849 } 850 851 prov = get_provider(argc, argv); 852 if (prov == NULL) { 853 usage(); 854 return (ERROR_USAGE); 855 } 856 if ((prov->cp_type != METASLOT) && (argc != 4)) { 857 usage(); 858 return (ERROR_USAGE); 859 } 860 if (prov->cp_type == PROV_BADNAME) { 861 rc = FAILURE; 862 goto out; 863 } 864 865 866 if (prov->cp_type == METASLOT) { 867 if ((rc = process_metaslot_operands(argc, argv, &alt_token, 868 &alt_slot, &use_default, &auto_key_migrate_flag)) 869 != SUCCESS) { 870 usage(); 871 goto out; 872 } 873 if ((alt_slot || alt_token) && use_default) { 874 usage(); 875 rc = FAILURE; 876 goto out; 877 } 878 } else { 879 if ((rc = process_feature_operands(argc, argv)) != SUCCESS) { 880 goto out; 881 } 882 883 /* 884 * If allflag or rndflag has already been set there is 885 * no reason to process mech= 886 */ 887 if (!allflag && !rndflag && 888 (rc = process_mech_operands(argc, argv, B_FALSE)) 889 != SUCCESS) { 890 goto out; 891 } 892 } 893 894 switch (prov->cp_type) { 895 case METASLOT: 896 rc = enable_metaslot(alt_token, alt_slot, use_default, 897 mecharglist, allflag, auto_key_migrate_flag); 898 break; 899 case PROV_UEF_LIB: 900 rc = enable_uef_lib(prov->cp_name, rndflag, allflag, 901 mecharglist); 902 break; 903 case PROV_KEF_SOFT: 904 case PROV_KEF_HARD: 905 if (rndflag && !allflag) { 906 if ((mecharglist = create_mech(RANDOM)) == NULL) { 907 rc = FAILURE; 908 break; 909 } 910 } 911 if (getzoneid() == GLOBAL_ZONEID) { 912 rc = enable_kef(prov->cp_name, rndflag, allflag, 913 mecharglist); 914 } else { 915 /* 916 * TRANSLATION_NOTE 917 * "enable" could be either a literal keyword 918 * and hence not to be translated, or a verb and 919 * translatable. A choice was made to view it as 920 * a literal keyword. "global" is keyword and not 921 * to be translated. 922 */ 923 cryptoerror(LOG_STDERR, gettext("%1$s for kernel " 924 "providers is supported in the %2$s zone only"), 925 "enable", "global"); 926 rc = FAILURE; 927 } 928 break; 929 default: /* should not come here */ 930 rc = FAILURE; 931 break; 932 } 933 out: 934 free(prov); 935 if (mecharglist != NULL) { 936 free_mechlist(mecharglist); 937 } 938 if (alt_token != NULL) { 939 free(alt_token); 940 } 941 if (alt_slot != NULL) { 942 free(alt_slot); 943 } 944 return (rc); 945 } 946 947 948 949 /* 950 * The top level function for the "cryptoadm install" subcommand. 951 */ 952 static int 953 do_install(int argc, char **argv) 954 { 955 cryptoadm_provider_t *prov = NULL; 956 int rc; 957 958 if (argc < 3) { 959 usage(); 960 return (ERROR_USAGE); 961 } 962 963 prov = get_provider(argc, argv); 964 if (prov == NULL || 965 prov->cp_type == PROV_BADNAME || prov->cp_type == PROV_KEF_HARD) { 966 /* 967 * TRANSLATION_NOTE 968 * "install" could be either a literal keyword and hence 969 * not to be translated, or a verb and translatable. A 970 * choice was made to view it as a literal keyword. 971 */ 972 cryptoerror(LOG_STDERR, 973 gettext("bad provider name for %s."), "install"); 974 rc = FAILURE; 975 goto out; 976 } 977 978 if (prov->cp_type == PROV_UEF_LIB) { 979 rc = install_uef_lib(prov->cp_name); 980 goto out; 981 } 982 983 /* It is the PROV_KEF_SOFT type now */ 984 985 /* check if there are mechanism operands */ 986 if (argc < 4) { 987 /* 988 * TRANSLATION_NOTE 989 * "mechanism" could be either a literal keyword and hence 990 * not to be translated, or a descriptive word and 991 * translatable. A choice was made to view it as a literal 992 * keyword. 993 */ 994 cryptoerror(LOG_STDERR, 995 gettext("need %s operands for installing a" 996 " kernel software provider."), "mechanism"); 997 rc = ERROR_USAGE; 998 goto out; 999 } 1000 1001 if ((rc = process_mech_operands(argc, argv, B_FALSE)) != SUCCESS) { 1002 goto out; 1003 } 1004 1005 if (allflag == B_TRUE) { 1006 /* 1007 * TRANSLATION_NOTE 1008 * "all", "mechanism", and "install" are all keywords and 1009 * not to be translated. 1010 */ 1011 cryptoerror(LOG_STDERR, 1012 gettext("can not use the %1$s keyword for %2$s " 1013 "in the %3$s subcommand."), "all", "mechanism", "install"); 1014 rc = ERROR_USAGE; 1015 goto out; 1016 } 1017 1018 if (getzoneid() == GLOBAL_ZONEID) { 1019 rc = install_kef(prov->cp_name, mecharglist); 1020 } else { 1021 /* 1022 * TRANSLATION_NOTE 1023 * "install" could be either a literal keyword and hence 1024 * not to be translated, or a verb and translatable. A 1025 * choice was made to view it as a literal keyword. 1026 * "global" is keyword and not to be translated. 1027 */ 1028 cryptoerror(LOG_STDERR, gettext("%1$s for kernel providers " 1029 "is supported in the %2$s zone only"), "install", "global"); 1030 rc = FAILURE; 1031 } 1032 out: 1033 free(prov); 1034 return (rc); 1035 } 1036 1037 1038 1039 /* 1040 * The top level function for the "cryptoadm uninstall" subcommand. 1041 */ 1042 static int 1043 do_uninstall(int argc, char **argv) 1044 { 1045 cryptoadm_provider_t *prov = NULL; 1046 int rc = SUCCESS; 1047 1048 if (argc != 3) { 1049 usage(); 1050 return (ERROR_USAGE); 1051 } 1052 1053 prov = get_provider(argc, argv); 1054 if (prov == NULL || 1055 prov->cp_type == PROV_BADNAME || prov->cp_type == PROV_KEF_HARD) { 1056 /* 1057 * TRANSLATION_NOTE 1058 * "uninstall" could be either a literal keyword and hence 1059 * not to be translated, or a verb and translatable. A 1060 * choice was made to view it as a literal keyword. 1061 */ 1062 cryptoerror(LOG_STDERR, 1063 gettext("bad provider name for %s."), "uninstall"); 1064 free(prov); 1065 return (FAILURE); 1066 } 1067 1068 if (prov->cp_type == PROV_UEF_LIB) { 1069 rc = uninstall_uef_lib(prov->cp_name); 1070 1071 } else if (prov->cp_type == PROV_KEF_SOFT) { 1072 if (getzoneid() == GLOBAL_ZONEID) { 1073 /* unload and remove from kcf.conf */ 1074 rc = uninstall_kef(prov->cp_name); 1075 } else { 1076 /* 1077 * TRANSLATION_NOTE 1078 * "uninstall" could be either a literal keyword and 1079 * hence not to be translated, or a verb and 1080 * translatable. A choice was made to view it as a 1081 * literal keyword. "global" is keyword and not to 1082 * be translated. 1083 */ 1084 cryptoerror(LOG_STDERR, gettext("%1$s for kernel " 1085 "providers is supported in the %2$s zone only"), 1086 "uninstall", "global"); 1087 rc = FAILURE; 1088 } 1089 } 1090 1091 free(prov); 1092 return (rc); 1093 } 1094 1095 1096 /* 1097 * The top level function for the "cryptoadm unload" subcommand. 1098 */ 1099 static int 1100 do_unload(int argc, char **argv) 1101 { 1102 cryptoadm_provider_t *prov = NULL; 1103 entry_t *pent = NULL; 1104 boolean_t in_kernel = B_FALSE; 1105 int rc = SUCCESS; 1106 char *provname = NULL; 1107 1108 if (argc != 3) { 1109 usage(); 1110 return (ERROR_USAGE); 1111 } 1112 1113 /* check if it is a kernel software provider */ 1114 prov = get_provider(argc, argv); 1115 if (prov == NULL) { 1116 cryptoerror(LOG_STDERR, 1117 gettext("unable to determine provider name.")); 1118 goto out; 1119 } 1120 provname = prov->cp_name; 1121 if (prov->cp_type != PROV_KEF_SOFT) { 1122 cryptoerror(LOG_STDERR, 1123 gettext("%s is not a valid kernel software provider."), 1124 provname); 1125 rc = FAILURE; 1126 goto out; 1127 } 1128 1129 if (getzoneid() != GLOBAL_ZONEID) { 1130 /* 1131 * TRANSLATION_NOTE 1132 * "unload" could be either a literal keyword and hence 1133 * not to be translated, or a verb and translatable. 1134 * A choice was made to view it as a literal keyword. 1135 * "global" is keyword and not to be translated. 1136 */ 1137 cryptoerror(LOG_STDERR, gettext("%1$s for kernel providers " 1138 "is supported in the %2$s zone only"), "unload", "global"); 1139 rc = FAILURE; 1140 goto out; 1141 } 1142 1143 if (check_kernel_for_soft(provname, NULL, &in_kernel) == FAILURE) { 1144 cryptodebug("internal error"); 1145 rc = FAILURE; 1146 goto out; 1147 } else if (in_kernel == B_FALSE) { 1148 cryptoerror(LOG_STDERR, 1149 gettext("provider %s is not loaded or does not exist."), 1150 provname); 1151 rc = FAILURE; 1152 goto out; 1153 } 1154 1155 /* Get kcf.conf entry. If none, build a new entry */ 1156 if ((pent = getent_kef(provname, NULL, NULL)) == NULL) { 1157 if ((pent = create_entry(provname)) == NULL) { 1158 cryptoerror(LOG_STDERR, gettext("out of memory.")); 1159 rc = FAILURE; 1160 goto out; 1161 } 1162 } 1163 1164 /* If it is unloaded already, return */ 1165 if (!pent->load) { /* unloaded already */ 1166 cryptoerror(LOG_STDERR, 1167 gettext("failed to unload %s."), provname); 1168 rc = FAILURE; 1169 goto out; 1170 } else if (unload_kef_soft(provname) != FAILURE) { 1171 /* Mark as unloaded in kcf.conf */ 1172 pent->load = B_FALSE; 1173 rc = update_kcfconf(pent, MODIFY_MODE); 1174 } else { 1175 cryptoerror(LOG_STDERR, 1176 gettext("failed to unload %s."), provname); 1177 rc = FAILURE; 1178 } 1179 out: 1180 free(prov); 1181 free_entry(pent); 1182 return (rc); 1183 } 1184 1185 1186 1187 /* 1188 * The top level function for the "cryptoadm refresh" subcommand. 1189 */ 1190 static int 1191 do_refresh(int argc) 1192 { 1193 if (argc != 2) { 1194 usage(); 1195 return (ERROR_USAGE); 1196 } 1197 1198 if (getzoneid() == GLOBAL_ZONEID) { 1199 return (refresh()); 1200 } else { /* non-global zone */ 1201 /* 1202 * Note: in non-global zone, this must silently return SUCCESS 1203 * due to integration with SMF, for "svcadm refresh cryptosvc" 1204 */ 1205 return (SUCCESS); 1206 } 1207 } 1208 1209 1210 /* 1211 * The top level function for the "cryptoadm start" subcommand. 1212 */ 1213 static int 1214 do_start(int argc) 1215 { 1216 int ret; 1217 1218 if (argc != 2) { 1219 usage(); 1220 return (ERROR_USAGE); 1221 } 1222 1223 ret = do_refresh(argc); 1224 if (ret != SUCCESS) 1225 return (ret); 1226 1227 return (start_daemon()); 1228 } 1229 1230 /* 1231 * The top level function for the "cryptoadm stop" subcommand. 1232 */ 1233 static int 1234 do_stop(int argc) 1235 { 1236 if (argc != 2) { 1237 usage(); 1238 return (ERROR_USAGE); 1239 } 1240 1241 return (stop_daemon()); 1242 } 1243 1244 1245 1246 /* 1247 * Print a list all the the providers. 1248 * Called for "cryptoadm list" or "cryptoadm list -v" (no -m or -p). 1249 */ 1250 static int 1251 list_simple_for_all(boolean_t verbose) 1252 { 1253 uentrylist_t *pliblist = NULL; 1254 uentrylist_t *plibptr = NULL; 1255 entry_t *pent = NULL; 1256 crypto_get_dev_list_t *pdevlist_kernel = NULL; 1257 int rc = SUCCESS; 1258 int i; 1259 1260 /* get user-level providers */ 1261 (void) printf(gettext("\nUser-level providers:\n")); 1262 if (get_pkcs11conf_info(&pliblist) != SUCCESS) { 1263 cryptoerror(LOG_STDERR, gettext( 1264 "failed to retrieve the list of user-level providers.")); 1265 rc = FAILURE; 1266 } 1267 1268 for (plibptr = pliblist; plibptr != NULL; plibptr = plibptr->next) { 1269 if (strcmp(plibptr->puent->name, METASLOT_KEYWORD) != 0) { 1270 (void) printf(gettext("Provider: %s\n"), 1271 plibptr->puent->name); 1272 if (verbose) { 1273 (void) list_mechlist_for_lib( 1274 plibptr->puent->name, mecharglist, NULL, 1275 B_FALSE, verbose, B_FALSE); 1276 (void) printf("\n"); 1277 } 1278 } 1279 } 1280 free_uentrylist(pliblist); 1281 1282 /* get kernel software providers */ 1283 (void) printf(gettext("\nKernel software providers:\n")); 1284 1285 if (getzoneid() == GLOBAL_ZONEID) { 1286 /* get kernel software providers from kernel ioctl */ 1287 crypto_get_soft_list_t *psoftlist_kernel = NULL; 1288 uint_t sl_soft_count; 1289 char *psoftname; 1290 entrylist_t *pdevlist_conf = NULL; 1291 entrylist_t *psoftlist_conf = NULL; 1292 1293 if (get_soft_list(&psoftlist_kernel) == FAILURE) { 1294 cryptoerror(LOG_ERR, gettext("Failed to retrieve the " 1295 "software provider list from kernel.")); 1296 rc = FAILURE; 1297 } else { 1298 sl_soft_count = psoftlist_kernel->sl_soft_count; 1299 1300 if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf) 1301 == FAILURE) { 1302 cryptoerror(LOG_ERR, 1303 "failed to retrieve the providers' " 1304 "information from file kcf.conf - %s.", 1305 _PATH_KCF_CONF); 1306 free(psoftlist_kernel); 1307 rc = FAILURE; 1308 } else { 1309 1310 for (i = 0, 1311 psoftname = psoftlist_kernel->sl_soft_names; 1312 i < sl_soft_count; 1313 ++i, psoftname += strlen(psoftname) + 1) { 1314 pent = getent_kef(psoftname, 1315 pdevlist_conf, psoftlist_conf); 1316 (void) printf("\t%s%s\n", psoftname, 1317 (pent == NULL) || (pent->load) ? 1318 "" : gettext(" (inactive)")); 1319 } 1320 free_entrylist(pdevlist_conf); 1321 free_entrylist(psoftlist_conf); 1322 } 1323 free(psoftlist_kernel); 1324 } 1325 1326 } else { 1327 /* kcf.conf not there in non-global zone, use /dev/cryptoadm */ 1328 entrylist_t *pdevlist_zone = NULL; 1329 entrylist_t *psoftlist_zone = NULL; 1330 entrylist_t *ptr; 1331 1332 if (get_admindev_info(&pdevlist_zone, &psoftlist_zone) != 1333 SUCCESS) { 1334 cryptoerror(LOG_STDERR, 1335 gettext("failed to retrieve the " 1336 "list of kernel software providers.\n")); 1337 rc = FAILURE; 1338 } 1339 1340 ptr = psoftlist_zone; 1341 while (ptr != NULL) { 1342 (void) printf("\t%s\n", ptr->pent->name); 1343 ptr = ptr->next; 1344 } 1345 1346 free_entrylist(pdevlist_zone); 1347 free_entrylist(psoftlist_zone); 1348 } 1349 1350 /* get kernel hardware providers */ 1351 (void) printf(gettext("\nKernel hardware providers:\n")); 1352 if (get_dev_list(&pdevlist_kernel) == FAILURE) { 1353 cryptoerror(LOG_STDERR, gettext("failed to retrieve " 1354 "the list of kernel hardware providers.\n")); 1355 rc = FAILURE; 1356 } else { 1357 for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) { 1358 (void) printf("\t%s/%d\n", 1359 pdevlist_kernel->dl_devs[i].le_dev_name, 1360 pdevlist_kernel->dl_devs[i].le_dev_instance); 1361 } 1362 } 1363 free(pdevlist_kernel); 1364 1365 return (rc); 1366 } 1367 1368 1369 1370 /* 1371 * List all the providers. And for each provider, list the mechanism list. 1372 * Called for "cryptoadm list -m" or "cryptoadm list -mv" . 1373 */ 1374 static int 1375 list_mechlist_for_all(boolean_t verbose) 1376 { 1377 crypto_get_dev_list_t *pdevlist_kernel = NULL; 1378 uentrylist_t *pliblist = NULL; 1379 uentrylist_t *plibptr = NULL; 1380 entry_t *pent = NULL; 1381 mechlist_t *pmechlist = NULL; 1382 char provname[MAXNAMELEN]; 1383 char devname[MAXNAMELEN]; 1384 int inst_num; 1385 int count; 1386 int i; 1387 int rv; 1388 int rc = SUCCESS; 1389 1390 /* get user-level providers */ 1391 (void) printf(gettext("\nUser-level providers:\n")); 1392 /* 1393 * TRANSLATION_NOTE 1394 * Strictly for appearance's sake, this line should be as long as 1395 * the length of the translated text above. 1396 */ 1397 (void) printf(gettext("=====================\n")); 1398 if (get_pkcs11conf_info(&pliblist) != SUCCESS) { 1399 cryptoerror(LOG_STDERR, gettext("failed to retrieve " 1400 "the list of user-level providers.\n")); 1401 rc = FAILURE; 1402 } 1403 1404 plibptr = pliblist; 1405 while (plibptr != NULL) { 1406 /* skip metaslot entry */ 1407 if (strcmp(plibptr->puent->name, METASLOT_KEYWORD) != 0) { 1408 (void) printf(gettext("\nProvider: %s\n"), 1409 plibptr->puent->name); 1410 rv = list_mechlist_for_lib(plibptr->puent->name, 1411 mecharglist, NULL, B_FALSE, verbose, B_TRUE); 1412 if (rv == FAILURE) { 1413 rc = FAILURE; 1414 } 1415 } 1416 plibptr = plibptr->next; 1417 } 1418 free_uentrylist(pliblist); 1419 1420 /* get kernel software providers */ 1421 (void) printf(gettext("\nKernel software providers:\n")); 1422 1423 /* 1424 * TRANSLATION_NOTE 1425 * Strictly for appearance's sake, this line should be as long as 1426 * the length of the translated text above. 1427 */ 1428 (void) printf(gettext("==========================\n")); 1429 if (getzoneid() == GLOBAL_ZONEID) { 1430 /* get kernel software providers from kernel ioctl */ 1431 crypto_get_soft_list_t *psoftlist_kernel = NULL; 1432 uint_t sl_soft_count; 1433 char *psoftname; 1434 int i; 1435 entrylist_t *pdevlist_conf = NULL; 1436 entrylist_t *psoftlist_conf = NULL; 1437 1438 if (get_soft_list(&psoftlist_kernel) == FAILURE) { 1439 cryptoerror(LOG_ERR, gettext("Failed to retrieve the " 1440 "software provider list from kernel.")); 1441 return (FAILURE); 1442 } 1443 sl_soft_count = psoftlist_kernel->sl_soft_count; 1444 1445 if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf) 1446 == FAILURE) { 1447 cryptoerror(LOG_ERR, 1448 "failed to retrieve the providers' " 1449 "information from file kcf.conf - %s.", 1450 _PATH_KCF_CONF); 1451 free(psoftlist_kernel); 1452 return (FAILURE); 1453 } 1454 1455 for (i = 0, psoftname = psoftlist_kernel->sl_soft_names; 1456 i < sl_soft_count; 1457 ++i, psoftname += strlen(psoftname) + 1) { 1458 pent = getent_kef(psoftname, pdevlist_conf, 1459 psoftlist_conf); 1460 if ((pent == NULL) || (pent->load)) { 1461 rv = list_mechlist_for_soft(psoftname, 1462 NULL, NULL); 1463 if (rv == FAILURE) { 1464 rc = FAILURE; 1465 } 1466 } else { 1467 (void) printf(gettext("%s: (inactive)\n"), 1468 psoftname); 1469 } 1470 } 1471 1472 free(psoftlist_kernel); 1473 free_entrylist(pdevlist_conf); 1474 free_entrylist(psoftlist_conf); 1475 1476 } else { 1477 /* kcf.conf not there in non-global zone, use /dev/cryptoadm */ 1478 entrylist_t *pdevlist_zone = NULL; 1479 entrylist_t *psoftlist_zone = NULL; 1480 entrylist_t *ptr; 1481 1482 if (get_admindev_info(&pdevlist_zone, &psoftlist_zone) != 1483 SUCCESS) { 1484 cryptoerror(LOG_STDERR, gettext("failed to retrieve " 1485 "the list of kernel software providers.\n")); 1486 rc = FAILURE; 1487 } 1488 1489 for (ptr = psoftlist_zone; ptr != NULL; ptr = ptr->next) { 1490 rv = list_mechlist_for_soft(ptr->pent->name, 1491 pdevlist_zone, psoftlist_zone); 1492 if (rv == FAILURE) { 1493 (void) printf(gettext( 1494 "%s: failed to get the mechanism list.\n"), 1495 ptr->pent->name); 1496 rc = FAILURE; 1497 } 1498 } 1499 1500 free_entrylist(pdevlist_zone); 1501 free_entrylist(psoftlist_zone); 1502 } 1503 1504 /* Get kernel hardware providers and their mechanism lists */ 1505 (void) printf(gettext("\nKernel hardware providers:\n")); 1506 /* 1507 * TRANSLATION_NOTE 1508 * Strictly for appearance's sake, this line should be as long as 1509 * the length of the translated text above. 1510 */ 1511 (void) printf(gettext("==========================\n")); 1512 if (get_dev_list(&pdevlist_kernel) != SUCCESS) { 1513 cryptoerror(LOG_STDERR, gettext("failed to retrieve " 1514 "the list of hardware providers.\n")); 1515 return (FAILURE); 1516 } 1517 1518 for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) { 1519 (void) strlcpy(devname, 1520 pdevlist_kernel->dl_devs[i].le_dev_name, MAXNAMELEN); 1521 inst_num = pdevlist_kernel->dl_devs[i].le_dev_instance; 1522 count = pdevlist_kernel->dl_devs[i].le_mechanism_count; 1523 (void) snprintf(provname, sizeof (provname), "%s/%d", devname, 1524 inst_num); 1525 if (get_dev_info(devname, inst_num, count, &pmechlist) == 1526 SUCCESS) { 1527 (void) filter_mechlist(&pmechlist, RANDOM); 1528 print_mechlist(provname, pmechlist); 1529 free_mechlist(pmechlist); 1530 } else { 1531 (void) printf(gettext("%s: failed to get the mechanism" 1532 " list.\n"), provname); 1533 rc = FAILURE; 1534 } 1535 } 1536 free(pdevlist_kernel); 1537 return (rc); 1538 } 1539 1540 1541 /* 1542 * List all the providers. And for each provider, list the policy information. 1543 * Called for "cryptoadm list -p". 1544 */ 1545 static int 1546 list_policy_for_all(void) 1547 { 1548 crypto_get_dev_list_t *pdevlist_kernel = NULL; 1549 uentrylist_t *pliblist = NULL; 1550 entrylist_t *pdevlist_conf = NULL; 1551 entrylist_t *psoftlist_conf = NULL; 1552 entrylist_t *ptr = NULL; 1553 entrylist_t *phead = NULL; 1554 boolean_t found = B_FALSE; 1555 char provname[MAXNAMELEN]; 1556 int i; 1557 int rc = SUCCESS; 1558 1559 /* Get user-level providers */ 1560 (void) printf(gettext("\nUser-level providers:\n")); 1561 /* 1562 * TRANSLATION_NOTE 1563 * Strictly for appearance's sake, this line should be as long as 1564 * the length of the translated text above. 1565 */ 1566 (void) printf(gettext("=====================\n")); 1567 if (get_pkcs11conf_info(&pliblist) == FAILURE) { 1568 cryptoerror(LOG_STDERR, gettext("failed to retrieve " 1569 "the list of user-level providers.\n")); 1570 rc = FAILURE; 1571 } else { 1572 uentrylist_t *plibptr = pliblist; 1573 1574 while (plibptr != NULL) { 1575 /* skip metaslot entry */ 1576 if (strcmp(plibptr->puent->name, 1577 METASLOT_KEYWORD) != 0) { 1578 if (print_uef_policy(plibptr->puent) 1579 == FAILURE) { 1580 rc = FAILURE; 1581 } 1582 } 1583 plibptr = plibptr->next; 1584 } 1585 free_uentrylist(pliblist); 1586 } 1587 1588 /* kernel software providers */ 1589 (void) printf(gettext("\nKernel software providers:\n")); 1590 /* 1591 * TRANSLATION_NOTE 1592 * Strictly for appearance's sake, this line should be as long as 1593 * the length of the translated text above. 1594 */ 1595 (void) printf(gettext("==========================\n")); 1596 1597 /* Get all entries from the kernel */ 1598 if (getzoneid() == GLOBAL_ZONEID) { 1599 /* get kernel software providers from kernel ioctl */ 1600 crypto_get_soft_list_t *psoftlist_kernel = NULL; 1601 uint_t sl_soft_count; 1602 char *psoftname; 1603 int i; 1604 1605 if (get_soft_list(&psoftlist_kernel) == FAILURE) { 1606 cryptoerror(LOG_ERR, gettext("Failed to retrieve the " 1607 "software provider list from kernel.")); 1608 rc = FAILURE; 1609 } else { 1610 sl_soft_count = psoftlist_kernel->sl_soft_count; 1611 1612 for (i = 0, psoftname = psoftlist_kernel->sl_soft_names; 1613 i < sl_soft_count; 1614 ++i, psoftname += strlen(psoftname) + 1) { 1615 (void) list_policy_for_soft(psoftname, 1616 pdevlist_conf, psoftlist_conf); 1617 } 1618 free(psoftlist_kernel); 1619 } 1620 1621 } else { 1622 /* kcf.conf not there in non-global zone, no policy info */ 1623 1624 /* 1625 * TRANSLATION_NOTE 1626 * "global" is keyword and not to be translated. 1627 */ 1628 cryptoerror(LOG_STDERR, gettext( 1629 "policy information for kernel software providers is " 1630 "available in the %s zone only"), "global"); 1631 } 1632 1633 /* Kernel hardware providers */ 1634 (void) printf(gettext("\nKernel hardware providers:\n")); 1635 /* 1636 * TRANSLATION_NOTE 1637 * Strictly for appearance's sake, this line should be as long as 1638 * the length of the translated text above. 1639 */ 1640 (void) printf(gettext("==========================\n")); 1641 1642 if (getzoneid() != GLOBAL_ZONEID) { 1643 /* 1644 * TRANSLATION_NOTE 1645 * "global" is keyword and not to be translated. 1646 */ 1647 cryptoerror(LOG_STDERR, gettext( 1648 "policy information for kernel hardware providers is " 1649 "available in the %s zone only"), "global"); 1650 return (FAILURE); 1651 } 1652 1653 /* Get the hardware provider list from kernel */ 1654 if (get_dev_list(&pdevlist_kernel) != SUCCESS) { 1655 cryptoerror(LOG_STDERR, gettext( 1656 "failed to retrieve the list of hardware providers.\n")); 1657 return (FAILURE); 1658 } 1659 1660 if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf) == FAILURE) { 1661 cryptoerror(LOG_ERR, "failed to retrieve the providers' " 1662 "information from file kcf.conf - %s.", 1663 _PATH_KCF_CONF); 1664 return (FAILURE); 1665 } 1666 1667 1668 /* 1669 * For each hardware provider from kernel, check if it has an entry 1670 * in the config file. If it has an entry, print out the policy from 1671 * config file and remove the entry from the hardware provider list 1672 * of the config file. If it does not have an entry in the config 1673 * file, no mechanisms of it have been disabled. But, we still call 1674 * list_policy_for_hard() to account for the "random" feature. 1675 */ 1676 for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) { 1677 (void) snprintf(provname, sizeof (provname), "%s/%d", 1678 pdevlist_kernel->dl_devs[i].le_dev_name, 1679 pdevlist_kernel->dl_devs[i].le_dev_instance); 1680 1681 found = B_FALSE; 1682 phead = ptr = pdevlist_conf; 1683 while (!found && ptr) { 1684 if (strcmp(ptr->pent->name, provname) == 0) { 1685 found = B_TRUE; 1686 } else { 1687 phead = ptr; 1688 ptr = ptr->next; 1689 } 1690 } 1691 1692 if (found) { 1693 (void) list_policy_for_hard(ptr->pent->name, 1694 pdevlist_conf, psoftlist_conf, pdevlist_kernel); 1695 if (phead == ptr) { 1696 pdevlist_conf = pdevlist_conf->next; 1697 } else { 1698 phead->next = ptr->next; 1699 } 1700 free_entry(ptr->pent); 1701 free(ptr); 1702 } else { 1703 (void) list_policy_for_hard(provname, pdevlist_conf, 1704 psoftlist_conf, pdevlist_kernel); 1705 } 1706 } 1707 1708 /* 1709 * If there are still entries left in the pdevlist_conf list from 1710 * the config file, these providers must have been detached. 1711 * Should print out their policy information also. 1712 */ 1713 for (ptr = pdevlist_conf; ptr != NULL; ptr = ptr->next) { 1714 print_kef_policy(ptr->pent->name, ptr->pent, B_FALSE, B_TRUE); 1715 } 1716 1717 free_entrylist(pdevlist_conf); 1718 free_entrylist(psoftlist_conf); 1719 free(pdevlist_kernel); 1720 1721 return (rc); 1722 } 1723