Print this page
6621176 $SRC/cmd/cmd-crypto/cryptoadm/*.c seem to have syntax errors in the translation notes
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/cmd-crypto/cryptoadm/adm_kef.c
+++ new/usr/src/cmd/cmd-crypto/cryptoadm/adm_kef.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.
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
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.
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 - * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22 + * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 -#pragma ident "%Z%%M% %I% %E% SMI"
27 -
28 26 #include <fcntl.h>
29 27 #include <stdio.h>
30 28 #include <stdlib.h>
31 29 #include <strings.h>
32 30 #include <unistd.h>
33 31 #include <locale.h>
34 32 #include <libgen.h>
35 33 #include <sys/types.h>
36 34 #include <sys/stat.h>
37 35 #include <sys/crypto/ioctladmin.h>
38 36 #include <signal.h>
39 37 #include <sys/crypto/elfsign.h>
40 38 #include "cryptoadm.h"
41 39
42 40 static int err; /* to store the value of errno in case being overwritten */
43 41 static int check_hardware_provider(char *, char *, int *, int *);
44 42
45 43 /*
46 44 * Display the mechanism list for a kernel software provider.
47 45 */
48 46 int
49 47 list_mechlist_for_soft(char *provname)
50 48 {
51 49 mechlist_t *pmechlist;
52 50 int rc;
53 51
54 52 if (provname == NULL) {
55 53 return (FAILURE);
56 54 }
57 55
58 56 rc = get_soft_info(provname, &pmechlist);
59 57 if (rc == SUCCESS) {
60 58 (void) filter_mechlist(&pmechlist, RANDOM);
61 59 print_mechlist(provname, pmechlist);
62 60 free_mechlist(pmechlist);
63 61 } else {
64 62 cryptoerror(LOG_STDERR, gettext(
65 63 "failed to retrieve the mechanism list for %s."),
66 64 provname);
67 65 }
68 66
69 67 return (rc);
70 68
71 69 }
72 70
73 71 /*
74 72 * Display the mechanism list for a kernel hardware provider.
75 73 */
76 74 int
77 75 list_mechlist_for_hard(char *provname)
78 76 {
79 77 mechlist_t *pmechlist;
80 78 char devname[MAXNAMELEN];
81 79 int inst_num;
82 80 int count;
83 81 int rc = SUCCESS;
84 82
85 83 if (provname == NULL) {
86 84 return (FAILURE);
87 85 }
88 86
89 87 /*
90 88 * Check if the provider is valid. If it is valid, get the number of
91 89 * mechanisms also.
92 90 */
93 91 if (check_hardware_provider(provname, devname, &inst_num, &count) ==
94 92 FAILURE) {
95 93 return (FAILURE);
96 94 }
97 95
98 96 /* Get the mechanism list for the kernel hardware provider */
99 97 if ((rc = get_dev_info(devname, inst_num, count, &pmechlist)) ==
100 98 SUCCESS) {
101 99 (void) filter_mechlist(&pmechlist, RANDOM);
102 100 print_mechlist(provname, pmechlist);
103 101 free_mechlist(pmechlist);
104 102 }
105 103
106 104 return (rc);
107 105 }
108 106
109 107
110 108 /*
111 109 * Display the policy information for a kernel software provider.
112 110 */
113 111 int
114 112 list_policy_for_soft(char *provname)
115 113 {
116 114 int rc;
117 115 entry_t *pent = NULL;
118 116 mechlist_t *pmechlist;
119 117 boolean_t has_random = B_FALSE;
120 118 boolean_t has_mechs = B_FALSE;
121 119
122 120 if (provname == NULL) {
123 121 return (FAILURE);
124 122 }
125 123
126 124 if ((pent = getent_kef(provname)) == NULL) {
127 125 cryptoerror(LOG_STDERR, gettext("%s does not exist."),
128 126 provname);
129 127 return (FAILURE);
130 128 }
131 129
132 130 rc = get_soft_info(provname, &pmechlist);
133 131 if (rc == SUCCESS) {
134 132 has_random = filter_mechlist(&pmechlist, RANDOM);
135 133 if (pmechlist != NULL) {
136 134 has_mechs = B_TRUE;
137 135 free_mechlist(pmechlist);
138 136 }
139 137 } else {
140 138 cryptoerror(LOG_STDERR, gettext(
141 139 "failed to retrieve the mechanism list for %s."),
142 140 provname);
143 141 return (rc);
144 142 }
145 143
146 144 print_kef_policy(pent, has_random, has_mechs);
147 145 free_entry(pent);
148 146 return (SUCCESS);
149 147 }
150 148
151 149
152 150
153 151 /*
154 152 * Display the policy information for a kernel hardware provider.
155 153 */
156 154 int
157 155 list_policy_for_hard(char *provname)
158 156 {
159 157 entry_t *pent;
160 158 boolean_t is_active;
161 159 mechlist_t *pmechlist;
162 160 char devname[MAXNAMELEN];
163 161 int inst_num;
164 162 int count;
165 163 int rc = SUCCESS;
166 164 boolean_t has_random = B_FALSE;
167 165 boolean_t has_mechs = B_FALSE;
168 166
169 167 if (provname == NULL) {
170 168 return (FAILURE);
171 169 }
172 170
173 171 /*
174 172 * Check if the provider is valid. If it is valid, get the number of
175 173 * mechanisms also.
176 174 */
177 175 if (check_hardware_provider(provname, devname, &inst_num, &count) ==
178 176 FAILURE) {
179 177 return (FAILURE);
180 178 }
181 179
182 180 /* Get the mechanism list for the kernel hardware provider */
183 181 if ((rc = get_dev_info(devname, inst_num, count, &pmechlist)) ==
184 182 SUCCESS) {
185 183 has_random = filter_mechlist(&pmechlist, RANDOM);
186 184
187 185 if (pmechlist != NULL) {
188 186 has_mechs = B_TRUE;
189 187 free_mechlist(pmechlist);
190 188 }
191 189 } else {
192 190 cryptoerror(LOG_STDERR, gettext(
193 191 "failed to retrieve the mechanism list for %s."),
194 192 devname);
195 193 return (rc);
196 194 }
197 195
198 196 /*
199 197 * If the hardware provider has an entry in the kcf.conf file,
200 198 * some of its mechanisms must have been disabled. Print out
201 199 * the disabled list from the config file entry. Otherwise,
202 200 * if it is active, then all the mechanisms for it are enabled.
203 201 */
204 202 if ((pent = getent_kef(provname)) != NULL) {
205 203 print_kef_policy(pent, has_random, has_mechs);
206 204 free_entry(pent);
↓ open down ↓ |
169 lines elided |
↑ open up ↑ |
207 205 return (SUCCESS);
208 206 } else {
209 207 if (check_active_for_hard(provname, &is_active) ==
210 208 FAILURE) {
211 209 return (FAILURE);
212 210 } else if (is_active == B_TRUE) {
213 211 (void) printf(gettext(
214 212 "%s: all mechanisms are enabled."), provname);
215 213 if (has_random)
216 214 /*
217 - * TRANSLATION_NOTE:
215 + * TRANSLATION_NOTE
218 216 * "random" is a keyword and not to be
219 217 * translated.
220 218 */
221 219 (void) printf(gettext(" %s is enabled.\n"),
222 220 "random");
223 221 else
224 222 (void) printf("\n");
225 223 return (SUCCESS);
226 224 } else {
227 225 cryptoerror(LOG_STDERR,
228 226 gettext("%s does not exist."), provname);
229 227 return (FAILURE);
230 228 }
231 229 }
232 230 }
233 231
234 232
235 233
236 234 int
237 235 disable_kef_hardware(char *provname, boolean_t rndflag, boolean_t allflag,
238 236 mechlist_t *dislist)
239 237 {
240 238 crypto_load_dev_disabled_t *pload_dev_dis;
241 239 mechlist_t *infolist;
242 240 entry_t *pent;
243 241 boolean_t new_dev_entry = B_FALSE;
244 242 char devname[MAXNAMELEN];
245 243 int inst_num;
246 244 int count;
247 245 int fd;
248 246 int rc = SUCCESS;
249 247
250 248 if (provname == NULL) {
251 249 return (FAILURE);
252 250 }
253 251
254 252 /*
255 253 * Check if the provider is valid. If it is valid, get the number of
256 254 * mechanisms also.
257 255 */
258 256 if (check_hardware_provider(provname, devname, &inst_num, &count)
259 257 == FAILURE) {
260 258 return (FAILURE);
261 259 }
262 260
263 261 /* Get the mechanism list for the kernel hardware provider */
264 262 if (get_dev_info(devname, inst_num, count, &infolist) == FAILURE) {
265 263 return (FAILURE);
266 264 }
267 265
268 266 /*
269 267 * Get the entry of this hardware provider from the config file.
270 268 * If there is no entry yet, create one for it.
271 269 */
272 270 if ((pent = getent_kef(provname)) == NULL) {
273 271 if ((pent = malloc(sizeof (entry_t))) == NULL) {
274 272 cryptoerror(LOG_STDERR, gettext("out of memory."));
275 273 free_mechlist(infolist);
276 274 return (FAILURE);
277 275 }
278 276 new_dev_entry = B_TRUE;
279 277 (void) strlcpy(pent->name, provname, MAXNAMELEN);
280 278 pent->suplist = NULL;
281 279 pent->sup_count = 0;
282 280 pent->dislist = NULL;
283 281 pent->dis_count = 0;
284 282 }
285 283
286 284 /*
287 285 * kCF treats random as an internal mechanism. So, we need to
288 286 * filter it from the mechanism list here, if we are NOT disabling
289 287 * or enabling the random feature. Note that we map random feature at
290 288 * cryptoadm(1M) level to the "random" mechanism in kCF.
291 289 */
292 290 if (!rndflag) {
293 291 (void) filter_mechlist(&dislist, RANDOM);
294 292 }
295 293
296 294 /* Calculate the new disabled list */
297 295 if (disable_mechs(&pent, infolist, allflag, dislist) == FAILURE) {
298 296 free_mechlist(infolist);
299 297 free_entry(pent);
300 298 return (FAILURE);
301 299 }
302 300 free_mechlist(infolist);
303 301
304 302 /* If no mechanisms are to be disabled, return */
305 303 if (pent->dis_count == 0) {
306 304 free_entry(pent);
307 305 return (SUCCESS);
308 306 }
309 307
310 308 /* Update the config file with the new entry or the updated entry */
311 309 if (new_dev_entry) {
312 310 rc = update_kcfconf(pent, ADD_MODE);
313 311 } else {
314 312 rc = update_kcfconf(pent, MODIFY_MODE);
315 313 }
316 314
317 315 if (rc == FAILURE) {
318 316 free_entry(pent);
319 317 return (FAILURE);
320 318 }
321 319
322 320 /* Inform kernel about the new disabled mechanism list */
323 321 if ((pload_dev_dis = setup_dev_dis(pent)) == NULL) {
324 322 free_entry(pent);
325 323 return (FAILURE);
326 324 }
327 325 free_entry(pent);
328 326
329 327 if ((fd = open(ADMIN_IOCTL_DEVICE, O_RDWR)) == -1) {
330 328 cryptoerror(LOG_STDERR, gettext("failed to open %s: %s"),
331 329 ADMIN_IOCTL_DEVICE, strerror(errno));
332 330 free(pload_dev_dis);
333 331 return (FAILURE);
334 332 }
335 333
336 334 if (ioctl(fd, CRYPTO_LOAD_DEV_DISABLED, pload_dev_dis) == -1) {
337 335 cryptodebug("CRYPTO_LOAD_DEV_DISABLED ioctl failed: %s",
338 336 strerror(errno));
339 337 free(pload_dev_dis);
340 338 (void) close(fd);
341 339 return (FAILURE);
342 340 }
343 341
344 342 if (pload_dev_dis->dd_return_value != CRYPTO_SUCCESS) {
345 343 cryptodebug("CRYPTO_LOAD_DEV_DISABLED ioctl return_value = "
346 344 "%d", pload_dev_dis->dd_return_value);
347 345 free(pload_dev_dis);
348 346 (void) close(fd);
349 347 return (FAILURE);
350 348 }
351 349
352 350 free(pload_dev_dis);
353 351 (void) close(fd);
354 352 return (SUCCESS);
355 353 }
356 354
357 355
358 356
359 357 int
360 358 disable_kef_software(char *provname, boolean_t rndflag, boolean_t allflag,
361 359 mechlist_t *dislist)
362 360 {
363 361 crypto_load_soft_disabled_t *pload_soft_dis = NULL;
364 362 mechlist_t *infolist;
365 363 entry_t *pent;
366 364 boolean_t is_active;
367 365 int fd;
368 366
369 367 if (provname == NULL) {
370 368 return (FAILURE);
371 369 }
372 370
373 371 /* Get the entry of this provider from the config file. */
374 372 if ((pent = getent_kef(provname)) == NULL) {
375 373 cryptoerror(LOG_STDERR,
376 374 gettext("%s does not exist."), provname);
377 375 return (FAILURE);
378 376 }
379 377
↓ open down ↓ |
152 lines elided |
↑ open up ↑ |
380 378 /*
381 379 * Check if the kernel software provider is currently unloaded.
382 380 * If it is unloaded, return FAILURE, because the disable subcommand
383 381 * can not perform on inactive (unloaded) providers.
384 382 */
385 383 if (check_active_for_soft(provname, &is_active) == FAILURE) {
386 384 free_entry(pent);
387 385 return (FAILURE);
388 386 } else if (is_active == B_FALSE) {
389 387 /*
390 - * TRANSLATION_NOTE:
388 + * TRANSLATION_NOTE
391 389 * "disable" is a keyword and not to be translated.
392 390 */
393 391 cryptoerror(LOG_STDERR,
394 392 gettext("can not do %1$s on an unloaded "
395 393 "kernel software provider -- %2$s."), "disable", provname);
396 394 free_entry(pent);
397 395 return (FAILURE);
398 396 }
399 397
400 398 /* Get the mechanism list for the software provider */
401 399 if (get_soft_info(provname, &infolist) == FAILURE) {
402 400 free(pent);
403 401 return (FAILURE);
404 402 }
405 403
406 404 /* See comments in disable_kef_hardware() */
407 405 if (!rndflag) {
408 406 (void) filter_mechlist(&infolist, RANDOM);
409 407 }
410 408
411 409 /* Calculate the new disabled list */
412 410 if (disable_mechs(&pent, infolist, allflag, dislist) == FAILURE) {
413 411 free_entry(pent);
414 412 free_mechlist(infolist);
415 413 return (FAILURE);
416 414 }
417 415
418 416 /* infolist is no longer needed; free it */
419 417 free_mechlist(infolist);
420 418
421 419 /* Update the kcf.conf file with the updated entry */
422 420 if (update_kcfconf(pent, MODIFY_MODE) == FAILURE) {
423 421 free_entry(pent);
424 422 return (FAILURE);
425 423 }
426 424
427 425 /* Inform kernel about the new disabled list. */
428 426 if ((pload_soft_dis = setup_soft_dis(pent)) == NULL) {
429 427 free_entry(pent);
430 428 return (FAILURE);
431 429 }
432 430
433 431 /* pent is no longer needed; free it. */
434 432 free_entry(pent);
435 433
436 434 if ((fd = open(ADMIN_IOCTL_DEVICE, O_RDWR)) == -1) {
437 435 cryptoerror(LOG_STDERR,
438 436 gettext("failed to open %s for RW: %s"),
439 437 ADMIN_IOCTL_DEVICE, strerror(errno));
440 438 free(pload_soft_dis);
441 439 return (FAILURE);
442 440 }
443 441
444 442 if (ioctl(fd, CRYPTO_LOAD_SOFT_DISABLED, pload_soft_dis) == -1) {
445 443 cryptodebug("CRYPTO_LOAD_SOFT_DISABLED ioctl failed: %s",
446 444 strerror(errno));
447 445 free(pload_soft_dis);
448 446 (void) close(fd);
449 447 return (FAILURE);
450 448 }
451 449
452 450 if (pload_soft_dis->sd_return_value != CRYPTO_SUCCESS) {
453 451 cryptodebug("CRYPTO_LOAD_SOFT_DISABLED ioctl return_value = "
454 452 "%d", pload_soft_dis->sd_return_value);
455 453 free(pload_soft_dis);
456 454 (void) close(fd);
457 455 return (FAILURE);
458 456 }
459 457
460 458 free(pload_soft_dis);
461 459 (void) close(fd);
462 460 return (SUCCESS);
463 461 }
464 462
465 463
466 464 int
467 465 enable_kef(char *provname, boolean_t rndflag, boolean_t allflag,
468 466 mechlist_t *mlist)
469 467 {
470 468 crypto_load_soft_disabled_t *pload_soft_dis = NULL;
471 469 crypto_load_dev_disabled_t *pload_dev_dis = NULL;
472 470 entry_t *pent;
473 471 boolean_t redo_flag = B_FALSE;
474 472 int fd;
475 473 int rc = SUCCESS;
476 474
477 475
478 476 /* Get the entry with the provider name from the kcf.conf file */
479 477 pent = getent_kef(provname);
480 478
481 479 if (is_device(provname)) {
482 480 if (pent == NULL) {
483 481 /*
484 482 * This device doesn't have an entry in the config
485 483 * file, therefore nothing is disabled.
486 484 */
487 485 cryptoerror(LOG_STDERR, gettext(
488 486 "all mechanisms are enabled already for %s."),
489 487 provname);
490 488 return (SUCCESS);
491 489 }
492 490 } else { /* a software module */
493 491 if (pent == NULL) {
494 492 cryptoerror(LOG_STDERR,
495 493 gettext("%s does not exist."), provname);
496 494 return (FAILURE);
497 495 } else if (pent->dis_count == 0) {
498 496 /* nothing to be enabled. */
499 497 cryptoerror(LOG_STDERR, gettext(
500 498 "all mechanisms are enabled already for %s."),
501 499 provname);
502 500 free_entry(pent);
503 501 return (SUCCESS);
504 502 }
505 503 }
506 504
507 505 if (!rndflag) {
508 506 /* See comments in disable_kef_hardware() */
509 507 redo_flag = filter_mechlist(&pent->dislist, RANDOM);
510 508 if (redo_flag)
511 509 pent->dis_count--;
512 510 }
513 511
514 512 /* Update the entry by enabling mechanisms for this provider */
515 513 if ((rc = enable_mechs(&pent, allflag, mlist)) != SUCCESS) {
516 514 free_entry(pent);
517 515 return (rc);
518 516 }
519 517
520 518 if (redo_flag) {
521 519 mechlist_t *tmp;
522 520
523 521 if ((tmp = create_mech(RANDOM)) == NULL) {
524 522 free_entry(pent);
525 523 return (FAILURE);
526 524 }
527 525 tmp->next = pent->dislist;
528 526 pent->dislist = tmp;
529 527 pent->dis_count++;
530 528 }
531 529
532 530 /*
533 531 * Update the kcf.conf file with the updated entry.
534 532 * For a hardware provider, if there is no more disabled mechanism,
535 533 * the entire entry in the config file should be removed.
536 534 */
537 535 if (is_device(pent->name) && (pent->dis_count == 0)) {
538 536 rc = update_kcfconf(pent, DELETE_MODE);
539 537 } else {
540 538 rc = update_kcfconf(pent, MODIFY_MODE);
541 539 }
542 540
543 541 if (rc == FAILURE) {
544 542 free_entry(pent);
545 543 return (FAILURE);
546 544 }
547 545
548 546
549 547 /* Inform Kernel about the policy change */
550 548
551 549 if ((fd = open(ADMIN_IOCTL_DEVICE, O_RDWR)) == -1) {
552 550 cryptoerror(LOG_STDERR, gettext("failed to open %s: %s"),
553 551 ADMIN_IOCTL_DEVICE, strerror(errno));
554 552 return (FAILURE);
555 553 }
556 554
557 555 if (is_device(provname)) {
558 556 /* LOAD_DEV_DISABLED */
559 557 if ((pload_dev_dis = setup_dev_dis(pent)) == NULL) {
560 558 return (FAILURE);
561 559 }
562 560
563 561 if (ioctl(fd, CRYPTO_LOAD_DEV_DISABLED, pload_dev_dis) == -1) {
564 562 cryptodebug("CRYPTO_LOAD_DEV_DISABLED ioctl failed: "
565 563 "%s", strerror(errno));
566 564 free(pload_dev_dis);
567 565 (void) close(fd);
568 566 return (FAILURE);
569 567 }
570 568
571 569 if (pload_dev_dis->dd_return_value != CRYPTO_SUCCESS) {
572 570 cryptodebug("CRYPTO_LOAD_DEV_DISABLED ioctl "
573 571 "return_value = %d",
574 572 pload_dev_dis->dd_return_value);
575 573 free(pload_dev_dis);
576 574 (void) close(fd);
577 575 return (FAILURE);
578 576 }
579 577
580 578 } else {
581 579 /* LOAD_SOFT_DISABLED */
582 580 if ((pload_soft_dis = setup_soft_dis(pent)) == NULL) {
583 581 return (FAILURE);
584 582 }
585 583
586 584 if (ioctl(fd, CRYPTO_LOAD_SOFT_DISABLED, pload_soft_dis)
587 585 == -1) {
588 586 cryptodebug("CRYPTO_LOAD_SOFT_DISABLED ioctl failed: "
589 587 "%s", strerror(errno));
590 588 free(pload_soft_dis);
591 589 (void) close(fd);
592 590 return (FAILURE);
593 591 }
594 592
595 593 if (pload_soft_dis->sd_return_value != CRYPTO_SUCCESS) {
596 594 cryptodebug("CRYPTO_LOAD_SOFT_DISABLED ioctl "
597 595 "return_value = %d",
598 596 pload_soft_dis->sd_return_value);
599 597 free(pload_soft_dis);
600 598 (void) close(fd);
601 599 return (FAILURE);
602 600 }
603 601 }
604 602
605 603 (void) close(fd);
606 604 return (SUCCESS);
607 605 }
608 606
609 607
610 608 /*
611 609 * Install a software module with the specified mechanism list into the system.
612 610 * This routine adds an entry into the config file for this software module
613 611 * first, then makes a CRYPTO_LOAD_SOFT_CONFIG ioctl call to inform kernel
614 612 * about the new addition.
615 613 */
616 614 int
617 615 install_kef(char *provname, mechlist_t *mlist)
618 616 {
619 617 crypto_load_soft_config_t *pload_soft_conf = NULL;
620 618 boolean_t found;
621 619 entry_t *pent;
622 620 FILE *pfile;
623 621 FILE *pfile_tmp;
624 622 char tmpfile_name[MAXPATHLEN];
625 623 char *ptr;
626 624 char *str;
627 625 char *name;
628 626 char buffer[BUFSIZ];
629 627 char buffer2[BUFSIZ];
630 628 int found_count;
631 629 int fd;
632 630 int rc = SUCCESS;
633 631
634 632 if ((provname == NULL) || (mlist == NULL)) {
635 633 return (FAILURE);
636 634 }
637 635
638 636 /* Check if the provider already exists */
639 637 if ((pent = getent_kef(provname)) != NULL) {
640 638 cryptoerror(LOG_STDERR, gettext("%s exists already."),
641 639 provname);
642 640 free_entry(pent);
643 641 return (FAILURE);
644 642 }
645 643
646 644 /* Create an entry with provname and mlist. */
647 645 if ((pent = malloc(sizeof (entry_t))) == NULL) {
648 646 cryptoerror(LOG_STDERR, gettext("out of memory."));
649 647 return (FAILURE);
650 648 }
651 649
652 650 (void) strlcpy(pent->name, provname, MAXNAMELEN);
653 651 pent->sup_count = get_mech_count(mlist);
654 652 pent->suplist = mlist;
655 653 pent->dis_count = 0;
656 654 pent->dislist = NULL;
657 655
658 656 /* Append an entry for this software module to the kcf.conf file. */
659 657 if ((str = ent2str(pent)) == NULL) {
660 658 free_entry(pent);
661 659 return (FAILURE);
662 660 }
663 661
664 662 if ((pfile = fopen(_PATH_KCF_CONF, "r+")) == NULL) {
665 663 err = errno;
666 664 cryptoerror(LOG_STDERR,
667 665 gettext("failed to update the configuration - %s"),
668 666 strerror(err));
669 667 cryptodebug("failed to open %s for write.", _PATH_KCF_CONF);
670 668 free_entry(pent);
671 669 return (FAILURE);
672 670 }
673 671
674 672 if (lockf(fileno(pfile), F_TLOCK, 0) == -1) {
675 673 err = errno;
676 674 cryptoerror(LOG_STDERR,
677 675 gettext("failed to lock the configuration - %s"),
678 676 strerror(err));
679 677 free_entry(pent);
680 678 (void) fclose(pfile);
681 679 return (FAILURE);
682 680 }
683 681
684 682 /*
685 683 * Create a temporary file in the /etc/crypto directory.
686 684 */
687 685 (void) strlcpy(tmpfile_name, TMPFILE_TEMPLATE, sizeof (tmpfile_name));
688 686 if (mkstemp(tmpfile_name) == -1) {
689 687 err = errno;
690 688 cryptoerror(LOG_STDERR,
691 689 gettext("failed to create a temporary file - %s"),
692 690 strerror(err));
693 691 free_entry(pent);
694 692 (void) fclose(pfile);
695 693 return (FAILURE);
696 694 }
697 695
698 696 if ((pfile_tmp = fopen(tmpfile_name, "w")) == NULL) {
699 697 err = errno;
700 698 cryptoerror(LOG_STDERR, gettext("failed to open %s - %s"),
701 699 tmpfile_name, strerror(err));
702 700 free_entry(pent);
703 701 (void) fclose(pfile);
704 702 return (FAILURE);
705 703 }
706 704
707 705
708 706 /*
709 707 * Loop thru the config file. If the provider was reserved within a
710 708 * package bracket, just uncomment it. Otherwise, append it at
711 709 * the end. The resulting file will be saved in the temp file first.
712 710 */
713 711 found_count = 0;
714 712 rc = SUCCESS;
715 713 while (fgets(buffer, BUFSIZ, pfile) != NULL) {
716 714 found = B_FALSE;
717 715 if (buffer[0] == '#') {
718 716 (void) strlcpy(buffer2, buffer, BUFSIZ);
719 717 ptr = buffer2;
720 718 ptr++;
721 719 if ((name = strtok(ptr, SEP_COLON)) == NULL) {
722 720 rc = FAILURE;
723 721 break;
724 722 } else if (strcmp(provname, name) == 0) {
725 723 found = B_TRUE;
726 724 found_count++;
727 725 }
728 726 }
729 727
730 728 if (found == B_FALSE) {
731 729 if (fputs(buffer, pfile_tmp) == EOF) {
732 730 rc = FAILURE;
733 731 }
734 732 } else {
735 733 if (found_count == 1) {
736 734 if (fputs(str, pfile_tmp) == EOF) {
737 735 rc = FAILURE;
738 736 }
739 737 } else {
740 738 /*
741 739 * Found a second entry with #libname.
742 740 * Should not happen. The kcf.conf ffile
743 741 * is corrupted. Give a warning and skip
744 742 * this entry.
745 743 */
746 744 cryptoerror(LOG_STDERR, gettext(
747 745 "(Warning) Found an additional reserved "
748 746 "entry for %s."), provname);
749 747 }
750 748 }
751 749
752 750 if (rc == FAILURE) {
753 751 break;
754 752 }
755 753 }
756 754 (void) fclose(pfile);
757 755
758 756 if (rc == FAILURE) {
759 757 cryptoerror(LOG_STDERR, gettext("write error."));
760 758 (void) fclose(pfile_tmp);
761 759 if (unlink(tmpfile_name) != 0) {
762 760 err = errno;
763 761 cryptoerror(LOG_STDERR, gettext(
764 762 "(Warning) failed to remove %s: %s"), tmpfile_name,
765 763 strerror(err));
766 764 }
767 765 free_entry(pent);
768 766 return (FAILURE);
769 767 }
770 768
771 769 if (found_count == 0) {
772 770 /*
773 771 * This libname was not in package before, append it to the
774 772 * end of the temp file.
775 773 */
776 774 if (fputs(str, pfile_tmp) == EOF) {
777 775 cryptoerror(LOG_STDERR, gettext(
778 776 "failed to write to %s: %s"), tmpfile_name,
779 777 strerror(errno));
780 778 (void) fclose(pfile_tmp);
781 779 if (unlink(tmpfile_name) != 0) {
782 780 err = errno;
783 781 cryptoerror(LOG_STDERR, gettext(
784 782 "(Warning) failed to remove %s: %s"),
785 783 tmpfile_name, strerror(err));
786 784 }
787 785 free_entry(pent);
788 786 return (FAILURE);
789 787 }
790 788 }
791 789
792 790 if (fclose(pfile_tmp) != 0) {
793 791 err = errno;
794 792 cryptoerror(LOG_STDERR,
795 793 gettext("failed to close %s: %s"), tmpfile_name,
796 794 strerror(err));
797 795 return (FAILURE);
798 796 }
799 797
800 798 if (rename(tmpfile_name, _PATH_KCF_CONF) == -1) {
801 799 err = errno;
802 800 cryptoerror(LOG_STDERR,
803 801 gettext("failed to update the configuration - %s"),
804 802 strerror(err));
805 803 cryptodebug("failed to rename %s to %s: %s", tmpfile_name,
806 804 _PATH_KCF_CONF, strerror(err));
807 805 rc = FAILURE;
808 806 } else if (chmod(_PATH_KCF_CONF,
809 807 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) {
810 808 err = errno;
811 809 cryptoerror(LOG_STDERR,
812 810 gettext("failed to update the configuration - %s"),
813 811 strerror(err));
814 812 cryptodebug("failed to chmod to %s: %s", _PATH_KCF_CONF,
815 813 strerror(err));
816 814 rc = FAILURE;
817 815 } else {
818 816 rc = SUCCESS;
819 817 }
820 818
821 819 if (rc == FAILURE) {
822 820 if (unlink(tmpfile_name) != 0) {
823 821 err = errno;
824 822 cryptoerror(LOG_STDERR, gettext(
825 823 "(Warning) failed to remove %s: %s"),
826 824 tmpfile_name, strerror(err));
827 825 }
828 826 return (FAILURE);
829 827 }
830 828
831 829
832 830 /* Inform kernel of this new software module. */
833 831
834 832 if ((pload_soft_conf = setup_soft_conf(pent)) == NULL) {
835 833 free_entry(pent);
836 834 return (FAILURE);
837 835 }
838 836
839 837 if ((fd = open(ADMIN_IOCTL_DEVICE, O_RDWR)) == -1) {
840 838 cryptoerror(LOG_STDERR, gettext("failed to open %s: %s"),
841 839 ADMIN_IOCTL_DEVICE, strerror(errno));
842 840 free_entry(pent);
843 841 free(pload_soft_conf);
844 842 return (FAILURE);
845 843 }
846 844
847 845 if (ioctl(fd, CRYPTO_LOAD_SOFT_CONFIG, pload_soft_conf) == -1) {
848 846 cryptodebug("CRYPTO_LOAD_SOFT_CONFIG ioctl failed: %s",
849 847 strerror(errno));
850 848 free_entry(pent);
851 849 free(pload_soft_conf);
852 850 (void) close(fd);
853 851 return (FAILURE);
854 852 }
855 853
856 854 if (pload_soft_conf->sc_return_value != CRYPTO_SUCCESS) {
857 855 cryptodebug("CRYPTO_LOAD_SOFT_CONFIG ioctl failed, "
858 856 "return_value = %d", pload_soft_conf->sc_return_value);
859 857 free_entry(pent);
860 858 free(pload_soft_conf);
861 859 (void) close(fd);
862 860 return (FAILURE);
863 861 }
864 862
865 863 free_entry(pent);
866 864 free(pload_soft_conf);
867 865 (void) close(fd);
868 866 return (SUCCESS);
869 867 }
870 868
871 869 /*
872 870 * Uninstall the software module. This routine first unloads the software
873 871 * module with 3 ioctl calls, then deletes its entry from the config file.
874 872 * Removing an entry from the config file needs to be done last to ensure
875 873 * that there is still an entry if the earlier unload failed for any reason.
876 874 */
877 875 int
878 876 uninstall_kef(char *provname)
879 877 {
880 878 entry_t *pent;
881 879 boolean_t is_active;
882 880 boolean_t in_package;
883 881 boolean_t found;
884 882 FILE *pfile;
885 883 FILE *pfile_tmp;
886 884 char tmpfile_name[MAXPATHLEN];
887 885 char *name;
888 886 char strbuf[BUFSIZ];
889 887 char buffer[BUFSIZ];
890 888 char buffer2[BUFSIZ];
891 889 char *str;
892 890 int len;
893 891 int rc = SUCCESS;
894 892
895 893
896 894 /* Check if it is in the kcf.conf file first. */
897 895 if ((pent = getent_kef(provname)) == NULL) {
898 896 cryptoerror(LOG_STDERR,
899 897 gettext("%s does not exist."), provname);
900 898 return (FAILURE);
901 899 }
902 900
903 901
904 902 /*
905 903 * Get rid of the disabled list for the provider and get the converted
906 904 * string for the entry. This is to prepare the string for a provider
907 905 * that is in a package.
908 906 */
909 907 free_mechlist(pent->dislist);
910 908 pent->dis_count = 0;
911 909 pent->dislist = NULL;
912 910 str = ent2str(pent);
913 911 free_entry(pent);
914 912 if (str == NULL) {
915 913 cryptoerror(LOG_STDERR, gettext("internal error."));
916 914 return (FAILURE);
917 915 }
918 916 (void) snprintf(strbuf, sizeof (strbuf), "%s%s", "#", str);
919 917 free(str);
920 918
921 919 /* If it is not loaded, unload it first */
922 920 if (check_active_for_soft(provname, &is_active) == FAILURE) {
923 921 return (FAILURE);
924 922 } else if ((is_active == B_TRUE) &&
925 923 (unload_kef_soft(provname, B_TRUE) == FAILURE)) {
926 924 cryptoerror(LOG_STDERR,
927 925 gettext("failed to uninstall %s.\n"), provname);
928 926 return (FAILURE);
929 927 }
930 928
931 929 /*
932 930 * Remove the entry from the config file. If the provider to be
933 931 * uninstalled is in a package, just comment it off.
934 932 */
935 933 if ((pfile = fopen(_PATH_KCF_CONF, "r+")) == NULL) {
936 934 err = errno;
937 935 cryptoerror(LOG_STDERR,
938 936 gettext("failed to update the configuration - %s"),
939 937 strerror(err));
940 938 cryptodebug("failed to open %s for write.", _PATH_KCF_CONF);
941 939 return (FAILURE);
942 940 }
943 941
944 942 if (lockf(fileno(pfile), F_TLOCK, 0) == -1) {
945 943 err = errno;
946 944 cryptoerror(LOG_STDERR,
947 945 gettext("failed to lock the configuration - %s"),
948 946 strerror(err));
949 947 (void) fclose(pfile);
950 948 return (FAILURE);
951 949 }
952 950
953 951 /*
954 952 * Create a temporary file in the /etc/crypto directory to save
955 953 * the new configuration file first.
956 954 */
957 955 (void) strlcpy(tmpfile_name, TMPFILE_TEMPLATE, sizeof (tmpfile_name));
958 956 if (mkstemp(tmpfile_name) == -1) {
959 957 err = errno;
960 958 cryptoerror(LOG_STDERR,
961 959 gettext("failed to create a temporary file - %s"),
962 960 strerror(err));
963 961 (void) fclose(pfile);
964 962 return (FAILURE);
965 963 }
966 964
967 965 if ((pfile_tmp = fopen(tmpfile_name, "w")) == NULL) {
968 966 err = errno;
969 967 cryptoerror(LOG_STDERR, gettext("failed to open %s - %s"),
970 968 tmpfile_name, strerror(err));
971 969 if (unlink(tmpfile_name) != 0) {
972 970 err = errno;
973 971 cryptoerror(LOG_STDERR, gettext(
974 972 "(Warning) failed to remove %s: %s"), tmpfile_name,
975 973 strerror(err));
976 974 }
977 975 (void) fclose(pfile);
978 976 return (FAILURE);
979 977 }
980 978
981 979 /*
982 980 * Loop thru the config file. If the kernel software provider
983 981 * to be uninstalled is in a package, just comment it off.
984 982 */
985 983 in_package = B_FALSE;
986 984 while (fgets(buffer, BUFSIZ, pfile) != NULL) {
987 985 found = B_FALSE;
988 986 if (!(buffer[0] == ' ' || buffer[0] == '\n' ||
989 987 buffer[0] == '\t')) {
990 988 if (strstr(buffer, " Start ") != NULL) {
991 989 in_package = B_TRUE;
992 990 } else if (strstr(buffer, " End ") != NULL) {
993 991 in_package = B_FALSE;
994 992 } else if (buffer[0] != '#') {
995 993 (void) strlcpy(buffer2, buffer, BUFSIZ);
996 994
997 995 /* get rid of trailing '\n' */
998 996 len = strlen(buffer2);
999 997 if (buffer2[len-1] == '\n') {
1000 998 len--;
1001 999 }
1002 1000 buffer2[len] = '\0';
1003 1001
1004 1002 if ((name = strtok(buffer2, SEP_COLON))
1005 1003 == NULL) {
1006 1004 rc = FAILURE;
1007 1005 break;
1008 1006 } else if (strcmp(provname, name) == 0) {
1009 1007 found = B_TRUE;
1010 1008 }
1011 1009 }
1012 1010 }
1013 1011
1014 1012 if (found) {
1015 1013 if (in_package) {
1016 1014 if (fputs(strbuf, pfile_tmp) == EOF) {
1017 1015 rc = FAILURE;
1018 1016 }
1019 1017 }
1020 1018 } else {
1021 1019 if (fputs(buffer, pfile_tmp) == EOF) {
1022 1020 rc = FAILURE;
1023 1021 }
1024 1022 }
1025 1023
1026 1024 if (rc == FAILURE) {
1027 1025 break;
1028 1026 }
1029 1027 }
1030 1028
1031 1029 if (rc == FAILURE) {
1032 1030 cryptoerror(LOG_STDERR, gettext("write error."));
1033 1031 (void) fclose(pfile);
1034 1032 (void) fclose(pfile_tmp);
1035 1033 if (unlink(tmpfile_name) != 0) {
1036 1034 err = errno;
1037 1035 cryptoerror(LOG_STDERR, gettext(
1038 1036 "(Warning) failed to remove %s: %s"), tmpfile_name,
1039 1037 strerror(err));
1040 1038 }
1041 1039 return (FAILURE);
1042 1040 }
1043 1041
1044 1042 (void) fclose(pfile);
1045 1043 if (fclose(pfile_tmp) != 0) {
1046 1044 err = errno;
1047 1045 cryptoerror(LOG_STDERR,
1048 1046 gettext("failed to close %s: %s"), tmpfile_name,
1049 1047 strerror(err));
1050 1048 return (FAILURE);
1051 1049 }
1052 1050
1053 1051 /* Now update the real config file */
1054 1052 if (rename(tmpfile_name, _PATH_KCF_CONF) == -1) {
1055 1053 err = errno;
1056 1054 cryptoerror(LOG_STDERR,
1057 1055 gettext("failed to update the configuration - %s"),
1058 1056 strerror(err));
1059 1057 cryptodebug("failed to rename %1$s to %2$s: %3$s", tmpfile,
1060 1058 _PATH_KCF_CONF, strerror(err));
1061 1059 rc = FAILURE;
1062 1060 } else if (chmod(_PATH_KCF_CONF,
1063 1061 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) {
1064 1062 err = errno;
1065 1063 cryptoerror(LOG_STDERR,
1066 1064 gettext("failed to update the configuration - %s"),
1067 1065 strerror(err));
1068 1066 cryptodebug("failed to chmod to %s: %s", _PATH_KCF_CONF,
1069 1067 strerror(err));
1070 1068 rc = FAILURE;
1071 1069 } else {
1072 1070 rc = SUCCESS;
1073 1071 }
1074 1072
1075 1073 if ((rc == FAILURE) && (unlink(tmpfile_name) != 0)) {
1076 1074 err = errno;
1077 1075 cryptoerror(LOG_STDERR, gettext(
1078 1076 "(Warning) failed to remove %s: %s"), tmpfile_name,
1079 1077 strerror(err));
1080 1078 }
1081 1079
1082 1080 return (rc);
1083 1081
1084 1082 }
1085 1083
1086 1084
1087 1085 int
1088 1086 refresh(void)
1089 1087 {
1090 1088 crypto_get_soft_list_t *psoftlist_kernel = NULL;
1091 1089 crypto_load_soft_config_t *pload_soft_conf = NULL;
1092 1090 crypto_load_soft_disabled_t *pload_soft_dis = NULL;
1093 1091 crypto_load_dev_disabled_t *pload_dev_dis = NULL;
1094 1092 entrylist_t *pdevlist = NULL;
1095 1093 entrylist_t *psoftlist = NULL;
1096 1094 entrylist_t *ptr;
1097 1095 boolean_t found;
1098 1096 char *psoftname;
1099 1097 int fd;
1100 1098 int rc = SUCCESS;
1101 1099 int i;
1102 1100
1103 1101 if (get_soft_list(&psoftlist_kernel) == FAILURE) {
1104 1102 cryptoerror(LOG_ERR, gettext("Failed to retrieve the "
1105 1103 "software provider list from kernel."));
1106 1104 return (FAILURE);
1107 1105 }
1108 1106
1109 1107 if (get_kcfconf_info(&pdevlist, &psoftlist) == FAILURE) {
1110 1108 cryptoerror(LOG_ERR, "failed to retrieve the providers' "
1111 1109 "information from the configuration file - %s.",
1112 1110 _PATH_KCF_CONF);
1113 1111 return (FAILURE);
1114 1112 }
1115 1113
1116 1114 /*
1117 1115 * If a kernel software provider is in kernel, but it is not in the
1118 1116 * kcf.conf file, it must have been pkgrm'ed and needs to be unloaded
1119 1117 * now.
1120 1118 */
1121 1119 if (psoftlist_kernel->sl_soft_count > 0) {
1122 1120 psoftname = psoftlist_kernel->sl_soft_names;
1123 1121 for (i = 0; i < psoftlist_kernel->sl_soft_count; i++) {
1124 1122 ptr = psoftlist;
1125 1123 found = B_FALSE;
1126 1124 while (ptr != NULL) {
1127 1125 if (strcmp(psoftname, ptr->pent->name) == 0) {
1128 1126 found = B_TRUE;
1129 1127 break;
1130 1128 }
1131 1129 ptr = ptr->next;
1132 1130 }
1133 1131
1134 1132 if (!found) {
1135 1133 rc = unload_kef_soft(psoftname, B_FALSE);
1136 1134 if (rc == FAILURE) {
1137 1135 cryptoerror(LOG_ERR, gettext(
1138 1136 "WARNING - the provider %s is "
1139 1137 "still in kernel."), psoftname);
1140 1138 }
1141 1139 }
1142 1140 psoftname = psoftname + strlen(psoftname) + 1;
1143 1141 }
1144 1142 }
1145 1143 free(psoftlist_kernel);
1146 1144
1147 1145 if ((fd = open(ADMIN_IOCTL_DEVICE, O_RDWR)) == -1) {
1148 1146 err = errno;
1149 1147 cryptoerror(LOG_STDERR, gettext("failed to open %s: %s"),
1150 1148 ADMIN_IOCTL_DEVICE, strerror(err));
1151 1149 free(psoftlist);
1152 1150 free(pdevlist);
1153 1151 return (FAILURE);
1154 1152 }
1155 1153
1156 1154 /*
1157 1155 * For each software module, pass two sets of information to kernel
1158 1156 * - the supported list and the disabled list
1159 1157 */
1160 1158 ptr = psoftlist;
1161 1159 while (ptr != NULL) {
1162 1160 /* load the supported list */
1163 1161 if ((pload_soft_conf = setup_soft_conf(ptr->pent)) == NULL) {
1164 1162 rc = FAILURE;
1165 1163 break;
1166 1164 }
1167 1165
1168 1166 if (ioctl(fd, CRYPTO_LOAD_SOFT_CONFIG, pload_soft_conf)
1169 1167 == -1) {
1170 1168 cryptodebug("CRYPTO_LOAD_SOFT_CONFIG ioctl failed: %s",
1171 1169 strerror(errno));
1172 1170 free(pload_soft_conf);
1173 1171 rc = FAILURE;
1174 1172 break;
1175 1173 }
1176 1174
1177 1175 if (pload_soft_conf->sc_return_value != CRYPTO_SUCCESS) {
1178 1176 cryptodebug("CRYPTO_LOAD_SOFT_CONFIG ioctl "
1179 1177 "return_value = %d",
1180 1178 pload_soft_conf->sc_return_value);
1181 1179 free(pload_soft_conf);
1182 1180 rc = FAILURE;
1183 1181 break;
1184 1182 }
1185 1183
1186 1184 /* load the disabled list */
1187 1185 if (ptr->pent->dis_count != 0) {
1188 1186 pload_soft_dis = setup_soft_dis(ptr->pent);
1189 1187 if (pload_soft_dis == NULL) {
1190 1188 rc = FAILURE;
1191 1189 break;
1192 1190 }
1193 1191
1194 1192 if (ioctl(fd, CRYPTO_LOAD_SOFT_DISABLED,
1195 1193 pload_soft_dis) == -1) {
1196 1194 cryptodebug("CRYPTO_LOAD_SOFT_DISABLED ioctl "
1197 1195 "failed: %s", strerror(errno));
1198 1196 free(pload_soft_dis);
1199 1197 rc = FAILURE;
1200 1198 break;
1201 1199 }
1202 1200
1203 1201 if (pload_soft_dis->sd_return_value !=
1204 1202 CRYPTO_SUCCESS) {
1205 1203 cryptodebug("CRYPTO_LOAD_SOFT_DISABLED ioctl "
1206 1204 "return_value = %d",
1207 1205 pload_soft_dis->sd_return_value);
1208 1206 free(pload_soft_dis);
1209 1207 rc = FAILURE;
1210 1208 break;
1211 1209 }
1212 1210 free(pload_soft_dis);
1213 1211 }
1214 1212
1215 1213 free(pload_soft_conf);
1216 1214 ptr = ptr->next;
1217 1215 }
1218 1216
1219 1217 if (rc != SUCCESS) {
1220 1218 (void) close(fd);
1221 1219 return (rc);
1222 1220 }
1223 1221
1224 1222
1225 1223 /* Pass the disabledlist information for Device to kernel */
1226 1224 ptr = pdevlist;
1227 1225 while (ptr != NULL) {
1228 1226 /* load the disabled list */
1229 1227 if (ptr->pent->dis_count != 0) {
1230 1228 pload_dev_dis = setup_dev_dis(ptr->pent);
1231 1229 if (pload_dev_dis == NULL) {
1232 1230 rc = FAILURE;
1233 1231 break;
1234 1232 }
1235 1233
1236 1234 if (ioctl(fd, CRYPTO_LOAD_DEV_DISABLED, pload_dev_dis)
1237 1235 == -1) {
1238 1236 cryptodebug("CRYPTO_LOAD_DEV_DISABLED ioctl "
1239 1237 "failed: %s", strerror(errno));
1240 1238 free(pload_dev_dis);
1241 1239 rc = FAILURE;
1242 1240 break;
1243 1241 }
1244 1242
1245 1243 if (pload_dev_dis->dd_return_value != CRYPTO_SUCCESS) {
1246 1244 cryptodebug("CRYPTO_LOAD_DEV_DISABLED ioctl "
1247 1245 "return_value = %d",
1248 1246 pload_dev_dis->dd_return_value);
1249 1247 free(pload_dev_dis);
1250 1248 rc = FAILURE;
1251 1249 break;
1252 1250 }
1253 1251 free(pload_dev_dis);
1254 1252 }
1255 1253
1256 1254 ptr = ptr->next;
1257 1255 }
1258 1256
1259 1257 (void) close(fd);
1260 1258 return (rc);
1261 1259 }
1262 1260
1263 1261 /*
1264 1262 * Unload the kernel software provider. Before calling this function, the
1265 1263 * caller should check if the provider is in the config file and if it
1266 1264 * is kernel. This routine makes 3 ioctl calls to remove it from kernel
1267 1265 * completely. The argument do_check set to B_FALSE means that the
1268 1266 * caller knows the provider is not the config file and hence the check
1269 1267 * is skipped.
1270 1268 */
1271 1269 int
1272 1270 unload_kef_soft(char *provname, boolean_t do_check)
1273 1271 {
1274 1272 crypto_unload_soft_module_t *punload_soft = NULL;
1275 1273 crypto_load_soft_config_t *pload_soft_conf = NULL;
1276 1274 crypto_load_soft_disabled_t *pload_soft_dis = NULL;
1277 1275 entry_t *pent = NULL;
1278 1276 int fd;
1279 1277
1280 1278 if (provname == NULL) {
1281 1279 cryptoerror(LOG_STDERR, gettext("internal error."));
1282 1280 return (FAILURE);
1283 1281 }
1284 1282
1285 1283 if (!do_check) {
1286 1284 /* Construct an entry using the provname */
1287 1285 pent = calloc(1, sizeof (entry_t));
1288 1286 if (pent == NULL) {
1289 1287 cryptoerror(LOG_STDERR, gettext("out of memory."));
1290 1288 return (FAILURE);
1291 1289 }
1292 1290 (void) strlcpy(pent->name, provname, MAXNAMELEN);
1293 1291 } else if ((pent = getent_kef(provname)) == NULL) {
1294 1292 cryptoerror(LOG_STDERR, gettext("%s does not exist."),
1295 1293 provname);
1296 1294 return (FAILURE);
1297 1295 }
1298 1296
1299 1297 /* Open the admin_ioctl_device */
1300 1298 if ((fd = open(ADMIN_IOCTL_DEVICE, O_RDWR)) == -1) {
1301 1299 err = errno;
1302 1300 cryptoerror(LOG_STDERR, gettext("failed to open %s: %s"),
1303 1301 ADMIN_IOCTL_DEVICE, strerror(err));
1304 1302 return (FAILURE);
1305 1303 }
1306 1304
1307 1305 /* Inform kernel to unload this software module */
1308 1306 if ((punload_soft = setup_unload_soft(pent)) == NULL) {
1309 1307 (void) close(fd);
1310 1308 return (FAILURE);
1311 1309 }
1312 1310
1313 1311 if (ioctl(fd, CRYPTO_UNLOAD_SOFT_MODULE, punload_soft) == -1) {
1314 1312 cryptodebug("CRYPTO_UNLOAD_SOFT_MODULE ioctl failed: %s",
1315 1313 strerror(errno));
↓ open down ↓ |
915 lines elided |
↑ open up ↑ |
1316 1314 free_entry(pent);
1317 1315 free(punload_soft);
1318 1316 (void) close(fd);
1319 1317 return (FAILURE);
1320 1318 }
1321 1319
1322 1320 if (punload_soft->sm_return_value != CRYPTO_SUCCESS) {
1323 1321 cryptodebug("CRYPTO_UNLOAD_SOFT_MODULE ioctl return_value = "
1324 1322 "%d", punload_soft->sm_return_value);
1325 1323 /*
1326 - * If the return value is CRYPTO_UNKNOWN_PRIVDER, it means
1324 + * If the return value is CRYPTO_UNKNOWN_PROVIDER, it means
1327 1325 * that the provider is not registered yet. Should just
1328 1326 * continue.
1329 1327 */
1330 1328 if (punload_soft->sm_return_value != CRYPTO_UNKNOWN_PROVIDER) {
1331 1329 free_entry(pent);
1332 1330 free(punload_soft);
1333 1331 (void) close(fd);
1334 1332 return (FAILURE);
1335 1333 }
1336 1334 }
1337 1335
1338 1336 free(punload_soft);
1339 1337
1340 1338 /*
1341 1339 * Inform kernel to remove the configuration of this software
1342 1340 * module.
1343 1341 */
1344 1342 free_mechlist(pent->suplist);
1345 1343 pent->suplist = NULL;
1346 1344 pent->sup_count = 0;
1347 1345 if ((pload_soft_conf = setup_soft_conf(pent)) == NULL) {
1348 1346 free_entry(pent);
1349 1347 (void) close(fd);
1350 1348 return (FAILURE);
1351 1349 }
1352 1350
1353 1351 if (ioctl(fd, CRYPTO_LOAD_SOFT_CONFIG, pload_soft_conf) == -1) {
1354 1352 cryptodebug("CRYPTO_LOAD_SOFT_CONFIG ioctl failed: %s",
1355 1353 strerror(errno));
1356 1354 free_entry(pent);
1357 1355 free(pload_soft_conf);
1358 1356 (void) close(fd);
1359 1357 return (FAILURE);
1360 1358 }
1361 1359
1362 1360 if (pload_soft_conf->sc_return_value != CRYPTO_SUCCESS) {
1363 1361 cryptodebug("CRYPTO_LOAD_SOFT_CONFIG ioctl return_value = "
1364 1362 "%d", pload_soft_conf->sc_return_value);
1365 1363 free_entry(pent);
1366 1364 free(pload_soft_conf);
1367 1365 (void) close(fd);
1368 1366 return (FAILURE);
1369 1367 }
1370 1368
1371 1369 free(pload_soft_conf);
1372 1370
1373 1371 /* Inform kernel to remove the disabled entries if any */
1374 1372 if (pent->dis_count == 0) {
1375 1373 free_entry(pent);
1376 1374 (void) close(fd);
1377 1375 return (SUCCESS);
1378 1376 } else {
1379 1377 free_mechlist(pent->dislist);
1380 1378 pent->dislist = NULL;
1381 1379 pent->dis_count = 0;
1382 1380 }
1383 1381
1384 1382 if ((pload_soft_dis = setup_soft_dis(pent)) == NULL) {
1385 1383 free_entry(pent);
1386 1384 (void) close(fd);
1387 1385 return (FAILURE);
1388 1386 }
1389 1387
1390 1388 /* pent is no longer needed; free it */
1391 1389 free_entry(pent);
1392 1390
1393 1391 if (ioctl(fd, CRYPTO_LOAD_SOFT_DISABLED, pload_soft_dis) == -1) {
1394 1392 cryptodebug("CRYPTO_LOAD_SOFT_DISABLED ioctl failed: %s",
1395 1393 strerror(errno));
1396 1394 free(pload_soft_dis);
1397 1395 (void) close(fd);
1398 1396 return (FAILURE);
1399 1397 }
1400 1398
1401 1399 if (pload_soft_dis->sd_return_value != CRYPTO_SUCCESS) {
1402 1400 cryptodebug("CRYPTO_LOAD_SOFT_DISABLED ioctl return_value = "
1403 1401 "%d", pload_soft_dis->sd_return_value);
1404 1402 free(pload_soft_dis);
1405 1403 (void) close(fd);
1406 1404 return (FAILURE);
1407 1405 }
1408 1406
1409 1407 free(pload_soft_dis);
1410 1408 (void) close(fd);
1411 1409 return (SUCCESS);
1412 1410 }
1413 1411
1414 1412
1415 1413 /*
1416 1414 * Check if a hardware provider is valid. If it is valid, returns its device
1417 1415 * name, instance number and the number of mechanisms it supports.
1418 1416 */
1419 1417 static int
1420 1418 check_hardware_provider(char *provname, char *pname, int *pnum, int *pcount)
1421 1419 {
1422 1420 crypto_get_dev_list_t *dev_list = NULL;
1423 1421 int i;
1424 1422
1425 1423 if (provname == NULL) {
1426 1424 return (FAILURE);
1427 1425 }
1428 1426
1429 1427 /* First, get the device name and the instance number from provname */
1430 1428 if (split_hw_provname(provname, pname, pnum) == FAILURE) {
1431 1429 return (FAILURE);
1432 1430 }
1433 1431
1434 1432 /*
1435 1433 * Get the complete device list from kernel and check if this provider
1436 1434 * is in the list.
1437 1435 */
1438 1436 if (get_dev_list(&dev_list) == FAILURE) {
1439 1437 return (FAILURE);
1440 1438 }
1441 1439
1442 1440 for (i = 0; i < dev_list->dl_dev_count; i++) {
1443 1441 if ((strcmp(dev_list->dl_devs[i].le_dev_name, pname) == 0) &&
1444 1442 (dev_list->dl_devs[i].le_dev_instance == *pnum)) {
1445 1443 break;
1446 1444 }
1447 1445 }
1448 1446
1449 1447 if (i == dev_list->dl_dev_count) {
1450 1448 /* didn't find this provider in the kernel device list */
1451 1449 cryptoerror(LOG_STDERR, gettext("%s does not exist."),
1452 1450 provname);
1453 1451 free(dev_list);
1454 1452 return (FAILURE);
1455 1453 }
1456 1454
1457 1455 /* This provider is valid. Get its mechanism count */
1458 1456 *pcount = dev_list->dl_devs[i].le_mechanism_count;
1459 1457
1460 1458 free(dev_list);
1461 1459 return (SUCCESS);
1462 1460 }
↓ open down ↓ |
126 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX