[pacman-dev] [PATCH 3/4] Allow frontend access to signature verification information

Dan McGee dan at archlinux.org
Sun Jul 3 16:28:44 EDT 2011


Show output in -Qip for each package signature, which includes the UID
string from the key ("Joe User <joe at example.com>") and the validity of
said key. Example output:

Signatures     : Valid signature from "Dan McGee <dpmcgee at gmail.com>"
                 Unknown signature from "<Key Unknown>"
                 Invalid signature from "Dan McGee <dpmcgee at gmail.com>"

Also add a backend alpm_sigresult_cleanup() function since memory
allocation took place on this object, and we need some way of freeing
it.

Signed-off-by: Dan McGee <dan at archlinux.org>
---
 lib/libalpm/alpm.h    |    2 ++
 lib/libalpm/signing.c |   22 ++++++++++++++++++++--
 src/pacman/package.c  |   11 +++++++++++
 src/pacman/util.c     |   48 +++++++++++++++++++++++++++++++++++++++++++++++-
 src/pacman/util.h     |    1 +
 5 files changed, 81 insertions(+), 3 deletions(-)

diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
index db8e8ef..e3304df 100644
--- a/lib/libalpm/alpm.h
+++ b/lib/libalpm/alpm.h
@@ -742,6 +742,8 @@ int alpm_pkg_check_pgp_signature(alpm_pkg_t *pkg, alpm_sigresult_t *result);
 
 int alpm_db_check_pgp_signature(alpm_db_t *db, alpm_sigresult_t *result);
 
+int alpm_sigresult_cleanup(alpm_sigresult_t *result);
+
 /*
  * Groups
  */
diff --git a/lib/libalpm/signing.c b/lib/libalpm/signing.c
index 9c5d8cb..7b048f6 100644
--- a/lib/libalpm/signing.c
+++ b/lib/libalpm/signing.c
@@ -309,6 +309,7 @@ int _alpm_gpgme_checksig(alpm_handle_t *handle, const char *path,
 			gpgsig = gpgsig->next, sigcount++) {
 		alpm_list_t *summary_list, *summary;
 		alpm_sigstatus_t status;
+		gpgme_key_t key;
 
 		_alpm_log(handle, ALPM_LOG_DEBUG, "fingerprint: %s\n", gpgsig->fpr);
 		summary_list = list_sigsum(gpgsig->summary);
@@ -448,8 +449,7 @@ int _alpm_check_pgp_helper(alpm_handle_t *handle, const char *path,
 		}
 	}
 
-	free(result.status);
-	free(result.uid);
+	alpm_sigresult_cleanup(&result);
 	return ret;
 }
 
@@ -484,4 +484,22 @@ int SYMEXPORT alpm_db_check_pgp_signature(alpm_db_t *db,
 	return _alpm_gpgme_checksig(db->handle, _alpm_db_path(db), NULL, result);
 }
 
+int SYMEXPORT alpm_sigresult_cleanup(alpm_sigresult_t *result)
+{
+	ASSERT(result != NULL, return -1);
+	/* Because it is likely result is on the stack, uid and status may have bogus
+	 * values in the struct. Only look at them if count is greater than 0. */
+	if(result->count > 0) {
+		free(result->status);
+		if(result->uid) {
+			int i;
+			for(i = 0; i < result->count; i++) {
+				free(result->uid[i]);
+			}
+			free(result->uid);
+		}
+	}
+	return 0;
+}
+
 /* vim: set ts=2 sw=2 noet: */
diff --git a/src/pacman/package.c b/src/pacman/package.c
index 5514f00..72b71dd 100644
--- a/src/pacman/package.c
+++ b/src/pacman/package.c
@@ -136,6 +136,17 @@ void dump_pkg_full(alpm_pkg_t *pkg, enum pkg_from from, int extra)
 	if(from == PKG_FROM_SYNCDB) {
 		string_display(_("MD5 Sum        :"), alpm_pkg_get_md5sum(pkg));
 	}
