[pacman-dev] [PATCH v3 1/3] signing: move key import confirmation before key_search
Jonas Witschel
diabonas at archlinux.org
Wed Oct 2 14:40:54 UTC 2019
Ask the user whether they want to import a missing key before even doing
a search on the keyserver. This will be useful for getting Web Key
Directory support in place: for a WKD, looking up and importing a key
are a single action, so the current key_search -> QUESTION -> key_import
workflow does not apply.
Since only the ID of the package signing key is available before
key_search, we display the packager variable in addition to the key ID
for user convenience.
Signed-off-by: Jonas Witschel <diabonas at archlinux.org>
---
lib/libalpm/be_package.c | 12 +++++++++-
lib/libalpm/signing.c | 50 ++++++++++++++++++++++------------------
lib/libalpm/signing.h | 2 +-
lib/libalpm/sync.c | 22 +++++++++++++++---
src/pacman/callback.c | 13 ++---------
5 files changed, 60 insertions(+), 39 deletions(-)
diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c
index ac911bdb..6c93d12b 100644
--- a/lib/libalpm/be_package.c
+++ b/lib/libalpm/be_package.c
@@ -731,6 +731,8 @@ int SYMEXPORT alpm_pkg_load(alpm_handle_t *handle, const char *filename, int ful
{
int validation = 0;
char *sigpath;
+ alpm_pkg_t *pkg_temp;
+ char *packager;
CHECK_HANDLE(handle, return -1);
ASSERT(pkg != NULL, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1));
@@ -755,9 +757,17 @@ int SYMEXPORT alpm_pkg_load(alpm_handle_t *handle, const char *filename, int ful
for(k = keys; k; k = k->next) {
char *key = k->data;
if(_alpm_key_in_keychain(handle, key) == 0) {
- if(_alpm_key_import(handle, key) == -1) {
+ pkg_temp = _alpm_pkg_load_internal(handle, filename, full);
+ if(pkg_temp) {
+ packager = pkg_temp->packager;
+ _alpm_pkg_free(pkg_temp);
+ } else {
+ packager = NULL;
+ }
+ if(_alpm_key_import(handle, packager, key) == -1) {
fail = 1;
}
+ free(packager);
}
}
FREELIST(keys);
diff --git a/lib/libalpm/signing.c b/lib/libalpm/signing.c
index 92598b0e..c1ae5354 100644
--- a/lib/libalpm/signing.c
+++ b/lib/libalpm/signing.c
@@ -433,42 +433,45 @@ gpg_error:
/**
* Import a key defined by a fingerprint into the local keyring.
* @param handle the context handle
+ * @param uid a user ID of the key to import
* @param fpr the fingerprint key ID to import
* @return 0 on success, -1 on error
*/
-int _alpm_key_import(alpm_handle_t *handle, const char *fpr)
+int _alpm_key_import(alpm_handle_t *handle, const char *uid, const char *fpr)
{
int ret = -1;
alpm_pgpkey_t fetch_key;
+
+ if(_alpm_access(handle, handle->gpgdir, "pubring.gpg", W_OK)) {
+ /* no chance of import succeeding if pubring isn't writable */
+ _alpm_log(handle, ALPM_LOG_ERROR, _("keyring is not writable\n"));
+ return -1;
+ }
+
memset(&fetch_key, 0, sizeof(fetch_key));
+ STRDUP(fetch_key.uid, uid, return -1);
+ STRDUP(fetch_key.fingerprint, fpr, return -1);
- if(key_search(handle, fpr, &fetch_key) == 1) {
- _alpm_log(handle, ALPM_LOG_DEBUG,
- "unknown key, found %s on keyserver\n", fetch_key.uid);
- if(!_alpm_access(handle, handle->gpgdir, "pubring.gpg", W_OK)) {
- alpm_question_import_key_t question = {
+ alpm_question_import_key_t question = {
.type = ALPM_QUESTION_IMPORT_KEY,
.import = 0,
.key = &fetch_key
};
- QUESTION(handle, &question);
- if(question.import) {
- if(key_import(handle, &fetch_key) == 0) {
- ret = 0;
- } else {
- _alpm_log(handle, ALPM_LOG_ERROR,
- _("key \"%s\" could not be imported\n"), fetch_key.uid);
- }
+ QUESTION(handle, &question);
+ if(question.import) {
+ if(key_search(handle, fpr, &fetch_key) == 1) {
+ _alpm_log(handle, ALPM_LOG_DEBUG,
+ _("key \"%s\" on keyserver\n"), fetch_key.uid);
+ if(key_import(handle, &fetch_key) == 0) {
+ ret = 0;
+ } else {
+ _alpm_log(handle, ALPM_LOG_ERROR,
+ _("key \"%s\" could not be imported\n"), fetch_key.uid);
}
} else {
- /* keyring directory was not writable, so we don't even try */
- _alpm_log(handle, ALPM_LOG_WARNING,
- _("key %s, \"%s\" found on keyserver, keyring is not writable\n"),
- fetch_key.fingerprint, fetch_key.uid);
+ _alpm_log(handle, ALPM_LOG_ERROR,
+ _("key \"%s\" could not be looked up remotely\n"), fpr);
}
- } else {
- _alpm_log(handle, ALPM_LOG_ERROR,
- _("key \"%s\" could not be looked up remotely\n"), fpr);
}
gpgme_key_unref(fetch_key.data);
@@ -714,7 +717,8 @@ int _alpm_key_in_keychain(alpm_handle_t UNUSED *handle, const char UNUSED *fpr)
return -1;
}
-int _alpm_key_import(alpm_handle_t UNUSED *handle, const char UNUSED *fpr)
+int _alpm_key_import(alpm_handle_t UNUSED *handle, const char UNUSED *uid,
+ const char UNUSED *fpr)
{
return -1;
}
@@ -900,7 +904,7 @@ int _alpm_process_siglist(alpm_handle_t *handle, const char *identifier,
_alpm_log(handle, ALPM_LOG_ERROR,
_("%s: key \"%s\" is unknown\n"), identifier, name);
- if(_alpm_key_import(handle, result->key.fingerprint) == 0) {
+ if(_alpm_key_import(handle, result->key.uid, result->key.fingerprint) == 0) {
retry = 1;
}
diff --git a/lib/libalpm/signing.h b/lib/libalpm/signing.h
index f8b84b94..36b64384 100644
--- a/lib/libalpm/signing.h
+++ b/lib/libalpm/signing.h
@@ -32,6 +32,6 @@ int _alpm_process_siglist(alpm_handle_t *handle, const char *identifier,
alpm_siglist_t *siglist, int optional, int marginal, int unknown);
int _alpm_key_in_keychain(alpm_handle_t *handle, const char *fpr);
-int _alpm_key_import(alpm_handle_t *handle, const char *fpr);
+int _alpm_key_import(alpm_handle_t *handle, const char *uid, const char *fpr);
#endif /* ALPM_SIGNING_H */
diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c
index cbd072e6..dd695877 100644
--- a/lib/libalpm/sync.c
+++ b/lib/libalpm/sync.c
@@ -47,6 +47,12 @@
#include "diskspace.h"
#include "signing.h"
+struct keyinfo_t {
+ char* uid;
+ char* keyid;
+};
+
+
/** Check for new version of pkg in sync repos
* (only the first occurrence is considered in sync)
*/
@@ -872,6 +878,7 @@ static int check_keyring(alpm_handle_t *handle)
size_t current = 0, numtargs;
alpm_list_t *i, *errors = NULL;
alpm_event_t event;
+ struct keyinfo_t *keyinfo;
event.type = ALPM_EVENT_KEYRING_START;
EVENT(handle, &event);
@@ -905,7 +912,13 @@ static int check_keyring(alpm_handle_t *handle)
char *key = k->data;
if(!alpm_list_find_str(errors, key) &&
_alpm_key_in_keychain(handle, key) == 0) {
- errors = alpm_list_add(errors, strdup(key));
+ keyinfo = malloc(sizeof(struct keyinfo_t));
+ if(!keyinfo) {
+ break;
+ }
+ keyinfo->uid = strdup(pkg->packager);
+ keyinfo->keyid = strdup(key);
+ errors = alpm_list_add(errors, keyinfo);
}
}
FREELIST(keys);
@@ -926,10 +939,13 @@ static int check_keyring(alpm_handle_t *handle)
int fail = 0;
alpm_list_t *k;
for(k = errors; k; k = k->next) {
- char *key = k->data;
- if(_alpm_key_import(handle, key) == -1) {
+ keyinfo = k->data;
+ if(_alpm_key_import(handle, keyinfo->uid, keyinfo->keyid) == -1) {
fail = 1;
}
+ free(keyinfo->uid);
+ free(keyinfo->keyid);
+
}
event.type = ALPM_EVENT_KEY_DOWNLOAD_DONE;
EVENT(handle, &event);
diff --git a/src/pacman/callback.c b/src/pacman/callback.c
index fc4ce875..25528100 100644
--- a/src/pacman/callback.c
+++ b/src/pacman/callback.c
@@ -456,17 +456,8 @@ void cb_question(alpm_question_t *question)
case ALPM_QUESTION_IMPORT_KEY:
{
alpm_question_import_key_t *q = &question->import_key;
- char created[12];
- time_t time = (time_t)q->key->created;
- strftime(created, 12, "%Y-%m-%d", localtime(&time));
-
- if(q->key->revoked) {
- q->import = yesno(_("Import PGP key %u%c/%s, \"%s\", created: %s (revoked)?"),
- q->key->length, q->key->pubkey_algo, q->key->fingerprint, q->key->uid, created);
- } else {
- q->import = yesno(_("Import PGP key %u%c/%s, \"%s\", created: %s?"),
- q->key->length, q->key->pubkey_algo, q->key->fingerprint, q->key->uid, created);
- }
+ q->import = yesno(_("Import PGP key %s, \"%s\"?"),
+ q->key->fingerprint, q->key->uid);
}
break;
}
--
2.23.0
More information about the pacman-dev
mailing list