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

📄 pgpk.c

📁 著名的加密软件的应用于电子邮件中
💻 C
📖 第 1 页 / 共 4 页
字号:
	char buf[8];		/* enough for 7 digit response */

#if ONLY_TRUST_VALID_KEYS
	pgpGetKeyNumber (pgpKeyIterKey (iter), kPGPKeyPropValidity, &valid);
	if (valid != PGP_VALIDITY_COMPLETE) {
		ErrorOutput(TRUE, LEVEL_CRITICAL, "CANNOT_TRUST_INVALID_KEYS");
		return 0;
	}
#endif

	if (firsttime) {
		InteractionOutput(TRUE, "DO_YOU_WISH_TO_CHANGE_INTRODUCER_RELIABITY");
		if (!pgpTtyGetBool(0, TRUE)) {
			StatusOutput(TRUE, "NO_CHANGES_MADE");
			return 0;
		}
		InteractionOutput(TRUE, "DETERMINE_IN_YOUR_MIND");
	}

	pgptrustmodel = PGPTRUST0;
	if (pgptrustmodel == PGPTRUST0) {
		InteractionOutput(TRUE, "WOULD_YOU_TRUST_THIS_KEY_AND_OWNER");
		len = pgpTtyGetString (buf, 2, TRUE);
		if (!len) {
			StatusOutput(TRUE, "NO_CHANGES_MADE");
			return 0;
		}
		trustcode = atoi(buf);
		switch (trustcode) {
		case 1:
			keytrust = PGP_KEYTRUST_UNKNOWN;
			break;
		case 2:
			keytrust = PGP_KEYTRUST_NEVER;
			break;
		case 3:
			keytrust = PGP_KEYTRUST_MARGINAL;
			break;
		case 4:
			keytrust = PGP_KEYTRUST_COMPLETE;
			break;
		default:
			StatusOutput(TRUE, "UNRECOGNIZED_RESPONSE");
			StatusOutput(TRUE, "NO_CHANGES_MADE");
			return 0;
		}	
		if (pgpSetKeyTrust (pgpKeyIterKey (iter), keytrust))
			ErrorOutput(TRUE, LEVEL_CRITICAL, "UNABLE_TO_SET_TRUST");
	} else {					/* New trust model */
		InteractionOutput(TRUE, "DESCRIBE_CONFIDENCE_AS_INTRODUCER");
		if (!firsttime) {
			pgpGetUserIDNumber (pgpKeyIterUserID (iter),
									kPGPUserIDPropConfidence, &oldtrust);
			if (oldtrust == PGP_TRUST_INFINITE)
				InteractionOutput(TRUE, "CURRENTLY_INFINITE_TRUST");
			else if (oldtrust == 0)
				InteractionOutput(TRUE, "CURRENTLY_ZERO_TRUST");
			else {
				int d = oldtrust-PGP_TRUST_DECADE-PGP_TRUST_OCTAVE;
				int i;
				unsigned long l;
				InteractionOutput(TRUE,
								  "CURRENTLY_HAS_PERCENT_TRUST_START");
				d -= d % PGP_TRUST_DECADE;
				i = d / PGP_TRUST_DECADE;
				l = ringTrustToInt(oldtrust - d);
				if (i)
					InteractionOutputString(FALSE, "%lu%0*u", l, i, 0);
				else
					InteractionOutputString(FALSE, "%lu", l);
				InteractionOutput(TRUE,
								  "CURRENTLY_HAS_PERCENT_TRUST_END");
			}
		}
		InteractionOutput(TRUE, "ENTER_A_TRUST_RANGE");
		if (!firsttime)
			InteractionOutput(FALSE, "OR_HIT_RETURN_TO_LEAVE_UNCHANGED");

		InteractionOutput(TRUE, "WILL_BE_WRONG_TIME_TIME_IN");
		len = pgpTtyGetString (buf, sizeof(buf), TRUE);
		if (!len) {
			StatusOutput(TRUE, "NO_CHANGES_MADE");
			return 0;
		}
		trustcode = strtoul(buf, NULL, 0);
		confvalue = ringIntToTrust(trustcode);
		pgpSetUserIDConf(pgpKeyIterUserID (iter), confvalue);
	}
	pgpCommitKeyRingChanges (defaultset);
	return 1;		/* made a change */
}


