📄 pgpk.c
字号:
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 + -