summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/libalpm/be_sync.c21
-rw-r--r--lib/libalpm/signing.c63
-rw-r--r--lib/libalpm/signing.h3
3 files changed, 81 insertions, 6 deletions
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 */