mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-02-20 17:33:08 +00:00
Improve "rhizome add file" for empty payloads
Accept the empty string for a payload pathname to mean a zero-length payload.
This commit is contained in:
parent
a9ad1b6afc
commit
b14db5c28b
26
rhizome.c
26
rhizome.c
@ -105,7 +105,7 @@ int rhizome_manifest_check_sanity(rhizome_manifest *m_in)
|
||||
return WHY("Manifest missing 'date' field");
|
||||
if (strcasecmp(service, RHIZOME_SERVICE_FILE) == 0) {
|
||||
const char *name = rhizome_manifest_get(m_in, "name", NULL, 0);
|
||||
if (name == NULL || !name[0])
|
||||
if (name == NULL)
|
||||
return WHY("Manifest missing 'name' field");
|
||||
} else if (strcasecmp(service, RHIZOME_SERVICE_MESHMS) == 0) {
|
||||
if (sender == NULL || !sender[0])
|
||||
@ -178,11 +178,14 @@ int rhizome_manifest_bind_file(rhizome_manifest *m_in,const char *filename,int e
|
||||
if (encryptP) rhizome_manifest_set_ll(m_in,"crypt",1);
|
||||
else rhizome_manifest_set_ll(m_in,"crypt",0);
|
||||
|
||||
/* Get length of payload */
|
||||
struct stat stat;
|
||||
if (lstat(filename,&stat))
|
||||
return WHYF("Could not stat() payload file '%s'",filename);
|
||||
m_in->fileLength = stat.st_size;
|
||||
/* Get length of payload. An empty filename means empty payload. */
|
||||
if (filename[0]) {
|
||||
struct stat stat;
|
||||
if (lstat(filename,&stat))
|
||||
return WHYF("Could not stat() payload file '%s'",filename);
|
||||
m_in->fileLength = stat.st_size;
|
||||
} else
|
||||
m_in->fileLength = 0;
|
||||
if (debug & DEBUG_RHIZOME)
|
||||
DEBUGF("filename=%s, fileLength=%lld", filename, m_in->fileLength);
|
||||
rhizome_manifest_set_ll(m_in,"filesize",m_in->fileLength);
|
||||
@ -214,10 +217,13 @@ int rhizome_manifest_check_file(rhizome_manifest *m_in)
|
||||
|
||||
/* Check payload file is accessible and discover its length, then check that it matches
|
||||
the file size stored in the manifest */
|
||||
struct stat stat;
|
||||
if (lstat(m_in->dataFileName,&stat))
|
||||
return WHYF("Could not stat() payload file '%s'",m_in->dataFileName);
|
||||
m_in->fileLength = stat.st_size;
|
||||
if (m_in->dataFileName[0]) {
|
||||
struct stat stat;
|
||||
if (lstat(m_in->dataFileName,&stat))
|
||||
return WHYF("Could not stat() payload file '%s'",m_in->dataFileName);
|
||||
m_in->fileLength = stat.st_size;
|
||||
} else
|
||||
m_in->fileLength = 0;
|
||||
if (debug & DEBUG_RHIZOME)
|
||||
DEBUGF("filename=%s, fileLength=%lld", m_in->dataFileName, m_in->fileLength);
|
||||
long long mfilesize = rhizome_manifest_get_ll(m_in, "filesize");
|
||||
|
@ -202,31 +202,33 @@ int rhizome_hash_file(rhizome_manifest *m,const char *filename,char *hash_out)
|
||||
and may be very resource constrained. Thus we need a streamable SHA-512
|
||||
implementation.
|
||||
*/
|
||||
#warning need to implement encryption
|
||||
if (m&&m->payloadEncryption)
|
||||
// TODO encrypted payloads
|
||||
if (m && m->payloadEncryption)
|
||||
return WHY("Encryption of payloads not implemented");
|
||||
|
||||
FILE *f = fopen(filename, "r");
|
||||
if (!f) {
|
||||
WHY_perror("fopen");
|
||||
return WHYF("Could not open %s to calculate SHA512 hash.", filename);
|
||||
}
|
||||
SHA512_CTX context;
|
||||
SHA512_Init(&context);
|
||||
while (!feof(f)) {
|
||||
unsigned char buffer[8192];
|
||||
int r = fread(buffer, 1, 8192, f);
|
||||
if (r == -1) {
|
||||
WHY_perror("fread");
|
||||
fclose(f);
|
||||
return WHYF("Error reading %s to calculate SHA512 hash", filename);
|
||||
if (filename[0]) {
|
||||
FILE *f = fopen(filename, "r");
|
||||
if (!f) {
|
||||
WHY_perror("fopen");
|
||||
return WHYF("Could not open %s to calculate SHA512 hash.", filename);
|
||||
}
|
||||
if (r > 0)
|
||||
SHA512_Update(&context, buffer, r);
|
||||
while (!feof(f)) {
|
||||
unsigned char buffer[8192];
|
||||
int r = fread(buffer, 1, 8192, f);
|
||||
if (r == -1) {
|
||||
WHY_perror("fread");
|
||||
fclose(f);
|
||||
return WHYF("Error reading %s to calculate SHA512 hash", filename);
|
||||
}
|
||||
if (r > 0)
|
||||
SHA512_Update(&context, buffer, r);
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
SHA512_End(&context, (char *)hash_out);
|
||||
str_toupper_inplace(hash_out);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -543,11 +545,15 @@ int rhizome_manifest_finalise(rhizome_manifest *m)
|
||||
m->fileHashedP=1;
|
||||
|
||||
/* set fileLength */
|
||||
struct stat stat;
|
||||
if (lstat(m->dataFileName,&stat)) {
|
||||
return WHY("Could not stat() associated file");
|
||||
}
|
||||
m->fileLength=stat.st_size;
|
||||
if (m->dataFileName[0]) {
|
||||
struct stat stat;
|
||||
if (lstat(m->dataFileName, &stat)) {
|
||||
WHY_perror("lstat");
|
||||
return WHY("Could not stat() associated file");
|
||||
}
|
||||
m->fileLength = stat.st_size;
|
||||
} else
|
||||
m->fileLength = 0;
|
||||
}
|
||||
|
||||
/* Set file hash and size information */
|
||||
|
@ -514,7 +514,7 @@ int rhizome_store_bundle(rhizome_manifest *m)
|
||||
|
||||
// we should add the file in the same transaction, but closing the blob seems to cause some issues.
|
||||
/* Store the file */
|
||||
#warning need to implement passing of encryption key for file here
|
||||
// TODO encrypted payloads - pass encryption key here
|
||||
if (m->fileLength>0){
|
||||
if (rhizome_store_file(m,NULL)){
|
||||
WHY("Could not store file");
|
||||
@ -724,10 +724,14 @@ int rhizome_store_file(rhizome_manifest *m,const unsigned char *key)
|
||||
return WHY("Cannot store bundle file until it has been hashed");
|
||||
|
||||
int fd=open(file,O_RDONLY);
|
||||
if (fd<0) return WHY("Could not open associated file");
|
||||
if (fd == -1) {
|
||||
WHY_perror("open");
|
||||
return WHY("Could not open associated file");
|
||||
}
|
||||
|
||||
struct stat stat;
|
||||
if (fstat(fd,&stat)) {
|
||||
WHY_perror("fstat");
|
||||
close(fd);
|
||||
return WHY("Could not stat() associated file");
|
||||
}
|
||||
@ -737,9 +741,9 @@ int rhizome_store_file(rhizome_manifest *m,const unsigned char *key)
|
||||
WARNF("File has grown by %lld bytes. I will just store the original number of bytes so that the hash (hopefully) matches",stat.st_size-m->fileLength);
|
||||
}
|
||||
|
||||
unsigned char *addr =
|
||||
mmap(NULL, m->fileLength, PROT_READ, MAP_FILE|MAP_SHARED, fd, 0);
|
||||
unsigned char *addr = mmap(NULL, m->fileLength, PROT_READ, MAP_FILE|MAP_SHARED, fd, 0);
|
||||
if (addr==MAP_FAILED) {
|
||||
WHY_perror("mmap");
|
||||
close(fd);
|
||||
return WHY("mmap() of associated file failed.");
|
||||
}
|
||||
|
@ -865,11 +865,10 @@ _tfw_failexit() {
|
||||
_tfw_errormsg() {
|
||||
[ $# -eq 0 ] && set -- "(no message)"
|
||||
local -i up=1
|
||||
while true; do
|
||||
case ${FUNCNAME[$up]} in
|
||||
_tfw_*) let up=up+1;;
|
||||
*) break;;
|
||||
esac
|
||||
local -i top=${#FUNCNAME[*]}
|
||||
let top=top-1
|
||||
while [ $up -lt $top -a "${BASH_SOURCE[$up]}" == "${BASH_SOURCE[0]}" ]; do
|
||||
let up=up+1
|
||||
done
|
||||
echo "ERROR in ${FUNCNAME[$up]}: $*"
|
||||
}
|
||||
|
@ -69,7 +69,8 @@ assert_rhizome_list() {
|
||||
}
|
||||
|
||||
assert_stdout_add_file() {
|
||||
local filename="$1"
|
||||
[ $# -ge 1 ] || error "missing filename arg"
|
||||
local filename="${1}"
|
||||
unpack_manifest_for_grep "$filename"
|
||||
assertStdoutLineCount '==' 6
|
||||
assertStdoutGrep --matches=1 "^service:$re_service\$"
|
||||
@ -83,7 +84,11 @@ assert_stdout_add_file() {
|
||||
unpack_manifest_for_grep() {
|
||||
local filename="$1"
|
||||
re_service="$rexp_service"
|
||||
re_size=$(( $(cat "$filename" | wc -c) + 0 ))
|
||||
if [ -n "$filename" ]; then
|
||||
re_size=$(( $(cat "$filename" | wc -c) + 0 ))
|
||||
else
|
||||
re_size=0
|
||||
fi
|
||||
compute_filehash re_filehash "$filename"
|
||||
re_manifestid="$rexp_manifestid"
|
||||
re_secret="$rexp_bundlesecret"
|
||||
@ -279,6 +284,26 @@ test_AddManifest() {
|
||||
assertGrep file1.manifest "^filesize=$re_size\$"
|
||||
}
|
||||
|
||||
doc_AddEmpty="Add with empty payload"
|
||||
setup_AddEmpty() {
|
||||
setup_servald_rhizome
|
||||
executeOk $servald rhizome list
|
||||
assert_rhizome_list
|
||||
}
|
||||
test_AddEmpty() {
|
||||
executeOk $servald rhizome add file $sid '' '' .manifest
|
||||
tfw_cat --stdout --stderr -v .manifest
|
||||
assert_stdout_add_file ''
|
||||
assertGrep .manifest '^service=file$'
|
||||
assertGrep .manifest "^BK=$rexp_bundlekey\$"
|
||||
assertGrep .manifest '^name=$'
|
||||
assertGrep .manifest "^version=$rexp_version\$"
|
||||
assertGrep .manifest "^date=$rexp_date\$"
|
||||
assertGrep .manifest "^id=$re_manifestid\$"
|
||||
assertGrep .manifest "^filehash=$re_filehash\$"
|
||||
assertGrep .manifest '^filesize=0$'
|
||||
}
|
||||
|
||||
doc_AddThenList="List contains one file after one add"
|
||||
setup_AddThenList() {
|
||||
setup_servald_rhizome
|
||||
|
Loading…
x
Reference in New Issue
Block a user