mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-01-18 02:39:44 +00:00
Added command line options to DNA to import a rhizome bundle.
This commit is contained in:
parent
6ec1d6032f
commit
1628d5cbfb
19
dna.c
19
dna.c
@ -219,10 +219,12 @@ int usage(char *complaint)
|
||||
{
|
||||
fprintf(stderr,"dna: %s\n",complaint);
|
||||
fprintf(stderr,"usage:\n");
|
||||
fprintf(stderr," dna [-v ...] -S <hlr size in MB> [-f HLR backing file] [-I import.txt] [-N interface,...] [-G gateway specification]\n");
|
||||
fprintf(stderr," dna [-v ...] -S <hlr size in MB> [-f HLR backing file] [-I import.txt] [-N interface,...] [-G gateway specification] [-r rhizome path]\n");
|
||||
fprintf(stderr,"or\n");
|
||||
fprintf(stderr," dna [-v ...] -f <HLR backing file> -E <hlr export file>\n");
|
||||
fprintf(stderr,"or\n");
|
||||
fprintf(stderr," dna -r <rhizome path> -M <manifest name>\n");
|
||||
fprintf(stderr,"or\n");
|
||||
fprintf(stderr," dna <-d|-s> id -A\n");
|
||||
fprintf(stderr,"or\n");
|
||||
fprintf(stderr," dna <-d|-s> id [-p pin] [-i variable instance] <-R variable[=value]>\n");
|
||||
@ -244,6 +246,7 @@ int usage(char *complaint)
|
||||
fprintf(stderr," -l - Specify BATMAN socket to obtain peer list (better, but requires Serval patched BATMAN).\n");
|
||||
fprintf(stderr," -L - Log mesh statistics to specified file.\n");
|
||||
fprintf(stderr," -m - Return multiple variable values instead of only first response.\n");
|
||||
fprintf(stderr," -M - Create and import a new bundle from the specified manifest.\n");
|
||||
fprintf(stderr," -n - Do not detach from foreground in server mode.\n");
|
||||
fprintf(stderr," -S - Run in server mode with an HLR of the specified size.\n");
|
||||
fprintf(stderr," -f - Use the specified file as a permanent store for HLR data.\n");
|
||||
@ -315,7 +318,7 @@ int main(int argc,char **argv)
|
||||
|
||||
srandomdev();
|
||||
|
||||
while((c=getopt(argc,argv,"Ab:B:E:G:I:S:f:d:i:l:L:mnp:P:r:s:t:vR:W:U:D:CO:N:")) != -1 )
|
||||
while((c=getopt(argc,argv,"Ab:B:E:G:I:S:f:d:i:l:L:mnp:P:r:s:t:vR:W:U:D:CO:M:N:")) != -1 )
|
||||
{
|
||||
switch(c)
|
||||
{
|
||||
@ -324,6 +327,18 @@ int main(int argc,char **argv)
|
||||
rhizome_datastore_path=optarg;
|
||||
rhizome_opendb();
|
||||
break;
|
||||
case 'M': /* Distribute specified manifest and file pair using Rhizome. */
|
||||
/* This option assumes that the manifest is locally produced, and will
|
||||
create any appropriate signatures, replacing any old signatures on the
|
||||
manifest.
|
||||
A different calling would be required to import an existing pre-signed
|
||||
manifest */
|
||||
return rhizome_bundle_import(optarg,
|
||||
NULL /* no groups - XXX should allow them */,
|
||||
0 /* int verifyP */,
|
||||
1 /* int checkFileP */,
|
||||
1 /* int signP */);
|
||||
break;
|
||||
case 'm': returnMultiVars=1; break;
|
||||
case 'N': /* Ask for overlay network to setup one or more interfaces */
|
||||
if (overlay_interface_args(optarg))
|
||||
|
127
rhizome.c
127
rhizome.c
@ -17,16 +17,6 @@ typedef struct rhizome_manifest {
|
||||
unsigned char cryptoSignPublic[crypto_sign_PUBLICKEYBYTES];
|
||||
unsigned char cryptoSignSecret[crypto_sign_SECRETKEYBYTES];
|
||||
|
||||
/* Set non-zero after variables have been packed and
|
||||
signature blocks appended */
|
||||
int finalised;
|
||||
|
||||
/* When finalised, we keep the filehash and maximum priority due to any
|
||||
group membership handy */
|
||||
long long fileLength;
|
||||
char fileHexHash[SHA512_DIGEST_STRING_LENGTH];
|
||||
int fileHighestPriority;
|
||||
|
||||
int var_count;
|
||||
char *vars[MAX_MANIFEST_VARS];
|
||||
char *values[MAX_MANIFEST_VARS];
|
||||
@ -38,6 +28,19 @@ typedef struct rhizome_manifest {
|
||||
/* 0x02 = CryptoSign signature of signatory */
|
||||
int signature_errors; /* if non-zero, then manifest should not be trusted */
|
||||
|
||||
/* Set non-zero after variables have been packed and
|
||||
signature blocks appended.
|
||||
All fields below are only valid once the manifest has been finalised */
|
||||
int finalised;
|
||||
|
||||
/* When finalised, we keep the filehash and maximum priority due to any
|
||||
group membership handy */
|
||||
long long fileLength;
|
||||
char fileHexHash[SHA512_DIGEST_STRING_LENGTH];
|
||||
int fileHighestPriority;
|
||||
|
||||
/* Version of the manifest. Typically the number of milliseconds since 1970. */
|
||||
long long version;
|
||||
|
||||
} rhizome_manifest;
|
||||
|
||||
@ -54,6 +57,7 @@ int rhizome_manifest_priority(char *id);
|
||||
rhizome_manifest *rhizome_read_manifest_file(char *filename);
|
||||
int rhizome_hash_file(char *filename,char *hash_out);
|
||||
int rhizome_manifest_get(rhizome_manifest *m,char *var,char *value_out);
|
||||
long long rhizome_manifest_get_ll(rhizome_manifest *m,char *var);
|
||||
int rhizome_manifest_set_ll(rhizome_manifest *m,char *var,long long value);
|
||||
int rhizome_manifest_set(rhizome_manifest *m,char *var,char *value);
|
||||
long long rhizome_file_size(char *filename);
|
||||
@ -62,6 +66,9 @@ int rhizome_manifest_pack_variables(rhizome_manifest *m);
|
||||
int rhizome_store_bundle(rhizome_manifest *m,char *associated_filename);
|
||||
int rhizome_manifest_add_group(rhizome_manifest *m,char *groupid);
|
||||
int rhizome_store_file(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(char *bundle,char *groups[],int verifyP, int checkFileP, int signP);
|
||||
|
||||
|
||||
int rhizome_opendb()
|
||||
@ -313,7 +320,7 @@ int rhizome_bundle_import(char *bundle,char *groups[],int verifyP, int checkFile
|
||||
char buffer[1024];
|
||||
|
||||
snprintf(filename,1024,"%s/import/file.%s",rhizome_datastore_path,bundle); filename[1023]=0;
|
||||
snprintf(manifestname,1024,"%s/manifest.%s",rhizome_datastore_path,bundle); manifestname[1023]=0;
|
||||
snprintf(manifestname,1024,"%s/import/manifest.%s",rhizome_datastore_path,bundle); manifestname[1023]=0;
|
||||
|
||||
/* Open files */
|
||||
rhizome_manifest *m=rhizome_read_manifest_file(manifestname);
|
||||
@ -504,6 +511,18 @@ int rhizome_manifest_get(rhizome_manifest *m,char *var,char *out)
|
||||
return -1;
|
||||
}
|
||||
|
||||
long long rhizome_manifest_get_ll(rhizome_manifest *m,char *var)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!m) return -1;
|
||||
|
||||
for(i=0;i<m->var_count;i++)
|
||||
if (!strcmp(m->vars[i],var))
|
||||
return strtoll(m->values[i],NULL,10);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int rhizome_manifest_set(rhizome_manifest *m,char *var,char *value)
|
||||
{
|
||||
int i;
|
||||
@ -627,6 +646,9 @@ int rhizome_manifest_createid(rhizome_manifest *m)
|
||||
*/
|
||||
int rhizome_store_bundle(rhizome_manifest *m,char *associated_filename)
|
||||
{
|
||||
char sqlcmd[1024];
|
||||
const char *cmdtail;
|
||||
|
||||
if (!m->finalised) return WHY("Manifest was not finalised");
|
||||
|
||||
if (m->fileLength>0)
|
||||
@ -634,9 +656,68 @@ int rhizome_store_bundle(rhizome_manifest *m,char *associated_filename)
|
||||
return WHY("Could not store associated file");
|
||||
/* XXX Store manifest itself, and create relationships to groups etc. */
|
||||
|
||||
/* Store manifest */
|
||||
snprintf(sqlcmd,1024,"INSERT INTO MANIFESTS(id,manifest,version,privatekey,inserttime) VALUES('%s',?,%lld,'%s',%lld);",
|
||||
rhizome_safe_encode(m->cryptoSignPublic,crypto_sign_PUBLICKEYBYTES),
|
||||
m->version,
|
||||
rhizome_safe_encode(m->cryptoSignSecret,crypto_sign_SECRETKEYBYTES),
|
||||
overlay_time_in_ms());
|
||||
sqlite3_stmt *statement;
|
||||
if (sqlite3_prepare_v2(rhizome_db,sqlcmd,strlen(sqlcmd)+1,&statement,&cmdtail)
|
||||
!= SQLITE_OK)
|
||||
return WHY(sqlite3_errmsg(rhizome_db));
|
||||
|
||||
/* Bind appropriate sized zero-filled blob to data field */
|
||||
sqlite3_bind_blob(statement,1,m->manifestdata,m->manifest_bytes,SQLITE_TRANSIENT);
|
||||
|
||||
if (rhizome_finish_sqlstatement(statement))
|
||||
return WHY("SQLite3 failed to insert row for manifest");
|
||||
|
||||
return WHY("Not implemented.");
|
||||
}
|
||||
|
||||
int rhizome_finish_sqlstatement(sqlite3_stmt *statement)
|
||||
{
|
||||
/* Do actual insert, and abort if it fails */
|
||||
int dud=0;
|
||||
if (sqlite3_step(statement)!=SQLITE_OK) dud++;
|
||||
if (sqlite3_finalize(statement)) dud++;
|
||||
if (dud) WHY(sqlite3_errmsg(rhizome_db));
|
||||
|
||||
return dud;
|
||||
}
|
||||
|
||||
/* 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[4][129];
|
||||
char *rhizome_safe_encode(unsigned char *in,int len)
|
||||
{
|
||||
char *r=rse_out[rse_rotor];
|
||||
rse_rotor++;
|
||||
rse_rotor&=3;
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/* The following function just stores the file (or silently returns if it already
|
||||
exists).
|
||||
The relationships of manifests to this file are the responsibility of the
|
||||
@ -704,7 +785,8 @@ int rhizome_store_file(char *file,char *hash,int priority) {
|
||||
return WHY("Duplicate records for a file in the rhizome database. Database probably corrupt.");
|
||||
}
|
||||
|
||||
/* Okay, so there are no records that match, but we should delete any half-baked record (with datavalid=0) so that the insert below doesn't fail. */
|
||||
/* Okay, so there are no records that match, but we should delete any half-baked record (with datavalid=0) so that the insert below doesn't fail.
|
||||
Don't worry about the return result, since it might not delete any records. */
|
||||
sqlite3_exec(rhizome_db,"DELETE FROM FILES WHERE datavalid=0;",NULL,NULL,NULL);
|
||||
|
||||
snprintf(sqlcmd,1024,"INSERT INTO FILES(id,data,length,highestpriority,datavalid) VALUES('%s',?,%lld,%d,0);",
|
||||
@ -781,3 +863,24 @@ int rhizome_manifest_add_group(rhizome_manifest *m,char *groupid)
|
||||
{
|
||||
return WHY("Not implemented.");
|
||||
}
|
||||
|
||||
int rhizome_manifest_finalise(rhizome_manifest *m)
|
||||
{
|
||||
/* set fileLength */
|
||||
/* set fileHexHash */
|
||||
/* set fileHighestPriority based on group associations */
|
||||
|
||||
/* set version of manifest, either from version variable, or using current time */
|
||||
if (rhizome_manifest_get(m,"version",NULL))
|
||||
{
|
||||
/* No version set */
|
||||
m->version = overlay_time_in_ms();
|
||||
rhizome_manifest_set_ll(m,"version",m->version);
|
||||
}
|
||||
else
|
||||
m->version = rhizome_manifest_get_ll(m,"version");
|
||||
|
||||
/* mark manifest as finalised */
|
||||
|
||||
return WHY("Not implemented.");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user