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:
Andrew Bettison 2012-05-23 16:04:00 +09:30
parent e1c30b8ed8
commit 1af9125392
11 changed files with 126 additions and 154 deletions

@ -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)
{

@ -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++)
{

@ -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 '?';

@ -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");
}

@ -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);