[pacman-dev] [PATCH 3/5 v2] sync: lookup missing keys in the WKD using the packager email

Jonas Witschel diabonas at gmx.de
Mon Aug 5 15:32:35 UTC 2019


We assume that the packager is of the form
"Example Name <email at 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 at 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 at 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


More information about the pacman-dev mailing list