⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pgp.c

📁 著名的加密软件的应用于电子邮件中
💻 C
📖 第 1 页 / 共 2 页
字号:
#endif
			    continue;
			  }
			  /* Determine whether this key is OK to use
			     for encryption */
			  if (ringTtyKeyOKToEncrypt (ringset,
										 ringobj)) {
				prefAlgs = ringKeyFindSubpacket (ringobj, ringset,
							SIGSUB_PREFERRED_ALGS,
				            0, &numPrefAlgs, NULL, NULL, NULL, NULL, &e);
				if (prefAlgs == NULL && e != 0)
					exitUsage(e);
				AccumAlgVotes(&algVotes, prefAlgs, numPrefAlgs);

			    temp = ringKeyPubKey (ringset, ringobj,
						  PGP_PKUSE_ENCRYPT);
			    if (temp) {
			      temp->next = publicKey;
			      publicKey = temp;
			    }
			  }
			}
			bestAlg = ChooseAlgFromVotes(&algVotes);
			CleanupAlgVotes(&algVotes);
			if (bestAlg > 0)
			{
				pgpenvSetInt(env, PGPENV_CIPHER, bestAlg, PGPENV_PRI_FORCE);
			}
			else
			{
				ErrorOutput(TRUE,
							LEVEL_CRITICAL,
							"INCONSISTENT_RECIPIENT_SET");
				exitCleanup (-1);
			}

			ringIterDestroy (ringiter);
			ringSetDestroy (ringset);
			if (e < 0)
			  exitUsage(e);
		}
	}

	/*
	 * Don't proceed if couldn't encrypt for anyone, otherwise we send
	 * out plaintext.
	 */
	if (flags->numrecips && !publicKey) {
		ErrorOutput(TRUE, LEVEL_CRITICAL, "NO_VALID_RECIPIENTS");
		exitCleanup (-1);
	}


	tail = pgpEncryptPipelineCreate (tail,
									 env,
									 NULL,
									 rng_p,
									 convkeys,
									 publicKey,
									 sigspec,
									 literalParams,
									 flags->sepsig);

	if (tail)
		*pipehead = mod;
	return tail;
}

/*
 * Process the flags that were set.  This builds the appropriate
 * pipelines and processes the input files.
 */
static int
mainProcessFlags (struct PgpUICb *ui, struct UIArg *ui_arg,
		  struct PgpEnv *env, int argc, char *argv[],
		  struct Flags *flags)
{
	struct PgpPipeline mod;
	struct PgpPipeline **tail = NULL;
	struct PgpEnv *tempenv = NULL;
	int retval = PGPERR_OK, err;
	int encrypting;
	int armoring;
	int filter = flags->filtermode;	/* Assign to 0 or 2 */
	
	if (flags->conventional && flags->numrecips) {
		ErrorOutput(TRUE,
					LEVEL_CRITICAL,
					"CANNOT_COMBINE_CONVENTIONAL_AND_PK");
		exitCleanup(PGPEXIT_ARGS);
	}

	if (!argc) {
		filter++;
		StatusOutput(TRUE, "USING_STDIN");
		argc = -1;
	}

	memset (&mod, 0, sizeof (mod));
	mod.name = "PGP Application";

	rng = pgpRandomCreate ();
	if (!rng)
		exitUsage (PGPERR_NOMEM);

	encrypting = (flags->numrecips || flags->conventional ||
		      (flags->doarmor && !flags->decrypt) ||
		      flags->sign); /* Encryption */
	armoring = pgpenvGetInt (env, PGPENV_ARMOR, NULL, NULL);

