parent
da6e455f70
commit
8d1ec4c5bc
|
@ -28,6 +28,7 @@ struct apk_db_acl {
|
||||||
mode_t mode;
|
mode_t mode;
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
gid_t gid;
|
gid_t gid;
|
||||||
|
struct apk_checksum xattr_csum;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct apk_db_file {
|
struct apk_db_file {
|
||||||
|
|
|
@ -45,6 +45,7 @@ struct apk_file_info {
|
||||||
time_t mtime;
|
time_t mtime;
|
||||||
dev_t device;
|
dev_t device;
|
||||||
struct apk_checksum csum;
|
struct apk_checksum csum;
|
||||||
|
struct apk_checksum xattr_csum;
|
||||||
struct apk_xattr_array *xattrs;
|
struct apk_xattr_array *xattrs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -150,6 +151,7 @@ int apk_blob_to_file(int atfd, const char *file, apk_blob_t b, unsigned int flag
|
||||||
#define APK_FI_NOFOLLOW 0x80000000
|
#define APK_FI_NOFOLLOW 0x80000000
|
||||||
int apk_fileinfo_get(int atfd, const char *filename, unsigned int flags,
|
int apk_fileinfo_get(int atfd, const char *filename, unsigned int flags,
|
||||||
struct apk_file_info *fi);
|
struct apk_file_info *fi);
|
||||||
|
void apk_fileinfo_hash_xattr(struct apk_file_info *fi);
|
||||||
void apk_fileinfo_free(struct apk_file_info *fi);
|
void apk_fileinfo_free(struct apk_file_info *fi);
|
||||||
|
|
||||||
typedef int apk_dir_file_cb(void *ctx, int dirfd, const char *entry);
|
typedef int apk_dir_file_cb(void *ctx, int dirfd, const char *entry);
|
||||||
|
|
|
@ -215,7 +215,10 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser,
|
||||||
teis.csum = NULL;
|
teis.csum = NULL;
|
||||||
apk_xattr_array_resize(&entry.xattrs, 0);
|
apk_xattr_array_resize(&entry.xattrs, 0);
|
||||||
|
|
||||||
if (paxlen) handle_extended_header(&entry, APK_BLOB_PTR_LEN(pax.ptr, paxlen));
|
if (paxlen) {
|
||||||
|
handle_extended_header(&entry, APK_BLOB_PTR_LEN(pax.ptr, paxlen));
|
||||||
|
apk_fileinfo_hash_xattr(&entry);
|
||||||
|
}
|
||||||
|
|
||||||
switch (buf.typeflag) {
|
switch (buf.typeflag) {
|
||||||
case 'L': /* GNU long name extension */
|
case 'L': /* GNU long name extension */
|
||||||
|
|
|
@ -220,10 +220,14 @@ struct apk_name *apk_db_get_name(struct apk_database *db, apk_blob_t name)
|
||||||
return pn;
|
return pn;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct apk_db_acl *apk_db_acl_atomize(mode_t mode, uid_t uid, gid_t gid)
|
static struct apk_db_acl *apk_db_acl_atomize(mode_t mode, uid_t uid, gid_t gid, const struct apk_checksum *xattr_csum)
|
||||||
{
|
{
|
||||||
struct apk_db_acl acl = { .mode = mode & 07777, .uid = uid, .gid = gid };
|
struct apk_db_acl acl = { .mode = mode & 07777, .uid = uid, .gid = gid };
|
||||||
apk_blob_t *b;
|
apk_blob_t *b;
|
||||||
|
|
||||||
|
if (xattr_csum && xattr_csum->type != APK_CHECKSUM_NONE)
|
||||||
|
acl.xattr_csum = *xattr_csum;
|
||||||
|
|
||||||
b = apk_blob_atomize_dup(APK_BLOB_STRUCT(acl));
|
b = apk_blob_atomize_dup(APK_BLOB_STRUCT(acl));
|
||||||
return (struct apk_db_acl *) b->ptr;
|
return (struct apk_db_acl *) b->ptr;
|
||||||
}
|
}
|
||||||
|
@ -740,6 +744,7 @@ int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo)
|
||||||
struct apk_db_acl *acl;
|
struct apk_db_acl *acl;
|
||||||
struct hlist_node **diri_node = NULL;
|
struct hlist_node **diri_node = NULL;
|
||||||
struct hlist_node **file_diri_node = NULL;
|
struct hlist_node **file_diri_node = NULL;
|
||||||
|
struct apk_checksum xattr_csum;
|
||||||
apk_blob_t token = APK_BLOB_STR("\n"), l;
|
apk_blob_t token = APK_BLOB_STR("\n"), l;
|
||||||
mode_t mode;
|
mode_t mode;
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
|
@ -814,7 +819,12 @@ int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo)
|
||||||
gid = apk_blob_pull_uint(&l, 10);
|
gid = apk_blob_pull_uint(&l, 10);
|
||||||
apk_blob_pull_char(&l, ':');
|
apk_blob_pull_char(&l, ':');
|
||||||
mode = apk_blob_pull_uint(&l, 8);
|
mode = apk_blob_pull_uint(&l, 8);
|
||||||
acl = apk_db_acl_atomize(mode, uid, gid);
|
if (apk_blob_pull_blob_match(&l, APK_BLOB_STR(":")))
|
||||||
|
apk_blob_pull_csum(&l, &xattr_csum);
|
||||||
|
else
|
||||||
|
xattr_csum.type = APK_CHECKSUM_NONE;
|
||||||
|
|
||||||
|
acl = apk_db_acl_atomize(mode, uid, gid, &xattr_csum);
|
||||||
if (field == 'M')
|
if (field == 'M')
|
||||||
apk_db_diri_set(diri, acl);
|
apk_db_diri_set(diri, acl);
|
||||||
else
|
else
|
||||||
|
@ -877,6 +887,10 @@ static void apk_blob_push_db_acl(apk_blob_t *b, char field, struct apk_db_acl *a
|
||||||
apk_blob_push_uint(b, acl->gid, 10);
|
apk_blob_push_uint(b, acl->gid, 10);
|
||||||
apk_blob_push_blob(b, APK_BLOB_STR(":"));
|
apk_blob_push_blob(b, APK_BLOB_STR(":"));
|
||||||
apk_blob_push_uint(b, acl->mode, 8);
|
apk_blob_push_uint(b, acl->mode, 8);
|
||||||
|
if (acl->xattr_csum.type != APK_CHECKSUM_NONE) {
|
||||||
|
apk_blob_push_blob(b, APK_BLOB_STR(":"));
|
||||||
|
apk_blob_push_csum(b, &acl->xattr_csum);
|
||||||
|
}
|
||||||
apk_blob_push_blob(b, APK_BLOB_STR("\n"));
|
apk_blob_push_blob(b, APK_BLOB_STR("\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1426,8 +1440,8 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts)
|
||||||
apk_blob_t blob;
|
apk_blob_t blob;
|
||||||
int r, fd, write_arch = FALSE;
|
int r, fd, write_arch = FALSE;
|
||||||
|
|
||||||
apk_default_acl_dir = apk_db_acl_atomize(0755, 0, 0);
|
apk_default_acl_dir = apk_db_acl_atomize(0755, 0, 0, NULL);
|
||||||
apk_default_acl_file = apk_db_acl_atomize(0644, 0, 0);
|
apk_default_acl_file = apk_db_acl_atomize(0644, 0, 0, NULL);
|
||||||
|
|
||||||
memset(db, 0, sizeof(*db));
|
memset(db, 0, sizeof(*db));
|
||||||
if (apk_flags & APK_SIMULATE) {
|
if (apk_flags & APK_SIMULATE) {
|
||||||
|
@ -2346,7 +2360,7 @@ static int apk_db_install_archive_entry(void *_ctx,
|
||||||
apk_message("%s", ae->name);
|
apk_message("%s", ae->name);
|
||||||
|
|
||||||
/* Extract the file as name.apk-new */
|
/* Extract the file as name.apk-new */
|
||||||
file->acl = apk_db_acl_atomize(ae->mode, ae->uid, ae->gid);
|
file->acl = apk_db_acl_atomize(ae->mode, ae->uid, ae->gid, &ae->xattr_csum);
|
||||||
r = apk_archive_entry_extract(db->root_fd, ae, ".apk-new", is,
|
r = apk_archive_entry_extract(db->root_fd, ae, ".apk-new", is,
|
||||||
extract_cb, ctx);
|
extract_cb, ctx);
|
||||||
|
|
||||||
|
@ -2388,7 +2402,7 @@ static int apk_db_install_archive_entry(void *_ctx,
|
||||||
|
|
||||||
diri = apk_db_install_directory_entry(ctx, name);
|
diri = apk_db_install_directory_entry(ctx, name);
|
||||||
apk_db_dir_prepare(db, diri->dir, ae->mode);
|
apk_db_dir_prepare(db, diri->dir, ae->mode);
|
||||||
apk_db_diri_set(diri, apk_db_acl_atomize(ae->mode, ae->uid, ae->gid));
|
apk_db_diri_set(diri, apk_db_acl_atomize(ae->mode, ae->uid, ae->gid, &ae->xattr_csum));
|
||||||
}
|
}
|
||||||
ctx->installed_size += ctx->current_file_size;
|
ctx->installed_size += ctx->current_file_size;
|
||||||
|
|
||||||
|
|
36
src/io.c
36
src/io.c
|
@ -12,6 +12,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <endian.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
@ -529,6 +530,41 @@ int apk_blob_to_file(int atfd, const char *file, apk_blob_t b, unsigned int flag
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cmp_xattr(const void *p1, const void *p2)
|
||||||
|
{
|
||||||
|
const struct apk_xattr *d1 = p1, *d2 = p2;
|
||||||
|
return strcmp(d1->name, d2->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void hash_len_data(EVP_MD_CTX *ctx, uint32_t len, const void *ptr)
|
||||||
|
{
|
||||||
|
uint32_t belen = htobe32(len);
|
||||||
|
EVP_DigestUpdate(ctx, &belen, sizeof(belen));
|
||||||
|
EVP_DigestUpdate(ctx, ptr, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void apk_fileinfo_hash_xattr(struct apk_file_info *fi)
|
||||||
|
{
|
||||||
|
struct apk_xattr *xattr;
|
||||||
|
const EVP_MD *md = apk_checksum_default();
|
||||||
|
EVP_MD_CTX mdctx;
|
||||||
|
|
||||||
|
if (!fi->xattrs || fi->xattrs->num == 0) {
|
||||||
|
fi->xattr_csum.type = APK_CHECKSUM_NONE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qsort(fi->xattrs->item, fi->xattrs->num, sizeof(fi->xattrs->item[0]), cmp_xattr);
|
||||||
|
|
||||||
|
EVP_DigestInit(&mdctx, md);
|
||||||
|
foreach_array_item(xattr, fi->xattrs) {
|
||||||
|
hash_len_data(&mdctx, strlen(xattr->name), xattr->name);
|
||||||
|
hash_len_data(&mdctx, xattr->value.len, xattr->value.ptr);
|
||||||
|
}
|
||||||
|
fi->xattr_csum.type = EVP_MD_CTX_size(&mdctx);
|
||||||
|
EVP_DigestFinal(&mdctx, fi->xattr_csum.data, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
int apk_fileinfo_get(int atfd, const char *filename, unsigned int flags,
|
int apk_fileinfo_get(int atfd, const char *filename, unsigned int flags,
|
||||||
struct apk_file_info *fi)
|
struct apk_file_info *fi)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue