signing: move to new signing verification and return scheme

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 array of status codes 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@archlinux.org>
This commit is contained in:
Dan McGee 2011-06-27 16:29:49 -05:00
parent 1ce7f39ad7
commit 7af0ab1cde
22 changed files with 270 additions and 142 deletions

View File

@ -87,14 +87,31 @@ typedef enum _alpm_fileconflicttype_t {
} alpm_fileconflicttype_t; } alpm_fileconflicttype_t;
/** /**
* GPG signature verification options * PGP signature verification options
*/ */
typedef enum _pgp_verify_t { typedef enum _alpm_siglevel_t {
PM_PGP_VERIFY_UNKNOWN, ALPM_SIG_PACKAGE = (1 << 0),
PM_PGP_VERIFY_NEVER, ALPM_SIG_PACKAGE_OPTIONAL = (1 << 1),
PM_PGP_VERIFY_OPTIONAL, ALPM_SIG_PACKAGE_MARGINAL_OK = (1 << 2),
PM_PGP_VERIFY_ALWAYS ALPM_SIG_PACKAGE_UNKNOWN_OK = (1 << 3),
} pgp_verify_t;
ALPM_SIG_DATABASE = (1 << 10),
ALPM_SIG_DATABASE_OPTIONAL = (1 << 11),
ALPM_SIG_DATABASE_MARGINAL_OK = (1 << 12),
ALPM_SIG_DATABASE_UNKNOWN_OK = (1 << 13),
ALPM_SIG_USE_DEFAULT = (1 << 31)
} alpm_siglevel_t;
/**
* PGP signature verification return codes
*/
typedef enum _alpm_sigstatus_t {
ALPM_SIGSTATUS_VALID = 0,
ALPM_SIGSTATUS_MARGINAL,
ALPM_SIGSTATUS_UNKNOWN,
ALPM_SIGSTATUS_BAD
} alpm_sigstatus_t;
/* /*
* Structures * Structures
@ -173,6 +190,15 @@ typedef struct _alpm_backup_t {
char *hash; char *hash;
} alpm_backup_t; } alpm_backup_t;
/** Signature result. Contains the number of signatures found and pointers to
* arrays containing key and status info. All contained arrays have size
* #count.*/
typedef struct _alpm_sigresult_t {
int count;
alpm_sigstatus_t *status;
char **uid;
} alpm_sigresult_t;
/* /*
* Logging facilities * Logging facilities
*/ */
@ -335,8 +361,8 @@ int alpm_option_set_usedelta(alpm_handle_t *handle, int usedelta);
int alpm_option_get_checkspace(alpm_handle_t *handle); int alpm_option_get_checkspace(alpm_handle_t *handle);
int alpm_option_set_checkspace(alpm_handle_t *handle, int checkspace); int alpm_option_set_checkspace(alpm_handle_t *handle, int checkspace);
pgp_verify_t alpm_option_get_default_sigverify(alpm_handle_t *handle); alpm_siglevel_t alpm_option_get_default_siglevel(alpm_handle_t *handle);
int alpm_option_set_default_sigverify(alpm_handle_t *handle, pgp_verify_t level); int alpm_option_set_default_siglevel(alpm_handle_t *handle, alpm_siglevel_t level);
/** @} */ /** @} */
@ -364,12 +390,12 @@ alpm_list_t *alpm_option_get_syncdbs(alpm_handle_t *handle);
/** Register a sync database of packages. /** Register a sync database of packages.
* @param handle the context handle * @param handle the context handle
* @param treename the name of the sync repository * @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 * database; note that this must be a '.sig' file type verification
* @return a alpm_db_t* on success (the value), NULL on error * @return an alpm_db_t* on success (the value), NULL on error
*/ */
alpm_db_t *alpm_db_register_sync(alpm_handle_t *handle, const char *treename, alpm_db_t *alpm_db_register_sync(alpm_handle_t *handle, const char *treename,
pgp_verify_t check_sig); alpm_siglevel_t level);
/** Unregister a package database. /** Unregister a package database.
* @param db pointer to the package database to unregister * @param db pointer to the package database to unregister
@ -391,11 +417,11 @@ const char *alpm_db_get_name(const alpm_db_t *db);
/** Get the signature verification level for a database. /** Get the signature verification level for a database.
* Will return the default verification level if this database is set up * Will return the default verification level if this database is set up
* with PM_PGP_VERIFY_UNKNOWN. * with ALPM_SIG_USE_DEFAULT.
* @param db pointer to the package database * @param db pointer to the package database
* @return the signature verification level * @return the signature verification level
*/ */
pgp_verify_t alpm_db_get_sigverify_level(alpm_db_t *db); alpm_siglevel_t alpm_db_get_siglevel(alpm_db_t *db);
/** Check the validity of a database. /** Check the validity of a database.
* This is most useful for sync databases and verifying signature status. * This is most useful for sync databases and verifying signature status.
@ -473,13 +499,13 @@ int alpm_db_set_pkgreason(alpm_db_t *db, const char *name, alpm_pkgreason_t reas
* @param filename location of the package tarball * @param filename location of the package tarball
* @param full whether to stop the load after metadata is read or continue * @param full whether to stop the load after metadata is read or continue
* through the full archive * 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 * package; note that this must be a '.sig' file type verification
* @param pkg address of the package pointer * @param pkg address of the package pointer
* @return 0 on success, -1 on error (pm_errno is set accordingly) * @return 0 on success, -1 on error (pm_errno is set accordingly)
*/ */
int alpm_pkg_load(alpm_handle_t *handle, const char *filename, int full, int alpm_pkg_load(alpm_handle_t *handle, const char *filename, int full,
pgp_verify_t check_sig, alpm_pkg_t **pkg); alpm_siglevel_t, alpm_pkg_t **pkg);
/** Free a package. /** Free a package.
* @param pkg package pointer to free * @param pkg package pointer to free
@ -715,9 +741,9 @@ alpm_list_t *alpm_pkg_unused_deltas(alpm_pkg_t *pkg);
* Signatures * Signatures
*/ */
int alpm_pkg_check_pgp_signature(alpm_pkg_t *pkg); int alpm_pkg_check_pgp_signature(alpm_pkg_t *pkg, alpm_sigresult_t *result);
int alpm_db_check_pgp_signature(alpm_db_t *db); int alpm_db_check_pgp_signature(alpm_db_t *db, alpm_sigresult_t *result);
/* /*
* Groups * Groups
@ -1025,6 +1051,7 @@ enum _alpm_errno_t {
ALPM_ERR_DB_NOT_NULL, ALPM_ERR_DB_NOT_NULL,
ALPM_ERR_DB_NOT_FOUND, ALPM_ERR_DB_NOT_FOUND,
ALPM_ERR_DB_INVALID, ALPM_ERR_DB_INVALID,
ALPM_ERR_DB_INVALID_SIG,
ALPM_ERR_DB_VERSION, ALPM_ERR_DB_VERSION,
ALPM_ERR_DB_WRITE, ALPM_ERR_DB_WRITE,
ALPM_ERR_DB_REMOVE, ALPM_ERR_DB_REMOVE,
@ -1044,15 +1071,15 @@ enum _alpm_errno_t {
ALPM_ERR_PKG_NOT_FOUND, ALPM_ERR_PKG_NOT_FOUND,
ALPM_ERR_PKG_IGNORED, ALPM_ERR_PKG_IGNORED,
ALPM_ERR_PKG_INVALID, ALPM_ERR_PKG_INVALID,
ALPM_ERR_PKG_INVALID_SIG,
ALPM_ERR_PKG_OPEN, ALPM_ERR_PKG_OPEN,
ALPM_ERR_PKG_CANT_REMOVE, ALPM_ERR_PKG_CANT_REMOVE,
ALPM_ERR_PKG_INVALID_NAME, ALPM_ERR_PKG_INVALID_NAME,
ALPM_ERR_PKG_INVALID_ARCH, ALPM_ERR_PKG_INVALID_ARCH,
ALPM_ERR_PKG_REPO_NOT_FOUND, ALPM_ERR_PKG_REPO_NOT_FOUND,
/* Signatures */ /* Signatures */
ALPM_ERR_SIG_MISSINGDIR, ALPM_ERR_SIG_MISSING,
ALPM_ERR_SIG_INVALID, ALPM_ERR_SIG_INVALID,
ALPM_ERR_SIG_UNKNOWN,
/* Deltas */ /* Deltas */
ALPM_ERR_DLT_INVALID, ALPM_ERR_DLT_INVALID,
ALPM_ERR_DLT_PATCHFAILED, ALPM_ERR_DLT_PATCHFAILED,