/* Helper routine for doKeyEdit, when the key being edited is someone else's */
static int
doKeyEditOthers(struct Flags *flags, PGPKeyIter *iter)
{
	int err = PGPERR_OK;
	PgpTrustModel pgptrustmodel;
	Boolean secret, SetAxiomatic = FALSE;
	PGPKey *key = pgpKeyIterKey (iter);
	char *string = NULL;

	(void) flags;

	pgptrustmodel = PGPTRUST0;
	pgpGetKeyBoolean (key, kPGPKeyPropIsSecret, &secret);
	if (secret) {
		InteractionOutput(TRUE, "DO_YOU_WANT_THIS_KEY_AXIOMATIC");
		if (pgpTtyGetBool(0, TRUE)) {
		    if((err = pgpSetKeyAxiomatic (key, FALSE, NULL)) == PGPERR_OK) {
				StatusOutput(TRUE, "PUBLIC_KEYRING_UPDATED");
				SetAxiomatic = TRUE;
				pgpCommitKeyRingChanges (defaultset);
			}
		}
	}

	if(!SetAxiomatic) {
		if (pgptrustmodel == PGPTRUST0) {
			if(doKeyEditTrust(iter, 0))
				err = PGPERR_OK;
		} else {
			/* New trust model works on a per user ID basis.*/
			/* Must select one. */
			if((err = LoadString(&string, "TO_EDIT")) == PGPERR_OK) {
				err = selectChildObject(&iter, KDBTYPE_USERID, string);
				FreeString(&string);
			
				kdbTtyShowKey(OUTPUT_INTERACTION, iter, defaultset, 0);
				err = doKeyEditTrust(iter, 0);
			}
		}
	}

	return(err);
}

/*
 * Helper routine for doKeyEditSelf, to change a pass phrase.
 * If parent is non-NULL, it is a subkey pass phrase.
 * secobj is the object getting its pass phrase changed, with seckey
 * having been made from it.
 */
static int
doKeyChangePassphrase(PGPKeyIter *iter)
{
	int         err = PGPERR_OK;
	char		oldphrase[PASSLEN], newphrase[PASSLEN], newphrase2[PASSLEN];
	PGPSubKey   *subkey;

	InteractionOutput(TRUE, "NEED_OLD_PASSPHRASE");
	pgpTtyGetPass (FALSE, oldphrase, PASSLEN);
	InteractionOutput(TRUE, "NEED_NEW_PASSPHRASE");
	pgpTtyGetPass (FALSE, newphrase, PASSLEN);
	InteractionOutput(TRUE, "ENTER_IT_A_SECOND_TIME");
	pgpTtyGetPass (FALSE, newphrase2, PASSLEN);
	if (strcmp (newphrase, newphrase2) != 0) {
		ErrorOutput(TRUE, LEVEL_CRITICAL, "PASSPHRASES_ARE_DIFFERENT");
		return -1;
	}
	StatusOutput(TRUE, "CHANGING_MASTER_KEY_PASSPHRASE");
	err = pgpChangePassphrase (pgpKeyIterKey (iter), oldphrase, newphrase);
	if (err)
		ErrorOutput(TRUE,
					LEVEL_CRITICAL,
					"PASSPHRASE_CHANGE_FAILED_MASTER",
					err);
	else {
		while ((subkey = pgpKeyIterNextSubKey (iter)) != NULL) {
			StatusOutput(TRUE, "CHANGING_SUBKEY_PASSPHRASE");
			err = pgpChangeSubKeyPassphrase (subkey, oldphrase, newphrase);
			if (err) {
				ErrorOutput(TRUE,
							LEVEL_CRITICAL,
							"PASSPHRASE_CHANGE_FAILED_SUBKEY",
							err);
				break;
			}
		}
	}
	return err;
}


