cpp: Add support for multiple keysigs in edit

* lang/cpp/src/gpgsignkeyeditinteractor.cpp
(GpgSignKeyEditInteractor::setDupeOk): New.
(makeTable): Add new tansitions.
(SignKeyState): Add DUPE_OK Status.
(GpgSignKeyEditInteractor::action): Handle DUPE_OK.
(GpgSignKeyEditInteractor::Private::Private): Carry flag.

--
When extended-edit is enabled this can be used to answer
the "dupe_ok" query from the edit-key with yes.

This is for:
GnuPG-Bug-Id: T4734
This commit is contained in:
Andre Heinecke 2019-10-29 16:26:42 +01:00
parent 83ecf1686a
commit 36f7f7a478
No known key found for this signature in database
GPG Key ID: 2978E9D40CBABA5C
3 changed files with 26 additions and 1 deletions

7
NEWS
View File

@ -3,8 +3,15 @@ Noteworthy changes in version 1.14.0 (unreleased)
* New context flag "extended-edit" to enable expert key edit. [#4734] * New context flag "extended-edit" to enable expert key edit. [#4734]
* cpp: Add convenience API to obtain remarks. [#4734]
* cpp: The sign key edit-interactor now supports multiple signatures
from the same key. [#4734]
* Interface changes relative to the 1.13.1 release: * Interface changes relative to the 1.13.1 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cpp: UserID::remark NEW.
cpp: GpgSignKeyEditInteractor::setDupeOk NEW.
Noteworthy changes in version 1.13.1 (2019-06-13) Noteworthy changes in version 1.13.1 (2019-06-13)

View File

@ -64,6 +64,7 @@ public:
std::vector<unsigned int> userIDs; std::vector<unsigned int> userIDs;
std::vector<unsigned int>::const_iterator currentId, nextId; std::vector<unsigned int>::const_iterator currentId, nextId;
unsigned int checkLevel; unsigned int checkLevel;
bool dupeOk;
const char *command() const const char *command() const
{ {
@ -126,7 +127,8 @@ GpgSignKeyEditInteractor::Private::Private()
userIDs(), userIDs(),
currentId(), currentId(),
nextId(), nextId(),
checkLevel(0) checkLevel(0),
dupeOk(false)
{ {
} }
@ -159,6 +161,7 @@ enum SignKeyState {
SET_TRUST_REGEXP, SET_TRUST_REGEXP,
CONFIRM, CONFIRM,
CONFIRM2, CONFIRM2,
DUPE_OK,
QUIT, QUIT,
SAVE, SAVE,
ERROR = EditInteractor::ErrorState ERROR = EditInteractor::ErrorState
@ -193,6 +196,7 @@ static GpgSignKeyEditInteractor_Private::TransitionMap makeTable()
addEntry(SET_CHECK_LEVEL, GET_BOOL, "sign_uid.okay", CONFIRM); addEntry(SET_CHECK_LEVEL, GET_BOOL, "sign_uid.okay", CONFIRM);
addEntry(SET_EXPIRE, GET_BOOL, "sign_uid.class", SET_CHECK_LEVEL); addEntry(SET_EXPIRE, GET_BOOL, "sign_uid.class", SET_CHECK_LEVEL);
addEntry(CONFIRM, GET_BOOL, "sign_uid.local_promote_okay", CONFIRM); addEntry(CONFIRM, GET_BOOL, "sign_uid.local_promote_okay", CONFIRM);
addEntry(DUPE_OK, GET_BOOL, "sign_uid.okay", CONFIRM);
addEntry(CONFIRM, GET_BOOL, "sign_uid.okay", CONFIRM); addEntry(CONFIRM, GET_BOOL, "sign_uid.okay", CONFIRM);
addEntry(CONFIRM2, GET_BOOL, "sign_uid.okay", CONFIRM); addEntry(CONFIRM2, GET_BOOL, "sign_uid.okay", CONFIRM);
addEntry(CONFIRM, GET_LINE, "keyedit.prompt", COMMAND); addEntry(CONFIRM, GET_LINE, "keyedit.prompt", COMMAND);
@ -205,6 +209,7 @@ static GpgSignKeyEditInteractor_Private::TransitionMap makeTable()
addEntry(UIDS_LIST_SEPARATELY_DONE, GET_LINE, "sign_uid.expire", SET_EXPIRE); addEntry(UIDS_LIST_SEPARATELY_DONE, GET_LINE, "sign_uid.expire", SET_EXPIRE);
addEntry(UIDS_LIST_SEPARATELY_DONE, GET_LINE, "sign_uid.class", SET_CHECK_LEVEL); addEntry(UIDS_LIST_SEPARATELY_DONE, GET_LINE, "sign_uid.class", SET_CHECK_LEVEL);
addEntry(UIDS_LIST_SEPARATELY_DONE, GET_BOOL, "sign_uid.okay", CONFIRM); addEntry(UIDS_LIST_SEPARATELY_DONE, GET_BOOL, "sign_uid.okay", CONFIRM);
addEntry(UIDS_LIST_SEPARATELY_DONE, GET_BOOL, "sign_uid.dupe_okay", DUPE_OK);
addEntry(CONFIRM, GET_LINE, "keyedit.prompt", QUIT); addEntry(CONFIRM, GET_LINE, "keyedit.prompt", QUIT);
addEntry(ERROR, GET_LINE, "keyedit.prompt", QUIT); addEntry(ERROR, GET_LINE, "keyedit.prompt", QUIT);
addEntry(QUIT, GET_BOOL, "keyedit.save.okay", SAVE); addEntry(QUIT, GET_BOOL, "keyedit.save.okay", SAVE);
@ -236,6 +241,8 @@ const char *GpgSignKeyEditInteractor::action(Error &err) const
return nullptr; return nullptr;
case SET_CHECK_LEVEL: case SET_CHECK_LEVEL:
return check_level_strings[d->checkLevel]; return check_level_strings[d->checkLevel];
case DUPE_OK:
return answer(d->dupeOk);
case CONFIRM2: case CONFIRM2:
case CONFIRM: case CONFIRM:
return answer(true); return answer(true);
@ -326,3 +333,9 @@ void GpgSignKeyEditInteractor::setSigningOptions(int options)
assert(!d->started); assert(!d->started);
d->options = options; d->options = options;
} }
void GpgSignKeyEditInteractor::setDupeOk(bool value)
{
assert(!d->started);
d->dupeOk = value;
}

View File

@ -52,6 +52,11 @@ public:
void setUserIDsToSign(const std::vector<unsigned int> &userIDsToSign); void setUserIDsToSign(const std::vector<unsigned int> &userIDsToSign);
void setSigningOptions(int options); void setSigningOptions(int options);
/* Set this if it is ok to overwrite an existing signature. In that
* case the context has to have the flag "extended-edit" set to 1 through
* Context::setFlag before calling edit.*/
void setDupeOk(bool value);
private: private:
const char *action(Error &err) const override; const char *action(Error &err) const override;
unsigned int nextState(unsigned int statusCode, const char *args, Error &err) const override; unsigned int nextState(unsigned int statusCode, const char *args, Error &err) const override;