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