security/nss/cmd/modutil/modutil.c

changeset 0
6474c204b198
     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 +}

mercurial