[pacman-dev] [PATCH 4/4] signing: move to new signing verification and return scheme

Dan McGee dan at archlinux.org
Mon Jun 27 17:39:39 EDT 2011


This gives us more granularity than the former Never/Optional/Always
trifecta. The frontend still uses these values temporarily but that will
be changed in a future patch.

* Use 'siglevel' consistenly in method names, 'level' as variable name
* The level becomes an enum bitmask value for flexibility
* Signature check methods now return a status code rather than a simple
  integer success/failure value. This allows callers to determine
  whether things such as an unknown signature are valid.
* Specific signature error codes mostly disappear in favor of the above
  returned status code; pm_errno is now set only to PKG_INVALID_SIG or
  DB_INVALID_SIG as appropriate.

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

This is still a slight WIP, but mostly finished. Thoughts? I think this gives
us the flexibility we need to verify everything we need to, as well as allow
frontend validation and useful display of what we found via -Qip with the
return code business.

Outstanding issues:
* Need to correctly handle the UNKNOWN_OK and MARGINAL_OK flags.
* Need to handle multiple sigs. Right now the last one wins; should the return
  type be an alpm_list_t instead? Or better yet, an array of enum values with
  the size returned in a passed parameter, which would be much more light
  weight than the whole linked list.

 lib/libalpm/alpm.h       |   57 +++++++++++++++++++++++++++++-----------------
 lib/libalpm/be_package.c |   25 +++++++++++++-------
 lib/libalpm/be_sync.c    |   35 ++++++++++++++++------------
 lib/libalpm/db.c         |   14 +++++-----
 lib/libalpm/db.h         |    4 +-
 lib/libalpm/dload.c      |    5 +--
 lib/libalpm/error.c      |   13 ++++------
 lib/libalpm/handle.c     |   14 +++++-----
 lib/libalpm/handle.h     |    2 +-
 lib/libalpm/package.h    |    2 +-
 lib/libalpm/signing.c    |   39 +++++++++++++-----------------
 lib/libalpm/signing.h    |    2 +-
 lib/libalpm/sync.c       |    6 ++--
 src/pacman/conf.c        |   38 ++++++++++++++++--------------
 src/pacman/conf.h        |    2 +-
 src/pacman/query.c       |    2 +-
 src/pacman/sync.c        |    2 +-
 src/pacman/upgrade.c     |    4 +-
 src/util/cleanupdelta.c  |    3 +-
 src/util/pactree.c       |    3 +-
 src/util/testdb.c        |    3 +-
 src/util/testpkg.c       |    3 +-
 22 files changed, 151 insertions(+), 127 deletions(-)

diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
index ec99541..3fd6a13 100644
--- a/lib/libalpm/alpm.h
+++ b/lib/libalpm/alpm.h
@@ -87,14 +87,31 @@ typedef enum _pmfileconflicttype_t {
 } pmfileconflicttype_t;
 
 /**
- * GPG signature verification options
+ * PGP signature verification options
  */
-typedef enum _pgp_verify_t {
-	PM_PGP_VERIFY_UNKNOWN,
-	PM_PGP_VERIFY_NEVER,
-	PM_PGP_VERIFY_OPTIONAL,
-	PM_PGP_VERIFY_ALWAYS
-} pgp_verify_t;
+typedef enum _pmsiglevel_t {
+	PM_SIG_PACKAGE = (1 << 0),
+	PM_SIG_PACKAGE_OPTIONAL = (1 << 1),
+	PM_SIG_DATABASE = (1 << 2),
+	PM_SIG_DATABASE_OPTIONAL = (1 << 3),
+	PM_SIG_UNKNOWN_OK = (1 << 4),
+	PM_SIG_MARGINAL_OK = (1 << 5),
+
+	PM_SIG_USE_DEFAULT = (1 << 31),
+} pmsiglevel_t;
+
+/**
+ * PGP signature verification return codes
+ */
+typedef enum _pmsigstatus_t {
+	PM_SIGSTATUS_VALID = 0,
+	PM_SIGSTATUS_FILE_MISSING,
+	PM_SIGSTATUS_SIG_MISSING,
+	PM_SIGSTATUS_INVALID,
+	PM_SIGSTATUS_UNKNOWN,
+	PM_SIGSTATUS_BAD,
+	PM_SIGSTATUS_ERROR
+} pmsigstatus_t;
 
 /*
  * Structures
@@ -328,8 +345,8 @@ int alpm_option_set_usedelta(pmhandle_t *handle, int usedelta);
 int alpm_option_get_checkspace(pmhandle_t *handle);
 int alpm_option_set_checkspace(pmhandle_t *handle, int checkspace);
 
-pgp_verify_t alpm_option_get_default_sigverify(pmhandle_t *handle);
-int alpm_option_set_default_sigverify(pmhandle_t *handle, pgp_verify_t level);
+pmsiglevel_t alpm_option_get_default_siglevel(pmhandle_t *handle);
+int alpm_option_set_default_siglevel(pmhandle_t *handle, pmsiglevel_t level);
 
 /** @} */
 
@@ -357,12 +374,12 @@ alpm_list_t *alpm_option_get_syncdbs(pmhandle_t *handle);
 /** Register a sync database of packages.
  * @param handle the context handle
  * @param treename the name of the sync repository
- * @param check_sig what level of signature checking to perform on the
+ * @param level what level of signature checking to perform on the
  * database; note that this must be a '.sig' file type verification
  * @return a pmdb_t* on success (the value), NULL on error
  */
 pmdb_t *alpm_db_register_sync(pmhandle_t *handle, const char *treename,
-		pgp_verify_t check_sig);
+		pmsiglevel_t level);
 
 /** Unregister a package database.
  * @param db pointer to the package database to unregister
@@ -384,11 +401,11 @@ const char *alpm_db_get_name(const pmdb_t *db);
 
 /** Get the signature verification level for a database.
  * Will return the default verification level if this database is set up
- * with PM_PGP_VERIFY_UNKNOWN.
+ * with PM_SIG_USE_DEFAULT.
  * @param db pointer to the package database
  * @return the signature verification level
  */
