summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllan McRae <allan@archlinux.org>2010-11-22 16:06:16 +1000
committerDan McGee <dan@archlinux.org>2011-03-23 22:58:00 -0500
commit38da050f31fad7fd9252cced698a66c3e3729d98 (patch)
tree3b444b86d7705f0e683e977af00876b79add83f1
parent9a3325a56db87cc8c6336225162daefcd190208f (diff)
downloadpacman-38da050f31fad7fd9252cced698a66c3e3729d98.tar.xz
Download and verify package database signatures
If signature verification is needed, attempt to download a signature file for a repo when it is updated. Return an error if unable to download signature only when checking is mandatory, or if signature is invalid. TODO: At the moment the database signature is only checked on download. Should we do anything with a database if it fails to be verified to prevent its future usage? Signed-off-by: Allan McRae <allan@archlinux.org>
-rw-r--r--lib/libalpm/be_sync.c44
1 files changed, 38 insertions, 6 deletions
diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c
index 5eec8a73..ed55b3bb 100644
--- a/lib/libalpm/be_sync.c
+++ b/lib/libalpm/be_sync.c
@@ -126,24 +126,56 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db)
}
ret = _alpm_download_single_file(dbfile, db->servers, syncpath, force);
- free(dbfile);
- free(syncpath);
- umask(oldmask);
if(ret == 1) {
/* files match, do nothing */
pm_errno = 0;
- return 1;
+ goto cleanup;
} else if(ret == -1) {
/* pm_errno was set by the download code */
_alpm_log(PM_LOG_DEBUG, "failed to sync db: %s\n", alpm_strerrorlast());
- return -1;
+ goto cleanup;
+ }
+
+ /* Download and check the signature of the database if needed */
+ if(db->pgp_verify != PM_PGP_VERIFY_NEVER) {
+ char *sigfile;
+ int sigret;
+
+ len = strlen(dbfile) + 5;
+ MALLOC(sigfile, len, RET_ERR(PM_ERR_MEMORY, -1));
+ sprintf(sigfile, "%s.sig", dbfile);
+
+ sigret = _alpm_download_single_file(sigfile, db->servers, syncpath, 1);
+ free(sigfile);
+
+ if(sigret == -1 && db->pgp_verify == PM_PGP_VERIFY_ALWAYS) {
+ _alpm_log(PM_LOG_ERROR, _("Failed to download signature for db: %s\n"),
+ alpm_strerrorlast());
+ pm_errno = PM_ERR_SIG_INVALID;
+ ret = -1;
+ goto cleanup;
+ }
+
+ sigret = alpm_db_check_pgp_signature(db);
+ if((db->pgp_verify == PM_PGP_VERIFY_ALWAYS && sigret != 0) ||
+ (db->pgp_verify == PM_PGP_VERIFY_OPTIONAL && sigret == 1)) {
+ /* pm_errno was set by the checking code */
+ /* TODO: should we just leave the unverified database */
+ ret = -1;
+ goto cleanup;
+ }
}
/* Cache needs to be rebuilt */
_alpm_db_free_pkgcache(db);
- return 0;
+cleanup:
+
+ free(dbfile);
+ free(syncpath);
+ umask(oldmask);
+ return ret;
}
/* Forward decl so I don't reorganize the whole file right now */