summaryrefslogtreecommitdiff
path: root/lib/libalpm/be_sync.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libalpm/be_sync.c')
-rw-r--r--lib/libalpm/be_sync.c74
1 files changed, 57 insertions, 17 deletions
diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c
index c2c62aa2..d4841854 100644
--- a/lib/libalpm/be_sync.c
+++ b/lib/libalpm/be_sync.c
@@ -20,8 +20,7 @@
#include "config.h"
-#include <errno.h>
-#include <limits.h>
+#include <sys/stat.h>
/* libarchive */
#include <archive.h>
@@ -85,6 +84,7 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db)
size_t len;
int ret;
mode_t oldmask;
+ pgp_verify_t check_sig;
ALPM_LOG_FUNC;
@@ -126,24 +126,65 @@ 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;
+ }
+
+ check_sig = _alpm_db_get_sigverify_level(db);
+
+ /* Download and check the signature of the database if needed */
+ if(check_sig != PM_PGP_VERIFY_NEVER) {
+ char *sigfile, *sigfilepath;
+ int sigret;
+
+ len = strlen(dbfile) + 5;
+ MALLOC(sigfile, len, RET_ERR(PM_ERR_MEMORY, -1));
+ sprintf(sigfile, "%s.sig", dbfile);
+
+ /* prevent old signature being used if the following download fails */
+ len = strlen(syncpath) + strlen(sigfile) + 1;
+ MALLOC(sigfilepath, len, RET_ERR(PM_ERR_MEMORY, -1));
+ sprintf(sigfilepath, "%s%s", syncpath, sigfile);
+ _alpm_rmrf(sigfilepath);
+ free(sigfilepath);
+
+ sigret = _alpm_download_single_file(sigfile, db->servers, syncpath, 0);
+ free(sigfile);
+
+ if(sigret == -1 && check_sig == 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((check_sig == PM_PGP_VERIFY_ALWAYS && sigret != 0) ||
+ (check_sig == 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 */
@@ -206,7 +247,7 @@ static size_t estimate_package_count(struct stat *st, struct archive *archive)
/* assume it is at least somewhat compressed */
per_package = 200;
}
- return((size_t)(st->st_size / per_package) + 1);
+ return (size_t)((st->st_size / per_package) + 1);
}
static int sync_db_populate(pmdb_t *db)
@@ -305,7 +346,7 @@ static int sync_db_populate(pmdb_t *db)
}
archive_read_finish(archive);
- return(count);
+ return count;
}
#define READ_NEXT(s) do { \
@@ -345,7 +386,7 @@ static int sync_db_read(pmdb_t *db, struct archive *archive,
}
if(entryname == NULL) {
_alpm_log(PM_LOG_DEBUG, "invalid archive entry provided to _alpm_sync_db_read, skipping\n");
- return(-1);
+ return -1;
}
_alpm_log(PM_LOG_FUNCTION, "loading package data from archive entry %s\n",
@@ -376,7 +417,7 @@ static int sync_db_read(pmdb_t *db, struct archive *archive,
if(pkg == NULL) {
_alpm_log(PM_LOG_DEBUG, "package %s not found in %s sync database",
pkgname, db->treename);
- return(-1);
+ return -1;
}
if(strcmp(filename, "desc") == 0 || strcmp(filename, "depends") == 0
@@ -433,8 +474,7 @@ static int sync_db_read(pmdb_t *db, struct archive *archive,
/* we don't do anything with this value right now */
READ_NEXT(line);
} else if(strcmp(line, "%PGPSIG%") == 0) {
- /* we don't do anything with this value right now */
- READ_NEXT(line);
+ READ_AND_STORE(pkg->pgpsig.base64_data);
} else if(strcmp(line, "%REPLACES%") == 0) {
READ_AND_STORE_ALL(pkg->replaces);
} else if(strcmp(line, "%DEPENDS%") == 0) {
@@ -469,12 +509,12 @@ static int sync_db_read(pmdb_t *db, struct archive *archive,
error:
FREE(pkgname);
/* TODO: return 0 always? */
- return(0);
+ return 0;
}
static int sync_db_version(pmdb_t *db)
{
- return(2);
+ return 2;
}
struct db_operations sync_db_ops = {
@@ -507,7 +547,7 @@ pmdb_t *_alpm_db_register_sync(const char *treename)
db->ops = &sync_db_ops;
handle->dbs_sync = alpm_list_add(handle->dbs_sync, db);
- return(db);
+ return db;
}