View File

@ -233,7 +233,7 @@ static int parse_descfile(alpm_handle_t *handle, struct archive *a, alpm_pkg_t *
*/ */
alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle, const char *pkgfile, alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle, const char *pkgfile,
int full, const char *md5sum, const char *base64_sig, int full, const char *md5sum, const char *base64_sig,
pgp_verify_t check_sig) alpm_siglevel_t level)
{ {
int ret; int ret;
int config = 0; int config = 0;
@ -271,14 +271,12 @@ alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle, const char *pkgfile,
} }
_alpm_log(handle, ALPM_LOG_DEBUG, "base64_sig: %s\n", base64_sig); _alpm_log(handle, ALPM_LOG_DEBUG, "base64_sig: %s\n", base64_sig);
if(check_sig != PM_PGP_VERIFY_NEVER) { if(level & ALPM_SIG_PACKAGE &&
_alpm_log(handle, ALPM_LOG_DEBUG, "checking signature for %s\n", pkgfile); _alpm_check_pgp_helper(handle, pkgfile, base64_sig,
ret = _alpm_gpgme_checksig(handle, pkgfile, base64_sig); level & ALPM_SIG_PACKAGE_OPTIONAL, level & ALPM_SIG_PACKAGE_MARGINAL_OK,
if((check_sig == PM_PGP_VERIFY_ALWAYS && ret != 0) || level & ALPM_SIG_PACKAGE_UNKNOWN_OK, ALPM_ERR_PKG_INVALID_SIG)) {
(check_sig == PM_PGP_VERIFY_OPTIONAL && ret == 1)) { _alpm_pkg_free(newpkg);
alpm_pkg_free(newpkg); return NULL;
RET_ERR(handle, ALPM_ERR_SIG_INVALID, NULL);
}
} }
/* next- try to create an archive object to read in the package */ /* next- try to create an archive object to read in the package */
@ -396,12 +394,12 @@ error:
} }
int SYMEXPORT alpm_pkg_load(alpm_handle_t *handle, const char *filename, int full, int SYMEXPORT alpm_pkg_load(alpm_handle_t *handle, const char *filename, int full,
pgp_verify_t check_sig, alpm_pkg_t **pkg) alpm_siglevel_t level, alpm_pkg_t **pkg)
{ {
CHECK_HANDLE(handle, return -1); CHECK_HANDLE(handle, return -1);
ASSERT(pkg != NULL, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1)); ASSERT(pkg != NULL, RET_ERR(handle, ALPM_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) { if(*pkg == NULL) {
/* pm_errno is set by pkg_load */ /* pm_errno is set by pkg_load */
return -1; return -1;

View File

@ -69,7 +69,7 @@ static char *get_sync_dir(alpm_handle_t *handle)
static int sync_db_validate(alpm_db_t *db) static int sync_db_validate(alpm_db_t *db)
{ {
pgp_verify_t check_sig; alpm_siglevel_t level;
if(db->status & DB_STATUS_VALID) { if(db->status & DB_STATUS_VALID) {
return 0; return 0;
@ -77,10 +77,9 @@ static int sync_db_validate(alpm_db_t *db)
/* this takes into account the default verification level if UNKNOWN /* this takes into account the default verification level if UNKNOWN
* was assigned to this db */ * 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) { if(level & ALPM_SIG_DATABASE) {
int ret;
const char *dbpath = _alpm_db_path(db); const char *dbpath = _alpm_db_path(db);
if(!dbpath) { if(!dbpath) {
/* pm_errno set in _alpm_db_path() */ /* pm_errno set in _alpm_db_path() */
@ -93,12 +92,10 @@ static int sync_db_validate(alpm_db_t *db)
return 0; return 0;
} }
_alpm_log(db->handle, ALPM_LOG_DEBUG, "checking signature for %s\n", if(_alpm_check_pgp_helper(db->handle, dbpath, NULL,
db->treename); level & ALPM_SIG_DATABASE_OPTIONAL, level & ALPM_SIG_DATABASE_MARGINAL_OK,
ret = _alpm_gpgme_checksig(db->handle, dbpath, NULL); level & ALPM_SIG_DATABASE_UNKNOWN_OK, ALPM_ERR_DB_INVALID_SIG)) {
if((check_sig == PM_PGP_VERIFY_ALWAYS && ret != 0) || return 1;
(check_sig == PM_PGP_VERIFY_OPTIONAL && ret == 1)) {
RET_ERR(db->handle, ALPM_ERR_SIG_INVALID, -1);
} }
} }
@ -149,7 +146,7 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db)
int ret = -1; int ret = -1;
mode_t oldmask; mode_t oldmask;
alpm_handle_t *handle; alpm_handle_t *handle;
pgp_verify_t check_sig; alpm_siglevel_t level;
/* Sanity checks */ /* Sanity checks */
ASSERT(db != NULL, return -1); ASSERT(db != NULL, return -1);
@ -166,7 +163,7 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db)
/* make sure we have a sane umask */ /* make sure we have a sane umask */
oldmask = umask(0022); oldmask = umask(0022);
check_sig = alpm_db_get_sigverify_level(db); level = alpm_db_get_siglevel(db);
/* attempt to grab a lock */ /* attempt to grab a lock */
if(_alpm_handle_lock(handle)) { if(_alpm_handle_lock(handle)) {
@ -186,8 +183,7 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db)
ret = _alpm_download(handle, fileurl, syncpath, force, 0, 0); ret = _alpm_download(handle, fileurl, syncpath, force, 0, 0);
if(ret == 0 && (check_sig == PM_PGP_VERIFY_ALWAYS || if(ret == 0 && (level & ALPM_SIG_DATABASE)) {
check_sig == PM_PGP_VERIFY_OPTIONAL)) {
/* an existing sig file is no good at this point */ /* an existing sig file is no good at this point */
char *sigpath = _alpm_db_sig_path(db); char *sigpath = _alpm_db_sig_path(db);
if(!sigpath) { if(!sigpath) {
@ -197,7 +193,7 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db)
unlink(sigpath); unlink(sigpath);
free(sigpath); free(sigpath);
int errors_ok = (check_sig == PM_PGP_VERIFY_OPTIONAL); int errors_ok = (level & ALPM_SIG_DATABASE_OPTIONAL);
/* if we downloaded a DB, we want the .sig from the same server */ /* if we downloaded a DB, we want the .sig from the same server */
snprintf(fileurl, len, "%s/%s.db.sig", server, db->treename); snprintf(fileurl, len, "%s/%s.db.sig", server, db->treename);
@ -586,7 +582,7 @@ struct db_operations sync_db_ops = {
}; };
alpm_db_t *_alpm_db_register_sync(alpm_handle_t *handle, const char *treename, alpm_db_t *_alpm_db_register_sync(alpm_handle_t *handle, const char *treename,
pgp_verify_t level) alpm_siglevel_t level)
{ {
alpm_db_t *db; alpm_db_t *db;
@ -598,7 +594,7 @@ alpm_db_t *_alpm_db_register_sync(alpm_handle_t *handle, const char *treename,
} }
db->ops = &sync_db_ops; db->ops = &sync_db_ops;
db->handle = handle; db->handle = handle;
db->pgp_verify = level; db->siglevel = level;
if(sync_db_validate(db)) { if(sync_db_validate(db)) {
_alpm_db_free(db); _alpm_db_free(db);

View File

@ -45,8 +45,8 @@
*/ */
/** Register a sync database of packages. */ /** Register a sync database of packages. */
alpm_db_t SYMEXPORT *alpm_db_register_sync(alpm_handle_t *handle, const char *treename, alpm_db_t SYMEXPORT *alpm_db_register_sync(alpm_handle_t *handle,
pgp_verify_t check_sig) const char *treename, alpm_siglevel_t level)
{ {
/* Sanity checks */ /* Sanity checks */
CHECK_HANDLE(handle, return NULL); CHECK_HANDLE(handle, return NULL);
@ -55,7 +55,7 @@ alpm_db_t SYMEXPORT *alpm_db_register_sync(alpm_handle_t *handle, const char *tr
/* Do not register a database if a transaction is on-going */ /* Do not register a database if a transaction is on-going */
ASSERT(handle->trans == NULL, RET_ERR(handle, ALPM_ERR_TRANS_NOT_NULL, NULL)); ASSERT(handle->trans == NULL, RET_ERR(handle, ALPM_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} */ /* Helper function for alpm_db_unregister{_all} */
@ -220,13 +220,13 @@ const char SYMEXPORT *alpm_db_get_name(const alpm_db_t *db)
} }
/** Get the signature verification level for a database. */ /** Get the signature verification level for a database. */
pgp_verify_t SYMEXPORT alpm_db_get_sigverify_level(alpm_db_t *db) alpm_siglevel_t SYMEXPORT alpm_db_get_siglevel(alpm_db_t *db)
{ {
ASSERT(db != NULL, return -1); ASSERT(db != NULL, return -1);
if(db->pgp_verify == PM_PGP_VERIFY_UNKNOWN) { if(db->siglevel & ALPM_SIG_USE_DEFAULT) {
return alpm_option_get_default_sigverify(db->handle); return alpm_option_get_default_siglevel(db->handle);
} else { } else {
return db->pgp_verify; return db->siglevel;
} }
} }
@ -323,7 +323,7 @@ alpm_db_t *_alpm_db_new(const char *treename, int is_local)
CALLOC(db, 1, sizeof(alpm_db_t), return NULL); CALLOC(db, 1, sizeof(alpm_db_t), return NULL);
STRDUP(db->treename, treename, return NULL); STRDUP(db->treename, treename, return NULL);
db->is_local = is_local; db->is_local = is_local;
db->pgp_verify = PM_PGP_VERIFY_UNKNOWN; db->siglevel = 0;
return db; return db;
} }

View File

@ -69,7 +69,7 @@ struct __alpm_db_t {
alpm_pkghash_t *pkgcache; alpm_pkghash_t *pkgcache;
alpm_list_t *grpcache; alpm_list_t *grpcache;
alpm_list_t *servers; alpm_list_t *servers;
pgp_verify_t pgp_verify; alpm_siglevel_t siglevel;
struct db_operations *ops; struct db_operations *ops;
}; };
@ -84,7 +84,7 @@ int _alpm_db_cmp(const void *d1, const void *d2);
alpm_list_t *_alpm_db_search(alpm_db_t *db, const alpm_list_t *needles); alpm_list_t *_alpm_db_search(alpm_db_t *db, const alpm_list_t *needles);
alpm_db_t *_alpm_db_register_local(alpm_handle_t *handle); alpm_db_t *_alpm_db_register_local(alpm_handle_t *handle);
alpm_db_t *_alpm_db_register_sync(alpm_handle_t *handle, const char *treename, alpm_db_t *_alpm_db_register_sync(alpm_handle_t *handle, const char *treename,
pgp_verify_t level); alpm_siglevel_t level);
void _alpm_db_unregister(alpm_db_t *db); void _alpm_db_unregister(alpm_db_t *db);
/* be_*.c, backend specific calls */ /* be_*.c, backend specific calls */

View File

@ -363,11 +363,10 @@ char SYMEXPORT *alpm_fetch_pkgurl(alpm_handle_t *handle, const char *url)
_alpm_log(handle, ALPM_LOG_DEBUG, "successfully downloaded %s\n", url); _alpm_log(handle, ALPM_LOG_DEBUG, "successfully downloaded %s\n", url);
/* attempt to download the signature */ /* attempt to download the signature */
if(ret == 0 && (handle->sigverify == PM_PGP_VERIFY_ALWAYS || if(ret == 0 && (handle->siglevel & ALPM_SIG_PACKAGE)) {
handle->sigverify == PM_PGP_VERIFY_OPTIONAL)) {
char *sig_url; char *sig_url;
size_t len; size_t len;
int errors_ok = (handle->sigverify == PM_PGP_VERIFY_OPTIONAL); int errors_ok = (handle->siglevel & ALPM_SIG_PACKAGE_OPTIONAL);
len = strlen(url) + 5; len = strlen(url) + 5;
CALLOC(sig_url, len, sizeof(char), RET_ERR(handle, ALPM_ERR_MEMORY, NULL)); CALLOC(sig_url, len, sizeof(char), RET_ERR(handle, ALPM_ERR_MEMORY, NULL));

View File

@ -72,6 +72,8 @@ const char SYMEXPORT *alpm_strerror(enum _alpm_errno_t err)
return _("could not find database"); return _("could not find database");
case ALPM_ERR_DB_INVALID: case ALPM_ERR_DB_INVALID:
return _("invalid or corrupted database"); return _("invalid or corrupted database");
case ALPM_ERR_DB_INVALID_SIG:
return _("invalid or corrupted database (PGP signature)");
case ALPM_ERR_DB_VERSION: case ALPM_ERR_DB_VERSION:
return _("database is incorrect version"); return _("database is incorrect version");
case ALPM_ERR_DB_WRITE: case ALPM_ERR_DB_WRITE:
@ -106,7 +108,9 @@ const char SYMEXPORT *alpm_strerror(enum _alpm_errno_t err)
case ALPM_ERR_PKG_IGNORED: case ALPM_ERR_PKG_IGNORED:
return _("operation cancelled due to ignorepkg"); return _("operation cancelled due to ignorepkg");
case ALPM_ERR_PKG_INVALID: case ALPM_ERR_PKG_INVALID:
return _("invalid or corrupted package"); return _("invalid or corrupted package (checksum)");
case ALPM_ERR_PKG_INVALID_SIG:
return _("invalid or corrupted package (PGP signature)");
case ALPM_ERR_PKG_OPEN: case ALPM_ERR_PKG_OPEN:
return _("cannot open package file"); return _("cannot open package file");
case ALPM_ERR_PKG_CANT_REMOVE: case ALPM_ERR_PKG_CANT_REMOVE:
@ -118,12 +122,10 @@ const char SYMEXPORT *alpm_strerror(enum _alpm_errno_t err)
case ALPM_ERR_PKG_REPO_NOT_FOUND: case ALPM_ERR_PKG_REPO_NOT_FOUND:
return _("could not find repository for target"); return _("could not find repository for target");
/* Signatures */ /* Signatures */
case ALPM_ERR_SIG_MISSINGDIR: case ALPM_ERR_SIG_MISSING:
return _("signature directory not configured correctly"); return _("missing PGP signature");
case ALPM_ERR_SIG_INVALID: case ALPM_ERR_SIG_INVALID:
return _("invalid PGP signature"); return _("invalid PGP signature");
case ALPM_ERR_SIG_UNKNOWN:
return _("unknown PGP signature");
/* Deltas */ /* Deltas */
case ALPM_ERR_DLT_INVALID: case ALPM_ERR_DLT_INVALID:
return _("invalid or corrupted delta"); return _("invalid or corrupted delta");

View File

@ -45,7 +45,8 @@ alpm_handle_t *_alpm_handle_new()
CALLOC(handle, 1, sizeof(alpm_handle_t), return NULL); CALLOC(handle, 1, sizeof(alpm_handle_t), return NULL);
handle->sigverify = PM_PGP_VERIFY_OPTIONAL; handle->siglevel = ALPM_SIG_PACKAGE | ALPM_SIG_PACKAGE_OPTIONAL |
ALPM_SIG_DATABASE | ALPM_SIG_DATABASE_OPTIONAL;
return handle; return handle;
} }
@ -574,18 +575,18 @@ int SYMEXPORT alpm_option_set_checkspace(alpm_handle_t *handle, int checkspace)
return 0; return 0;
} }
int SYMEXPORT alpm_option_set_default_sigverify(alpm_handle_t *handle, pgp_verify_t level) int SYMEXPORT alpm_option_set_default_siglevel(alpm_handle_t *handle,
alpm_siglevel_t level)
{ {
CHECK_HANDLE(handle, return -1); CHECK_HANDLE(handle, return -1);
ASSERT(level != PM_PGP_VERIFY_UNKNOWN, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1)); handle->siglevel = level;
handle->sigverify = level;
return 0; return 0;
} }
pgp_verify_t SYMEXPORT alpm_option_get_default_sigverify(alpm_handle_t *handle) alpm_siglevel_t SYMEXPORT alpm_option_get_default_siglevel(alpm_handle_t *handle)
{ {
CHECK_HANDLE(handle, return PM_PGP_VERIFY_UNKNOWN); CHECK_HANDLE(handle, return -1);
return handle->sigverify; return handle->siglevel;
} }
/* vim: set ts=2 sw=2 noet: */ /* vim: set ts=2 sw=2 noet: */

View File

@ -69,7 +69,7 @@ struct __alpm_handle_t {
char *arch; /* Architecture of packages we should allow */ char *arch; /* Architecture of packages we should allow */
int usedelta; /* Download deltas if possible */ int usedelta; /* Download deltas if possible */
int checkspace; /* Check disk space before installing */ int checkspace; /* Check disk space before installing */
pgp_verify_t sigverify; /* Default signature verification level */ alpm_siglevel_t siglevel; /* Default signature verification level */
/* error code */ /* error code */
enum _alpm_errno_t pm_errno; enum _alpm_errno_t pm_errno;

View File

@ -151,7 +151,7 @@ void _alpm_pkg_free_trans(alpm_pkg_t *pkg);
alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle, const char *pkgfile, alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle, const char *pkgfile,
int full, const char *md5sum, const char *base64_sig, int full, const char *md5sum, const char *base64_sig,
pgp_verify_t check_sig); alpm_siglevel_t level);
int _alpm_pkg_cmp(const void *p1, const void *p2); int _alpm_pkg_cmp(const void *p1, const void *p2);
int _alpm_pkg_compare_versions(alpm_pkg_t *local_pkg, alpm_pkg_t *pkg); int _alpm_pkg_compare_versions(alpm_pkg_t *local_pkg, alpm_pkg_t *pkg);

View File

@ -117,9 +117,6 @@ static int init_gpgme(alpm_handle_t *handle)
} }
sigdir = alpm_option_get_gpgdir(handle); sigdir = alpm_option_get_gpgdir(handle);
if(!sigdir) {
RET_ERR(handle, ALPM_ERR_SIG_MISSINGDIR, 1);
}
/* calling gpgme_check_version() returns the current version and runs /* calling gpgme_check_version() returns the current version and runs
* some internal library setup code */ * some internal library setup code */
@ -196,23 +193,27 @@ error:
* Check the PGP signature for the given file path. * Check the PGP signature for the given file path.
* If base64_sig is provided, it will be used as the signature data after * If base64_sig is provided, it will be used as the signature data after
* decoding. If base64_sig is NULL, expect a signature file next to path * decoding. If base64_sig is NULL, expect a signature file next to path
* (e.g. "%s.sig"). The return value will be 0 if all checked signatures are * (e.g. "%s.sig").
* valid, 1 if there was some sort of problem (but not necessarily rejection), *
* and -1 if an error occurred while checking signatures. If 1 is returned, * The return value will be 0 if nothing abnormal happened during the signature
* pm_errno should be checked to see why the signatures did not pass muster. * check, and -1 if an error occurred while checking signatures or if a
* signature could not be found; pm_errno will be set. Note that "abnormal"
* does not include a failed signature; the value in #result should be checked
* to determine if the signature(s) are good.
* @param handle the context handle * @param handle the context handle
* @param path the full path to a file * @param path the full path to a file
* @param base64_sig optional PGP signature data in base64 encoding * @param base64_sig optional PGP signature data in base64 encoding
* @return a int value : 0 (valid), 1 (invalid), -1 (an error occurred) * @result
* @return 0 in normal cases, -1 if the something failed in the check process
*/ */
int _alpm_gpgme_checksig(alpm_handle_t *handle, const char *path, int _alpm_gpgme_checksig(alpm_handle_t *handle, const char *path,
const char *base64_sig) const char *base64_sig, alpm_sigresult_t *result)
{ {
int ret = 0; int ret = -1, sigcount;
gpgme_error_t err; gpgme_error_t err;
gpgme_ctx_t ctx; gpgme_ctx_t ctx;
gpgme_data_t filedata, sigdata; gpgme_data_t filedata, sigdata;
gpgme_verify_result_t result; gpgme_verify_result_t verify_result;
gpgme_signature_t gpgsig; gpgme_signature_t gpgsig;
char *sigpath = NULL; char *sigpath = NULL;
unsigned char *decoded_sigdata = NULL; unsigned char *decoded_sigdata = NULL;
@ -222,14 +223,18 @@ int _alpm_gpgme_checksig(alpm_handle_t *handle, const char *path,
RET_ERR(handle, ALPM_ERR_NOT_A_FILE, -1); RET_ERR(handle, ALPM_ERR_NOT_A_FILE, -1);
} }
if(!result) {
RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1);
}
result->count = 0;
if(!base64_sig) { if(!base64_sig) {
size_t len = strlen(path) + 5; size_t len = strlen(path) + 5;
CALLOC(sigpath, len, sizeof(char), RET_ERR(handle, ALPM_ERR_MEMORY, -1)); CALLOC(sigpath, len, sizeof(char), RET_ERR(handle, ALPM_ERR_MEMORY, -1));
snprintf(sigpath, len, "%s.sig", path); snprintf(sigpath, len, "%s.sig", path);
if(!access(sigpath, R_OK) == 0) { if(!access(sigpath, R_OK) == 0) {
FREE(sigpath); /* sigcount is 0 */
RET_ERR(handle, ALPM_ERR_SIG_UNKNOWN, -1);
} }
} }
@ -251,7 +256,6 @@ int _alpm_gpgme_checksig(alpm_handle_t *handle, const char *path,
file = fopen(path, "rb"); file = fopen(path, "rb");
if(file == NULL) { if(file == NULL) {
handle->pm_errno = ALPM_ERR_NOT_A_FILE; handle->pm_errno = ALPM_ERR_NOT_A_FILE;
ret = -1;
goto error; goto error;
} }
err = gpgme_data_new_from_stream(&filedata, file); err = gpgme_data_new_from_stream(&filedata, file);
@ -264,7 +268,7 @@ int _alpm_gpgme_checksig(alpm_handle_t *handle, const char *path,
int decode_ret = decode_signature(base64_sig, int decode_ret = decode_signature(base64_sig,
&decoded_sigdata, &data_len); &decoded_sigdata, &data_len);
if(decode_ret) { if(decode_ret) {
ret = -1; handle->pm_errno = ALPM_ERR_SIG_INVALID;
goto error; goto error;
} }
err = gpgme_data_new_from_mem(&sigdata, err = gpgme_data_new_from_mem(&sigdata,
@ -273,8 +277,7 @@ int _alpm_gpgme_checksig(alpm_handle_t *handle, const char *path,
/* file-based, it is on disk */ /* file-based, it is on disk */
sigfile = fopen(sigpath, "rb"); sigfile = fopen(sigpath, "rb");
if(sigfile == NULL) { if(sigfile == NULL) {
handle->pm_errno = ALPM_ERR_NOT_A_FILE; handle->pm_errno = ALPM_ERR_SIG_MISSING;
ret = -1;
goto error; goto error;
} }
err = gpgme_data_new_from_stream(&sigdata, sigfile); err = gpgme_data_new_from_stream(&sigdata, sigfile);
@ -284,16 +287,29 @@ int _alpm_gpgme_checksig(alpm_handle_t *handle, const char *path,
/* here's where the magic happens */ /* here's where the magic happens */
err = gpgme_op_verify(ctx, sigdata, filedata, NULL); err = gpgme_op_verify(ctx, sigdata, filedata, NULL);
CHECK_ERR(); CHECK_ERR();
result = gpgme_op_verify_result(ctx); verify_result = gpgme_op_verify_result(ctx);
gpgsig = result->signatures; CHECK_ERR();
if(!gpgsig) { if(!verify_result || !verify_result->signatures) {
_alpm_log(handle, ALPM_LOG_DEBUG, "no signatures returned\n"); _alpm_log(handle, ALPM_LOG_DEBUG, "no signatures returned\n");
ret = -1; handle->pm_errno = ALPM_ERR_SIG_MISSING;
goto error; goto error;
} }
for(gpgsig = verify_result->signatures, sigcount = 0;
gpgsig; gpgsig = gpgsig->next, sigcount++);
_alpm_log(handle, ALPM_LOG_DEBUG, "%d signatures returned\n", sigcount);
while(gpgsig) { result->status = calloc(sigcount, sizeof(alpm_sigstatus_t));
result->uid = calloc(sigcount, sizeof(char*));
if(!result->status || !result->uid) {
handle->pm_errno = ALPM_ERR_MEMORY;
goto error;
}
result->count = sigcount;
for(gpgsig = verify_result->signatures, sigcount = 0; gpgsig;
gpgsig = gpgsig->next, sigcount++) {
alpm_list_t *summary_list, *summary; alpm_list_t *summary_list, *summary;
alpm_sigstatus_t status;
_alpm_log(handle, ALPM_LOG_DEBUG, "fingerprint: %s\n", gpgsig->fpr); _alpm_log(handle, ALPM_LOG_DEBUG, "fingerprint: %s\n", gpgsig->fpr);
summary_list = list_sigsum(gpgsig->summary); summary_list = list_sigsum(gpgsig->summary);
@ -308,34 +324,53 @@ int _alpm_gpgme_checksig(alpm_handle_t *handle, const char *path,
string_validity(gpgsig->validity), string_validity(gpgsig->validity),
gpgme_strerror(gpgsig->validity_reason)); gpgme_strerror(gpgsig->validity_reason));
/* Note: this is structured so any bad signature will set the return code err = gpgme_get_key(ctx, gpgsig->fpr, &key, 0);
* to a bad one, but good ones just leave the default value in place; e.g. if(gpg_err_code(err) == GPG_ERR_EOF) {
* worst case wins out. */ _alpm_log(handle, ALPM_LOG_DEBUG, "key lookup failed, unknown key\n");
err = GPG_ERR_NO_ERROR;
} else {
CHECK_ERR();
if(key->uids) {
const char *uid = key->uids->uid;
STRDUP(result->uid[sigcount], uid,
handle->pm_errno = ALPM_ERR_MEMORY; goto error);
_alpm_log(handle, ALPM_LOG_DEBUG, "key user: %s\n", uid);
}
gpgme_key_unref(key);
}
if(gpgsig->summary & GPGME_SIGSUM_VALID) { if(gpgsig->summary & GPGME_SIGSUM_VALID) {
/* definite good signature */ /* definite good signature */
_alpm_log(handle, ALPM_LOG_DEBUG, "result: valid signature\n"); _alpm_log(handle, ALPM_LOG_DEBUG, "result: valid signature\n");
status = ALPM_SIGSTATUS_VALID;
} else if(gpgsig->summary & GPGME_SIGSUM_GREEN) { } else if(gpgsig->summary & GPGME_SIGSUM_GREEN) {
/* good signature */ /* good signature */
_alpm_log(handle, ALPM_LOG_DEBUG, "result: green signature\n"); _alpm_log(handle, ALPM_LOG_DEBUG, "result: green signature\n");
status = ALPM_SIGSTATUS_VALID;
} else if(gpgsig->summary & GPGME_SIGSUM_RED) { } else if(gpgsig->summary & GPGME_SIGSUM_RED) {
/* definite bad signature, error */ /* definite bad signature, error */
_alpm_log(handle, ALPM_LOG_DEBUG, "result: red signature\n"); _alpm_log(handle, ALPM_LOG_DEBUG, "result: red signature\n");
handle->pm_errno = ALPM_ERR_SIG_INVALID; status = ALPM_SIGSTATUS_BAD;
ret = 1;
} else if(gpgsig->summary & GPGME_SIGSUM_KEY_MISSING) { } else if(gpgsig->summary & GPGME_SIGSUM_KEY_MISSING) {
_alpm_log(handle, ALPM_LOG_DEBUG, "result: signature from unknown key\n"); _alpm_log(handle, ALPM_LOG_DEBUG, "result: signature from unknown key\n");
handle->pm_errno = ALPM_ERR_SIG_UNKNOWN; status = ALPM_SIGSTATUS_UNKNOWN;
ret = 1; } else if(gpgsig->summary & GPGME_SIGSUM_KEY_EXPIRED) {
_alpm_log(handle, ALPM_LOG_DEBUG, "result: key expired\n");
status = ALPM_SIGSTATUS_BAD;
} else if(gpgsig->summary & GPGME_SIGSUM_SIG_EXPIRED) {
_alpm_log(handle, ALPM_LOG_DEBUG, "result: signature expired\n");
status = ALPM_SIGSTATUS_BAD;
} else { } else {
/* we'll capture everything else here */ /* we'll capture everything else here */
_alpm_log(handle, ALPM_LOG_DEBUG, "result: invalid signature\n"); _alpm_log(handle, ALPM_LOG_DEBUG, "result: invalid signature\n");
handle->pm_errno = ALPM_ERR_SIG_INVALID; status = ALPM_SIGSTATUS_BAD;
ret = 1;
} }
gpgsig = gpgsig->next; result->status[sigcount] = status;
} }
ret = 0;
error: error:
gpgme_data_release(sigdata); gpgme_data_release(sigdata);
gpgme_data_release(filedata); gpgme_data_release(filedata);
@ -362,18 +397,77 @@ int _alpm_gpgme_checksig(alpm_handle_t *handle, const char *path,
} }
#endif #endif
int _alpm_check_pgp_helper(alpm_handle_t *handle, const char *path,
const char *base64_sig, int optional, int marginal, int unknown,
enum _alpm_errno_t invalid_err)
{
alpm_sigresult_t result;
int ret;
memset(&result, 0, sizeof(result));
_alpm_log(handle, ALPM_LOG_DEBUG, "checking signatures for %s\n", path);
ret = _alpm_gpgme_checksig(handle, path, base64_sig, &result);
if(ret && handle->pm_errno == ALPM_ERR_SIG_MISSING) {
if(optional) {
_alpm_log(handle, ALPM_LOG_DEBUG, "missing optional signature\n");
handle->pm_errno = 0;
ret = 0;
} else {
_alpm_log(handle, ALPM_LOG_DEBUG, "missing required signature\n");
/* ret will already be -1 */
}
} else if(ret) {
_alpm_log(handle, ALPM_LOG_DEBUG, "signature check failed\n");
/* ret will already be -1 */
} else {
int num;
for(num = 0; num < result.count; num++) {
/* fallthrough in this case block is on purpose. if one allows unknown
* signatures, then a marginal signature should be allowed as well, and
* if neither of these are allowed we fall all the way through to bad. */
switch(result.status[num]) {
case ALPM_SIGSTATUS_VALID:
_alpm_log(handle, ALPM_LOG_DEBUG, "signature is valid\n");
break;
case ALPM_SIGSTATUS_MARGINAL:
if(marginal) {
_alpm_log(handle, ALPM_LOG_DEBUG, "allowing marginal signature\n");
break;
}
case ALPM_SIGSTATUS_UNKNOWN:
if(unknown) {
_alpm_log(handle, ALPM_LOG_DEBUG, "allowing unknown signature\n");
break;
}
case ALPM_SIGSTATUS_BAD:
default:
_alpm_log(handle, ALPM_LOG_DEBUG, "signature is invalid\n");
handle->pm_errno = invalid_err;
ret = -1;
}
}
}
free(result.status);
free(result.uid);
return ret;
}
/** /**
* Check the PGP signature for the given package file. * Check the PGP signature for the given package file.
* @param pkg the package to check * @param pkg the package to check
* @return a int value : 0 (valid), 1 (invalid), -1 (an error occurred) * @return a int value : 0 (valid), 1 (invalid), -1 (an error occurred)
*/ */
int SYMEXPORT alpm_pkg_check_pgp_signature(alpm_pkg_t *pkg) int SYMEXPORT alpm_pkg_check_pgp_signature(alpm_pkg_t *pkg,
alpm_sigresult_t *result)
{ {
ASSERT(pkg != NULL, return -1); ASSERT(pkg != NULL, return -1);
ASSERT(result != NULL, RET_ERR(pkg->handle, ALPM_ERR_WRONG_ARGS, -1));
pkg->handle->pm_errno = 0; pkg->handle->pm_errno = 0;
return _alpm_gpgme_checksig(pkg->handle, alpm_pkg_get_filename(pkg), return _alpm_gpgme_checksig(pkg->handle, alpm_pkg_get_filename(pkg),
pkg->base64_sig); pkg->base64_sig, result);
} }
/** /**
@ -381,12 +475,14 @@ int SYMEXPORT alpm_pkg_check_pgp_signature(alpm_pkg_t *pkg)
* @param db the database to check * @param db the database to check
* @return a int value : 0 (valid), 1 (invalid), -1 (an error occurred) * @return a int value : 0 (valid), 1 (invalid), -1 (an error occurred)
*/ */
int SYMEXPORT alpm_db_check_pgp_signature(alpm_db_t *db) int SYMEXPORT alpm_db_check_pgp_signature(alpm_db_t *db,
alpm_sigresult_t *result)
{ {
ASSERT(db != NULL, return -1); ASSERT(db != NULL, return -1);
ASSERT(result != NULL, RET_ERR(db->handle, ALPM_ERR_WRONG_ARGS, -1));
db->handle->pm_errno = 0; db->handle->pm_errno = 0;
return _alpm_gpgme_checksig(db->handle, _alpm_db_path(db), NULL); return _alpm_gpgme_checksig(db->handle, _alpm_db_path(db), NULL, result);
} }
/* vim: set ts=2 sw=2 noet: */ /* vim: set ts=2 sw=2 noet: */

View File

@ -22,7 +22,10 @@
#include "alpm.h" #include "alpm.h"
int _alpm_gpgme_checksig(alpm_handle_t *handle, const char *path, int _alpm_gpgme_checksig(alpm_handle_t *handle, const char *path,
const char *base64_sig); const char *base64_sig, alpm_sigresult_t *result);
int _alpm_check_pgp_helper(alpm_handle_t *handle, const char *path,
const char *base64_sig, int optional, int marginal, int unknown,
enum _alpm_errno_t invalid_err);
#endif /* _ALPM_SIGNING_H */ #endif /* _ALPM_SIGNING_H */

View File

@ -863,7 +863,7 @@ int _alpm_sync_commit(alpm_handle_t *handle, alpm_list_t **data)
int percent = (current * 100) / numtargs; int percent = (current * 100) / numtargs;
const char *filename; const char *filename;
char *filepath; char *filepath;
pgp_verify_t check_sig; alpm_siglevel_t level;
PROGRESS(trans, ALPM_TRANS_PROGRESS_INTEGRITY_START, "", percent, PROGRESS(trans, ALPM_TRANS_PROGRESS_INTEGRITY_START, "", percent,
numtargs, current); numtargs, current);
@ -874,7 +874,7 @@ int _alpm_sync_commit(alpm_handle_t *handle, alpm_list_t **data)
filename = alpm_pkg_get_filename(spkg); filename = alpm_pkg_get_filename(spkg);
filepath = _alpm_filecache_find(handle, filename); filepath = _alpm_filecache_find(handle, filename);
alpm_db_t *sdb = alpm_pkg_get_db(spkg); alpm_db_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 */ /* 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 */ /* TODO: alpm_pkg_get_db() will not work on this target anymore */
@ -882,7 +882,7 @@ int _alpm_sync_commit(alpm_handle_t *handle, alpm_list_t **data)
"replacing pkgcache entry with package file for target %s\n", "replacing pkgcache entry with package file for target %s\n",
spkg->name); spkg->name);
alpm_pkg_t *pkgfile =_alpm_pkg_load_internal(handle, filepath, 1, spkg->md5sum, alpm_pkg_t *pkgfile =_alpm_pkg_load_internal(handle, filepath, 1, spkg->md5sum,
spkg->base64_sig, check_sig); spkg->base64_sig, level);
if(!pkgfile) { if(!pkgfile) {
errors++; errors++;
*data = alpm_list_add(*data, strdup(filename)); *data = alpm_list_add(*data, strdup(filename));

View File

@ -52,7 +52,7 @@ config_t *config_new(void)
newconfig->op = PM_OP_MAIN; newconfig->op = PM_OP_MAIN;
newconfig->logmask = ALPM_LOG_ERROR | ALPM_LOG_WARNING; newconfig->logmask = ALPM_LOG_ERROR | ALPM_LOG_WARNING;
newconfig->configfile = strdup(CONFFILE); newconfig->configfile = strdup(CONFFILE);
newconfig->sigverify = PM_PGP_VERIFY_UNKNOWN; newconfig->siglevel = ALPM_SIG_USE_DEFAULT;
return newconfig; return newconfig;
} }
@ -222,17 +222,18 @@ int config_set_arch(const char *arch)
return 0; return 0;
} }
static pgp_verify_t option_verifysig(const char *value) static alpm_siglevel_t option_verifysig(const char *value)
{ {
pgp_verify_t level; alpm_siglevel_t level;
if(strcmp(value, "Always") == 0) { if(strcmp(value, "Always") == 0) {
level = PM_PGP_VERIFY_ALWAYS; level = ALPM_SIG_PACKAGE | ALPM_SIG_DATABASE;
} else if(strcmp(value, "Optional") == 0) { } else if(strcmp(value, "Optional") == 0) {
level = PM_PGP_VERIFY_OPTIONAL; level = ALPM_SIG_PACKAGE | ALPM_SIG_PACKAGE_OPTIONAL |
ALPM_SIG_DATABASE | ALPM_SIG_DATABASE_OPTIONAL;
} else if(strcmp(value, "Never") == 0) { } else if(strcmp(value, "Never") == 0) {
level = PM_PGP_VERIFY_NEVER; level = 0;
} else { } else {
level = PM_PGP_VERIFY_UNKNOWN; return -1;
} }
pm_printf(ALPM_LOG_DEBUG, "config: VerifySig = %s (%d)\n", value, level); pm_printf(ALPM_LOG_DEBUG, "config: VerifySig = %s (%d)\n", value, level);
return level; return level;
@ -359,9 +360,9 @@ static int _parse_options(const char *key, char *value,
} }
FREELIST(methods); FREELIST(methods);
} else if(strcmp(key, "VerifySig") == 0) { } else if(strcmp(key, "VerifySig") == 0) {
pgp_verify_t level = option_verifysig(value); alpm_siglevel_t level = option_verifysig(value);
if(level != PM_PGP_VERIFY_UNKNOWN) { if(level != -1) {
config->sigverify = level; config->siglevel = level;
} else { } else {
pm_printf(ALPM_LOG_ERROR, pm_printf(ALPM_LOG_ERROR,
_("config file %s, line %d: directive '%s' has invalid value '%s'\n"), _("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); alpm_option_set_cachedirs(handle, config->cachedirs);
} }
if(config->sigverify != PM_PGP_VERIFY_UNKNOWN) { if(config->siglevel != ALPM_SIG_USE_DEFAULT) {
alpm_option_set_default_sigverify(handle, config->sigverify); alpm_option_set_default_siglevel(handle, config->siglevel);
} }
if(config->xfercommand) { if(config->xfercommand) {
@ -518,7 +519,7 @@ struct section_t {
char *name; char *name;
int is_options; int is_options;
/* db section option gathering */ /* db section option gathering */
pgp_verify_t sigverify; alpm_siglevel_t siglevel;
alpm_list_t *servers; 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 */ /* 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) { if(db == NULL) {
pm_printf(ALPM_LOG_ERROR, _("could not register '%s' database (%s)\n"), pm_printf(ALPM_LOG_ERROR, _("could not register '%s' database (%s)\n"),
section->name, alpm_strerror(alpm_errno(config->handle))); section->name, alpm_strerror(alpm_errno(config->handle)));
@ -568,7 +569,7 @@ static int finish_section(struct section_t *section, int parse_options)
cleanup: cleanup:
alpm_list_free(section->servers); alpm_list_free(section->servers);
section->servers = NULL; section->servers = NULL;
section->sigverify = 0; section->siglevel = ALPM_SIG_USE_DEFAULT;
free(section->name); free(section->name);
section->name = NULL; section->name = NULL;
return ret; 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)); section->servers = alpm_list_add(section->servers, strdup(value));
} else if(strcmp(key, "VerifySig") == 0) { } else if(strcmp(key, "VerifySig") == 0) {
pgp_verify_t level = option_verifysig(value); alpm_siglevel_t level = option_verifysig(value);
if(level != PM_PGP_VERIFY_UNKNOWN) { if(level != -1) {
section->sigverify = level; section->siglevel = level;
} else { } else {
pm_printf(ALPM_LOG_ERROR, pm_printf(ALPM_LOG_ERROR,
_("config file %s, line %d: directive '%s' has invalid value '%s'\n"), _("config file %s, line %d: directive '%s' has invalid value '%s'\n"),
@ -763,6 +764,7 @@ int parseconfig(const char *file)
int ret; int ret;
struct section_t section; struct section_t section;
memset(&section, 0, sizeof(struct section_t)); memset(&section, 0, sizeof(struct section_t));
section.siglevel = ALPM_SIG_USE_DEFAULT;
/* the config parse is a two-pass affair. We first parse the entire thing for /* 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. * the [options] section so we can get all default and path options set.
* Next, we go back and parse everything but [options]. */ * Next, we go back and parse everything but [options]. */

View File

@ -71,7 +71,7 @@ typedef struct __config_t {
unsigned short noask; unsigned short noask;
unsigned int ask; unsigned int ask;
alpm_transflag_t flags; alpm_transflag_t flags;
pgp_verify_t sigverify; alpm_siglevel_t siglevel;
/* conf file options */ /* conf file options */
/* I Love Candy! */ /* I Love Candy! */

View File

@ -551,7 +551,7 @@ int pacman_query(alpm_list_t *targets)
char *strname = alpm_list_getdata(i); char *strname = alpm_list_getdata(i);
if(config->op_q_isfile) { 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 { } else {
pkg = alpm_db_get_pkg(db_local, strname); pkg = alpm_db_get_pkg(db_local, strname);
} }

View File

@ -220,7 +220,7 @@ static int sync_cleancache(int level)
/* attempt to load the package, prompt removal on failures as we may have /* 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 * files here that aren't valid packages. we also don't need a full
* load of the package, just the metadata. */ * 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) { || localpkg == NULL) {
if(yesno(_("File %s does not seem to be a valid package, remove it?"), if(yesno(_("File %s does not seem to be a valid package, remove it?"),
path)) { path)) {

View File

@ -42,7 +42,7 @@
int pacman_upgrade(alpm_list_t *targets) int pacman_upgrade(alpm_list_t *targets)
{ {
alpm_list_t *i, *data = NULL; alpm_list_t *i, *data = NULL;
pgp_verify_t check_sig = alpm_option_get_default_sigverify(config->handle); alpm_siglevel_t level = alpm_option_get_default_siglevel(config->handle);
int retval = 0; int retval = 0;
if(targets == NULL) { if(targets == NULL) {
@ -76,7 +76,7 @@ int pacman_upgrade(alpm_list_t *targets)
char *targ = alpm_list_getdata(i); char *targ = alpm_list_getdata(i);
alpm_pkg_t *pkg; alpm_pkg_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, ALPM_LOG_ERROR, "'%s': %s\n", pm_fprintf(stderr, ALPM_LOG_ERROR, "'%s': %s\n",
targ, alpm_strerror(alpm_errno(config->handle))); targ, alpm_strerror(alpm_errno(config->handle)));
trans_release(); trans_release();

View File

@ -71,11 +71,12 @@ static void checkdbs(const char *dbpath, alpm_list_t *dbnames) {
char syncdbpath[PATH_MAX]; char syncdbpath[PATH_MAX];
alpm_db_t *db = NULL; alpm_db_t *db = NULL;
alpm_list_t *i; alpm_list_t *i;
const alpm_siglevel_t level = ALPM_SIG_DATABASE | ALPM_SIG_DATABASE_OPTIONAL;
for(i = dbnames; i; i = alpm_list_next(i)) { for(i = dbnames; i; i = alpm_list_next(i)) {
char *dbname = alpm_list_getdata(i); char *dbname = alpm_list_getdata(i);
snprintf(syncdbpath, PATH_MAX, "%s/sync/%s", dbpath, dbname); 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) { if(db == NULL) {
fprintf(stderr, "error: could not register sync database (%s)\n", fprintf(stderr, "error: could not register sync database (%s)\n",
alpm_strerror(alpm_errno(handle))); alpm_strerror(alpm_errno(handle)));

View File

@ -124,6 +124,7 @@ static int register_syncs(void) {
FILE *fp; FILE *fp;
char *ptr, *section = NULL; char *ptr, *section = NULL;
char line[LINE_MAX]; char line[LINE_MAX];
const alpm_siglevel_t level = ALPM_SIG_DATABASE | ALPM_SIG_DATABASE_OPTIONAL;
fp = fopen(CONFFILE, "r"); fp = fopen(CONFFILE, "r");
if(!fp) { if(!fp) {
@ -147,7 +148,7 @@ static int register_syncs(void) {
section = strndup(&line[1], strlen(line) - 2); section = strndup(&line[1], strlen(line) - 2);
if(section && strcmp(section, "options") != 0) { if(section && strcmp(section, "options") != 0) {
alpm_db_register_sync(handle, section, PM_PGP_VERIFY_OPTIONAL); alpm_db_register_sync(handle, section, level);
} }
} }
} }

View File

@ -148,10 +148,11 @@ static int check_syncdbs(alpm_list_t *dbnames) {
int ret = 0; int ret = 0;
alpm_db_t *db = NULL; alpm_db_t *db = NULL;
alpm_list_t *i, *pkglist, *syncpkglist = NULL; alpm_list_t *i, *pkglist, *syncpkglist = NULL;
const alpm_siglevel_t level = ALPM_SIG_DATABASE | ALPM_SIG_DATABASE_OPTIONAL;
for(i = dbnames; i; i = alpm_list_next(i)) { for(i = dbnames; i; i = alpm_list_next(i)) {
char *dbname = alpm_list_getdata(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) { if(db == NULL) {
fprintf(stderr, "error: could not register sync database (%s)\n", fprintf(stderr, "error: could not register sync database (%s)\n",
alpm_strerror(alpm_errno(handle))); alpm_strerror(alpm_errno(handle)));

View File

@ -43,6 +43,7 @@ int main(int argc, char *argv[])
alpm_handle_t *handle; alpm_handle_t *handle;
enum _alpm_errno_t err; enum _alpm_errno_t err;
alpm_pkg_t *pkg = NULL; alpm_pkg_t *pkg = NULL;
const alpm_siglevel_t level = ALPM_SIG_PACKAGE | ALPM_SIG_PACKAGE_OPTIONAL;
if(argc != 2) { if(argc != 2) {
fprintf(stderr, "usage: %s <package file>\n", BASENAME); 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 */ /* let us get log messages from libalpm */
alpm_option_set_logcb(handle, output_cb); 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) { || pkg == NULL) {
err = alpm_errno(handle); err = alpm_errno(handle);
switch(err) { switch(err) {