signtool.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,012 行 · 第 1/2 页

C
1,012
字号
/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is the Netscape security libraries. *  * The Initial Developer of the Original Code is Netscape * Communications Corporation.  Portions created by Netscape are  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All * Rights Reserved. *  * Contributor(s): *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable  * instead of those above.  If you wish to allow use of your  * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL.  If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. *//* *  SIGNTOOL * *  A command line tool to create manifest files *  from a directory hierarchy. It is assumed that *  the tree will be equivalent to what resides *  or will reside in an archive.  * *  */#include "signtool.h"#include <prmem.h>#include <prio.h>/*********************************************************************** * Global Variable Definitions */char *progName; /* argv[0] *//* password on command line. Use for build testing only */char *password = NULL;/* directories or files to exclude in descent */PLHashTable *excludeDirs = NULL;static PRBool exclusionsGiven = PR_FALSE;/* zatharus is the man who knows no time, dies tragic death */int no_time = 0;/* -b basename of .rsa, .sf files */char *base = DEFAULT_BASE_NAME;/* Only sign files with this extension */PLHashTable *extensions=NULL;PRBool extensionsGiven = PR_FALSE;char *scriptdir = NULL;int verbosity = 0;PRFileDesc *outputFD=NULL, *errorFD=NULL;int errorCount=0, warningCount=0;int compression_level=DEFAULT_COMPRESSION_LEVEL;PRBool compression_level_specified = PR_FALSE;/* Command-line arguments */static char *genkey = NULL;static char *verify = NULL;static char *zipfile = NULL;static char *cert_dir = NULL;static int javascript = 0;static char *jartree = NULL;static char *keyName = NULL;static char *metafile = NULL;static char *install_script = NULL;static int list_certs = 0;static int list_modules = 0;static int optimize = 0;static char *tell_who = NULL;static char *outfile = NULL;static char *cmdFile = NULL;static PRBool noRecurse = PR_FALSE;static PRBool leaveArc = PR_FALSE;static int keySize = -1;static char *token = NULL;typedef enum {	UNKNOWN_OPT,	QUESTION_OPT,	BASE_OPT,	COMPRESSION_OPT,	CERT_DIR_OPT,	EXTENSION_OPT,	INSTALL_SCRIPT_OPT,	SCRIPTDIR_OPT,	CERTNAME_OPT,	LIST_OBJSIGN_CERTS_OPT,	LIST_ALL_CERTS_OPT,	METAFILE_OPT,	OPTIMIZE_OPT,	PASSWORD_OPT,	VERIFY_OPT,	WHO_OPT,	EXCLUDE_OPT,	NO_TIME_OPT,	JAVASCRIPT_OPT,	ZIPFILE_OPT,	GENKEY_OPT,	MODULES_OPT,	NORECURSE_OPT,	SIGNDIR_OPT,	OUTFILE_OPT,	COMMAND_FILE_OPT,	LEAVE_ARC_OPT,	VERBOSITY_OPT,    KEYSIZE_OPT,    TOKEN_OPT} OPT_TYPE;typedef enum {	DUPLICATE_OPTION_ERR=0,	OPTION_NEEDS_ARG_ERR} Error;static char *errStrings[] = {"warning: %s option specified more than once. Only last specification will be used.\n","ERROR: option \"%s\" requires an argument.\n"};static int ProcessOneOpt(OPT_TYPE type, char *arg);/********************************************************************* * * P r o c e s s C o m m a n d F i l e */intProcessCommandFile(){	PRFileDesc *fd;#define CMD_FILE_BUFSIZE 1024	char buf[CMD_FILE_BUFSIZE];	char *equals;	int linenum=0;	int retval=-1;	OPT_TYPE type;	fd = PR_Open(cmdFile, PR_RDONLY, 0777);	if(!fd) {		PR_fprintf(errorFD, "ERROR: Unable to open command file %s.\n");		errorCount++;		return -1;	}	while(pr_fgets(buf, CMD_FILE_BUFSIZE, fd), buf && *buf!='\0') {		char *eol;		linenum++;		/* Chop off final newline */		eol = PL_strchr(buf, '\r');		if(!eol) {			eol = PL_strchr(buf, '\n');		}		if(eol) *eol = '\0';		equals = PL_strchr(buf, '=');		if(!equals) {			continue;		}		*equals = '\0';		equals++;		/* Now buf points to the attribute, and equals points to the value. */		/* This is pretty straightforward, just deal with whatever attribute		 * this is */		if(!PL_strcasecmp(buf, "basename")) {			type = BASE_OPT;		} else if(!PL_strcasecmp(buf, "compression")) {			type = COMPRESSION_OPT;		} else if(!PL_strcasecmp(buf, "certdir")) {			type = CERT_DIR_OPT;		} else if(!PL_strcasecmp(buf, "extension")) {			type = EXTENSION_OPT;		} else if(!PL_strcasecmp(buf, "generate")) {			type = GENKEY_OPT;		} else if(!PL_strcasecmp(buf, "installScript")) {			type = INSTALL_SCRIPT_OPT;		} else if(!PL_strcasecmp(buf, "javascriptdir")) {			type = SCRIPTDIR_OPT;		} else if(!PL_strcasecmp(buf, "htmldir")) {			type = JAVASCRIPT_OPT;			if(jartree) {				PR_fprintf(errorFD,				  "warning: directory to be signed specified more than once."				  " Only last specification will be used.\n");				warningCount++;				PR_Free(jartree); jartree=NULL;			}			jartree = PL_strdup(equals);		} else if(!PL_strcasecmp(buf, "certname")) {			type = CERTNAME_OPT;		} else if(!PL_strcasecmp(buf, "signdir")) {			type = SIGNDIR_OPT;		} else if(!PL_strcasecmp(buf, "list")) {			type = LIST_OBJSIGN_CERTS_OPT;		} else if(!PL_strcasecmp(buf, "listall")) {			type = LIST_ALL_CERTS_OPT;		} else if(!PL_strcasecmp(buf, "metafile")) {			type = METAFILE_OPT;		} else if(!PL_strcasecmp(buf, "modules")) {			type = MODULES_OPT;		} else if(!PL_strcasecmp(buf, "optimize")) {			type = OPTIMIZE_OPT;		} else if(!PL_strcasecmp(buf, "password")) {			type = PASSWORD_OPT;		} else if(!PL_strcasecmp(buf, "verify")) {			type = VERIFY_OPT;		} else if(!PL_strcasecmp(buf, "who")) {			type = WHO_OPT;		} else if(!PL_strcasecmp(buf, "exclude")) {			type = EXCLUDE_OPT;		} else if(!PL_strcasecmp(buf, "notime")) {			type = NO_TIME_OPT;		} else if(!PL_strcasecmp(buf, "jarfile")) {			type = ZIPFILE_OPT;		} else if(!PL_strcasecmp(buf, "outfile")) {			type = OUTFILE_OPT;		} else if(!PL_strcasecmp(buf, "leavearc")) {			type = LEAVE_ARC_OPT;		} else if(!PL_strcasecmp(buf, "verbosity")) {			type = VERBOSITY_OPT;        } else if(!PL_strcasecmp(buf, "keysize")) {            type = KEYSIZE_OPT;        } else if(!PL_strcasecmp(buf, "token")) {            type = TOKEN_OPT;		} else {			PR_fprintf(errorFD,				"warning: unknown attribute \"%s\" in command file, line %d.\n",					buf, linenum);			warningCount++;			type = UNKNOWN_OPT;		}		/* Process the option, whatever it is */		if(type != UNKNOWN_OPT) {			if(ProcessOneOpt(type, equals)==-1) {				goto finish;			}		}	}	retval = 0;finish:	PR_Close(fd);	return retval;}/********************************************************************* * * p a r s e _ a r g s */static intparse_args(int argc, char *argv[]){	char *opt;	char *arg;	int needsInc;	int i;	OPT_TYPE type;	/* Loop over all arguments */	for(i=1; i < argc; i++) {		opt = argv[i];		arg = NULL;		if(opt[0] == '-') {			if(opt[1] == '-') {				/* word option */				if(i < argc-1) {					needsInc = 1;					arg = argv[i+1];				} else {					needsInc = 0;					arg = NULL;				} 				if( !PL_strcasecmp(opt+2, "norecurse")) {					type = NORECURSE_OPT;				} else if( !PL_strcasecmp(opt+2, "leavearc")) {					type = LEAVE_ARC_OPT;				} else if( !PL_strcasecmp(opt+2, "verbosity")) {					type = VERBOSITY_OPT;				} else if( !PL_strcasecmp(opt+2, "outfile")) {					type = OUTFILE_OPT;                } else if( !PL_strcasecmp(opt+2, "keysize")) {                    type = KEYSIZE_OPT;                } else if( !PL_strcasecmp(opt+2, "token")) {                    type = TOKEN_OPT;				} else {					PR_fprintf(errorFD, "warning: unknown option: %s\n", opt);					warningCount++;					type = UNKNOWN_OPT;				}			} else {				/* char option */				if(opt[2]!='\0') {					needsInc = 0;					arg = opt+2;				} else if(i < argc-1) {					needsInc = 1;					arg = argv[i+1];				} else {					needsInc = 0;					arg = NULL;				}				switch(opt[1]) {				case '?':					type = QUESTION_OPT;					break;				case 'b':					type = BASE_OPT;					break;				case 'c':					type = COMPRESSION_OPT;					break;				case 'd':					type = CERT_DIR_OPT;					break;				case 'e':					type = EXTENSION_OPT;					break;				case 'f':					type = COMMAND_FILE_OPT;					break;				case 'i':					type = INSTALL_SCRIPT_OPT;					break;				case 'j':					type = SCRIPTDIR_OPT;					break;				case 'k':					type = CERTNAME_OPT;					break;				case 'l':					type = LIST_OBJSIGN_CERTS_OPT;					break;				case 'L':					type = LIST_ALL_CERTS_OPT;					break;				case 'm':					type = METAFILE_OPT;					break;				case 'o':					type = OPTIMIZE_OPT;					break;				case 'p':					type = PASSWORD_OPT;					break;				case 'v':					type = VERIFY_OPT;					break;				case 'w':					type = WHO_OPT;					break;				case 'x':					type = EXCLUDE_OPT;					break;				case 'z':					type = NO_TIME_OPT;					break;				case 'J':					type = JAVASCRIPT_OPT;					break;				case 'Z':					type = ZIPFILE_OPT;					break;				case 'G':					type = GENKEY_OPT;					break;				case 'M':					type = MODULES_OPT;					break;                case 's':                    type = KEYSIZE_OPT;                    break;                case 't':                    type = TOKEN_OPT;                    break;				default:					type = UNKNOWN_OPT;					PR_fprintf(errorFD, "warning: unrecognized option: -%c.\n", 						opt[1]);					warningCount++;					break;				}			}		} else {			if(i == argc-1) {				type = UNKNOWN_OPT;				if(jartree) {				  PR_fprintf(errorFD,				    "warning: directory to be signed specified more than once."				    " Only last specification will be used.\n");				  warningCount++;				  PR_Free(jartree); jartree = NULL;				}				jartree = PL_strdup(opt);			} else {				type = UNKNOWN_OPT;				PR_fprintf(errorFD, "warning: unrecognized option: %s\n", opt);				warningCount++;			}		}		if(type != UNKNOWN_OPT) {			short ateArg;			ateArg = ProcessOneOpt(type, arg);			if(ateArg==-1) {				/* error */				return -1;			} else if(ateArg && needsInc) {				i++;			}		}	}	return 0;}/********************************************************************* * * P r o c e s s O n e O p t * * Since options can come from different places (command file, word options, * char options), this is a central function that is called to deal with * them no matter where they come from. * * type is the type of option. * arg is the argument to the option, possibly NULL. * Returns 1 if the argument was eaten, 0 if it wasn't, and -1 for error. */static intProcessOneOpt(OPT_TYPE type, char *arg){	int ate=0;	switch(type) {	case QUESTION_OPT:		usage();		break;	case BASE_OPT:		if(base) {			PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR], "-b");			warningCount++;			PR_Free(base); base=NULL;		}		if(!arg) {			PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR], "-b");			errorCount++;			goto loser;		}		base = PL_strdup(arg);		ate = 1;		break;	case COMPRESSION_OPT:		if(compression_level_specified) {			PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR], "-c");			warningCount++;		}		if( !arg ) {			PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR], "-c");			errorCount++;			goto loser;		}		compression_level = atoi(arg);		compression_level_specified = PR_TRUE;		ate = 1;		break;	case CERT_DIR_OPT:		if(cert_dir) {			PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR], "-d");			warningCount++;			PR_Free(cert_dir); cert_dir = NULL;		}		if(!arg) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?