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

📄 pgpk.c

📁 著名的加密软件的应用于电子邮件中
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
 * pgpk.c -- PGP keyring manipulation program
 *
 * Copyright (C) 1996,1997 Pretty Good Privacy, Inc.  All rights reserved.
 *
 * $Id: pgpk.c,v 1.13.2.12.2.13 1997/07/15 22:22:36 quark Exp $
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdio.h>
#include <string.h>
#include <time.h>
#include <ctype.h>

#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>		/* for sbrk() */
#endif
#ifdef UNIX
#include <sys/stat.h>		/* for umask() */
#endif

#include "pgpDebug.h"
#include "pgpEnv.h"
#include "pgpMem.h"
#include "pgpKeyDB.h"
#include "pgpOutput.h"
#include "pgpkUI.h"
#include "pgpUI.h"
#include "pgpInitApp.h"
#include "pgpExit.h"
#include "pgpUI.h"
#include "pgpOpt.h"
#include "pgpUserIO.h"
#include "pgpRndPool.h"
#include "pgpConf.h"

#include "pass.h"
#include "pgpkKeyGen.h"
#include "keyserver.h"
#include "url.h"

#include "pgpLicense.h"


#define KDBTYPE_KEY          1
#define KDBTYPE_USERID       2
#define KDBTYPE_CERT         3

#define MAXARGS 2

struct Flags {
	char args[MAXARGS];
	int argc;
	char const *outfile;
	char const *ringfile;
	char const *signName;
	PGPKey *signKey;
	char opt;
	byte doarmor;
    char quit;
};

PGPKeySet  *defaultset = NULL;    /* All keys in default keyrings */
Boolean		enableUI = TRUE;

#define PASSLEN 256

static void
setOptArgs (char const *args, struct PgpOptContext *opt, struct Flags *flags)
{
	while (*opt->optarg && strchr (args, *opt->optarg))
		flags->args[flags->argc++] = *(opt->optarg++);
}

static void
setOpt (int opt, struct PgpOptContext *optp, struct Flags *flags)
{
	if (!flags->opt) {
		flags->opt = opt;

		if (optp->state == 1 && optp->optarg)
			switch (opt) {
			case 'k':
				setOptArgs ("s", optp, flags);
				break;
			case 'l':
				setOptArgs ("l", optp, flags);
				break;
			case 'r':
				setOptArgs ("su", optp, flags);
				break;
			case 'x':
				setOptArgs ("a", optp, flags);
				break;
			}

		return;
	}
	ErrorOutput(TRUE, LEVEL_CRITICAL, "ARGS_INCOMPATABLE", flags->opt, opt);
}

/*
 * A key printer for selectOneDBObj (above),
 * which prints keys for a menu.
 */
static void
keyPrint(PGPKeyIter *iter, PgpOutputType OutputType)
{
	SpecifiedOutputString(FALSE, OutputType, 0, "\n");
	kdbTtyShowKey(OutputType, iter, defaultset, 0);
}

/*
 * A name printer for selectOneDBObj (above),
 * which prints keys for a menu.
 */
static void
namePrint(PGPKeyIter *iter,	PgpOutputType OutputType)
{
	char namestring[256];
	size_t len = 256;

	SpecifiedOutputString(FALSE, OutputType, 0, "\n");
	pgpGetUserIDString (pgpKeyIterUserID (iter), kPGPUserIDPropName,
						namestring, &len);
	kdbTtyPutString (namestring, len, (unsigned) len, TRUE, OutputType, 0, 0);
	SpecifiedOutputString(FALSE, OutputType, 0, "\n");
	kdbTtyShowSigs (OutputType, iter, defaultset, 2);
}

/*
 * A sig printer for selectOneDBObj (above),
 * which prints keys for a menu.
 */
