Print this page
6862532 "cryptoadm: failed to parse configuration" error
6353443 domestic (crypt) source build leaves stuff it shouldn't
6818180 mac(1) printed "invalid key" error message when user input an invalid passphrase
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/cmd-crypto/cryptoadm/adm_kef_util.c
+++ new/usr/src/cmd/cmd-crypto/cryptoadm/adm_kef_util.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 2009 Sun Microsystems, Inc. All rights reserved.
22 + * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 #include <errno.h>
27 27 #include <fcntl.h>
28 28 #include <stdio.h>
29 29 #include <stdlib.h>
30 30 #include <strings.h>
31 31 #include <time.h>
32 32 #include <unistd.h>
33 33 #include <locale.h>
34 34 #include <sys/types.h>
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
35 35 #include <zone.h>
36 36 #include <sys/stat.h>
37 37 #include "cryptoadm.h"
38 38
39 39 static int err; /* To store errno which may be overwritten by gettext() */
40 40 static int build_entrylist(entry_t *, entrylist_t **);
41 41 static entry_t *dup_entry(entry_t *);
42 42 static mechlist_t *dup_mechlist(mechlist_t *);
43 43 static entry_t *getent(char *, entrylist_t *);
44 44 static int interpret(char *, entry_t **);
45 -static int parse_sup_dis_list(char *, entry_t *);
45 +static int parse_sup_dis_list(const char *buf, entry_t *pent);
46 46
47 47
48 48 /*
49 49 * Duplicate the mechanism list. A null pointer is returned if the storage
50 50 * space available is insufficient or the input argument is NULL.
51 51 */
52 52 static mechlist_t *
53 53 dup_mechlist(mechlist_t *plist)
54 54 {
55 55 mechlist_t *pres = NULL;
56 56 mechlist_t *pcur;
57 57 mechlist_t *ptmp;
58 58 int rc = SUCCESS;
59 59
60 60 while (plist != NULL) {
61 61 if (!(ptmp = create_mech(plist->name))) {
62 62 rc = FAILURE;
63 63 break;
64 64 }
65 65
66 66 if (pres == NULL) {
67 67 pres = pcur = ptmp;
68 68 } else {
69 69 pcur->next = ptmp;
70 70 pcur = pcur->next;
71 71 }
72 72 plist = plist->next;
73 73 }
74 74
75 75 if (rc != SUCCESS) {
76 76 free_mechlist(pres);
77 77 return (NULL);
78 78 }
79 79
80 80 return (pres);
81 81 }
82 82
83 83
84 84 /*
85 85 * Get the number of mechanisms in the mechanism list.
86 86 */
87 87 int
88 88 get_mech_count(mechlist_t *plist)
89 89 {
90 90 int count = 0;
91 91
92 92 while (plist != NULL) {
93 93 count++;
94 94 plist = plist->next;
95 95 }
96 96 return (count);
97 97 }
98 98
99 99 /*
100 100 * Create one item of type entry_t with the provider name.
101 101 * Return NULL if there's not enough memory or provname is NULL.
102 102 */
103 103 entry_t *
104 104 create_entry(char *provname)
105 105 {
106 106 entry_t *pent = NULL;
107 107
108 108 if (provname == NULL) {
109 109 return (NULL);
110 110 }
111 111
112 112 pent = calloc(1, sizeof (entry_t));
113 113 if (pent == NULL) {
114 114 cryptodebug("out of memory.");
115 115 return (NULL);
116 116 }
117 117
118 118 (void) strlcpy(pent->name, provname, MAXNAMELEN);
119 119 pent->suplist = NULL;
120 120 pent->sup_count = 0;
121 121 pent->dislist = NULL;
122 122 pent->dis_count = 0;
123 123 pent->load = B_TRUE;
124 124
125 125 return (pent);
126 126 }
127 127
128 128 /*
129 129 * Duplicate an entry for a provider from kcf.conf.
130 130 * Return NULL if memory is insufficient or the input argument is NULL.
131 131 * Called by getent().
132 132 */
133 133 static entry_t *
134 134 dup_entry(entry_t *pent1)
135 135 {
136 136 entry_t *pent2 = NULL;
137 137
138 138 if (pent1 == NULL) {
139 139 return (NULL);
140 140 }
141 141
142 142 if ((pent2 = create_entry(pent1->name)) == NULL) {
143 143 cryptodebug("out of memory.");
144 144 return (NULL);
145 145 }
146 146
147 147 pent2->sup_count = pent1->sup_count;
148 148 pent2->dis_count = pent1->dis_count;
149 149 pent2->load = pent1->load;
150 150 if (pent1->suplist != NULL) {
151 151 pent2->suplist = dup_mechlist(pent1->suplist);
152 152 if (pent2->suplist == NULL) {
153 153 free_entry(pent2);
154 154 return (NULL);
155 155 }
156 156 }
157 157 if (pent1->dislist != NULL) {
158 158 pent2->dislist = dup_mechlist(pent1->dislist);
159 159 if (pent2->dislist == NULL) {
160 160 free_entry(pent2);
161 161 return (NULL);
162 162 }
163 163 }
164 164
165 165 return (pent2);
166 166 }
167 167
168 168
169 169 /*
170 170 * This routine parses the disabledlist or the supportedlist of an entry
↓ open down ↓ |
115 lines elided |
↑ open up ↑ |
171 171 * in the kcf.conf configuration file.
172 172 *
173 173 * Arguments:
174 174 * buf: an input argument which is a char string with the format of
175 175 * "disabledlist=m1,m2,..." or "supportedlist=m1,m2,..."
176 176 * pent: the entry for the disabledlist. This is an IN/OUT argument.
177 177 *
178 178 * Return value: SUCCESS or FAILURE.
179 179 */
180 180 static int
181 -parse_sup_dis_list(char *buf, entry_t *pent)
181 +parse_sup_dis_list(const char *buf, entry_t *pent)
182 182 {
183 183 mechlist_t *pmech = NULL;
184 184 mechlist_t *phead = NULL;
185 185 char *next_token;
186 186 char *value;
187 187 int count;
188 188 int supflag = B_FALSE;
189 189 int disflag = B_FALSE;
190 190 int rc = SUCCESS;
191 191
192 192 if (strncmp(buf, EF_SUPPORTED, strlen(EF_SUPPORTED)) == 0) {
193 193 supflag = B_TRUE;
194 194 } else if (strncmp(buf, EF_DISABLED, strlen(EF_DISABLED)) == 0) {
195 195 disflag = B_TRUE;
196 196 } else {
197 197 /* should not come here */
198 198 return (FAILURE);
199 199 }
200 200
201 201 if (value = strpbrk(buf, SEP_EQUAL)) {
202 202 value++; /* get rid of = */
203 203 } else {
204 204 cryptodebug("failed to parse the kcf.conf file.");
205 205 return (FAILURE);
206 206 }
207 207
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
208 208 if ((next_token = strtok(value, SEP_COMMA)) == NULL) {
209 209 cryptodebug("failed to parse the kcf.conf file.");
210 210 return (FAILURE);
211 211 }
212 212
213 213 if ((pmech = create_mech(next_token)) == NULL) {
214 214 return (FAILURE);
215 215 }
216 216
217 217 if (supflag) {
218 - pent->suplist = phead = pmech;
218 + if (pent->suplist != NULL) {
219 + cryptodebug("multiple supportedlist entries "
220 + "for a mechanism in file kcf.conf.");
221 + return (FAILURE);
222 + } else {
223 + pent->suplist = phead = pmech;
224 + }
219 225 } else if (disflag) {
220 - pent->dislist = phead = pmech;
226 + if (pent->dislist != NULL) {
227 + cryptodebug("multiple disabledlist entries "
228 + "for a mechanism in file kcf.conf.");
229 + return (FAILURE);
230 + } else {
231 + pent->dislist = phead = pmech;
232 + }
221 233 }
222 234
223 235 count = 1;
224 236 while (next_token) {
225 237 if (next_token = strtok(NULL, SEP_COMMA)) {
226 238 if ((pmech = create_mech(next_token)) == NULL) {
227 239 rc = FAILURE;
228 240 break;
229 241 }
230 242 count++;
231 243 phead->next = pmech;
232 244 phead = phead->next;
233 245 }
234 246 }
235 247
236 248 if (rc == SUCCESS) {
237 249 if (supflag) {
238 250 pent->sup_count = count;
239 251 } else if (disflag) {
240 252 pent->dis_count = count;
241 253 }
242 254 } else {
243 255 free_mechlist(phead);
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
244 256 }
245 257
246 258 return (rc);
247 259 }
248 260
249 261
250 262 /*
251 263 * Convert a char string containing a line about a provider
252 264 * from kcf.conf into an entry_t structure.
253 265 *
266 + * Note: the input string, buf, may be modified by this function.
267 + *
254 268 * See ent2str(), the reverse of this function, for the format of
255 269 * kcf.conf lines.
256 270 */
257 271 static int
258 272 interpret(char *buf, entry_t **ppent)
259 273 {
260 274 entry_t *pent = NULL;
261 275 char *token1;
262 276 char *token2;
263 277 char *token3;
264 278 int rc;
265 279
266 280 /* Get provider name */
267 281 if ((token1 = strtok(buf, SEP_COLON)) == NULL) { /* buf is NULL */
268 282 return (FAILURE);
269 283 };
270 284
271 285 pent = create_entry(token1);
272 286 if (pent == NULL) {
273 287 cryptodebug("out of memory.");
274 288 return (FAILURE);
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
275 289 }
276 290
277 291 if ((token2 = strtok(NULL, SEP_SEMICOLON)) == NULL) {
278 292 /* The entry contains a provider name only */
279 293 free_entry(pent);
280 294 return (FAILURE);
281 295 }
282 296
283 297 if (strncmp(token2, EF_UNLOAD, strlen(EF_UNLOAD)) == 0) {
284 298 pent->load = B_FALSE; /* cryptoadm unload */
285 - if ((token2 = strtok(NULL, SEP_SEMICOLON)) == NULL) {
286 - /* The entry contains a provider name:unload only */
287 - free_entry(pent);
288 - return (FAILURE);
289 - }
299 + token2 = strtok(NULL, SEP_SEMICOLON);
300 + /*
301 + * If token2 is NULL, the entry contains a
302 + * provider name:unload only
303 + */
290 304 }
291 305
292 - /* need to get token3 first to satisfy nested strtok invocations */
293 - token3 = strtok(NULL, SEP_SEMICOLON); /* optional */
306 + if (token2 != NULL) {
307 + /*
308 + * Either supportedlist or disabledlist or both are present.
309 + * Need to call strtok() to get token3 first, as function
310 + * parse_sup_dis_list() makes strtok() calls on the
311 + * token2 substring.
312 + */
313 + token3 = strtok(NULL, SEP_SEMICOLON); /* optional */
294 314
295 - /* parse supportedlist (or disabledlist if no supportedlist) */
296 - if ((token2 != NULL) && ((rc = parse_sup_dis_list(token2, pent)) !=
297 - SUCCESS)) {
298 - free_entry(pent);
299 - return (rc);
300 - }
315 + /* parse supportedlist (or disabledlist if no supportedlist) */
316 + if ((rc = parse_sup_dis_list(token2, pent)) != SUCCESS) {
317 + free_entry(pent);
318 + return (rc);
319 + }
301 320
302 - /* parse disabledlist (if there's a supportedlist) */
303 - if ((token3 != NULL) && ((rc = parse_sup_dis_list(token3, pent)) !=
304 - SUCCESS)) {
305 - free_entry(pent);
306 - return (rc);
321 + /* parse disabledlist (if there's a supportedlist) */
322 + if ((token3 != NULL) && ((rc = parse_sup_dis_list(token3,
323 + pent)) != SUCCESS)) {
324 + free_entry(pent);
325 + return (rc);
326 + }
307 327 }
308 328
309 329 *ppent = pent;
310 330 return (SUCCESS);
311 331 }
312 332
313 333
314 334 /*
315 335 * Add an entry about a provider from kcf.conf to the end of an entry list.
316 336 * If the entry list pplist is NULL, create the linked list with pent as the
317 337 * first element.
318 338 */
319 339 static int
320 340 build_entrylist(entry_t *pent, entrylist_t **pplist)
321 341 {
322 342 entrylist_t *pentlist;
323 343 entrylist_t *pcur = NULL;
324 344
325 345 pentlist = malloc(sizeof (entrylist_t));
326 346 if (pentlist == NULL) {
327 347 cryptodebug("out of memory.");
328 348 return (FAILURE);
329 349 }
330 350 pentlist->pent = pent;
331 351 pentlist->next = NULL;
332 352
333 353 if (*pplist) {
334 354 pcur = *pplist;
335 355 while (pcur->next != NULL)
336 356 pcur = pcur->next;
337 357 pcur->next = pentlist;
338 358 } else { /* empty list */
339 359 *pplist = pentlist;
340 360 }
341 361
342 362 return (SUCCESS);
343 363 }
344 364
345 365
346 366
347 367 /*
348 368 * Find the entry with the "provname" name from the entry list and duplicate
349 369 * it. Called by getent_kef().
350 370 */
351 371 static entry_t *
352 372 getent(char *provname, entrylist_t *entrylist)
353 373 {
354 374 boolean_t found = B_FALSE;
355 375 entry_t *pent1 = NULL;
356 376
357 377 if ((provname == NULL) || (entrylist == NULL)) {
358 378 return (NULL);
359 379 }
360 380
361 381 while (!found && entrylist) {
362 382 if (strcmp(entrylist->pent->name, provname) == 0) {
363 383 found = B_TRUE;
364 384 pent1 = entrylist->pent;
365 385 } else {
366 386 entrylist = entrylist->next;
367 387 }
368 388 }
369 389
370 390 if (!found) {
371 391 return (NULL);
372 392 }
373 393
374 394 /* duplicate the entry to be returned */
375 395 return (dup_entry(pent1));
376 396 }
377 397
378 398
379 399 /*
380 400 * Free memory in entry_t.
381 401 * That is, the supported and disabled lists for a provider
382 402 * from kcf.conf.
383 403 */
384 404 void
385 405 free_entry(entry_t *pent)
386 406 {
387 407 if (pent == NULL) {
388 408 return;
389 409 } else {
390 410 free_mechlist(pent->suplist);
391 411 free_mechlist(pent->dislist);
392 412 free(pent);
393 413 }
394 414 }
395 415
396 416
397 417 /*
398 418 * Free elements in a entrylist_t linked list,
399 419 * which lists providers in kcf.conf.
400 420 */
401 421 void
402 422 free_entrylist(entrylist_t *entrylist)
403 423 {
404 424 entrylist_t *pnext;
405 425
406 426 while (entrylist != NULL) {
↓ open down ↓ |
90 lines elided |
↑ open up ↑ |
407 427 pnext = entrylist->next;
408 428 free_entry(entrylist->pent);
409 429 entrylist = pnext;
410 430 }
411 431 }
412 432
413 433
414 434 /*
415 435 * Convert an entry to a string. This routine builds a string for the entry
416 436 * to be inserted in the kcf.conf file. Based on the content of each entry,
417 - * the result string can be one of these 6 forms:
437 + * the result string can be one of these 7 forms:
418 438 * - name:supportedlist=m1,m2,...,mj
419 439 * - name:disabledlist=m1,m2,...,mj
420 440 * - name:supportedlist=m1,...,mj;disabledlist=m1,m2,...,mk
421 441 *
442 + * - name:unload
422 443 * - name:unload;supportedlist=m1,m2,...,mj
423 444 * - name:unload;disabledlist=m1,m2,...,mj
424 445 * - name:unload;supportedlist=m1,...,mj;disabledlist=m1,m2,...,mk
425 446 *
426 447 * Note that the caller is responsible for freeing the returned string
427 448 * (with free_entry()).
428 449 * See interpret() for the reverse of this function: converting a string
429 450 * to an entry_t.
430 451 */
431 452 char *
432 453 ent2str(entry_t *pent)
433 454 {
434 455 char *buf;
435 456 mechlist_t *pcur = NULL;
436 457 boolean_t semicolon_separator = B_FALSE;
437 458
438 459
439 460 if (pent == NULL) {
440 461 return (NULL);
441 462 }
442 463
443 464 if ((buf = malloc(BUFSIZ)) == NULL) {
444 465 return (NULL);
445 466 }
446 467
447 468 /* convert the provider name */
448 469 if (strlcpy(buf, pent->name, BUFSIZ) >= BUFSIZ) {
449 470 free(buf);
450 471 return (NULL);
451 472 }
452 473
453 474 if (!pent->load) { /* add "unload" keyword */
454 475 if (strlcat(buf, SEP_COLON, BUFSIZ) >= BUFSIZ) {
455 476 free(buf);
456 477 return (NULL);
457 478 }
458 479
459 480 if (strlcat(buf, EF_UNLOAD, BUFSIZ) >= BUFSIZ) {
460 481 free(buf);
461 482 return (NULL);
462 483 }
463 484
464 485 semicolon_separator = B_TRUE;
465 486 }
466 487
467 488 /* convert the supported list if any */
468 489 pcur = pent->suplist;
469 490 if (pcur != NULL) {
470 491 if (strlcat(buf,
471 492 semicolon_separator ? SEP_SEMICOLON : SEP_COLON,
472 493 BUFSIZ) >= BUFSIZ) {
473 494 free(buf);
474 495 return (NULL);
475 496 }
476 497
477 498 if (strlcat(buf, EF_SUPPORTED, BUFSIZ) >= BUFSIZ) {
478 499 free(buf);
479 500 return (NULL);
480 501 }
481 502
482 503 while (pcur != NULL) {
483 504 if (strlcat(buf, pcur->name, BUFSIZ) >= BUFSIZ) {
484 505 free(buf);
485 506 return (NULL);
486 507 }
487 508
488 509 pcur = pcur->next;
489 510 if (pcur != NULL) {
490 511 if (strlcat(buf, SEP_COMMA, BUFSIZ)
491 512 >= BUFSIZ) {
492 513 free(buf);
493 514 return (NULL);
494 515 }
495 516 }
496 517 }
497 518 semicolon_separator = B_TRUE;
498 519 }
499 520
500 521 /* convert the disabled list if any */
501 522 pcur = pent->dislist;
502 523 if (pcur != NULL) {
503 524 if (strlcat(buf,
504 525 semicolon_separator ? SEP_SEMICOLON : SEP_COLON,
505 526 BUFSIZ) >= BUFSIZ) {
506 527 free(buf);
507 528 return (NULL);
508 529 }
509 530
510 531 if (strlcat(buf, EF_DISABLED, BUFSIZ) >= BUFSIZ) {
511 532 free(buf);
512 533 return (NULL);
513 534 }
514 535
515 536 while (pcur != NULL) {
516 537 if (strlcat(buf, pcur->name, BUFSIZ) >= BUFSIZ) {
517 538 free(buf);
518 539 return (NULL);
519 540 }
520 541
521 542 pcur = pcur->next;
522 543 if (pcur != NULL) {
523 544 if (strlcat(buf, SEP_COMMA, BUFSIZ)
524 545 >= BUFSIZ) {
525 546 free(buf);
526 547 return (NULL);
527 548 }
528 549 }
529 550 }
530 551 semicolon_separator = B_TRUE;
531 552 }
532 553
533 554 if (strlcat(buf, "\n", BUFSIZ) >= BUFSIZ) {
534 555 free(buf);
535 556 return (NULL);
536 557 }
537 558
538 559 return (buf);
539 560 }
540 561
541 562
542 563 /*
543 564 * Enable the mechanisms for the provider pointed by *ppent. If allflag is
544 565 * TRUE, enable all. Otherwise, enable the mechanisms specified in the 3rd
545 566 * argument "mlist". The result will be stored in ppent also.
546 567 */
547 568 int
548 569 enable_mechs(entry_t **ppent, boolean_t allflag, mechlist_t *mlist)
549 570 {
550 571 entry_t *pent;
551 572 mechlist_t *phead; /* the current and resulting disabled list */
552 573 mechlist_t *ptr = NULL;
553 574 mechlist_t *pcur = NULL;
554 575 boolean_t found;
555 576
556 577 pent = *ppent;
557 578 if (pent == NULL) {
558 579 return (FAILURE);
559 580 }
560 581
561 582 if (allflag) {
562 583 free_mechlist(pent->dislist);
563 584 pent->dis_count = 0;
564 585 pent->dislist = NULL;
565 586 return (SUCCESS);
566 587 }
567 588
568 589 /*
569 590 * for each mechanism in the to-be-enabled mechanism list,
570 591 * - check if it is in the current disabled list
571 592 * - if found, delete it from the disabled list
572 593 * otherwise, give a warning.
573 594 */
574 595 ptr = mlist;
575 596 while (ptr != NULL) {
576 597 found = B_FALSE;
577 598 phead = pcur = pent->dislist;
578 599 while (!found && pcur) {
579 600 if (strcmp(pcur->name, ptr->name) == 0) {
580 601 found = B_TRUE;
581 602 } else {
582 603 phead = pcur;
583 604 pcur = pcur->next;
584 605 }
585 606 }
586 607
587 608 if (found) {
588 609 if (phead == pcur) {
589 610 pent->dislist = pent->dislist->next;
590 611 free(pcur);
591 612 } else {
592 613 phead->next = pcur->next;
593 614 free(pcur);
594 615 }
595 616 pent->dis_count--;
596 617 } else {
597 618 cryptoerror(LOG_STDERR, gettext(
598 619 "(Warning) %1$s is either enabled already or not "
599 620 "a valid mechanism for %2$s"), ptr->name,
600 621 pent->name);
601 622 }
602 623 ptr = ptr->next;
603 624 }
604 625
605 626 if (pent->dis_count == 0) {
606 627 pent->dislist = NULL;
607 628 }
608 629
609 630 return (SUCCESS);
610 631
611 632 }
612 633
613 634
614 635 /*
615 636 * Determine if the kernel provider name, path, is a device
616 637 * (that is, it contains a slash character (e.g., "mca/0").
617 638 * If so, it is a hardware provider; otherwise it is a software provider.
618 639 */
619 640 boolean_t
620 641 is_device(char *path)
621 642 {
622 643 if (strchr(path, SEP_SLASH) != NULL) {
623 644 return (B_TRUE);
624 645 } else {
625 646 return (B_FALSE);
626 647 }
627 648 }
628 649
629 650 /*
630 651 * Split a hardware provider name with the "name/inst_num" format into
631 652 * a name and a number (e.g., split "mca/0" into "mca" instance 0).
632 653 */
633 654 int
634 655 split_hw_provname(char *provname, char *pname, int *inst_num)
635 656 {
636 657 char name[MAXNAMELEN];
637 658 char *inst_str;
638 659
639 660 if (provname == NULL) {
640 661 return (FAILURE);
641 662 }
642 663
643 664 (void) strlcpy(name, provname, MAXNAMELEN);
644 665 if (strtok(name, "/") == NULL) {
645 666 return (FAILURE);
646 667 }
647 668
648 669 if ((inst_str = strtok(NULL, "/")) == NULL) {
649 670 return (FAILURE);
650 671 }
651 672
652 673 (void) strlcpy(pname, name, MAXNAMELEN);
653 674 *inst_num = atoi(inst_str);
654 675
655 676 return (SUCCESS);
656 677 }
657 678
658 679
659 680 /*
660 681 * Retrieve information from kcf.conf and build a hardware device entry list
661 682 * and a software entry list of kernel crypto providers.
662 683 *
663 684 * This list is usually incomplete, as kernel crypto providers only have to
664 685 * be listed in kcf.conf if a mechanism is disabled (by cryptoadm) or
665 686 * if the kernel provider module is not one of the default kernel providers.
666 687 *
667 688 * The kcf.conf file is available only in the global zone.
668 689 */
669 690 int
670 691 get_kcfconf_info(entrylist_t **ppdevlist, entrylist_t **ppsoftlist)
671 692 {
672 693 FILE *pfile = NULL;
673 694 char buffer[BUFSIZ];
674 695 int len;
675 696 entry_t *pent = NULL;
676 697 int rc = SUCCESS;
677 698
678 699 if ((pfile = fopen(_PATH_KCF_CONF, "r")) == NULL) {
679 700 cryptodebug("failed to open the kcf.conf file for read only");
680 701 return (FAILURE);
681 702 }
682 703
683 704 *ppdevlist = NULL;
684 705 *ppsoftlist = NULL;
685 706 while (fgets(buffer, BUFSIZ, pfile) != NULL) {
686 707 if (buffer[0] == '#' || buffer[0] == ' ' ||
687 708 buffer[0] == '\n'|| buffer[0] == '\t') {
688 709 continue; /* ignore comment lines */
689 710 }
690 711
691 712 len = strlen(buffer);
692 713 if (buffer[len - 1] == '\n') { /* get rid of trailing '\n' */
693 714 len--;
694 715 }
695 716 buffer[len] = '\0';
696 717
697 718 if ((rc = interpret(buffer, &pent)) == SUCCESS) {
698 719 if (is_device(pent->name)) {
699 720 rc = build_entrylist(pent, ppdevlist);
700 721 } else {
701 722 rc = build_entrylist(pent, ppsoftlist);
702 723 }
703 724 } else {
704 725 cryptoerror(LOG_STDERR, gettext(
705 726 "failed to parse configuration."));
706 727 }
707 728
708 729 if (rc != SUCCESS) {
709 730 free_entrylist(*ppdevlist);
710 731 free_entrylist(*ppsoftlist);
711 732 free_entry(pent);
712 733 break;
713 734 }
714 735 }
715 736
716 737 (void) fclose(pfile);
717 738 return (rc);
718 739 }
719 740
720 741 /*
721 742 * Retrieve information from admin device and build a device entry list and
722 743 * a software entry list. This is used where there is no kcf.conf, e.g., the
723 744 * non-global zone.
724 745 */
725 746 int
726 747 get_admindev_info(entrylist_t **ppdevlist, entrylist_t **ppsoftlist)
727 748 {
728 749 crypto_get_dev_list_t *pdevlist_kernel = NULL;
729 750 crypto_get_soft_list_t *psoftlist_kernel = NULL;
730 751 char *devname;
731 752 int inst_num;
732 753 int mcount;
733 754 mechlist_t *pmech = NULL;
734 755 entry_t *pent_dev = NULL, *pent_soft = NULL;
735 756 int i;
736 757 char *psoftname;
737 758 entrylist_t *tmp_pdev = NULL;
738 759 entrylist_t *tmp_psoft = NULL;
739 760 entrylist_t *phardlist = NULL, *psoftlist = NULL;
740 761
741 762 /*
742 763 * Get hardware providers
743 764 */
744 765 if (get_dev_list(&pdevlist_kernel) != SUCCESS) {
745 766 cryptodebug("failed to get hardware provider list from kernel");
746 767 return (FAILURE);
747 768 }
748 769
749 770 for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) {
750 771 devname = pdevlist_kernel->dl_devs[i].le_dev_name;
751 772 inst_num = pdevlist_kernel->dl_devs[i].le_dev_instance;
752 773 mcount = pdevlist_kernel->dl_devs[i].le_mechanism_count;
753 774
754 775 pmech = NULL;
755 776 if (get_dev_info(devname, inst_num, mcount, &pmech) !=
756 777 SUCCESS) {
757 778 cryptodebug(
758 779 "failed to retrieve the mechanism list for %s/%d.",
759 780 devname, inst_num);
760 781 goto fail_out;
761 782 }
762 783
763 784 if ((pent_dev = create_entry(devname)) == NULL) {
764 785 cryptodebug("out of memory.");
765 786 free_mechlist(pmech);
766 787 goto fail_out;
767 788 }
768 789 pent_dev->suplist = pmech;
769 790 pent_dev->sup_count = mcount;
770 791
771 792 if (build_entrylist(pent_dev, &tmp_pdev) != SUCCESS) {
772 793 goto fail_out;
773 794 }
774 795 }
775 796
776 797 free(pdevlist_kernel);
777 798 pdevlist_kernel = NULL;
778 799
779 800 /*
780 801 * Get software providers
781 802 */
782 803 if (getzoneid() == GLOBAL_ZONEID) {
783 804 if (get_kcfconf_info(&phardlist, &psoftlist) != SUCCESS) {
784 805 goto fail_out;
785 806 }
786 807 }
787 808
788 809 if (get_soft_list(&psoftlist_kernel) != SUCCESS) {
789 810 cryptodebug("failed to get software provider list from kernel");
790 811 goto fail_out;
791 812 }
792 813
793 814 for (i = 0, psoftname = psoftlist_kernel->sl_soft_names;
794 815 i < psoftlist_kernel->sl_soft_count;
795 816 i++, psoftname = psoftname + strlen(psoftname) + 1) {
796 817 pmech = NULL;
797 818 if (get_soft_info(psoftname, &pmech, phardlist, psoftlist) !=
798 819 SUCCESS) {
799 820 cryptodebug(
800 821 "failed to retrieve the mechanism list for %s.",
801 822 psoftname);
802 823 goto fail_out;
803 824 }
804 825
805 826 if ((pent_soft = create_entry(psoftname)) == NULL) {
806 827 cryptodebug("out of memory.");
807 828 free_mechlist(pmech);
808 829 goto fail_out;
809 830 }
810 831 pent_soft->suplist = pmech;
811 832 pent_soft->sup_count = get_mech_count(pmech);
812 833
813 834 if (build_entrylist(pent_soft, &tmp_psoft) != SUCCESS) {
814 835 goto fail_out;
815 836 }
816 837 }
817 838
818 839 free(psoftlist_kernel);
819 840 psoftlist_kernel = NULL;
820 841
821 842 *ppdevlist = tmp_pdev;
822 843 *ppsoftlist = tmp_psoft;
823 844
824 845 return (SUCCESS);
825 846
826 847 fail_out:
827 848 if (pent_dev != NULL)
828 849 free_entry(pent_dev);
829 850 if (pent_soft != NULL)
830 851 free_entry(pent_soft);
831 852
832 853 free_entrylist(tmp_pdev);
833 854 free_entrylist(tmp_psoft);
834 855
835 856 if (pdevlist_kernel != NULL)
836 857 free(pdevlist_kernel);
837 858 if (psoftlist_kernel != NULL)
838 859 free(psoftlist_kernel);
839 860
840 861 return (FAILURE);
841 862 }
842 863
843 864 /*
844 865 * Return configuration information for a kernel provider from kcf.conf.
845 866 * For kernel software providers return a enabled list and disabled list.
846 867 * For kernel hardware providers return just a disabled list.
847 868 *
848 869 * Parameters phardlist and psoftlist are supplied by get_kcfconf_info().
849 870 * If NULL, this function calls get_kcfconf_info() internally.
850 871 */
851 872 entry_t *
852 873 getent_kef(char *provname, entrylist_t *phardlist, entrylist_t *psoftlist)
853 874 {
854 875 entry_t *pent = NULL;
855 876 boolean_t memory_allocated = B_FALSE;
856 877
857 878 if ((phardlist == NULL) || (psoftlist == NULL)) {
858 879 if (get_kcfconf_info(&phardlist, &psoftlist) != SUCCESS) {
859 880 return (NULL);
860 881 }
861 882 memory_allocated = B_TRUE;
862 883 }
863 884
864 885 if (is_device(provname)) {
865 886 pent = getent(provname, phardlist);
866 887 } else {
867 888 pent = getent(provname, psoftlist);
868 889 }
869 890
870 891 if (memory_allocated) {
871 892 free_entrylist(phardlist);
872 893 free_entrylist(psoftlist);
873 894 }
874 895
875 896 return (pent);
876 897 }
877 898
878 899 /*
879 900 * Print out the provider name and the mechanism list.
880 901 */
881 902 void
882 903 print_mechlist(char *provname, mechlist_t *pmechlist)
883 904 {
884 905 mechlist_t *ptr = NULL;
885 906
886 907 if (provname == NULL) {
887 908 return;
888 909 }
889 910
890 911 (void) printf("%s: ", provname);
891 912 if (pmechlist == NULL) {
892 913 (void) printf(gettext("No mechanisms presented.\n"));
893 914 return;
894 915 }
895 916
896 917 ptr = pmechlist;
897 918 while (ptr != NULL) {
898 919 (void) printf("%s", ptr->name);
899 920 ptr = ptr->next;
900 921 if (ptr == NULL) {
901 922 (void) printf("\n");
902 923 } else {
903 924 (void) printf(",");
904 925 }
905 926 }
906 927 }
907 928
908 929
909 930 /*
910 931 * Update the kcf.conf file based on the update mode:
911 932 * - If update_mode is MODIFY_MODE, modify the entry with the same name.
912 933 * If not found, append a new entry to the kcf.conf file.
913 934 * - If update_mode is DELETE_MODE, delete the entry with the same name.
914 935 * - If update_mode is ADD_MODE, append a new entry to the kcf.conf file.
915 936 */
916 937 int
917 938 update_kcfconf(entry_t *pent, int update_mode)
918 939 {
919 940 boolean_t add_it = B_FALSE;
920 941 boolean_t delete_it = B_FALSE;
921 942 boolean_t this_entry_matches = B_FALSE;
922 943 boolean_t found_entry = B_FALSE;
923 944 FILE *pfile = NULL;
924 945 FILE *pfile_tmp = NULL;
925 946 char buffer[BUFSIZ];
926 947 char buffer2[BUFSIZ];
927 948 char tmpfile_name[MAXPATHLEN];
928 949 char *name;
929 950 char *new_str = NULL;
930 951 int rc = SUCCESS;
931 952
932 953 if (pent == NULL) {
933 954 cryptoerror(LOG_STDERR, gettext("internal error."));
934 955 return (FAILURE);
935 956 }
936 957
937 958 /* Check the update_mode */
938 959 switch (update_mode) {
939 960 case ADD_MODE:
940 961 add_it = B_TRUE;
941 962 /* FALLTHROUGH */
942 963 case MODIFY_MODE:
943 964 /* Convert the entry a string to add to kcf.conf */
944 965 if ((new_str = ent2str(pent)) == NULL) {
945 966 return (FAILURE);
946 967 }
947 968 break;
948 969 case DELETE_MODE:
949 970 delete_it = B_TRUE;
950 971 break;
951 972 default:
952 973 cryptoerror(LOG_STDERR, gettext("internal error."));
953 974 return (FAILURE);
954 975 }
955 976
956 977 /* Open the kcf.conf file */
957 978 if ((pfile = fopen(_PATH_KCF_CONF, "r+")) == NULL) {
958 979 err = errno;
959 980 cryptoerror(LOG_STDERR,
960 981 gettext("failed to update the configuration - %s"),
961 982 strerror(err));
962 983 cryptodebug("failed to open %s for write.", _PATH_KCF_CONF);
963 984 return (FAILURE);
964 985 }
965 986
966 987 /* Lock the kcf.conf file */
967 988 if (lockf(fileno(pfile), F_TLOCK, 0) == -1) {
968 989 err = errno;
969 990 cryptoerror(LOG_STDERR,
970 991 gettext("failed to update the configuration - %s"),
971 992 strerror(err));
972 993 (void) fclose(pfile);
973 994 return (FAILURE);
974 995 }
975 996
976 997 /*
977 998 * Create a temporary file in the /etc/crypto directory to save
978 999 * updated configuration file first.
979 1000 */
980 1001 (void) strlcpy(tmpfile_name, TMPFILE_TEMPLATE, sizeof (tmpfile_name));
981 1002 if (mkstemp(tmpfile_name) == -1) {
982 1003 err = errno;
983 1004 cryptoerror(LOG_STDERR,
984 1005 gettext("failed to create a temporary file - %s"),
985 1006 strerror(err));
986 1007 (void) fclose(pfile);
987 1008 return (FAILURE);
988 1009 }
989 1010
990 1011 if ((pfile_tmp = fopen(tmpfile_name, "w")) == NULL) {
991 1012 err = errno;
992 1013 cryptoerror(LOG_STDERR, gettext("failed to open %s - %s"),
993 1014 tmpfile_name, strerror(err));
994 1015 (void) fclose(pfile);
995 1016 return (FAILURE);
996 1017 }
997 1018
998 1019 /*
999 1020 * Loop thru the entire kcf.conf file, insert, modify or delete
1000 1021 * an entry.
1001 1022 */
1002 1023 while (fgets(buffer, BUFSIZ, pfile) != NULL) {
1003 1024 if (add_it) {
1004 1025 if (fputs(buffer, pfile_tmp) == EOF) {
1005 1026 err = errno;
1006 1027 cryptoerror(LOG_STDERR, gettext(
1007 1028 "failed to write to a temp file: %s."),
1008 1029 strerror(err));
1009 1030 rc = FAILURE;
1010 1031 break;
1011 1032 }
1012 1033
1013 1034 } else { /* modify or delete */
1014 1035 this_entry_matches = B_FALSE;
1015 1036
1016 1037 if (!(buffer[0] == '#' || buffer[0] == ' ' ||
1017 1038 buffer[0] == '\n'|| buffer[0] == '\t')) {
1018 1039 /*
1019 1040 * Get the provider name from this line and
1020 1041 * check if this is the entry to be updated
1021 1042 * or deleted. Note: can not use "buffer"
1022 1043 * directly because strtok will change its
1023 1044 * value.
1024 1045 */
1025 1046 (void) strlcpy(buffer2, buffer, BUFSIZ);
1026 1047 if ((name = strtok(buffer2, SEP_COLON)) ==
1027 1048 NULL) {
1028 1049 rc = FAILURE;
1029 1050 break;
1030 1051 }
1031 1052
1032 1053 if (strcmp(pent->name, name) == 0) {
1033 1054 this_entry_matches = B_TRUE;
1034 1055 found_entry = B_TRUE;
1035 1056 }
1036 1057 }
1037 1058
1038 1059
1039 1060 if (!this_entry_matches || !delete_it) {
1040 1061 /* write this entry */
1041 1062 if (this_entry_matches) {
1042 1063 /*
1043 1064 * Modify this entry: get the
1044 1065 * updated string and place into buffer.
1045 1066 */
1046 1067 (void) strlcpy(buffer, new_str, BUFSIZ);
1047 1068 free(new_str);
1048 1069 }
1049 1070 /* write the (unchanged or modified) entry */
1050 1071 if (fputs(buffer, pfile_tmp) == EOF) {
1051 1072 err = errno;
1052 1073 cryptoerror(LOG_STDERR, gettext(
1053 1074 "failed to write to a temp file: "
1054 1075 "%s."), strerror(err));
1055 1076 rc = FAILURE;
1056 1077 break;
1057 1078 }
1058 1079 }
1059 1080 }
1060 1081 }
1061 1082
1062 1083 if ((!delete_it) && (rc != FAILURE)) {
1063 1084 if (add_it || !found_entry) {
1064 1085 /* append new entry to end of file */
1065 1086 if (fputs(new_str, pfile_tmp) == EOF) {
1066 1087 err = errno;
1067 1088 cryptoerror(LOG_STDERR, gettext(
1068 1089 "failed to write to a temp file: %s."),
1069 1090 strerror(err));
1070 1091 rc = FAILURE;
1071 1092 }
1072 1093 free(new_str);
1073 1094 }
1074 1095 }
1075 1096
1076 1097 (void) fclose(pfile);
1077 1098 if (fclose(pfile_tmp) != 0) {
1078 1099 err = errno;
1079 1100 cryptoerror(LOG_STDERR,
1080 1101 gettext("failed to close %s: %s"), tmpfile_name,
1081 1102 strerror(err));
1082 1103 return (FAILURE);
1083 1104 }
1084 1105
1085 1106 /* Copy the temporary file to the kcf.conf file */
1086 1107 if (rename(tmpfile_name, _PATH_KCF_CONF) == -1) {
1087 1108 err = errno;
1088 1109 cryptoerror(LOG_STDERR,
1089 1110 gettext("failed to update the configuration - %s"),
1090 1111 strerror(err));
1091 1112 cryptodebug("failed to rename %s to %s: %s", tmpfile,
1092 1113 _PATH_KCF_CONF, strerror(err));
1093 1114 rc = FAILURE;
1094 1115 } else if (chmod(_PATH_KCF_CONF,
1095 1116 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) {
1096 1117 err = errno;
1097 1118 cryptoerror(LOG_STDERR,
1098 1119 gettext("failed to update the configuration - %s"),
1099 1120 strerror(err));
1100 1121 cryptodebug("failed to chmod to %s: %s", _PATH_KCF_CONF,
1101 1122 strerror(err));
1102 1123 rc = FAILURE;
1103 1124 } else {
1104 1125 rc = SUCCESS;
1105 1126 }
1106 1127
1107 1128 if ((rc == FAILURE) && (unlink(tmpfile_name) != 0)) {
1108 1129 err = errno;
1109 1130 cryptoerror(LOG_STDERR, gettext(
1110 1131 "(Warning) failed to remove %s: %s"),
1111 1132 tmpfile_name, strerror(err));
1112 1133 }
1113 1134
1114 1135 return (rc);
1115 1136 }
1116 1137
1117 1138
1118 1139 /*
1119 1140 * Disable the mechanisms for the provider pointed by *ppent. If allflag is
1120 1141 * TRUE, disable all. Otherwise, disable the mechanisms specified in the
1121 1142 * dislist argument. The "infolist" argument contains the mechanism list
1122 1143 * supported by this provider.
1123 1144 */
1124 1145 int
1125 1146 disable_mechs(entry_t **ppent, mechlist_t *infolist, boolean_t allflag,
1126 1147 mechlist_t *dislist)
1127 1148 {
1128 1149 entry_t *pent;
1129 1150 mechlist_t *plist = NULL;
1130 1151 mechlist_t *phead = NULL;
1131 1152 mechlist_t *pmech = NULL;
1132 1153 int rc = SUCCESS;
1133 1154
1134 1155 pent = *ppent;
1135 1156 if (pent == NULL) {
1136 1157 return (FAILURE);
1137 1158 }
1138 1159
1139 1160 if (allflag) {
1140 1161 free_mechlist(pent->dislist);
1141 1162 pent->dis_count = get_mech_count(infolist);
1142 1163 if (!(pent->dislist = dup_mechlist(infolist))) {
1143 1164 return (FAILURE);
1144 1165 } else {
1145 1166 return (SUCCESS);
1146 1167 }
1147 1168 }
1148 1169
1149 1170 /*
1150 1171 * Not disable all. Now loop thru the mechanisms specified in the
1151 1172 * dislist. If the mechanism is not supported by the provider,
1152 1173 * ignore it with a warning. If the mechanism is disabled already,
1153 1174 * do nothing. Otherwise, prepend it to the beginning of the disabled
1154 1175 * list of the provider.
1155 1176 */
1156 1177 plist = dislist;
1157 1178 while (plist != NULL) {
1158 1179 if (!is_in_list(plist->name, infolist)) {
1159 1180 cryptoerror(LOG_STDERR, gettext("(Warning) "
1160 1181 "%1$s is not a valid mechanism for %2$s."),
1161 1182 plist->name, pent->name);
1162 1183 } else if (!is_in_list(plist->name, pent->dislist)) {
1163 1184 /* Add this mechanism into the disabled list */
1164 1185 if ((pmech = create_mech(plist->name)) == NULL) {
1165 1186 rc = FAILURE;
1166 1187 break;
1167 1188 }
1168 1189
1169 1190 if (pent->dislist == NULL) {
1170 1191 pent->dislist = pmech;
1171 1192 } else {
1172 1193 phead = pent->dislist;
1173 1194 pent->dislist = pmech;
1174 1195 pmech->next = phead;
1175 1196 }
1176 1197 pent->dis_count++;
1177 1198 }
1178 1199 plist = plist->next;
1179 1200 }
1180 1201
1181 1202 return (rc);
1182 1203 }
1183 1204
1184 1205 /*
1185 1206 * Remove the mechanism passed, specified by mech, from the list of
1186 1207 * mechanisms, if present in the list. Else, do nothing.
1187 1208 *
1188 1209 * Returns B_TRUE if mechanism is present in the list.
1189 1210 */
1190 1211 boolean_t
1191 1212 filter_mechlist(mechlist_t **pmechlist, const char *mech)
1192 1213 {
1193 1214 int cnt = 0;
1194 1215 mechlist_t *ptr, *pptr;
1195 1216 boolean_t mech_present = B_FALSE;
1196 1217
1197 1218 ptr = pptr = *pmechlist;
1198 1219
1199 1220 while (ptr != NULL) {
1200 1221 if (strncmp(ptr->name, mech, sizeof (mech_name_t)) == 0) {
1201 1222 mech_present = B_TRUE;
1202 1223 if (ptr == *pmechlist) {
1203 1224 pptr = *pmechlist = ptr->next;
1204 1225 free(ptr);
1205 1226 ptr = pptr;
1206 1227 } else {
1207 1228 pptr->next = ptr->next;
1208 1229 free(ptr);
1209 1230 ptr = pptr->next;
1210 1231 }
1211 1232 } else {
1212 1233 pptr = ptr;
1213 1234 ptr = ptr->next;
1214 1235 cnt++;
1215 1236 }
1216 1237 }
1217 1238
1218 1239 /* Only one entry is present */
1219 1240 if (cnt == 0)
1220 1241 *pmechlist = NULL;
1221 1242
1222 1243 return (mech_present);
1223 1244 }
1224 1245
1225 1246
1226 1247
1227 1248 /*
1228 1249 * Print out the mechanism policy for a kernel provider that has an entry
1229 1250 * in the kcf.conf file.
1230 1251 *
1231 1252 * The flag has_random is set to B_TRUE if the provider does random
1232 1253 * numbers. The flag has_mechs is set by the caller to B_TRUE if the provider
1233 1254 * has some mechanisms.
1234 1255 *
1235 1256 * If pent is NULL, the provider doesn't have a kcf.conf entry.
1236 1257 */
1237 1258 void
1238 1259 print_kef_policy(char *provname, entry_t *pent, boolean_t has_random,
1239 1260 boolean_t has_mechs)
1240 1261 {
1241 1262 mechlist_t *ptr = NULL;
1242 1263 boolean_t rnd_disabled = B_FALSE;
1243 1264
1244 1265 if (pent != NULL) {
1245 1266 rnd_disabled = filter_mechlist(&pent->dislist, RANDOM);
1246 1267 ptr = pent->dislist;
1247 1268 }
1248 1269
1249 1270 (void) printf("%s:", provname);
1250 1271
1251 1272 if (has_mechs == B_TRUE) {
1252 1273 /*
1253 1274 * TRANSLATION_NOTE
1254 1275 * This code block may need to be modified a bit to avoid
1255 1276 * constructing the text message on the fly.
1256 1277 */
1257 1278 (void) printf(gettext(" all mechanisms are enabled"));
1258 1279 if (ptr != NULL)
1259 1280 (void) printf(gettext(", except "));
1260 1281 while (ptr != NULL) {
1261 1282 (void) printf("%s", ptr->name);
1262 1283 ptr = ptr->next;
1263 1284 if (ptr != NULL)
1264 1285 (void) printf(",");
1265 1286 }
1266 1287 if (ptr == NULL)
1267 1288 (void) printf(".");
1268 1289 }
1269 1290
1270 1291 /*
1271 1292 * TRANSLATION_NOTE
1272 1293 * "random" is a keyword and not to be translated.
1273 1294 */
1274 1295 if (rnd_disabled)
1275 1296 (void) printf(gettext(" %s is disabled."), "random");
1276 1297 else if (has_random)
1277 1298 (void) printf(gettext(" %s is enabled."), "random");
1278 1299 (void) printf("\n");
1279 1300 }
1280 1301
1281 1302
1282 1303 /*
1283 1304 * Check if a kernel software provider is in the kernel.
1284 1305 *
1285 1306 * Parameters:
1286 1307 * provname Provider name
1287 1308 * psoftlist_kernel Optional software provider list. If NULL, it will be
1288 1309 * obtained from get_soft_list().
1289 1310 * in_kernel Set to B_TRUE if device is in the kernel, else B_FALSE
1290 1311 */
1291 1312 int
1292 1313 check_kernel_for_soft(char *provname, crypto_get_soft_list_t *psoftlist_kernel,
1293 1314 boolean_t *in_kernel)
1294 1315 {
1295 1316 char *ptr;
1296 1317 int i;
1297 1318 boolean_t psoftlist_allocated = B_FALSE;
1298 1319
1299 1320 if (provname == NULL) {
1300 1321 cryptoerror(LOG_STDERR, gettext("internal error."));
1301 1322 return (FAILURE);
1302 1323 }
1303 1324
1304 1325 if (psoftlist_kernel == NULL) {
1305 1326 if (get_soft_list(&psoftlist_kernel) == FAILURE) {
1306 1327 cryptodebug("failed to get the software provider list"
1307 1328 " from kernel.");
1308 1329 return (FAILURE);
1309 1330 }
1310 1331 psoftlist_allocated = B_TRUE;
1311 1332 }
1312 1333
1313 1334 *in_kernel = B_FALSE;
1314 1335 ptr = psoftlist_kernel->sl_soft_names;
1315 1336 for (i = 0; i < psoftlist_kernel->sl_soft_count; i++) {
1316 1337 if (strcmp(provname, ptr) == 0) {
1317 1338 *in_kernel = B_TRUE;
1318 1339 break;
1319 1340 }
1320 1341 ptr = ptr + strlen(ptr) + 1;
1321 1342 }
1322 1343
1323 1344 if (psoftlist_allocated)
1324 1345 free(psoftlist_kernel);
1325 1346
1326 1347 return (SUCCESS);
1327 1348 }
1328 1349
1329 1350
1330 1351 /*
1331 1352 * Check if a kernel hardware provider is in the kernel.
1332 1353 *
1333 1354 * Parameters:
1334 1355 * provname Provider name
1335 1356 * pdevlist Optional Hardware Crypto Device List. If NULL, it will be
1336 1357 * obtained from get_dev_list().
1337 1358 * in_kernel Set to B_TRUE if device is in the kernel, otherwise B_FALSE
1338 1359 */
1339 1360 int
1340 1361 check_kernel_for_hard(char *provname,
1341 1362 crypto_get_dev_list_t *pdevlist, boolean_t *in_kernel)
1342 1363 {
1343 1364 char devname[MAXNAMELEN];
1344 1365 int inst_num;
1345 1366 int i;
1346 1367 boolean_t dev_list_allocated = B_FALSE;
1347 1368
1348 1369 if (provname == NULL) {
1349 1370 cryptoerror(LOG_STDERR, gettext("internal error."));
1350 1371 return (FAILURE);
1351 1372 }
1352 1373
1353 1374 if (split_hw_provname(provname, devname, &inst_num) == FAILURE) {
1354 1375 return (FAILURE);
1355 1376 }
1356 1377
1357 1378 if (pdevlist == NULL) {
1358 1379 if (get_dev_list(&pdevlist) == FAILURE) {
1359 1380 cryptoerror(LOG_STDERR, gettext("internal error."));
1360 1381 return (FAILURE);
1361 1382 }
1362 1383 dev_list_allocated = B_TRUE;
1363 1384 }
1364 1385
1365 1386 *in_kernel = B_FALSE;
1366 1387 for (i = 0; i < pdevlist->dl_dev_count; i++) {
1367 1388 if ((strcmp(pdevlist->dl_devs[i].le_dev_name, devname) == 0) &&
1368 1389 (pdevlist->dl_devs[i].le_dev_instance == inst_num)) {
1369 1390 *in_kernel = B_TRUE;
1370 1391 break;
1371 1392 }
1372 1393 }
1373 1394
1374 1395 if (dev_list_allocated)
1375 1396 free(pdevlist);
1376 1397
1377 1398 return (SUCCESS);
1378 1399 }
↓ open down ↓ |
947 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX