OLD | NEW |
1 /* This Source Code Form is subject to the terms of the Mozilla Public | 1 /* This Source Code Form is subject to the terms of the Mozilla Public |
2 * License, v. 2.0. If a copy of the MPL was not distributed with this | 2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
4 /* | 4 /* |
5 * The following code handles the storage of PKCS 11 modules used by the | 5 * The following code handles the storage of PKCS 11 modules used by the |
6 * NSS. For the rest of NSS, only one kind of database handle exists: | 6 * NSS. For the rest of NSS, only one kind of database handle exists: |
7 * | 7 * |
8 * SFTKDBHandle | 8 * SFTKDBHandle |
9 * | 9 * |
10 * There is one SFTKDBHandle for each key database and one for each cert | 10 * There is one SFTKDBHandle for each key database and one for each cert |
11 * database. These databases are opened as associated pairs, one pair per | 11 * database. These databases are opened as associated pairs, one pair per |
12 * slot. SFTKDBHandles are reference counted objects. | 12 * slot. SFTKDBHandles are reference counted objects. |
13 * | 13 * |
14 * Each SFTKDBHandle points to a low level database handle (SDB). This handle | 14 * Each SFTKDBHandle points to a low level database handle (SDB). This handle |
15 * represents the underlying physical database. These objects are not | 15 * represents the underlying physical database. These objects are not |
16 * reference counted, and are 'owned' by their respective SFTKDBHandles. | 16 * reference counted, and are 'owned' by their respective SFTKDBHandles. |
17 */ | 17 */ |
18 | 18 |
19 #include "prprf.h" | 19 #include "prprf.h" |
20 #include "prsystem.h" | 20 #include "prsystem.h" |
21 #include "secport.h" | 21 #include "secport.h" |
22 #include "utilpars.h" | 22 #include "utilpars.h" |
23 #include "secerr.h" | 23 #include "secerr.h" |
| 24 |
24 #if defined (_WIN32) | 25 #if defined (_WIN32) |
25 #include <io.h> | 26 #include <io.h> |
26 #endif | 27 #endif |
| 28 #ifdef XP_UNIX |
| 29 #include <unistd.h> |
| 30 #endif |
| 31 |
| 32 #include <sys/types.h> |
| 33 #include <sys/stat.h> |
| 34 #include <fcntl.h> |
| 35 |
| 36 #if defined (_WIN32) |
| 37 #define os_open _open |
| 38 #define os_fdopen _fdopen |
| 39 #define os_stat _stat |
| 40 #define os_truncate_open_flags _O_CREAT|_O_RDWR|_O_TRUNC |
| 41 #define os_append_open_flags _O_CREAT|_O_RDWR|_O_APPEND |
| 42 #define os_open_permissions_type int |
| 43 #define os_open_permissions_default _S_IREAD | _S_IWRITE |
| 44 #define os_stat_type struct _stat |
| 45 #else |
| 46 #define os_open open |
| 47 #define os_fdopen fdopen |
| 48 #define os_stat stat |
| 49 #define os_truncate_open_flags O_CREAT|O_RDWR|O_TRUNC |
| 50 #define os_append_open_flags O_CREAT|O_RDWR|O_APPEND |
| 51 #define os_open_permissions_type mode_t |
| 52 #define os_open_permissions_default 0600 |
| 53 #define os_stat_type struct stat |
| 54 #endif |
27 | 55 |
28 /**************************************************************** | 56 /**************************************************************** |
29 * | 57 * |
30 * Secmod database. | 58 * Secmod database. |
31 * | 59 * |
32 * The new secmod database is simply a text file with each of the module | 60 * The new secmod database is simply a text file with each of the module |
33 * entries in the following form: | 61 * entries in the following form: |
34 * | 62 * |
35 * # | 63 * # |
36 * # This is a comment The next line is the library to load | 64 * # This is a comment The next line is the library to load |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 if (sep) { | 153 if (sep) { |
126 *sep = 0; | 154 *sep = 0; |
127 file = PR_smprintf("%s"NSSUTIL_PATH_SEPARATOR"%s", dirPath, filename); | 155 file = PR_smprintf("%s"NSSUTIL_PATH_SEPARATOR"%s", dirPath, filename); |
128 } else { | 156 } else { |
129 file = PR_smprintf("%s", filename); | 157 file = PR_smprintf("%s", filename); |
130 } | 158 } |
131 PORT_Free(dirPath); | 159 PORT_Free(dirPath); |
132 return file; | 160 return file; |
133 } | 161 } |
134 | 162 |
135 static SECStatus nssutil_AddSecmodDB(const char *appName, | 163 static SECStatus nssutil_AddSecmodDBEntry(const char *appName, |
136 » » const char *filename, const char *dbname, | 164 const char *filename, |
137 » » char *module, PRBool rw); | 165 const char *dbname, |
| 166 char *module, PRBool rw); |
138 | 167 |
139 #ifdef XP_UNIX | 168 enum lfopen_mode { lfopen_truncate, lfopen_append }; |
140 #include <unistd.h> | |
141 #endif | |
142 #include <fcntl.h> | |
143 | 169 |
144 /* same as fopen, except it doesn't use umask, but explicit */ | |
145 FILE * | 170 FILE * |
146 lfopen(const char *name, const char *mode, int flags) | 171 lfopen(const char *name, enum lfopen_mode om, os_open_permissions_type open_perm
s) |
147 { | 172 { |
148 int fd; | 173 int fd; |
149 FILE *file; | 174 FILE *file; |
150 | 175 |
151 fd = open(name, flags, 0600); | 176 fd = os_open(name, |
| 177 (om == lfopen_truncate) ? os_truncate_open_flags : os_append_op
en_flags, |
| 178 open_perms); |
152 if (fd < 0) { | 179 if (fd < 0) { |
153 return NULL; | 180 return NULL; |
154 } | 181 } |
155 file = fdopen(fd, mode); | 182 file = os_fdopen(fd, (om == lfopen_truncate) ? "w+" : "a+"); |
156 if (!file) { | 183 if (!file) { |
157 close(fd); | 184 close(fd); |
158 } | 185 } |
159 /* file inherits fd */ | 186 /* file inherits fd */ |
160 return file; | 187 return file; |
161 } | 188 } |
162 | 189 |
163 #define MAX_LINE_LENGTH 2048 | 190 #define MAX_LINE_LENGTH 2048 |
164 | 191 |
165 /* | 192 /* |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 if (failed || (moduleList[0] == NULL)) { | 436 if (failed || (moduleList[0] == NULL)) { |
410 /* This is wrong! FIXME */ | 437 /* This is wrong! FIXME */ |
411 nssutil_releaseSpecList(moduleList); | 438 nssutil_releaseSpecList(moduleList); |
412 moduleList = NULL; | 439 moduleList = NULL; |
413 failed = PR_TRUE; | 440 failed = PR_TRUE; |
414 } | 441 } |
415 if (fd != NULL) { | 442 if (fd != NULL) { |
416 fclose(fd); | 443 fclose(fd); |
417 } else if (!failed && rw) { | 444 } else if (!failed && rw) { |
418 /* update our internal module */ | 445 /* update our internal module */ |
419 » nssutil_AddSecmodDB(appName,filename,dbname,moduleList[0],rw); | 446 » nssutil_AddSecmodDBEntry(appName, filename, dbname, moduleList[0], rw); |
420 } | 447 } |
421 return moduleList; | 448 return moduleList; |
422 } | 449 } |
423 | 450 |
424 static SECStatus | 451 static SECStatus |
425 nssutil_ReleaseSecmodDBData(const char *appName, | 452 nssutil_ReleaseSecmodDBData(const char *appName, |
426 const char *filename, const char *dbname, | 453 const char *filename, const char *dbname, |
427 char **moduleSpecList, PRBool rw) | 454 char **moduleSpecList, PRBool rw) |
428 { | 455 { |
429 if (moduleSpecList) { | 456 if (moduleSpecList) { |
430 nssutil_releaseSpecList(moduleSpecList); | 457 nssutil_releaseSpecList(moduleSpecList); |
431 } | 458 } |
432 return SECSuccess; | 459 return SECSuccess; |
433 } | 460 } |
434 | 461 |
435 | 462 |
436 /* | 463 /* |
437 * Delete a module from the Data Base | 464 * Delete a module from the Data Base |
438 */ | 465 */ |
439 static SECStatus | 466 static SECStatus |
440 nssutil_DeleteSecmodDB(const char *appName, | 467 nssutil_DeleteSecmodDBEntry(const char *appName, |
441 » » const char *filename, const char *dbname, | 468 const char *filename, |
442 » » char *args, PRBool rw) | 469 const char *dbname, |
| 470 char *args, |
| 471 PRBool rw) |
443 { | 472 { |
444 /* SHDB_FIXME implement */ | 473 /* SHDB_FIXME implement */ |
| 474 os_stat_type stat_existing; |
| 475 os_open_permissions_type file_mode; |
445 FILE *fd = NULL; | 476 FILE *fd = NULL; |
446 FILE *fd2 = NULL; | 477 FILE *fd2 = NULL; |
447 char line[MAX_LINE_LENGTH]; | 478 char line[MAX_LINE_LENGTH]; |
448 char *dbname2 = NULL; | 479 char *dbname2 = NULL; |
449 char *block = NULL; | 480 char *block = NULL; |
450 char *name = NULL; | 481 char *name = NULL; |
451 char *lib = NULL; | 482 char *lib = NULL; |
452 int name_len, lib_len; | 483 int name_len, lib_len; |
453 PRBool skip = PR_FALSE; | 484 PRBool skip = PR_FALSE; |
454 PRBool found = PR_FALSE; | 485 PRBool found = PR_FALSE; |
455 | 486 |
456 if (dbname == NULL) { | 487 if (dbname == NULL) { |
457 PORT_SetError(SEC_ERROR_INVALID_ARGS); | 488 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
458 return SECFailure; | 489 return SECFailure; |
459 } | 490 } |
460 | 491 |
461 if (!rw) { | 492 if (!rw) { |
462 PORT_SetError(SEC_ERROR_READ_ONLY); | 493 PORT_SetError(SEC_ERROR_READ_ONLY); |
463 return SECFailure; | 494 return SECFailure; |
464 } | 495 } |
465 | 496 |
466 dbname2 = PORT_Strdup(dbname); | 497 dbname2 = PORT_Strdup(dbname); |
467 if (dbname2 == NULL) goto loser; | 498 if (dbname2 == NULL) goto loser; |
468 dbname2[strlen(dbname)-1]++; | 499 dbname2[strlen(dbname)-1]++; |
469 | 500 |
| 501 /* get the permissions of the existing file, or use the default */ |
| 502 if (!os_stat(dbname, &stat_existing)) { |
| 503 file_mode = stat_existing.st_mode; |
| 504 } else { |
| 505 file_mode = os_open_permissions_default; |
| 506 } |
| 507 |
470 /* do we really want to use streams here */ | 508 /* do we really want to use streams here */ |
471 fd = fopen(dbname, "r"); | 509 fd = fopen(dbname, "r"); |
472 if (fd == NULL) goto loser; | 510 if (fd == NULL) goto loser; |
473 fd2 = lfopen(dbname2, "w+", O_CREAT|O_RDWR|O_TRUNC); | 511 |
| 512 fd2 = lfopen(dbname2, lfopen_truncate, file_mode); |
| 513 |
474 if (fd2 == NULL) goto loser; | 514 if (fd2 == NULL) goto loser; |
475 | 515 |
476 name = NSSUTIL_ArgGetParamValue("name",args); | 516 name = NSSUTIL_ArgGetParamValue("name",args); |
477 if (name) { | 517 if (name) { |
478 name_len = PORT_Strlen(name); | 518 name_len = PORT_Strlen(name); |
479 } | 519 } |
480 lib = NSSUTIL_ArgGetParamValue("library",args); | 520 lib = NSSUTIL_ArgGetParamValue("library",args); |
481 if (lib) { | 521 if (lib) { |
482 lib_len = PORT_Strlen(lib); | 522 lib_len = PORT_Strlen(lib); |
483 } | 523 } |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
559 } | 599 } |
560 PORT_Free(lib); | 600 PORT_Free(lib); |
561 PORT_Free(name); | 601 PORT_Free(name); |
562 return SECFailure; | 602 return SECFailure; |
563 } | 603 } |
564 | 604 |
565 /* | 605 /* |
566 * Add a module to the Data base | 606 * Add a module to the Data base |
567 */ | 607 */ |
568 static SECStatus | 608 static SECStatus |
569 nssutil_AddSecmodDB(const char *appName, | 609 nssutil_AddSecmodDBEntry(const char *appName, |
570 » » const char *filename, const char *dbname, | 610 const char *filename, const char *dbname, |
571 » » char *module, PRBool rw) | 611 char *module, PRBool rw) |
572 { | 612 { |
| 613 os_stat_type stat_existing; |
| 614 os_open_permissions_type file_mode; |
573 FILE *fd = NULL; | 615 FILE *fd = NULL; |
574 char *block = NULL; | 616 char *block = NULL; |
575 PRBool libFound = PR_FALSE; | 617 PRBool libFound = PR_FALSE; |
576 | 618 |
577 if (dbname == NULL) { | 619 if (dbname == NULL) { |
578 PORT_SetError(SEC_ERROR_INVALID_ARGS); | 620 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
579 return SECFailure; | 621 return SECFailure; |
580 } | 622 } |
581 | 623 |
582 /* can't write to a read only module */ | 624 /* can't write to a read only module */ |
583 if (!rw) { | 625 if (!rw) { |
584 PORT_SetError(SEC_ERROR_READ_ONLY); | 626 PORT_SetError(SEC_ERROR_READ_ONLY); |
585 return SECFailure; | 627 return SECFailure; |
586 } | 628 } |
587 | 629 |
588 /* remove the previous version if it exists */ | 630 /* remove the previous version if it exists */ |
589 (void) nssutil_DeleteSecmodDB(appName, filename, | 631 (void) nssutil_DeleteSecmodDBEntry(appName, filename, dbname, module, rw); |
590 » » » » dbname, module, rw); | |
591 | 632 |
592 fd = lfopen(dbname, "a+", O_CREAT|O_RDWR|O_APPEND); | 633 /* get the permissions of the existing file, or use the default */ |
| 634 if (!os_stat(dbname, &stat_existing)) { |
| 635 » file_mode = stat_existing.st_mode; |
| 636 } else { |
| 637 » file_mode = os_open_permissions_default; |
| 638 } |
| 639 |
| 640 fd = lfopen(dbname, lfopen_append, file_mode); |
593 if (fd == NULL) { | 641 if (fd == NULL) { |
594 return SECFailure; | 642 return SECFailure; |
595 } | 643 } |
596 module = NSSUTIL_ArgStrip(module); | 644 module = NSSUTIL_ArgStrip(module); |
597 while (*module) { | 645 while (*module) { |
598 int count; | 646 int count; |
599 char *keyEnd = PORT_Strchr(module,'='); | 647 char *keyEnd = PORT_Strchr(module,'='); |
600 char *value; | 648 char *value; |
601 | 649 |
602 if (PORT_Strncmp(module, "library=", 8) == 0) { | 650 if (PORT_Strncmp(module, "library=", 8) == 0) { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
658 rvstr = NULL; | 706 rvstr = NULL; |
659 goto done; | 707 goto done; |
660 } | 708 } |
661 | 709 |
662 switch (function) { | 710 switch (function) { |
663 case SECMOD_MODULE_DB_FUNCTION_FIND: | 711 case SECMOD_MODULE_DB_FUNCTION_FIND: |
664 rvstr = nssutil_ReadSecmodDB(appName,filename, | 712 rvstr = nssutil_ReadSecmodDB(appName,filename, |
665 secmod,(char *)parameters,rw); | 713 secmod,(char *)parameters,rw); |
666 break; | 714 break; |
667 case SECMOD_MODULE_DB_FUNCTION_ADD: | 715 case SECMOD_MODULE_DB_FUNCTION_ADD: |
668 rvstr = (nssutil_AddSecmodDB(appName,filename, | 716 rvstr = (nssutil_AddSecmodDBEntry(appName, filename, |
669 » » secmod,(char *)args,rw) == SECSuccess) ? &success: NULL; | 717 secmod, (char *)args, rw) |
| 718 == SECSuccess) ? &success: NULL; |
670 break; | 719 break; |
671 case SECMOD_MODULE_DB_FUNCTION_DEL: | 720 case SECMOD_MODULE_DB_FUNCTION_DEL: |
672 rvstr = (nssutil_DeleteSecmodDB(appName,filename, | 721 rvstr = (nssutil_DeleteSecmodDBEntry(appName, filename, |
673 » » secmod,(char *)args,rw) == SECSuccess) ? &success: NULL; | 722 secmod, (char *)args, rw) |
| 723 == SECSuccess) ? &success: NULL; |
674 break; | 724 break; |
675 case SECMOD_MODULE_DB_FUNCTION_RELEASE: | 725 case SECMOD_MODULE_DB_FUNCTION_RELEASE: |
676 rvstr = (nssutil_ReleaseSecmodDBData(appName,filename, | 726 rvstr = (nssutil_ReleaseSecmodDBData(appName, filename, |
677 » » secmod, (char **)args,rw) == SECSuccess) ? &success: NULL; | 727 secmod, (char **)args, rw) |
| 728 == SECSuccess) ? &success: NULL; |
678 break; | 729 break; |
679 } | 730 } |
680 done: | 731 done: |
681 if (secmod) PR_smprintf_free(secmod); | 732 if (secmod) PR_smprintf_free(secmod); |
682 if (appName) PORT_Free(appName); | 733 if (appName) PORT_Free(appName); |
683 if (filename) PORT_Free(filename); | 734 if (filename) PORT_Free(filename); |
684 return rvstr; | 735 return rvstr; |
685 } | 736 } |
OLD | NEW |