static void
sigPrint(PGPKeyIter *iter, PgpOutputType OutputType)
{
	pgpAssert(defaultset);
	SpecifiedOutputString(FALSE, OutputType, 0, "\n");
	kdbTtyShowSig(OutputType, iter, defaultset, 1);
}


/*  Print the deepest current object */

static void
objPrint(PGPKeyIter *iter, PgpOutputType OutputType)
{
    PGPKeyIter  *printiter = pgpCopyKeyIter (iter);

	if (pgpKeyIterCert (printiter))
		sigPrint (printiter, OutputType);
	else if (pgpKeyIterUserID (printiter))
		namePrint (printiter, OutputType);
	else
		keyPrint (printiter, OutputType);
	pgpFreeKeyIter (printiter);
}

/*
 * Searches <fullset> for keys matching the substrings on the
 * command line.
 * If <argc>==0 and <defAll>, uses the entire <fullset>.
 * In either case, the *subset returned is a valid, newly created,
 * keyset.
 *
 * Returns 1 if any keys were selected, else 0.
 */
static int
selectKeyArgs(int argc, char *argv[], PGPKeySet *fullset,
			  PGPKeySet **subset, int defAll, Boolean KeySetReadOnly)
{
	PGPError AddKeysResult = PGPERR_OK;
	int AnyKeys = 0;

	if (argc <= 0 && defAll) {
		*subset = pgpCopyKeySet (fullset);
	} else {
		if(!KeySetReadOnly) {
			*subset = pgpFilterKeySetAuto(fullset, argv[0]);
		}
		else {
			int i = 0;
			PGPKeySet *SingleMatchSet;
			/*Assign subset to a new keyset.  We can't just use the result of
			 *pgpFilterKeySetAuto(), because it returns a read-only keyset
			 *(not like that's documented, or anything)
			 */
			*subset = pgpNewKeySet();

			/*Loop through the command line arguments, adding each one to the
			 *resulting keyset.
			 */
			for(i = 0;
				i < argc && *subset && AddKeysResult == PGPERR_OK;
				++i) {
				if((SingleMatchSet = pgpFilterKeySetAuto (fullset, argv[i]))) {
					AddKeysResult = pgpAddKeys(*subset, SingleMatchSet);
					pgpFreeKeySet(SingleMatchSet);
				}
			}
		}
	}

	if((AddKeysResult == PGPERR_OK) &&
	   *subset &&
	   (pgpCountKeys(*subset) > 0)) {
		AnyKeys = 1;
	}
	return (AnyKeys);
}

/*
 * Select one object of type <selecttype> and return an iterator pointing
 * to it.  The iterator passed is replaced by a new one.
 *
 * <targettype> defines the requirements for the returned object. For example,
 * if <selecttype> == key and <targettype> == sig, the selected key must
 * have a signed userid attached to it.
 */