	/*
	 * Loop through input files.
	 */
	for (; argc; argc--, argv++) {
		FILE *input;
		struct PgpFileRead *context = NULL;
		char name[PATH_MAX+1];
		char *fn = NULL;
		char const *outfile = NULL;

		if (argc < 0) {
			pgpAssert (filter & 1);
			argc = 1;
			input = stdin;
		} else {
			input = fopen (argv[0], "rb");
			if (!input) {
				ErrorOutput(TRUE,
							LEVEL_CRITICAL,
							"CANNOT_OPEN_INPUT_FILE",
							argv[0]);
				continue;
			}
		}

		if (!tempenv)
			tempenv = pgpenvCopy (env);
		if (!tempenv) {
			retval = PGPERR_NOMEM;
			break;
		}			

		context = pgpFileReadCreate (input, ((filter & 1) ? 0 : 1));
		if (!context) {
			fclose (input);
			retval = PGPERR_NOMEM;
			break;
		}

		if (flags->decrypt) {
			if (flags->doarmor) {
				/* Want to just strip off ascii armor */
				ui_arg->arg.commits = 0;
			} else {
				/* Unwind just one layer of PGP */
				ui_arg->arg.commits = 1;
			}
		} else {
			/* Unwind all layers if decrypting */
			ui_arg->arg.commits = -1;
		}

		if (encrypting) {
			char const *in_name;

			if (filter & 1)
				in_name = "stdin";
			else
				in_name = argv[0];
			
			if (flags->outfile)
				outfile = flags->outfile;
			else if (filter) {
				outfile = NULL;
			} else {
				char *outname = argv[0];
#ifdef MSDOS
				outname = fileNameContract(outname);
#endif
				fn = fileNameExtend (outname,
						     (armoring ? ".asc" :
						      (flags->sign &&
						       flags->sepsig) ? ".sig"
						      : ".pgp"));
				strncpy (name, fn, sizeof (name));
				pgpMemFree (fn);
				outfile = name;
			}

			tail = mainSetupPipeline (&head, tempenv,
						  flags, rng, in_name,
						  context, ui_arg);
		} else {	/* Decryption */
			/* Choose an output name */
			if (!ui_arg->arg.protect_name) {
				/* Allow -o to override -f */
				if (flags->outfile) {
					ui_arg->arg.outname = flags->outfile;
				} else if (filter) {
					/* use stdout */
					ui_arg->arg.protect_name = -1;
				} else {
					fn = fileNameContract (argv[0]);
					strncpy (name, fn, sizeof (name));
					pgpMemFree (fn);
					ui_arg->arg.outname = name;
				}
			}
			if (!head) {
				tail = &head;
				if (filter & 2)	/* if -f is used */
					tail = pgpBufferModCreate (
						tail, &pgpFlexFifoDesc);
				tail = pgpDecryptPipelineCreate (tail, tempenv,
								 NULL, ui,
								 ui_arg);
				
				if (!head)
					exitCleanup (PGPERR_NOMEM);
			}
		}

		if (!tail) {
			ErrorOutput(TRUE,
						LEVEL_CRITICAL,
						"CANNOT_SETUP_PROCESSING_PIPELINE");
			exitCleanup (-1);
		}

		if (encrypting) {
			if (!outfile) {
				pgpAssert (filter);
				if (!pgpFileWriteCreate (tail,
							 pgpFileWriteOpen
							 (stdout, NULL), 0)) {
					head->teardown (head);
					head = NULL;
					continue;
				}
			} else {
				if (!pgpArmorFileWriteCreate (tail, openFile,
			  	          (void *) env, outfile)) {

					head->teardown (head);
					head = NULL;
					continue;
				}
			}
		}

		retval = pgpFileReadPump (context, head);
		if (retval)
			PGPErrCodeOutput(TRUE, LEVEL_CRITICAL, retval);

		if (retval) {
			err = pgpFileReadClose (context, head);
			if (err) {
				PGPErrCodeOutput(TRUE, LEVEL_CRITICAL, err);
			}
		}
		pgpFileReadDestroy (context);

		if (encrypting) {
			if (!retval) {
				retval = head->sizeAdvise (head, 0);
				if (retval)
					PGPErrCodeOutput(TRUE, LEVEL_CRITICAL, retval);
			}
			head->teardown (head);
			head = NULL;
		}

		if (retval)
			break;
	}
	if (!retval && head) {
		retval = head->sizeAdvise (head, 0);
		if (retval)
			PGPErrCodeOutput(TRUE, LEVEL_CRITICAL, retval);
	}
	if (head)
		head->teardown (head);
	head = NULL;