/* Helper routine for doKeyEdit, when the key being edited belongs to us */
static int
doKeyEditSelf(struct Flags *flags, PGPKeyIter *iter)
{
	int err = 0;
	char	passphrase[PASSLEN];
	PGPKey *key = pgpKeyIterKey (iter);

	(void)flags;		/* make the compiler happy */

	InteractionOutput(TRUE, "CONFIRM_NON_AXIOMATIC");
	if (pgpTtyGetBool (0, TRUE)) {
	    pgpUnsetKeyAxiomatic (key);
		goto commit;
	}
	InteractionOutput(TRUE, "CONFIRM_ADD_NEW_USERID");
	if (pgpTtyGetBool (0, TRUE)) {
		char namebuf[256];
		int namelen;

		InteractionOutput(TRUE, "ENTER_NEW_USERID");
		namelen = pgpTtyGetString (namebuf, sizeof (namebuf), TRUE);
		if (!namelen) {
			ErrorOutput(TRUE, LEVEL_CRITICAL, "NO_NAME_ENTERED");
			goto cleanup;
		}

		pgpTtyGetPass (FALSE, passphrase, PASSLEN);
		err = pgpAddUserID(pgpKeyIterKey (iter),
						   namebuf,
						   namelen,
						   passphrase);
		if (err) {
			ErrorOutput(TRUE,
						LEVEL_CRITICAL,
						"UNABLE_TO_ADD_NEW_USERID",
						err);
			goto cleanup;
		}
#if 0
		/* debugging consistency check */
		{
			extern RingPool PGPKDBExport *pgpRingPool;
			int nsets, nfiles;
			ringPoolConsistent (pgpRingPool, &nsets, &nfiles);
			pgpAssert (nsets==5);
			pgpAssert (nfiles==3);
		}
#endif
	}


	InteractionOutput(TRUE, "CONFIRM_CHANGE_PASSPHRASE");
	if (pgpTtyGetBool(0, TRUE)) {
		err = doKeyChangePassphrase(iter);
		if (err < 0) {
			ErrorOutput(TRUE,
						LEVEL_CRITICAL,
						"CHANGE_PASSPHRASE_FAILED",
						err);
			goto cleanup;
		}
#if 0
		/* debugging consistency check */
		{
			extern RingPool PGPKDBExport *pgpRingPool;
			int nsets, nfiles;
			ringPoolConsistent (pgpRingPool, &nsets, &nfiles);
			pgpAssert (nsets==3);
			pgpAssert (nfiles==3);
		}
#endif
	}

	InteractionOutput(TRUE, "CONFIRM_SET_DEFAULT_KEY");
	if (pgpTtyGetBool (0, TRUE))
	    pgpSetDefaultPrivateKey (pgpKeyIterKey (iter));

commit:
	StatusOutput(TRUE, "KEYRINGS_UPDATED");
	pgpCommitKeyRingChanges (defaultset);
cleanup:
	return err;
}


static int
doKeyEdit (struct Flags *flags, int argc, char *argv[])
{
	char const *prep = "to edit";
	PGPKeyIter *iter = NULL;
	int err;
	Boolean axiomatic;

	(void)flags;		/* make the compiler happy */

	/* Select object to sign */
	err = selectDBObject (argc, argv, defaultset, KDBTYPE_KEY,
						  prep, &iter);
	if (err <= 0)
		return err;

	InteractionOutputString(FALSE, "\n");
	kdbKeyPrint (OUTPUT_INTERACTION, iter, 1);
	InteractionOutputString(FALSE, "\n");

	pgpGetKeyBoolean (pgpKeyIterKey (iter), kPGPKeyPropIsAxiomatic,
					  &axiomatic);
	if (axiomatic)
		err = doKeyEditSelf(flags, iter);
	else
	    err = doKeyEditOthers(flags, iter);
	pgpFreeKeyIter (iter);
	return err;
}


/*
 * This handles key, user ID (with -ru), or signature (with -rs) removal.
 */
