231 (void) fprintf(stderr,
232 " cryptoadm install provider=<%s> [mechanism=<%s>]\n",
233 gettext("provider-name"), gettext("mechanism-list"));
234 (void) fprintf(stderr,
235 " cryptoadm uninstall provider=<%s>\n",
236 gettext("provider-name"));
237 (void) fprintf(stderr,
238 " cryptoadm unload provider=<%s>\n",
239 gettext("provider-name"));
240 (void) fprintf(stderr,
241 " cryptoadm refresh\n"
242 " cryptoadm start\n"
243 " cryptoadm stop\n"
244 " cryptoadm --help\n");
245 }
246
247
248 /*
249 * Get the provider type. This function returns
250 * - PROV_UEF_LIB if provname contains an absolute path name
251 * - PROV_KEF_SOFT if provname is a base name only
252 * - PROV_KEF_HARD if provname contains one slash only and the slash is not
253 * the 1st character.
254 * - PROV_BADNAME otherwise.
255 */
256 static int
257 get_provider_type(char *provname)
258 {
259 char *pslash1;
260 char *pslash2;
261
262 if (provname == NULL) {
263 return (FAILURE);
264 }
265
266 if (provname[0] == '/') {
267 return (PROV_UEF_LIB);
268 } else if ((pslash1 = strchr(provname, SEP_SLASH)) == NULL) {
269 /* no slash */
270 return (PROV_KEF_SOFT);
271 } else {
272 pslash2 = strrchr(provname, SEP_SLASH);
273 if (pslash1 == pslash2) {
513 } else {
514 pcur->next = pmech;
515 pcur = pmech;
516 }
517 }
518 } while ((curmech = strtok(NULL, ",")) != NULL);
519
520 if (rc == FAILURE) {
521 cryptoerror(LOG_STDERR, gettext("out of memory."));
522 free_mechlist(phead);
523 } else {
524 mecharglist = phead;
525 rc = SUCCESS;
526 }
527 return (rc);
528 }
529
530
531
532 /*
533 * The top level function for the list subcommand and options.
534 */
535 static int
536 do_list(int argc, char **argv)
537 {
538 boolean_t mflag = B_FALSE;
539 boolean_t pflag = B_FALSE;
540 boolean_t vflag = B_FALSE;
541 char ch;
542 cryptoadm_provider_t *prov = NULL;
543 int rc = SUCCESS;
544
545 argc -= 1;
546 argv += 1;
547
548 if (argc == 1) {
549 rc = list_simple_for_all(B_FALSE);
550 goto out;
551 }
552
553 /*
554 * [-v] [-m] [-p] [provider=<>] [mechanism=<>]
555 */
556 if (argc > 5) {
557 usage();
558 return (rc);
559 }
560
561 while ((ch = getopt(argc, argv, "mpv")) != EOF) {
562 switch (ch) {
563 case 'm':
564 mflag = B_TRUE;
565 if (pflag) {
566 rc = ERROR_USAGE;
567 }
568 break;
569 case 'p':
570 pflag = B_TRUE;
571 if (mflag || vflag) {
572 rc = ERROR_USAGE;
573 }
574 break;
614 rc = list_simple_for_all(vflag);
615 }
616 } else if (prov->cp_type == METASLOT) {
617 if ((!mflag) && (!vflag) && (!pflag)) {
618 /* no flag is specified, just list metaslot status */
619 rc = list_metaslot_info(mflag, vflag, mecharglist);
620 } else if (mflag || vflag) {
621 rc = list_metaslot_info(mflag, vflag, mecharglist);
622 } else if (pflag) {
623 rc = list_metaslot_policy();
624 } else {
625 /* error message */
626 usage();
627 rc = ERROR_USAGE;
628 }
629 } else if (prov->cp_type == PROV_BADNAME) {
630 usage();
631 rc = ERROR_USAGE;
632 goto out;
633 } else { /* do the listing for a provider only */
634 if (mflag || vflag) {
635 if (vflag)
636 (void) printf(gettext("Provider: %s\n"),
637 prov->cp_name);
638 switch (prov->cp_type) {
639 case PROV_UEF_LIB:
640 rc = list_mechlist_for_lib(prov->cp_name,
641 mecharglist, NULL, B_FALSE,
642 vflag, mflag);
643 break;
644 case PROV_KEF_SOFT:
645 rc = list_mechlist_for_soft(prov->cp_name);
646 break;
647 case PROV_KEF_HARD:
648 rc = list_mechlist_for_hard(prov->cp_name);
649 break;
650 default: /* should not come here */
651 rc = FAILURE;
652 break;
653 }
654 } else if (pflag) {
655 switch (prov->cp_type) {
656 case PROV_UEF_LIB:
657 rc = list_policy_for_lib(prov->cp_name);
658 break;
659 case PROV_KEF_SOFT:
660 if (getzoneid() == GLOBAL_ZONEID) {
661 rc = list_policy_for_soft(
662 prov->cp_name);
663 } else {
664 /*
665 * TRANSLATION_NOTE
666 * "global" is keyword and not to
667 * be translated.
668 */
669 cryptoerror(LOG_STDERR, gettext(
670 "policy information for kernel "
671 "providers is available "
672 "in the %s zone only"), "global");
673 rc = FAILURE;
674 }
675 break;
676 case PROV_KEF_HARD:
677 if (getzoneid() == GLOBAL_ZONEID) {
678 rc = list_policy_for_hard(
679 prov->cp_name);
680 } else {
681 /*
682 * TRANSLATION_NOTE
683 * "global" is keyword and not to
684 * be translated.
685 */
686 cryptoerror(LOG_STDERR, gettext(
687 "policy information for kernel "
688 "providers is available "
689 "in the %s zone only"), "global");
690 rc = FAILURE;
691 }
692
693 break;
694 default: /* should not come here */
695 rc = FAILURE;
696 break;
697 }
698 } else {
699 /* error message */
700 usage();
701 rc = ERROR_USAGE;
702 }
703 }
704
705 out:
706 if (prov != NULL)
707 free(prov);
708
709 if (mecharglist != NULL)
710 free_mechlist(mecharglist);
711 return (rc);
712 }
713
714
715 /*
716 * The top level function for the disable subcommand.
717 */
718 static int
719 do_disable(int argc, char **argv)
720 {
721 cryptoadm_provider_t *prov = NULL;
722 int rc = SUCCESS;
723 boolean_t auto_key_migrate_flag = B_FALSE;
724
725 if ((argc < 3) || (argc > 5)) {
726 usage();
727 return (ERROR_USAGE);
728 }
729
730 prov = get_provider(argc, argv);
731 if (prov == NULL) {
732 usage();
733 return (ERROR_USAGE);
734 }
735 if (prov->cp_type == PROV_BADNAME) {
736 return (FAILURE);
813 "providers is supported in the %2$s zone only"),
814 "disable", "global");
815 rc = FAILURE;
816 }
817 break;
818 default: /* should not come here */
819 rc = FAILURE;
820 break;
821 }
822
823 out:
824 free(prov);
825 if (mecharglist != NULL) {
826 free_mechlist(mecharglist);
827 }
828 return (rc);
829 }
830
831
832 /*
833 * The top level function fo the enable subcommand.
834 */
835 static int
836 do_enable(int argc, char **argv)
837 {
838 cryptoadm_provider_t *prov = NULL;
839 int rc = SUCCESS;
840 char *alt_token = NULL, *alt_slot = NULL;
841 boolean_t use_default = B_FALSE, auto_key_migrate_flag = B_FALSE;
842
843 if ((argc < 3) || (argc > 6)) {
844 usage();
845 return (ERROR_USAGE);
846 }
847
848 prov = get_provider(argc, argv);
849 if (prov == NULL) {
850 usage();
851 return (ERROR_USAGE);
852 }
853 if ((prov->cp_type != METASLOT) && (argc != 4)) {
854 usage();
855 return (ERROR_USAGE);
856 }
857 if (prov->cp_type == PROV_BADNAME) {
858 rc = FAILURE;
859 goto out;
860 }
861
927 rc = FAILURE;
928 break;
929 }
930 out:
931 free(prov);
932 if (mecharglist != NULL) {
933 free_mechlist(mecharglist);
934 }
935 if (alt_token != NULL) {
936 free(alt_token);
937 }
938 if (alt_slot != NULL) {
939 free(alt_slot);
940 }
941 return (rc);
942 }
943
944
945
946 /*
947 * The top level function fo the install subcommand.
948 */
949 static int
950 do_install(int argc, char **argv)
951 {
952 cryptoadm_provider_t *prov = NULL;
953 int rc;
954
955 if (argc < 3) {
956 usage();
957 return (ERROR_USAGE);
958 }
959
960 prov = get_provider(argc, argv);
961 if (prov == NULL ||
962 prov->cp_type == PROV_BADNAME || prov->cp_type == PROV_KEF_HARD) {
963 /*
964 * TRANSLATION_NOTE
965 * "install" could be either a literal keyword and hence
966 * not to be translated, or a verb and translatable. A
967 * choice was made to view it as a literal keyword.
1017 } else {
1018 /*
1019 * TRANSLATION_NOTE
1020 * "install" could be either a literal keyword and hence
1021 * not to be translated, or a verb and translatable. A
1022 * choice was made to view it as a literal keyword.
1023 * "global" is keyword and not to be translated.
1024 */
1025 cryptoerror(LOG_STDERR, gettext("%1$s for kernel providers "
1026 "is supported in the %2$s zone only"), "install", "global");
1027 rc = FAILURE;
1028 }
1029 out:
1030 free(prov);
1031 return (rc);
1032 }
1033
1034
1035
1036 /*
1037 * The top level function for the uninstall subcommand.
1038 */
1039 static int
1040 do_uninstall(int argc, char **argv)
1041 {
1042 cryptoadm_provider_t *prov = NULL;
1043 int rc = SUCCESS;
1044
1045 if (argc != 3) {
1046 usage();
1047 return (ERROR_USAGE);
1048 }
1049
1050 prov = get_provider(argc, argv);
1051 if (prov == NULL ||
1052 prov->cp_type == PROV_BADNAME || prov->cp_type == PROV_KEF_HARD) {
1053 /*
1054 * TRANSLATION_NOTE
1055 * "uninstall" could be either a literal keyword and hence
1056 * not to be translated, or a verb and translatable. A
1057 * choice was made to view it as a literal keyword.
1058 */
1059 cryptoerror(LOG_STDERR,
1060 gettext("bad provider name for %s."), "uninstall");
1061 free(prov);
1062 return (FAILURE);
1063 }
1064
1065 if (prov->cp_type == PROV_UEF_LIB) {
1066 rc = uninstall_uef_lib(prov->cp_name);
1067 } else if (prov->cp_type == PROV_KEF_SOFT) {
1068 if (getzoneid() == GLOBAL_ZONEID) {
1069 rc = uninstall_kef(prov->cp_name);
1070 } else {
1071 /*
1072 * TRANSLATION_NOTE
1073 * "uninstall" could be either a literal keyword and
1074 * hence not to be translated, or a verb and
1075 * translatable. A choice was made to view it as a
1076 * literal keyword. "global" is keyword and not to
1077 * be translated.
1078 */
1079 cryptoerror(LOG_STDERR, gettext("%1$s for kernel "
1080 "providers is supported in the %2$s zone only"),
1081 "uninstall", "global");
1082 rc = FAILURE;
1083 }
1084 }
1085
1086 free(prov);
1087 return (rc);
1088 }
1089
1090
1091 /*
1092 * The top level function for the unload subcommand.
1093 */
1094 static int
1095 do_unload(int argc, char **argv)
1096 {
1097 cryptoadm_provider_t *prov = NULL;
1098 entry_t *pent;
1099 boolean_t is_active;
1100 int rc = SUCCESS;
1101
1102 if (argc != 3) {
1103 usage();
1104 return (ERROR_USAGE);
1105 }
1106
1107 /* check if it is a kernel software provider */
1108 prov = get_provider(argc, argv);
1109 if (prov == NULL) {
1110 cryptoerror(LOG_STDERR,
1111 gettext("unable to determine provider name."));
1112 goto out;
1113 }
1114 if (prov->cp_type != PROV_KEF_SOFT) {
1115 cryptoerror(LOG_STDERR,
1116 gettext("%s is not a valid kernel software provider."),
1117 prov->cp_name);
1118 rc = FAILURE;
1119 goto out;
1120 }
1121
1122 if (getzoneid() != GLOBAL_ZONEID) {
1123 /*
1124 * TRANSLATION_NOTE
1125 * "unload" could be either a literal keyword and hence
1126 * not to be translated, or a verb and translatable.
1127 * A choice was made to view it as a literal keyword.
1128 * "global" is keyword and not to be translated.
1129 */
1130 cryptoerror(LOG_STDERR, gettext("%1$s for kernel providers "
1131 "is supported in the %2$s zone only"), "unload", "global");
1132 rc = FAILURE;
1133 goto out;
1134 }
1135
1136 /* Check if it is in the kcf.conf file first */
1137 if ((pent = getent_kef(prov->cp_name)) == NULL) {
1138 cryptoerror(LOG_STDERR,
1139 gettext("provider %s does not exist."), prov->cp_name);
1140 rc = FAILURE;
1141 goto out;
1142 }
1143 free_entry(pent);
1144
1145 /* If it is unloaded already, return */
1146 if (check_active_for_soft(prov->cp_name, &is_active) == FAILURE) {
1147 cryptodebug("internal error");
1148 cryptoerror(LOG_STDERR,
1149 gettext("failed to unload %s."), prov->cp_name);
1150 rc = FAILURE;
1151 goto out;
1152 }
1153
1154 if (is_active == B_FALSE) { /* unloaded already */
1155 rc = SUCCESS;
1156 goto out;
1157 } else if (unload_kef_soft(prov->cp_name, B_TRUE) == FAILURE) {
1158 cryptoerror(LOG_STDERR,
1159 gettext("failed to unload %s."), prov->cp_name);
1160 rc = FAILURE;
1161 } else {
1162 rc = SUCCESS;
1163 }
1164 out:
1165 free(prov);
1166 return (rc);
1167 }
1168
1169
1170
1171 /*
1172 * The top level function for the refresh subcommand.
1173 */
1174 static int
1175 do_refresh(int argc)
1176 {
1177 if (argc != 2) {
1178 usage();
1179 return (ERROR_USAGE);
1180 }
1181
1182 /*
1183 * Note: in non-global zone, this must silently return SUCCESS
1184 * due to integration with SMF, for "svcadm refresh cryptosvc"
1185 */
1186 if (getzoneid() != GLOBAL_ZONEID)
1187 return (SUCCESS);
1188
1189 return (refresh());
1190 }
1191
1192
1193 /*
1194 * The top level function for the start subcommand.
1195 */
1196 static int
1197 do_start(int argc)
1198 {
1199 int ret;
1200
1201 if (argc != 2) {
1202 usage();
1203 return (ERROR_USAGE);
1204 }
1205
1206 ret = do_refresh(argc);
1207 if (ret != SUCCESS)
1208 return (ret);
1209
1210 return (start_daemon());
1211 }
1212
1213 /*
1214 * The top level function for the stop subcommand.
1215 */
1216 static int
1217 do_stop(int argc)
1218 {
1219 if (argc != 2) {
1220 usage();
1221 return (ERROR_USAGE);
1222 }
1223
1224 return (stop_daemon());
1225 }
1226
1227
1228
1229 /*
1230 * List all the providers.
1231 */
1232 static int
1233 list_simple_for_all(boolean_t verbose)
1234 {
1235 uentrylist_t *pliblist;
1236 uentrylist_t *plibptr;
1237 entrylist_t *pdevlist_conf;
1238 entrylist_t *psoftlist_conf;
1239 entrylist_t *pdevlist_zone;
1240 entrylist_t *psoftlist_zone;
1241 entrylist_t *ptr;
1242 crypto_get_dev_list_t *pdevlist_kernel = NULL;
1243 boolean_t is_active;
1244 int ru = SUCCESS;
1245 int rs = SUCCESS;
1246 int rd = SUCCESS;
1247 int i;
1248
1249 /* get user-level providers */
1250 (void) printf(gettext("\nUser-level providers:\n"));
1251 if (get_pkcs11conf_info(&pliblist) != SUCCESS) {
1252 cryptoerror(LOG_STDERR, gettext(
1253 "failed to retrieve the list of user-level providers."));
1254 ru = FAILURE;
1255 }
1256 plibptr = pliblist;
1257 while (plibptr != NULL) {
1258 if (strcmp(plibptr->puent->name, METASLOT_KEYWORD) != 0) {
1259 (void) printf(gettext("Provider: %s\n"),
1260 plibptr->puent->name);
1261 if (verbose) {
1262 (void) list_mechlist_for_lib(
1263 plibptr->puent->name, mecharglist, NULL,
1264 B_FALSE, verbose, B_FALSE);
1265 (void) printf("\n");
1266 }
1267 }
1268 plibptr = plibptr->next;
1269 }
1270 free_uentrylist(pliblist);
1271
1272 /* get kernel software providers */
1273 (void) printf(gettext("\nKernel software providers:\n"));
1274
1275 if (getzoneid() == GLOBAL_ZONEID) {
1276 /* use kcf.conf for kernel software providers in global zone */
1277 pdevlist_conf = NULL;
1278 psoftlist_conf = NULL;
1279
1280 if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf) !=
1281 SUCCESS) {
1282 cryptoerror(LOG_STDERR,
1283 gettext("failed to retrieve the "
1284 "list of kernel software providers.\n"));
1285 rs = FAILURE;
1286 }
1287
1288 ptr = psoftlist_conf;
1289 while (ptr != NULL) {
1290 if (check_active_for_soft(ptr->pent->name, &is_active)
1291 == FAILURE) {
1292 rs = FAILURE;
1293 cryptoerror(LOG_STDERR, gettext("failed to "
1294 "get the state of a kernel software "
1295 "providers.\n"));
1296 break;
1297 }
1298
1299 (void) printf("\t%s", ptr->pent->name);
1300 if (is_active == B_FALSE) {
1301 (void) printf(gettext(" (inactive)\n"));
1302 } else {
1303 (void) printf("\n");
1304 }
1305 ptr = ptr->next;
1306 }
1307
1308 free_entrylist(pdevlist_conf);
1309 free_entrylist(psoftlist_conf);
1310 } else {
1311 /* kcf.conf not there in non-global zone, use /dev/cryptoadm */
1312 pdevlist_zone = NULL;
1313 psoftlist_zone = NULL;
1314
1315 if (get_admindev_info(&pdevlist_zone, &psoftlist_zone) !=
1316 SUCCESS) {
1317 cryptoerror(LOG_STDERR,
1318 gettext("failed to retrieve the "
1319 "list of kernel software providers.\n"));
1320 rs = FAILURE;
1321 }
1322
1323 ptr = psoftlist_zone;
1324 while (ptr != NULL) {
1325 (void) printf("\t%s\n", ptr->pent->name);
1326 ptr = ptr->next;
1327 }
1328
1329 free_entrylist(pdevlist_zone);
1330 free_entrylist(psoftlist_zone);
1331 }
1332
1333 /* get kernel hardware providers */
1334 (void) printf(gettext("\nKernel hardware providers:\n"));
1335 if (get_dev_list(&pdevlist_kernel) == FAILURE) {
1336 cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1337 "the list of kernel hardware providers.\n"));
1338 rd = FAILURE;
1339 } else {
1340 for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) {
1341 (void) printf("\t%s/%d\n",
1342 pdevlist_kernel->dl_devs[i].le_dev_name,
1343 pdevlist_kernel->dl_devs[i].le_dev_instance);
1344 }
1345 }
1346 free(pdevlist_kernel);
1347
1348 if (ru == FAILURE || rs == FAILURE || rd == FAILURE) {
1349 return (FAILURE);
1350 } else {
1351 return (SUCCESS);
1352 }
1353 }
1354
1355
1356
1357 /*
1358 * List all the providers. And for each provider, list the mechanism list.
1359 */
1360 static int
1361 list_mechlist_for_all(boolean_t verbose)
1362 {
1363 crypto_get_dev_list_t *pdevlist_kernel;
1364 uentrylist_t *pliblist;
1365 uentrylist_t *plibptr;
1366 entrylist_t *pdevlist_conf;
1367 entrylist_t *psoftlist_conf;
1368 entrylist_t *pdevlist_zone;
1369 entrylist_t *psoftlist_zone;
1370 entrylist_t *ptr;
1371 mechlist_t *pmechlist;
1372 boolean_t is_active;
1373 char provname[MAXNAMELEN];
1374 char devname[MAXNAMELEN];
1375 int inst_num;
1376 int count;
1377 int i;
1378 int rv;
1379 int rc = SUCCESS;
1380
1381 /* get user-level providers */
1382 (void) printf(gettext("\nUser-level providers:\n"));
1383 /*
1384 * TRANSLATION_NOTE
1385 * Strictly for appearance's sake, this line should be as long as
1386 * the length of the translated text above.
1387 */
1388 (void) printf(gettext("=====================\n"));
1389 if (get_pkcs11conf_info(&pliblist) != SUCCESS) {
1390 cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1391 "the list of user-level providers.\n"));
1392 rc = FAILURE;
1393 }
1394
1395 plibptr = pliblist;
1396 while (plibptr != NULL) {
1397 /* skip metaslot entry */
1398 if (strcmp(plibptr->puent->name, METASLOT_KEYWORD) != 0) {
1399 (void) printf(gettext("\nProvider: %s\n"),
1400 plibptr->puent->name);
1401 rv = list_mechlist_for_lib(plibptr->puent->name,
1402 mecharglist, NULL, B_FALSE, verbose, B_TRUE);
1403 if (rv == FAILURE) {
1404 rc = FAILURE;
1405 }
1406 }
1407 plibptr = plibptr->next;
1408 }
1409 free_uentrylist(pliblist);
1410
1411 /* get kernel software providers */
1412 (void) printf(gettext("\nKernel software providers:\n"));
1413 /*
1414 * TRANSLATION_NOTE
1415 * Strictly for appearance's sake, this line should be as long as
1416 * the length of the translated text above.
1417 */
1418 (void) printf(gettext("==========================\n"));
1419 if (getzoneid() == GLOBAL_ZONEID) {
1420 /* use kcf.conf for kernel software providers in global zone */
1421 pdevlist_conf = NULL;
1422 psoftlist_conf = NULL;
1423
1424 if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf) !=
1425 SUCCESS) {
1426 cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1427 "the list of kernel software providers.\n"));
1428 rc = FAILURE;
1429 }
1430
1431 ptr = psoftlist_conf;
1432 while (ptr != NULL) {
1433 if (check_active_for_soft(ptr->pent->name, &is_active)
1434 == SUCCESS) {
1435 if (is_active) {
1436 rv = list_mechlist_for_soft(
1437 ptr->pent->name);
1438 if (rv == FAILURE) {
1439 rc = FAILURE;
1440 }
1441 } else {
1442 (void) printf(gettext(
1443 "%s: (inactive)\n"),
1444 ptr->pent->name);
1445 }
1446 } else {
1447 /* should not happen */
1448 (void) printf(gettext(
1449 "%s: failed to get the mechanism list.\n"),
1450 ptr->pent->name);
1451 rc = FAILURE;
1452 }
1453 ptr = ptr->next;
1454 }
1455
1456 free_entrylist(pdevlist_conf);
1457 free_entrylist(psoftlist_conf);
1458 } else {
1459 /* kcf.conf not there in non-global zone, use /dev/cryptoadm */
1460 pdevlist_zone = NULL;
1461 psoftlist_zone = NULL;
1462
1463 if (get_admindev_info(&pdevlist_zone, &psoftlist_zone) !=
1464 SUCCESS) {
1465 cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1466 "the list of kernel software providers.\n"));
1467 rc = FAILURE;
1468 }
1469
1470 ptr = psoftlist_zone;
1471 while (ptr != NULL) {
1472 rv = list_mechlist_for_soft(ptr->pent->name);
1473 if (rv == FAILURE) {
1474 (void) printf(gettext(
1475 "%s: failed to get the mechanism list.\n"),
1476 ptr->pent->name);
1477 rc = FAILURE;
1478 }
1479 ptr = ptr->next;
1480 }
1481
1482 free_entrylist(pdevlist_zone);
1483 free_entrylist(psoftlist_zone);
1484 }
1485
1486 /* Get kernel hardware providers and their mechanism lists */
1487 (void) printf(gettext("\nKernel hardware providers:\n"));
1488 /*
1489 * TRANSLATION_NOTE
1490 * Strictly for appearance's sake, this line should be as long as
1491 * the length of the translated text above.
1492 */
1493 (void) printf(gettext("==========================\n"));
1494 if (get_dev_list(&pdevlist_kernel) != SUCCESS) {
1495 cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1496 "the list of hardware providers.\n"));
1497 return (FAILURE);
1498 }
1499
1505 (void) snprintf(provname, sizeof (provname), "%s/%d", devname,
1506 inst_num);
1507 if (get_dev_info(devname, inst_num, count, &pmechlist) ==
1508 SUCCESS) {
1509 (void) filter_mechlist(&pmechlist, RANDOM);
1510 print_mechlist(provname, pmechlist);
1511 free_mechlist(pmechlist);
1512 } else {
1513 (void) printf(gettext("%s: failed to get the mechanism"
1514 " list.\n"), provname);
1515 rc = FAILURE;
1516 }
1517 }
1518 free(pdevlist_kernel);
1519 return (rc);
1520 }
1521
1522
1523 /*
1524 * List all the providers. And for each provider, list the policy information.
1525 */
1526 static int
1527 list_policy_for_all(void)
1528 {
1529 crypto_get_dev_list_t *pdevlist_kernel;
1530 uentrylist_t *pliblist;
1531 uentrylist_t *plibptr;
1532 entrylist_t *pdevlist_conf;
1533 entrylist_t *psoftlist_conf;
1534 entrylist_t *ptr;
1535 entrylist_t *phead;
1536 boolean_t found;
1537 char provname[MAXNAMELEN];
1538 int i;
1539 int rc = SUCCESS;
1540
1541 /* Get user-level providers */
1542 (void) printf(gettext("\nUser-level providers:\n"));
1543 /*
1544 * TRANSLATION_NOTE
1545 * Strictly for appearance's sake, this line should be as long as
1546 * the length of the translated text above.
1547 */
1548 (void) printf(gettext("=====================\n"));
1549 if (get_pkcs11conf_info(&pliblist) == FAILURE) {
1550 cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1551 "the list of user-level providers.\n"));
1552 } else {
1553 plibptr = pliblist;
1554 while (plibptr != NULL) {
1555 /* skip metaslot entry */
1556 if (strcmp(plibptr->puent->name,
1557 METASLOT_KEYWORD) != 0) {
1558 if (print_uef_policy(plibptr->puent)
1559 == FAILURE) {
1560 rc = FAILURE;
1561 }
1562 }
1563 plibptr = plibptr->next;
1564 }
1565 free_uentrylist(pliblist);
1566 }
1567
1568 /* kernel software providers */
1569 (void) printf(gettext("\nKernel software providers:\n"));
1570 /*
1571 * TRANSLATION_NOTE
1572 * Strictly for appearance's sake, this line should be as long as
1573 * the length of the translated text above.
1574 */
1575 (void) printf(gettext("==========================\n"));
1576
1577 /* Get all entries from the kcf.conf file */
1578 pdevlist_conf = NULL;
1579 if (getzoneid() == GLOBAL_ZONEID) {
1580 /* use kcf.conf for kernel software providers in global zone */
1581 psoftlist_conf = NULL;
1582
1583 if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf) ==
1584 FAILURE) {
1585 cryptoerror(LOG_STDERR, gettext(
1586 "failed to retrieve the list of kernel "
1587 "providers.\n"));
1588 return (FAILURE);
1589 }
1590
1591 ptr = psoftlist_conf;
1592 while (ptr != NULL) {
1593 (void) list_policy_for_soft(ptr->pent->name);
1594 ptr = ptr->next;
1595 }
1596
1597 free_entrylist(psoftlist_conf);
1598 } else {
1599 /* kcf.conf not there in non-global zone, no policy info */
1600
1601 /*
1602 * TRANSLATION_NOTE
1603 * "global" is keyword and not to be translated.
1604 */
1605 cryptoerror(LOG_STDERR, gettext(
1606 "policy information for kernel software providers is "
1607 "available in the %s zone only"), "global");
1608 }
1609
1610 /* Kernel hardware providers */
1611 (void) printf(gettext("\nKernel hardware providers:\n"));
1612 /*
1613 * TRANSLATION_NOTE
1614 * Strictly for appearance's sake, this line should be as long as
1615 * the length of the translated text above.
1616 */
1617 (void) printf(gettext("==========================\n"));
1618
1619 if (getzoneid() != GLOBAL_ZONEID) {
1620 /*
1621 * TRANSLATION_NOTE
1622 * "global" is keyword and not to be translated.
1623 */
1624 cryptoerror(LOG_STDERR, gettext(
1625 "policy information for kernel hardware providers is "
1626 "available in the %s zone only"), "global");
1627 return (FAILURE);
1628 }
1629
1630 /* Get the hardware provider list from kernel */
1631 if (get_dev_list(&pdevlist_kernel) != SUCCESS) {
1632 cryptoerror(LOG_STDERR, gettext(
1633 "failed to retrieve the list of hardware providers.\n"));
1634 free_entrylist(pdevlist_conf);
1635 return (FAILURE);
1636 }
1637
1638 /*
1639 * For each hardware provider from kernel, check if it has an entry
1640 * in the config file. If it has an entry, print out the policy from
1641 * config file and remove the entry from the hardware provider list
1642 * of the config file. If it does not have an entry in the config
1643 * file, no mechanisms of it have been disabled. But, we still call
1644 * list_policy_for_hard() to account for the "random" feature.
1645 */
1646 for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) {
1647 (void) snprintf(provname, sizeof (provname), "%s/%d",
1648 pdevlist_kernel->dl_devs[i].le_dev_name,
1649 pdevlist_kernel->dl_devs[i].le_dev_instance);
1650 found = B_FALSE;
1651 phead = ptr = pdevlist_conf;
1652 while (!found && ptr) {
1653 if (strcmp(ptr->pent->name, provname) == 0) {
1654 found = B_TRUE;
1655 } else {
1656 phead = ptr;
1657 ptr = ptr->next;
1658 }
1659 }
1660
1661 if (found) {
1662 (void) list_policy_for_hard(ptr->pent->name);
1663 if (phead == ptr) {
1664 pdevlist_conf = pdevlist_conf->next;
1665 } else {
1666 phead->next = ptr->next;
1667 }
1668 free_entry(ptr->pent);
1669 free(ptr);
1670 } else {
1671 (void) list_policy_for_hard(provname);
1672 }
1673 }
1674
1675 /*
1676 * If there are still entries left in the pdevlist_conf list from
1677 * the config file, these providers must have been detached.
1678 * Should print out their policy information also.
1679 */
1680 ptr = pdevlist_conf;
1681 while (ptr != NULL) {
1682 print_kef_policy(ptr->pent, B_FALSE, B_TRUE);
1683 ptr = ptr->next;
1684 }
1685
1686 free_entrylist(pdevlist_conf);
1687 free(pdevlist_kernel);
1688
1689 return (rc);
1690 }
|
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) {
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;
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);
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
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.
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
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 }
|