	if (rng)
		pgpRandomDestroy (rng);
	rng = NULL;

	if (tempenv)
		pgpenvDestroy (tempenv);
	tempenv = NULL;

	return retval;
}

/* Clean up allocated space (like the pipeline and the rng) on exit */
static void
mainExit (void)
{
	if (head)
		head->teardown (head);
	head = NULL;

	if (rng)
		pgpRandomDestroy (rng);
	rng = NULL;

	if (secretKey)
		pgpSecKeyDestroy (secretKey);
	secretKey = NULL;

	while (publicKey) {
		struct PgpPubKey *temp = publicKey->next;
		pgpPubKeyDestroy (publicKey);
		publicKey = temp;
	}

	if (ringpool)
		ringPoolDestroy (ringpool);
	ringpool = NULL;

	if (passcache)
		pgpPassCacheDestroy (passcache);
	passcache = NULL;

	memset (phrase, 0, sizeof (phrase));

	FreeLanguageStrings();
}

int
appMain (int argc, char *argv[])
{
	struct PgpUICb ui;
	struct UIArg ui_arg;
	struct Flags flags;
	struct PgpEnv *env;
	struct RingSet *tset;
	char const *p;
	int retval, prog_code = 0;
	PGPInvokedType invoked_type;

	/* Setup my exit function to clean myself up */
	atexit (mainExit);

	/* Setup the UI callback functions */
	ui.message = pgpTtyMessage;
	ui.doCommit = pgpTtyDoCommit;
	ui.newOutput = pgpTtyNewOutput;
	ui.needInput = pgpTtyNeedInput;
	ui.sigVerify = pgpTtySigVerify;
	ui.eskDecrypt = pgpTtyEskDecrypt;
	ui.annotate = NULL;

	/* Setup the TTY UI argument */
	ui_arg.arg.verbose = 1;
	ui_arg.arg.fp = stderr;
	ui_arg.arg.ringset = NULL;
	ui_arg.arg.showpass = 0;
	ui_arg.arg.commits = -1;
	ui_arg.arg.addKeys = mainAddKeys;
	ui_arg.arg.protect_name = 0;

	retval = pgpInitApp (&env, &argc, &ui, &ui_arg, prog_code, 0);
	if (retval) {
		/*XXX Is this message strictly neccessary?*/
		fprintf (stderr, "pgpInitApp failed: %d\n", retval);
		goto error;
	}
	/* Now initialize the values that need initialization */
	ui_arg.arg.env = env;
	ui_arg.arg.passcache = passcache = pgpPassCacheCreate (env);
	ui_arg.arg.verbose = pgpenvGetInt(env, PGPENV_VERBOSE, NULL, NULL);

	/* Check the exiration date on the application */
	exitExpiryCheck (env);

#if defined(UNIX) || defined(VMS)
	umask(077);             /* Make files default to private */
#endif

	/* Grab the pass phrase from the PGPPASS Env Var */
	p = getenv ("PGPPASS");
	if (p)
		pgpPassCacheAdd (passcache, p, strlen (p));

	/* XXX add PGPPASSFD here? */

	memset (&flags, 0, sizeof (flags));
	/* XXX This is never freed */
	flags.recips = (char **)malloc (argc * sizeof (*(flags.recips)));

	/* Initialize the application from config files, etc. */
	invoked_type = getInvokedType(argv[0]);
	switch(invoked_type) {
		case PGPencrypt:
			prog_code = EXIT_PROG_PGPE;
			break;
			
		case PGPsign:
			prog_code = EXIT_PROG_PGPS;
			break;

		case PGPverify:
			prog_code = EXIT_PROG_PGPV;
			break;

		case PGPold:
			prog_code = EXIT_PROG_PGPO;
			break;

	    case PGPkeys:
			/* XXX This shouldn't call exitArgError*/
			ErrorOutput(TRUE, LEVEL_CRITICAL, "PGPK_IS_SEPERATE");
			exitCleanup(PGPEXIT_ARGS);
			/*NOT EXECUTED*/
			break;

	    case PGPraw:
			exitInvokedRaw();
			/*NOT EXECUTED*/
			break;

	    default:
			/* XXX This shouldn't call exitArgError*/
			ErrorOutput(TRUE, LEVEL_CRITICAL, "UNKNOWN_SYMLINK");
			exitCleanup(PGPEXIT_ARGS);
			/*NOT EXECUTED*/
			break;
	}

	SetProgramName(prog_code);

	/* Now, read the argument list */
	switch(invoked_type) {
	    case PGPencrypt:
			mainParseEncryptArgs(&ui, &ui_arg, env, &argc, argv, &flags);
			break;

	    case PGPsign:
			mainParseSignArgs(&ui, &ui_arg, env, &argc, argv, &flags);
			break;

	    case PGPverify:
			mainParseVerifyArgs(&ui, &ui_arg, env, &argc, argv, &flags);
			break;

	    case PGPold:
			/*XXX this probably needs to be a seperate exe, but I'm not
			 *100% sure what to do about this, now.  -BAT
			 */
			mainParse262Args(&ui, &ui_arg, env, &argc, argv, &flags);
			break;

		case Unknown:
		case PGPraw:
		case PGPkeys:
			/*GCC's overly zealous preparser warns us of these, even though*/
			/*we can't get here...*/
			break;
	}

	ui_arg.arg.showpass = pgpenvGetInt (env, PGPENV_SHOWPASS, NULL, NULL);
	ui_arg.arg.moreflag = flags.moreflag;
	ui_arg.arg.pager = getenv ("PAGER");

	SetHeaders(pgpenvGetInt(env, PGPENV_HEADERS, NULL, NULL));

	if (!ringpool)
		ringpool = ringPoolCreate(env);
	if (!ringpool) {
		retval = PGPERR_NOMEM;
		goto error;
	}

	retval = mainOpenKeyrings (env, ringpool, 0, &tset);
	ui_arg.arg.ringset = tset;
	if (retval)
		goto error;

	/* Now process the flags */
	retval = mainProcessFlags (&ui, &ui_arg, env, argc, argv, &flags);
	
	exitCleanup (retval);
error:
	return (retval);
}