static int
selectOneDBObj(PGPKeyIter **iter,
			   int selecttype,
			   int targettype,
			   char *header)
{
	PGPKeyIter		*selectiter = *iter, *targetiter = NULL;
	PGPKeyIter		*iterList[50];
	PGPKey			*key = NULL;
	PGPUserID		*userid = NULL;
	PGPCert			*cert = NULL;
	int             maxObjs = sizeof(iterList) / sizeof(iterList[0]);
	int             numObjs = 0;
	int             notFirst = 0;
	int             result = 0;
	long            choice;
	char            *endNum, buf[32];
	int             i;
	
	do {
		result = 0;
		
		switch (selecttype) {
			case KDBTYPE_KEY:
				key = pgpKeyIterNext (selectiter);
				if(key) {
					/*  Do we need a name or a sig on the key? */
					if (targettype == KDBTYPE_USERID ||
						targettype == KDBTYPE_CERT) {
						targetiter = pgpCopyKeyIter (selectiter);
						do {
							if((userid = pgpKeyIterNextUserID (targetiter)) &&
							   ((targettype == KDBTYPE_USERID) ||
								((targettype == KDBTYPE_CERT) &&
								(cert = pgpKeyIterNextUIDCert(targetiter)))))
								result = 1;
						}while(userid && !result);
						
						pgpFreeKeyIter (targetiter);
					}
					else
						result = 1;
				}
				break;

			case KDBTYPE_USERID:
				if((userid = pgpKeyIterNextUserID (selectiter))) {
					if (targettype == KDBTYPE_CERT) {
						targetiter = pgpCopyKeyIter (selectiter);
						cert = pgpKeyIterNextUIDCert (targetiter);
						if (cert)
							result = 1;
						pgpFreeKeyIter (targetiter);
					}
					else
						result = 1;
				}
				break;

			case KDBTYPE_CERT:
				cert = pgpKeyIterNextUIDCert (selectiter);
				if (cert)
					result = 1;
				break;
		}

		if(result) {
			/*Copy and store the iterator that points to the current object */
			iterList[numObjs++] = pgpCopyKeyIter (selectiter);
			if (notFirst) {
				/*XXX Ambiguous match if we're in batch mode...*/
				if (numObjs == 2) {
					InteractionOutputString(TRUE, "%s\n 1) ", header);
					objPrint(iterList[0], OUTPUT_INTERACTION);
				}
				InteractionOutputString(TRUE, "%2d) ", numObjs);
				objPrint (selectiter, OUTPUT_INTERACTION);
			}
			else
				notFirst = 1;
		}
	} while(result && (numObjs < maxObjs));

	if (numObjs < maxObjs) {
		if(numObjs < 1)
			result = 0;
		else {
			if(numObjs == 1) {
				objPrint(iterList[0], OUTPUT_INTERACTION);
/*				*iter = iterList[0];*/
				*iter = pgpCopyKeyIter (iterList[0]);
				pgpFreeKeyIter(selectiter);
				result = 1;
			}
			else {
				result = 0;
				while(!result) {
					InteractionOutput(TRUE, "CHOOSE_ONE_ABOVE");
					pgpTtyGetString(buf, sizeof(buf), TRUE);
					choice = strtol(buf, &endNum, 10);
					while (isspace (*endNum))
						endNum++;
					if (choice >= 1 && choice <= numObjs) {
						*iter = pgpCopyKeyIter (iterList[choice - 1]);
						pgpFreeKeyIter (selectiter);
						result = numObjs;
					}
					else
						InteractionOutput(TRUE, "INVALID_SELECTION");
				}
			}
		}
	}
	else {
		ErrorOutput(TRUE, LEVEL_CRITICAL, "TOO_MANY_MATCHES");
		result = -1;
	}
		
	/*  Free all the key iterators we copied */
	for (i = 0; i < numObjs; i++)
		pgpFreeKeyIter (iterList[i]);

	return result;
}

#if 0

/*
 * Select one object of type <selecttype> and return an iterator pointing
 * to it.  The iterator passed is replaced by a new one.
 *
 * <targettype> defines the requirements for the returned object. For example,
 * if <selecttype> == key and <targettype> == sig, the selected key must
 * have a signed userid attached to it.
 */
