summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimo Teras <timo.teras@iki.fi>2009-07-22 14:24:19 +0300
committerTimo Teras <timo.teras@iki.fi>2009-07-22 14:24:19 +0300
commit0a7991f70dcfe9f8e05f6a4a4a59af21be878915 (patch)
tree9c6ef07e6f594b524bd1fc4746a103ab3d93d926
parent0dadc27ce1cfe84585a747d57e7d3bcafc1069eb (diff)
downloadapk-tools-0a7991f70dcfe9f8e05f6a4a4a59af21be878915.tar.bz2
apk-tools-0a7991f70dcfe9f8e05f6a4a4a59af21be878915.tar.xz
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.c11
-rw-r--r--src/apk.c2
-rw-r--r--src/apk_defines.h6
-rw-r--r--src/apk_package.h8
-rw-r--r--src/cache.c7
-rw-r--r--src/database.c25
-rw-r--r--src/package.c113
7 files changed, 88 insertions, 84 deletions
diff --git a/src/add.c b/src/add.c
index fac1edc..f78b4e0 100644
--- a/src/add.c
+++ b/src/add.c
@@ -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);
diff --git a/src/apk.c b/src/apk.c
index ecbae72..b60ae0f 100644
--- a/src/apk.c
+++ b/src/apk.c
@@ -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,
- };
-}
-