summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Teras <timo.teras@iki.fi>2009-07-16 15:16:05 +0300
committerTimo Teras <timo.teras@iki.fi>2009-07-16 15:16:05 +0300
commit6b471bb614beaeadcfa08008918ef6a2d93ac7e0 (patch)
treefd46188956a5fb8c22801dc49efa5e8730b657c6
parent0f6d96a4f5a904fd95b96e13715b50befa6a0ee9 (diff)
downloadapk-tools-6b471bb614beaeadcfa08008918ef6a2d93ac7e0.tar.gz
apk-tools-6b471bb614beaeadcfa08008918ef6a2d93ac7e0.tar.bz2
apk-tools-6b471bb614beaeadcfa08008918ef6a2d93ac7e0.tar.xz
apk-tools-6b471bb614beaeadcfa08008918ef6a2d93ac7e0.zip
various: new style index generation
change the index generation to do old index, or the new style index where package identity is sha1 of control block and it's contained within an .tar.gz to allow signing in future.
-rw-r--r--src/add.c2
-rw-r--r--src/apk_archive.h5
-rw-r--r--src/apk_database.h1
-rw-r--r--src/apk_io.h1
-rw-r--r--src/apk_package.h6
-rw-r--r--src/archive.c39
-rw-r--r--src/database.c30
-rw-r--r--src/gunzip.c98
-rw-r--r--src/index.c51
-rw-r--r--src/io.c39
-rw-r--r--src/package.c93
11 files changed, 289 insertions, 76 deletions
diff --git a/src/add.c b/src/add.c
index 180615c..8f067b7 100644
--- a/src/add.c
+++ b/src/add.c
@@ -118,7 +118,7 @@ static int add_main(void *ctx, int argc, char **argv)
if (strstr(argv[i], ".apk") != NULL) {
struct apk_package *pkg;
- pkg = apk_db_pkg_add_file(&db, argv[i]);
+ pkg = apk_pkg_read(&db, argv[i], APK_SIGN_VERIFY);
if (pkg == NULL) {
apk_error("Unable to read '%s'", argv[i]);
goto err;
diff --git a/src/apk_archive.h b/src/apk_archive.h
index f1787dc..a0a289a 100644
--- a/src/apk_archive.h
+++ b/src/apk_archive.h
@@ -20,8 +20,9 @@ typedef int (*apk_archive_entry_parser)(void *ctx,
const struct apk_file_info *ae,
struct apk_istream *istream);
-int apk_parse_tar(struct apk_istream *, apk_archive_entry_parser parser, void *ctx);
-int apk_write_tar_entry(struct apk_ostream *, const struct apk_file_info *ae, char *data);
+int apk_tar_parse(struct apk_istream *, apk_archive_entry_parser parser, void *ctx);
+int apk_tar_write_entry(struct apk_ostream *, const struct apk_file_info *ae, char *data);
+int apk_tar_write_padding(struct apk_ostream *, const struct apk_file_info *ae);
int apk_archive_entry_extract(const struct apk_file_info *ae,
struct apk_istream *is,
diff --git a/src/apk_database.h b/src/apk_database.h
index b4c3f04..979d0e8 100644
--- a/src/apk_database.h
+++ b/src/apk_database.h
@@ -134,7 +134,6 @@ int apk_db_write_config(struct apk_database *db);
void apk_db_close(struct apk_database *db);
int apk_db_cache_active(struct apk_database *db);
-struct apk_package *apk_db_pkg_add_file(struct apk_database *db, const char *file);
struct apk_package *apk_db_pkg_add(struct apk_database *db, struct apk_package *pkg);
struct apk_package *apk_db_get_pkg(struct apk_database *db, struct apk_checksum *csum);
struct apk_package *apk_db_get_file_owner(struct apk_database *db, apk_blob_t filename);
diff --git a/src/apk_io.h b/src/apk_io.h
index 49d9fcf..e547668 100644
--- a/src/apk_io.h
+++ b/src/apk_io.h
@@ -59,6 +59,7 @@ static inline struct apk_istream *apk_bstream_gunzip(struct apk_bstream *bs)
}
struct apk_ostream *apk_ostream_gzip(struct apk_ostream *);
+struct apk_ostream *apk_ostream_counter(off_t *);
struct apk_istream *apk_istream_from_fd(int fd);
struct apk_istream *apk_istream_from_file(const char *file);
diff --git a/src/apk_package.h b/src/apk_package.h
index b874e0c..bf30350 100644
--- a/src/apk_package.h
+++ b/src/apk_package.h
@@ -30,6 +30,10 @@ struct apk_name;
#define APK_PKG_NOT_INSTALLED 0
#define APK_PKG_INSTALLED 1
+#define APK_SIGN_VERIFY 0
+#define APK_SIGN_GENERATE_V1 1
+#define APK_SIGN_GENERATE 2
+
struct apk_script {
struct hlist_node script_list;
unsigned int type;
@@ -80,7 +84,7 @@ int apk_deps_write(struct apk_dependency_array *deps, struct apk_ostream *os);
int apk_script_type(const char *name);
struct apk_package *apk_pkg_new(void);
-struct apk_package *apk_pkg_read(struct apk_database *db, const char *name);
+struct apk_package *apk_pkg_read(struct apk_database *db, const char *name, int indexstyle);
void apk_pkg_free(struct apk_package *pkg);
int apk_pkg_parse_name(apk_blob_t apkname, apk_blob_t *name, apk_blob_t *version);
diff --git a/src/archive.c b/src/archive.c
index 8e55295..f30463f 100644
--- a/src/archive.c
+++ b/src/archive.c
@@ -93,7 +93,7 @@ static size_t tar_entry_read(void *stream, void *ptr, size_t size)
return size;
}
-int apk_parse_tar(struct apk_istream *is, apk_archive_entry_parser parser,
+int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser,
void *ctx)
{
struct apk_file_info entry;
@@ -205,11 +205,9 @@ err:
return r;
}
-int apk_write_tar_entry(struct apk_ostream *os, const struct apk_file_info *ae, char *data)
+int apk_tar_write_entry(struct apk_ostream *os, const struct apk_file_info *ae, char *data)
{
- static char padding[512];
struct tar_header buf;
- int pad;
memset(&buf, 0, sizeof(buf));
if (ae != NULL) {
@@ -221,15 +219,17 @@ int apk_write_tar_entry(struct apk_ostream *os, const struct apk_file_info *ae,
else
return -1;
- strncpy(buf.name, ae->name, sizeof(buf.name));
- strncpy(buf.uname, ae->uname, sizeof(buf.uname));
- strncpy(buf.gname, ae->gname, sizeof(buf.gname));
+ if (ae->name != NULL)
+ strncpy(buf.name, ae->name, sizeof(buf.name));
+
+ strncpy(buf.uname, ae->uname ?: "root", sizeof(buf.uname));
+ strncpy(buf.gname, ae->gname ?: "root", sizeof(buf.gname));
PUT_OCTAL(buf.size, ae->size);
PUT_OCTAL(buf.uid, ae->uid);
PUT_OCTAL(buf.gid, ae->gid);
PUT_OCTAL(buf.mode, ae->mode & 07777);
- PUT_OCTAL(buf.mtime, ae->mtime);
+ PUT_OCTAL(buf.mtime, ae->mtime ?: time(NULL));
/* Checksum */
strcpy(buf.magic, "ustar ");
@@ -243,18 +243,33 @@ int apk_write_tar_entry(struct apk_ostream *os, const struct apk_file_info *ae,
if (os->write(os, &buf, sizeof(buf)) != sizeof(buf))
return -1;
- if (data != NULL) {
+ if (ae == NULL) {
+ /* End-of-archive is two empty headers */
+ if (os->write(os, &buf, sizeof(buf)) != sizeof(buf))
+ return -1;
+ } else if (data != NULL) {
if (os->write(os, data, ae->size) != ae->size)
return -1;
- pad = 512 - (ae->size & 511);
- if (pad != 512 &&
- os->write(os, padding, pad) != pad)
+ if (apk_tar_write_padding(os, ae) != 0)
return -1;
}
return 0;
}
+int apk_tar_write_padding(struct apk_ostream *os, const struct apk_file_info *ae)
+{
+ static char padding[512];
+ int pad;
+
+ pad = 512 - (ae->size & 511);
+ if (pad != 512 &&
+ os->write(os, padding, pad) != pad)
+ return -1;
+
+ return 0;
+}
+
int apk_archive_entry_extract(const struct apk_file_info *ae,
struct apk_istream *is,
const char *fn, apk_progress_cb cb,
diff --git a/src/database.c b/src/database.c
index 2a15385..5a1348e 100644
--- a/src/database.c
+++ b/src/database.c
@@ -545,19 +545,14 @@ static int apk_db_scriptdb_write(struct apk_database *db, struct apk_ostream *os
struct apk_file_info fi;
char filename[256];
apk_blob_t bfn;
- int r, i;
+ int r;
list_for_each_entry(pkg, &db->installed.packages, installed_pkgs_list) {
hlist_for_each_entry(script, c2, &pkg->scripts, script_list) {
fi = (struct apk_file_info) {
.name = filename,
- .uname = "root",
- .gname = "root",
.size = script->size,
- .uid = 0,
- .gid = 0,
.mode = 0755 | S_IFREG,
- .mtime = time(NULL),
};
/* The scripts db expects file names in format:
* pkg-version.<hexdump of package checksum>.action */
@@ -571,18 +566,13 @@ static int apk_db_scriptdb_write(struct apk_database *db, struct apk_ostream *os
apk_blob_push_blob(&bfn, APK_BLOB_STR(apk_script_types[script->type]));
apk_blob_push_blob(&bfn, APK_BLOB_PTR_LEN("", 1));
- r = apk_write_tar_entry(os, &fi, script->script);
+ r = apk_tar_write_entry(os, &fi, script->script);
if (r < 0)
return r;
}
}
- for (i = 0; i < 2; i++) {
- r = apk_write_tar_entry(os, NULL, NULL);
- if (r < 0)
- return r;
- }
- return 0;
+ return apk_tar_write_entry(os, NULL, NULL);
}
static int apk_db_scriptdb_read_v1(struct apk_database *db, struct apk_istream *is)
@@ -688,7 +678,7 @@ static int apk_db_read_state(struct apk_database *db, int flags)
if (!(flags & APK_OPENF_NO_SCRIPTS)) {
is = apk_istream_from_file("var/lib/apk/scripts.tar");
if (is != NULL) {
- apk_parse_tar(is, apk_read_script_archive_entry, db);
+ apk_tar_parse(is, apk_read_script_archive_entry, db);
} else {
is = apk_istream_from_file("var/lib/apk/scripts");
if (is != NULL)
@@ -970,16 +960,6 @@ struct apk_package *apk_db_get_file_owner(struct apk_database *db,
return dbf->diri->pkg;
}
-struct apk_package *apk_db_pkg_add_file(struct apk_database *db, const char *file)
-{
- struct apk_package *info;
-
- info = apk_pkg_read(db, file);
- if (info != NULL)
- info = apk_db_pkg_add(db, info);
- return info;
-}
-
struct index_write_ctx {
struct apk_ostream *os;
int count;
@@ -1433,7 +1413,7 @@ static int apk_db_unpack_pkg(struct apk_database *db,
};
tar = apk_bstream_gunzip_mpart(bs, apk_db_gzip_part, &ctx);
- if (apk_parse_tar(tar, apk_db_install_archive_entry, &ctx) != 0)
+ if (apk_tar_parse(tar, apk_db_install_archive_entry, &ctx) != 0)
goto err_close;
tar->close(tar);
diff --git a/src/gunzip.c b/src/gunzip.c
index af906d1..2c4387e 100644
--- a/src/gunzip.c
+++ b/src/gunzip.c
@@ -30,7 +30,7 @@ struct apk_gzip_istream {
void *cbctx;
};
-static size_t gz_read(void *stream, void *ptr, size_t size)
+static size_t gzi_read(void *stream, void *ptr, size_t size)
{
struct apk_gzip_istream *gis =
container_of(stream, struct apk_gzip_istream, is);
@@ -78,11 +78,13 @@ static size_t gz_read(void *stream, void *ptr, size_t size)
EVP_DigestUpdate(&gis->mdctx, gis->mdblock,
(void *)gis->zs.next_in - gis->mdblock);
gis->mdblock = gis->zs.next_in;
- gis->cb(gis->cbctx, &gis->mdctx,
- APK_MPART_BOUNDARY);
+ if (gis->cb(gis->cbctx, &gis->mdctx,
+ APK_MPART_BOUNDARY)) {
+ gis->z_err = Z_STREAM_END;
+ break;
+ }
}
inflateEnd(&gis->zs);
-
if (inflateInit2(&gis->zs, 15+32) != Z_OK)
return -1;
gis->z_err = Z_OK;
@@ -95,7 +97,7 @@ static size_t gz_read(void *stream, void *ptr, size_t size)
return size - gis->zs.avail_out;
}
-static void gz_close(void *stream)
+static void gzi_close(void *stream)
{
struct apk_gzip_istream *gis =
container_of(stream, struct apk_gzip_istream, is);
@@ -117,11 +119,11 @@ struct apk_istream *apk_bstream_gunzip_mpart(struct apk_bstream *bs,
gis = malloc(sizeof(struct apk_gzip_istream));
if (gis == NULL)
- return NULL;
+ goto err;
*gis = (struct apk_gzip_istream) {
- .is.read = gz_read,
- .is.close = gz_close,
+ .is.read = gzi_read,
+ .is.close = gzi_close,
.bs = bs,
.z_err = 0,
.cb = cb,
@@ -130,7 +132,7 @@ struct apk_istream *apk_bstream_gunzip_mpart(struct apk_bstream *bs,
if (inflateInit2(&gis->zs, 15+32) != Z_OK) {
free(gis);
- return NULL;
+ goto err;
}
if (gis->cb != NULL) {
@@ -139,5 +141,83 @@ struct apk_istream *apk_bstream_gunzip_mpart(struct apk_bstream *bs,
}
return &gis->is;
+err:
+ bs->close(bs, NULL);
+ return NULL;
+}
+
+struct apk_gzip_ostream {
+ struct apk_ostream os;
+ struct apk_ostream *output;
+ z_stream zs;
+ unsigned char buffer[8*1024];
+};
+
+static size_t gzo_write(void *stream, const void *ptr, size_t size)
+{
+ struct apk_gzip_ostream *gos = (struct apk_gzip_ostream *) stream;
+ size_t have;
+ int r;
+
+ gos->zs.avail_in = size;
+ gos->zs.next_in = (void *) ptr;
+ while (gos->zs.avail_in) {
+ gos->zs.avail_out = sizeof(gos->buffer);
+ gos->zs.next_out = gos->buffer;
+ r = deflate(&gos->zs, Z_NO_FLUSH);
+ if (r == Z_STREAM_ERROR)
+ return -1;
+ have = sizeof(gos->buffer) - gos->zs.avail_out;
+ if (have != 0) {
+ r = gos->output->write(gos->output, gos->buffer, have);
+ if (r != have)
+ return -1;
+ }
+ }
+
+ return size;
+}
+
+static void gzo_close(void *stream)
+{
+ struct apk_gzip_ostream *gos = (struct apk_gzip_ostream *) stream;
+ size_t have;
+
+ deflate(&gos->zs, Z_FINISH);
+ have = sizeof(gos->buffer) - gos->zs.avail_out;
+ gos->output->write(gos->output, gos->buffer, have);
+ gos->output->close(gos->output);
+
+ deflateEnd(&gos->zs);
+ free(stream);
+}
+
+struct apk_ostream *apk_ostream_gzip(struct apk_ostream *output)
+{
+ struct apk_gzip_ostream *gos;
+
+ if (output == NULL)
+ return NULL;
+
+ gos = malloc(sizeof(struct apk_gzip_ostream));
+ if (gos == NULL)
+ goto err;
+
+ *gos = (struct apk_gzip_ostream) {
+ .os.write = gzo_write,
+ .os.close = gzo_close,
+ .output = output,
+ };
+
+ if (deflateInit2(&gos->zs, 9, Z_DEFLATED, 15 | 16, 8,
+ Z_DEFAULT_STRATEGY) != Z_OK) {
+ free(gos);
+ goto err;
+ }
+
+ return &gos->os;
+err:
+ output->close(output);
+ return NULL;
}
diff --git a/src/index.c b/src/index.c
index d7402f9..86c1f44 100644
--- a/src/index.c
+++ b/src/index.c
@@ -10,18 +10,23 @@
*/
#include <stdio.h>
+#include <fcntl.h>
#include <unistd.h>
#include "apk_applet.h"
#include "apk_database.h"
+#define INDEX_OLD_FORMAT 0x10000
+
struct counts {
int unsatisfied;
};
struct index_ctx {
const char *index;
+ const char *output;
time_t index_mtime;
+ int method;
};
static int index_parse(void *ctx, int optch, int optindex, const char *optarg)
@@ -32,6 +37,12 @@ static int index_parse(void *ctx, int optch, int optindex, const char *optarg)
case 'x':
ictx->index = optarg;
break;
+ case 'o':
+ ictx->output = optarg;
+ break;
+ case INDEX_OLD_FORMAT:
+ ictx->method = APK_SIGN_GENERATE_V1;
+ break;
default:
return -1;
}
@@ -83,6 +94,16 @@ static int index_main(void *ctx, int argc, char **argv)
int total, i, j, found, newpkgs = 0;
struct index_ctx *ictx = (struct index_ctx *) ctx;
+ if (isatty(STDOUT_FILENO) && ictx->output == NULL &&
+ !(apk_flags & APK_FORCE)) {
+ apk_error("Will not write binary index to console "
+ "without --force");
+ return -1;
+ }
+
+ if (ictx->method == 0)
+ ictx->method = APK_SIGN_GENERATE;
+
apk_db_open(&db, NULL, APK_OPENF_READ);
if (index_read_file(&db, ictx) < 0) {
apk_db_close(&db);
@@ -137,13 +158,33 @@ static int index_main(void *ctx, int argc, char **argv)
} while (0);
if (!found) {
- apk_db_pkg_add_file(&db, argv[i]);
- newpkgs++;
+ if (apk_pkg_read(&db, argv[i], ictx->method) != NULL)
+ newpkgs++;
}
}
- os = apk_ostream_to_fd(STDOUT_FILENO);
+ if (ictx->method == APK_SIGN_GENERATE) {
+ memset(&fi, 0, sizeof(fi));
+ fi.name = "APKINDEX";
+ fi.mode = 0755 | S_IFREG;
+ os = apk_ostream_counter(&fi.size);
+ apk_db_index_write(&db, os);
+ os->close(os);
+ }
+
+ if (ictx->output != NULL)
+ os = apk_ostream_to_file(ictx->output, 0755);
+ else
+ os = apk_ostream_to_fd(STDOUT_FILENO);
+ if (ictx->method == APK_SIGN_GENERATE) {
+ os = apk_ostream_gzip(os);
+ apk_tar_write_entry(os, &fi, NULL);
+ }
total = apk_db_index_write(&db, os);
+ if (ictx->method == APK_SIGN_GENERATE) {
+ apk_tar_write_padding(os, &fi);
+ apk_tar_write_entry(os, NULL, NULL);
+ }
os->close(os);
apk_hash_foreach(&db.available.names, warn_if_no_providers, &counts);
@@ -160,9 +201,13 @@ static int index_main(void *ctx, int argc, char **argv)
}
static struct apk_option index_options[] = {
+ { 'o', "output", "Write the generated index to FILE",
+ required_argument, "FILE" },
{ 'x', "index", "Read INDEX to speed up new index creation by reusing "
"the information from an old index",
required_argument, "INDEX" },
+ { INDEX_OLD_FORMAT, "old-format",
+ "Specify to create old style index files" }
};
static struct apk_applet apk_index = {
diff --git a/src/io.c b/src/io.c
index 26d51b9..c7846c9 100644
--- a/src/io.c
+++ b/src/io.c
@@ -578,6 +578,45 @@ struct apk_ostream *apk_ostream_to_file(const char *file, mode_t mode)
return apk_ostream_to_fd(fd);
}
+struct apk_counter_ostream {
+ struct apk_ostream os;
+ off_t *counter;
+};
+
+static size_t co_write(void *stream, const void *ptr, size_t size)
+{
+ struct apk_counter_ostream *cos =
+ container_of(stream, struct apk_counter_ostream, os);
+
+ *cos->counter += size;
+ return size;
+}
+
+static void co_close(void *stream)
+{
+ struct apk_counter_ostream *cos =
+ container_of(stream, struct apk_counter_ostream, os);
+
+ free(cos);
+}
+
+struct apk_ostream *apk_ostream_counter(off_t *counter)
+{
+ struct apk_counter_ostream *cos;
+
+ cos = malloc(sizeof(struct apk_counter_ostream));
+ if (cos == NULL)
+ return NULL;
+
+ *cos = (struct apk_counter_ostream) {
+ .os.write = co_write,
+ .os.close = co_close,
+ .counter = counter,
+ };
+
+ return &cos->os;
+}
+
size_t apk_ostream_write_string(struct apk_ostream *os, const char *string)
{
size_t len;
diff --git a/src/package.c b/src/package.c
index c01a5e8..95c4cc0 100644
--- a/src/package.c
+++ b/src/package.c
@@ -257,8 +257,13 @@ int apk_script_type(const char *name)
struct read_info_ctx {
struct apk_database *db;
struct apk_package *pkg;
- int version;
- int has_install;
+ const EVP_MD *md;
+ int version, action;
+ int has_signature : 1;
+ int has_install : 1;
+ int has_data_checksum : 1;
+ int data_started : 1;
+ int in_signatures : 1;
};
int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg,
@@ -325,12 +330,16 @@ static int read_info_line(void *ctx, apk_blob_t line)
return 0;
for (i = 0; i < ARRAY_SIZE(fields); i++) {
- if (strncmp(fields[i].str, l.ptr, l.len) == 0) {
+ if (apk_blob_compare(APK_BLOB_STR(fields[i].str), l) == 0) {
apk_pkg_add_info(ri->db, ri->pkg, fields[i].field, r);
- break;
+ return 0;
}
}
+ if (ri->data_started == 0 &&
+ apk_blob_compare(APK_BLOB_STR("sha256"), l) == 0)
+ ri->has_data_checksum = 1;
+
return 0;
}
@@ -354,21 +363,27 @@ static int read_info_entry(void *ctx, const struct apk_file_info *ae,
int i;
/* Meta info and scripts */
- if (ae->name[0] == '.') {
+ if (ri->in_signatures && strncmp(ae->name, ".SIGN.", 6) != 0)
+ ri->in_signatures = 0;
+
+ if (ri->data_started == 0 && ae->name[0] == '.') {
/* APK 2.0 format */
- ri->version = 2;
if (strcmp(ae->name, ".PKGINFO") == 0) {
apk_blob_t blob = apk_blob_from_istream(is, ae->size);
apk_blob_for_each_segment(blob, "\n", read_info_line, ctx);
free(blob.ptr);
- return 0;
- }
- if (strcmp(ae->name, ".INSTALL") == 0) {
+ ri->version = 2;
+ } else if (strncmp(ae->name, ".SIGN.", 6) == 0) {
+ ri->has_signature = 1;
+ } else if (strcmp(ae->name, ".INSTALL") == 0) {
apk_warning("Package '%s-%s' contains deprecated .INSTALL",
pkg->name->name, pkg->version);
- return 0;
}
- } else if (strncmp(ae->name, "var/db/apk/", 11) == 0) {
+ return 0;
+ }
+
+ ri->data_started = 1;
+ if (strncmp(ae->name, "var/db/apk/", 11) == 0) {
/* APK 1.0 format */
ri->version = 1;
if (!S_ISREG(ae->mode))
@@ -399,10 +414,7 @@ static int read_info_entry(void *ctx, const struct apk_file_info *ae,
if (apk_script_type(slash+1) == APK_SCRIPT_POST_INSTALL ||
apk_script_type(slash+1) == APK_SCRIPT_PRE_INSTALL)
ri->has_install = 1;
- } else if (ri->version == 2) {
- /* All metdata of version 2.x package handled */
- return 0;
- } else {
+ } else if (ri->version < 2) {
/* Version 1.x packages do not contain installed size
* in metadata, so we calculate it here */
pkg->installed_size += apk_calc_installed_size(ae->size);
@@ -417,29 +429,59 @@ static int apk_pkg_gzip_part(void *ctx, EVP_MD_CTX *mdctx, int part)
switch (part) {
case APK_MPART_BEGIN:
- EVP_DigestInit_ex(mdctx, EVP_md5(), NULL);
+ EVP_DigestInit_ex(mdctx, ri->md, NULL);
break;
+ case APK_MPART_BOUNDARY:
+ if (ri->in_signatures) {
+ EVP_DigestFinal_ex(mdctx, ri->pkg->csum.data, NULL);
+ EVP_DigestInit_ex(mdctx, ri->md, NULL);
+ return 0;
+ }
+
+ if (ri->action == APK_SIGN_GENERATE_V1 ||
+ !ri->has_data_checksum)
+ break;
+ /* Fallthrough to calculate checksum */
case APK_MPART_END:
ri->pkg->csum.type = EVP_MD_CTX_size(mdctx);
EVP_DigestFinal_ex(mdctx, ri->pkg->csum.data, NULL);
- break;
+ return 1;
}
return 0;
}
-struct apk_package *apk_pkg_read(struct apk_database *db, const char *file)
+struct apk_package *apk_pkg_read(struct apk_database *db, const char *file,
+ int action)
{
struct read_info_ctx ctx;
struct apk_file_info fi;
struct apk_bstream *bs;
struct apk_istream *tar;
char realfile[PATH_MAX];
+ int r;
if (realpath(file, realfile) < 0)
return NULL;
if (apk_file_get_info(realfile, APK_CHECKSUM_NONE, &fi) < 0)
return NULL;
+ memset(&ctx, 0, sizeof(ctx));
+ switch (action) {
+ case APK_SIGN_VERIFY:
+ ctx.in_signatures = 1;
+ ctx.md = EVP_md_null();
+ break;
+ case APK_SIGN_GENERATE:
+ ctx.in_signatures = 1;
+ ctx.md = EVP_sha1();
+ break;
+ case APK_SIGN_GENERATE_V1:
+ ctx.md = EVP_md5();
+ break;
+ default:
+ return NULL;
+ }
+
ctx.pkg = apk_pkg_new();
if (ctx.pkg == NULL)
return NULL;
@@ -450,15 +492,22 @@ struct apk_package *apk_pkg_read(struct apk_database *db, const char *file)
ctx.db = db;
ctx.has_install = 0;
+ ctx.action = action;
ctx.pkg->size = fi.size;
tar = apk_bstream_gunzip_mpart(bs, apk_pkg_gzip_part, &ctx);
- if (apk_parse_tar(tar, read_info_entry, &ctx) < 0) {
+ r = apk_tar_parse(tar, read_info_entry, &ctx);
+ tar->close(tar);
+ switch (r) {
+ case 0:
+ break;
+ case -2:
+ apk_error("File %s does not have a signature", file);
+ goto err;
+ default:
apk_error("File %s is not an APK archive", file);
- bs->close(bs, NULL);
goto err;
}
- tar->close(tar);
if (ctx.pkg->name == NULL) {
apk_error("File %s is corrupted", file);
@@ -474,7 +523,7 @@ struct apk_package *apk_pkg_read(struct apk_database *db, const char *file)
}
ctx.pkg->filename = strdup(realfile);
- return ctx.pkg;
+ return apk_db_pkg_add(db, ctx.pkg);
err:
apk_pkg_free(ctx.pkg);
return NULL;