2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #pragma ident "%Z%%M% %I% %E% SMI"
27
28 #include <fcntl.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <strings.h>
32 #include <unistd.h>
33 #include <locale.h>
34 #include <libgen.h>
35 #include <sys/types.h>
36 #include <zone.h>
37 #include <sys/crypto/ioctladmin.h>
38 #include <cryptoutil.h>
39 #include "cryptoadm.h"
40
41 #define REQ_ARG_CNT 2
42
43 /* subcommand index */
44 enum subcommand_index {
45 CRYPTO_LIST,
46 CRYPTO_DISABLE,
47 CRYPTO_ENABLE,
48 CRYPTO_INSTALL,
49 CRYPTO_UNINSTALL,
50 CRYPTO_UNLOAD,
51 CRYPTO_REFRESH,
52 CRYPTO_START,
53 CRYPTO_STOP,
54 CRYPTO_HELP };
55
56 /*
57 * TRANSLATION_NOTE:
58 * Command keywords are not to be translated.
59 */
60 static char *cmd_table[] = {
61 "list",
62 "disable",
63 "enable",
64 "install",
65 "uninstall",
66 "unload",
67 "refresh",
68 "start",
69 "stop",
70 "--help" };
71
72 /* provider type */
73 enum provider_type_index {
74 PROV_UEF_LIB,
75 PROV_KEF_SOFT,
76 PROV_KEF_HARD,
77 METASLOT,
78 PROV_BADNAME };
79
80 typedef struct {
81 char cp_name[MAXPATHLEN];
82 enum provider_type_index cp_type;
83 } cryptoadm_provider_t;
84
85 /*
86 * TRANSLATION_NOTE:
87 * Operand keywords are not to be translated.
88 */
89 static const char *KN_PROVIDER = "provider=";
90 static const char *KN_MECH = "mechanism=";
91 static const char *KN_ALL = "all";
92 static const char *KN_TOKEN = "token=";
93 static const char *KN_SLOT = "slot=";
94 static const char *KN_DEFAULT_KS = "default-keystore";
95 static const char *KN_AUTO_KEY_MIGRATE = "auto-key-migrate";
96
97 /* static variables */
98 static boolean_t allflag = B_FALSE;
99 static boolean_t rndflag = B_FALSE;
100 static mechlist_t *mecharglist = NULL;
101
102 /* static functions */
103 static void usage(void);
104 static int get_provider_type(char *);
105 static int process_mech_operands(int, char **, boolean_t);
106 static int do_list(int, char **);
181 case CRYPTO_STOP:
182 rc = do_stop(argc);
183 break;
184 case CRYPTO_HELP:
185 usage();
186 rc = SUCCESS;
187 break;
188 default: /* should not come here */
189 usage();
190 rc = ERROR_USAGE;
191 break;
192 }
193 return (rc);
194 }
195
196
197 static void
198 usage(void)
199 {
200 /*
201 * TRANSLATION_NOTE:
202 * Command usage is not to be translated. Only the word "Usage:"
203 * along with localized expressions indicating what kind of value
204 * is expected for arguments.
205 */
206 (void) fprintf(stderr, gettext("Usage:\n"));
207 (void) fprintf(stderr,
208 " cryptoadm list [-mpv] [provider=<%s> | metaslot]"
209 " [mechanism=<%s>]\n",
210 gettext("provider-name"), gettext("mechanism-list"));
211 (void) fprintf(stderr,
212 " cryptoadm disable provider=<%s>"
213 " mechanism=<%s> | random | all\n",
214 gettext("provider-name"), gettext("mechanism-list"));
215 (void) fprintf(stderr,
216 " cryptoadm disable metaslot"
217 " [auto-key-migrate] [mechanism=<%s>]\n",
218 gettext("mechanism-list"));
219 (void) fprintf(stderr,
220 " cryptoadm enable provider=<%s>"
221 " mechanism=<%s> | random | all\n",
235 (void) fprintf(stderr,
236 " cryptoadm uninstall provider=<%s>\n",
237 gettext("provider-name"));
238 (void) fprintf(stderr,
239 " cryptoadm unload provider=<%s>\n",
240 gettext("provider-name"));
241 (void) fprintf(stderr,
242 " cryptoadm refresh\n"
243 " cryptoadm start\n"
244 " cryptoadm stop\n"
245 " cryptoadm --help\n");
246 }
247
248
249 /*
250 * Get the provider type. This function returns
251 * - PROV_UEF_LIB if provname contains an absolute path name
252 * - PROV_KEF_SOFT if provname is a base name only
253 * - PROV_KEF_HARD if provname contains one slash only and the slash is not
254 * the 1st character.
255 * - PROV_BADNAME othewise.
256 */
257 static int
258 get_provider_type(char *provname)
259 {
260 char *pslash1;
261 char *pslash2;
262
263 if (provname == NULL) {
264 return (FAILURE);
265 }
266
267 if (provname[0] == '/') {
268 return (PROV_UEF_LIB);
269 } else if ((pslash1 = strchr(provname, SEP_SLASH)) == NULL) {
270 /* no slash */
271 return (PROV_KEF_SOFT);
272 } else {
273 pslash2 = strrchr(provname, SEP_SLASH);
274 if (pslash1 == pslash2) {
275 return (PROV_KEF_HARD);
288 static cryptoadm_provider_t *
289 get_provider(int argc, char **argv)
290 {
291 int c = 0;
292 boolean_t found = B_FALSE;
293 cryptoadm_provider_t *provider = NULL;
294 char *provstr = NULL, *savstr;
295 boolean_t is_metaslot = B_FALSE;
296
297 while (!found && ++c < argc) {
298 if (strncmp(argv[c], METASLOT_KEYWORD,
299 strlen(METASLOT_KEYWORD)) == 0) {
300 is_metaslot = B_TRUE;
301 found = B_TRUE;
302 } else if (strncmp(argv[c], KN_PROVIDER,
303 strlen(KN_PROVIDER)) == 0 &&
304 strlen(argv[c]) > strlen(KN_PROVIDER)) {
305 if ((provstr = strdup(argv[c])) == NULL) {
306 int err = errno;
307 /*
308 * TRANSLATION_NOTE:
309 * "get_provider" is a function name and should
310 * not be translated.
311 */
312 cryptoerror(LOG_STDERR, "get_provider: %s.",
313 strerror(err));
314 return (NULL);
315 }
316 found = B_TRUE;
317 }
318 }
319 if (!found)
320 return (NULL);
321
322 provider = malloc(sizeof (cryptoadm_provider_t));
323 if (provider == NULL) {
324 cryptoerror(LOG_STDERR, gettext("out of memory."));
325 if (provstr) {
326 free(provstr);
327 }
328 return (NULL);
466 process_mech_operands(int argc, char **argv, boolean_t quiet)
467 {
468 mechlist_t *pmech;
469 mechlist_t *pcur = NULL;
470 mechlist_t *phead = NULL;
471 boolean_t found = B_FALSE;
472 char *mechliststr = NULL;
473 char *curmech = NULL;
474 int c = -1;
475 int rc = SUCCESS;
476
477 while (!found && ++c < argc) {
478 if ((strncmp(argv[c], KN_MECH, strlen(KN_MECH)) == 0) &&
479 strlen(argv[c]) > strlen(KN_MECH)) {
480 found = B_TRUE;
481 }
482 }
483 if (!found) {
484 if (!quiet)
485 /*
486 * TRANSLATION_NOTE:
487 * "mechanism" could be either a literal keyword
488 * and hence not to be translated, or a descriptive
489 * word and translatable. A choice was made to
490 * view it as a literal keyword.
491 */
492 cryptoerror(LOG_STDERR,
493 gettext("the %s operand is missing.\n"),
494 "mechanism");
495 return (ERROR_USAGE);
496 }
497 (void) strtok(argv[c], "=");
498 mechliststr = strtok(NULL, "=");
499
500 if (strcmp(mechliststr, "all") == 0) {
501 allflag = B_TRUE;
502 mecharglist = NULL;
503 return (SUCCESS);
504 }
505
506 curmech = strtok(mechliststr, ",");
646 rc = list_mechlist_for_soft(prov->cp_name);
647 break;
648 case PROV_KEF_HARD:
649 rc = list_mechlist_for_hard(prov->cp_name);
650 break;
651 default: /* should not come here */
652 rc = FAILURE;
653 break;
654 }
655 } else if (pflag) {
656 switch (prov->cp_type) {
657 case PROV_UEF_LIB:
658 rc = list_policy_for_lib(prov->cp_name);
659 break;
660 case PROV_KEF_SOFT:
661 if (getzoneid() == GLOBAL_ZONEID) {
662 rc = list_policy_for_soft(
663 prov->cp_name);
664 } else {
665 /*
666 * TRANSLATION_NOTE:
667 * "global" is keyword and not to
668 * be translated.
669 */
670 cryptoerror(LOG_STDERR, gettext(
671 "policy information for kernel "
672 "providers is available "
673 "in the %s zone only"), "global");
674 rc = FAILURE;
675 }
676 break;
677 case PROV_KEF_HARD:
678 if (getzoneid() == GLOBAL_ZONEID) {
679 rc = list_policy_for_hard(
680 prov->cp_name);
681 } else {
682 /*
683 * TRANSLATION_NOTE:
684 * "global" is keyword and not to
685 * be translated.
686 */
687 cryptoerror(LOG_STDERR, gettext(
688 "policy information for kernel "
689 "providers is available "
690 "in the %s zone only"), "global");
691 rc = FAILURE;
692 }
693
694 break;
695 default: /* should not come here */
696 rc = FAILURE;
697 break;
698 }
699 } else {
700 /* error message */
701 usage();
702 rc = ERROR_USAGE;
703 }
761 case METASLOT:
762 rc = disable_metaslot(mecharglist, allflag,
763 auto_key_migrate_flag);
764 break;
765 case PROV_UEF_LIB:
766 rc = disable_uef_lib(prov->cp_name, rndflag, allflag,
767 mecharglist);
768 break;
769 case PROV_KEF_SOFT:
770 if (rndflag && !allflag) {
771 if ((mecharglist = create_mech(RANDOM)) == NULL) {
772 rc = FAILURE;
773 break;
774 }
775 }
776 if (getzoneid() == GLOBAL_ZONEID) {
777 rc = disable_kef_software(prov->cp_name, rndflag,
778 allflag, mecharglist);
779 } else {
780 /*
781 * TRANSLATION_NOTE:
782 * "disable" could be either a literal keyword
783 * and hence not to be translated, or a verb and
784 * translatable. A choice was made to view it as
785 * a literal keyword. "global" is keyword and not
786 * to be translated.
787 */
788 cryptoerror(LOG_STDERR, gettext("%1$s for kernel "
789 "providers is supported in the %2$s zone only"),
790 "disable", "global");
791 rc = FAILURE;
792 }
793 break;
794 case PROV_KEF_HARD:
795 if (rndflag && !allflag) {
796 if ((mecharglist = create_mech(RANDOM)) == NULL) {
797 rc = FAILURE;
798 break;
799 }
800 }
801 if (getzoneid() == GLOBAL_ZONEID) {
802 rc = disable_kef_hardware(prov->cp_name, rndflag,
803 allflag, mecharglist);
804 } else {
805 /*
806 * TRANSLATION_NOTE:
807 * "disable" could be either a literal keyword
808 * and hence not to be translated, or a verb and
809 * translatable. A choice was made to view it as
810 * a literal keyword. "global" is keyword and not
811 * to be translated.
812 */
813 cryptoerror(LOG_STDERR, gettext("%1$s for kernel "
814 "providers is supported in the %2$s zone only"),
815 "disable", "global");
816 rc = FAILURE;
817 }
818 break;
819 default: /* should not come here */
820 rc = FAILURE;
821 break;
822 }
823
824 out:
825 free(prov);
826 if (mecharglist != NULL) {
894 rc = enable_metaslot(alt_token, alt_slot, use_default,
895 mecharglist, allflag, auto_key_migrate_flag);
896 break;
897 case PROV_UEF_LIB:
898 rc = enable_uef_lib(prov->cp_name, rndflag, allflag,
899 mecharglist);
900 break;
901 case PROV_KEF_SOFT:
902 case PROV_KEF_HARD:
903 if (rndflag && !allflag) {
904 if ((mecharglist = create_mech(RANDOM)) == NULL) {
905 rc = FAILURE;
906 break;
907 }
908 }
909 if (getzoneid() == GLOBAL_ZONEID) {
910 rc = enable_kef(prov->cp_name, rndflag, allflag,
911 mecharglist);
912 } else {
913 /*
914 * TRANSLATION_NOTE:
915 * "enable" could be either a literal keyword
916 * and hence not to be translated, or a verb and
917 * translatable. A choice was made to view it as
918 * a literal keyword. "global" is keyword and not
919 * to be translated.
920 */
921 cryptoerror(LOG_STDERR, gettext("%1$s for kernel "
922 "providers is supported in the %2$s zone only"),
923 "enable", "global");
924 rc = FAILURE;
925 }
926 break;
927 default: /* should not come here */
928 rc = FAILURE;
929 break;
930 }
931 out:
932 free(prov);
933 if (mecharglist != NULL) {
934 free_mechlist(mecharglist);
945
946
947 /*
948 * The top level function fo the install subcommand.
949 */
950 static int
951 do_install(int argc, char **argv)
952 {
953 cryptoadm_provider_t *prov = NULL;
954 int rc;
955
956 if (argc < 3) {
957 usage();
958 return (ERROR_USAGE);
959 }
960
961 prov = get_provider(argc, argv);
962 if (prov == NULL ||
963 prov->cp_type == PROV_BADNAME || prov->cp_type == PROV_KEF_HARD) {
964 /*
965 * TRANSLATION_NOTE:
966 * "install" could be either a literal keyword and hence
967 * not to be translated, or a verb and translatable. A
968 * choice was made to view it as a literal keyword.
969 */
970 cryptoerror(LOG_STDERR,
971 gettext("bad provider name for %s."), "install");
972 rc = FAILURE;
973 goto out;
974 }
975
976 if (prov->cp_type == PROV_UEF_LIB) {
977 rc = install_uef_lib(prov->cp_name);
978 goto out;
979 }
980
981 /* It is the PROV_KEF_SOFT type now */
982
983 /* check if there are mechanism operands */
984 if (argc < 4) {
985 /*
986 * TRANSLATION_NOTE:
987 * "mechanism" could be either a literal keyword and hence
988 * not to be translated, or a descriptive word and
989 * translatable. A choice was made to view it as a literal
990 * keyword.
991 */
992 cryptoerror(LOG_STDERR,
993 gettext("need %s operands for installing a"
994 " kernel software provider."), "mechanism");
995 rc = ERROR_USAGE;
996 goto out;
997 }
998
999 if ((rc = process_mech_operands(argc, argv, B_FALSE)) != SUCCESS) {
1000 goto out;
1001 }
1002
1003 if (allflag == B_TRUE) {
1004 /*
1005 * TRANSLATION_NOTE:
1006 * "all", "mechanism", and "install" are all keywords and
1007 * not to be translated.
1008 */
1009 cryptoerror(LOG_STDERR,
1010 gettext("can not use the %1$s keyword for %2$s "
1011 "in the %3$s subcommand."), "all", "mechanism", "install");
1012 rc = ERROR_USAGE;
1013 goto out;
1014 }
1015
1016 if (getzoneid() == GLOBAL_ZONEID) {
1017 rc = install_kef(prov->cp_name, mecharglist);
1018 } else {
1019 /*
1020 * TRANSLATION_NOTE:
1021 * "install" could be either a literal keyword and hence
1022 * not to be translated, or a verb and translatable. A
1023 * choice was made to view it as a literal keyword.
1024 * "global" is keyword and not to be translated.
1025 */
1026 cryptoerror(LOG_STDERR, gettext("%1$s for kernel providers "
1027 "is supported in the %2$s zone only"), "install", "global");
1028 rc = FAILURE;
1029 }
1030 out:
1031 free(prov);
1032 return (rc);
1033 }
1034
1035
1036
1037 /*
1038 * The top level function for the uninstall subcommand.
1039 */
1040 static int
1041 do_uninstall(int argc, char **argv)
1042 {
1043 cryptoadm_provider_t *prov = NULL;
1044 int rc = SUCCESS;
1045
1046 if (argc != 3) {
1047 usage();
1048 return (ERROR_USAGE);
1049 }
1050
1051 prov = get_provider(argc, argv);
1052 if (prov == NULL ||
1053 prov->cp_type == PROV_BADNAME || prov->cp_type == PROV_KEF_HARD) {
1054 /*
1055 * TRANSLATION_NOTE:
1056 * "uninstall" could be either a literal keyword and hence
1057 * not to be translated, or a verb and translatable. A
1058 * choice was made to view it as a literal keyword.
1059 */
1060 cryptoerror(LOG_STDERR,
1061 gettext("bad provider name for %s."), "uninstall");
1062 free(prov);
1063 return (FAILURE);
1064 }
1065
1066 if (prov->cp_type == PROV_UEF_LIB) {
1067 rc = uninstall_uef_lib(prov->cp_name);
1068 } else if (prov->cp_type == PROV_KEF_SOFT) {
1069 if (getzoneid() == GLOBAL_ZONEID) {
1070 rc = uninstall_kef(prov->cp_name);
1071 } else {
1072 /*
1073 * TRANSLATION_NOTE:
1074 * "uninstall" could be either a literal keyword and
1075 * hence not to be translated, or a verb and
1076 * translatable. A choice was made to view it as a
1077 * literal keyword. "global" is keyword and not to
1078 * be translated.
1079 */
1080 cryptoerror(LOG_STDERR, gettext("%1$s for kernel "
1081 "providers is supported in the %2$s zone only"),
1082 "uninstall", "global");
1083 rc = FAILURE;
1084 }
1085 }
1086
1087 free(prov);
1088 return (rc);
1089 }
1090
1091
1092 /*
1093 * The top level function for the unload subcommand.
1105 return (ERROR_USAGE);
1106 }
1107
1108 /* check if it is a kernel software provider */
1109 prov = get_provider(argc, argv);
1110 if (prov == NULL) {
1111 cryptoerror(LOG_STDERR,
1112 gettext("unable to determine provider name."));
1113 goto out;
1114 }
1115 if (prov->cp_type != PROV_KEF_SOFT) {
1116 cryptoerror(LOG_STDERR,
1117 gettext("%s is not a valid kernel software provider."),
1118 prov->cp_name);
1119 rc = FAILURE;
1120 goto out;
1121 }
1122
1123 if (getzoneid() != GLOBAL_ZONEID) {
1124 /*
1125 * TRANSLATION_NOTE:
1126 * "unload" could be either a literal keyword and hence
1127 * not to be translated, or a verb and translatable.
1128 * A choice was made to view it as a literal keyword.
1129 * "global" is keyword and not to be translated.
1130 */
1131 cryptoerror(LOG_STDERR, gettext("%1$s for kernel providers "
1132 "is supported in the %2$s zone only"), "unload", "global");
1133 rc = FAILURE;
1134 goto out;
1135 }
1136
1137 /* Check if it is in the kcf.conf file first */
1138 if ((pent = getent_kef(prov->cp_name)) == NULL) {
1139 cryptoerror(LOG_STDERR,
1140 gettext("provider %s does not exist."), prov->cp_name);
1141 rc = FAILURE;
1142 goto out;
1143 }
1144 free_entry(pent);
1145
1365 uentrylist_t *pliblist;
1366 uentrylist_t *plibptr;
1367 entrylist_t *pdevlist_conf;
1368 entrylist_t *psoftlist_conf;
1369 entrylist_t *pdevlist_zone;
1370 entrylist_t *psoftlist_zone;
1371 entrylist_t *ptr;
1372 mechlist_t *pmechlist;
1373 boolean_t is_active;
1374 char provname[MAXNAMELEN];
1375 char devname[MAXNAMELEN];
1376 int inst_num;
1377 int count;
1378 int i;
1379 int rv;
1380 int rc = SUCCESS;
1381
1382 /* get user-level providers */
1383 (void) printf(gettext("\nUser-level providers:\n"));
1384 /*
1385 * TRANSLATION_NOTE:
1386 * Strictly for appearance's sake, this line should be as long as
1387 * the length of the translated text above.
1388 */
1389 (void) printf(gettext("=====================\n"));
1390 if (get_pkcs11conf_info(&pliblist) != SUCCESS) {
1391 cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1392 "the list of user-level providers.\n"));
1393 rc = FAILURE;
1394 }
1395
1396 plibptr = pliblist;
1397 while (plibptr != NULL) {
1398 /* skip metaslot entry */
1399 if (strcmp(plibptr->puent->name, METASLOT_KEYWORD) != 0) {
1400 (void) printf(gettext("\nProvider: %s\n"),
1401 plibptr->puent->name);
1402 rv = list_mechlist_for_lib(plibptr->puent->name,
1403 mecharglist, NULL, B_FALSE, verbose, B_TRUE);
1404 if (rv == FAILURE) {
1405 rc = FAILURE;
1406 }
1407 }
1408 plibptr = plibptr->next;
1409 }
1410 free_uentrylist(pliblist);
1411
1412 /* get kernel software providers */
1413 (void) printf(gettext("\nKernel software providers:\n"));
1414 /*
1415 * TRANSLATION_NOTE:
1416 * Strictly for appearance's sake, this line should be as long as
1417 * the length of the translated text above.
1418 */
1419 (void) printf(gettext("==========================\n"));
1420 if (getzoneid() == GLOBAL_ZONEID) {
1421 /* use kcf.conf for kernel software providers in global zone */
1422 pdevlist_conf = NULL;
1423 psoftlist_conf = NULL;
1424
1425 if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf) !=
1426 SUCCESS) {
1427 cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1428 "the list of kernel software providers.\n"));
1429 rc = FAILURE;
1430 }
1431
1432 ptr = psoftlist_conf;
1433 while (ptr != NULL) {
1434 if (check_active_for_soft(ptr->pent->name, &is_active)
1435 == SUCCESS) {
1470
1471 ptr = psoftlist_zone;
1472 while (ptr != NULL) {
1473 rv = list_mechlist_for_soft(ptr->pent->name);
1474 if (rv == FAILURE) {
1475 (void) printf(gettext(
1476 "%s: failed to get the mechanism list.\n"),
1477 ptr->pent->name);
1478 rc = FAILURE;
1479 }
1480 ptr = ptr->next;
1481 }
1482
1483 free_entrylist(pdevlist_zone);
1484 free_entrylist(psoftlist_zone);
1485 }
1486
1487 /* Get kernel hardware providers and their mechanism lists */
1488 (void) printf(gettext("\nKernel hardware providers:\n"));
1489 /*
1490 * TRANSLATION_NOTE:
1491 * Strictly for appearance's sake, this line should be as long as
1492 * the length of the translated text above.
1493 */
1494 (void) printf(gettext("==========================\n"));
1495 if (get_dev_list(&pdevlist_kernel) != SUCCESS) {
1496 cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1497 "the list of hardware providers.\n"));
1498 return (FAILURE);
1499 }
1500
1501 for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) {
1502 (void) strlcpy(devname,
1503 pdevlist_kernel->dl_devs[i].le_dev_name, MAXNAMELEN);
1504 inst_num = pdevlist_kernel->dl_devs[i].le_dev_instance;
1505 count = pdevlist_kernel->dl_devs[i].le_mechanism_count;
1506 (void) snprintf(provname, sizeof (provname), "%s/%d", devname,
1507 inst_num);
1508 if (get_dev_info(devname, inst_num, count, &pmechlist) ==
1509 SUCCESS) {
1510 (void) filter_mechlist(&pmechlist, RANDOM);
1525 * List all the providers. And for each provider, list the policy information.
1526 */
1527 static int
1528 list_policy_for_all(void)
1529 {
1530 crypto_get_dev_list_t *pdevlist_kernel;
1531 uentrylist_t *pliblist;
1532 uentrylist_t *plibptr;
1533 entrylist_t *pdevlist_conf;
1534 entrylist_t *psoftlist_conf;
1535 entrylist_t *ptr;
1536 entrylist_t *phead;
1537 boolean_t found;
1538 char provname[MAXNAMELEN];
1539 int i;
1540 int rc = SUCCESS;
1541
1542 /* Get user-level providers */
1543 (void) printf(gettext("\nUser-level providers:\n"));
1544 /*
1545 * TRANSLATION_NOTE:
1546 * Strictly for appearance's sake, this line should be as long as
1547 * the length of the translated text above.
1548 */
1549 (void) printf(gettext("=====================\n"));
1550 if (get_pkcs11conf_info(&pliblist) == FAILURE) {
1551 cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1552 "the list of user-level providers.\n"));
1553 } else {
1554 plibptr = pliblist;
1555 while (plibptr != NULL) {
1556 /* skip metaslot entry */
1557 if (strcmp(plibptr->puent->name,
1558 METASLOT_KEYWORD) != 0) {
1559 if (print_uef_policy(plibptr->puent)
1560 == FAILURE) {
1561 rc = FAILURE;
1562 }
1563 }
1564 plibptr = plibptr->next;
1565 }
1566 free_uentrylist(pliblist);
1567 }
1568
1569 /* kernel software providers */
1570 (void) printf(gettext("\nKernel software providers:\n"));
1571 /*
1572 * TRANSLATION_NOTE:
1573 * Strictly for appearance's sake, this line should be as long as
1574 * the length of the translated text above.
1575 */
1576 (void) printf(gettext("==========================\n"));
1577
1578 /* Get all entries from the kcf.conf file */
1579 pdevlist_conf = NULL;
1580 if (getzoneid() == GLOBAL_ZONEID) {
1581 /* use kcf.conf for kernel software providers in global zone */
1582 psoftlist_conf = NULL;
1583
1584 if (get_kcfconf_info(&pdevlist_conf, &psoftlist_conf) ==
1585 FAILURE) {
1586 cryptoerror(LOG_STDERR, gettext(
1587 "failed to retrieve the list of kernel "
1588 "providers.\n"));
1589 return (FAILURE);
1590 }
1591
1592 ptr = psoftlist_conf;
1593 while (ptr != NULL) {
1594 (void) list_policy_for_soft(ptr->pent->name);
1595 ptr = ptr->next;
1596 }
1597
1598 free_entrylist(psoftlist_conf);
1599 } else {
1600 /* kcf.conf not there in non-global zone, no policy info */
1601
1602 /*
1603 * TRANSLATION_NOTE:
1604 * "global" is keyword and not to be translated.
1605 */
1606 cryptoerror(LOG_STDERR, gettext(
1607 "policy information for kernel software providers is "
1608 "available in the %s zone only"), "global");
1609 }
1610
1611 /* Kernel hardware providers */
1612 (void) printf(gettext("\nKernel hardware providers:\n"));
1613 /*
1614 * TRANSLATION_NOTE:
1615 * Strictly for appearance's sake, this line should be as long as
1616 * the length of the translated text above.
1617 */
1618 (void) printf(gettext("==========================\n"));
1619
1620 if (getzoneid() != GLOBAL_ZONEID) {
1621 /*
1622 * TRANSLATION_NOTE:
1623 * "global" is keyword and not to be translated.
1624 */
1625 cryptoerror(LOG_STDERR, gettext(
1626 "policy information for kernel hardware providers is "
1627 "available in the %s zone only"), "global");
1628 return (FAILURE);
1629 }
1630
1631 /* Get the hardware provider list from kernel */
1632 if (get_dev_list(&pdevlist_kernel) != SUCCESS) {
1633 cryptoerror(LOG_STDERR, gettext(
1634 "failed to retrieve the list of hardware providers.\n"));
1635 free_entrylist(pdevlist_conf);
1636 return (FAILURE);
1637 }
1638
1639 /*
1640 * For each hardware provider from kernel, check if it has an entry
1641 * in the config file. If it has an entry, print out the policy from
1642 * config file and remove the entry from the hardware provider list
|
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 **);
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",
234 (void) fprintf(stderr,
235 " cryptoadm uninstall provider=<%s>\n",
236 gettext("provider-name"));
237 (void) fprintf(stderr,
238 " cryptoadm unload provider=<%s>\n",
239 gettext("provider-name"));
240 (void) fprintf(stderr,
241 " cryptoadm refresh\n"
242 " cryptoadm start\n"
243 " cryptoadm stop\n"
244 " cryptoadm --help\n");
245 }
246
247
248 /*
249 * Get the provider type. This function returns
250 * - PROV_UEF_LIB if provname contains an absolute path name
251 * - PROV_KEF_SOFT if provname is a base name only
252 * - PROV_KEF_HARD if provname contains one slash only and the slash is not
253 * the 1st character.
254 * - PROV_BADNAME otherwise.
255 */
256 static int
257 get_provider_type(char *provname)
258 {
259 char *pslash1;
260 char *pslash2;
261
262 if (provname == NULL) {
263 return (FAILURE);
264 }
265
266 if (provname[0] == '/') {
267 return (PROV_UEF_LIB);
268 } else if ((pslash1 = strchr(provname, SEP_SLASH)) == NULL) {
269 /* no slash */
270 return (PROV_KEF_SOFT);
271 } else {
272 pslash2 = strrchr(provname, SEP_SLASH);
273 if (pslash1 == pslash2) {
274 return (PROV_KEF_HARD);
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);
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, ",");
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 }
760 case METASLOT:
761 rc = disable_metaslot(mecharglist, allflag,
762 auto_key_migrate_flag);
763 break;
764 case PROV_UEF_LIB:
765 rc = disable_uef_lib(prov->cp_name, rndflag, allflag,
766 mecharglist);
767 break;
768 case PROV_KEF_SOFT:
769 if (rndflag && !allflag) {
770 if ((mecharglist = create_mech(RANDOM)) == NULL) {
771 rc = FAILURE;
772 break;
773 }
774 }
775 if (getzoneid() == GLOBAL_ZONEID) {
776 rc = disable_kef_software(prov->cp_name, rndflag,
777 allflag, mecharglist);
778 } else {
779 /*
780 * TRANSLATION_NOTE
781 * "disable" could be either a literal keyword
782 * and hence not to be translated, or a verb and
783 * translatable. A choice was made to view it as
784 * a literal keyword. "global" is keyword and not
785 * to be translated.
786 */
787 cryptoerror(LOG_STDERR, gettext("%1$s for kernel "
788 "providers is supported in the %2$s zone only"),
789 "disable", "global");
790 rc = FAILURE;
791 }
792 break;
793 case PROV_KEF_HARD:
794 if (rndflag && !allflag) {
795 if ((mecharglist = create_mech(RANDOM)) == NULL) {
796 rc = FAILURE;
797 break;
798 }
799 }
800 if (getzoneid() == GLOBAL_ZONEID) {
801 rc = disable_kef_hardware(prov->cp_name, rndflag,
802 allflag, mecharglist);
803 } else {
804 /*
805 * TRANSLATION_NOTE
806 * "disable" could be either a literal keyword
807 * and hence not to be translated, or a verb and
808 * translatable. A choice was made to view it as
809 * a literal keyword. "global" is keyword and not
810 * to be translated.
811 */
812 cryptoerror(LOG_STDERR, gettext("%1$s for kernel "
813 "providers is supported in the %2$s zone only"),
814 "disable", "global");
815 rc = FAILURE;
816 }
817 break;
818 default: /* should not come here */
819 rc = FAILURE;
820 break;
821 }
822
823 out:
824 free(prov);
825 if (mecharglist != NULL) {
893 rc = enable_metaslot(alt_token, alt_slot, use_default,
894 mecharglist, allflag, auto_key_migrate_flag);
895 break;
896 case PROV_UEF_LIB:
897 rc = enable_uef_lib(prov->cp_name, rndflag, allflag,
898 mecharglist);
899 break;
900 case PROV_KEF_SOFT:
901 case PROV_KEF_HARD:
902 if (rndflag && !allflag) {
903 if ((mecharglist = create_mech(RANDOM)) == NULL) {
904 rc = FAILURE;
905 break;
906 }
907 }
908 if (getzoneid() == GLOBAL_ZONEID) {
909 rc = enable_kef(prov->cp_name, rndflag, allflag,
910 mecharglist);
911 } else {
912 /*
913 * TRANSLATION_NOTE
914 * "enable" could be either a literal keyword
915 * and hence not to be translated, or a verb and
916 * translatable. A choice was made to view it as
917 * a literal keyword. "global" is keyword and not
918 * to be translated.
919 */
920 cryptoerror(LOG_STDERR, gettext("%1$s for kernel "
921 "providers is supported in the %2$s zone only"),
922 "enable", "global");
923 rc = FAILURE;
924 }
925 break;
926 default: /* should not come here */
927 rc = FAILURE;
928 break;
929 }
930 out:
931 free(prov);
932 if (mecharglist != NULL) {
933 free_mechlist(mecharglist);
944
945
946 /*
947 * The top level function fo the install subcommand.
948 */
949 static int
950 do_install(int argc, char **argv)
951 {
952 cryptoadm_provider_t *prov = NULL;
953 int rc;
954
955 if (argc < 3) {
956 usage();
957 return (ERROR_USAGE);
958 }
959
960 prov = get_provider(argc, argv);
961 if (prov == NULL ||
962 prov->cp_type == PROV_BADNAME || prov->cp_type == PROV_KEF_HARD) {
963 /*
964 * TRANSLATION_NOTE
965 * "install" could be either a literal keyword and hence
966 * not to be translated, or a verb and translatable. A
967 * choice was made to view it as a literal keyword.
968 */
969 cryptoerror(LOG_STDERR,
970 gettext("bad provider name for %s."), "install");
971 rc = FAILURE;
972 goto out;
973 }
974
975 if (prov->cp_type == PROV_UEF_LIB) {
976 rc = install_uef_lib(prov->cp_name);
977 goto out;
978 }
979
980 /* It is the PROV_KEF_SOFT type now */
981
982 /* check if there are mechanism operands */
983 if (argc < 4) {
984 /*
985 * TRANSLATION_NOTE
986 * "mechanism" could be either a literal keyword and hence
987 * not to be translated, or a descriptive word and
988 * translatable. A choice was made to view it as a literal
989 * keyword.
990 */
991 cryptoerror(LOG_STDERR,
992 gettext("need %s operands for installing a"
993 " kernel software provider."), "mechanism");
994 rc = ERROR_USAGE;
995 goto out;
996 }
997
998 if ((rc = process_mech_operands(argc, argv, B_FALSE)) != SUCCESS) {
999 goto out;
1000 }
1001
1002 if (allflag == B_TRUE) {
1003 /*
1004 * TRANSLATION_NOTE
1005 * "all", "mechanism", and "install" are all keywords and
1006 * not to be translated.
1007 */
1008 cryptoerror(LOG_STDERR,
1009 gettext("can not use the %1$s keyword for %2$s "
1010 "in the %3$s subcommand."), "all", "mechanism", "install");
1011 rc = ERROR_USAGE;
1012 goto out;
1013 }
1014
1015 if (getzoneid() == GLOBAL_ZONEID) {
1016 rc = install_kef(prov->cp_name, mecharglist);
1017 } else {
1018 /*
1019 * TRANSLATION_NOTE
1020 * "install" could be either a literal keyword and hence
1021 * not to be translated, or a verb and translatable. A
1022 * choice was made to view it as a literal keyword.
1023 * "global" is keyword and not to be translated.
1024 */
1025 cryptoerror(LOG_STDERR, gettext("%1$s for kernel providers "
1026 "is supported in the %2$s zone only"), "install", "global");
1027 rc = FAILURE;
1028 }
1029 out:
1030 free(prov);
1031 return (rc);
1032 }
1033
1034
1035
1036 /*
1037 * The top level function for the uninstall subcommand.
1038 */
1039 static int
1040 do_uninstall(int argc, char **argv)
1041 {
1042 cryptoadm_provider_t *prov = NULL;
1043 int rc = SUCCESS;
1044
1045 if (argc != 3) {
1046 usage();
1047 return (ERROR_USAGE);
1048 }
1049
1050 prov = get_provider(argc, argv);
1051 if (prov == NULL ||
1052 prov->cp_type == PROV_BADNAME || prov->cp_type == PROV_KEF_HARD) {
1053 /*
1054 * TRANSLATION_NOTE
1055 * "uninstall" could be either a literal keyword and hence
1056 * not to be translated, or a verb and translatable. A
1057 * choice was made to view it as a literal keyword.
1058 */
1059 cryptoerror(LOG_STDERR,
1060 gettext("bad provider name for %s."), "uninstall");
1061 free(prov);
1062 return (FAILURE);
1063 }
1064
1065 if (prov->cp_type == PROV_UEF_LIB) {
1066 rc = uninstall_uef_lib(prov->cp_name);
1067 } else if (prov->cp_type == PROV_KEF_SOFT) {
1068 if (getzoneid() == GLOBAL_ZONEID) {
1069 rc = uninstall_kef(prov->cp_name);
1070 } else {
1071 /*
1072 * TRANSLATION_NOTE
1073 * "uninstall" could be either a literal keyword and
1074 * hence not to be translated, or a verb and
1075 * translatable. A choice was made to view it as a
1076 * literal keyword. "global" is keyword and not to
1077 * be translated.
1078 */
1079 cryptoerror(LOG_STDERR, gettext("%1$s for kernel "
1080 "providers is supported in the %2$s zone only"),
1081 "uninstall", "global");
1082 rc = FAILURE;
1083 }
1084 }
1085
1086 free(prov);
1087 return (rc);
1088 }
1089
1090
1091 /*
1092 * The top level function for the unload subcommand.
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
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) {
1469
1470 ptr = psoftlist_zone;
1471 while (ptr != NULL) {
1472 rv = list_mechlist_for_soft(ptr->pent->name);
1473 if (rv == FAILURE) {
1474 (void) printf(gettext(
1475 "%s: failed to get the mechanism list.\n"),
1476 ptr->pent->name);
1477 rc = FAILURE;
1478 }
1479 ptr = ptr->next;
1480 }
1481
1482 free_entrylist(pdevlist_zone);
1483 free_entrylist(psoftlist_zone);
1484 }
1485
1486 /* Get kernel hardware providers and their mechanism lists */
1487 (void) printf(gettext("\nKernel hardware providers:\n"));
1488 /*
1489 * TRANSLATION_NOTE
1490 * Strictly for appearance's sake, this line should be as long as
1491 * the length of the translated text above.
1492 */
1493 (void) printf(gettext("==========================\n"));
1494 if (get_dev_list(&pdevlist_kernel) != SUCCESS) {
1495 cryptoerror(LOG_STDERR, gettext("failed to retrieve "
1496 "the list of hardware providers.\n"));
1497 return (FAILURE);
1498 }
1499
1500 for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) {
1501 (void) strlcpy(devname,
1502 pdevlist_kernel->dl_devs[i].le_dev_name, MAXNAMELEN);
1503 inst_num = pdevlist_kernel->dl_devs[i].le_dev_instance;
1504 count = pdevlist_kernel->dl_devs[i].le_mechanism_count;
1505 (void) snprintf(provname, sizeof (provname), "%s/%d", devname,
1506 inst_num);
1507 if (get_dev_info(devname, inst_num, count, &pmechlist) ==
1508 SUCCESS) {
1509 (void) filter_mechlist(&pmechlist, RANDOM);
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
|