[pacman-dev] [RFC PATCH 0/2] Improve sync db signature error messages
Currently we always say "Invalid or corrupt database" when database signature checking fails. This is particularly confusing when there is not signature. Also, we immediately verify databases at the start of the transaction which potentially results in (invalid) error messages being output that may be fixed when the sync database gets updated. I'm not 100% convinced this is the right way to fix this... Allan McRae (2): Provide a mechanism to skip validation of sync repos Provide more information for database signature failures lib/libalpm/alpm.h | 4 +++- lib/libalpm/be_sync.c | 20 ++++++++++++++++---- lib/libalpm/db.c | 4 ++-- lib/libalpm/db.h | 3 ++- lib/libalpm/error.c | 2 ++ src/pacman/conf.c | 2 +- src/util/cleanupdelta.c | 2 +- src/util/pactree.c | 2 +- src/util/testdb.c | 2 +- 9 files changed, 29 insertions(+), 12 deletions(-) -- 1.8.3.3
We often know when we initially register a sync database that it is scheduled to be updated. In particular, if the current copy of the sync database is invalid but we are refreshing it, there is no need to output error messages before updating. Signed-off-by: Allan McRae <allan@archlinux.org> --- lib/libalpm/alpm.h | 3 ++- lib/libalpm/be_sync.c | 6 ++++-- lib/libalpm/db.c | 4 ++-- lib/libalpm/db.h | 2 +- src/pacman/conf.c | 2 +- src/util/cleanupdelta.c | 2 +- src/util/pactree.c | 2 +- src/util/testdb.c | 2 +- 8 files changed, 13 insertions(+), 10 deletions(-) diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index c6d97c5..28608bd 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -626,10 +626,11 @@ alpm_list_t *alpm_get_syncdbs(alpm_handle_t *handle); * @param treename the name of the sync repository * @param level what level of signature checking to perform on the * database; note that this must be a '.sig' file type verification + * @param skip skip initial validation of sync dbs * @return an alpm_db_t* on success (the value), NULL on error */ alpm_db_t *alpm_register_syncdb(alpm_handle_t *handle, const char *treename, - alpm_siglevel_t level); + alpm_siglevel_t level, int skip); /** Unregister all package databases. * @param handle the context handle diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c index 0b99684..65d2331 100644 --- a/lib/libalpm/be_sync.c +++ b/lib/libalpm/be_sync.c @@ -683,7 +683,7 @@ struct db_operations sync_db_ops = { }; alpm_db_t *_alpm_db_register_sync(alpm_handle_t *handle, const char *treename, - alpm_siglevel_t level) + alpm_siglevel_t level, int skip) { alpm_db_t *db; @@ -703,7 +703,9 @@ alpm_db_t *_alpm_db_register_sync(alpm_handle_t *handle, const char *treename, db->handle = handle; db->siglevel = level; - sync_db_validate(db); + if(!skip) { + sync_db_validate(db); + } handle->dbs_sync = alpm_list_add(handle->dbs_sync, db); return db; diff --git a/lib/libalpm/db.c b/lib/libalpm/db.c index 3a04a87..6fc1d5e 100644 --- a/lib/libalpm/db.c +++ b/lib/libalpm/db.c @@ -44,7 +44,7 @@ /** Register a sync database of packages. */ alpm_db_t SYMEXPORT *alpm_register_syncdb(alpm_handle_t *handle, - const char *treename, alpm_siglevel_t level) + const char *treename, alpm_siglevel_t level, int skip) { /* Sanity checks */ CHECK_HANDLE(handle, return NULL); @@ -53,7 +53,7 @@ alpm_db_t SYMEXPORT *alpm_register_syncdb(alpm_handle_t *handle, /* Do not register a database if a transaction is on-going */ ASSERT(handle->trans == NULL, RET_ERR(handle, ALPM_ERR_TRANS_NOT_NULL, NULL)); - return _alpm_db_register_sync(handle, treename, level); + return _alpm_db_register_sync(handle, treename, level, skip); } /* Helper function for alpm_db_unregister{_all} */ diff --git a/lib/libalpm/db.h b/lib/libalpm/db.h index 8029293..e4d9f71 100644 --- a/lib/libalpm/db.h +++ b/lib/libalpm/db.h @@ -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_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_siglevel_t level); + alpm_siglevel_t level, int skip); void _alpm_db_unregister(alpm_db_t *db); /* be_*.c, backend specific calls */ diff --git a/src/pacman/conf.c b/src/pacman/conf.c index ab6dae0..aa27559 100644 --- a/src/pacman/conf.c +++ b/src/pacman/conf.c @@ -774,7 +774,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_register_syncdb(config->handle, section->name, section->siglevel); + db = alpm_register_syncdb(config->handle, section->name, section->siglevel, config->op_s_upgrade); if(db == NULL) { pm_printf(ALPM_LOG_ERROR, _("could not register '%s' database (%s)\n"), section->name, alpm_strerror(alpm_errno(config->handle))); diff --git a/src/util/cleanupdelta.c b/src/util/cleanupdelta.c index 4f34435..a323533 100644 --- a/src/util/cleanupdelta.c +++ b/src/util/cleanupdelta.c @@ -74,7 +74,7 @@ static void checkdbs(alpm_list_t *dbnames) for(i = dbnames; i; i = alpm_list_next(i)) { const char *dbname = i->data; - db = alpm_register_syncdb(handle, dbname, level); + db = alpm_register_syncdb(handle, dbname, level, 0); if(db == NULL) { fprintf(stderr, "error: could not register sync database '%s' (%s)\n", dbname, alpm_strerror(alpm_errno(handle))); diff --git a/src/util/pactree.c b/src/util/pactree.c index 4ca41a0..22aaff8 100644 --- a/src/util/pactree.c +++ b/src/util/pactree.c @@ -211,7 +211,7 @@ static int register_syncs(void) section = strndup(&line[1], linelen - 2); if(section && strcmp(section, "options") != 0) { - alpm_register_syncdb(handle, section, level); + alpm_register_syncdb(handle, section, level, 0); } } } diff --git a/src/util/testdb.c b/src/util/testdb.c index 0ca7ffc..33dd623 100644 --- a/src/util/testdb.c +++ b/src/util/testdb.c @@ -225,7 +225,7 @@ static int check_syncdbs(alpm_list_t *dbnames) for(i = dbnames; i; i = alpm_list_next(i)) { const char *dbname = i->data; - db = alpm_register_syncdb(handle, dbname, level); + db = alpm_register_syncdb(handle, dbname, level, 0); if(db == NULL) { fprintf(stderr, "error: could not register sync database (%s)\n", alpm_strerror(alpm_errno(handle))); -- 1.8.3.3
Distinguish between database that failed to verify and that are missing. Signed-off-by: Allan McRae <allan@archlinux.org> --- lib/libalpm/alpm.h | 1 + lib/libalpm/be_sync.c | 14 ++++++++++++-- lib/libalpm/db.h | 1 + lib/libalpm/error.c | 2 ++ src/pacman/conf.c | 2 +- 5 files changed, 17 insertions(+), 3 deletions(-) diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 28608bd..b8aab76 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -1246,6 +1246,7 @@ typedef enum _alpm_errno_t { ALPM_ERR_DB_NOT_FOUND, ALPM_ERR_DB_INVALID, ALPM_ERR_DB_INVALID_SIG, + ALPM_ERR_DB_MISSING_SIG, ALPM_ERR_DB_VERSION, ALPM_ERR_DB_WRITE, ALPM_ERR_DB_REMOVE, diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c index 65d2331..72589ef 100644 --- a/lib/libalpm/be_sync.c +++ b/lib/libalpm/be_sync.c @@ -76,8 +76,13 @@ static int sync_db_validate(alpm_db_t *db) if(db->status & DB_STATUS_VALID || db->status & DB_STATUS_MISSING) { return 0; } + if(db->status & DB_STATUS_INVALID) { - db->handle->pm_errno = ALPM_ERR_DB_INVALID_SIG; + if(db->status & DB_STATUS_MISSING_SIG) { + db->handle->pm_errno = ALPM_ERR_DB_MISSING_SIG; + } else { + db->handle->pm_errno = ALPM_ERR_DB_INVALID_SIG; + } return -1; } @@ -121,7 +126,12 @@ static int sync_db_validate(alpm_db_t *db) if(ret) { db->status &= ~DB_STATUS_VALID; db->status |= DB_STATUS_INVALID; - db->handle->pm_errno = ALPM_ERR_DB_INVALID_SIG; + if(db->handle->pm_errno == ALPM_ERR_SIG_MISSING) { + db->status |= DB_STATUS_MISSING_SIG; + db->handle->pm_errno = ALPM_ERR_DB_MISSING_SIG; + } else { + db->handle->pm_errno = ALPM_ERR_DB_INVALID_SIG; + } return 1; } } diff --git a/lib/libalpm/db.h b/lib/libalpm/db.h index e4d9f71..909c66f 100644 --- a/lib/libalpm/db.h +++ b/lib/libalpm/db.h @@ -48,6 +48,7 @@ enum _alpm_dbstatus_t { DB_STATUS_INVALID = (1 << 1), DB_STATUS_EXISTS = (1 << 2), DB_STATUS_MISSING = (1 << 3), + DB_STATUS_MISSING_SIG = (1 << 4), DB_STATUS_LOCAL = (1 << 10), DB_STATUS_PKGCACHE = (1 << 11), diff --git a/lib/libalpm/error.c b/lib/libalpm/error.c index 8622180..bf085e4 100644 --- a/lib/libalpm/error.c +++ b/lib/libalpm/error.c @@ -72,6 +72,8 @@ const char SYMEXPORT *alpm_strerror(alpm_errno_t err) return _("invalid or corrupted database"); case ALPM_ERR_DB_INVALID_SIG: return _("invalid or corrupted database (PGP signature)"); + case ALPM_ERR_DB_MISSING_SIG: + return _("database missing required signature"); case ALPM_ERR_DB_VERSION: return _("database is incorrect version"); case ALPM_ERR_DB_WRITE: diff --git a/src/pacman/conf.c b/src/pacman/conf.c index aa27559..42b59bd 100644 --- a/src/pacman/conf.c +++ b/src/pacman/conf.c @@ -774,7 +774,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_register_syncdb(config->handle, section->name, section->siglevel, config->op_s_upgrade); + db = alpm_register_syncdb(config->handle, section->name, section->siglevel, config->op_s_sync); if(db == NULL) { pm_printf(ALPM_LOG_ERROR, _("could not register '%s' database (%s)\n"), section->name, alpm_strerror(alpm_errno(config->handle))); -- 1.8.3.3
participants (1)
-
Allan McRae