[pacman-dev] [PATCH 1/6] signing: let GPGME handle loading signatures from files

Dan McGee dan at archlinux.org
Fri Apr 22 17:40:06 EDT 2011


Rather than go through all the hassle of doing this ourselves, just let
GPGME handle the work by passing it a file handle.

Signed-off-by: Dan McGee <dan at archlinux.org>
---

I applied patches from two years ago that introduced this madness, so it is no
wonder I am going back and refactoring and simplifying the old stuff. I see
little disadvantage to not manually reading the signature files if we can have
the library handle that itself.

 lib/libalpm/be_package.c |    6 ---
 lib/libalpm/db.c         |   23 -----------
 lib/libalpm/db.h         |    3 -
 lib/libalpm/signing.c    |   94 +++++++++++++++++-----------------------------
 lib/libalpm/signing.h    |    1 -
 5 files changed, 35 insertions(+), 92 deletions(-)

diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c
index 8a6ed6c..6e65c7d 100644
--- a/lib/libalpm/be_package.c
+++ b/lib/libalpm/be_package.c
@@ -243,18 +243,12 @@ static pmpkg_t *pkg_load(const char *pkgfile, int full)
 
 	/* attempt to stat the package file, ensure it exists */
 	if(stat(pkgfile, &st) == 0) {
-		int sig_ret;
-
 		newpkg = _alpm_pkg_new();
 		if(newpkg == NULL) {
 			RET_ERR(PM_ERR_MEMORY, NULL);
 		}
 		newpkg->filename = strdup(pkgfile);
 		newpkg->size = st.st_size;
-
-		/* TODO: do something with ret value */
-		sig_ret = _alpm_load_signature(pkgfile, &(newpkg->pgpsig));
-		(void)sig_ret;
 	} else {
 		/* couldn't stat the pkgfile, return an error */
 		RET_ERR(PM_ERR_PKG_OPEN, NULL);
diff --git a/lib/libalpm/db.c b/lib/libalpm/db.c
index f5e7a25..3d593b3 100644
--- a/lib/libalpm/db.c
+++ b/lib/libalpm/db.c
@@ -314,27 +314,6 @@ pmdb_t *_alpm_db_new(const char *treename, int is_local)
 	return db;
 }
 
-const pmpgpsig_t *_alpm_db_pgpsig(pmdb_t *db)
-{
-	ALPM_LOG_FUNC;
-
-	/* Sanity checks */
-	ASSERT(db != NULL, return(NULL));
-
-	if(db->pgpsig.data == NULL) {
-		const char *dbfile;
-		int ret;
-
-		dbfile = _alpm_db_path(db);
-
-		/* TODO: do something with ret value */
-		ret = _alpm_load_signature(dbfile, &(db->pgpsig));
-		(void)ret;
-	}
-
-	return &(db->pgpsig);
-}
-
 void _alpm_db_free(pmdb_t *db)
 {
 	ALPM_LOG_FUNC;
@@ -343,8 +322,6 @@ void _alpm_db_free(pmdb_t *db)
 	_alpm_db_free_pkgcache(db);
 	/* cleanup server list */
 	FREELIST(db->servers);
-	/* only need to free data */
-	FREE(db->pgpsig.data);
 	FREE(db->_path);
 	FREE(db->treename);
 	FREE(db);
diff --git a/lib/libalpm/db.h b/lib/libalpm/db.h
index 204a0be..399e2d5 100644
--- a/lib/libalpm/db.h
+++ b/lib/libalpm/db.h
@@ -63,8 +63,6 @@ struct __pmdb_t {
 	pmpkghash_t *pkgcache;
 	alpm_list_t *grpcache;
 	alpm_list_t *servers;
-	/* do not access directly, use _alpm_db_pgpsig(db) for lazy access */
-	pmpgpsig_t pgpsig;
 	pgp_verify_t pgp_verify;
 
 	struct db_operations *ops;
@@ -81,7 +79,6 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles);
 pmdb_t *_alpm_db_register_local(void);
 pmdb_t *_alpm_db_register_sync(const char *treename);
 void _alpm_db_unregister(pmdb_t *db);
-const pmpgpsig_t *_alpm_db_pgpsig(pmdb_t *db);
 
 /* be_*.c, backend specific calls */
 int _alpm_local_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq);
diff --git a/lib/libalpm/signing.c b/lib/libalpm/signing.c
index 9d4fd07..28b7ad9 100644
--- a/lib/libalpm/signing.c
+++ b/lib/libalpm/signing.c
@@ -92,9 +92,10 @@ error:
 }
 
 /**
- * Check the PGP package signature for the given file.
+ * Check the PGP signature for the given file.
  * @param path the full path to a file
- * @param sig PGP signature data in raw form (already decoded)
+ * @param sig PGP signature data in raw form (already decoded); if NULL, expect
+ * a signature file next to 'path'
  * @return a int value : 0 (valid), 1 (invalid), -1 (an error occured)
  */
 int _alpm_gpgme_checksig(const char *path, const pmpgpsig_t *sig)
@@ -105,16 +106,28 @@ int _alpm_gpgme_checksig(const char *path, const pmpgpsig_t *sig)
 	gpgme_data_t filedata, sigdata;
 	gpgme_verify_result_t result;
 	gpgme_signature_t gpgsig;
+	char *sigpath = NULL;
 	FILE *file = NULL, *sigfile = NULL;
 
 	ALPM_LOG_FUNC;
 
-	if(!sig || !sig->data) {
-		 RET_ERR(PM_ERR_SIG_UNKNOWN, -1);
-	}
 	if(!path || access(path, R_OK) != 0) {
 		RET_ERR(PM_ERR_NOT_A_FILE, -1);
 	}
