mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-04-07 19:14:17 +00:00
Make "rhizome add file" work for MeshMS
This commit is contained in:
parent
b739bfd572
commit
ddd17db1c4
@ -1092,11 +1092,13 @@ int app_rhizome_add_file(int argc, const char *const *argv, struct command_line_
|
||||
rhizome_manifest *m = NULL;
|
||||
int manifest_file_supplied = 0;
|
||||
if (manifestpath[0] && access(manifestpath, R_OK) == 0) {
|
||||
if (debug & DEBUG_RHIZOME) DEBUGF("reading manifest from %s", manifestpath);
|
||||
m = rhizome_read_manifest_file(manifestpath, 0, 0); // no verify
|
||||
if (!m)
|
||||
return WHY("Manifest file could not be loaded -- not added to rhizome");
|
||||
manifest_file_supplied = 1;
|
||||
} else {
|
||||
if (debug & DEBUG_RHIZOME) DEBUGF("manifest file %s does not exist", manifestpath);
|
||||
m = rhizome_new_manifest();
|
||||
if (!m)
|
||||
return WHY("Manifest struct could not be allocated -- not added to rhizome");
|
||||
@ -1109,15 +1111,23 @@ int app_rhizome_add_file(int argc, const char *const *argv, struct command_line_
|
||||
const char *service = rhizome_manifest_get(m, "service", NULL, 0);
|
||||
if (service == NULL) {
|
||||
rhizome_manifest_set(m, "service", (service = RHIZOME_SERVICE_FILE));
|
||||
if (debug & DEBUG_RHIZOME) DEBUGF("missing 'service', set default service=%s", service);
|
||||
} else {
|
||||
if (debug & DEBUG_RHIZOME) DEBUGF("manifest contains service=%s", service);
|
||||
}
|
||||
if (rhizome_manifest_get(m, "date", NULL, 0) == NULL) {
|
||||
rhizome_manifest_set_ll(m, "date", gettime_ms());
|
||||
if (debug & DEBUG_RHIZOME) DEBUGF("missing 'date', set default date=%s", rhizome_manifest_get(m, "date", NULL, 0));
|
||||
}
|
||||
if (strcasecmp(RHIZOME_SERVICE_FILE, service) == 0) {
|
||||
if (rhizome_manifest_get(m, "name", NULL, 0) == NULL) {
|
||||
const char *name = strrchr(filepath, '/');
|
||||
const char *name = rhizome_manifest_get(m, "name", NULL, 0);
|
||||
if (name == NULL) {
|
||||
name = strrchr(filepath, '/');
|
||||
name = name ? name + 1 : filepath;
|
||||
rhizome_manifest_set(m, "name", name);
|
||||
if (debug & DEBUG_RHIZOME) DEBUGF("missing 'name', set default name=\"%s\"", name);
|
||||
} else {
|
||||
if (debug & DEBUG_RHIZOME) DEBUGF("manifest contains name=\"%s\"", name);
|
||||
}
|
||||
}
|
||||
/* Add the manifest and its associated file to the Rhizome database, generating an "id" in the
|
||||
|
@ -159,11 +159,11 @@ int rhizome_add_manifest(rhizome_manifest *m_in,
|
||||
} else if (strcasecmp(service, RHIZOME_SERVICE_MESHMS) == 0) {
|
||||
const char *sender = rhizome_manifest_get(m_in, "sender", NULL, 0);
|
||||
const char *recipient = rhizome_manifest_get(m_in, "recipient", NULL, 0);
|
||||
if (sender == NULL || sender[0])
|
||||
if (sender == NULL || !sender[0])
|
||||
return WHY("Manifest missing 'sender' field");
|
||||
if (!validateSid(sender))
|
||||
return WHY("Manifest contains invalid 'sender' field");
|
||||
if (recipient == NULL || recipient[0])
|
||||
if (recipient == NULL || !recipient[0])
|
||||
return WHY("Manifest missing 'recipient' field");
|
||||
if (!validateSid(recipient))
|
||||
return WHY("Manifest contains invalid 'recipient' field");
|
||||
|
@ -31,8 +31,7 @@ rhizome_manifest *rhizome_read_manifest_file(const char *filename, int bufferP,
|
||||
if (bufferP) {
|
||||
m->manifest_bytes=bufferP;
|
||||
memcpy(m->manifestdata, filename, m->manifest_bytes);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
FILE *f=fopen(filename,"r");
|
||||
if (!f) {
|
||||
WHYF("Could not open manifest file %s for reading.", filename);
|
||||
@ -71,25 +70,25 @@ rhizome_manifest *rhizome_read_manifest_file(const char *filename, int bufferP,
|
||||
/* Parse property lines */
|
||||
/* This could be improved to parse Java's Properties.store() output, by handling backlash
|
||||
escapes and continuation lines */
|
||||
if (sscanf(line,"%[^=]=%[^\n\r]",var,value)==2)
|
||||
{
|
||||
if (rhizome_manifest_get(m,var,NULL,0)!=NULL) {
|
||||
if (debug&DEBUG_RHIZOME) fprintf(stderr, "Error in manifest file (duplicate variable \"%s\"-- keeping first value)\n", var);
|
||||
m->errors++;
|
||||
if (sscanf(line,"%[^=]=%[^\n\r]", var, value)==2) {
|
||||
if (rhizome_manifest_get(m,var,NULL,0)) {
|
||||
WARNF("Ill formed manifest file, duplicate variable \"%s\"-- keeping first value)", var);
|
||||
m->errors++;
|
||||
} else if (m->var_count<MAX_MANIFEST_VARS) {
|
||||
/*`
|
||||
if (debug & DEBUG_RHIZOME) {
|
||||
char buf[80];
|
||||
DEBUGF("read manifest line: %s=%s", var, catv(value, buf, sizeof buf));
|
||||
}
|
||||
if (m->var_count<MAX_MANIFEST_VARS)
|
||||
{
|
||||
m->vars[m->var_count]=strdup(var);
|
||||
m->values[m->var_count]=strdup(value);
|
||||
m->var_count++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Error in manifest file.
|
||||
Silently ignore for now. */
|
||||
WHY("Error in manifest file (badly formatted line).");
|
||||
*/
|
||||
m->vars[m->var_count]=strdup(var);
|
||||
m->values[m->var_count]=strdup(value);
|
||||
m->var_count++;
|
||||
}
|
||||
} else {
|
||||
char buf[80];
|
||||
WARNF("Skipping malformed line in manifest file %s: %s", bufferP ? "<buffer>" : filename, catv(line, buf, sizeof buf));
|
||||
}
|
||||
}
|
||||
/* The null byte gets included in the check sum */
|
||||
if (ofs<m->manifest_bytes) ofs++;
|
||||
@ -104,9 +103,7 @@ rhizome_manifest *rhizome_read_manifest_file(const char *filename, int bufferP,
|
||||
|
||||
/* Read signature blocks from file. */
|
||||
while(ofs<m->manifest_bytes) {
|
||||
if (debug&DEBUG_RHIZOME)
|
||||
fprintf(stderr,"ofs=0x%x, m->manifest_bytes=0x%x\n",
|
||||
ofs,m->manifest_bytes);
|
||||
if (debug & DEBUG_RHIZOME) DEBUGF("ofs=0x%x, m->manifest_bytes=0x%x", ofs,m->manifest_bytes);
|
||||
rhizome_manifest_extract_signature(m,&ofs);
|
||||
}
|
||||
|
||||
@ -117,10 +114,10 @@ rhizome_manifest *rhizome_read_manifest_file(const char *filename, int bufferP,
|
||||
/* Make sure that id variable is correct */
|
||||
{
|
||||
char *id=rhizome_manifest_get(m,"id",NULL,0);
|
||||
|
||||
if (!id) {
|
||||
if (debug&DEBUG_RHIZOME) fprintf(stderr,"Manifest lacks id variable.\n");
|
||||
m->errors++; }
|
||||
WARN("Manifest lacks 'id' field");
|
||||
m->errors++;
|
||||
}
|
||||
else {
|
||||
unsigned char manifest_bytes[crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES];
|
||||
rhizome_hex_to_bytes(id,manifest_bytes,
|
||||
@ -131,13 +128,12 @@ rhizome_manifest *rhizome_read_manifest_file(const char *filename, int bufferP,
|
||||
{
|
||||
if (debug&DEBUG_RHIZOME) {
|
||||
if (m->sig_count>0) {
|
||||
fprintf(stderr,
|
||||
"Manifest id variable does not match first signature block.\n");
|
||||
fprintf(stderr," (signature key is %s)\n",
|
||||
DEBUGF("Manifest id variable does not match first signature block (signature key is %s)",
|
||||
/* XXX bit of a hack that relies on SIDs and signing public keys being the same length */
|
||||
overlay_render_sid(&m->signatories[0][0]));
|
||||
overlay_render_sid(&m->signatories[0][0])
|
||||
);
|
||||
} else {
|
||||
fprintf(stderr,"Manifest has no signature blocks, but should have self-signature block");
|
||||
DEBUG("Manifest has no signature blocks, but should have self-signature block");
|
||||
}
|
||||
}
|
||||
m->errors++;
|
||||
@ -147,7 +143,7 @@ rhizome_manifest *rhizome_read_manifest_file(const char *filename, int bufferP,
|
||||
}
|
||||
|
||||
if (debug&DEBUG_RHIZOME)
|
||||
fprintf(stderr, "Group membership determination not implemented (see which signatories are groups? what about manifests signed by groups we don't yet know about?)\n");
|
||||
DEBUG("Group membership determination not implemented (see which signatories are groups? what about manifests signed by groups we don't yet know about?)");
|
||||
}
|
||||
|
||||
m->manifest_bytes=end_of_text;
|
||||
@ -404,7 +400,7 @@ int rhizome_manifest_pack_variables(rhizome_manifest *m)
|
||||
}
|
||||
m->manifestdata[ofs++]=0x00;
|
||||
m->manifest_bytes=ofs;
|
||||
if (debug&DEBUG_RHIZOME) fprintf(stderr, "Repacked variables in manifest.\n");
|
||||
if (debug&DEBUG_RHIZOME) DEBUG("Repacked variables in manifest.");
|
||||
m->manifest_all_bytes=ofs;
|
||||
|
||||
/* Recalculate hash */
|
||||
|
@ -537,29 +537,23 @@ char *rhizome_safe_encode(unsigned char *in,int len)
|
||||
|
||||
int rhizome_list_manifests(const char *service, const char *sender_sid, const char *recipient_sid, int limit, int offset)
|
||||
{
|
||||
char sqlcmd[1024];
|
||||
int n = snprintf(sqlcmd, sizeof(sqlcmd),
|
||||
strbuf b = strbuf_alloca(1024);
|
||||
strbuf_sprintf(b,
|
||||
"SELECT files.id, files.length, manifests.id, manifests.manifest, manifests.version, manifests.inserttime"
|
||||
" FROM files, filemanifests, manifests"
|
||||
" WHERE files.id = filemanifests.fileid AND filemanifests.manifestid = manifests.id AND files.datavalid <> 0"
|
||||
" ORDER BY files.id ASC"
|
||||
);
|
||||
if (n >= sizeof(sqlcmd))
|
||||
return WHY("SQL command too long");
|
||||
if (limit) {
|
||||
n += snprintf(&sqlcmd[n], sizeof(sqlcmd) - n, " LIMIT %u", limit);
|
||||
if (n >= sizeof(sqlcmd))
|
||||
return WHY("SQL command too long");
|
||||
}
|
||||
if (offset) {
|
||||
n += snprintf(&sqlcmd[n], sizeof(sqlcmd) - n, " OFFSET %u", offset);
|
||||
if (n >= sizeof(sqlcmd))
|
||||
return WHY("SQL command too long");
|
||||
}
|
||||
if (limit)
|
||||
strbuf_sprintf(b, " LIMIT %u", limit);
|
||||
if (offset)
|
||||
strbuf_sprintf(b, " OFFSET %u", offset);
|
||||
if (strbuf_overrun(b))
|
||||
return WHYF("SQL command too long: ", strbuf_str(b));
|
||||
sqlite3_stmt *statement;
|
||||
const char *cmdtail;
|
||||
int ret = 0;
|
||||
if (sqlite3_prepare_v2(rhizome_db, sqlcmd, strlen(sqlcmd) + 1, &statement, &cmdtail) != SQLITE_OK) {
|
||||
if (sqlite3_prepare_v2(rhizome_db, strbuf_str(b), strbuf_len(b) + 1, &statement, &cmdtail) != SQLITE_OK) {
|
||||
sqlite3_finalize(statement);
|
||||
ret = WHY(sqlite3_errmsg(rhizome_db));
|
||||
} else {
|
||||
@ -810,9 +804,23 @@ int rhizome_find_duplicate(const rhizome_manifest *m, rhizome_manifest **found)
|
||||
{
|
||||
if (!m->fileHashedP)
|
||||
return WHY("Manifest payload is not hashed");
|
||||
const char *name = rhizome_manifest_get(m, "name", NULL, 0);
|
||||
if (!name)
|
||||
return WHY("Manifest has no name");
|
||||
const char *service = rhizome_manifest_get(m, "service", NULL, 0);
|
||||
const char *name = NULL;
|
||||
const char *sender = NULL;
|
||||
const char *recipient = NULL;
|
||||
if (service == NULL) {
|
||||
return WHY("Manifest has no service");
|
||||
} else if (strcasecmp(service, RHIZOME_SERVICE_FILE) == 0) {
|
||||
name = rhizome_manifest_get(m, "name", NULL, 0);
|
||||
if (!name) return WHY("Manifest has no name");
|
||||
} else if (strcasecmp(service, RHIZOME_SERVICE_MESHMS) == 0) {
|
||||
sender = rhizome_manifest_get(m, "sender", NULL, 0);
|
||||
recipient = rhizome_manifest_get(m, "recipient", NULL, 0);
|
||||
if (!sender) return WHY("Manifest has no sender");
|
||||
if (!recipient) return WHY("Manifest has no recipient");
|
||||
} else {
|
||||
return WHYF("Unsupported service '%s'", service);
|
||||
}
|
||||
char sqlcmd[1024];
|
||||
char *s = sqlcmd;
|
||||
s += snprintf(s, &sqlcmd[sizeof sqlcmd] - s,
|
||||
@ -855,13 +863,13 @@ int rhizome_find_duplicate(const rhizome_manifest *m, rhizome_manifest **found)
|
||||
size_t manifestblobsize = sqlite3_column_bytes(statement, 1); // must call after sqlite3_column_blob()
|
||||
long long q_version = sqlite3_column_int64(statement, 2);
|
||||
rhizome_manifest *blob_m = rhizome_read_manifest_file(manifestblob, manifestblobsize, 0);
|
||||
const char *blob_service = rhizome_manifest_get(blob_m, "service", NULL, 0);
|
||||
const char *blob_id = rhizome_manifest_get(blob_m, "id", NULL, 0);
|
||||
const char *blob_name = rhizome_manifest_get(blob_m, "name", NULL, 0);
|
||||
long long blob_version = rhizome_manifest_get_ll(blob_m, "version");
|
||||
const char *blob_filehash = rhizome_manifest_get(blob_m, "filehash", NULL, 0);
|
||||
long long blob_filesize = rhizome_manifest_get_ll(blob_m, "filesize");
|
||||
if (debug & DEBUG_RHIZOME)
|
||||
DEBUGF("Consider manifest.id=%s manifest.name=\"%s\" manifest.version=%lld", q_manifestid, blob_name, blob_version);
|
||||
DEBUGF("Consider manifest.service=%s manifest.id=%s manifest.version=%lld", blob_service, q_manifestid, blob_version);
|
||||
/* Perform consistency checks, because we're paranoid. */
|
||||
int inconsistent = 0;
|
||||
if (blob_id && strcasecmp(blob_id, q_manifestid)) {
|
||||
@ -887,19 +895,40 @@ int rhizome_find_duplicate(const rhizome_manifest *m, rhizome_manifest **found)
|
||||
WARNF("SELECT query with version=%lld returned incorrect row: manifests.version=%lld -- skipped", m->version, q_version);
|
||||
++inconsistent;
|
||||
}
|
||||
/* The "name" comparison is the only one we can't do in the SELECT, so we do it here. */
|
||||
if (!inconsistent && blob_name && !strcmp(blob_name, name)) {
|
||||
rhizome_hex_to_bytes(q_manifestid, blob_m->cryptoSignPublic, crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES*2);
|
||||
memcpy(blob_m->fileHexHash, m->fileHexHash, SHA512_DIGEST_STRING_LENGTH);
|
||||
blob_m->fileHashedP = 1;
|
||||
blob_m->fileLength = m->fileLength;
|
||||
blob_m->version = q_version;
|
||||
*found = blob_m;
|
||||
if (debug & DEBUG_RHIZOME)
|
||||
DEBUGF("Found duplicate payload: name=\"%s\" version=%llu hexhash=%s -- not adding\n", blob_m, blob_m->version, blob_m->fileHexHash);
|
||||
ret = 1;
|
||||
if (debug & DEBUG_RHIZOME) DEBUG("found");
|
||||
break;
|
||||
if (blob_service == NULL) {
|
||||
WARNF("MANIFESTS row id=%s has blob with no 'service' -- skipped", q_manifestid, blob_id);
|
||||
++inconsistent;
|
||||
}
|
||||
if (!inconsistent) {
|
||||
strbuf b = strbuf_alloca(1024);
|
||||
if (strcasecmp(service, RHIZOME_SERVICE_FILE) == 0) {
|
||||
const char *blob_name = rhizome_manifest_get(blob_m, "name", NULL, 0);
|
||||
if (blob_name && !strcmp(blob_name, name)) {
|
||||
if (debug & DEBUG_RHIZOME)
|
||||
strbuf_sprintf(b, " name=\"%s\"", blob_name);
|
||||
ret = 1;
|
||||
}
|
||||
} else if (strcasecmp(service, RHIZOME_SERVICE_FILE) == 0) {
|
||||
const char *blob_sender = rhizome_manifest_get(blob_m, "sender", NULL, 0);
|
||||
const char *blob_recipient = rhizome_manifest_get(blob_m, "recipient", NULL, 0);
|
||||
if (blob_sender && !strcasecmp(blob_sender, sender) && blob_recipient && !strcasecmp(blob_recipient, recipient)) {
|
||||
if (debug & DEBUG_RHIZOME)
|
||||
strbuf_sprintf(b, " sender=%s recipient=%s", blob_sender, blob_recipient);
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
if (ret == 1) {
|
||||
rhizome_hex_to_bytes(q_manifestid, blob_m->cryptoSignPublic, crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES*2);
|
||||
memcpy(blob_m->fileHexHash, m->fileHexHash, SHA512_DIGEST_STRING_LENGTH);
|
||||
blob_m->fileHashedP = 1;
|
||||
blob_m->fileLength = m->fileLength;
|
||||
blob_m->version = q_version;
|
||||
*found = blob_m;
|
||||
DEBUGF("Found duplicate payload: service=%s%s version=%llu hexhash=%s",
|
||||
blob_service, strbuf_str(b), blob_m->version, blob_m->fileHexHash
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
rhizome_manifest_free(blob_m);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user