Wed, 31 Dec 2014 07:16:47 +0100
Revert simplistic fix pending revisit of Mozilla integration attempt.
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
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 /* To edit this file, set TABSTOPS to 4 spaces.
6 * This is not the normal NSS convention.
7 */
9 #include "modutil.h"
10 #include "install.h"
11 #include <plstr.h>
12 #include "certdb.h" /* for CERT_DB_FILE_VERSION */
13 #include "nss.h"
15 static void install_error(char *message);
16 static char* PR_fgets(char *buf, int size, PRFileDesc *file);
17 static char *progName;
20 /* This enum must be kept in sync with the commandNames list */
21 typedef enum {
22 NO_COMMAND,
23 ADD_COMMAND,
24 CHANGEPW_COMMAND,
25 CREATE_COMMAND,
26 DEFAULT_COMMAND,
27 DELETE_COMMAND,
28 DISABLE_COMMAND,
29 ENABLE_COMMAND,
30 FIPS_COMMAND,
31 JAR_COMMAND,
32 LIST_COMMAND,
33 RAW_LIST_COMMAND,
34 RAW_ADD_COMMAND,
35 CHKFIPS_COMMAND,
36 UNDEFAULT_COMMAND
37 } Command;
39 /* This list must be kept in sync with the Command enum */
40 static char *commandNames[] = {
41 "(no command)",
42 "-add",
43 "-changepw",
44 "-create",
45 "-default",
46 "-delete",
47 "-disable",
48 "-enable",
49 "-fips",
50 "-jar",
51 "-list",
52 "-rawlist",
53 "-rawadd",
54 "-chkfips",
55 "-undefault"
56 };
59 /* this enum must be kept in sync with the optionStrings list */
60 typedef enum {
61 ADD_ARG=0,
62 RAW_ADD_ARG,
63 CHANGEPW_ARG,
64 CIPHERS_ARG,
65 CREATE_ARG,
66 DBDIR_ARG,
67 DBPREFIX_ARG,
68 DEFAULT_ARG,
69 DELETE_ARG,
70 DISABLE_ARG,
71 ENABLE_ARG,
72 FIPS_ARG,
73 FORCE_ARG,
74 JAR_ARG,
75 LIBFILE_ARG,
76 LIST_ARG,
77 RAW_LIST_ARG,
78 MECHANISMS_ARG,
79 NEWPWFILE_ARG,
80 PWFILE_ARG,
81 SLOT_ARG,
82 UNDEFAULT_ARG,
83 INSTALLDIR_ARG,
84 TEMPDIR_ARG,
85 SECMOD_ARG,
86 NOCERTDB_ARG,
87 STRING_ARG,
88 CHKFIPS_ARG,
90 NUM_ARGS /* must be last */
91 } Arg;
93 /* This list must be kept in sync with the Arg enum */
94 static char *optionStrings[] = {
95 "-add",
96 "-rawadd",
97 "-changepw",
98 "-ciphers",
99 "-create",
100 "-dbdir",
101 "-dbprefix",
102 "-default",
103 "-delete",
104 "-disable",
105 "-enable",
106 "-fips",
107 "-force",
108 "-jar",
109 "-libfile",
110 "-list",
111 "-rawlist",
112 "-mechanisms",
113 "-newpwfile",
114 "-pwfile",
115 "-slot",
116 "-undefault",
117 "-installdir",
118 "-tempdir",
119 "-secmod",
120 "-nocertdb",
121 "-string",
122 "-chkfips",
123 };
125 /* Increment i if doing so would have i still be less than j. If you
126 are able to do this, return 0. Otherwise return 1. */
127 #define TRY_INC(i,j) ( ((i+1)<j) ? (++i, 0) : 1 )
129 /********************************************************************
130 *
131 * file-wide variables obtained from the command line
132 */
133 static Command command = NO_COMMAND;
134 static char* pwFile = NULL;
135 static char* newpwFile = NULL;
136 static char* moduleName = NULL;
137 static char* moduleSpec = NULL;
138 static char* slotName = NULL;
139 static char* secmodName = NULL;
140 static char* tokenName = NULL;
141 static char* libFile = NULL;
142 static char* dbdir = NULL;
143 static char* dbprefix = "";
144 static char* secmodString = NULL;
145 static char* mechanisms = NULL;
146 static char* ciphers = NULL;
147 static char* fipsArg = NULL;
148 static char* jarFile = NULL;
149 static char* installDir = NULL;
150 static char* tempDir = NULL;
151 static short force = 0;
152 static PRBool nocertdb = PR_FALSE;
154 /*******************************************************************
155 *
156 * p a r s e _ a r g s
157 */
158 static Error
159 parse_args(int argc, char *argv[])
160 {
161 int i;
162 char *arg;
163 int optionType;
165 /* Loop over all arguments */
166 for(i=1; i < argc; i++) {
167 arg = argv[i];
169 /* Make sure this is an option and not some floating argument */
170 if(arg[0] != '-') {
171 PR_fprintf(PR_STDERR, errStrings[UNEXPECTED_ARG_ERR], argv[i]);
172 return UNEXPECTED_ARG_ERR;
173 }
175 /* Find which option this is */
176 for(optionType=0; optionType < NUM_ARGS; optionType++) {
177 if(! strcmp(arg, optionStrings[optionType])) {
178 break;
179 }
180 }
182 /* Deal with this specific option */
183 switch(optionType) {
184 case NUM_ARGS:
185 default:
186 PR_fprintf(PR_STDERR, errStrings[UNKNOWN_OPTION_ERR], arg);
187 return UNKNOWN_OPTION_ERR;
188 break;
189 case ADD_ARG:
190 if(command != NO_COMMAND) {
191 PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg);
192 return MULTIPLE_COMMAND_ERR;
193 }
194 command = ADD_COMMAND;
195 if(TRY_INC(i, argc)) {
196 PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
197 return OPTION_NEEDS_ARG_ERR;
198 }
199 moduleName = argv[i];
200 break;
201 case CHANGEPW_ARG:
202 if(command != NO_COMMAND) {
203 PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg);
204 return MULTIPLE_COMMAND_ERR;
205 }
206 command = CHANGEPW_COMMAND;
207 if(TRY_INC(i, argc)) {
208 PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
209 return OPTION_NEEDS_ARG_ERR;
210 }
211 tokenName = argv[i];
212 break;
213 case CIPHERS_ARG:
214 if(ciphers != NULL) {
215 PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg);
216 return DUPLICATE_OPTION_ERR;
217 }
218 if(TRY_INC(i, argc)) {
219 PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
220 return OPTION_NEEDS_ARG_ERR;
221 }
222 ciphers = argv[i];
223 break;
224 case CREATE_ARG:
225 if(command != NO_COMMAND) {
226 PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg);
227 return MULTIPLE_COMMAND_ERR;
228 }
229 command = CREATE_COMMAND;
230 break;
231 case DBDIR_ARG:
232 if(dbdir != NULL) {
233 PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg);
234 return DUPLICATE_OPTION_ERR;
235 }
236 if(TRY_INC(i, argc)) {
237 PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
238 return OPTION_NEEDS_ARG_ERR;
239 }
240 dbdir = argv[i];
241 break;
242 case DBPREFIX_ARG:
243 if(TRY_INC(i, argc)) {
244 PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
245 return OPTION_NEEDS_ARG_ERR;
246 }
247 dbprefix = argv[i];
248 break;
249 case UNDEFAULT_ARG:
250 case DEFAULT_ARG:
251 if(command != NO_COMMAND) {
252 PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg);
253 return MULTIPLE_COMMAND_ERR;
254 }
255 if(optionType == DEFAULT_ARG) {
256 command = DEFAULT_COMMAND;
257 } else {
258 command = UNDEFAULT_COMMAND;
259 }
260 if(TRY_INC(i, argc)) {
261 PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
262 return OPTION_NEEDS_ARG_ERR;
263 }
264 moduleName = argv[i];
265 break;
266 case DELETE_ARG:
267 if(command != NO_COMMAND) {
268 PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg);
269 return MULTIPLE_COMMAND_ERR;
270 }
271 command = DELETE_COMMAND;
272 if(TRY_INC(i, argc)) {
273 PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
274 return OPTION_NEEDS_ARG_ERR;
275 }
276 moduleName = argv[i];
277 break;
278 case DISABLE_ARG:
279 if(command != NO_COMMAND) {
280 PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg);
281 return MULTIPLE_COMMAND_ERR;
282 }
283 command = DISABLE_COMMAND;
284 if(TRY_INC(i, argc)) {
285 PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
286 return OPTION_NEEDS_ARG_ERR;
287 }
288 moduleName = argv[i];
289 break;
290 case ENABLE_ARG:
291 if(command != NO_COMMAND) {
292 PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg);
293 return MULTIPLE_COMMAND_ERR;
294 }
295 command = ENABLE_COMMAND;
296 if(TRY_INC(i, argc)) {
297 PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
298 return OPTION_NEEDS_ARG_ERR;
299 }
300 moduleName = argv[i];
301 break;
302 case FIPS_ARG:
303 if(command != NO_COMMAND) {
304 PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg);
305 return MULTIPLE_COMMAND_ERR;
306 }
307 command = FIPS_COMMAND;
308 if(TRY_INC(i, argc)) {
309 PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
310 return OPTION_NEEDS_ARG_ERR;
311 }
312 fipsArg = argv[i];
313 break;
314 case CHKFIPS_ARG:
315 if(command != NO_COMMAND) {
316 PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg);
317 return MULTIPLE_COMMAND_ERR;
318 }
319 command = CHKFIPS_COMMAND;
320 if(TRY_INC(i, argc)) {
321 PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
322 return OPTION_NEEDS_ARG_ERR;
323 }
324 fipsArg = argv[i];
325 break;
326 case FORCE_ARG:
327 force = 1;
328 break;
329 case NOCERTDB_ARG:
330 nocertdb = PR_TRUE;
331 break;
332 case INSTALLDIR_ARG:
333 if(installDir != NULL) {
334 PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg);
335 return DUPLICATE_OPTION_ERR;
336 }
337 if(TRY_INC(i, argc)) {
338 PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
339 return OPTION_NEEDS_ARG_ERR;
340 }
341 installDir = argv[i];
342 break;
343 case TEMPDIR_ARG:
344 if(tempDir != NULL) {
345 PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg);
346 return DUPLICATE_OPTION_ERR;
347 }
348 if(TRY_INC(i, argc)) {
349 PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
350 return OPTION_NEEDS_ARG_ERR;
351 }
352 tempDir = argv[i];
353 break;
354 case JAR_ARG:
355 if(command != NO_COMMAND) {
356 PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg);
357 return MULTIPLE_COMMAND_ERR;
358 }
359 command = JAR_COMMAND;
360 if(TRY_INC(i, argc)) {
361 PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
362 return OPTION_NEEDS_ARG_ERR;
363 }
364 jarFile = argv[i];
365 break;
366 case LIBFILE_ARG:
367 if(libFile != NULL) {
368 PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg);
369 return DUPLICATE_OPTION_ERR;
370 }
371 if(TRY_INC(i, argc)) {
372 PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
373 return OPTION_NEEDS_ARG_ERR;
374 }
375 libFile = argv[i];
376 break;
377 case LIST_ARG:
378 if(command != NO_COMMAND) {
379 PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg);
380 return MULTIPLE_COMMAND_ERR;
381 }
382 command = LIST_COMMAND;
383 /* This option may or may not have an argument */
384 if( (i+1 < argc) && (argv[i+1][0] != '-') ) {
385 moduleName = argv[++i];
386 }
387 break;
388 case RAW_LIST_ARG:
389 if(command != NO_COMMAND) {
390 PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg);
391 return MULTIPLE_COMMAND_ERR;
392 }
393 command = RAW_LIST_COMMAND;
394 /* This option may or may not have an argument */
395 if( (i+1 < argc) && (argv[i+1][0] != '-') ) {
396 moduleName = argv[++i];
397 }
398 break;
399 case RAW_ADD_ARG:
400 if(command != NO_COMMAND) {
401 PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg);
402 return MULTIPLE_COMMAND_ERR;
403 }
404 command = RAW_ADD_COMMAND;
405 if(TRY_INC(i, argc)) {
406 PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
407 return OPTION_NEEDS_ARG_ERR;
408 }
409 moduleSpec = argv[i];
410 break;
411 case MECHANISMS_ARG:
412 if(mechanisms != NULL) {
413 PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg);
414 return DUPLICATE_OPTION_ERR;
415 }
416 if(TRY_INC(i, argc)) {
417 PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
418 return OPTION_NEEDS_ARG_ERR;
419 }
420 mechanisms = argv[i];
421 break;
422 case NEWPWFILE_ARG:
423 if(newpwFile != NULL) {
424 PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg);
425 return DUPLICATE_OPTION_ERR;
426 }
427 if(TRY_INC(i, argc)) {
428 PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
429 return OPTION_NEEDS_ARG_ERR;
430 }
431 newpwFile = argv[i];
432 break;
433 case PWFILE_ARG:
434 if(pwFile != NULL) {
435 PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg);
436 return DUPLICATE_OPTION_ERR;
437 }
438 if(TRY_INC(i, argc)) {
439 PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
440 return OPTION_NEEDS_ARG_ERR;
441 }
442 pwFile = argv[i];
443 break;
444 case SLOT_ARG:
445 if(slotName != NULL) {
446 PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg);
447 return DUPLICATE_OPTION_ERR;
448 }
449 if(TRY_INC(i, argc)) {
450 PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
451 return OPTION_NEEDS_ARG_ERR;
452 }
453 slotName = argv[i];
454 break;
455 case SECMOD_ARG:
456 if(secmodName != NULL) {
457 PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg);
458 return DUPLICATE_OPTION_ERR;
459 }
460 if(TRY_INC(i, argc)) {
461 PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
462 return OPTION_NEEDS_ARG_ERR;
463 }
464 secmodName = argv[i];
465 break;
466 case STRING_ARG:
467 if(secmodString != NULL) {
468 PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg);
469 return DUPLICATE_OPTION_ERR;
470 }
471 if(TRY_INC(i, argc)) {
472 PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
473 return OPTION_NEEDS_ARG_ERR;
474 }
475 secmodString = argv[i];
476 break;
477 }
478 }
479 return SUCCESS;
480 }
482 /************************************************************************
483 *
484 * v e r i f y _ p a r a m s
485 */
486 static Error
487 verify_params()
488 {
489 switch(command) {
490 case ADD_COMMAND:
491 if(libFile == NULL) {
492 PR_fprintf(PR_STDERR, errStrings[MISSING_PARAM_ERR],
493 commandNames[ADD_COMMAND], optionStrings[LIBFILE_ARG]);
494 return MISSING_PARAM_ERR;
495 }
496 break;
497 case CHANGEPW_COMMAND:
498 break;
499 case CREATE_COMMAND:
500 break;
501 case DELETE_COMMAND:
502 break;
503 case DISABLE_COMMAND:
504 break;
505 case ENABLE_COMMAND:
506 break;
507 case FIPS_COMMAND:
508 case CHKFIPS_COMMAND:
509 if(PL_strcasecmp(fipsArg, "true") &&
510 PL_strcasecmp(fipsArg, "false")) {
511 PR_fprintf(PR_STDERR, errStrings[INVALID_FIPS_ARG]);
512 return INVALID_FIPS_ARG;
513 }
514 break;
515 case JAR_COMMAND:
516 if(installDir == NULL) {
517 PR_fprintf(PR_STDERR, errStrings[MISSING_PARAM_ERR],
518 commandNames[JAR_COMMAND], optionStrings[INSTALLDIR_ARG]);
519 return MISSING_PARAM_ERR;
520 }
521 break;
522 case LIST_COMMAND:
523 case RAW_LIST_COMMAND:
524 break;
525 case RAW_ADD_COMMAND:
526 break;
527 case UNDEFAULT_COMMAND:
528 case DEFAULT_COMMAND:
529 if(mechanisms == NULL) {
530 PR_fprintf(PR_STDERR, errStrings[MISSING_PARAM_ERR],
531 commandNames[command], optionStrings[MECHANISMS_ARG]);
532 return MISSING_PARAM_ERR;
533 }
534 break;
535 default:
536 /* Ignore this here */
537 break;
538 }
540 return SUCCESS;
541 }
543 /********************************************************************
544 *
545 * i n i t _ c r y p t o
546 *
547 * Does crypto initialization that all commands will require.
548 * If -nocertdb option is specified, don't open key or cert db (we don't
549 * need them if we aren't going to be verifying signatures). This is
550 * because serverland doesn't always have cert and key database files
551 * available.
552 *
553 * This function is ill advised. Names and locations of databases are
554 * private to NSS proper. Such functions only confuse other users.
555 *
556 */
557 static Error
558 check_crypto(PRBool create, PRBool readOnly)
559 {
560 char *dir;
561 char *moddbname=NULL;
562 Error retval;
563 static const char multiaccess[] = { "multiaccess:" };
565 dir = SECU_ConfigDirectory(dbdir); /* dir is never NULL */
566 if (dir[0] == '\0') {
567 PR_fprintf(PR_STDERR, errStrings[NO_DBDIR_ERR]);
568 retval=NO_DBDIR_ERR;
569 goto loser;
570 }
571 if (strncmp(dir, multiaccess, sizeof multiaccess - 1) == 0) {
572 /* won't attempt to handle the multiaccess case. */
573 return SUCCESS;
574 }
575 #ifdef notdef
576 /* Make sure db directory exists and is readable */
577 if(PR_Access(dir, PR_ACCESS_EXISTS) != PR_SUCCESS) {
578 PR_fprintf(PR_STDERR, errStrings[DIR_DOESNT_EXIST_ERR], dir);
579 retval = DIR_DOESNT_EXIST_ERR;
580 goto loser;
581 } else if(PR_Access(dir, PR_ACCESS_READ_OK) != PR_SUCCESS) {
582 PR_fprintf(PR_STDERR, errStrings[DIR_NOT_READABLE_ERR], dir);
583 retval = DIR_NOT_READABLE_ERR;
584 goto loser;
585 }
587 if (secmodName == NULL) {
588 secmodName = "secmod.db";
589 }
591 moddbname = PR_smprintf("%s/%s", dir, secmodName);
592 if (!moddbname)
593 return OUT_OF_MEM_ERR;
595 /* Check for the proper permissions on databases */
596 if(create) {
597 /* Make sure dbs don't already exist, and the directory is
598 writeable */
599 if(PR_Access(moddbname, PR_ACCESS_EXISTS)==PR_SUCCESS) {
600 PR_fprintf(PR_STDERR, errStrings[FILE_ALREADY_EXISTS_ERR],
601 moddbname);
602 retval=FILE_ALREADY_EXISTS_ERR;
603 goto loser;
604 } else
605 if(PR_Access(dir, PR_ACCESS_WRITE_OK) != PR_SUCCESS) {
606 PR_fprintf(PR_STDERR, errStrings[DIR_NOT_WRITEABLE_ERR], dir);
607 retval=DIR_NOT_WRITEABLE_ERR;
608 goto loser;
609 }
610 } else {
611 /* Make sure dbs are readable and writeable */
612 if(PR_Access(moddbname, PR_ACCESS_READ_OK) != PR_SUCCESS) {
613 PR_fprintf(PR_STDERR, errStrings[FILE_NOT_READABLE_ERR], moddbname);
614 retval=FILE_NOT_READABLE_ERR;
615 goto loser;
616 }
618 /* Check for write access if we'll be making changes */
619 if( !readOnly ) {
620 if(PR_Access(moddbname, PR_ACCESS_WRITE_OK) != PR_SUCCESS) {
621 PR_fprintf(PR_STDERR, errStrings[FILE_NOT_WRITEABLE_ERR],
622 moddbname);
623 retval=FILE_NOT_WRITEABLE_ERR;
624 goto loser;
625 }
626 }
627 PR_fprintf(PR_STDOUT, msgStrings[USING_DBDIR_MSG],
628 SECU_ConfigDirectory(NULL));
629 }
630 #endif
631 retval=SUCCESS;
632 loser:
633 if (moddbname) {
634 PR_Free(moddbname);
635 }
636 return retval;
637 }
639 static Error
640 init_crypto(PRBool create, PRBool readOnly)
641 {
643 PRUint32 flags = 0;
644 SECStatus rv;
645 Error retval;
646 /* Open/create key database */
648 if (readOnly) flags |= NSS_INIT_READONLY;
649 if (nocertdb) flags |= NSS_INIT_NOCERTDB;
650 rv = NSS_Initialize(SECU_ConfigDirectory(NULL), dbprefix, dbprefix,
651 secmodName, flags);
652 if (rv != SECSuccess) {
653 SECU_PrintPRandOSError(progName);
654 retval=NSS_INITIALIZE_FAILED_ERR;
655 } else
656 retval=SUCCESS;
658 return retval;
659 }
661 /*************************************************************************
662 *
663 * u s a g e
664 */
665 static void
666 usage()
667 {
668 PR_fprintf(PR_STDOUT,
669 "\nNetscape Cryptographic Module Utility\n"
670 "Usage: modutil [command] [options]\n\n"
671 " COMMANDS\n"
672 "---------------------------------------------------------------------------\n"
673 "-add MODULE_NAME Add the named module to the module database\n"
674 " -libfile LIBRARY_FILE The name of the file (.so or .dll)\n"
675 " containing the implementation of PKCS #11\n"
676 " [-ciphers CIPHER_LIST] Enable the given ciphers on this module\n"
677 " [-mechanisms MECHANISM_LIST] Make the module a default provider of the\n"
678 " given mechanisms\n"
679 " [-string CONFIG_STRING] Pass a configuration string to this module\n"
680 "-changepw TOKEN Change the password on the named token\n"
681 " [-pwfile FILE] The old password is in this file\n"
682 " [-newpwfile FILE] The new password is in this file\n"
683 "-chkfips [ true | false ] If true, verify FIPS mode. If false,\n"
684 " verify not FIPS mode\n"
685 "-create Create a new set of security databases\n"
686 "-default MODULE Make the given module a default provider\n"
687 " -mechanisms MECHANISM_LIST of the given mechanisms\n"
688 " [-slot SLOT] limit change to only the given slot\n"
689 "-delete MODULE Remove the named module from the module\n"
690 " database\n"
691 "-disable MODULE Disable the named module\n"
692 " [-slot SLOT] Disable only the named slot on the module\n"
693 "-enable MODULE Enable the named module\n"
694 " [-slot SLOT] Enable only the named slot on the module\n"
695 "-fips [ true | false ] If true, enable FIPS mode. If false,\n"
696 " disable FIPS mode\n"
697 "-force Do not run interactively\n"
698 "-jar JARFILE Install a PKCS #11 module from the given\n"
699 " JAR file in the PKCS #11 JAR format\n"
700 " -installdir DIR Use DIR as the root directory of the\n"
701 " installation\n"
702 " [-tempdir DIR] Use DIR as the temporary installation\n"
703 " directory. If not specified, the current\n"
704 " directory is used\n"
705 "-list [MODULE] Lists information about the specified module\n"
706 " or about all modules if none is specified\n"
707 "-rawadd MODULESPEC Add module spec string to secmod DB\n"
708 "-rawlist [MODULE] Display module spec(s) for one or all\n"
709 " loadable modules\n"
710 "-undefault MODULE The given module is NOT a default provider\n"
711 " -mechanisms MECHANISM_LIST of the listed mechanisms\n"
712 " [-slot SLOT] limit change to only the given slot\n"
713 "---------------------------------------------------------------------------\n"
714 "\n"
715 " OPTIONS\n"
716 "---------------------------------------------------------------------------\n"
717 "-dbdir DIR Directory DIR contains the security databases\n"
718 "-dbprefix prefix Prefix for the security databases\n"
719 "-nocertdb Do not load certificate or key databases. No\n"
720 " verification will be performed on JAR files.\n"
721 "-secmod secmodName Name of the security modules file\n"
722 "---------------------------------------------------------------------------\n"
723 "\n"
724 "Mechanism lists are colon-separated. The following mechanisms are recognized:\n"
725 "RSA, DSA, DH, RC2, RC4, RC5, AES, CAMELLIA, DES, MD2, MD5, SHA1, SHA256, SHA512,\n"
726 "SSL, TLS, RANDOM, and FRIENDLY\n"
727 "\n"
728 "Cipher lists are colon-separated. The following ciphers are recognized:\n"
729 "\n"
730 "\nQuestions or bug reports should be sent to modutil-support@netscape.com.\n"
731 );
733 }
735 /*************************************************************************
736 *
737 * m a i n
738 */
739 int
740 main(int argc, char *argv[])
741 {
742 int errcode = SUCCESS;
743 PRBool createdb, readOnly;
744 #define STDINBUF_SIZE 80
745 char stdinbuf[STDINBUF_SIZE];
747 progName = strrchr(argv[0], '/');
748 progName = progName ? progName+1 : argv[0];
751 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
753 if(parse_args(argc, argv) != SUCCESS) {
754 usage();
755 errcode = INVALID_USAGE_ERR;
756 goto loser;
757 }
759 if(verify_params() != SUCCESS) {
760 usage();
761 errcode = INVALID_USAGE_ERR;
762 goto loser;
763 }
765 if(command==NO_COMMAND) {
766 PR_fprintf(PR_STDERR, errStrings[NO_COMMAND_ERR]);
767 usage();
768 errcode = INVALID_USAGE_ERR;
769 goto loser;
770 }
772 /* Set up crypto stuff */
773 createdb = command==CREATE_COMMAND;
774 readOnly = ((command == LIST_COMMAND) ||
775 (command == CHKFIPS_COMMAND) ||
776 (command == RAW_LIST_COMMAND));
778 /* Make sure browser is not running if we're writing to a database */
779 /* Do this before initializing crypto */
780 if(!readOnly && !force) {
781 char *response;
783 PR_fprintf(PR_STDOUT, msgStrings[BROWSER_RUNNING_MSG]);
784 if( ! PR_fgets(stdinbuf, STDINBUF_SIZE, PR_STDIN)) {
785 PR_fprintf(PR_STDERR, errStrings[STDIN_READ_ERR]);
786 errcode = STDIN_READ_ERR;
787 goto loser;
788 }
789 if( (response=strtok(stdinbuf, " \r\n\t")) ) {
790 if(!PL_strcasecmp(response, "q")) {
791 PR_fprintf(PR_STDOUT, msgStrings[ABORTING_MSG]);
792 errcode = SUCCESS;
793 goto loser;
794 }
795 }
796 PR_fprintf(PR_STDOUT, "\n");
797 }
799 errcode = check_crypto(createdb, readOnly);
800 if( errcode != SUCCESS) {
801 goto loser;
802 }
804 if ((command == RAW_LIST_COMMAND) || (command == RAW_ADD_COMMAND)) {
805 if(!moduleName) {
806 char *readOnlyStr, *noCertDBStr, *sep;
807 if (!secmodName) secmodName="secmod.db";
808 if (!dbprefix) dbprefix = "";
809 sep = ((command == RAW_LIST_COMMAND) && nocertdb) ? "," : " ";
810 readOnlyStr = (command == RAW_LIST_COMMAND) ? "readOnly" : "" ;
811 noCertDBStr = nocertdb ? "noCertDB" : "";
812 SECU_ConfigDirectory(dbdir);
814 moduleName=PR_smprintf(
815 "name=\"NSS default Module DB\" parameters=\"configdir=%s certPrefix=%s "
816 "keyPrefix=%s secmod=%s flags=%s%s%s\" NSS=\"flags=internal,moduleDB,"
817 "moduleDBOnly,critical\"",
818 SECU_ConfigDirectory(NULL),dbprefix,dbprefix,
819 secmodName, readOnlyStr,sep, noCertDBStr);
820 }
821 if (command == RAW_LIST_COMMAND) {
822 errcode = RawListModule(moduleName);
823 } else {
824 PORT_Assert(moduleSpec);
825 errcode = RawAddModule(moduleName,moduleSpec);
826 }
827 goto loser;
828 }
830 errcode = init_crypto(createdb, readOnly);
831 if( errcode != SUCCESS) {
832 goto loser;
833 }
835 errcode = LoadMechanismList();
836 if (errcode != SUCCESS) {
837 goto loser;
838 }
840 /* Execute the command */
841 switch(command) {
842 case ADD_COMMAND:
843 errcode = AddModule(moduleName, libFile, ciphers, mechanisms, secmodString);
844 break;
845 case CHANGEPW_COMMAND:
846 errcode = ChangePW(tokenName, pwFile, newpwFile);
847 break;
848 case CREATE_COMMAND:
849 /* The work was already done in init_crypto() */
850 break;
851 case DEFAULT_COMMAND:
852 errcode = SetDefaultModule(moduleName, slotName, mechanisms);
853 break;
854 case DELETE_COMMAND:
855 errcode = DeleteModule(moduleName);
856 break;
857 case DISABLE_COMMAND:
858 errcode = EnableModule(moduleName, slotName, PR_FALSE);
859 break;
860 case ENABLE_COMMAND:
861 errcode = EnableModule(moduleName, slotName, PR_TRUE);
862 break;
863 case FIPS_COMMAND:
864 errcode = FipsMode(fipsArg);
865 break;
866 case CHKFIPS_COMMAND:
867 errcode = ChkFipsMode(fipsArg);
868 break;
869 case JAR_COMMAND:
870 Pk11Install_SetErrorHandler(install_error);
871 errcode = Pk11Install_DoInstall(jarFile, installDir, tempDir,
872 PR_STDOUT, force, nocertdb);
873 break;
874 case LIST_COMMAND:
875 if(moduleName) {
876 errcode = ListModule(moduleName);
877 } else {
878 errcode = ListModules();
879 }
880 break;
881 case UNDEFAULT_COMMAND:
882 errcode = UnsetDefaultModule(moduleName, slotName, mechanisms);
883 break;
884 default:
885 PR_fprintf(PR_STDERR, "This command is not supported yet.\n");
886 errcode = INVALID_USAGE_ERR;
887 break;
888 }
890 if (NSS_Shutdown() != SECSuccess) {
891 exit(1);
892 }
894 loser:
895 PR_Cleanup();
896 return errcode;
897 }
899 /************************************************************************
900 *
901 * i n s t a l l _ e r r o r
902 *
903 * Callback function to handle errors in PK11 JAR file installation.
904 */
905 static void
906 install_error(char *message)
907 {
908 PR_fprintf(PR_STDERR, "Install error: %s\n", message);
909 }
911 /*************************************************************************
912 *
913 * o u t _ o f _ m e m o r y
914 */
915 void
916 out_of_memory(void)
917 {
918 PR_fprintf(PR_STDERR, errStrings[OUT_OF_MEM_ERR]);
919 exit(OUT_OF_MEM_ERR);
920 }
923 /**************************************************************************
924 *
925 * P R _ f g e t s
926 *
927 * fgets implemented with NSPR.
928 */
929 static char*
930 PR_fgets(char *buf, int size, PRFileDesc *file)
931 {
932 int i;
933 int status;
934 char c;
936 i=0;
937 while(i < size-1) {
938 status = PR_Read(file, (void*) &c, 1);
939 if(status==-1) {
940 return NULL;
941 } else if(status==0) {
942 break;
943 }
944 buf[i++] = c;
945 if(c=='\n') {
946 break;
947 }
948 }
949 buf[i]='\0';
951 return buf;
952 }