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