+	if(from == PKG_FROM_FILE) {
+		alpm_sigresult_t result;
+		int err = alpm_pkg_check_pgp_signature(pkg, &result);
+		if(err) {
+			string_display(_("Signatures     :"),
+					_("Error checking package signatures"));
+		} else {
+			signature_display(_("Signatures     :"), &result);
+		}
+		alpm_sigresult_cleanup(&result);
+	}
 	string_display(_("Description    :"), alpm_pkg_get_desc(pkg));
 
 	/* Print additional package info if info flag passed more than once */
diff --git a/src/pacman/util.c b/src/pacman/util.c
index 9ced7aa..28beaca 100644
--- a/src/pacman/util.c
+++ b/src/pacman/util.c
@@ -613,7 +613,6 @@ void list_display(const char *title, const alpm_list_t *list)
 
 void list_display_linebreak(const char *title, const alpm_list_t *list)
 {
-	const alpm_list_t *i;
 	int len = 0;
 
 	if(title) {
@@ -624,6 +623,7 @@ void list_display_linebreak(const char *title, const alpm_list_t *list)
 	if(!list) {
 		printf("%s\n", _("None"));
 	} else {
+		const alpm_list_t *i;
 		/* Print the first element */
 		indentprint((const char *) alpm_list_getdata(list), len);
 		printf("\n");
@@ -639,6 +639,52 @@ void list_display_linebreak(const char *title, const alpm_list_t *list)
 	}
 }
 
+void signature_display(const char *title, alpm_sigresult_t *result)
+{
+	int len = 0;
+
+	if(title) {
+		len = string_length(title) + 1;
+		printf("%s ", title);
+	}
+	if(result->count == 0) {
+		printf(_("None"));
+	} else {
+		int i;
+		for(i = 0; i < result->count; i++) {
+			char sigline[PATH_MAX];
+			const char *validity, *name;
+			/* Don't re-indent the first result */
+			if(i != 0) {
+				int j;
+				for(j = 1; j <= len; j++) {
+					printf(" ");
+				}
+			}
+			switch(result->status[i]) {
+				case ALPM_SIGSTATUS_VALID:
+					validity = _("Valid signature");
+					break;
+				case ALPM_SIGSTATUS_MARGINAL:
+					validity = _("Marginal signature");
+					break;
+				case ALPM_SIGSTATUS_UNKNOWN:
+					validity = _("Unknown signature");
+					break;
+				case ALPM_SIGSTATUS_BAD:
+					validity = _("Invalid signature");
+					break;
+				default:
+					validity = _("Signature error");
+			}
+			name = result->uid[i] ? result->uid[i] : _("<Key Unknown>");
+			snprintf(sigline, PATH_MAX, _("%s from \"%s\""), validity, name);
+			indentprint(sigline, len);
+			printf("\n");
+		}
+	}
+}
+
 /* creates a header row for use with table_display */
 static alpm_list_t *create_verbose_header(int install)
 {
diff --git a/src/pacman/util.h b/src/pacman/util.h
index 5d86dfd..a914d0c 100644
--- a/src/pacman/util.h
+++ b/src/pacman/util.h
@@ -56,6 +56,7 @@ double humanize_size(off_t bytes, const char target_unit, int long_labels, const
 int table_display(const char *title, const alpm_list_t *header, const alpm_list_t *rows);
 void list_display(const char *title, const alpm_list_t *list);
 void list_display_linebreak(const char *title, const alpm_list_t *list);
+void signature_display(const char *title, alpm_sigresult_t *result);
 void display_targets(const alpm_list_t *pkgs, int install);
 int str_cmp(const void *s1, const void *s2);
 void display_new_optdepends(alpm_pkg_t *oldpkg, alpm_pkg_t *newpkg);
-- 
1.7.6



More information about the pacman-dev mailing list