static PGPInvokedType getInvokedType(char *Argv0)
{
    char *p = NULL;
    PGPInvokedType invoked_type = Unknown;

    /*First of all, strip off any leading path info.  We don't care WHERE we
     *are, just WHAT we are:
     */
	invoked_type = PGPencrypt;

	/*Thanks to Chuck Bertsch, who pointed out that I'd written this wrong
	 *and that we should just look at the last character to see what we
	 *are, which enables you to call it pgp50e, for example.
	 */

	if((p = pgpFileNameTail(Argv0))) {
		p += strlen(p) - 1;
		switch(tolower(*p)) {
			case 'e':
				invoked_type = PGPencrypt;
				break;
					
			case 's':
				invoked_type = PGPsign;
				break;
				
			case 'v':
				invoked_type = PGPverify;
				break;
					
			case 'o':
				invoked_type = PGPold;
				break;
					
			case 'k':
				/*Huh?  They ran us as keys!*/
				invoked_type = PGPkeys;
				break;
					
			case 'p':
				invoked_type = PGPraw;
				break;
					
			default:
				invoked_type = Unknown;
		}
	}

    return(invoked_type);
}

static void exitInvokedRaw(void) {
	ErrorOutput(TRUE, LEVEL_CRITICAL, "DIFFERENT_EXES");
    exitCleanup(PGPEXIT_ARGS);
}


/*
 * Local Variables:
 * tab-width: 4
 * End:
 * vi: ts=4 sw=4
 * vim: si
 */

⌨️ 快捷键说明

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