static int
doKeyRemove (struct Flags *flags, int argc, char *argv[])
{
	int err = 0;
	PGPKeyIter	  *iter = NULL;
	PGPKeySet     *newset = NULL;
	PGPKey        *key = NULL;
	int removelevel;
	char *prep = NULL, *typename = NULL;
	Boolean IsSecret = FALSE, RemoveKey = FALSE;

	LoadString(&prep, "TO_BE_REMOVED_FRAGMENT");
	
	/* Distinguish what we are to remove */
	if (flags->argc && strchr(flags->args, 's')) {
		removelevel = KDBTYPE_CERT; /* signature */
		LoadString(&typename, "SIGNATURE_FRAGMENT");
	}
	else if (flags->argc && strchr(flags->args, 'u')) {
		removelevel = KDBTYPE_USERID; /* user id */
		LoadString(&typename, "USERID_FRAGMENT");
	}
	else {
		removelevel = KDBTYPE_KEY; /* key */
		LoadString(&typename, "KEY_FRAGMENT");
	}

	/* Select object to remove */
	InteractionOutputString(TRUE, "\n");

	err = selectDBObject(argc, argv, defaultset, removelevel,
							prep, &iter);
	if (err <= 0)
		goto cleanup;

	/* err holds number of possible objects at that level */
	if (removelevel == KDBTYPE_USERID && err == 1) {
		err = 0;
		ErrorOutput(TRUE,
					LEVEL_CRITICAL,
					"SELECTED_KEY_HAS_ONLY_ONE_USERID",
					prep);
		goto cleanup;
	}

	/* Confirm removal */
	StatusOutput(TRUE,
				 "FOLLOWING_OBJECT_HAS_BEEN_SELECTED",
				 typename,
				 prep);

	objPrint(iter, OUTPUT_STATUS);
	/* Perform removal, but don't write back yet */
	switch (removelevel) {
		case KDBTYPE_KEY:
			/*We only ask if they're trying to delete a secret key. UserIDs
			 *and certs can be gotten again from other sources, but you are
			 *presumably the only person with a copy of your secret key.
			 */
			key = pgpKeyIterKey(iter);
			pgpAssert(key);
			
			if(key) {
				pgpGetKeyBoolean(key, kPGPKeyPropIsSecret, &IsSecret);
				if(IsSecret) {
					InteractionOutput(TRUE,
									  "VERIFY_REMOVE_KEY_PUBLIC_PRIVATE");
					RemoveKey = pgpTtyGetBool(0, TRUE);
				}
				else
					RemoveKey = TRUE;
				
				if(RemoveKey) {
					newset = pgpNewSingletonKeySet (pgpKeyIterKey(iter));
					err = pgpRemoveKeys (defaultset, newset);
					pgpFreeKeySet (newset);
#ifdef WUBBA
					PGPKey *TmpKey;
					char buf[256];
					int bufsize;
					bufsize = sizeof(buf);

					TmpKey = pgpKeyIterKey(iter);
					pgpGetKeyString(TmpKey, kPGPKeyPropKeyId, buf, &bufsize);
					KMConvertStringKeyID (buf);

					newset = pgpFilterKeySetUserID(defaultset,
												   buf,
												   strlen(buf));
/*					newset = pgpNewSingletonKeySet (TmpKey);*/
/*					err = pgpRemoveKeys (defaultset, newset);*/
					err = PGPERR_OK;
#endif
					StatusOutput(TRUE, "REMOVED");
				}
				else {
					StatusOutput(TRUE, "CANCELED");
					err = PGPERR_OK;
				}
			}
			else {
				ErrorOutput(TRUE, LEVEL_CRITICAL, "UNABLE_TO_ITERATE_KEY");
				err = PGPERR_NOMEM;
			}
			break;
		case KDBTYPE_USERID:
			if((err = pgpRemoveUserID (pgpKeyIterUserID (iter))) == PGPERR_OK)
				StatusOutput(TRUE, "REMOVED");
			break;
		case KDBTYPE_CERT:
			if((err = pgpRemoveCert (pgpKeyIterCert (iter))) == PGPERR_OK)
				StatusOutput(TRUE, "REMOVED");
	}
	if (err) {
		ErrorOutput(TRUE, LEVEL_CRITICAL, "UNABLE_TO_REMOVE_OBJECT");
		goto cleanup;
	}

	/* Write out results */
	pgpCommitKeyRingChanges (defaultset);

	/* success */
	err = PGPERR_OK;

cleanup:
	if (iter)
	    pgpFreeKeyIter (iter);

	if(prep)
		FreeString(&prep);

	if(typename)
		FreeString(&typename);

	return err;
}


/*
 * Issue a signature on a userID.
 */
static int
doKeySign (struct Flags *flags, int argc, char *argv[])
{
	int err;
	char *prep = NULL;
	char passphrase[PASSLEN];
	PGPKeyIter  *iter = NULL;
	PGPKey *key;
	(void)flags;
	
	if (flags->signKey != NULL) {
		key = flags->signKey;
	} else {
		key = pgpGetDefaultPrivateKey (defaultset);
		if (!key) {
			ErrorOutput(TRUE, LEVEL_CRITICAL, "NO_DEFAULT_PRIVATE_KEY");
			return(PGPERR_NO_SECKEY);
		}
	}

	InteractionOutputString(TRUE, "\n");

	LoadString(&prep, "TO_BE_SIGNED_FRAGMENT");

	/* Select object to sign */
	err = selectDBObject(argc, argv, defaultset, KDBTYPE_USERID,
								prep, &iter);

	if(err >= PGPERR_OK) {
		/* Confirm signature */
		InteractionOutput(TRUE, "VALIDITY_CERTIFICATION_WARNING");
		
		if (pgpTtyGetBool(0, TRUE)) {
			StatusOutput(TRUE, "KEY_SELECTED_FOR_SIGNING_IS");
			objPrint (iter, OUTPUT_INTERACTION);
			pgpTtyGetPass (FALSE, passphrase, PASSLEN);
			if((err = pgpCertifyUserID(pgpKeyIterUserID (iter),
									   key,
									   passphrase)) == PGPERR_OK) {
				StatusOutput(TRUE, "KEY_SIG_CERT_ADDED");
			
				pgpCommitKeyRingChanges (defaultset);
			}
			else {
				ErrorOutput(TRUE,
							LEVEL_CRITICAL,
							"KEY_SIGN_OPERATION_FAILED");
			}
		}
		else {
			StatusOutput(TRUE, "KEY_SIGNING_CANCELED");
		}
	}

	if(iter)
		pgpFreeKeyIter (iter);

	if(prep)
		FreeString(&prep);

	return err;
}


/*

⌨️ 快捷键说明

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