1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/cmd/modutil/modutil.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,952 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +/* To edit this file, set TABSTOPS to 4 spaces. 1.9 + * This is not the normal NSS convention. 1.10 + */ 1.11 + 1.12 +#include "modutil.h" 1.13 +#include "install.h" 1.14 +#include <plstr.h> 1.15 +#include "certdb.h" /* for CERT_DB_FILE_VERSION */ 1.16 +#include "nss.h" 1.17 + 1.18 +static void install_error(char *message); 1.19 +static char* PR_fgets(char *buf, int size, PRFileDesc *file); 1.20 +static char *progName; 1.21 + 1.22 + 1.23 +/* This enum must be kept in sync with the commandNames list */ 1.24 +typedef enum { 1.25 + NO_COMMAND, 1.26 + ADD_COMMAND, 1.27 + CHANGEPW_COMMAND, 1.28 + CREATE_COMMAND, 1.29 + DEFAULT_COMMAND, 1.30 + DELETE_COMMAND, 1.31 + DISABLE_COMMAND, 1.32 + ENABLE_COMMAND, 1.33 + FIPS_COMMAND, 1.34 + JAR_COMMAND, 1.35 + LIST_COMMAND, 1.36 + RAW_LIST_COMMAND, 1.37 + RAW_ADD_COMMAND, 1.38 + CHKFIPS_COMMAND, 1.39 + UNDEFAULT_COMMAND 1.40 +} Command; 1.41 + 1.42 +/* This list must be kept in sync with the Command enum */ 1.43 +static char *commandNames[] = { 1.44 + "(no command)", 1.45 + "-add", 1.46 + "-changepw", 1.47 + "-create", 1.48 + "-default", 1.49 + "-delete", 1.50 + "-disable", 1.51 + "-enable", 1.52 + "-fips", 1.53 + "-jar", 1.54 + "-list", 1.55 + "-rawlist", 1.56 + "-rawadd", 1.57 + "-chkfips", 1.58 + "-undefault" 1.59 +}; 1.60 + 1.61 + 1.62 +/* this enum must be kept in sync with the optionStrings list */ 1.63 +typedef enum { 1.64 + ADD_ARG=0, 1.65 + RAW_ADD_ARG, 1.66 + CHANGEPW_ARG, 1.67 + CIPHERS_ARG, 1.68 + CREATE_ARG, 1.69 + DBDIR_ARG, 1.70 + DBPREFIX_ARG, 1.71 + DEFAULT_ARG, 1.72 + DELETE_ARG, 1.73 + DISABLE_ARG, 1.74 + ENABLE_ARG, 1.75 + FIPS_ARG, 1.76 + FORCE_ARG, 1.77 + JAR_ARG, 1.78 + LIBFILE_ARG, 1.79 + LIST_ARG, 1.80 + RAW_LIST_ARG, 1.81 + MECHANISMS_ARG, 1.82 + NEWPWFILE_ARG, 1.83 + PWFILE_ARG, 1.84 + SLOT_ARG, 1.85 + UNDEFAULT_ARG, 1.86 + INSTALLDIR_ARG, 1.87 + TEMPDIR_ARG, 1.88 + SECMOD_ARG, 1.89 + NOCERTDB_ARG, 1.90 + STRING_ARG, 1.91 + CHKFIPS_ARG, 1.92 + 1.93 + NUM_ARGS /* must be last */ 1.94 +} Arg; 1.95 + 1.96 +/* This list must be kept in sync with the Arg enum */ 1.97 +static char *optionStrings[] = { 1.98 + "-add", 1.99 + "-rawadd", 1.100 + "-changepw", 1.101 + "-ciphers", 1.102 + "-create", 1.103 + "-dbdir", 1.104 + "-dbprefix", 1.105 + "-default", 1.106 + "-delete", 1.107 + "-disable", 1.108 + "-enable", 1.109 + "-fips", 1.110 + "-force", 1.111 + "-jar", 1.112 + "-libfile", 1.113 + "-list", 1.114 + "-rawlist", 1.115 + "-mechanisms", 1.116 + "-newpwfile", 1.117 + "-pwfile", 1.118 + "-slot", 1.119 + "-undefault", 1.120 + "-installdir", 1.121 + "-tempdir", 1.122 + "-secmod", 1.123 + "-nocertdb", 1.124 + "-string", 1.125 + "-chkfips", 1.126 +}; 1.127 + 1.128 +/* Increment i if doing so would have i still be less than j. If you 1.129 + are able to do this, return 0. Otherwise return 1. */ 1.130 +#define TRY_INC(i,j) ( ((i+1)<j) ? (++i, 0) : 1 ) 1.131 + 1.132 +/******************************************************************** 1.133 + * 1.134 + * file-wide variables obtained from the command line 1.135 + */ 1.136 +static Command command = NO_COMMAND; 1.137 +static char* pwFile = NULL; 1.138 +static char* newpwFile = NULL; 1.139 +static char* moduleName = NULL; 1.140 +static char* moduleSpec = NULL; 1.141 +static char* slotName = NULL; 1.142 +static char* secmodName = NULL; 1.143 +static char* tokenName = NULL; 1.144 +static char* libFile = NULL; 1.145 +static char* dbdir = NULL; 1.146 +static char* dbprefix = ""; 1.147 +static char* secmodString = NULL; 1.148 +static char* mechanisms = NULL; 1.149 +static char* ciphers = NULL; 1.150 +static char* fipsArg = NULL; 1.151 +static char* jarFile = NULL; 1.152 +static char* installDir = NULL; 1.153 +static char* tempDir = NULL; 1.154 +static short force = 0; 1.155 +static PRBool nocertdb = PR_FALSE; 1.156 + 1.157 +/******************************************************************* 1.158 + * 1.159 + * p a r s e _ a r g s 1.160 + */ 1.161 +static Error 1.162 +parse_args(int argc, char *argv[]) 1.163 +{ 1.164 + int i; 1.165 + char *arg; 1.166 + int optionType; 1.167 + 1.168 + /* Loop over all arguments */ 1.169 + for(i=1; i < argc; i++) { 1.170 + arg = argv[i]; 1.171 + 1.172 + /* Make sure this is an option and not some floating argument */ 1.173 + if(arg[0] != '-') { 1.174 + PR_fprintf(PR_STDERR, errStrings[UNEXPECTED_ARG_ERR], argv[i]); 1.175 + return UNEXPECTED_ARG_ERR; 1.176 + } 1.177 + 1.178 + /* Find which option this is */ 1.179 + for(optionType=0; optionType < NUM_ARGS; optionType++) { 1.180 + if(! strcmp(arg, optionStrings[optionType])) { 1.181 + break; 1.182 + } 1.183 + } 1.184 + 1.185 + /* Deal with this specific option */ 1.186 + switch(optionType) { 1.187 + case NUM_ARGS: 1.188 + default: 1.189 + PR_fprintf(PR_STDERR, errStrings[UNKNOWN_OPTION_ERR], arg); 1.190 + return UNKNOWN_OPTION_ERR; 1.191 + break; 1.192 + case ADD_ARG: 1.193 + if(command != NO_COMMAND) { 1.194 + PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg); 1.195 + return MULTIPLE_COMMAND_ERR; 1.196 + } 1.197 + command = ADD_COMMAND; 1.198 + if(TRY_INC(i, argc)) { 1.199 + PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg); 1.200 + return OPTION_NEEDS_ARG_ERR; 1.201 + } 1.202 + moduleName = argv[i]; 1.203 + break; 1.204 + case CHANGEPW_ARG: 1.205 + if(command != NO_COMMAND) { 1.206 + PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg); 1.207 + return MULTIPLE_COMMAND_ERR; 1.208 + } 1.209 + command = CHANGEPW_COMMAND; 1.210 + if(TRY_INC(i, argc)) { 1.211 + PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg); 1.212 + return OPTION_NEEDS_ARG_ERR; 1.213 + } 1.214 + tokenName = argv[i]; 1.215 + break; 1.216 + case CIPHERS_ARG: 1.217 + if(ciphers != NULL) { 1.218 + PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg); 1.219 + return DUPLICATE_OPTION_ERR; 1.220 + } 1.221 + if(TRY_INC(i, argc)) { 1.222 + PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg); 1.223 + return OPTION_NEEDS_ARG_ERR; 1.224 + } 1.225 + ciphers = argv[i]; 1.226 + break; 1.227 + case CREATE_ARG: 1.228 + if(command != NO_COMMAND) { 1.229 + PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg); 1.230 + return MULTIPLE_COMMAND_ERR; 1.231 + } 1.232 + command = CREATE_COMMAND; 1.233 + break; 1.234 + case DBDIR_ARG: 1.235 + if(dbdir != NULL) { 1.236 + PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg); 1.237 + return DUPLICATE_OPTION_ERR; 1.238 + } 1.239 + if(TRY_INC(i, argc)) { 1.240 + PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg); 1.241 + return OPTION_NEEDS_ARG_ERR; 1.242 + } 1.243 + dbdir = argv[i]; 1.244 + break; 1.245 + case DBPREFIX_ARG: 1.246 + if(TRY_INC(i, argc)) { 1.247 + PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg); 1.248 + return OPTION_NEEDS_ARG_ERR; 1.249 + } 1.250 + dbprefix = argv[i]; 1.251 + break; 1.252 + case UNDEFAULT_ARG: 1.253 + case DEFAULT_ARG: 1.254 + if(command != NO_COMMAND) { 1.255 + PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg); 1.256 + return MULTIPLE_COMMAND_ERR; 1.257 + } 1.258 + if(optionType == DEFAULT_ARG) { 1.259 + command = DEFAULT_COMMAND; 1.260 + } else { 1.261 + command = UNDEFAULT_COMMAND; 1.262 + } 1.263 + if(TRY_INC(i, argc)) { 1.264 + PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg); 1.265 + return OPTION_NEEDS_ARG_ERR; 1.266 + } 1.267 + moduleName = argv[i]; 1.268 + break; 1.269 + case DELETE_ARG: 1.270 + if(command != NO_COMMAND) { 1.271 + PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg); 1.272 + return MULTIPLE_COMMAND_ERR; 1.273 + } 1.274 + command = DELETE_COMMAND; 1.275 + if(TRY_INC(i, argc)) { 1.276 + PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg); 1.277 + return OPTION_NEEDS_ARG_ERR; 1.278 + } 1.279 + moduleName = argv[i]; 1.280 + break; 1.281 + case DISABLE_ARG: 1.282 + if(command != NO_COMMAND) { 1.283 + PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg); 1.284 + return MULTIPLE_COMMAND_ERR; 1.285 + } 1.286 + command = DISABLE_COMMAND; 1.287 + if(TRY_INC(i, argc)) { 1.288 + PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg); 1.289 + return OPTION_NEEDS_ARG_ERR; 1.290 + } 1.291 + moduleName = argv[i]; 1.292 + break; 1.293 + case ENABLE_ARG: 1.294 + if(command != NO_COMMAND) { 1.295 + PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg); 1.296 + return MULTIPLE_COMMAND_ERR; 1.297 + } 1.298 + command = ENABLE_COMMAND; 1.299 + if(TRY_INC(i, argc)) { 1.300 + PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg); 1.301 + return OPTION_NEEDS_ARG_ERR; 1.302 + } 1.303 + moduleName = argv[i]; 1.304 + break; 1.305 + case FIPS_ARG: 1.306 + if(command != NO_COMMAND) { 1.307 + PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg); 1.308 + return MULTIPLE_COMMAND_ERR; 1.309 + } 1.310 + command = FIPS_COMMAND; 1.311 + if(TRY_INC(i, argc)) { 1.312 + PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg); 1.313 + return OPTION_NEEDS_ARG_ERR; 1.314 + } 1.315 + fipsArg = argv[i]; 1.316 + break; 1.317 + case CHKFIPS_ARG: 1.318 + if(command != NO_COMMAND) { 1.319 + PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg); 1.320 + return MULTIPLE_COMMAND_ERR; 1.321 + } 1.322 + command = CHKFIPS_COMMAND; 1.323 + if(TRY_INC(i, argc)) { 1.324 + PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg); 1.325 + return OPTION_NEEDS_ARG_ERR; 1.326 + } 1.327 + fipsArg = argv[i]; 1.328 + break; 1.329 + case FORCE_ARG: 1.330 + force = 1; 1.331 + break; 1.332 + case NOCERTDB_ARG: 1.333 + nocertdb = PR_TRUE; 1.334 + break; 1.335 + case INSTALLDIR_ARG: 1.336 + if(installDir != NULL) { 1.337 + PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg); 1.338 + return DUPLICATE_OPTION_ERR; 1.339 + } 1.340 + if(TRY_INC(i, argc)) { 1.341 + PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg); 1.342 + return OPTION_NEEDS_ARG_ERR; 1.343 + } 1.344 + installDir = argv[i]; 1.345 + break; 1.346 + case TEMPDIR_ARG: 1.347 + if(tempDir != NULL) { 1.348 + PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg); 1.349 + return DUPLICATE_OPTION_ERR; 1.350 + } 1.351 + if(TRY_INC(i, argc)) { 1.352 + PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg); 1.353 + return OPTION_NEEDS_ARG_ERR; 1.354 + } 1.355 + tempDir = argv[i]; 1.356 + break; 1.357 + case JAR_ARG: 1.358 + if(command != NO_COMMAND) { 1.359 + PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg); 1.360 + return MULTIPLE_COMMAND_ERR; 1.361 + } 1.362 + command = JAR_COMMAND; 1.363 + if(TRY_INC(i, argc)) { 1.364 + PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg); 1.365 + return OPTION_NEEDS_ARG_ERR; 1.366 + } 1.367 + jarFile = argv[i]; 1.368 + break; 1.369 + case LIBFILE_ARG: 1.370 + if(libFile != NULL) { 1.371 + PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg); 1.372 + return DUPLICATE_OPTION_ERR; 1.373 + } 1.374 + if(TRY_INC(i, argc)) { 1.375 + PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg); 1.376 + return OPTION_NEEDS_ARG_ERR; 1.377 + } 1.378 + libFile = argv[i]; 1.379 + break; 1.380 + case LIST_ARG: 1.381 + if(command != NO_COMMAND) { 1.382 + PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg); 1.383 + return MULTIPLE_COMMAND_ERR; 1.384 + } 1.385 + command = LIST_COMMAND; 1.386 + /* This option may or may not have an argument */ 1.387 + if( (i+1 < argc) && (argv[i+1][0] != '-') ) { 1.388 + moduleName = argv[++i]; 1.389 + } 1.390 + break; 1.391 + case RAW_LIST_ARG: 1.392 + if(command != NO_COMMAND) { 1.393 + PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg); 1.394 + return MULTIPLE_COMMAND_ERR; 1.395 + } 1.396 + command = RAW_LIST_COMMAND; 1.397 + /* This option may or may not have an argument */ 1.398 + if( (i+1 < argc) && (argv[i+1][0] != '-') ) { 1.399 + moduleName = argv[++i]; 1.400 + } 1.401 + break; 1.402 + case RAW_ADD_ARG: 1.403 + if(command != NO_COMMAND) { 1.404 + PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg); 1.405 + return MULTIPLE_COMMAND_ERR; 1.406 + } 1.407 + command = RAW_ADD_COMMAND; 1.408 + if(TRY_INC(i, argc)) { 1.409 + PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg); 1.410 + return OPTION_NEEDS_ARG_ERR; 1.411 + } 1.412 + moduleSpec = argv[i]; 1.413 + break; 1.414 + case MECHANISMS_ARG: 1.415 + if(mechanisms != NULL) { 1.416 + PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg); 1.417 + return DUPLICATE_OPTION_ERR; 1.418 + } 1.419 + if(TRY_INC(i, argc)) { 1.420 + PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg); 1.421 + return OPTION_NEEDS_ARG_ERR; 1.422 + } 1.423 + mechanisms = argv[i]; 1.424 + break; 1.425 + case NEWPWFILE_ARG: 1.426 + if(newpwFile != NULL) { 1.427 + PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg); 1.428 + return DUPLICATE_OPTION_ERR; 1.429 + } 1.430 + if(TRY_INC(i, argc)) { 1.431 + PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg); 1.432 + return OPTION_NEEDS_ARG_ERR; 1.433 + } 1.434 + newpwFile = argv[i]; 1.435 + break; 1.436 + case PWFILE_ARG: 1.437 + if(pwFile != NULL) { 1.438 + PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg); 1.439 + return DUPLICATE_OPTION_ERR; 1.440 + } 1.441 + if(TRY_INC(i, argc)) { 1.442 + PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg); 1.443 + return OPTION_NEEDS_ARG_ERR; 1.444 + } 1.445 + pwFile = argv[i]; 1.446 + break; 1.447 + case SLOT_ARG: 1.448 + if(slotName != NULL) { 1.449 + PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg); 1.450 + return DUPLICATE_OPTION_ERR; 1.451 + } 1.452 + if(TRY_INC(i, argc)) { 1.453 + PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg); 1.454 + return OPTION_NEEDS_ARG_ERR; 1.455 + } 1.456 + slotName = argv[i]; 1.457 + break; 1.458 + case SECMOD_ARG: 1.459 + if(secmodName != NULL) { 1.460 + PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg); 1.461 + return DUPLICATE_OPTION_ERR; 1.462 + } 1.463 + if(TRY_INC(i, argc)) { 1.464 + PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg); 1.465 + return OPTION_NEEDS_ARG_ERR; 1.466 + } 1.467 + secmodName = argv[i]; 1.468 + break; 1.469 + case STRING_ARG: 1.470 + if(secmodString != NULL) { 1.471 + PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg); 1.472 + return DUPLICATE_OPTION_ERR; 1.473 + } 1.474 + if(TRY_INC(i, argc)) { 1.475 + PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg); 1.476 + return OPTION_NEEDS_ARG_ERR; 1.477 + } 1.478 + secmodString = argv[i]; 1.479 + break; 1.480 + } 1.481 + } 1.482 + return SUCCESS; 1.483 +} 1.484 + 1.485 +/************************************************************************ 1.486 + * 1.487 + * v e r i f y _ p a r a m s 1.488 + */ 1.489 +static Error 1.490 +verify_params() 1.491 +{ 1.492 + switch(command) { 1.493 + case ADD_COMMAND: 1.494 + if(libFile == NULL) { 1.495 + PR_fprintf(PR_STDERR, errStrings[MISSING_PARAM_ERR], 1.496 + commandNames[ADD_COMMAND], optionStrings[LIBFILE_ARG]); 1.497 + return MISSING_PARAM_ERR; 1.498 + } 1.499 + break; 1.500 + case CHANGEPW_COMMAND: 1.501 + break; 1.502 + case CREATE_COMMAND: 1.503 + break; 1.504 + case DELETE_COMMAND: 1.505 + break; 1.506 + case DISABLE_COMMAND: 1.507 + break; 1.508 + case ENABLE_COMMAND: 1.509 + break; 1.510 + case FIPS_COMMAND: 1.511 + case CHKFIPS_COMMAND: 1.512 + if(PL_strcasecmp(fipsArg, "true") && 1.513 + PL_strcasecmp(fipsArg, "false")) { 1.514 + PR_fprintf(PR_STDERR, errStrings[INVALID_FIPS_ARG]); 1.515 + return INVALID_FIPS_ARG; 1.516 + } 1.517 + break; 1.518 + case JAR_COMMAND: 1.519 + if(installDir == NULL) { 1.520 + PR_fprintf(PR_STDERR, errStrings[MISSING_PARAM_ERR], 1.521 + commandNames[JAR_COMMAND], optionStrings[INSTALLDIR_ARG]); 1.522 + return MISSING_PARAM_ERR; 1.523 + } 1.524 + break; 1.525 + case LIST_COMMAND: 1.526 + case RAW_LIST_COMMAND: 1.527 + break; 1.528 + case RAW_ADD_COMMAND: 1.529 + break; 1.530 + case UNDEFAULT_COMMAND: 1.531 + case DEFAULT_COMMAND: 1.532 + if(mechanisms == NULL) { 1.533 + PR_fprintf(PR_STDERR, errStrings[MISSING_PARAM_ERR], 1.534 + commandNames[command], optionStrings[MECHANISMS_ARG]); 1.535 + return MISSING_PARAM_ERR; 1.536 + } 1.537 + break; 1.538 + default: 1.539 + /* Ignore this here */ 1.540 + break; 1.541 + } 1.542 + 1.543 + return SUCCESS; 1.544 +} 1.545 + 1.546 +/******************************************************************** 1.547 + * 1.548 + * i n i t _ c r y p t o 1.549 + * 1.550 + * Does crypto initialization that all commands will require. 1.551 + * If -nocertdb option is specified, don't open key or cert db (we don't 1.552 + * need them if we aren't going to be verifying signatures). This is 1.553 + * because serverland doesn't always have cert and key database files 1.554 + * available. 1.555 + * 1.556 + * This function is ill advised. Names and locations of databases are 1.557 + * private to NSS proper. Such functions only confuse other users. 1.558 + * 1.559 + */ 1.560 +static Error 1.561 +check_crypto(PRBool create, PRBool readOnly) 1.562 +{ 1.563 + char *dir; 1.564 + char *moddbname=NULL; 1.565 + Error retval; 1.566 + static const char multiaccess[] = { "multiaccess:" }; 1.567 + 1.568 + dir = SECU_ConfigDirectory(dbdir); /* dir is never NULL */ 1.569 + if (dir[0] == '\0') { 1.570 + PR_fprintf(PR_STDERR, errStrings[NO_DBDIR_ERR]); 1.571 + retval=NO_DBDIR_ERR; 1.572 + goto loser; 1.573 + } 1.574 + if (strncmp(dir, multiaccess, sizeof multiaccess - 1) == 0) { 1.575 + /* won't attempt to handle the multiaccess case. */ 1.576 + return SUCCESS; 1.577 + } 1.578 +#ifdef notdef 1.579 + /* Make sure db directory exists and is readable */ 1.580 + if(PR_Access(dir, PR_ACCESS_EXISTS) != PR_SUCCESS) { 1.581 + PR_fprintf(PR_STDERR, errStrings[DIR_DOESNT_EXIST_ERR], dir); 1.582 + retval = DIR_DOESNT_EXIST_ERR; 1.583 + goto loser; 1.584 + } else if(PR_Access(dir, PR_ACCESS_READ_OK) != PR_SUCCESS) { 1.585 + PR_fprintf(PR_STDERR, errStrings[DIR_NOT_READABLE_ERR], dir); 1.586 + retval = DIR_NOT_READABLE_ERR; 1.587 + goto loser; 1.588 + } 1.589 + 1.590 + if (secmodName == NULL) { 1.591 + secmodName = "secmod.db"; 1.592 + } 1.593 + 1.594 + moddbname = PR_smprintf("%s/%s", dir, secmodName); 1.595 + if (!moddbname) 1.596 + return OUT_OF_MEM_ERR; 1.597 + 1.598 + /* Check for the proper permissions on databases */ 1.599 + if(create) { 1.600 + /* Make sure dbs don't already exist, and the directory is 1.601 + writeable */ 1.602 + if(PR_Access(moddbname, PR_ACCESS_EXISTS)==PR_SUCCESS) { 1.603 + PR_fprintf(PR_STDERR, errStrings[FILE_ALREADY_EXISTS_ERR], 1.604 + moddbname); 1.605 + retval=FILE_ALREADY_EXISTS_ERR; 1.606 + goto loser; 1.607 + } else 1.608 + if(PR_Access(dir, PR_ACCESS_WRITE_OK) != PR_SUCCESS) { 1.609 + PR_fprintf(PR_STDERR, errStrings[DIR_NOT_WRITEABLE_ERR], dir); 1.610 + retval=DIR_NOT_WRITEABLE_ERR; 1.611 + goto loser; 1.612 + } 1.613 + } else { 1.614 + /* Make sure dbs are readable and writeable */ 1.615 + if(PR_Access(moddbname, PR_ACCESS_READ_OK) != PR_SUCCESS) { 1.616 + PR_fprintf(PR_STDERR, errStrings[FILE_NOT_READABLE_ERR], moddbname); 1.617 + retval=FILE_NOT_READABLE_ERR; 1.618 + goto loser; 1.619 + } 1.620 + 1.621 + /* Check for write access if we'll be making changes */ 1.622 + if( !readOnly ) { 1.623 + if(PR_Access(moddbname, PR_ACCESS_WRITE_OK) != PR_SUCCESS) { 1.624 + PR_fprintf(PR_STDERR, errStrings[FILE_NOT_WRITEABLE_ERR], 1.625 + moddbname); 1.626 + retval=FILE_NOT_WRITEABLE_ERR; 1.627 + goto loser; 1.628 + } 1.629 + } 1.630 + PR_fprintf(PR_STDOUT, msgStrings[USING_DBDIR_MSG], 1.631 + SECU_ConfigDirectory(NULL)); 1.632 + } 1.633 +#endif 1.634 + retval=SUCCESS; 1.635 +loser: 1.636 + if (moddbname) { 1.637 + PR_Free(moddbname); 1.638 + } 1.639 + return retval; 1.640 +} 1.641 + 1.642 +static Error 1.643 +init_crypto(PRBool create, PRBool readOnly) 1.644 +{ 1.645 + 1.646 + PRUint32 flags = 0; 1.647 + SECStatus rv; 1.648 + Error retval; 1.649 + /* Open/create key database */ 1.650 + 1.651 + if (readOnly) flags |= NSS_INIT_READONLY; 1.652 + if (nocertdb) flags |= NSS_INIT_NOCERTDB; 1.653 + rv = NSS_Initialize(SECU_ConfigDirectory(NULL), dbprefix, dbprefix, 1.654 + secmodName, flags); 1.655 + if (rv != SECSuccess) { 1.656 + SECU_PrintPRandOSError(progName); 1.657 + retval=NSS_INITIALIZE_FAILED_ERR; 1.658 + } else 1.659 + retval=SUCCESS; 1.660 + 1.661 + return retval; 1.662 +} 1.663 + 1.664 +/************************************************************************* 1.665 + * 1.666 + * u s a g e 1.667 + */ 1.668 +static void 1.669 +usage() 1.670 +{ 1.671 + PR_fprintf(PR_STDOUT, 1.672 +"\nNetscape Cryptographic Module Utility\n" 1.673 +"Usage: modutil [command] [options]\n\n" 1.674 +" COMMANDS\n" 1.675 +"---------------------------------------------------------------------------\n" 1.676 +"-add MODULE_NAME Add the named module to the module database\n" 1.677 +" -libfile LIBRARY_FILE The name of the file (.so or .dll)\n" 1.678 +" containing the implementation of PKCS #11\n" 1.679 +" [-ciphers CIPHER_LIST] Enable the given ciphers on this module\n" 1.680 +" [-mechanisms MECHANISM_LIST] Make the module a default provider of the\n" 1.681 +" given mechanisms\n" 1.682 +" [-string CONFIG_STRING] Pass a configuration string to this module\n" 1.683 +"-changepw TOKEN Change the password on the named token\n" 1.684 +" [-pwfile FILE] The old password is in this file\n" 1.685 +" [-newpwfile FILE] The new password is in this file\n" 1.686 +"-chkfips [ true | false ] If true, verify FIPS mode. If false,\n" 1.687 +" verify not FIPS mode\n" 1.688 +"-create Create a new set of security databases\n" 1.689 +"-default MODULE Make the given module a default provider\n" 1.690 +" -mechanisms MECHANISM_LIST of the given mechanisms\n" 1.691 +" [-slot SLOT] limit change to only the given slot\n" 1.692 +"-delete MODULE Remove the named module from the module\n" 1.693 +" database\n" 1.694 +"-disable MODULE Disable the named module\n" 1.695 +" [-slot SLOT] Disable only the named slot on the module\n" 1.696 +"-enable MODULE Enable the named module\n" 1.697 +" [-slot SLOT] Enable only the named slot on the module\n" 1.698 +"-fips [ true | false ] If true, enable FIPS mode. If false,\n" 1.699 +" disable FIPS mode\n" 1.700 +"-force Do not run interactively\n" 1.701 +"-jar JARFILE Install a PKCS #11 module from the given\n" 1.702 +" JAR file in the PKCS #11 JAR format\n" 1.703 +" -installdir DIR Use DIR as the root directory of the\n" 1.704 +" installation\n" 1.705 +" [-tempdir DIR] Use DIR as the temporary installation\n" 1.706 +" directory. If not specified, the current\n" 1.707 +" directory is used\n" 1.708 +"-list [MODULE] Lists information about the specified module\n" 1.709 +" or about all modules if none is specified\n" 1.710 +"-rawadd MODULESPEC Add module spec string to secmod DB\n" 1.711 +"-rawlist [MODULE] Display module spec(s) for one or all\n" 1.712 +" loadable modules\n" 1.713 +"-undefault MODULE The given module is NOT a default provider\n" 1.714 +" -mechanisms MECHANISM_LIST of the listed mechanisms\n" 1.715 +" [-slot SLOT] limit change to only the given slot\n" 1.716 +"---------------------------------------------------------------------------\n" 1.717 +"\n" 1.718 +" OPTIONS\n" 1.719 +"---------------------------------------------------------------------------\n" 1.720 +"-dbdir DIR Directory DIR contains the security databases\n" 1.721 +"-dbprefix prefix Prefix for the security databases\n" 1.722 +"-nocertdb Do not load certificate or key databases. No\n" 1.723 +" verification will be performed on JAR files.\n" 1.724 +"-secmod secmodName Name of the security modules file\n" 1.725 +"---------------------------------------------------------------------------\n" 1.726 +"\n" 1.727 +"Mechanism lists are colon-separated. The following mechanisms are recognized:\n" 1.728 +"RSA, DSA, DH, RC2, RC4, RC5, AES, CAMELLIA, DES, MD2, MD5, SHA1, SHA256, SHA512,\n" 1.729 +"SSL, TLS, RANDOM, and FRIENDLY\n" 1.730 +"\n" 1.731 +"Cipher lists are colon-separated. The following ciphers are recognized:\n" 1.732 +"\n" 1.733 +"\nQuestions or bug reports should be sent to modutil-support@netscape.com.\n" 1.734 +); 1.735 + 1.736 +} 1.737 + 1.738 +/************************************************************************* 1.739 + * 1.740 + * m a i n 1.741 + */ 1.742 +int 1.743 +main(int argc, char *argv[]) 1.744 +{ 1.745 + int errcode = SUCCESS; 1.746 + PRBool createdb, readOnly; 1.747 +#define STDINBUF_SIZE 80 1.748 + char stdinbuf[STDINBUF_SIZE]; 1.749 + 1.750 + progName = strrchr(argv[0], '/'); 1.751 + progName = progName ? progName+1 : argv[0]; 1.752 + 1.753 + 1.754 + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); 1.755 + 1.756 + if(parse_args(argc, argv) != SUCCESS) { 1.757 + usage(); 1.758 + errcode = INVALID_USAGE_ERR; 1.759 + goto loser; 1.760 + } 1.761 + 1.762 + if(verify_params() != SUCCESS) { 1.763 + usage(); 1.764 + errcode = INVALID_USAGE_ERR; 1.765 + goto loser; 1.766 + } 1.767 + 1.768 + if(command==NO_COMMAND) { 1.769 + PR_fprintf(PR_STDERR, errStrings[NO_COMMAND_ERR]); 1.770 + usage(); 1.771 + errcode = INVALID_USAGE_ERR; 1.772 + goto loser; 1.773 + } 1.774 + 1.775 + /* Set up crypto stuff */ 1.776 + createdb = command==CREATE_COMMAND; 1.777 + readOnly = ((command == LIST_COMMAND) || 1.778 + (command == CHKFIPS_COMMAND) || 1.779 + (command == RAW_LIST_COMMAND)); 1.780 + 1.781 + /* Make sure browser is not running if we're writing to a database */ 1.782 + /* Do this before initializing crypto */ 1.783 + if(!readOnly && !force) { 1.784 + char *response; 1.785 + 1.786 + PR_fprintf(PR_STDOUT, msgStrings[BROWSER_RUNNING_MSG]); 1.787 + if( ! PR_fgets(stdinbuf, STDINBUF_SIZE, PR_STDIN)) { 1.788 + PR_fprintf(PR_STDERR, errStrings[STDIN_READ_ERR]); 1.789 + errcode = STDIN_READ_ERR; 1.790 + goto loser; 1.791 + } 1.792 + if( (response=strtok(stdinbuf, " \r\n\t")) ) { 1.793 + if(!PL_strcasecmp(response, "q")) { 1.794 + PR_fprintf(PR_STDOUT, msgStrings[ABORTING_MSG]); 1.795 + errcode = SUCCESS; 1.796 + goto loser; 1.797 + } 1.798 + } 1.799 + PR_fprintf(PR_STDOUT, "\n"); 1.800 + } 1.801 + 1.802 + errcode = check_crypto(createdb, readOnly); 1.803 + if( errcode != SUCCESS) { 1.804 + goto loser; 1.805 + } 1.806 + 1.807 + if ((command == RAW_LIST_COMMAND) || (command == RAW_ADD_COMMAND)) { 1.808 + if(!moduleName) { 1.809 + char *readOnlyStr, *noCertDBStr, *sep; 1.810 + if (!secmodName) secmodName="secmod.db"; 1.811 + if (!dbprefix) dbprefix = ""; 1.812 + sep = ((command == RAW_LIST_COMMAND) && nocertdb) ? "," : " "; 1.813 + readOnlyStr = (command == RAW_LIST_COMMAND) ? "readOnly" : "" ; 1.814 + noCertDBStr = nocertdb ? "noCertDB" : ""; 1.815 + SECU_ConfigDirectory(dbdir); 1.816 + 1.817 + moduleName=PR_smprintf( 1.818 + "name=\"NSS default Module DB\" parameters=\"configdir=%s certPrefix=%s " 1.819 + "keyPrefix=%s secmod=%s flags=%s%s%s\" NSS=\"flags=internal,moduleDB," 1.820 + "moduleDBOnly,critical\"", 1.821 + SECU_ConfigDirectory(NULL),dbprefix,dbprefix, 1.822 + secmodName, readOnlyStr,sep, noCertDBStr); 1.823 + } 1.824 + if (command == RAW_LIST_COMMAND) { 1.825 + errcode = RawListModule(moduleName); 1.826 + } else { 1.827 + PORT_Assert(moduleSpec); 1.828 + errcode = RawAddModule(moduleName,moduleSpec); 1.829 + } 1.830 + goto loser; 1.831 + } 1.832 + 1.833 + errcode = init_crypto(createdb, readOnly); 1.834 + if( errcode != SUCCESS) { 1.835 + goto loser; 1.836 + } 1.837 + 1.838 + errcode = LoadMechanismList(); 1.839 + if (errcode != SUCCESS) { 1.840 + goto loser; 1.841 + } 1.842 + 1.843 + /* Execute the command */ 1.844 + switch(command) { 1.845 + case ADD_COMMAND: 1.846 + errcode = AddModule(moduleName, libFile, ciphers, mechanisms, secmodString); 1.847 + break; 1.848 + case CHANGEPW_COMMAND: 1.849 + errcode = ChangePW(tokenName, pwFile, newpwFile); 1.850 + break; 1.851 + case CREATE_COMMAND: 1.852 + /* The work was already done in init_crypto() */ 1.853 + break; 1.854 + case DEFAULT_COMMAND: 1.855 + errcode = SetDefaultModule(moduleName, slotName, mechanisms); 1.856 + break; 1.857 + case DELETE_COMMAND: 1.858 + errcode = DeleteModule(moduleName); 1.859 + break; 1.860 + case DISABLE_COMMAND: 1.861 + errcode = EnableModule(moduleName, slotName, PR_FALSE); 1.862 + break; 1.863 + case ENABLE_COMMAND: 1.864 + errcode = EnableModule(moduleName, slotName, PR_TRUE); 1.865 + break; 1.866 + case FIPS_COMMAND: 1.867 + errcode = FipsMode(fipsArg); 1.868 + break; 1.869 + case CHKFIPS_COMMAND: 1.870 + errcode = ChkFipsMode(fipsArg); 1.871 + break; 1.872 + case JAR_COMMAND: 1.873 + Pk11Install_SetErrorHandler(install_error); 1.874 + errcode = Pk11Install_DoInstall(jarFile, installDir, tempDir, 1.875 + PR_STDOUT, force, nocertdb); 1.876 + break; 1.877 + case LIST_COMMAND: 1.878 + if(moduleName) { 1.879 + errcode = ListModule(moduleName); 1.880 + } else { 1.881 + errcode = ListModules(); 1.882 + } 1.883 + break; 1.884 + case UNDEFAULT_COMMAND: 1.885 + errcode = UnsetDefaultModule(moduleName, slotName, mechanisms); 1.886 + break; 1.887 + default: 1.888 + PR_fprintf(PR_STDERR, "This command is not supported yet.\n"); 1.889 + errcode = INVALID_USAGE_ERR; 1.890 + break; 1.891 + } 1.892 + 1.893 + if (NSS_Shutdown() != SECSuccess) { 1.894 + exit(1); 1.895 + } 1.896 + 1.897 +loser: 1.898 + PR_Cleanup(); 1.899 + return errcode; 1.900 +} 1.901 + 1.902 +/************************************************************************ 1.903 + * 1.904 + * i n s t a l l _ e r r o r 1.905 + * 1.906 + * Callback function to handle errors in PK11 JAR file installation. 1.907 + */ 1.908 +static void 1.909 +install_error(char *message) 1.910 +{ 1.911 + PR_fprintf(PR_STDERR, "Install error: %s\n", message); 1.912 +} 1.913 + 1.914 +/************************************************************************* 1.915 + * 1.916 + * o u t _ o f _ m e m o r y 1.917 + */ 1.918 +void 1.919 +out_of_memory(void) 1.920 +{ 1.921 + PR_fprintf(PR_STDERR, errStrings[OUT_OF_MEM_ERR]); 1.922 + exit(OUT_OF_MEM_ERR); 1.923 +} 1.924 + 1.925 + 1.926 +/************************************************************************** 1.927 + * 1.928 + * P R _ f g e t s 1.929 + * 1.930 + * fgets implemented with NSPR. 1.931 + */ 1.932 +static char* 1.933 +PR_fgets(char *buf, int size, PRFileDesc *file) 1.934 +{ 1.935 + int i; 1.936 + int status; 1.937 + char c; 1.938 + 1.939 + i=0; 1.940 + while(i < size-1) { 1.941 + status = PR_Read(file, (void*) &c, 1); 1.942 + if(status==-1) { 1.943 + return NULL; 1.944 + } else if(status==0) { 1.945 + break; 1.946 + } 1.947 + buf[i++] = c; 1.948 + if(c=='\n') { 1.949 + break; 1.950 + } 1.951 + } 1.952 + buf[i]='\0'; 1.953 + 1.954 + return buf; 1.955 +}