Commit 721137fe authored by Timo Teräs's avatar Timo Teräs

pkg, db: fix signature checking for files without control part

Also clean up handling of signature failures for index files.
(cherry picked from commit 304dc4a6)
(cherry picked from commit b7f58c96)

Conflicts:

	src/apk_database.h
	src/database.c
parent 8bec21e3
...@@ -104,7 +104,7 @@ struct apk_database { ...@@ -104,7 +104,7 @@ struct apk_database {
int root_fd, lock_fd, cache_fd, cachetmp_fd, keys_fd; int root_fd, lock_fd, cache_fd, cachetmp_fd, keys_fd;
unsigned name_id, num_repos; unsigned name_id, num_repos;
const char *cache_dir, *arch; const char *cache_dir, *arch;
unsigned int local_repos; unsigned int local_repos, bad_repos;
int permanent : 1; int permanent : 1;
int compat_newfeatures : 1; int compat_newfeatures : 1;
int compat_notinstallable : 1; int compat_notinstallable : 1;
......
...@@ -532,7 +532,6 @@ int apk_db_read_overlay(struct apk_database *db, struct apk_bstream *bs) ...@@ -532,7 +532,6 @@ int apk_db_read_overlay(struct apk_database *db, struct apk_bstream *bs)
struct hlist_node **diri_node = NULL, **file_diri_node = NULL; struct hlist_node **diri_node = NULL, **file_diri_node = NULL;
struct apk_package *pkg; struct apk_package *pkg;
struct apk_installed_package *ipkg; struct apk_installed_package *ipkg;
struct apk_db_file *file;
apk_blob_t token = APK_BLOB_STR("\n"), line, bdir, bfile; apk_blob_t token = APK_BLOB_STR("\n"), line, bdir, bfile;
pkg = apk_pkg_new(); pkg = apk_pkg_new();
...@@ -558,7 +557,7 @@ int apk_db_read_overlay(struct apk_database *db, struct apk_bstream *bs) ...@@ -558,7 +557,7 @@ int apk_db_read_overlay(struct apk_database *db, struct apk_bstream *bs)
diri = apk_db_diri_new(db, pkg, bdir, &diri_node); diri = apk_db_diri_new(db, pkg, bdir, &diri_node);
file_diri_node = &diri->owned_files.first; file_diri_node = &diri->owned_files.first;
} }
file = apk_db_file_get(db, diri, bfile, &file_diri_node); apk_db_file_get(db, diri, bfile, &file_diri_node);
} }
} }
...@@ -1059,7 +1058,7 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts) ...@@ -1059,7 +1058,7 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts)
struct apk_bstream *bs; struct apk_bstream *bs;
struct stat64 st; struct stat64 st;
apk_blob_t blob; apk_blob_t blob;
int r, rr = 0; int r;
memset(db, 0, sizeof(*db)); memset(db, 0, sizeof(*db));
if (apk_flags & APK_SIMULATE) { if (apk_flags & APK_SIMULATE) {
...@@ -1180,25 +1179,23 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts) ...@@ -1180,25 +1179,23 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts)
} }
} }
if (!(dbopts->open_flags & APK_OPENF_NO_SYS_REPOS)) { if (!(dbopts->open_flags & APK_OPENF_NO_SYS_REPOS)) {
list_for_each_entry(repo, &dbopts->repository_list, list) { list_for_each_entry(repo, &dbopts->repository_list, list)
r = apk_db_add_repository(db, APK_BLOB_STR(repo->url)); apk_db_add_repository(db, APK_BLOB_STR(repo->url));
rr = r ?: rr;
}
blob = apk_blob_from_file( blob = apk_blob_from_file(
db->root_fd, db->root_fd,
dbopts->repositories_file ?: "etc/apk/repositories"); dbopts->repositories_file ?: "etc/apk/repositories");
if (!APK_BLOB_IS_NULL(blob)) { if (!APK_BLOB_IS_NULL(blob)) {
r = apk_blob_for_each_segment( apk_blob_for_each_segment(
blob, "\n", blob, "\n",
apk_db_add_repository, db); apk_db_add_repository, db);
rr = r ?: rr;
free(blob.ptr); free(blob.ptr);
} }
if (apk_flags & APK_UPDATE_CACHE) if (apk_flags & APK_UPDATE_CACHE)
apk_db_index_write_nr_cache(db); apk_db_index_write_nr_cache(db);
} }
if (rr != 0) { if (db->bad_repos && !(apk_flags & APK_FORCE)) {
r = rr; apk_error("Aborting due to some repositories failed to load. Use --force to ignore this error.");
r = -EBADMSG;
goto ret_r; goto ret_r;
} }
...@@ -1209,7 +1206,7 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts) ...@@ -1209,7 +1206,7 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts)
"might not function properly"); "might not function properly");
} }
return rr; return 0;
ret_errno: ret_errno:
r = -errno; r = -errno;
...@@ -1462,7 +1459,7 @@ struct apk_repository *apk_db_select_repo(struct apk_database *db, ...@@ -1462,7 +1459,7 @@ struct apk_repository *apk_db_select_repo(struct apk_database *db,
0xf5,0xa7,0x0a,0x7c,0x17,0x26,0x69,0xb0,0x05,0x38 }, 0xf5,0xa7,0x0a,0x7c,0x17,0x26,0x69,0xb0,0x05,0x38 },
.csum.type = APK_CHECKSUM_SHA1, .csum.type = APK_CHECKSUM_SHA1,
}; };
unsigned int repos = pkg->repos; unsigned int repos = pkg->repos & ~(db->bad_repos);
int i; int i;
/* Always prefer local repositories */ /* Always prefer local repositories */
...@@ -1564,7 +1561,8 @@ static int load_index(struct apk_database *db, struct apk_bstream *bs, ...@@ -1564,7 +1561,8 @@ static int load_index(struct apk_database *db, struct apk_bstream *bs,
r = apk_tar_parse(is, load_apkindex, &ctx, FALSE, &db->id_cache); r = apk_tar_parse(is, load_apkindex, &ctx, FALSE, &db->id_cache);
is->close(is); is->close(is);
apk_sign_ctx_free(&ctx.sctx); apk_sign_ctx_free(&ctx.sctx);
if (ctx.found == 0)
if (r >= 0 && ctx.found == 0)
r = -ENOMSG; r = -ENOMSG;
} else { } else {
bs = apk_bstream_from_istream(apk_bstream_gunzip(bs)); bs = apk_bstream_from_istream(apk_bstream_gunzip(bs));
...@@ -1628,15 +1626,18 @@ int apk_db_add_repository(apk_database_t _db, apk_blob_t repository) ...@@ -1628,15 +1626,18 @@ int apk_db_add_repository(apk_database_t _db, apk_blob_t repository)
targz = 0; targz = 0;
} }
} }
if (bs == NULL) { if (bs != NULL)
apk_warning("Failed to open index for %s", repo->url); r = load_index(db, bs, targz, r);
return 0; else
r = -ENOENT;
if (r != 0) {
apk_warning("Ignoring %s: %s", buf, apk_error_str(r));
db->bad_repos |= BIT(r);
r = 0;
} }
r = load_index(db, bs, targz, r); return 0;
if (r != 0)
apk_error("%s: Bad repository signature", repo->url);
return r;
} }
static void extract_cb(void *_ctx, size_t progress) static void extract_cb(void *_ctx, size_t progress)
......
...@@ -410,16 +410,35 @@ void apk_sign_ctx_free(struct apk_sign_ctx *ctx) ...@@ -410,16 +410,35 @@ void apk_sign_ctx_free(struct apk_sign_ctx *ctx)
EVP_MD_CTX_cleanup(&ctx->mdctx); EVP_MD_CTX_cleanup(&ctx->mdctx);
} }
static int check_signing_key_trust(struct apk_sign_ctx *sctx)
{
switch (sctx->action) {
case APK_SIGN_VERIFY:
case APK_SIGN_VERIFY_AND_GENERATE:
if (sctx->signature.pkey == NULL) {
if (apk_flags & APK_ALLOW_UNTRUSTED)
break;
return -ENOKEY;
}
}
return 0;
}
int apk_sign_ctx_process_file(struct apk_sign_ctx *ctx, int apk_sign_ctx_process_file(struct apk_sign_ctx *ctx,
const struct apk_file_info *fi, const struct apk_file_info *fi,
struct apk_istream *is) struct apk_istream *is)
{ {
int r;
if (ctx->data_started) if (ctx->data_started)
return 1; return 1;
if (fi->name[0] != '.' || strchr(fi->name, '/') != NULL) { if (fi->name[0] != '.' || strchr(fi->name, '/') != NULL) {
ctx->data_started = 1; ctx->data_started = 1;
ctx->control_started = 1; ctx->control_started = 1;
r = check_signing_key_trust(ctx);
if (r < 0)
return r;
return 1; return 1;
} }
...@@ -446,7 +465,7 @@ int apk_sign_ctx_process_file(struct apk_sign_ctx *ctx, ...@@ -446,7 +465,7 @@ int apk_sign_ctx_process_file(struct apk_sign_ctx *ctx,
if (strncmp(&fi->name[6], "RSA.", 4) == 0 || if (strncmp(&fi->name[6], "RSA.", 4) == 0 ||
strncmp(&fi->name[6], "DSA.", 4) == 0) { strncmp(&fi->name[6], "DSA.", 4) == 0) {
int fd = openat(ctx->keys_fd, &fi->name[10], O_RDONLY|O_CLOEXEC); int fd = openat(ctx->keys_fd, &fi->name[10], O_RDONLY|O_CLOEXEC);
BIO *bio; BIO *bio;
if (fd < 0) if (fd < 0)
return 0; return 0;
...@@ -557,15 +576,13 @@ int apk_sign_ctx_mpart_cb(void *ctx, int part, apk_blob_t data) ...@@ -557,15 +576,13 @@ int apk_sign_ctx_mpart_cb(void *ctx, int part, apk_blob_t data)
return 0; return 0;
} }
r = check_signing_key_trust(sctx);
if (r < 0)
return r;
switch (sctx->action) { switch (sctx->action) {
case APK_SIGN_VERIFY: case APK_SIGN_VERIFY:
case APK_SIGN_VERIFY_AND_GENERATE: case APK_SIGN_VERIFY_AND_GENERATE:
if (sctx->signature.pkey == NULL) {
if (apk_flags & APK_ALLOW_UNTRUSTED)
break;
return -ENOKEY;
}
r = EVP_VerifyFinal(&sctx->mdctx, r = EVP_VerifyFinal(&sctx->mdctx,
(unsigned char *) sctx->signature.data.ptr, (unsigned char *) sctx->signature.data.ptr,
sctx->signature.data.len, sctx->signature.data.len,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment