We assume that the packager is of the form "Example Name <email@address.invalid>" and that the key used to sign the package can be resolved using WKD with this address. This means that the package signing key should have one user ID with the given email address, which does not need to be a valid address, but needs to be published in the WKD. Signed-off-by: Jonas Witschel <diabonas@gmx.de> --- lib/libalpm/sync.c | 20 +++++++++++++++++--- lib/libalpm/util.c | 23 +++++++++++++++++++++++ lib/libalpm/util.h | 1 + 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index efad77ba..6e8e23f1 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -47,6 +47,11 @@ #include "diskspace.h" #include "signing.h" +struct keyinfo_t { + char* email; + char* keyid; +}; + /** Check for new version of pkg in sync repos * (only the first occurrence is considered in sync) */ @@ -872,6 +877,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 +911,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; + } + _alpm_email_from_packager(pkg->packager, &keyinfo->email); + keyinfo->keyid = strdup(key); + errors = alpm_list_add(errors, keyinfo); } } FREELIST(keys); @@ -926,10 +938,12 @@ 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, NULL, key) == -1) { + keyinfo = k->data; + if(_alpm_key_import(handle, keyinfo->email, keyinfo->keyid) == -1) { fail = 1; } + free(keyinfo->email); + free(keyinfo->keyid); } event.type = ALPM_EVENT_KEY_DOWNLOAD_DONE; EVENT(handle, &event); diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c index d33eef2a..5e2e9770 100644 --- a/lib/libalpm/util.c +++ b/lib/libalpm/util.c @@ -1491,3 +1491,26 @@ void _alpm_alloc_fail(size_t size) { fprintf(stderr, "alloc failure: could not allocate %zu bytes\n", size); } + +/** Extract the email address from the packager field + * @param packager the packager to parse in the form "Example Name <email@address.invalid>" + * @param email to hold email address + * @return 0 on success, -1 on error + */ +int _alpm_email_from_packager(const char *packager, char **email) +{ + char *start, *end; + + start = strrchr(packager, '<'); + if(start) { + end = strrchr(start, '>'); + } + + if(start && end) { + STRNDUP(*email, start+1, end-start-1, return -1); + return 0; + } else { + email = NULL; + return -1; + } +} diff --git a/lib/libalpm/util.h b/lib/libalpm/util.h index 9a3942f1..f1ff97be 100644 --- a/lib/libalpm/util.h +++ b/lib/libalpm/util.h @@ -147,6 +147,7 @@ int _alpm_fnmatch_patterns(alpm_list_t *patterns, const char *string); int _alpm_fnmatch(const void *pattern, const void *string); void *_alpm_realloc(void **data, size_t *current, const size_t required); void *_alpm_greedy_grow(void **data, size_t *current, const size_t required); +int _alpm_email_from_packager(const char *packager, char **email); #ifndef HAVE_STRSEP char *strsep(char **, const char *); -- 2.22.0