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