Commit b65ea84b authored by Mark Fasheh's avatar Mark Fasheh

Write hash type into hashfile header, check against what hash we were

compiled with.
Signed-off-by: 's avatarMark Fasheh <mfasheh@suse.de>
parent 955b51b9
......@@ -29,6 +29,8 @@
GCRY_THREAD_OPTION_PTHREAD_IMPL;
unsigned int digest_len = 0;
#define HASH_TYPE "SHA256 "
char hash_type[8];
void checksum_block(char *buf, int len, unsigned char *digest)
{
......@@ -59,6 +61,8 @@ int init_hash(void)
if (!digest_len)
return 1;
strncpy(hash_type, HASH_TYPE, 8);
abort_on(digest_len == 0 || digest_len > DIGEST_LEN_MAX);
return 0;
......
......@@ -27,6 +27,8 @@ static MHASH td;
#define HASH_FUNC MHASH_SHA256
uint32_t digest_len = 0;
#define HASH_TYPE "SHA256 "
char hash_type[8];
void checksum_block(char *buf, int len, unsigned char *digest)
{
......@@ -43,6 +45,8 @@ int init_hash(void)
if (!digest_len)
return 1;
strncpy(hash_type, HASH_TYPE, 8);
abort_on(digest_len == 0 || digest_len > DIGEST_LEN_MAX);
return 0;
......
......@@ -6,6 +6,7 @@
#define DIGEST_LEN_MAX 32
extern unsigned int digest_len;
extern char hash_type[8];
/* Init / debug */
int init_hash(void);
......
......@@ -1236,7 +1236,8 @@ int main(int argc, char **argv)
fancy_status = 1;
if (read_hashes) {
ret = read_hash_tree(serialize_fname, &tree, &blocksize, NULL);
ret = read_hash_tree(serialize_fname, &tree, &blocksize, NULL,
0);
if (ret == FILE_VERSION_ERROR) {
fprintf(stderr,
"Hash file \"%s\": "
......@@ -1250,6 +1251,12 @@ int main(int argc, char **argv)
"Bad magic.\n",
serialize_fname);
goto out;
} else if (ret == FILE_HASH_TYPE_ERROR) {
fprintf(stderr,
"Hash file \"%s\": Unkown hash type \"%.*s\".\n"
"(we use \"%.*s\").\n", serialize_fname,
8, unknown_hash_type, 8, hash_type);
goto out;
} else if (ret) {
fprintf(stderr, "Hash file \"%s\": "
"Error %d while reading: %s.\n",
......@@ -1259,6 +1266,7 @@ int main(int argc, char **argv)
}
printf("Using %uK blocks\n", blocksize/1024);
printf("Using hash: %.*s\n", 8, hash_type);
if (!read_hashes) {
ret = populate_hash_tree(&tree);
......
......@@ -264,7 +264,7 @@ int main(int argc, char **argv)
return EINVAL;
}
ret = read_hash_tree(serialize_fname, &tree, &blocksize, &h);
ret = read_hash_tree(serialize_fname, &tree, &blocksize, &h, 0);
if (ret == FILE_VERSION_ERROR) {
fprintf(stderr,
"Hash file \"%s\": "
......
......@@ -39,6 +39,9 @@
#include "serialize.h"
char unknown_hash_type[8];
#define hash_type_v1_0 "\0\0\0\0\0\0\0\0"
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define swap16(_x) ((uint16_t)_x)
#define swap32(_x) ((uint32_t)_x)
......@@ -60,6 +63,7 @@ static void debug_print_header(struct hash_file_header *h)
dprintf("num_files: %"PRIu64"\t", h->num_files);
dprintf("num_hashes: %"PRIu64"\t", h->num_hashes);
dprintf("block_size: %u\t", h->block_size);
dprintf("hash_type: %.*s\t", 8, h->hash_type);
dprintf(" ]\n");
}
......@@ -91,6 +95,7 @@ static int write_header(int fd, struct hash_file_header *h)
disk.num_files = swap64(h->num_files);
disk.num_hashes = swap64(h->num_hashes);
disk.block_size = swap32(h->block_size);
memcpy(&disk.hash_type, hash_type, 8);
ret = lseek(fd, 0, SEEK_SET);
if (ret == (loff_t)-1)
......@@ -332,12 +337,14 @@ static int read_header(int fd, struct hash_file_header *h)
h->num_files = swap64(disk.num_files);
h->num_hashes = swap64(disk.num_hashes);
h->block_size = swap32(disk.block_size);
memcpy(&h->hash_type, &disk.hash_type, 8);
return 0;
}
int read_hash_tree(char *filename, struct hash_tree *tree,
unsigned int *block_size, struct hash_file_header *ret_hdr)
unsigned int *block_size, struct hash_file_header *ret_hdr,
int ignore_hash_type)
{
int ret, fd;
uint32_t i;
......@@ -361,6 +368,22 @@ int read_hash_tree(char *filename, struct hash_tree *tree,
goto out;
}
if (!ignore_hash_type) {
/*
* v1.0 hash files were SHA256 but wrote out hash_type
* as nulls
*/
if (h.minor == 0 && memcmp(hash_type_v1_0, h.hash_type, 8)) {
ret = FILE_HASH_TYPE_ERROR;
memcpy(unknown_hash_type, hash_type_v1_0, 8);
goto out;
} else if (h.minor > 0 && memcmp(h.hash_type, hash_type, 8)) {
ret = FILE_HASH_TYPE_ERROR;
memcpy(unknown_hash_type, h.hash_type, 8);
goto out;
}
}
*block_size = h.block_size;
dprintf("Load %"PRIu64" files from \"%s\"\n",
......
......@@ -17,7 +17,7 @@
#define __SERIALIZE__
#define HASH_FILE_MAJOR 1
#define HASH_FILE_MINOR 0
#define HASH_FILE_MINOR 1
#define HASH_FILE_MAGIC "dupehash"
struct hash_file_header {
......@@ -28,7 +28,8 @@ struct hash_file_header {
/*20*/ uint64_t num_hashes;
uint32_t block_size; /* In bytes */
uint32_t pad0;
uint64_t pad1[10];
char hash_type[8];
uint64_t pad1[9];
};
#define DISK_DIGEST_LEN 32
......@@ -57,7 +58,10 @@ int serialize_hash_tree(char *filename, struct hash_tree *tree,
#define FILE_VERSION_ERROR 1001
#define FILE_MAGIC_ERROR 1002
#define FILE_HASH_TYPE_ERROR 1003
extern char unknown_hash_type[8];
int read_hash_tree(char *filename, struct hash_tree *tree,
unsigned int *block_size, struct hash_file_header *ret_hdr);
unsigned int *block_size, struct hash_file_header *ret_hdr,
int ignore_hash_type);
#endif /* __SERIALIZE__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment