diff options
author | Timo Teras <timo.teras@iki.fi> | 2009-07-22 14:24:19 +0300 |
---|---|---|
committer | Timo Teras <timo.teras@iki.fi> | 2009-07-22 14:24:19 +0300 |
commit | 0a7991f70dcfe9f8e05f6a4a4a59af21be878915 (patch) | |
tree | 9c6ef07e6f594b524bd1fc4746a103ab3d93d926 | |
parent | 0dadc27ce1cfe84585a747d57e7d3bcafc1069eb (diff) | |
download | apk-tools-0a7991f70dcfe9f8e05f6a4a4a59af21be878915.tar.gz apk-tools-0a7991f70dcfe9f8e05f6a4a4a59af21be878915.tar.bz2 apk-tools-0a7991f70dcfe9f8e05f6a4a4a59af21be878915.tar.xz apk-tools-0a7991f70dcfe9f8e05f6a4a4a59af21be878915.zip |
various: misc fixes
- error codes for verification failure types
- fix some fdb corruption on file migration
- combine some dependency parsing code
- fix versioned dependencies
-rw-r--r-- | src/add.c | 11 | ||||
-rw-r--r-- | src/apk.c | 2 | ||||
-rw-r--r-- | src/apk_defines.h | 6 | ||||
-rw-r--r-- | src/apk_package.h | 8 | ||||
-rw-r--r-- | src/cache.c | 7 | ||||
-rw-r--r-- | src/database.c | 25 | ||||
-rw-r--r-- | src/package.c | 113 |
7 files changed, 88 insertions, 84 deletions
@@ -107,7 +107,7 @@ static int add_main(void *ctx, int argc, char **argv) apk_default_checksum(), &virtpkg->csum); virtpkg->version = strdup("0"); virtpkg->description = strdup("virtual meta package"); - virtdep = apk_dep_from_pkg(&db, virtpkg); + apk_dep_from_pkg(&virtdep, &db, virtpkg); virtdep.name->flags |= APK_NAME_TOPLEVEL | APK_NAME_VIRTUAL; virtpkg = apk_db_pkg_add(&db, virtpkg); } @@ -127,9 +127,12 @@ static int add_main(void *ctx, int argc, char **argv) goto err; } - dep = apk_dep_from_pkg(&db, pkg); - } else - dep = apk_dep_from_str(&db, argv[i]); + apk_dep_from_pkg(&dep, &db, pkg); + } else { + r = apk_dep_from_blob(&dep, &db, APK_BLOB_STR(argv[i])); + if (r != 0) + goto err; + } if (virtpkg) { apk_deps_add(&virtpkg->depends, &dep); @@ -363,7 +363,7 @@ int main(int argc, char **argv) } r = applet->main(ctx, argc, argv); - if (r == -100) + if (r == -EINVAL) return usage(applet); return r; } diff --git a/src/apk_defines.h b/src/apk_defines.h index c8a3622..d1f26d2 100644 --- a/src/apk_defines.h +++ b/src/apk_defines.h @@ -60,9 +60,9 @@ extern unsigned int apk_flags; #define APK_PREFER_AVAILABLE 0x0040 #define APK_UPDATE_CACHE 0x0080 -#define apk_error(args...) apk_log("ERROR: ", args); -#define apk_warning(args...) if (apk_verbosity > 0) { apk_log("WARNING: ", args); } -#define apk_message(args...) if (apk_verbosity > 0) { apk_log(NULL, args); } +#define apk_error(args...) do { apk_log("ERROR: ", args); } while (0) +#define apk_warning(args...) do { if (apk_verbosity > 0) { apk_log("WARNING: ", args); } } while (0) +#define apk_message(args...) do { if (apk_verbosity > 0) { apk_log(NULL, args); } } while (0) void apk_log(const char *prefix, const char *format, ...); diff --git a/src/apk_package.h b/src/apk_package.h index c816633..9f74deb 100644 --- a/src/apk_package.h +++ b/src/apk_package.h @@ -105,6 +105,10 @@ int apk_sign_ctx_verify_tar(void *ctx, const struct apk_file_info *fi, struct apk_istream *is); int apk_sign_ctx_mpart_cb(void *ctx, int part, apk_blob_t blob); +int apk_dep_from_blob(struct apk_dependency *dep, struct apk_database *db, + apk_blob_t blob); +void apk_dep_from_pkg(struct apk_dependency *dep, struct apk_database *db, + struct apk_package *pkg); int apk_deps_add(struct apk_dependency_array **depends, struct apk_dependency *dep); void apk_deps_del(struct apk_dependency_array **deps, @@ -112,6 +116,7 @@ void apk_deps_del(struct apk_dependency_array **deps, void apk_deps_parse(struct apk_database *db, struct apk_dependency_array **depends, apk_blob_t blob); + int apk_deps_write(struct apk_dependency_array *deps, struct apk_ostream *os); int apk_script_type(const char *name); @@ -136,7 +141,4 @@ int apk_pkg_write_index_entry(struct apk_package *pkg, struct apk_ostream *os); int apk_pkg_version_compare(struct apk_package *a, struct apk_package *b); -struct apk_dependency apk_dep_from_str(struct apk_database *db, char *str); -struct apk_dependency apk_dep_from_pkg(struct apk_database *db, - struct apk_package *pkg); #endif diff --git a/src/cache.c b/src/cache.c index 7b5b7f1..ac2281e 100644 --- a/src/cache.c +++ b/src/cache.c @@ -9,9 +9,10 @@ * by the Free Software Foundation. See http://www.gnu.org/ for details. */ +#include <errno.h> +#include <stdio.h> #include <dirent.h> #include <unistd.h> -#include <stdio.h> #include "apk_defines.h" #include "apk_applet.h" @@ -140,7 +141,7 @@ static int cache_main(void *ctx, int argc, char **argv) int r; if (argc != 1) - return -100; + return -EINVAL; if (strcmp(argv[0], "sync") == 0) actions = CACHE_CLEAN | CACHE_DOWNLOAD; @@ -149,7 +150,7 @@ static int cache_main(void *ctx, int argc, char **argv) else if (strcmp(argv[0], "download") == 0) actions = CACHE_DOWNLOAD; else - return -100; + return -EINVAL; r = apk_db_open(&db, apk_root, APK_OPENF_NO_SCRIPTS | APK_OPENF_NO_INSTALLED); diff --git a/src/database.c b/src/database.c index 2cad438..6138c5c 100644 --- a/src/database.c +++ b/src/database.c @@ -668,7 +668,7 @@ static int apk_db_read_state(struct apk_database *db, int flags) apk_deps_parse(db, &db->world, blob); free(blob.ptr); - for (i = 0; i < db->world->num; i++) + for (i = 0; db->world != NULL && i < db->world->num; i++) db->world->item[i].name->flags |= APK_NAME_TOPLEVEL; } @@ -868,12 +868,14 @@ int apk_db_write_config(struct apk_database *db) fchdir(db->root_fd); - os = apk_ostream_to_file("var/lib/apk/world", 0644); + os = apk_ostream_to_file("var/lib/apk/world.new", 0644); if (os == NULL) return -1; apk_deps_write(db->world, os); os->write(os, "\n", 1); os->close(os); + if (rename("var/lib/apk/world.new", "var/lib/apk/world") < 0) + return -errno; os = apk_ostream_to_file("var/lib/apk/installed.new", 0644); if (os == NULL) @@ -1061,18 +1063,16 @@ int apk_cache_download(struct apk_database *db, struct apk_checksum *csum, if (verify != APK_SIGN_NONE) { struct apk_istream *is; struct apk_sign_ctx sctx; - int ok; apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY, NULL); is = apk_bstream_gunzip_mpart(apk_bstream_from_file(tmp2), apk_sign_ctx_mpart_cb, &sctx); r = apk_tar_parse(is, apk_sign_ctx_verify_tar, &sctx); is->close(is); - ok = (r == 0) && sctx.control_verified && sctx.data_verified; apk_sign_ctx_free(&sctx); - if (!ok) { + if (r != 0) { unlink(tmp2); - return -10; + return r; } } @@ -1116,9 +1116,11 @@ int apk_repository_update(struct apk_database *db, struct apk_repository *repo) r = apk_cache_download(db, &repo->csum, repo->url, apkindex_tar_gz, APK_SIGN_VERIFY); - if (r == 0 || r == -10) { - if (r == -10) - apk_error("%s: untrusted or bad signature!", repo->url); + if (r == 0 || r == -ENOKEY || r == -EKEYREJECTED) { + if (r == -ENOKEY) + apk_error("%s: verify: UNTRUSTED", repo->url); + else if (r == -EKEYREJECTED) + apk_error("%s: verify: FAILED", repo->url); apk_cache_delete(db, &repo->csum, apk_index_gz); return r; } @@ -1126,7 +1128,7 @@ int apk_repository_update(struct apk_database *db, struct apk_repository *repo) r = apk_cache_download(db, &repo->csum, repo->url, apk_index_gz, APK_SIGN_NONE); if (r != 0) - apk_error("Failed to update %s: download failed"); + apk_error("Failed to update %s: download failed", repo->url); return r; } @@ -1454,6 +1456,7 @@ static void apk_db_migrate_files(struct apk_database *db, struct hlist_node *dc, *dn, *fc, *fn; unsigned long hash; char name[1024], tmpname[1024]; + int r; hlist_for_each_entry_safe(diri, dc, dn, &pkg->owned_dirs, pkg_dirs_list) { dir = diri->dir; @@ -1500,7 +1503,7 @@ static void apk_db_migrate_files(struct apk_database *db, /* Claim ownership of the file in db */ if (ofile != NULL) { hlist_del(&ofile->diri_files_list, - &diri->owned_files); + &ofile->diri->owned_files); apk_hash_delete_hashed(&db->installed.files, APK_BLOB_BUF(&key), hash); } else diff --git a/src/package.c b/src/package.c index 9fb4024..5bf4478 100644 --- a/src/package.c +++ b/src/package.c @@ -86,8 +86,10 @@ int apk_deps_add(struct apk_dependency_array **depends, if (deps != NULL) { for (i = 0; i < deps->num; i++) { - if (deps->item[i].name == dep->name) + if (deps->item[i].name == dep->name) { + deps->item[i] = *dep; return 0; + } } } @@ -119,17 +121,13 @@ struct parse_depend_ctx { struct apk_dependency_array **depends; }; -static int parse_depend(void *ctx, apk_blob_t blob) +int apk_dep_from_blob(struct apk_dependency *dep, struct apk_database *db, + apk_blob_t blob) { - struct parse_depend_ctx *pctx = (struct parse_depend_ctx *) ctx; - struct apk_dependency *dep; struct apk_name *name; apk_blob_t bname, bop, bver = APK_BLOB_NULL; int mask = APK_VERSION_LESS | APK_VERSION_EQUAL | APK_VERSION_GREATER; - if (blob.len == 0) - return 0; - /* [!]name[<,<=,=,>=,>]ver */ if (blob.ptr[0] == '!') { mask = 0; @@ -140,11 +138,12 @@ static int parse_depend(void *ctx, apk_blob_t blob) int i; if (mask == 0) - return -1; + return -EINVAL; if (!apk_blob_spn(bop, "<>=", &bop, &bver)) - return -1; - for (i = 0; i < blob.len; i++) { - switch (blob.ptr[i]) { + return -EINVAL; + mask = 0; + for (i = 0; i < bop.len; i++) { + switch (bop.ptr[i]) { case '<': mask |= APK_VERSION_LESS; break; @@ -158,25 +157,51 @@ static int parse_depend(void *ctx, apk_blob_t blob) } if ((mask & (APK_VERSION_LESS|APK_VERSION_GREATER)) == (APK_VERSION_LESS|APK_VERSION_GREATER)) - return -1; + return -EINVAL; if (!apk_version_validate(bver)) - return -1; + return -EINVAL; + + blob = bname; } - name = apk_db_get_name(pctx->db, blob); + name = apk_db_get_name(db, blob); if (name == NULL) - return -1; - - dep = apk_dependency_array_add(pctx->depends); - if (dep == NULL) - return -1; + return -ENOENT; *dep = (struct apk_dependency){ .name = name, .version = APK_BLOB_IS_NULL(bver) ? NULL : apk_blob_cstr(bver), .result_mask = mask, }; + return 0; +} + +void apk_dep_from_pkg(struct apk_dependency *dep, struct apk_database *db, + struct apk_package *pkg) +{ + *dep = (struct apk_dependency) { + .name = apk_db_get_name(db, APK_BLOB_STR(pkg->name->name)), + .version = pkg->version, + .result_mask = APK_VERSION_EQUAL, + }; +} + +static int parse_depend(void *ctx, apk_blob_t blob) +{ + struct parse_depend_ctx *pctx = (struct parse_depend_ctx *) ctx; + struct apk_dependency *dep, p; + + if (blob.len == 0) + return 0; + + if (apk_dep_from_blob(&p, pctx->db, blob) < 0) + return -1; + + dep = apk_dependency_array_add(pctx->depends); + if (dep == NULL) + return -1; + *dep = p; return 0; } @@ -435,7 +460,7 @@ int apk_sign_ctx_mpart_cb(void *ctx, int part, apk_blob_t data) sctx->signature.data.len, sctx->signature.pkey); if (r != 1) - return -1; + return -EKEYREJECTED; sctx->control_verified = 1; EVP_DigestInit_ex(&sctx->mdctx, sctx->md, NULL); @@ -444,7 +469,7 @@ int apk_sign_ctx_mpart_cb(void *ctx, int part, apk_blob_t data) /* Package identity is checksum of control block */ sctx->identity.type = EVP_MD_CTX_size(&sctx->mdctx); EVP_DigestFinal_ex(&sctx->mdctx, sctx->identity.data, NULL); - return -1000; + return -ECANCELED; } else { /* Reset digest for hashing data */ EVP_DigestFinal_ex(&sctx->mdctx, calculated, NULL); @@ -453,7 +478,7 @@ int apk_sign_ctx_mpart_cb(void *ctx, int part, apk_blob_t data) if (sctx->action == APK_SIGN_VERIFY_IDENTITY) { if (memcmp(calculated, sctx->identity.data, sctx->identity.type) != 0) - return -1; + return -EKEYREJECTED; sctx->control_verified = 1; } } @@ -465,11 +490,13 @@ int apk_sign_ctx_mpart_cb(void *ctx, int part, apk_blob_t data) if (EVP_MD_CTX_size(&sctx->mdctx) == 0 || memcmp(calculated, sctx->data_checksum, EVP_MD_CTX_size(&sctx->mdctx)) != 0) - return -1; + return -EKEYREJECTED; sctx->data_verified = 1; + if (!sctx->control_verified) + return -ENOKEY; } else if (sctx->action == APK_SIGN_VERIFY) { if (sctx->signature.pkey == NULL) - return -1; + return -EKEYREJECTED; /* Assume that the data is fully signed */ r = EVP_VerifyFinal(&sctx->mdctx, @@ -477,7 +504,7 @@ int apk_sign_ctx_mpart_cb(void *ctx, int part, apk_blob_t data) sctx->signature.data.len, sctx->signature.pkey); if (r != 1) - return -1; + return -EKEYREJECTED; sctx->control_verified = 1; sctx->data_verified = 1; @@ -486,7 +513,7 @@ int apk_sign_ctx_mpart_cb(void *ctx, int part, apk_blob_t data) if (EVP_MD_CTX_size(&sctx->mdctx) == 0 || memcmp(calculated, sctx->identity.data, EVP_MD_CTX_size(&sctx->mdctx)) != 0) - return -1; + return -EKEYREJECTED; sctx->control_verified = 1; sctx->data_verified = 1; } else { @@ -698,7 +725,7 @@ struct apk_package *apk_pkg_read(struct apk_database *db, const char *file, tar = apk_bstream_gunzip_mpart(bs, apk_sign_ctx_mpart_cb, sctx); r = apk_tar_parse(tar, read_info_entry, &ctx); tar->close(tar); - if (r < 0 && r != -1000) + if (r < 0 && r != -ECANCELED) goto err; if (ctx.pkg->name == NULL) goto err; @@ -927,35 +954,3 @@ int apk_pkg_version_compare(struct apk_package *a, struct apk_package *b) { return apk_version_compare(a->version, b->version); } - -struct apk_dependency apk_dep_from_str(struct apk_database *db, - char *str) -{ - apk_blob_t name = APK_BLOB_STR(str); - char *v = str; - int mask = APK_DEPMASK_REQUIRE; - - v = strpbrk(str, "<>="); - if (v != NULL) { - name.len = v - str; - mask = apk_version_result_mask(v++); - if (*v == '=') - v++; - } - return (struct apk_dependency) { - .name = apk_db_get_name(db, name), - .version = v, - .result_mask = mask, - }; -} - -struct apk_dependency apk_dep_from_pkg(struct apk_database *db, - struct apk_package *pkg) -{ - return (struct apk_dependency) { - .name = apk_db_get_name(db, APK_BLOB_STR(pkg->name->name)), - .version = pkg->version, - .result_mask = APK_VERSION_EQUAL, - }; -} - |