diff options
Diffstat (limited to 'lib/libalpm/be_sync.c')
-rw-r--r-- | lib/libalpm/be_sync.c | 56 |
1 files changed, 55 insertions, 1 deletions
diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c index e5fc6a70..2cf90544 100644 --- a/lib/libalpm/be_sync.c +++ b/lib/libalpm/be_sync.c @@ -20,7 +20,9 @@ #include "config.h" +#include <errno.h> #include <sys/stat.h> +#include <unistd.h> /* libarchive */ #include <archive.h> @@ -65,6 +67,37 @@ static char *get_sync_dir(pmhandle_t *handle) return syncpath; } +static int sync_db_validate(pmdb_t *db) +{ + /* this takes into account the default verification level if UNKNOWN + * was assigned to this db */ + pgp_verify_t check_sig = _alpm_db_get_sigverify_level(db); + + if(check_sig != PM_PGP_VERIFY_NEVER) { + int ret; + const char *dbpath = _alpm_db_path(db); + if(!dbpath) { + /* pm_errno set in _alpm_db_path() */ + return -1; + } + + /* we can skip any validation if the database doesn't exist */ + if(access(dbpath, R_OK) != 0 && errno == ENOENT) { + return 0; + } + + _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); + } + } + + return 0; +} + /** Update a package database * * An update of the package database \a db will be attempted. Unless @@ -144,6 +177,15 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db) if(ret == 0 && (check_sig == PM_PGP_VERIFY_ALWAYS || check_sig == PM_PGP_VERIFY_OPTIONAL)) { + /* an existing sig file is no good at this point */ + char *sigpath = _alpm_db_sig_path(db); + if(!sigpath) { + ret = -1; + break; + } + unlink(sigpath); + free(sigpath); + int errors_ok = (check_sig == PM_PGP_VERIFY_OPTIONAL); /* if we downloaded a DB, we want the .sig from the same server */ snprintf(fileurl, len, "%s/%s.db.sig", server, db->treename); @@ -173,6 +215,11 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db) /* Cache needs to be rebuilt */ _alpm_db_free_pkgcache(db); + if(sync_db_validate(db)) { + /* pm_errno should be set */ + ret = -1; + } + cleanup: free(syncpath); @@ -523,7 +570,8 @@ struct db_operations sync_db_ops = { .version = sync_db_version, }; -pmdb_t *_alpm_db_register_sync(pmhandle_t *handle, const char *treename) +pmdb_t *_alpm_db_register_sync(pmhandle_t *handle, const char *treename, + pgp_verify_t level) { pmdb_t *db; @@ -535,6 +583,12 @@ pmdb_t *_alpm_db_register_sync(pmhandle_t *handle, const char *treename) } db->ops = &sync_db_ops; db->handle = handle; + db->pgp_verify = level; + + if(sync_db_validate(db)) { + _alpm_db_free(db); + return NULL; + } handle->dbs_sync = alpm_list_add(handle->dbs_sync, db); return db; |