signing: move key import confirmation before key_search
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@archlinux.org> Signed-off-by: Allan McRae <allan@archlinux.org>
This commit is contained in:
parent
0c4a8ae24b
commit
80e2e1c7c9
5 changed files with 61 additions and 40 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
memset(&fetch_key, 0, sizeof(fetch_key));
|
||||
|
||||
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 = {
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue