| 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 |