From 721137fe0c5dde2fd6bb3624df67966b0443e68d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Tue, 31 Jan 2012 15:49:04 +0200 Subject: [PATCH] pkg, db: fix signature checking for files without control part Also clean up handling of signature failures for index files. (cherry picked from commit 304dc4a69234b4161e8b34b34dc92ebfa9beac25) (cherry picked from commit b7f58c960d3882bab492e6722a92403d649db416) Conflicts: src/apk_database.h src/database.c --- src/apk_database.h | 2 +- src/database.c | 43 ++++++++++++++++++++++--------------------- src/package.c | 31 ++++++++++++++++++++++++------- 3 files changed, 47 insertions(+), 29 deletions(-) diff --git a/src/apk_database.h b/src/apk_database.h index 8436d35..b169d22 100644 --- a/src/apk_database.h +++ b/src/apk_database.h @@ -104,7 +104,7 @@ struct apk_database { int root_fd, lock_fd, cache_fd, cachetmp_fd, keys_fd; unsigned name_id, num_repos; const char *cache_dir, *arch; - unsigned int local_repos; + unsigned int local_repos, bad_repos; int permanent : 1; int compat_newfeatures : 1; int compat_notinstallable : 1; diff --git a/src/database.c b/src/database.c index 70e4820..98b5de4 100644 --- a/src/database.c +++ b/src/database.c @@ -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 apk_package *pkg; struct apk_installed_package *ipkg; - struct apk_db_file *file; apk_blob_t token = APK_BLOB_STR("\n"), line, bdir, bfile; pkg = apk_pkg_new(); @@ -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); 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) struct apk_bstream *bs; struct stat64 st; apk_blob_t blob; - int r, rr = 0; + int r; memset(db, 0, sizeof(*db)); if (apk_flags & APK_SIMULATE) { @@ -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)) { - list_for_each_entry(repo, &dbopts->repository_list, list) { - r = apk_db_add_repository(db, APK_BLOB_STR(repo->url)); - rr = r ?: rr; - } + list_for_each_entry(repo, &dbopts->repository_list, list) + apk_db_add_repository(db, APK_BLOB_STR(repo->url)); blob = apk_blob_from_file( db->root_fd, dbopts->repositories_file ?: "etc/apk/repositories"); if (!APK_BLOB_IS_NULL(blob)) { - r = apk_blob_for_each_segment( + apk_blob_for_each_segment( blob, "\n", apk_db_add_repository, db); - rr = r ?: rr; free(blob.ptr); } if (apk_flags & APK_UPDATE_CACHE) apk_db_index_write_nr_cache(db); } - if (rr != 0) { - r = rr; + if (db->bad_repos && !(apk_flags & APK_FORCE)) { + apk_error("Aborting due to some repositories failed to load. Use --force to ignore this error."); + r = -EBADMSG; goto ret_r; } @@ -1209,7 +1206,7 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts) "might not function properly"); } - return rr; + return 0; ret_errno: r = -errno; @@ -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 }, .csum.type = APK_CHECKSUM_SHA1, }; - unsigned int repos = pkg->repos; + unsigned int repos = pkg->repos & ~(db->bad_repos); int i; /* Always prefer local repositories */ @@ -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); is->close(is); apk_sign_ctx_free(&ctx.sctx); - if (ctx.found == 0) + + if (r >= 0 && ctx.found == 0) r = -ENOMSG; } else { 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) targz = 0; } } - if (bs == NULL) { - apk_warning("Failed to open index for %s", repo->url); - return 0; + if (bs != NULL) + r = load_index(db, bs, targz, r); + 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); - if (r != 0) - apk_error("%s: Bad repository signature", repo->url); - return r; + return 0; } static void extract_cb(void *_ctx, size_t progress) diff --git a/src/package.c b/src/package.c index 55dc5aa..4ee9a51 100644 --- a/src/package.c +++ b/src/package.c @@ -410,16 +410,35 @@ void apk_sign_ctx_free(struct apk_sign_ctx *ctx) 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, const struct apk_file_info *fi, struct apk_istream *is) { + int r; + if (ctx->data_started) return 1; if (fi->name[0] != '.' || strchr(fi->name, '/') != NULL) { ctx->data_started = 1; ctx->control_started = 1; + r = check_signing_key_trust(ctx); + if (r < 0) + return r; return 1; } @@ -446,7 +465,7 @@ int apk_sign_ctx_process_file(struct apk_sign_ctx *ctx, if (strncmp(&fi->name[6], "RSA.", 4) == 0 || strncmp(&fi->name[6], "DSA.", 4) == 0) { int fd = openat(ctx->keys_fd, &fi->name[10], O_RDONLY|O_CLOEXEC); - BIO *bio; + BIO *bio; if (fd < 0) return 0; @@ -557,15 +576,13 @@ int apk_sign_ctx_mpart_cb(void *ctx, int part, apk_blob_t data) return 0; } + r = check_signing_key_trust(sctx); + if (r < 0) + return r; + 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; - } - r = EVP_VerifyFinal(&sctx->mdctx, (unsigned char *) sctx->signature.data.ptr, sctx->signature.data.len, -- GitLab