-pgp_verify_t alpm_db_get_sigverify_level(pmdb_t *db);
+pmsiglevel_t alpm_db_get_siglevel(pmdb_t *db);
 
 /** Check the validity of a database.
  * This is most useful for sync databases and verifying signature status.
@@ -466,13 +483,13 @@ int alpm_db_set_pkgreason(pmdb_t *db, const char *name, pmpkgreason_t reason);
  * @param filename location of the package tarball
  * @param full whether to stop the load after metadata is read or continue
  * through the full archive
- * @param check_sig what level of package signature checking to perform on the
+ * @param level what level of package signature checking to perform on the
  * package; note that this must be a '.sig' file type verification
  * @param pkg address of the package pointer
  * @return 0 on success, -1 on error (pm_errno is set accordingly)
  */
 int alpm_pkg_load(pmhandle_t *handle, const char *filename, int full,
-		pgp_verify_t check_sig, pmpkg_t **pkg);
+		pmsiglevel_t level, pmpkg_t **pkg);
 
 /** Free a package.
  * @param pkg package pointer to free
@@ -708,9 +725,9 @@ alpm_list_t *alpm_pkg_unused_deltas(pmpkg_t *pkg);
  * Signatures
  */
 
-int alpm_pkg_check_pgp_signature(pmpkg_t *pkg);
+pmsigstatus_t alpm_pkg_check_pgp_signature(pmpkg_t *pkg);
 
-int alpm_db_check_pgp_signature(pmdb_t *db);
+pmsigstatus_t alpm_db_check_pgp_signature(pmdb_t *db);
 
 /*
  * Groups
@@ -1018,6 +1035,7 @@ enum _pmerrno_t {
 	PM_ERR_DB_NOT_NULL,
 	PM_ERR_DB_NOT_FOUND,
 	PM_ERR_DB_INVALID,
+	PM_ERR_DB_INVALID_SIG,
 	PM_ERR_DB_VERSION,
 	PM_ERR_DB_WRITE,
 	PM_ERR_DB_REMOVE,
@@ -1037,15 +1055,12 @@ enum _pmerrno_t {
 	PM_ERR_PKG_NOT_FOUND,
 	PM_ERR_PKG_IGNORED,
 	PM_ERR_PKG_INVALID,
+	PM_ERR_PKG_INVALID_SIG,
 	PM_ERR_PKG_OPEN,
 	PM_ERR_PKG_CANT_REMOVE,
 	PM_ERR_PKG_INVALID_NAME,
 	PM_ERR_PKG_INVALID_ARCH,
 	PM_ERR_PKG_REPO_NOT_FOUND,
-	/* Signatures */
-	PM_ERR_SIG_MISSINGDIR,
-	PM_ERR_SIG_INVALID,
-	PM_ERR_SIG_UNKNOWN,
 	/* Deltas */
 	PM_ERR_DLT_INVALID,
 	PM_ERR_DLT_PATCHFAILED,
diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c
index 748f27a..2a05c8f 100644
--- a/lib/libalpm/be_package.c
+++ b/lib/libalpm/be_package.c
@@ -233,7 +233,7 @@ static int parse_descfile(pmhandle_t *handle, struct archive *a, pmpkg_t *newpkg
  */
 pmpkg_t *_alpm_pkg_load_internal(pmhandle_t *handle, const char *pkgfile,
 		int full, const char *md5sum, const char *base64_sig,
-		pgp_verify_t check_sig)
+		pmsiglevel_t level)
 {
 	int ret;
 	int config = 0;
@@ -271,13 +271,20 @@ pmpkg_t *_alpm_pkg_load_internal(pmhandle_t *handle, const char *pkgfile,
 	}
 
 	_alpm_log(handle, PM_LOG_DEBUG, "base64_sig: %s\n", base64_sig);
-	if(check_sig != PM_PGP_VERIFY_NEVER) {
+	if(level & PM_SIG_PACKAGE) {
+		enum _pmsigstatus_t status;
 		_alpm_log(handle, PM_LOG_DEBUG, "checking signature for %s\n", pkgfile);
-		ret = _alpm_gpgme_checksig(handle, pkgfile, base64_sig);
-		if((check_sig == PM_PGP_VERIFY_ALWAYS && ret != 0) ||
-				(check_sig == PM_PGP_VERIFY_OPTIONAL && ret == 1)) {
-			alpm_pkg_free(newpkg);
-			RET_ERR(handle, PM_ERR_SIG_INVALID, NULL);
+		status = _alpm_gpgme_checksig(handle, pkgfile, base64_sig);
+		switch(status) {
+			case PM_SIGSTATUS_VALID:
+				break;
+			case PM_SIGSTATUS_SIG_MISSING:
+				if(level & PM_SIG_PACKAGE_OPTIONAL) {
+					break;
+				}
+			default:
+				alpm_pkg_free(newpkg);
+				RET_ERR(handle, PM_ERR_PKG_INVALID_SIG, NULL);
 		}
 	}
 
@@ -388,12 +395,12 @@ error:
 }
 
 int SYMEXPORT alpm_pkg_load(pmhandle_t *handle, const char *filename, int full,
-		pgp_verify_t check_sig, pmpkg_t **pkg)
+		pmsiglevel_t level, pmpkg_t **pkg)
 {
 	CHECK_HANDLE(handle, return -1);
 	ASSERT(pkg != NULL, RET_ERR(handle, PM_ERR_WRONG_ARGS, -1));
 
-	*pkg = _alpm_pkg_load_internal(handle, filename, full, NULL, NULL, check_sig);
+	*pkg = _alpm_pkg_load_internal(handle, filename, full, NULL, NULL, level);
 	if(*pkg == NULL) {
 		/* pm_errno is set by pkg_load */
 		return -1;
diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c
index bcd8564..20eb108 100644
--- a/lib/libalpm/be_sync.c
+++ b/lib/libalpm/be_sync.c
@@ -69,7 +69,7 @@ static char *get_sync_dir(pmhandle_t *handle)
 
 static int sync_db_validate(pmdb_t *db)
 {
-	pgp_verify_t check_sig;
+	pmsiglevel_t level;
 
 	if(db->status & DB_STATUS_VALID) {
 		return 0;
@@ -77,10 +77,10 @@ static int sync_db_validate(pmdb_t *db)
 
 	/* this takes into account the default verification level if UNKNOWN
 	 * was assigned to this db */
-	check_sig = alpm_db_get_sigverify_level(db);
+	level = alpm_db_get_siglevel(db);
 
-	if(check_sig != PM_PGP_VERIFY_NEVER) {
-		int ret;
+	if(level & PM_SIG_DATABASE) {
+		enum _pmsigstatus_t status;
 		const char *dbpath = _alpm_db_path(db);
 		if(!dbpath) {
 			/* pm_errno set in _alpm_db_path() */
@@ -95,10 +95,16 @@ static int sync_db_validate(pmdb_t *db)
 
 		_alpm_log(db->handle, PM_LOG_DEBUG, "checking signature for %s\n",
 				db->treename);
-		ret = _alpm_gpgme_checksig(db->handle, dbpath, NULL);
-		if((check_sig == PM_PGP_VERIFY_ALWAYS && ret != 0) ||
-				(check_sig == PM_PGP_VERIFY_OPTIONAL && ret == 1)) {
-			RET_ERR(db->handle, PM_ERR_SIG_INVALID, -1);
+		status = _alpm_gpgme_checksig(db->handle, dbpath, NULL);
+		switch(status) {
+			case PM_SIGSTATUS_VALID:
+				break;
+			case PM_SIGSTATUS_SIG_MISSING:
+				if(level & PM_SIG_DATABASE_OPTIONAL) {
+					break;
+				}
+			default:
+				RET_ERR(db->handle, PM_ERR_DB_INVALID_SIG, 1);
 		}
 	}
 
@@ -149,7 +155,7 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db)
 	int ret = -1;
 	mode_t oldmask;
 	pmhandle_t *handle;
-	pgp_verify_t check_sig;
+	pmsiglevel_t level;
 
 	/* Sanity checks */
 	ASSERT(db != NULL, return -1);
@@ -166,7 +172,7 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db)
 	/* make sure we have a sane umask */
 	oldmask = umask(0022);
 
-	check_sig = alpm_db_get_sigverify_level(db);
+	level = alpm_db_get_siglevel(db);
 
 	/* attempt to grab a lock */
 	if(_alpm_handle_lock(handle)) {
@@ -186,8 +192,7 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db)
 
 		ret = _alpm_download(handle, fileurl, syncpath, force, 0, 0);
 
-		if(ret == 0 && (check_sig == PM_PGP_VERIFY_ALWAYS ||
-					check_sig == PM_PGP_VERIFY_OPTIONAL)) {
+		if(ret == 0 && (level & PM_SIG_DATABASE)) {
 			/* an existing sig file is no good at this point */
 			char *sigpath = _alpm_db_sig_path(db);
 			if(!sigpath) {
@@ -197,7 +202,7 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db)
 			unlink(sigpath);
 			free(sigpath);
 
-			int errors_ok = (check_sig == PM_PGP_VERIFY_OPTIONAL);
+			int errors_ok = (level & PM_SIG_DATABASE_OPTIONAL);
 			/* if we downloaded a DB, we want the .sig from the same server */
 			snprintf(fileurl, len, "%s/%s.db.sig", server, db->treename);
 
@@ -586,7 +591,7 @@ struct db_operations sync_db_ops = {
 };
 
 pmdb_t *_alpm_db_register_sync(pmhandle_t *handle, const char *treename,
-		pgp_verify_t level)
+		pmsiglevel_t level)
 {
 	pmdb_t *db;
 
@@ -598,7 +603,7 @@ pmdb_t *_alpm_db_register_sync(pmhandle_t *handle, const char *treename,
 	}
 	db->ops = &sync_db_ops;
 	db->handle = handle;
-	db->pgp_verify = level;
+	db->siglevel = level;
 
 	if(sync_db_validate(db)) {
 		_alpm_db_free(db);
diff --git a/lib/libalpm/db.c b/lib/libalpm/db.c
index ac02740..9435135 100644
--- a/lib/libalpm/db.c
+++ b/lib/libalpm/db.c
@@ -46,7 +46,7 @@
 
 /** Register a sync database of packages. */
 pmdb_t SYMEXPORT *alpm_db_register_sync(pmhandle_t *handle, const char *treename,
-		pgp_verify_t check_sig)
+		pmsiglevel_t level)
 {
 	/* Sanity checks */
 	CHECK_HANDLE(handle, return NULL);
@@ -55,7 +55,7 @@ pmdb_t SYMEXPORT *alpm_db_register_sync(pmhandle_t *handle, const char *treename
 	/* Do not register a database if a transaction is on-going */
 	ASSERT(handle->trans == NULL, RET_ERR(handle, PM_ERR_TRANS_NOT_NULL, NULL));
 
-	return _alpm_db_register_sync(handle, treename, check_sig);
+	return _alpm_db_register_sync(handle, treename, level);
 }
 
 /* Helper function for alpm_db_unregister{_all} */
@@ -220,13 +220,13 @@ const char SYMEXPORT *alpm_db_get_name(const pmdb_t *db)
 }
 
 /** Get the signature verification level for a database. */
-pgp_verify_t SYMEXPORT alpm_db_get_sigverify_level(pmdb_t *db)
+pmsiglevel_t SYMEXPORT alpm_db_get_siglevel(pmdb_t *db)
 {
 	ASSERT(db != NULL, return -1);
-	if(db->pgp_verify == PM_PGP_VERIFY_UNKNOWN) {
-		return alpm_option_get_default_sigverify(db->handle);
+	if(db->siglevel & PM_SIG_USE_DEFAULT) {
+		return alpm_option_get_default_siglevel(db->handle);
 	} else {
-		return db->pgp_verify;
+		return db->siglevel;
 	}
 }
 
@@ -323,7 +323,7 @@ pmdb_t *_alpm_db_new(const char *treename, int is_local)
 	CALLOC(db, 1, sizeof(pmdb_t), return NULL);
 	STRDUP(db->treename, treename, return NULL);
 	db->is_local = is_local;
-	db->pgp_verify = PM_PGP_VERIFY_UNKNOWN;
+	db->siglevel = 0;
 
 	return db;
 }
diff --git a/lib/libalpm/db.h b/lib/libalpm/db.h
index 5da28bf..60d8c94 100644
--- a/lib/libalpm/db.h
+++ b/lib/libalpm/db.h
@@ -69,7 +69,7 @@ struct __pmdb_t {
 	pmpkghash_t *pkgcache;
 	alpm_list_t *grpcache;
 	alpm_list_t *servers;
-	pgp_verify_t pgp_verify;
+	pmsiglevel_t siglevel;
 
 	struct db_operations *ops;
 };
@@ -84,7 +84,7 @@ int _alpm_db_cmp(const void *d1, const void *d2);
 alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles);
 pmdb_t *_alpm_db_register_local(pmhandle_t *handle);
 pmdb_t *_alpm_db_register_sync(pmhandle_t *handle, const char *treename,
-		pgp_verify_t level);
+		pmsiglevel_t level);
 void _alpm_db_unregister(pmdb_t *db);
 
 /* be_*.c, backend specific calls */
diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c
index c7903ff..b1d9b04 100644
--- a/lib/libalpm/dload.c
+++ b/lib/libalpm/dload.c
@@ -363,11 +363,10 @@ char SYMEXPORT *alpm_fetch_pkgurl(pmhandle_t *handle, const char *url)
 	_alpm_log(handle, PM_LOG_DEBUG, "successfully downloaded %s\n", url);
 
 	/* attempt to download the signature */
-	if(ret == 0 && (handle->sigverify == PM_PGP_VERIFY_ALWAYS ||
-				handle->sigverify == PM_PGP_VERIFY_OPTIONAL)) {
+	if(ret == 0 && (handle->siglevel & PM_SIG_PACKAGE)) {
 		char *sig_url;
 		size_t len;
-		int errors_ok = (handle->sigverify == PM_PGP_VERIFY_OPTIONAL);
+		int errors_ok = (handle->siglevel & PM_SIG_PACKAGE_OPTIONAL);
 
 		len = strlen(url) + 5;
 		CALLOC(sig_url, len, sizeof(char), RET_ERR(handle, PM_ERR_MEMORY, NULL));
diff --git a/lib/libalpm/error.c b/lib/libalpm/error.c
index 1e4e705..78dce5c 100644
--- a/lib/libalpm/error.c
+++ b/lib/libalpm/error.c
@@ -72,6 +72,8 @@ const char SYMEXPORT *alpm_strerror(enum _pmerrno_t err)
 			return _("could not find database");
 		case PM_ERR_DB_INVALID:
 			return _("invalid or corrupted database");
+		case PM_ERR_DB_INVALID_SIG:
+			return _("invalid or corrupted database (PGP)");
 		case PM_ERR_DB_VERSION:
 			return _("database is incorrect version");
 		case PM_ERR_DB_WRITE:
@@ -106,7 +108,9 @@ const char SYMEXPORT *alpm_strerror(enum _pmerrno_t err)
 		case PM_ERR_PKG_IGNORED:
 			return _("operation cancelled due to ignorepkg");
 		case PM_ERR_PKG_INVALID:
-			return _("invalid or corrupted package");
+			return _("invalid or corrupted package (checksum)");
+		case PM_ERR_PKG_INVALID_SIG:
+			return _("invalid or corrupted package (PGP)");
 		case PM_ERR_PKG_OPEN:
 			return _("cannot open package file");
 		case PM_ERR_PKG_CANT_REMOVE:
@@ -117,13 +121,6 @@ const char SYMEXPORT *alpm_strerror(enum _pmerrno_t err)
 			return _("package architecture is not valid");
 		case PM_ERR_PKG_REPO_NOT_FOUND:
 			return _("could not find repository for target");
-		/* Signatures */
-		case PM_ERR_SIG_MISSINGDIR:
-			return _("signature directory not configured correctly");
-		case PM_ERR_SIG_INVALID:
-			return _("invalid PGP signature");
-		case PM_ERR_SIG_UNKNOWN:
-			return _("unknown PGP signature");
 		/* Deltas */
 		case PM_ERR_DLT_INVALID:
 			return _("invalid or corrupted delta");
diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c
index acd3540..b7eae1e 100644
--- a/lib/libalpm/handle.c
+++ b/lib/libalpm/handle.c
@@ -45,7 +45,8 @@ pmhandle_t *_alpm_handle_new()
 
 	CALLOC(handle, 1, sizeof(pmhandle_t), return NULL);
 
-	handle->sigverify = PM_PGP_VERIFY_OPTIONAL;
+	handle->siglevel = PM_SIG_PACKAGE | PM_SIG_PACKAGE_OPTIONAL |
+		PM_SIG_DATABASE | PM_SIG_DATABASE_OPTIONAL;
 
 	return handle;
 }
@@ -574,18 +575,17 @@ int SYMEXPORT alpm_option_set_checkspace(pmhandle_t *handle, int checkspace)
 	return 0;
 }
 
-int SYMEXPORT alpm_option_set_default_sigverify(pmhandle_t *handle, pgp_verify_t level)
+int SYMEXPORT alpm_option_set_default_siglevel(pmhandle_t *handle, pmsiglevel_t level)
 {
 	CHECK_HANDLE(handle, return -1);
-	ASSERT(level != PM_PGP_VERIFY_UNKNOWN, RET_ERR(handle, PM_ERR_WRONG_ARGS, -1));
-	handle->sigverify = level;
+	handle->siglevel = level;
 	return 0;
 }
 
-pgp_verify_t SYMEXPORT alpm_option_get_default_sigverify(pmhandle_t *handle)
+pmsiglevel_t SYMEXPORT alpm_option_get_default_siglevel(pmhandle_t *handle)
 {
-	CHECK_HANDLE(handle, return PM_PGP_VERIFY_UNKNOWN);
-	return handle->sigverify;
+	CHECK_HANDLE(handle, return -1);
+	return handle->siglevel;
 }
 
 /* vim: set ts=2 sw=2 noet: */
diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h
index 4ffd00c..4196e82 100644
--- a/lib/libalpm/handle.h
+++ b/lib/libalpm/handle.h
@@ -69,7 +69,7 @@ struct __pmhandle_t {
 	char *arch;              /* Architecture of packages we should allow */
 	int usedelta;            /* Download deltas if possible */
 	int checkspace;          /* Check disk space before installing */
-	pgp_verify_t sigverify;  /* Default signature verification level */
+	pmsiglevel_t siglevel;   /* Default signature verification level */
 
 	/* error code */
 	enum _pmerrno_t pm_errno;
diff --git a/lib/libalpm/package.h b/lib/libalpm/package.h
index d18020d..9739f96 100644
--- a/lib/libalpm/package.h
+++ b/lib/libalpm/package.h
@@ -145,7 +145,7 @@ void _alpm_pkg_free_trans(pmpkg_t *pkg);
 
 pmpkg_t *_alpm_pkg_load_internal(pmhandle_t *handle, const char *pkgfile,
 		int full, const char *md5sum, const char *base64_sig,
-		pgp_verify_t check_sig);
+		pmsiglevel_t level);
 
 int _alpm_pkg_cmp(const void *p1, const void *p2);
 int _alpm_pkg_compare_versions(pmpkg_t *local_pkg, pmpkg_t *pkg);
diff --git a/lib/libalpm/signing.c b/lib/libalpm/signing.c
index a19c1cb..f505995 100644
--- a/lib/libalpm/signing.c
+++ b/lib/libalpm/signing.c
@@ -117,9 +117,6 @@ static int init_gpgme(pmhandle_t *handle)
 	}
 
 	sigdir = alpm_option_get_gpgdir(handle);
-	if(!sigdir) {
-		RET_ERR(handle, PM_ERR_SIG_MISSINGDIR, 1);
-	}
 
 	/* calling gpgme_check_version() returns the current version and runs
 	 * some internal library setup code */
@@ -203,9 +200,9 @@ error:
  * @param handle the context handle
  * @param path the full path to a file
  * @param base64_sig optional PGP signature data in base64 encoding
- * @return a int value : 0 (valid), 1 (invalid), -1 (an error occurred)
+ * @return a value indicating signature check status
  */
-int _alpm_gpgme_checksig(pmhandle_t *handle, const char *path,
+pmsigstatus_t _alpm_gpgme_checksig(pmhandle_t *handle, const char *path,
 		const char *base64_sig)
 {
 	int ret = 0;
@@ -219,23 +216,24 @@ int _alpm_gpgme_checksig(pmhandle_t *handle, const char *path,
 	FILE *file = NULL, *sigfile = NULL;
 
 	if(!path || access(path, R_OK) != 0) {
-		RET_ERR(handle, PM_ERR_NOT_A_FILE, -1);
+		return PM_SIGSTATUS_FILE_MISSING;
 	}
 
 	if(!base64_sig) {
 		size_t len = strlen(path) + 5;
-		CALLOC(sigpath, len, sizeof(char), RET_ERR(handle, PM_ERR_MEMORY, -1));
+		CALLOC(sigpath, len, sizeof(char),
+				RET_ERR(handle, PM_ERR_MEMORY, PM_SIGSTATUS_ERROR));
 		snprintf(sigpath, len, "%s.sig", path);
 
 		if(!access(sigpath, R_OK) == 0) {
 			FREE(sigpath);
-			RET_ERR(handle, PM_ERR_SIG_UNKNOWN, -1);
+			return PM_SIGSTATUS_SIG_MISSING;
 		}
 	}
 
 	if(init_gpgme(handle)) {
 		/* pm_errno was set in gpgme_init() */
-		return -1;
+		return PM_SIGSTATUS_ERROR;
 	}
 
 	_alpm_log(handle, PM_LOG_DEBUG, "checking signature for %s\n", path);
@@ -250,8 +248,7 @@ int _alpm_gpgme_checksig(pmhandle_t *handle, const char *path,
 	/* create our necessary data objects to verify the signature */
 	file = fopen(path, "rb");
 	if(file == NULL) {
-		handle->pm_errno = PM_ERR_NOT_A_FILE;
-		ret = -1;
+		ret = PM_SIGSTATUS_FILE_MISSING;
 		goto error;
 	}
 	err = gpgme_data_new_from_stream(&filedata, file);
@@ -264,7 +261,7 @@ int _alpm_gpgme_checksig(pmhandle_t *handle, const char *path,
 		int decode_ret = decode_signature(base64_sig,
 				&decoded_sigdata, &data_len);
 		if(decode_ret) {
-			ret = -1;
+			ret = PM_SIGSTATUS_INVALID;
 			goto error;
 		}
 		err = gpgme_data_new_from_mem(&sigdata,
@@ -273,8 +270,7 @@ int _alpm_gpgme_checksig(pmhandle_t *handle, const char *path,
 		/* file-based, it is on disk */
 		sigfile = fopen(sigpath, "rb");
 		if(sigfile == NULL) {
-			handle->pm_errno = PM_ERR_NOT_A_FILE;
-			ret = -1;
+			ret = PM_SIGSTATUS_SIG_MISSING;
 			goto error;
 		}
 		err = gpgme_data_new_from_stream(&sigdata, sigfile);
@@ -311,23 +307,22 @@ int _alpm_gpgme_checksig(pmhandle_t *handle, const char *path,
 		if(gpgsig->summary & GPGME_SIGSUM_VALID) {
 			/* definite good signature */
 			_alpm_log(handle, PM_LOG_DEBUG, "result: valid signature\n");
+			ret = PM_SIGSTATUS_VALID;
 		} else if(gpgsig->summary & GPGME_SIGSUM_GREEN) {
 			/* good signature */
 			_alpm_log(handle, PM_LOG_DEBUG, "result: green signature\n");
+			ret = PM_SIGSTATUS_VALID;
 		} else if(gpgsig->summary & GPGME_SIGSUM_RED) {
 			/* definite bad signature, error */
 			_alpm_log(handle, PM_LOG_DEBUG, "result: red signature\n");
-			handle->pm_errno = PM_ERR_SIG_INVALID;
-			ret = 1;
+			ret = PM_SIGSTATUS_BAD;
 		} else if(gpgsig->summary & GPGME_SIGSUM_KEY_MISSING) {
 			_alpm_log(handle, PM_LOG_DEBUG, "result: signature from unknown key\n");
-			handle->pm_errno = PM_ERR_SIG_UNKNOWN;
-			ret = 1;
+			ret = PM_SIGSTATUS_UNKNOWN;
 		} else {
 			/* we'll capture everything else here */
 			_alpm_log(handle, PM_LOG_DEBUG, "result: invalid signature\n");
-			handle->pm_errno = PM_ERR_SIG_INVALID;
-			ret = 1;
+			ret = PM_SIGSTATUS_BAD;
 		}
 
 		gpgsig = gpgsig->next;
@@ -364,7 +359,7 @@ int _alpm_gpgme_checksig(pmhandle_t *handle, const char *path,
  * @param pkg the package to check
  * @return a int value : 0 (valid), 1 (invalid), -1 (an error occurred)
  */
-int SYMEXPORT alpm_pkg_check_pgp_signature(pmpkg_t *pkg)
+pmsigstatus_t SYMEXPORT alpm_pkg_check_pgp_signature(pmpkg_t *pkg)
 {
 	ASSERT(pkg != NULL, return -1);
 	pkg->handle->pm_errno = 0;
@@ -378,7 +373,7 @@ int SYMEXPORT alpm_pkg_check_pgp_signature(pmpkg_t *pkg)
  * @param db the database to check
  * @return a int value : 0 (valid), 1 (invalid), -1 (an error occurred)
  */
-int SYMEXPORT alpm_db_check_pgp_signature(pmdb_t *db)
+pmsigstatus_t SYMEXPORT alpm_db_check_pgp_signature(pmdb_t *db)
 {
 	ASSERT(db != NULL, return -1);
 	db->handle->pm_errno = 0;
diff --git a/lib/libalpm/signing.h b/lib/libalpm/signing.h
index 14b2ad7..c8e6220 100644
--- a/lib/libalpm/signing.h
+++ b/lib/libalpm/signing.h
@@ -21,7 +21,7 @@
 
 #include "alpm.h"
 
-int _alpm_gpgme_checksig(pmhandle_t *handle, const char *path,
+enum _pmsigstatus_t _alpm_gpgme_checksig(pmhandle_t *handle, const char *path,
 		const char *base64_sig);
 
 #endif /* _ALPM_SIGNING_H */
diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c
index 0a38a77..9494b91 100644
--- a/lib/libalpm/sync.c
+++ b/lib/libalpm/sync.c
@@ -863,7 +863,7 @@ int _alpm_sync_commit(pmhandle_t *handle, alpm_list_t **data)
 		int percent = (current * 100) / numtargs;
 		const char *filename;
 		char *filepath;
-		pgp_verify_t check_sig;
+		pmsiglevel_t level;
 
 		PROGRESS(trans, PM_TRANS_PROGRESS_INTEGRITY_START, "", percent,
 				numtargs, current);
@@ -874,7 +874,7 @@ int _alpm_sync_commit(pmhandle_t *handle, alpm_list_t **data)
 		filename = alpm_pkg_get_filename(spkg);
 		filepath = _alpm_filecache_find(handle, filename);
 		pmdb_t *sdb = alpm_pkg_get_db(spkg);
-		check_sig = alpm_db_get_sigverify_level(sdb);
+		level = alpm_db_get_siglevel(sdb);
 
 		/* load the package file and replace pkgcache entry with it in the target list */
 		/* TODO: alpm_pkg_get_db() will not work on this target anymore */
@@ -882,7 +882,7 @@ int _alpm_sync_commit(pmhandle_t *handle, alpm_list_t **data)
 				"replacing pkgcache entry with package file for target %s\n",
 				spkg->name);
 		pmpkg_t *pkgfile =_alpm_pkg_load_internal(handle, filepath, 1, spkg->md5sum,
-				spkg->base64_sig, check_sig);
+				spkg->base64_sig, level);
 		if(!pkgfile) {
 			errors++;
 			*data = alpm_list_add(*data, strdup(filename));
diff --git a/src/pacman/conf.c b/src/pacman/conf.c
index 076e854..dcb45f6 100644
--- a/src/pacman/conf.c
+++ b/src/pacman/conf.c
@@ -52,7 +52,7 @@ config_t *config_new(void)
 	newconfig->op = PM_OP_MAIN;
 	newconfig->logmask = PM_LOG_ERROR | PM_LOG_WARNING;
 	newconfig->configfile = strdup(CONFFILE);
-	newconfig->sigverify = PM_PGP_VERIFY_UNKNOWN;
+	newconfig->siglevel = PM_SIG_USE_DEFAULT;
 
 	return newconfig;
 }
@@ -222,17 +222,18 @@ int config_set_arch(const char *arch)
 	return 0;
 }
 
-static pgp_verify_t option_verifysig(const char *value)
+static pmsiglevel_t option_verifysig(const char *value)
 {
-	pgp_verify_t level;
+	pmsiglevel_t level;
 	if(strcmp(value, "Always") == 0) {
-		level = PM_PGP_VERIFY_ALWAYS;
+		level = PM_SIG_PACKAGE | PM_SIG_DATABASE;
 	} else if(strcmp(value, "Optional") == 0) {
-		level = PM_PGP_VERIFY_OPTIONAL;
+		level = PM_SIG_PACKAGE | PM_SIG_PACKAGE_OPTIONAL |
+			PM_SIG_DATABASE | PM_SIG_DATABASE_OPTIONAL;
 	} else if(strcmp(value, "Never") == 0) {
-		level = PM_PGP_VERIFY_NEVER;
+		level = 0;
 	} else {
-		level = PM_PGP_VERIFY_UNKNOWN;
+		return -1;
 	}
 	pm_printf(PM_LOG_DEBUG, "config: VerifySig = %s (%d)\n", value, level);
 	return level;
@@ -359,9 +360,9 @@ static int _parse_options(const char *key, char *value,
 			}
 			FREELIST(methods);
 		} else if(strcmp(key, "VerifySig") == 0) {
-			pgp_verify_t level = option_verifysig(value);
-			if(level != PM_PGP_VERIFY_UNKNOWN) {
-				config->sigverify = level;
+			pmsiglevel_t level = option_verifysig(value);
+			if(level != -1) {
+				config->siglevel = level;
 			} else {
 				pm_printf(PM_LOG_ERROR,
 						_("config file %s, line %d: directive '%s' has invalid value '%s'\n"),
@@ -484,8 +485,8 @@ static int setup_libalpm(void)
 		alpm_option_set_cachedirs(handle, config->cachedirs);
 	}
 
-	if(config->sigverify != PM_PGP_VERIFY_UNKNOWN) {
-		alpm_option_set_default_sigverify(handle, config->sigverify);
+	if(config->siglevel != PM_SIG_USE_DEFAULT) {
+		alpm_option_set_default_siglevel(handle, config->siglevel);
 	}
 
 	if(config->xfercommand) {
@@ -518,7 +519,7 @@ struct section_t {
 	char *name;
 	int is_options;
 	/* db section option gathering */
-	pgp_verify_t sigverify;
+	pmsiglevel_t siglevel;
 	alpm_list_t *servers;
 };
 
@@ -545,7 +546,7 @@ static int finish_section(struct section_t *section, int parse_options)
 	}
 
 	/* if we are not looking at options sections only, register a db */
-	db = alpm_db_register_sync(config->handle, section->name, section->sigverify);
+	db = alpm_db_register_sync(config->handle, section->name, section->siglevel);
 	if(db == NULL) {
 		pm_printf(PM_LOG_ERROR, _("could not register '%s' database (%s)\n"),
 				section->name, alpm_strerror(alpm_errno(config->handle)));
@@ -568,7 +569,7 @@ static int finish_section(struct section_t *section, int parse_options)
 cleanup:
 	alpm_list_free(section->servers);
 	section->servers = NULL;
-	section->sigverify = 0;
+	section->siglevel = PM_SIG_USE_DEFAULT;
 	free(section->name);
 	section->name = NULL;
 	return ret;
@@ -726,9 +727,9 @@ static int _parseconfig(const char *file, struct section_t *section,
 				}
 				section->servers = alpm_list_add(section->servers, strdup(value));
 			} else if(strcmp(key, "VerifySig") == 0) {
-				pgp_verify_t level = option_verifysig(value);
-				if(level != PM_PGP_VERIFY_UNKNOWN) {
-					section->sigverify = level;
+				pmsiglevel_t level = option_verifysig(value);
+				if(level != -1) {
+					section->siglevel = level;
 				} else {
 					pm_printf(PM_LOG_ERROR,
 							_("config file %s, line %d: directive '%s' has invalid value '%s'\n"),
@@ -763,6 +764,7 @@ int parseconfig(const char *file)
 	int ret;
 	struct section_t section;
 	memset(&section, 0, sizeof(struct section_t));
+	section.siglevel = PM_SIG_USE_DEFAULT;
 	/* the config parse is a two-pass affair. We first parse the entire thing for
 	 * the [options] section so we can get all default and path options set.
 	 * Next, we go back and parse everything but [options]. */
diff --git a/src/pacman/conf.h b/src/pacman/conf.h
index 4c44bfd..5e1a5b1 100644
--- a/src/pacman/conf.h
+++ b/src/pacman/conf.h
@@ -71,7 +71,7 @@ typedef struct __config_t {
 	unsigned short noask;
 	unsigned int ask;
 	pmtransflag_t flags;
-	pgp_verify_t sigverify;
+	pmsiglevel_t siglevel;
 
 	/* conf file options */
 	/* I Love Candy! */
diff --git a/src/pacman/query.c b/src/pacman/query.c
index 62472cb..566787a 100644
--- a/src/pacman/query.c
+++ b/src/pacman/query.c
@@ -549,7 +549,7 @@ int pacman_query(alpm_list_t *targets)
 		char *strname = alpm_list_getdata(i);
 
 		if(config->op_q_isfile) {
-			alpm_pkg_load(config->handle, strname, 1, PM_PGP_VERIFY_OPTIONAL, &pkg);
+			alpm_pkg_load(config->handle, strname, 1, 0, &pkg);
 		} else {
 			pkg = alpm_db_get_pkg(db_local, strname);
 		}
diff --git a/src/pacman/sync.c b/src/pacman/sync.c
index fa30b8d..218a770 100644
--- a/src/pacman/sync.c
+++ b/src/pacman/sync.c
@@ -220,7 +220,7 @@ static int sync_cleancache(int level)
 			/* attempt to load the package, prompt removal on failures as we may have
 			 * files here that aren't valid packages. we also don't need a full
 			 * load of the package, just the metadata. */
-			if(alpm_pkg_load(config->handle, path, 0, PM_PGP_VERIFY_NEVER, &localpkg) != 0
+			if(alpm_pkg_load(config->handle, path, 0, 0, &localpkg) != 0
 					|| localpkg == NULL) {
 				if(yesno(_("File %s does not seem to be a valid package, remove it?"),
 							path)) {
diff --git a/src/pacman/upgrade.c b/src/pacman/upgrade.c
index c1f72f6..4a64dd8 100644
--- a/src/pacman/upgrade.c
+++ b/src/pacman/upgrade.c
@@ -42,7 +42,7 @@
 int pacman_upgrade(alpm_list_t *targets)
 {
 	alpm_list_t *i, *data = NULL;
-	pgp_verify_t check_sig = alpm_option_get_default_sigverify(config->handle);
+	pmsiglevel_t level = alpm_option_get_default_siglevel(config->handle);
 	int retval = 0;
 
 	if(targets == NULL) {
@@ -76,7 +76,7 @@ int pacman_upgrade(alpm_list_t *targets)
 		char *targ = alpm_list_getdata(i);
 		pmpkg_t *pkg;
 
-		if(alpm_pkg_load(config->handle, targ, 1, check_sig, &pkg) != 0) {
+		if(alpm_pkg_load(config->handle, targ, 1, level, &pkg) != 0) {
 			pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n",
 					targ, alpm_strerror(alpm_errno(config->handle)));
 			trans_release();
diff --git a/src/util/cleanupdelta.c b/src/util/cleanupdelta.c
index 5ee59db..3809525 100644
--- a/src/util/cleanupdelta.c
+++ b/src/util/cleanupdelta.c
@@ -71,11 +71,12 @@ static void checkdbs(const char *dbpath, alpm_list_t *dbnames) {
 	char syncdbpath[PATH_MAX];
 	pmdb_t *db = NULL;
 	alpm_list_t *i;
+	const pmsiglevel_t level = PM_SIG_DATABASE | PM_SIG_DATABASE_OPTIONAL;
 
 	for(i = dbnames; i; i = alpm_list_next(i)) {
 		char *dbname = alpm_list_getdata(i);
 		snprintf(syncdbpath, PATH_MAX, "%s/sync/%s", dbpath, dbname);
-		db = alpm_db_register_sync(handle, dbname, PM_PGP_VERIFY_OPTIONAL);
+		db = alpm_db_register_sync(handle, dbname, level);
 		if(db == NULL) {
 			fprintf(stderr, "error: could not register sync database (%s)\n",
 					alpm_strerror(alpm_errno(handle)));
diff --git a/src/util/pactree.c b/src/util/pactree.c
index 5beaa5a..f44deb1 100644
--- a/src/util/pactree.c
+++ b/src/util/pactree.c
@@ -124,6 +124,7 @@ static int register_syncs(void) {
 	FILE *fp;
 	char *ptr, *section = NULL;
 	char line[LINE_MAX];
+	const pmsiglevel_t level = PM_SIG_DATABASE | PM_SIG_DATABASE_OPTIONAL;
 
 	fp = fopen(CONFFILE, "r");
 	if(!fp) {
@@ -147,7 +148,7 @@ static int register_syncs(void) {
 			section = strndup(&line[1], strlen(line) - 2);
 
 			if(section && strcmp(section, "options") != 0) {
-				alpm_db_register_sync(handle, section, PM_PGP_VERIFY_OPTIONAL);
+				alpm_db_register_sync(handle, section, level);
 			}
 		}
 	}
diff --git a/src/util/testdb.c b/src/util/testdb.c
index af5007e..8eefe30 100644
--- a/src/util/testdb.c
+++ b/src/util/testdb.c
@@ -148,10 +148,11 @@ static int check_syncdbs(alpm_list_t *dbnames) {
 	int ret = 0;
 	pmdb_t *db = NULL;
 	alpm_list_t *i, *pkglist, *syncpkglist = NULL;
+	const pmsiglevel_t level = PM_SIG_DATABASE | PM_SIG_DATABASE_OPTIONAL;
 
 	for(i = dbnames; i; i = alpm_list_next(i)) {
 		char *dbname = alpm_list_getdata(i);
-		db = alpm_db_register_sync(handle, dbname, PM_PGP_VERIFY_OPTIONAL);
+		db = alpm_db_register_sync(handle, dbname, level);
 		if(db == NULL) {
 			fprintf(stderr, "error: could not register sync database (%s)\n",
 					alpm_strerror(alpm_errno(handle)));
diff --git a/src/util/testpkg.c b/src/util/testpkg.c
index d4d058d..984142a 100644
--- a/src/util/testpkg.c
+++ b/src/util/testpkg.c
@@ -43,6 +43,7 @@ int main(int argc, char *argv[])
 	pmhandle_t *handle;
 	enum _pmerrno_t err;
 	pmpkg_t *pkg = NULL;
+	const pmsiglevel_t level = PM_SIG_PACKAGE | PM_SIG_PACKAGE_OPTIONAL;
 
 	if(argc != 2) {
 		fprintf(stderr, "usage: %s <package file>\n", BASENAME);
@@ -58,7 +59,7 @@ int main(int argc, char *argv[])
 	/* let us get log messages from libalpm */
 	alpm_option_set_logcb(handle, output_cb);
 
-	if(alpm_pkg_load(handle, argv[1], 1, PM_PGP_VERIFY_OPTIONAL, &pkg) == -1
+	if(alpm_pkg_load(handle, argv[1], 1, level, &pkg) == -1
 			|| pkg == NULL) {
 		err = alpm_errno(handle);
 		switch(err) {
-- 
1.7.5.4



More information about the pacman-dev mailing list