static int
selectOneDBObj(PGPKeyIter **iter, int selecttype,
			   int targettype, char const *header)
{
	PGPKeyIter		*selectiter = *iter, *targetiter = NULL;
	PGPKeyIter		*iterList[50];
	PGPKey			*key = NULL;
	PGPUserID		*userid = NULL;
	PGPCert			*cert = NULL;
	int             maxObjs = sizeof(iterList) / sizeof(iterList[0]);
	int             numObjs = 0;
	int             notFirst = 0;
	int             result = 0;
	long            choice;
	char            *endNum, buf[32];
	int             i;

	for (;;) {
		result = 0;
		switch (selecttype) {
		case KDBTYPE_KEY:
			key = pgpKeyIterNext (selectiter);
			if (!key)
			    break;
			/*  Do we need a name or a sig on the key? */
			if (targettype == KDBTYPE_USERID || targettype == KDBTYPE_CERT) {
				targetiter = pgpCopyKeyIter (selectiter);
				for (;;) {
					userid = pgpKeyIterNextUserID (targetiter);
					if (userid && targettype == KDBTYPE_USERID) {
						result = 1;
						break;
					}
					else if (!userid)
						break;
					if (targettype == KDBTYPE_CERT) {
						cert = pgpKeyIterNextUIDCert (targetiter);
						if (cert) {
							result = 1;
							break;
						}
					}
				}
				pgpFreeKeyIter (targetiter);
			}
			else
				result = 1;
			break;
		case KDBTYPE_USERID:
			userid = pgpKeyIterNextUserID (selectiter);
			if (!userid)
			    break;
			if (targettype == KDBTYPE_CERT) {
				targetiter = pgpCopyKeyIter (selectiter);
				cert = pgpKeyIterNextUIDCert (targetiter);
				if (cert)
					result = 1;
				pgpFreeKeyIter (targetiter);
			}
			else
				result = 1;
			break;
		case KDBTYPE_CERT:
			cert = pgpKeyIterNextUIDCert (selectiter);
			if (cert)
				result = 1;
			break;
		}
		if (!result)
			break;

		if (numObjs >= maxObjs) {
			ErrorOutput(TRUE, LEVEL_CRITICAL, "TOO_MANY_MATCHES");
			goto destroyAndError;
		}

		/*  Copy and store the iterator that points to the current object */
		iterList[numObjs++] = pgpCopyKeyIter (selectiter);
		if (notFirst) {
			if (numObjs == 2) {
				InteractionOutputString(TRUE, "%s\n 1) ", header);
				objPrint (iterList[0], OUTPUT_INTERACTION);
			}
			InteractionOutputString(TRUE, "%2d) ", numObjs);
			objPrint (selectiter, OUTPUT_INTERACTION);
		}
		else
			notFirst = 1;
	}

	if (numObjs < 1)
		return 0;
	else if (numObjs == 1) {
		objPrint (iterList[0], OUTPUT_INTERACTION);
		*iter = iterList[0];
		pgpFreeKeyIter (selectiter);
		return numObjs;
	}
	InteractionOutput(TRUE, "CHOOSE_ONE_ABOVE");
	pgpTtyGetString(buf, sizeof(buf), TRUE);
	choice = strtol(buf, &endNum, 10);
	while (isspace (*endNum))
		endNum++;
	if (*endNum || choice < 1 || choice > numObjs) {
		InteractionOutput(TRUE, "INVALID_SELECTION");
		goto destroyAndError;
	}
	*iter = pgpCopyKeyIter (iterList[choice - 1]);
	pgpFreeKeyIter (selectiter);
	result = numObjs;
	goto destroyAndExit;

destroyAndError:
	result = -1;
destroyAndExit:
	/*  Free all the key iterators we copied */
	for (i = 0; i < numObjs; i++)
		pgpFreeKeyIter (iterList[i]);
	return result;
}

#endif


/*
 * Service routine for selectDBObject, below.  This one selects a user ID
 * and optionally a signature from a RingSet composed of a single key
 * and its descendants.
 *	
 * <iter> points to a key object previously selected, and is updated to
 * point to the child object.
 */
static int
selectChildObject(PGPKeyIter **iter, int selecttype, char const *prep)
{
	int err = 0;
	char header[255], *string = NULL;;

	pgpAssert (selecttype == KDBTYPE_USERID || selecttype == KDBTYPE_CERT);

	if (selecttype == KDBTYPE_USERID)
		LoadString(&string, "PLEASE_SELECT_A_USER_ID");
	else
		LoadString(&string, "PLEASE_SELECT_A_USER_ID_WITH_SIG");

	if(string) {
		sprintf(header, string, prep);

⌨️ 快捷键说明

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