From c57f10316fd583133d858762090e610766641485 Mon Sep 17 00:00:00 2001 From: cathugger Date: Fri, 17 Jan 2020 14:15:56 +0000 Subject: [PATCH] rawyaml mode --- common.h | 3 +++ main.c | 25 +++++++++++++----- worker.c | 10 +++++--- worker.h | 1 + yaml.c | 77 ++++++++++++++++++++++++++++++++++++++++---------------- yaml.h | 6 +++-- 6 files changed, 89 insertions(+), 33 deletions(-) diff --git a/common.h b/common.h index 918e453..8910715 100644 --- a/common.h +++ b/common.h @@ -7,6 +7,9 @@ #define PKPREFIX_SIZE (29 + 3) #define SKPREFIX_SIZE (29 + 3) +extern const char * const pkprefix; +extern const char * const skprefix; + #define FORMATTED_PUBLIC_LEN (PKPREFIX_SIZE + PUBLIC_LEN) #define FORMATTED_SECRET_LEN (SKPREFIX_SIZE + SECRET_LEN) diff --git a/main.c b/main.c index fc38b2c..4672984 100644 --- a/main.c +++ b/main.c @@ -106,6 +106,7 @@ static void printhelp(FILE *out,const char *progname) "\t-T - do not reset statistics counters when printing\n" "\t-y - output generated keys in YAML format instead of dumping them to filesystem\n" "\t-Y [filename [host.onion]] - parse YAML encoded input and extract key(s) to filesystem\n" + "\t--rawyaml - raw (unprefixed) public/secret keys for -y/-Y (may be useful for tor controller API)\n" #ifdef PASSPHRASE "\t-p passphrase - use passphrase to initialize the random seed with\n" "\t-P - same as -p, but takes passphrase from PASSPHRASE environment variable\n" @@ -180,7 +181,7 @@ int main(int argc,char **argv) { const char *outfile = 0; const char *infile = 0; - const char *hostname = 0; + const char *onehostname = 0; const char *arg; int ignoreargs = 0; int dirnameflag = 0; @@ -237,6 +238,8 @@ int main(int argc,char **argv) printhelp(stdout,progname); exit(0); } + else if (!strcmp(arg,"rawyaml")) + yamlraw = 1; else { fprintf(stderr,"unrecognised argument: --%s\n",arg); exit(1); @@ -352,10 +355,10 @@ int main(int argc,char **argv) infile = 0; if (argc) { --argc; - hostname = *argv++; - if (!*hostname) - hostname = 0; - if (hostname && strlen(hostname) != ONION_LEN) { + onehostname = *argv++; + if (!*onehostname) + onehostname = 0; + if (onehostname && strlen(onehostname) != ONION_LEN) { fprintf(stderr,"bad onion argument length\n"); exit(1); } @@ -392,6 +395,16 @@ int main(int argc,char **argv) filters_add(arg); } + if (yamlinput && yamloutput) { + fprintf(stderr,"both -y and -Y does not make sense\n"); + exit(1); + } + + if (yamlraw && !yamlinput && !yamloutput) { + fprintf(stderr,"--rawyaml requires either -y or -Y to do anything\n"); + exit(1); + } + if (outfile) { fout = fopen(outfile,!outfileoverwrite ? "a" : "w"); if (!fout) { @@ -429,7 +442,7 @@ int main(int argc,char **argv) return 1; } } - tret = yamlin_parseandcreate(fin,sname,hostname); + tret = yamlin_parseandcreate(fin,sname,onehostname,yamlraw); if (infile) { fclose(fin); fin = 0; diff --git a/worker.c b/worker.c index ea8acd1..4962c8b 100644 --- a/worker.c +++ b/worker.c @@ -33,8 +33,8 @@ #endif // additional 0 terminator is added by C -static const char * const pkprefix = "== ed25519v1-public: type0 ==\0\0"; -static const char * const skprefix = "== ed25519v1-secret: type0 ==\0\0"; +const char * const pkprefix = "== ed25519v1-public: type0 ==\0\0"; +const char * const skprefix = "== ed25519v1-secret: type0 ==\0\0"; static const char checksumstr[] = ".onion checksum"; #define checksumstrlen (sizeof(checksumstr) - 1) // 15 @@ -44,6 +44,7 @@ volatile size_t keysgenerated = 0; volatile int endwork = 0; int yamloutput = 0; +int yamlraw = 0; int numwords = 1; size_t numneedgenerate = 0; @@ -127,8 +128,9 @@ static void onionready(char *sname,const u8 *secret,const u8 *pubonion) fflush(fout); pthread_mutex_unlock(&fout_mutex); } - } else - yamlout_writekeys(&sname[direndpos],pubonion,secret); + } + else + yamlout_writekeys(&sname[direndpos],pubonion,secret,yamlraw); } #include "filters_worker.inc.h" diff --git a/worker.h b/worker.h index a06edd4..209d7e5 100644 --- a/worker.h +++ b/worker.h @@ -4,6 +4,7 @@ extern volatile size_t keysgenerated; extern volatile int endwork; extern int yamloutput; +extern int yamlraw; extern int numwords; extern size_t numneedgenerate; diff --git a/yaml.c b/yaml.c index ebe03ab..c8778a6 100644 --- a/yaml.c +++ b/yaml.c @@ -21,7 +21,6 @@ #define LINEFEED_LEN (sizeof(char)) #define NULLTERM_LEN (sizeof(char)) -#define PATH_SEPARATOR_LEN (sizeof(char)) static const char keys_field_generated[] = "---"; static const char keys_field_hostname[] = "hostname: "; @@ -37,15 +36,20 @@ static const char keys_field_time[] = "time: "; #define B64_PUBKEY_LEN (BASE64_TO_LEN(FORMATTED_PUBLIC_LEN)) #define B64_SECKEY_LEN (BASE64_TO_LEN(FORMATTED_SECRET_LEN)) -#define TIME_LEN (21 * sizeof(char)) // strlen("2018-07-04 21:31:20 Z") +#define B64_RAW_PUBKEY_LEN (BASE64_TO_LEN(PUBLIC_LEN)) +#define B64_RAW_SECKEY_LEN (BASE64_TO_LEN(SECRET_LEN)) +#define TIME_LEN 21 // strlen("2018-07-04 21:31:20 Z") #define KEYS_LEN ( \ - KEYS_FIELD_GENERATED_LEN + LINEFEED_LEN + \ - KEYS_FIELD_HOSTNAME_LEN + ONION_LEN + LINEFEED_LEN + \ + KEYS_FIELD_GENERATED_LEN + LINEFEED_LEN + \ + KEYS_FIELD_HOSTNAME_LEN + ONION_LEN + LINEFEED_LEN + \ KEYS_FIELD_PUBLICKEY_LEN + B64_PUBKEY_LEN + LINEFEED_LEN + \ KEYS_FIELD_SECRETKEY_LEN + B64_SECKEY_LEN + LINEFEED_LEN + \ - KEYS_FIELD_TIME_LEN + TIME_LEN + LINEFEED_LEN \ + KEYS_FIELD_TIME_LEN + TIME_LEN + LINEFEED_LEN \ ) +#define RAW_KEYS_LEN (KEYS_LEN \ + - B64_PUBKEY_LEN + B64_RAW_PUBKEY_LEN \ + - B64_SECKEY_LEN + B64_RAW_SECKEY_LEN) static pthread_mutex_t tminfo_mutex; @@ -67,7 +71,8 @@ do { \ #define BUF_APPEND_CSTR(buf,offset,src) BUF_APPEND(buf,offset,src,strlen(src)) #define BUF_APPEND_CHAR(buf,offset,c) buf[offset++] = (c) -void yamlout_writekeys(const char *hostname,const u8 *formated_public,const u8 *formated_secret) +void yamlout_writekeys( + const char *hostname,const u8 *publickey,const u8 *secretkey,int rawkeys) { char keysbuf[KEYS_LEN]; char pubkeybuf[B64_PUBKEY_LEN + NULLTERM_LEN]; @@ -75,23 +80,38 @@ void yamlout_writekeys(const char *hostname,const u8 *formated_public,const u8 * char timebuf[TIME_LEN + NULLTERM_LEN]; size_t offset = 0; + BUF_APPEND(keysbuf,offset,keys_field_generated,KEYS_FIELD_GENERATED_LEN); BUF_APPEND_CHAR(keysbuf,offset,'\n'); + BUF_APPEND(keysbuf,offset,keys_field_hostname,KEYS_FIELD_HOSTNAME_LEN); BUF_APPEND(keysbuf,offset,hostname,ONION_LEN); BUF_APPEND_CHAR(keysbuf,offset,'\n'); + BUF_APPEND(keysbuf,offset,keys_field_publickey,KEYS_FIELD_PUBLICKEY_LEN); - base64_to(pubkeybuf,formated_public,FORMATTED_PUBLIC_LEN); - BUF_APPEND(keysbuf,offset,pubkeybuf,B64_PUBKEY_LEN); + + if (!rawkeys) + base64_to(pubkeybuf,publickey,FORMATTED_PUBLIC_LEN); + else + base64_to(pubkeybuf,&publickey[PKPREFIX_SIZE],PUBLIC_LEN); + + BUF_APPEND_CSTR(keysbuf,offset,pubkeybuf); BUF_APPEND_CHAR(keysbuf,offset,'\n'); + BUF_APPEND(keysbuf,offset,keys_field_secretkey,KEYS_FIELD_SECRETKEY_LEN); - base64_to(seckeybuf,formated_secret,FORMATTED_SECRET_LEN); - BUF_APPEND(keysbuf,offset,seckeybuf,B64_SECKEY_LEN); + + if (!rawkeys) + base64_to(seckeybuf,secretkey,FORMATTED_SECRET_LEN); + else + base64_to(seckeybuf,&secretkey[SKPREFIX_SIZE],SECRET_LEN); + + BUF_APPEND_CSTR(keysbuf,offset,seckeybuf); BUF_APPEND_CHAR(keysbuf,offset,'\n'); + BUF_APPEND(keysbuf,offset,keys_field_time,KEYS_FIELD_TIME_LEN); time_t currtime; @@ -106,10 +126,12 @@ void yamlout_writekeys(const char *hostname,const u8 *formated_public,const u8 * BUF_APPEND(keysbuf,offset,timebuf,TIME_LEN); BUF_APPEND_CHAR(keysbuf,offset,'\n'); - assert(offset == KEYS_LEN); + + assert(offset == (!rawkeys ? KEYS_LEN : RAW_KEYS_LEN)); + pthread_mutex_lock(&fout_mutex); - fwrite(keysbuf,sizeof(keysbuf),1,fout); + fwrite(keysbuf,offset,1,fout); fflush(fout); pthread_mutex_unlock(&fout_mutex); } @@ -119,7 +141,8 @@ void yamlout_writekeys(const char *hostname,const u8 *formated_public,const u8 * #undef BUF_APPEND // pseudo YAML parser -int yamlin_parseandcreate(FILE *fin,char *sname,const char *hostname) +int yamlin_parseandcreate( + FILE *fin,char *sname,const char *onehostname,int rawkeys) { char line[256]; size_t len,cnt; @@ -128,6 +151,11 @@ int yamlin_parseandcreate(FILE *fin,char *sname,const char *hostname) int hashost = 0,haspub = 0,hassec = 0,skipthis = 0; enum keytype { HOST, PUB, SEC } keyt; + if (rawkeys) { + memcpy(pubbuf,pkprefix,PKPREFIX_SIZE); + memcpy(secbuf,skprefix,SKPREFIX_SIZE); + } + while (!feof(fin) && !ferror(fin)) { if (!fgets(line,sizeof(line),fin)) break; @@ -143,7 +171,7 @@ int yamlin_parseandcreate(FILE *fin,char *sname,const char *hostname) continue; if (len >= 3 && line[0] == '-' && line[1] == '-' && line[2] == '-') { - // end of document indicator + // end of document / start of new document indicator if (!skipthis && (hashost || haspub || hassec)) { fprintf(stderr,"ERROR: incomplete record\n"); return 1; @@ -206,15 +234,18 @@ int yamlin_parseandcreate(FILE *fin,char *sname,const char *hostname) fprintf(stderr,"ERROR: invalid hostname syntax\n"); return 1; } - if (!hostname || !strcmp(hostname,p)) { + if (!onehostname || !strcmp(onehostname,p)) { memcpy(&sname[direndpos],p,len + 1); hashost = 1; } else skipthis = 1; break; case PUB: - if (len != B64_PUBKEY_LEN || !base64_valid(p,0) || - base64_from(pubbuf,p,len) != FORMATTED_PUBLIC_LEN) + if (!rawkeys + ? (len != B64_PUBKEY_LEN || !base64_valid(p,0) || + base64_from(pubbuf,p,len) != FORMATTED_PUBLIC_LEN) + : (len != B64_RAW_PUBKEY_LEN || !base64_valid(p,0) || + base64_from(&pubbuf[PKPREFIX_SIZE],p,len) != PUBLIC_LEN)) { fprintf(stderr,"ERROR: invalid pubkey syntax\n"); return 1; @@ -222,8 +253,11 @@ int yamlin_parseandcreate(FILE *fin,char *sname,const char *hostname) haspub = 1; break; case SEC: - if (len != B64_SECKEY_LEN || !base64_valid(p,0) || - base64_from(secbuf,p,len) != FORMATTED_SECRET_LEN) + if (!rawkeys + ? (len != B64_SECKEY_LEN || !base64_valid(p,0) || + base64_from(secbuf,p,len) != FORMATTED_SECRET_LEN) + : (len != B64_RAW_SECKEY_LEN || !base64_valid(p,0) || + base64_from(&secbuf[SKPREFIX_SIZE],p,len) != SECRET_LEN)) { fprintf(stderr,"ERROR: invalid seckey syntax\n"); return 1; @@ -264,8 +298,9 @@ int yamlin_parseandcreate(FILE *fin,char *sname,const char *hostname) #ifndef _WIN32 sigprocmask(SIG_SETMASK,&oset,0); #endif - if (hostname) + if (onehostname) return 0; // finished + // skip rest of lines until we hit start of new doc indicator skipthis = 1; } } @@ -275,7 +310,7 @@ int yamlin_parseandcreate(FILE *fin,char *sname,const char *hostname) return 1; } - if (hostname) { + if (onehostname) { fprintf(stderr,"hostname wasn't found in input\n"); return 1; } diff --git a/yaml.h b/yaml.h index ca356c5..85faf95 100644 --- a/yaml.h +++ b/yaml.h @@ -1,4 +1,6 @@ extern void yamlout_init(void); extern void yamlout_clean(void); -extern void yamlout_writekeys(const char *hostname,const u8 *formated_public,const u8 *formated_secret); -extern int yamlin_parseandcreate(FILE *fin,char *sname,const char *hostname); +extern void yamlout_writekeys( + const char *hostname,const u8 *publickey,const u8 *secretkey,int rawkeys); +extern int yamlin_parseandcreate( + FILE *fin,char *sname,const char *hostname,int rawkeys);