mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-04-26 22:10:09 +00:00
All rhizome database keys are uppercase hex
FILES.id, MANIFESTS.id, FILEMANIFESTS.fileid, FILEMANIFESTS.manifestid Named constants for hex and binary ID sizes
This commit is contained in:
parent
e1c30b8ed8
commit
1af9125392
@ -1119,7 +1119,7 @@ int app_rhizome_hash_file(int argc, const char *const *argv, struct command_line
|
||||
{
|
||||
const char *filepath;
|
||||
cli_arg(argc, argv, o, "filepath", &filepath, NULL, "");
|
||||
char hexhash[SHA512_DIGEST_STRING_LENGTH];
|
||||
char hexhash[RHIZOME_FILEHASH_STRLEN + 1];
|
||||
if (rhizome_hash_file(filepath, hexhash))
|
||||
return -1;
|
||||
cli_puts(hexhash);
|
||||
@ -1206,19 +1206,16 @@ int app_rhizome_add_file(int argc, const char *const *argv, struct command_line_
|
||||
ret = WHY("Could not overwrite manifest file.");
|
||||
service = rhizome_manifest_get(mout, "service", NULL, 0);
|
||||
if (service) {
|
||||
cli_puts("service"); cli_delim(":");
|
||||
cli_puts(service); cli_delim("\n");
|
||||
cli_puts("service"); cli_delim(":"); cli_puts(service); cli_delim("\n");
|
||||
}
|
||||
cli_puts("manifestid"); cli_delim(":");
|
||||
cli_puts(rhizome_bytes_to_hex(mout->cryptoSignPublic, crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES)); cli_delim("\n");
|
||||
cli_puts("filehash"); cli_delim(":");
|
||||
cli_puts(mout->fileHexHash); cli_delim("\n");
|
||||
cli_puts("filesize"); cli_delim(":");
|
||||
cli_printf("%lld", mout->fileLength); cli_delim("\n");
|
||||
char bid[RHIZOME_MANIFEST_ID_STRLEN + 1];
|
||||
rhizome_bytes_to_hex_upper(mout->cryptoSignPublic, bid, RHIZOME_MANIFEST_ID_BYTES);
|
||||
cli_puts("manifestid"); cli_delim(":"); cli_puts(bid); cli_delim("\n");
|
||||
cli_puts("filehash"); cli_delim(":"); cli_puts(mout->fileHexHash); cli_delim("\n");
|
||||
cli_puts("filesize"); cli_delim(":"); cli_printf("%lld", mout->fileLength); cli_delim("\n");
|
||||
const char *name = rhizome_manifest_get(mout, "name", NULL, 0);
|
||||
if (name) {
|
||||
cli_puts("name"); cli_delim(":");
|
||||
cli_puts(name); cli_delim("\n");
|
||||
cli_puts("name"); cli_delim(":"); cli_puts(name); cli_delim("\n");
|
||||
}
|
||||
rhizome_manifest_free(m);
|
||||
if (mout != m)
|
||||
|
@ -155,6 +155,13 @@ int stowBytes(unsigned char *packet, const char *in,int count)
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *str_toupper_inplace(char *str)
|
||||
{
|
||||
register char *s;
|
||||
for (s = str; *s; ++s)
|
||||
*s = toupper(*s);
|
||||
return str;
|
||||
}
|
||||
|
||||
int hexvalue(unsigned char c)
|
||||
{
|
||||
|
11
monitor.c
11
monitor.c
@ -539,12 +539,17 @@ int monitor_announce_bundle(rhizome_manifest *m)
|
||||
{
|
||||
int i;
|
||||
char msg[1024];
|
||||
snprintf(msg,1024,"\nBUNDLE:%s:%lld:%lld:%s\n",
|
||||
/* XXX bit of a hack here, since SIDs and
|
||||
cryptosign public keys have the same length */
|
||||
const char *service = rhizome_manifest_get(m, "service", NULL, 0);
|
||||
const char *sender = rhizome_manifest_get(m, "sender", NULL, 0);
|
||||
const char *recipient = rhizome_manifest_get(m, "recipient", NULL, 0);
|
||||
snprintf(msg,1024,"\nBUNDLE:%s:%s:%lld:%lld:%s:%s:%s\n",
|
||||
/* XXX bit of a hack here, since SIDs and cryptosign public keys have the same length */
|
||||
overlay_render_sid(m->cryptoSignPublic),
|
||||
service ? service : "",
|
||||
m->version,
|
||||
m->fileLength,
|
||||
sender,
|
||||
recipient,
|
||||
m->dataFileName?m->dataFileName:"");
|
||||
for(i=0;i<monitor_socket_count;i++)
|
||||
{
|
||||
|
36
rhizome.c
36
rhizome.c
@ -156,10 +156,11 @@ int rhizome_add_manifest(rhizome_manifest *m_in,
|
||||
int verifyP, // verify that file's hash is consistent with manifest
|
||||
int checkFileP,
|
||||
int signP,
|
||||
const char *author // NULL to make an unauthored manifest
|
||||
const char *author // NULL or zero-length to make an unauthored manifest
|
||||
)
|
||||
{
|
||||
if (m_out) *m_out = NULL;
|
||||
if (author && !author[0]) author = NULL;
|
||||
|
||||
/* Ensure manifest meets basic sanity checks. */
|
||||
const char *service = rhizome_manifest_get(m_in, "service", NULL, 0);
|
||||
@ -180,7 +181,7 @@ int rhizome_add_manifest(rhizome_manifest *m_in,
|
||||
return WHY("Manifest contains invalid 'sender' field");
|
||||
/* If the author was not specified, use the 'sender' as the author, otherwise ensure that they
|
||||
match. */
|
||||
if (!author || !author[0])
|
||||
if (!author)
|
||||
author = sender;
|
||||
else if (strcasecmp(author, sender))
|
||||
return WHYF("Author inconsistent with sender: author=%s, sender=%s", author, sender);
|
||||
@ -189,6 +190,7 @@ int rhizome_add_manifest(rhizome_manifest *m_in,
|
||||
if (!validateSid(recipient))
|
||||
return WHY("Manifest contains invalid 'recipient' field");
|
||||
}
|
||||
if (debug & DEBUG_RHIZOME) DEBUGF("author='%s'", author ? author : "(null)");
|
||||
|
||||
/* Keep payload file name handy for later */
|
||||
m_in->dataFileName = strdup(filename);
|
||||
@ -217,10 +219,10 @@ int rhizome_add_manifest(rhizome_manifest *m_in,
|
||||
|
||||
/* Compute hash of payload unless we know verification has already failed */
|
||||
if (checkFileP || signP) {
|
||||
char hexhash[SHA512_DIGEST_STRING_LENGTH];
|
||||
char hexhash[RHIZOME_FILEHASH_STRLEN + 1];
|
||||
if (rhizome_hash_file(filename, hexhash))
|
||||
return WHY("Could not hash file.");
|
||||
memcpy(&m_in->fileHexHash[0], &hexhash[0], SHA512_DIGEST_STRING_LENGTH);
|
||||
memcpy(&m_in->fileHexHash[0], &hexhash[0], sizeof hexhash);
|
||||
m_in->fileHashedP = 1;
|
||||
}
|
||||
|
||||
@ -269,12 +271,13 @@ int rhizome_add_manifest(rhizome_manifest *m_in,
|
||||
}
|
||||
|
||||
/* If the manifest already has an ID */
|
||||
char *id = NULL;
|
||||
if ((id = rhizome_manifest_get(m_in, "id", NULL, 0))) {
|
||||
char id[SID_STRLEN + 1];
|
||||
if (rhizome_manifest_get(m_in, "id", id, SID_STRLEN + 1)) {
|
||||
str_toupper_inplace(id);
|
||||
/* Discard the new manifest unless it is newer than the most recent known version with the same ID */
|
||||
long long storedversion = sqlite_exec_int64("SELECT version from manifests where id='%s';", id);
|
||||
if (debug & DEBUG_RHIZOME)
|
||||
fprintf(stderr, "Found existing version=%lld, new version=%lld\n", storedversion, m_in->version);
|
||||
DEBUGF("Found existing version=%lld, new version=%lld", storedversion, m_in->version);
|
||||
if (m_in->version < storedversion) {
|
||||
return WHY("Newer version exists");
|
||||
}
|
||||
@ -283,7 +286,7 @@ int rhizome_add_manifest(rhizome_manifest *m_in,
|
||||
}
|
||||
/* Check if we know its private key */
|
||||
rhizome_hex_to_bytes(id, m_in->cryptoSignPublic, crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES*2);
|
||||
if (!rhizome_extract_privatekey(m_in, author))
|
||||
if (rhizome_extract_privatekey(m_in, author) == 0)
|
||||
m_in->haveSecret=1;
|
||||
} else {
|
||||
/* The manifest had no ID (256 bit random string being a public key in the NaCl CryptoSign
|
||||
@ -293,7 +296,7 @@ int rhizome_add_manifest(rhizome_manifest *m_in,
|
||||
manifests on receiver nodes works easily. We might implement something that strips the id
|
||||
variable out of the manifest when sending it, or some other scheme to avoid sending all the
|
||||
extra bytes. */
|
||||
id = rhizome_bytes_to_hex(m_in->cryptoSignPublic, crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES);
|
||||
rhizome_bytes_to_hex_upper(m_in->cryptoSignPublic, id, crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES);
|
||||
rhizome_manifest_set(m_in, "id", id);
|
||||
if (author) {
|
||||
/* Set the BK using the provided authorship information.
|
||||
@ -303,11 +306,12 @@ int rhizome_add_manifest(rhizome_manifest *m_in,
|
||||
The nice thing about this specification is that:
|
||||
privateKey = BK XOR sha512(RS##BID), so the same function can be used
|
||||
to encrypt and decrypt the BK field. */
|
||||
int len=crypto_sign_edwards25519sha512batch_SECRETKEYBYTES;
|
||||
unsigned char bkbytes[len];
|
||||
if (!rhizome_bk_xor(author, m_in->cryptoSignPublic, m_in->cryptoSignSecret, bkbytes)) {
|
||||
if (debug&DEBUG_RHIZOME) DEBUGF("set BK='%s'", rhizome_bytes_to_hex(bkbytes,len));
|
||||
rhizome_manifest_set(m_in, "BK", rhizome_bytes_to_hex(bkbytes,len));
|
||||
unsigned char bkbytes[RHIZOME_BUNDLE_KEY_BYTES];
|
||||
if (rhizome_bk_xor(author, m_in->cryptoSignPublic, m_in->cryptoSignSecret, bkbytes) == 0) {
|
||||
char bkhex[RHIZOME_BUNDLE_KEY_STRLEN + 1];
|
||||
rhizome_bytes_to_hex_upper(bkbytes, bkhex, RHIZOME_BUNDLE_KEY_BYTES);
|
||||
if (debug&DEBUG_RHIZOME) DEBUGF("set BK=%s", bkhex);
|
||||
rhizome_manifest_set(m_in, "BK", bkhex);
|
||||
} else {
|
||||
return WHY("Failed to set BK");
|
||||
}
|
||||
@ -341,7 +345,9 @@ int rhizome_bundle_push_update(char *id,long long version,unsigned char *data,in
|
||||
return WHY("Not implemented");
|
||||
}
|
||||
|
||||
char nybltochar(int nybl)
|
||||
/** Return the uppercase hex digit for a given nybble value 0..15.
|
||||
*/
|
||||
char nybltochar_upper(int nybl)
|
||||
{
|
||||
if (nybl<0) return '?';
|
||||
if (nybl>15) return '?';
|
||||
|
12
rhizome.h
12
rhizome.h
@ -21,6 +21,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include "sha2.h"
|
||||
#include <sys/stat.h>
|
||||
|
||||
#define RHIZOME_MANIFEST_ID_BYTES crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES
|
||||
#define RHIZOME_MANIFEST_ID_STRLEN (RHIZOME_MANIFEST_ID_BYTES * 2)
|
||||
#define RHIZOME_BUNDLE_KEY_BYTES crypto_sign_edwards25519sha512batch_SECRETKEYBYTES
|
||||
#define RHIZOME_BUNDLE_KEY_STRLEN (RHIZOME_BUNDLE_KEY_BYTES * 2)
|
||||
#define RHIZOME_FILEHASH_BYTES SHA512_DIGEST_LENGTH
|
||||
#define RHIZOME_FILEHASH_STRLEN (RHIZOME_FILEHASH_BYTES * 2)
|
||||
|
||||
#define RHIZOME_HTTP_PORT 4110
|
||||
|
||||
extern long long rhizome_voice_timeout;
|
||||
@ -201,7 +208,6 @@ int rhizome_manifest_pack_variables(rhizome_manifest *m);
|
||||
int rhizome_store_bundle(rhizome_manifest *m, const char *associated_filename);
|
||||
int rhizome_manifest_add_group(rhizome_manifest *m,char *groupid);
|
||||
int rhizome_store_file(const char *file,char *hash,int priortity);
|
||||
char *rhizome_safe_encode(unsigned char *in,int len);
|
||||
int rhizome_finish_sqlstatement(sqlite3_stmt *statement);
|
||||
int rhizome_bundle_import(rhizome_manifest *m_in, rhizome_manifest **m_out, const char *bundle,
|
||||
char *groups[], int ttl,
|
||||
@ -211,7 +217,7 @@ int rhizome_add_manifest(rhizome_manifest *m_in, rhizome_manifest **m_out, const
|
||||
int verifyP, int checkFileP, int signP,
|
||||
const char *author);
|
||||
int rhizome_manifest_finalise(rhizome_manifest *m,int signP,const char *author);
|
||||
char *rhizome_bytes_to_hex(unsigned char *in,int byteCount);
|
||||
void rhizome_bytes_to_hex_upper(unsigned const char *in, char *out, int byteCount);
|
||||
int rhizome_hex_to_bytes(const char *in,unsigned char *out,int hexChars);
|
||||
int rhizome_find_privatekey(rhizome_manifest *m);
|
||||
rhizome_signature *rhizome_sign_hash(rhizome_manifest *m,const char *author);
|
||||
@ -231,7 +237,7 @@ long long sqlite_exec_int64(char *sqlformat,...);
|
||||
int rhizome_update_file_priority(char *fileid);
|
||||
int rhizome_find_duplicate(const rhizome_manifest *m, rhizome_manifest **found);
|
||||
int rhizome_manifest_to_bar(rhizome_manifest *m,unsigned char *bar);
|
||||
char nybltochar(int n);
|
||||
char nybltochar_upper(int n);
|
||||
int rhizome_queue_manifest_import(rhizome_manifest *m,struct sockaddr_in *peerip);
|
||||
int rhizome_list_manifests(const char *service, const char *sender_sid, const char *recipient_sid, int limit, int offset);
|
||||
int rhizome_retrieve_manifest(const char *manifestid, rhizome_manifest **mp);
|
||||
|
@ -154,7 +154,7 @@ rhizome_manifest *rhizome_read_manifest_file(const char *filename, int bufferP,
|
||||
int rhizome_strn_is_file_hash(const char *text)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i != SHA512_DIGEST_LENGTH * 2; ++i)
|
||||
for (i = 0; i != RHIZOME_FILEHASH_STRLEN; ++i)
|
||||
if (!isxdigit(text[i]))
|
||||
return 0;
|
||||
return 1;
|
||||
@ -163,7 +163,7 @@ int rhizome_strn_is_file_hash(const char *text)
|
||||
int rhizome_str_is_file_hash(const char *text)
|
||||
{
|
||||
size_t len = strlen(text);
|
||||
return len == SHA512_DIGEST_LENGTH * 2 && rhizome_strn_is_file_hash(text);
|
||||
return len == RHIZOME_FILEHASH_STRLEN && rhizome_strn_is_file_hash(text);
|
||||
}
|
||||
|
||||
int rhizome_hash_file(const char *filename,char *hash_out)
|
||||
@ -192,6 +192,7 @@ int rhizome_hash_file(const char *filename,char *hash_out)
|
||||
SHA512_Update(&context, buffer, r);
|
||||
}
|
||||
SHA512_End(&context, (char *)hash_out);
|
||||
str_toupper_inplace(hash_out);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ int rhizome_bk_xor(const char *author,
|
||||
return WHY("BK needs to be longer than it can be");
|
||||
|
||||
unsigned char authorSid[SID_SIZE];
|
||||
if (stowSid(authorSid,0,author)) return WHY("stowSid() failed");
|
||||
if (stowSid(authorSid,0,author)) return WHYF("stowSid(%s) failed", author);
|
||||
int cn=0,in=0,kp=0;
|
||||
if (!keyring_find_sid(keyring,&cn,&in,&kp,authorSid))
|
||||
return WHY("keyring_find_sid() couldn't find that SID. Have you unlocked that identity?");
|
||||
@ -117,11 +117,6 @@ int rhizome_bk_xor(const char *author,
|
||||
int i;
|
||||
for(i=0;i<len;i++)
|
||||
bkout[i]=bkin[i]^hash[i];
|
||||
if (0) WHYF("%s* ^ %s* = %s*",
|
||||
rhizome_bytes_to_hex(bkin,8),
|
||||
rhizome_bytes_to_hex(hash,8),
|
||||
rhizome_bytes_to_hex(bkout,8));
|
||||
|
||||
bzero(&buffer[0],combined_len);
|
||||
bzero(&hash[0],crypto_hash_sha512_BYTES);
|
||||
|
||||
@ -174,11 +169,13 @@ int rhizome_extract_privatekey(rhizome_manifest *m,const char *authorHex)
|
||||
ge25519_scalarmult_base(&gepk, &scsk);
|
||||
ge25519_pack(pk, &gepk);
|
||||
bzero(&scsk,sizeof(scsk));
|
||||
if (memcmp(pk, m->cryptoSignPublic,
|
||||
crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES)) {
|
||||
if (memcmp(pk, m->cryptoSignPublic, crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES)) {
|
||||
if (0) {
|
||||
WHYF(" stored public key = %s*",rhizome_bytes_to_hex(m->cryptoSignPublic,8));
|
||||
WHYF("computed public key = %s*",rhizome_bytes_to_hex(pk,8));
|
||||
char hex[17];
|
||||
rhizome_bytes_to_hex_upper(m->cryptoSignPublic, hex, 8);
|
||||
WHYF(" stored public key = %s*", hex);
|
||||
rhizome_bytes_to_hex_upper(pk, hex, 8);
|
||||
WHYF("computed public key = %s*", hex);
|
||||
}
|
||||
return WHY("BID secret key decoded from BK was not valid");
|
||||
} else
|
||||
|
@ -331,18 +331,16 @@ int rhizome_drop_stored_file(char *id,int maximum_priority)
|
||||
*/
|
||||
int rhizome_store_bundle(rhizome_manifest *m, const char *associated_filename)
|
||||
{
|
||||
char sqlcmd[1024];
|
||||
const char *cmdtail;
|
||||
int i;
|
||||
|
||||
char manifestid[crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES * 2 + 1];
|
||||
strncpy(manifestid,rhizome_manifest_get(m,"id",NULL,0),64);
|
||||
manifestid[64]=0;
|
||||
for(i=0;i<64;i++)
|
||||
manifestid[i]=toupper(manifestid[i]);
|
||||
|
||||
if (!m->finalised) return WHY("Manifest was not finalised");
|
||||
|
||||
char manifestid[RHIZOME_MANIFEST_ID_STRLEN + 1];
|
||||
rhizome_manifest_get(m, "id", manifestid, sizeof manifestid);
|
||||
str_toupper_inplace(manifestid);
|
||||
|
||||
char filehash[RHIZOME_FILEHASH_STRLEN + 1];
|
||||
strncpy(filehash, m->fileHexHash, sizeof filehash);
|
||||
str_toupper_inplace(filehash);
|
||||
|
||||
/* remove any old version of the manifest */
|
||||
if (sqlite_exec_int64("SELECT COUNT(*) FROM MANIFESTS WHERE id='%s';",manifestid)>0)
|
||||
{
|
||||
@ -354,8 +352,7 @@ int rhizome_store_bundle(rhizome_manifest *m, const char *associated_filename)
|
||||
|
||||
char sql[1024];
|
||||
sqlite3_stmt *statement;
|
||||
snprintf(sql,1024,"SELECT fileid from filemanifests where manifestid='%s';",
|
||||
manifestid);
|
||||
snprintf(sql,1024,"SELECT fileid from filemanifests where manifestid='%s';", manifestid);
|
||||
if (sqlite3_prepare_v2(rhizome_db,sql,strlen(sql)+1,&statement,NULL)!=SQLITE_OK)
|
||||
{
|
||||
WHY("sqlite3_prepare_v2() failed");
|
||||
@ -380,6 +377,7 @@ int rhizome_store_bundle(rhizome_manifest *m, const char *associated_filename)
|
||||
|
||||
/* Store manifest */
|
||||
if (debug & DEBUG_RHIZOME) DEBUGF("Writing into manifests table");
|
||||
char sqlcmd[1024];
|
||||
snprintf(sqlcmd,1024,
|
||||
"INSERT INTO MANIFESTS(id,manifest,version,inserttime,bar) VALUES('%s',?,%lld,%lld,?);",
|
||||
manifestid, m->version, gettime_ms());
|
||||
@ -396,6 +394,7 @@ int rhizome_store_bundle(rhizome_manifest *m, const char *associated_filename)
|
||||
}
|
||||
}
|
||||
|
||||
const char *cmdtail;
|
||||
sqlite3_stmt *statement;
|
||||
if (sqlite3_prepare_v2(rhizome_db,sqlcmd,strlen(sqlcmd)+1,&statement,&cmdtail)
|
||||
!= SQLITE_OK) {
|
||||
@ -433,9 +432,7 @@ int rhizome_store_bundle(rhizome_manifest *m, const char *associated_filename)
|
||||
}
|
||||
|
||||
/* Create relationship between file and manifest */
|
||||
long long r=sqlite_exec_int64("INSERT INTO FILEMANIFESTS(manifestid,fileid) VALUES('%s','%s');",
|
||||
manifestid,
|
||||
m->fileHexHash);
|
||||
long long r=sqlite_exec_int64("INSERT INTO FILEMANIFESTS(manifestid,fileid) VALUES('%s','%s');", manifestid, filehash);
|
||||
if (r<0) {
|
||||
WHY(sqlite3_errmsg(rhizome_db));
|
||||
return WHY("SQLite3 failed to insert row in filemanifests.");
|
||||
@ -470,7 +467,7 @@ int rhizome_store_bundle(rhizome_manifest *m, const char *associated_filename)
|
||||
|
||||
/* Store the file */
|
||||
if (m->fileLength>0)
|
||||
if (rhizome_store_file(associated_filename,m->fileHexHash,m->fileHighestPriority))
|
||||
if (rhizome_store_file(associated_filename, filehash, m->fileHighestPriority))
|
||||
return WHY("Could not store associated file");
|
||||
|
||||
/* Get things consistent */
|
||||
@ -505,38 +502,6 @@ int rhizome_finish_sqlstatement(sqlite3_stmt *statement)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Like sqlite_encode_binary(), but with a fixed rotation to make comparison of
|
||||
string prefixes easier. Also, returns string directly for convenience.
|
||||
The rotoring through four return strings is so that this function can be used
|
||||
safely inline in sprintf() type functions, which makes composition of sql statements
|
||||
easier. */
|
||||
int rse_rotor=0;
|
||||
char rse_out[8][129];
|
||||
char *rhizome_safe_encode(unsigned char *in,int len)
|
||||
{
|
||||
char *r=rse_out[rse_rotor];
|
||||
rse_rotor++;
|
||||
rse_rotor&=7;
|
||||
|
||||
int i,o=0;
|
||||
|
||||
for(i=0;i<len;i++)
|
||||
{
|
||||
if (o<=127)
|
||||
switch(in[i])
|
||||
{
|
||||
case 0x00: case 0x01: case '\'':
|
||||
r[o++]=0x01;
|
||||
r[o++]=in[i]^0x80;
|
||||
break;
|
||||
default:
|
||||
r[o++]=in[i];
|
||||
}
|
||||
}
|
||||
r[128]=0;
|
||||
return r;
|
||||
}
|
||||
|
||||
int rhizome_list_manifests(const char *service, const char *sender_sid, const char *recipient_sid, int limit, int offset)
|
||||
{
|
||||
strbuf b = strbuf_alloca(1024);
|
||||
@ -639,7 +604,7 @@ int rhizome_store_file(const char *file,char *hash,int priority)
|
||||
}
|
||||
|
||||
/* Get hash of file if not supplied */
|
||||
char hexhash[SHA512_DIGEST_STRING_LENGTH];
|
||||
char hexhash[RHIZOME_FILEHASH_STRLEN + 1];
|
||||
if (!hash)
|
||||
{
|
||||
/* Hash the file */
|
||||
@ -647,6 +612,7 @@ int rhizome_store_file(const char *file,char *hash,int priority)
|
||||
SHA512_Init(&c);
|
||||
SHA512_Update(&c,addr,stat.st_size);
|
||||
SHA512_End(&c,hexhash);
|
||||
str_toupper_inplace(hexhash);
|
||||
hash=hexhash;
|
||||
}
|
||||
|
||||
@ -776,22 +742,12 @@ int rhizome_store_file(const char *file,char *hash,int priority)
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *rhizome_bytes_to_hex(unsigned char *in,int byteCount)
|
||||
void rhizome_bytes_to_hex_upper(unsigned const char *in, char *out, int byteCount)
|
||||
{
|
||||
int i=0;
|
||||
|
||||
if (byteCount>64) return "<too long>";
|
||||
|
||||
rse_rotor++;
|
||||
rse_rotor&=7;
|
||||
|
||||
for(i=0;i<byteCount*2;i++)
|
||||
{
|
||||
int d=nybltochar((in[i>>1]>>(4-4*(i&1)))&0xf);
|
||||
rse_out[rse_rotor][i]=d;
|
||||
}
|
||||
rse_out[rse_rotor][i]=0;
|
||||
return rse_out[rse_rotor++];
|
||||
for(i = 0; i != byteCount * 2 ; ++i)
|
||||
out[i] = nybltochar_upper((in[i >> 1] >> (4 - 4 * (i & 1))) & 0xf);
|
||||
out[i] = '\0';
|
||||
}
|
||||
|
||||
int rhizome_update_file_priority(char *fileid)
|
||||
@ -853,7 +809,10 @@ int rhizome_find_duplicate(const rhizome_manifest *m, rhizome_manifest **found)
|
||||
ret = WHY(sqlite3_errmsg(rhizome_db));
|
||||
} else {
|
||||
if (debug & DEBUG_RHIZOME) DEBUGF("fileHexHash = \"%s\"", m->fileHexHash);
|
||||
sqlite3_bind_text(statement, 1, m->fileHexHash, -1, SQLITE_STATIC);
|
||||
char filehash[RHIZOME_FILEHASH_STRLEN + 1];
|
||||
strncpy(filehash, m->fileHexHash, sizeof filehash);
|
||||
str_toupper_inplace(filehash);
|
||||
sqlite3_bind_text(statement, 1, filehash, -1, SQLITE_STATIC);
|
||||
if (m->version != -1)
|
||||
sqlite3_bind_int64(statement, 2, m->version);
|
||||
size_t rows = 0;
|
||||
@ -896,7 +855,7 @@ int rhizome_find_duplicate(const rhizome_manifest *m, rhizome_manifest **found)
|
||||
q_manifestid, q_version, blob_version);
|
||||
++inconsistent;
|
||||
}
|
||||
if (!blob_filehash && strcmp(blob_filehash, m->fileHexHash)) {
|
||||
if (!blob_filehash && strcasecmp(blob_filehash, m->fileHexHash)) {
|
||||
WARNF("MANIFESTS row id=%s joined to FILES row id=%s has inconsistent blob: blob.filehash=%s -- skipped",
|
||||
q_manifestid, m->fileHexHash, blob_filehash);
|
||||
++inconsistent;
|
||||
@ -934,7 +893,7 @@ int rhizome_find_duplicate(const rhizome_manifest *m, rhizome_manifest **found)
|
||||
}
|
||||
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);
|
||||
memcpy(blob_m->fileHexHash, m->fileHexHash, RHIZOME_FILEHASH_STRLEN + 1);
|
||||
blob_m->fileHashedP = 1;
|
||||
blob_m->fileLength = m->fileLength;
|
||||
blob_m->version = q_version;
|
||||
@ -973,7 +932,11 @@ int rhizome_retrieve_manifest(const char *manifestid, rhizome_manifest **mp)
|
||||
sqlite3_finalize(statement);
|
||||
ret = WHY(sqlite3_errmsg(rhizome_db));
|
||||
} else {
|
||||
sqlite3_bind_text(statement, 1, manifestid, crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES * 2, SQLITE_STATIC);
|
||||
char manifestIdUpper[RHIZOME_MANIFEST_ID_STRLEN + 1];
|
||||
strncpy(manifestIdUpper, manifestid, sizeof manifestIdUpper);
|
||||
manifestIdUpper[RHIZOME_MANIFEST_ID_STRLEN] = '\0';
|
||||
str_toupper_inplace(manifestIdUpper);
|
||||
sqlite3_bind_text(statement, 1, manifestIdUpper, -1, SQLITE_STATIC);
|
||||
while (sqlite3_step(statement) == SQLITE_ROW) {
|
||||
if (!( sqlite3_column_count(statement) == 4
|
||||
&& sqlite3_column_type(statement, 0) == SQLITE_TEXT
|
||||
@ -1000,7 +963,7 @@ int rhizome_retrieve_manifest(const char *manifestid, rhizome_manifest **mp)
|
||||
if (blob_filehash == NULL)
|
||||
ret = WHY("Manifest is missing 'filehash' field");
|
||||
else {
|
||||
memcpy(m->fileHexHash, blob_filehash, SHA512_DIGEST_STRING_LENGTH);
|
||||
memcpy(m->fileHexHash, blob_filehash, RHIZOME_FILEHASH_STRLEN + 1);
|
||||
m->fileHashedP = 1;
|
||||
}
|
||||
long long blob_version = rhizome_manifest_get_ll(m, "version");
|
||||
@ -1059,7 +1022,11 @@ int rhizome_retrieve_file(const char *fileid, const char *filepath)
|
||||
sqlite3_finalize(statement);
|
||||
ret = WHY(sqlite3_errmsg(rhizome_db));
|
||||
} else {
|
||||
sqlite3_bind_text(statement, 1, fileid, SHA512_DIGEST_LENGTH * 2, SQLITE_STATIC);
|
||||
char fileIdUpper[RHIZOME_FILEHASH_STRLEN + 1];
|
||||
strncpy(fileIdUpper, fileid, sizeof fileIdUpper);
|
||||
fileIdUpper[RHIZOME_FILEHASH_STRLEN] = '\0';
|
||||
str_toupper_inplace(fileIdUpper);
|
||||
sqlite3_bind_text(statement, 1, fileIdUpper, -1, SQLITE_STATIC);
|
||||
while (sqlite3_step(statement) == SQLITE_ROW) {
|
||||
if (!( sqlite3_column_count(statement) == 3
|
||||
&& sqlite3_column_type(statement, 0) == SQLITE_TEXT
|
||||
|
@ -28,7 +28,7 @@ extern int sigIoFlag;
|
||||
typedef struct rhizome_file_fetch_record {
|
||||
int socket; /* if non-zero this is the socket to read from */
|
||||
rhizome_manifest *manifest;
|
||||
char fileid[SHA512_DIGEST_STRING_LENGTH];
|
||||
char fileid[RHIZOME_FILEHASH_STRLEN + 1];
|
||||
FILE *file;
|
||||
|
||||
int close;
|
||||
@ -525,24 +525,20 @@ int rhizome_queue_manifest_import(rhizome_manifest *m,
|
||||
}
|
||||
}
|
||||
|
||||
char *filehash=rhizome_manifest_get(m,"filehash",NULL,0);
|
||||
char filehash[RHIZOME_FILEHASH_STRLEN + 1];
|
||||
if (!rhizome_manifest_get(m, "filehash", filehash, sizeof filehash))
|
||||
filehash[0] = '\0';
|
||||
str_toupper_inplace(filehash);
|
||||
long long filesize=rhizome_manifest_get_ll(m,"filesize");
|
||||
|
||||
if (debug&DEBUG_RHIZOMESYNC)
|
||||
WHYF("Getting ready to fetch file %s for manifest %s\n",filehash,rhizome_manifest_get(m,"id",NULL,0));
|
||||
|
||||
if (filesize>0&&(filehash!=NULL))
|
||||
if (filesize > 0 && filehash[0])
|
||||
{
|
||||
if (strlen(filehash)!=SHA512_DIGEST_STRING_LENGTH-1)
|
||||
{
|
||||
return WHY("File hash is wrong length");
|
||||
}
|
||||
|
||||
int gotfile=
|
||||
sqlite_exec_int64("SELECT COUNT(*) FROM FILES WHERE ID='%s';",
|
||||
rhizome_safe_encode((unsigned char *)filehash,
|
||||
strlen(filehash)));
|
||||
|
||||
if (!rhizome_str_is_file_hash(filehash))
|
||||
return WHYF("Invalid file hash: ", filehash);
|
||||
int gotfile= sqlite_exec_int64("SELECT COUNT(*) FROM FILES WHERE ID='%s';", filehash);
|
||||
if (gotfile!=1) {
|
||||
/* We need to get the file */
|
||||
|
||||
@ -560,9 +556,9 @@ int rhizome_queue_manifest_import(rhizome_manifest *m,
|
||||
if (debug&DEBUG_RHIZOME) WHYF("Already fetching manifest\n");
|
||||
return -1;
|
||||
}
|
||||
for(j=0;j<SHA512_DIGEST_STRING_LENGTH;j++)
|
||||
for(j=0;j<=RHIZOME_FILEHASH_STRLEN;j++)
|
||||
if (filehash[j]!=file_fetch_queue[i].fileid[j]) break;
|
||||
if (j==SHA512_DIGEST_STRING_LENGTH)
|
||||
if (j==RHIZOME_FILEHASH_STRLEN + 1)
|
||||
{
|
||||
/* We are already fetching this file */
|
||||
if (debug&DEBUG_RHIZOME) WHYF("Already fetching file %s\n",
|
||||
@ -591,8 +587,7 @@ int rhizome_queue_manifest_import(rhizome_manifest *m,
|
||||
*q=&file_fetch_queue[rhizome_file_fetch_queue_count];
|
||||
q->manifest=m;
|
||||
q->socket=sock;
|
||||
strncpy(q->fileid,
|
||||
filehash,SHA512_DIGEST_STRING_LENGTH);
|
||||
strncpy(q->fileid, filehash, RHIZOME_FILEHASH_STRLEN + 1);
|
||||
snprintf(q->request,1024,"GET /rhizome/file/%s HTTP/1.0\r\n\r\n",
|
||||
q->fileid);
|
||||
q->request_len=strlen(q->request);
|
||||
|
@ -20,6 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <signal.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "serval.h"
|
||||
#include "rhizome.h"
|
||||
@ -305,22 +306,13 @@ int rhizome_server_get_fds(struct pollfd *fds,int *fdcount,int fdmax)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hexFilter(char *s)
|
||||
void hexFilter(char *s)
|
||||
{
|
||||
int l=strlen(s);
|
||||
int i;
|
||||
int o=0;
|
||||
int e=0;
|
||||
for(i=0;i<l;i++)
|
||||
{
|
||||
if ((s[i]>='0'&&s[i]<='9')
|
||||
||(s[i]>='a'&&s[i]<='f')
|
||||
||(s[i]>='A'&&s[i]<='F'))
|
||||
s[o++]=s[i];
|
||||
else e++;
|
||||
}
|
||||
s[o]=0;
|
||||
return -e;
|
||||
char *t;
|
||||
for (t = s; *s; ++s)
|
||||
if (isxdigit(*s))
|
||||
*t++ = *s;
|
||||
*t = '\0';
|
||||
}
|
||||
|
||||
int rhizome_server_sql_query_http_response(int rn,rhizome_http_request *r,
|
||||
@ -528,8 +520,7 @@ int rhizome_server_parse_http_request(int rn,rhizome_http_request *r)
|
||||
WHYF("get /rhizome/bars (list of BARs)");
|
||||
rhizome_server_sql_query_http_response(rn,r,"bar","manifests","from manifests",32,0);
|
||||
}
|
||||
else if (sscanf(r->request,"GET /rhizome/file/%s HTTP/1.",
|
||||
id)==1)
|
||||
else if (sscanf(r->request,"GET /rhizome/file/%s HTTP/1.", id)==1)
|
||||
{
|
||||
/* Stream the specified file */
|
||||
int dud=0;
|
||||
@ -537,16 +528,15 @@ int rhizome_server_parse_http_request(int rn,rhizome_http_request *r)
|
||||
hexFilter(id);
|
||||
WHYF("get /rhizome/file/ [%s]",id);
|
||||
WHY("Check for range: header, and return 206 if returning partial content");
|
||||
for(i=0;i<strlen(id);i++) if ((id[i]<'0')||(id[i]>'f')||(id[i]=='\'')) dud++;
|
||||
for(i=0;i<strlen(id);i++) if (!isxdigit(id[i])) dud++;
|
||||
if (dud) rhizome_server_simple_http_response(r,400,"<html><h1>That doesn't look like hex to me.</h1></html>\r\n");
|
||||
else {
|
||||
str_toupper_inplace(id);
|
||||
long long rowid = sqlite_exec_int64("select rowid from files where id='%s';",id);
|
||||
sqlite3_blob *blob;
|
||||
if (rowid>=0)
|
||||
if (sqlite3_blob_open(rhizome_db,"main","files","data",rowid,0,&blob)
|
||||
!=SQLITE_OK)
|
||||
if (sqlite3_blob_open(rhizome_db,"main","files","data",rowid,0,&blob) !=SQLITE_OK)
|
||||
rowid=-1;
|
||||
|
||||
if (rowid<0) {
|
||||
rhizome_server_simple_http_response(r,404,"<html><h1>Sorry, can't find that here.</h1></html>\r\n");
|
||||
WHY("File not found / blob not opened");
|
||||
@ -565,13 +555,13 @@ int rhizome_server_parse_http_request(int rn,rhizome_http_request *r)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sscanf(r->request,"GET /rhizome/manifest/%s HTTP/1.",
|
||||
id)==1)
|
||||
else if (sscanf(r->request,"GET /rhizome/manifest/%s HTTP/1.", id)==1)
|
||||
{
|
||||
/* Stream the specified manifest */
|
||||
hexFilter(id);
|
||||
WHYF("get /rhizome/manifest/ [%s]",id);
|
||||
rhizome_server_simple_http_response(r,400,"<html><h1>A specific manifest</h1></html>\r\n"); }
|
||||
rhizome_server_simple_http_response(r,400,"<html><h1>A specific manifest</h1></html>\r\n");
|
||||
}
|
||||
else
|
||||
rhizome_server_simple_http_response(r,400,"<html><h1>Sorry, couldn't parse your request.</h1></html>\r\n");
|
||||
}
|
||||
|
1
serval.h
1
serval.h
@ -425,6 +425,7 @@ int isTransactionInCache(unsigned char *transaction_id);
|
||||
void insertTransactionInCache(unsigned char *transaction_id);
|
||||
|
||||
int hexvalue(unsigned char c);
|
||||
char *str_toupper_inplace(char *s);
|
||||
int packetOk(int interface,unsigned char *packet,int len,
|
||||
unsigned char *transaction_id, int recvttl,
|
||||
struct sockaddr *recvaddr,int recvaddrlen,int parseP);
|
||||
|
Loading…
x
Reference in New Issue
Block a user