+
+	if(!sig) {
+		size_t len = strlen(path) + 5;
+		CALLOC(sigpath, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, -1));
+		snprintf(sigpath, len, "%s.sig", path);
+
+		if(!access(sigpath, R_OK) == 0) {
+			FREE(sigpath);
+			RET_ERR(PM_ERR_SIG_UNKNOWN, -1);
+		}
+	} else if(!sig->data) {
+		 RET_ERR(PM_ERR_SIG_UNKNOWN, -1);
+	}
+
 	if(gpgme_init()) {
 		/* pm_errno was set in gpgme_init() */
 		return -1;
@@ -140,7 +153,19 @@ int _alpm_gpgme_checksig(const char *path, const pmpgpsig_t *sig)
 	CHECK_ERR();
 
 	/* next create data object for the signature */
-	err = gpgme_data_new_from_mem(&sigdata, (char *)sig->data, sig->len, 0);
+	if(sig) {
+		/* memory-based, we loaded it from a sync DB */
+		err = gpgme_data_new_from_mem(&sigdata, (char *)sig->data, sig->len, 0);
+	} else {
+		/* file-based, it is on disk */
+		sigfile = fopen(sigpath, "rb");
+		if(sigfile == NULL) {
+			pm_errno = PM_ERR_NOT_A_FILE;
+			ret = -1;
+			goto error;
+		}
+		err = gpgme_data_new_from_stream(&sigdata, sigfile);
+	}
 	CHECK_ERR();
 
 	/* here's where the magic happens */
@@ -196,6 +221,7 @@ error:
 	if(file) {
 		fclose(file);
 	}
+	FREE(sigpath);
 	if(err != GPG_ERR_NO_ERROR) {
 		_alpm_log(PM_LOG_ERROR, _("GPGME error: %s\n"), gpgme_strerror(err));
 		RET_ERR(PM_ERR_GPGME, -1);
@@ -204,55 +230,6 @@ error:
 }
 
 /**
- * Load the signature from the given path into the provided struct.
- * @param sigfile the signature to attempt to load
- * @param pgpsig the struct to place the data in
- *
- * @return 0 on success, 1 on file not found, -1 on error
- */
-int _alpm_load_signature(const char *file, pmpgpsig_t *pgpsig) {
-	struct stat st;
-	char *sigfile;
-	int ret = -1;
-
-	/* look around for a PGP signature file; load if available */
-	MALLOC(sigfile, strlen(file) + 5, RET_ERR(PM_ERR_MEMORY, -1));
-	sprintf(sigfile, "%s.sig", file);
-
-	if(access(sigfile, R_OK) == 0 && stat(sigfile, &st) == 0) {
-		FILE *f;
-		size_t bytes_read;
-
-		if(st.st_size > 4096 || (f = fopen(sigfile, "rb")) == NULL) {
-			free(sigfile);
-			return ret;
-		}
-		CALLOC(pgpsig->data, st.st_size, sizeof(unsigned char),
-				RET_ERR(PM_ERR_MEMORY, -1));
-		bytes_read = fread(pgpsig->data, sizeof(char), st.st_size, f);
-		if(bytes_read == (size_t)st.st_size) {
-			pgpsig->len = bytes_read;
-			_alpm_log(PM_LOG_DEBUG, "loaded gpg signature file, location %s\n",
-					sigfile);
-			ret = 0;
-		} else {
-			_alpm_log(PM_LOG_WARNING, _("Failed reading PGP signature file %s"),
-					sigfile);
-			FREE(pgpsig->data);
-		}
-
-		fclose(f);
-	} else {
-		_alpm_log(PM_LOG_DEBUG, "signature file %s not found\n", sigfile);
-		/* not fatal...we return a different error code here */
-		ret = 1;
-	}
-
-	free(sigfile);
-	return ret;
-}
-
-/**
  * Determines the necessity of checking for a valid PGP signature
  * @param db the sync database to query
  *
@@ -271,7 +248,7 @@ pgp_verify_t _alpm_db_get_sigverify_level(pmdb_t *db)
 }
 
 /**
- * Check the PGP package signature for the given package file.
+ * Check the PGP signature for the given package file.
  * @param pkg the package to check
  * @return a int value : 0 (valid), 1 (invalid), -1 (an error occurred)
  */
@@ -285,7 +262,7 @@ int SYMEXPORT alpm_pkg_check_pgp_signature(pmpkg_t *pkg)
 }
 
 /**
- * Check the PGP package signature for the given database.
+ * Check the PGP signature for the given database.
  * @param db the database to check
  * @return a int value : 0 (valid), 1 (invalid), -1 (an error occurred)
  */
@@ -294,8 +271,7 @@ int SYMEXPORT alpm_db_check_pgp_signature(pmdb_t *db)
 	ALPM_LOG_FUNC;
 	ASSERT(db != NULL, return 0);
 
-	return _alpm_gpgme_checksig(_alpm_db_path(db),
-			_alpm_db_pgpsig(db));
+	return _alpm_gpgme_checksig(_alpm_db_path(db), NULL);
 }
 
 /* vim: set ts=2 sw=2 noet: */
diff --git a/lib/libalpm/signing.h b/lib/libalpm/signing.h
index a378fa5..5976cf2 100644
--- a/lib/libalpm/signing.h
+++ b/lib/libalpm/signing.h
@@ -32,7 +32,6 @@ struct __pmpgpsig_t {
 };
 
 int _alpm_gpgme_checksig(const char *path, const pmpgpsig_t *sig);
-int _alpm_load_signature(const char *sigfile, pmpgpsig_t *pgpsig);
 pgp_verify_t _alpm_db_get_sigverify_level(pmdb_t *db);
 
 #endif /* _ALPM_SIGNING_H */
-- 
1.7.4.4



More information about the pacman-dev mailing list