Change manifest service to MeshMS2

This commit is contained in:
Jeremy Lakeman 2013-08-01 11:37:35 +09:30
parent 2fa1cb3aec
commit 68bf04f69d
7 changed files with 183 additions and 271 deletions

View File

@ -119,7 +119,7 @@ static int get_database_conversations(const sid_t *my_sid, const sid_t *their_si
sqlite3_stmt *statement = sqlite_prepare(&retry,
"SELECT id, version, filesize, tail, sender, recipient "
"FROM manifests "
"WHERE service = 'MeshMS1' "
"WHERE service = '"RHIZOME_SERVICE_MESHMS2"' "
"AND (sender=?1 or recipient=?1) "
"AND (sender=?2 or recipient=?2)");
if (!statement)
@ -197,7 +197,7 @@ static int create_ply(const sid_t *my_sid, struct conversations *conv, rhizome_m
m->journalTail = 0;
const char *my_sidhex = alloca_tohex_sid(my_sid->binary);
const char *their_sidhex = alloca_tohex_sid(conv->them.binary);
rhizome_manifest_set(m, "service", RHIZOME_SERVICE_MESHMS);
rhizome_manifest_set(m, "service", RHIZOME_SERVICE_MESHMS2);
rhizome_manifest_set(m, "sender", my_sidhex);
rhizome_manifest_set(m, "recipient", their_sidhex);
rhizome_manifest_set_ll(m, "tail", m->journalTail);

View File

@ -137,36 +137,22 @@ int rhizome_bundle_import_files(rhizome_manifest *m, const char *manifest_path,
// This feels like a hack...
m->manifest_bytes=m->manifest_all_bytes;
/* Do we already have this manifest or newer? */
int64_t dbVersion = -1;
const char *id=rhizome_manifest_get(m, "id", NULL, 0);
if (sqlite_exec_int64(&dbVersion, "SELECT version FROM MANIFESTS WHERE id='%s';", id) == -1)
return WHY("Select failure");
if (dbVersion>=m->version)
return 2;
int status = rhizome_import_file(m, filepath);
if (status<0)
return status;
status = rhizome_manifest_check_duplicate(m, NULL, 0);
if (status)
return status;
return rhizome_add_manifest(m, 1);
}
/* Import a bundle from a finalised manifest struct. The dataFileName element must give the path
of a readable file containing the payload unless the payload is null (zero length). The logic is
all in rhizome_add_manifest(). This function just wraps that function and manages object buffers
and lifetimes.
*/
int rhizome_bundle_import(rhizome_manifest *m, int ttl)
{
if (config.debug.rhizome)
DEBUGF("(m=%p, ttl=%d)", m, ttl);
int ret = rhizome_manifest_check_duplicate(m, NULL, 0);
if (ret == 0) {
ret = rhizome_add_manifest(m, ttl);
if (ret == -1)
WHY("rhizome_add_manifest() failed");
}
return ret;
}
int rhizome_manifest_check_sanity(rhizome_manifest *m_in)
{
/* Ensure manifest meets basic sanity checks. */
@ -188,7 +174,8 @@ int rhizome_manifest_check_sanity(rhizome_manifest *m_in)
const char *name = rhizome_manifest_get(m_in, "name", NULL, 0);
if (name == NULL)
return WHY("Manifest missing 'name' field");
} else if (strcasecmp(service, RHIZOME_SERVICE_MESHMS) == 0) {
} else if (strcasecmp(service, RHIZOME_SERVICE_MESHMS) == 0
|| strcasecmp(service, RHIZOME_SERVICE_MESHMS2) == 0) {
if (sender == NULL || !sender[0])
return WHY("MeshMS Manifest missing 'sender' field");
if (!str_is_subscriber_id(sender))
@ -254,30 +241,6 @@ int rhizome_manifest_bind_id(rhizome_manifest *m_in)
return 0;
}
/* Check if a manifest is already stored for the same payload with the same details.
This catches the case of "rhizome add file <filename>" on the same file more than once.
(Debounce!) */
int rhizome_manifest_check_duplicate(rhizome_manifest *m_in, rhizome_manifest **m_out, int check_author)
{
if (config.debug.rhizome) DEBUG("Checking for duplicate");
if (m_out) *m_out = NULL;
rhizome_manifest *dupm = NULL;
if (rhizome_find_duplicate(m_in, &dupm, check_author) == -1)
return WHY("Errors encountered searching for duplicate manifest");
if (dupm) {
/* If the caller wants the duplicate manifest, it must be finalised, otherwise discarded. */
if (m_out) {
*m_out = dupm;
}
else
rhizome_manifest_free(dupm);
if (config.debug.rhizome) DEBUG("Found a duplicate");
return 2;
}
if (config.debug.rhizome) DEBUG("No duplicate found");
return 0;
}
int rhizome_add_manifest(rhizome_manifest *m_in,int ttl)
{
if (config.debug.rhizome)

View File

@ -108,6 +108,8 @@ typedef struct rhizome_manifest {
except the creator. */
unsigned char cryptoSignPublic[crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES];
unsigned char cryptoSignSecret[crypto_sign_edwards25519sha512batch_SECRETKEYBYTES];
/* Whether we have the secret for this manifest on hand */
int haveSecret;
int var_count;
char *vars[MAX_MANIFEST_VARS];
@ -121,7 +123,13 @@ typedef struct rhizome_manifest {
*/
unsigned char signatureTypes[MAX_MANIFEST_VARS];
int errors; /* if non-zero, then manifest should not be trusted */
// errors only involve the correctness of fields that are mandatory for
// proper operation of the transport and storage layer
int errors;
// a warning indicates that the manifest cannot be perfectly understood by this version of rhizome
// during add, the manifest should not be finalised and imported
// during extract an error should be displayed.
int warnings;
time_ms_t inserttime;
/* Set non-zero after variables have been packed and
@ -149,8 +157,6 @@ typedef struct rhizome_manifest {
unsigned char payloadKey[RHIZOME_CRYPT_KEY_BYTES];
unsigned char payloadNonce[crypto_stream_xsalsa20_NONCEBYTES];
/* Whether we have the secret for this manifest on hand */
int haveSecret;
/* Whether the manifest contains a signature that corresponds to the
manifest id (ie public key) */
int selfSigned;
@ -174,6 +180,7 @@ typedef struct rhizome_manifest {
*/
#define RHIZOME_SERVICE_FILE "file"
#define RHIZOME_SERVICE_MESHMS "MeshMS1"
#define RHIZOME_SERVICE_MESHMS2 "MeshMS2"
extern int64_t rhizome_space;
extern unsigned short rhizome_http_server_port;
@ -259,12 +266,10 @@ int rhizome_manifest_add_group(rhizome_manifest *m,char *groupid);
int rhizome_clean_payload(const char *fileidhex);
int rhizome_store_file(rhizome_manifest *m,const unsigned char *key);
int rhizome_bundle_import_files(rhizome_manifest *m, const char *manifest_path, const char *filepath);
int rhizome_bundle_import(rhizome_manifest *m, int ttl);
int rhizome_fill_manifest(rhizome_manifest *m, const char *filepath, const sid_t *authorSid, rhizome_bk_t *bsk);
int rhizome_manifest_verify(rhizome_manifest *m);
int rhizome_manifest_check_sanity(rhizome_manifest *m_in);
int rhizome_manifest_check_duplicate(rhizome_manifest *m_in,rhizome_manifest **m_out, int check_author);
int rhizome_manifest_bind_id(rhizome_manifest *m_in);
int rhizome_manifest_finalise(rhizome_manifest *m, rhizome_manifest **mout);
@ -321,7 +326,7 @@ int _sqlite_vexec_strbuf_retry(struct __sourceloc, sqlite_retry_state *retry, st
double rhizome_manifest_get_double(rhizome_manifest *m,char *var,double default_value);
int rhizome_manifest_extract_signature(rhizome_manifest *m,int *ofs);
int rhizome_update_file_priority(const char *fileid);
int rhizome_find_duplicate(const rhizome_manifest *m, rhizome_manifest **found, int check_author);
int rhizome_find_duplicate(const rhizome_manifest *m, rhizome_manifest **found);
int rhizome_manifest_to_bar(rhizome_manifest *m,unsigned char *bar);
int64_t rhizome_bar_version(const unsigned char *bar);
uint64_t rhizome_bar_bidprefix_ll(unsigned char *bar);

View File

@ -84,29 +84,22 @@ int rhizome_manifest_verify(rhizome_manifest *m)
else return 0;
}
int rhizome_read_manifest_file(rhizome_manifest *m, const char *filename, int bufferP)
int read_whole_file(const char *filename, unsigned char *buffer, int buffer_size)
{
FILE *f = fopen(filename, "r");
if (f == NULL)
return WHYF("Could not open file %s for reading", filename);
int ret = fread(buffer, 1, buffer_size, f);
if (ret == -1)
ret = WHY_perror("fread");
if (fclose(f) == EOF)
ret = WHY_perror("fclose");
return ret;
}
int rhizome_manifest_parse(rhizome_manifest *m)
{
IN();
if (bufferP>MAX_MANIFEST_BYTES) RETURN(WHY("Buffer too big"));
if (!m) RETURN(WHY("Null manifest"));
if (bufferP) {
m->manifest_bytes=bufferP;
memcpy(m->manifestdata, filename, m->manifest_bytes);
} else {
FILE *f = fopen(filename, "r");
if (f == NULL)
RETURN(WHYF("Could not open manifest file %s for reading.", filename));
m->manifest_bytes = fread(m->manifestdata, 1, MAX_MANIFEST_BYTES, f);
int ret = 0;
if (m->manifest_bytes == -1)
ret = WHY_perror("fread");
if (fclose(f) == EOF)
ret = WHY_perror("fclose");
if (ret == -1)
RETURN(-1);
}
m->manifest_all_bytes=m->manifest_bytes;
m->var_count=0;
m->journalTail=-1;
@ -118,6 +111,7 @@ int rhizome_read_manifest_file(rhizome_manifest *m, const char *filename, int bu
int have_date = 0;
int have_filesize = 0;
int have_filehash = 0;
int ofs = 0;
while (ofs < m->manifest_bytes && m->manifestdata[ofs]) {
char line[1024];
@ -143,9 +137,7 @@ int rhizome_read_manifest_file(rhizome_manifest *m, const char *filename, int bu
p = strchr(line, '=');
if (p == NULL || p == line) {
m->errors++;
WARNF(bufferP ? "Malformed manifest line in buffer %p: %s"
: "Malformed manifest line in file %s: %s",
filename, alloca_toprint(80, line, linelen));
WARNF("Malformed manifest line: %s", alloca_toprint(80, line, linelen));
} else {
*p++ = '\0';
char *var = line;
@ -161,6 +153,9 @@ int rhizome_read_manifest_file(rhizome_manifest *m, const char *filename, int bu
} else {
m->vars[m->var_count] = strdup(var);
m->values[m->var_count] = strdup(value);
// if any of these fields are not well formed, the manifest is invalid and cannot be imported
if (strcasecmp(var, "id") == 0) {
have_id = 1;
if (fromhexstr(m->cryptoSignPublic, value, RHIZOME_MANIFEST_ID_BYTES) == -1) {
@ -182,15 +177,6 @@ int rhizome_read_manifest_file(rhizome_manifest *m, const char *filename, int bu
str_toupper_inplace(m->values[m->var_count]);
strcpy(m->fileHexHash, m->values[m->var_count]);
}
} else if (strcasecmp(var, "BK") == 0) {
if (!rhizome_str_is_bundle_key(value)) {
if (config.debug.rejecteddata)
WARNF("Invalid BK: %s", value);
m->errors++;
} else {
/* Force to upper case to avoid case sensitive comparison problems later. */
str_toupper_inplace(m->values[m->var_count]);
}
} else if (strcasecmp(var, "filesize") == 0) {
have_filesize = 1;
char *ep = value;
@ -202,14 +188,6 @@ int rhizome_read_manifest_file(rhizome_manifest *m, const char *filename, int bu
} else {
m->fileLength = filesize;
}
} else if (strcasecmp(var, "service") == 0) {
have_service = 1;
if ( strcasecmp(value, RHIZOME_SERVICE_FILE) == 0
|| strcasecmp(value, RHIZOME_SERVICE_MESHMS) == 0) {
} else {
INFOF("Unsupported service: %s", value);
// This is not an error... older rhizome nodes must carry newer manifests.
}
} else if (strcasecmp(var, "version") == 0) {
have_version = 1;
char *ep = value;
@ -221,6 +199,40 @@ int rhizome_read_manifest_file(rhizome_manifest *m, const char *filename, int bu
} else {
m->version = version;
}
// since rhizome *MUST* be able to carry future manifest versions
// if any of these fields are not well formed, the manifest can still be imported and exported
// but the bundle should not be added or exported
} else if (strcasecmp(var, "tail") == 0) {
char *ep = value;
long long tail = strtoll(value, &ep, 10);
if (ep == value || *ep || tail < 0) {
if (config.debug.rejecteddata)
WARNF("Invalid tail: %s", value);
m->warnings++;
} else {
m->journalTail = tail;
}
} else if (strcasecmp(var, "BK") == 0) {
if (!rhizome_str_is_bundle_key(value)) {
if (config.debug.rejecteddata)
WARNF("Invalid BK: %s", value);
m->warnings++;
} else {
/* Force to upper case to avoid case sensitive comparison problems later. */
str_toupper_inplace(m->values[m->var_count]);
}
} else if (strcasecmp(var, "service") == 0) {
have_service = 1;
if ( strcasecmp(value, RHIZOME_SERVICE_FILE) == 0
|| strcasecmp(value, RHIZOME_SERVICE_MESHMS) == 0
|| strcasecmp(value, RHIZOME_SERVICE_MESHMS2) == 0) {
} else {
if (config.debug.rejecteddata)
WARNF("Unsupported service: %s", value);
m->warnings++;
}
} else if (strcasecmp(var, "date") == 0) {
have_date = 1;
char *ep = value;
@ -228,14 +240,14 @@ int rhizome_read_manifest_file(rhizome_manifest *m, const char *filename, int bu
if (ep == value || *ep || date < 0) {
if (config.debug.rejecteddata)
WARNF("Invalid date: %s", value);
m->errors++;
m->warnings++;
}
// TODO: store date in manifest struct
} else if (strcasecmp(var, "sender") == 0 || strcasecmp(var, "recipient") == 0) {
if (!str_is_subscriber_id(value)) {
if (config.debug.rejecteddata)
WARNF("Invalid %s: %s", var, value);
m->errors++;
m->warnings++;
} else {
/* Force to upper case to avoid case sensitive comparison problems later. */
str_toupper_inplace(m->values[m->var_count]);
@ -244,30 +256,18 @@ int rhizome_read_manifest_file(rhizome_manifest *m, const char *filename, int bu
if (value[0] == '\0') {
if (config.debug.rejecteddata)
WARN("Empty name");
m->errors++;
m->warnings++;
}
// TODO: complain if service is not MeshMS
} else if (strcasecmp(var, "crypt") == 0) {
if (!(strcmp(value, "0") == 0 || strcmp(value, "1") == 0)) {
if (config.debug.rejecteddata)
WARNF("Invalid crypt: %s", value);
m->errors++;
m->warnings++;
} else {
m->payloadEncryption = atoi(value);
}
} else if (strcasecmp(var, "tail") == 0) {
char *ep = value;
long long tail = strtoll(value, &ep, 10);
if (ep == value || *ep || tail < 0) {
if (config.debug.rejecteddata)
WARNF("Invalid tail: %s", value);
m->errors++;
} else {
m->journalTail = tail;
}
} else {
INFOF("Unsupported field: %s=%s", var, value);
// This is not an error... older rhizome nodes must carry newer manifests.
// An unknown field is not an error... older rhizome nodes must carry newer manifests.
}
m->var_count++;
}
@ -281,11 +281,7 @@ int rhizome_read_manifest_file(rhizome_manifest *m, const char *filename, int bu
int end_of_text=ofs;
m->manifest_bytes = end_of_text;
if (!have_service) {
if (config.debug.rejecteddata)
WARNF("Missing service field");
m->errors++;
}
// verify that all required fields are consistent.
if (!have_id) {
if (config.debug.rejecteddata)
WARNF("Missing manifest id field");
@ -296,11 +292,6 @@ int rhizome_read_manifest_file(rhizome_manifest *m, const char *filename, int bu
WARNF("Missing version field");
m->errors++;
}
if (!have_date) {
if (config.debug.rejecteddata)
WARNF("Missing date field");
m->errors++;
}
if (!have_filesize) {
if (config.debug.rejecteddata)
WARNF("Missing filesize field");
@ -317,9 +308,21 @@ int rhizome_read_manifest_file(rhizome_manifest *m, const char *filename, int bu
m->errors++;
}
// warn if expected fields are missing
if (!have_service) {
if (config.debug.rejecteddata)
WARNF("Missing service field");
m->warnings++;
}
if (!have_date) {
if (config.debug.rejecteddata)
WARNF("Missing date field");
m->warnings++;
}
// TODO Determine group membership here.
if (m->errors) {
if (m->errors || m->warnings) {
if (config.debug.rejecteddata)
dump("manifest body",m->manifestdata,m->manifest_bytes);
}
@ -328,6 +331,24 @@ int rhizome_read_manifest_file(rhizome_manifest *m, const char *filename, int bu
OUT();
}
int rhizome_read_manifest_file(rhizome_manifest *m, const char *filename, int bufferP)
{
if (!m)
return WHY("Null manifest");
if (bufferP>sizeof(m->manifestdata))
return WHY("Buffer too big");
if (bufferP) {
m->manifest_bytes=bufferP;
memcpy(m->manifestdata, filename, m->manifest_bytes);
} else {
m->manifest_bytes = read_whole_file(filename, m->manifestdata, sizeof(m->manifestdata));
if (m->manifest_bytes == -1)
return -1;
}
return rhizome_manifest_parse(m);
}
int rhizome_hash_file(rhizome_manifest *m,const char *filename,char *hash_out)
{
/* Gnarf! NaCl's crypto_hash() function needs the whole file passed in in one
@ -680,11 +701,8 @@ int rhizome_manifest_finalise(rhizome_manifest *m, rhizome_manifest **mout)
// if a manifest was supplied with an ID, don't bother to check for a duplicate.
// we only want to filter out added files with no existing manifest.
if (m->haveSecret==NEW_BUNDLE_ID){
if (rhizome_manifest_check_duplicate(m, mout, 1) == 2) {
/* duplicate found -- verify it so that we can write it out later */
rhizome_manifest_verify(*mout);
if (rhizome_find_duplicate(m, mout)==1)
RETURN(2);
}
}
*mout=m;

View File

@ -1232,171 +1232,96 @@ int rhizome_update_file_priority(const char *fileid)
@author Andrew Bettison <andrew@servalproject.com>
*/
int rhizome_find_duplicate(const rhizome_manifest *m, rhizome_manifest **found, int check_author)
int rhizome_find_duplicate(const rhizome_manifest *m, rhizome_manifest **found)
{
// TODO, add service, name, sender & recipient to manifests table so we can simply query them.
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) {
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);
}
const char *name = rhizome_manifest_get(m, "name", NULL, 0);
const char *sender = rhizome_manifest_get(m, "sender", NULL, 0);
const char *recipient = rhizome_manifest_get(m, "recipient", NULL, 0);
char sqlcmd[1024];
strbuf b = strbuf_local(sqlcmd, sizeof sqlcmd);
strbuf_puts(b, "SELECT id, manifest, version, author FROM manifests WHERE ");
if (m->fileLength != 0) {
strbuf_puts(b, "filehash = ?");
} else
strbuf_puts(b, "filesize = 0");
strbuf_puts(b, "SELECT id, manifest, author FROM manifests WHERE filesize = ? AND service = ?");
if (m->fileLength != 0)
strbuf_puts(b, " AND filehash = ?");
if (name)
strbuf_puts(b, " AND name = ?");
if (sender)
strbuf_puts(b, " AND sender = ?");
if (recipient)
strbuf_puts(b, " AND recipient = ?");
if (strbuf_overrun(b))
return WHYF("SQL command too long: %s", strbuf_str(b));
int ret = 0;
sqlite_retry_state retry = SQLITE_RETRY_STATE_DEFAULT;
sqlite3_stmt *statement = sqlite_prepare(&retry, "%s", strbuf_str(b));
if (!statement)
return -1;
int field = 1;
char filehash[RHIZOME_FILEHASH_STRLEN + 1];
if (m->fileLength != 0) {
strncpy(filehash, m->fileHexHash, sizeof filehash);
str_toupper_inplace(filehash);
if (config.debug.rhizome)
DEBUGF("filehash=\"%s\"", filehash);
sqlite3_bind_text(statement, field++, filehash, -1, SQLITE_STATIC);
}
sqlite3_bind_int(statement, field++, m->fileLength);
sqlite3_bind_text(statement, field++, service, -1, SQLITE_STATIC);
if (m->fileLength != 0)
sqlite3_bind_text(statement, field++, m->fileHexHash, -1, SQLITE_STATIC);
if (name)
sqlite3_bind_text(statement, field++, name, -1, SQLITE_STATIC);
if (sender)
sqlite3_bind_text(statement, field++, sender, -1, SQLITE_STATIC);
if (recipient)
sqlite3_bind_text(statement, field++, recipient, -1, SQLITE_STATIC);
int rows = 0;
while (sqlite_step_retry(&retry, statement) == SQLITE_ROW) {
++rows;
if (config.debug.rhizome) DEBUGF("Row %d", rows);
if (!( sqlite3_column_count(statement) == 4
&& sqlite3_column_type(statement, 0) == SQLITE_TEXT
&& sqlite3_column_type(statement, 1) == SQLITE_BLOB
&& sqlite3_column_type(statement, 2) == SQLITE_INTEGER
&& ( sqlite3_column_type(statement, 3) == SQLITE_TEXT
|| sqlite3_column_type(statement, 3) == SQLITE_NULL
)
)) {
ret = WHY("Incorrect statement columns");
break;
}
const char *q_manifestid = (const char *) sqlite3_column_text(statement, 0);
size_t manifestidsize = sqlite3_column_bytes(statement, 0); // must call after sqlite3_column_text()
unsigned char manifest_id[RHIZOME_MANIFEST_ID_BYTES];
if ( manifestidsize != crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES * 2
|| fromhexstr(manifest_id, q_manifestid, RHIZOME_MANIFEST_ID_BYTES) == -1
) {
ret = WHYF("Malformed manifest.id from query: %s", q_manifestid);
break;
}
const char *manifestblob = (char *) sqlite3_column_blob(statement, 1);
size_t manifestblobsize = sqlite3_column_bytes(statement, 1); // must call after sqlite3_column_blob()
int64_t q_version = sqlite3_column_int64(statement, 2);
const char *q_author = (const char *) sqlite3_column_text(statement, 3);
if (config.debug.rhizome)
DEBUGF("Row %d", rows);
rhizome_manifest *blob_m = rhizome_new_manifest();
if (blob_m == NULL) {
ret = WHY("Out of manifests");
break;
}
const unsigned char *q_manifestid = sqlite3_column_text(statement, 0);
const char *manifestblob = (char *) sqlite3_column_blob(statement, 1);
size_t manifestblobsize = sqlite3_column_bytes(statement, 1); // must call after sqlite3_column_blob()
if (rhizome_read_manifest_file(blob_m, manifestblob, manifestblobsize) == -1) {
WARNF("MANIFESTS row id=%s has invalid manifest blob -- skipped", q_manifestid);
} else if (rhizome_manifest_verify(blob_m)) {
WARNF("MANIFESTS row id=%s fails verification -- skipped", q_manifestid);
} else {
const char *blob_service = rhizome_manifest_get(blob_m, "service", NULL, 0);
const char *blob_id = rhizome_manifest_get(blob_m, "id", NULL, 0);
int64_t blob_version = rhizome_manifest_get_ll(blob_m, "version");
const char *blob_filehash = rhizome_manifest_get(blob_m, "filehash", NULL, 0);
int64_t blob_filesize = rhizome_manifest_get_ll(blob_m, "filesize");
if (config.debug.rhizome)
DEBUGF("Consider manifest.service=%s manifest.id=%s manifest.version=%"PRId64, blob_service, q_manifestid, blob_version);
if (q_author) {
if (config.debug.rhizome)
strbuf_sprintf(b, " .author=%s", q_author);
stowSid(blob_m->author, 0, q_author);
}
/* Perform consistency checks, because we're paranoid. */
int inconsistent = 0;
if (blob_id && strcasecmp(blob_id, q_manifestid)) {
WARNF("MANIFESTS row id=%s has inconsistent blob with id=%s -- skipped", q_manifestid, blob_id);
++inconsistent;
}
if (blob_version != q_version) {
WARNF("MANIFESTS row id=%s has inconsistent blob: manifests.version=%"PRId64", blob.version=%"PRId64" -- skipped",
q_manifestid, q_version, blob_version);
++inconsistent;
}
if (blob_filesize != -1 && blob_filesize != m->fileLength) {
WARNF("MANIFESTS row id=%s has inconsistent blob: known file size %"PRId64", blob.filesize=%"PRId64" -- skipped",
q_manifestid, m->fileLength, blob_filesize);
++inconsistent;
}
if (m->fileLength != 0) {
if (!blob_filehash && strcasecmp(blob_filehash, m->fileHexHash)) {
WARNF("MANIFESTS row id=%s has inconsistent blob: manifests.filehash=%s, blob.filehash=%s -- skipped",
q_manifestid, m->fileHexHash, blob_filehash);
++inconsistent;
}
} else {
if (blob_filehash) {
WARNF("MANIFESTS row id=%s has inconsistent blob: blob.filehash should be absent -- skipped",
q_manifestid);
++inconsistent;
}
}
if (blob_service == NULL) {
WARNF("MANIFESTS row id=%s has blob with no 'service' -- skipped", q_manifestid);
++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 (config.debug.rhizome)
strbuf_sprintf(b, " name=\"%s\"", blob_name);
}else
++inconsistent;
} else if (strcasecmp(service, RHIZOME_SERVICE_MESHMS) == 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 (config.debug.rhizome)
strbuf_sprintf(b, " sender=%s recipient=%s", blob_sender, blob_recipient);
}else
++inconsistent;
}
}
if ((!inconsistent) && check_author) {
// check that we can re-author this manifest
if (rhizome_extract_privatekey(blob_m, NULL))
++inconsistent;
}
if (!inconsistent) {
*found = blob_m;
if (config.debug.rhizome)
DEBUGF("Found duplicate payload: service=%s%s version=%"PRIu64" hexhash=%s",
blob_service, strbuf_str(b), blob_m->version, blob_m->fileHexHash
);
ret = 1;
break;
}
goto next;
}
if (rhizome_manifest_verify(blob_m)) {
WARNF("MANIFESTS row id=%s fails verification -- skipped", q_manifestid);
goto next;
}
const char *q_author = (const char *) sqlite3_column_text(statement, 2);
if (q_author) {
if (config.debug.rhizome)
strbuf_sprintf(b, " .author=%s", q_author);
stowSid(blob_m->author, 0, q_author);
}
// check that we can re-author this manifest
if (rhizome_extract_privatekey(blob_m, NULL)){
goto next;
}
*found = blob_m;
if (config.debug.rhizome)
DEBUGF("Found duplicate payload, %s", q_manifestid);
ret = 1;
break;
next:
if (blob_m)
rhizome_manifest_free(blob_m);
}

View File

@ -396,7 +396,7 @@ static int rhizome_import_received_bundle(struct rhizome_manifest *m)
m->manifest_bytes, m->sig_count,(long long)m->fileLength);
dump("manifest", m->manifestdata, m->manifest_all_bytes);
}
return rhizome_bundle_import(m, m->ttl - 1 /* TTL */);
return rhizome_add_manifest(m, m->ttl - 1 /* TTL */);
}
static int schedule_fetch(struct rhizome_fetch_slot *slot)

View File

@ -29,6 +29,7 @@ includeTests dnahelper
includeTests dnaprotocol
includeTests rhizomeops
includeTests rhizomeprotocol
includeTests meshms
includeTests directory_service
runTests "$@"