diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c index ef0f1ef4..5477eff4 100644 --- a/lib/libalpm/be_sync.c +++ b/lib/libalpm/be_sync.c @@ -70,7 +70,6 @@ static int sync_db_validate(alpm_db_t *db) { alpm_siglevel_t level; const char *dbpath; - alpm_siglist_t *siglist; if(db->status & DB_STATUS_VALID || db->status & DB_STATUS_MISSING) { return 0; @@ -101,16 +100,26 @@ static int sync_db_validate(alpm_db_t *db) level = alpm_db_get_siglevel(db); if(level & ALPM_SIG_DATABASE) { - if(_alpm_check_pgp_helper(db->handle, dbpath, NULL, + int retry, ret; + do { + retry = 0; + alpm_siglist_t *siglist; + ret = _alpm_check_pgp_helper(db->handle, dbpath, NULL, level & ALPM_SIG_DATABASE_OPTIONAL, level & ALPM_SIG_DATABASE_MARGINAL_OK, - level & ALPM_SIG_DATABASE_UNKNOWN_OK, &siglist)) { - db->handle->pm_errno = ALPM_ERR_DB_INVALID_SIG; + level & ALPM_SIG_DATABASE_UNKNOWN_OK, &siglist); + if(ret) { + retry = _alpm_process_siglist(db->handle, db->treename, siglist, + level & ALPM_SIG_DATABASE_OPTIONAL, level & ALPM_SIG_DATABASE_MARGINAL_OK, + level & ALPM_SIG_DATABASE_UNKNOWN_OK); + } alpm_siglist_cleanup(siglist); free(siglist); + } while(retry); + + if(ret) { + db->handle->pm_errno = ALPM_ERR_DB_INVALID_SIG; return 1; } - alpm_siglist_cleanup(siglist); - free(siglist); } valid: diff --git a/lib/libalpm/signing.c b/lib/libalpm/signing.c index 7e05a237..e1b6452c 100644 --- a/lib/libalpm/signing.c +++ b/lib/libalpm/signing.c @@ -507,6 +507,69 @@ int _alpm_check_pgp_helper(alpm_handle_t *handle, const char *path, return ret; } +int _alpm_process_siglist(alpm_handle_t *handle, const char *identifier, + alpm_siglist_t *siglist, int optional, int marginal, int unknown) +{ + size_t i; + int retry = 0; + + if(!optional && siglist->count == 0) { + _alpm_log(handle, ALPM_LOG_ERROR, + _("%s: missing required signature\n"), identifier); + } + + for(i = 0; i < siglist->count; i++) { + alpm_sigresult_t *result = siglist->results + i; + const char *name = result->key.uid ? result->key.uid : result->key.fingerprint; + switch(result->status) { + case ALPM_SIGSTATUS_VALID: + case ALPM_SIGSTATUS_KEY_EXPIRED: + switch(result->validity) { + case ALPM_SIGVALIDITY_FULL: + break; + case ALPM_SIGVALIDITY_MARGINAL: + if(!marginal) { + _alpm_log(handle, ALPM_LOG_ERROR, + _("%s: signature from \"%s\" is marginal trust\n"), + identifier, name); + } + break; + case ALPM_SIGVALIDITY_UNKNOWN: + if(!unknown) { + _alpm_log(handle, ALPM_LOG_ERROR, + _("%s: signature from \"%s\" is unknown trust\n"), + identifier, name); + } + break; + case ALPM_SIGVALIDITY_NEVER: + _alpm_log(handle, ALPM_LOG_ERROR, + _("%s: signature from \"%s\" should never be trusted\n"), + identifier, name); + break; + } + break; + case ALPM_SIGSTATUS_KEY_UNKNOWN: + /* TODO import key here */ + _alpm_log(handle, ALPM_LOG_ERROR, + _("%s: key \"%s\" is unknown\n"), + identifier, name); + break; + case ALPM_SIGSTATUS_SIG_EXPIRED: + _alpm_log(handle, ALPM_LOG_ERROR, + _("%s: signature from \"%s\" is expired\n"), + identifier, name); + break; + case ALPM_SIGSTATUS_INVALID: + _alpm_log(handle, ALPM_LOG_ERROR, + _("%s: signature from \"%s\" is invalid\n"), + identifier, name); + break; + } + } + + return retry; +} + /** * Check the PGP signature for the given package file. * @param pkg the package to check diff --git a/lib/libalpm/signing.h b/lib/libalpm/signing.h index ee4a94a0..315d6059 100644 --- a/lib/libalpm/signing.h +++ b/lib/libalpm/signing.h @@ -24,9 +24,12 @@ char *_alpm_sigpath(alpm_handle_t *handle, const char *path); int _alpm_gpgme_checksig(alpm_handle_t *handle, const char *path, const char *base64_sig, alpm_siglist_t *result); + int _alpm_check_pgp_helper(alpm_handle_t *handle, const char *path, const char *base64_sig, int optional, int marginal, int unknown, alpm_siglist_t **sigdata); +int _alpm_process_siglist(alpm_handle_t *handle, const char *identifier, + alpm_siglist_t *siglist, int optional, int marginal, int unknown); #endif /* _ALPM_SIGNING_H */