mirror of
https://github.com/cathugger/mkp224o.git
synced 2025-05-14 05:52:49 +00:00
refactor,fix,rewrite parts,tweak
This commit is contained in:
parent
4bdeb62f44
commit
be50d6b929
6 changed files with 432 additions and 363 deletions
454
main.c
454
main.c
|
@ -2,12 +2,10 @@
|
|||
#define _POSIX_C_SOURCE 200112L
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <sodium/randombytes.h>
|
||||
|
@ -17,12 +15,12 @@
|
|||
#include "likely.h"
|
||||
#include "vec.h"
|
||||
#include "base32.h"
|
||||
#include "base64.h"
|
||||
#include "cpucount.h"
|
||||
#include "keccak.h"
|
||||
#include "ed25519/ed25519.h"
|
||||
#include "ioutil.h"
|
||||
#include "constants.h"
|
||||
#include "common.h"
|
||||
#include "yaml.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#define FSZ "%zu"
|
||||
|
@ -31,12 +29,11 @@
|
|||
#endif
|
||||
|
||||
// additional 0 terminator is added by C
|
||||
static const char pkprefix[] = "== ed25519v1-public: type0 ==\0\0";
|
||||
#define pkprefixlen (sizeof(pkprefix)) // three null-terminators included
|
||||
static const char skprefix[] = "== ed25519v1-secret: type0 ==\0\0";
|
||||
#define skprefixlen (sizeof(skprefix)) // three null-terminators included
|
||||
static const char * const pkprefix = "== ed25519v1-public: type0 ==\0\0";
|
||||
static const char * const skprefix = "== ed25519v1-secret: type0 ==\0\0";
|
||||
|
||||
static const char checksumstr[] = ".onion checksum";
|
||||
#define checksumstrlen (sizeof(checksumstr) - NULLTERM_LEN)
|
||||
#define checksumstrlen (sizeof(checksumstr) - 1) // 15
|
||||
|
||||
// output directory
|
||||
static char *workdir = 0;
|
||||
|
@ -46,31 +43,25 @@ static int quietflag = 0;
|
|||
//static int wantdedup = 0;
|
||||
#define wantdedup 0
|
||||
|
||||
#define SECRET_LEN 64
|
||||
#define PUBLIC_LEN 32
|
||||
#define SEED_LEN 32
|
||||
// with checksum + version num
|
||||
#define PUBONION_LEN (PUBLIC_LEN + 3)
|
||||
// with newline included
|
||||
#define ONION_LEN 62
|
||||
// 0, direndpos, onionendpos
|
||||
// printstartpos = either 0 or direndpos
|
||||
// printlen = either onionendpos + 1 or ONION_LEN + 1 (additional 1 is for newline)
|
||||
size_t onionendpos; // end of .onion within string
|
||||
size_t direndpos; // end of dir before .onion within string
|
||||
size_t printstartpos; // where to start printing from
|
||||
size_t printlen; // precalculated, related to printstartpos
|
||||
|
||||
#define FORMATTED_SECRET_LEN (skprefixlen + SECRET_LEN)
|
||||
#define FORMATTED_PUBLIC_LEN (pkprefixlen + PUBLIC_LEN)
|
||||
|
||||
static size_t onionendpos; // end of .onion within string
|
||||
static size_t direndpos; // end of dir before .onion within string
|
||||
static size_t printstartpos; // where to start printing from
|
||||
static size_t printlen; // precalculated, related to printstartpos
|
||||
|
||||
static pthread_mutex_t fout_mutex;
|
||||
static FILE *fout;
|
||||
static int yamloutput = 0;
|
||||
static size_t numneedgenerate = 0;
|
||||
static int numwords = 1;
|
||||
static size_t numneedgenerate = 0;
|
||||
|
||||
static pthread_mutex_t keysgenerated_mutex;
|
||||
static volatile size_t keysgenerated = 0;
|
||||
static volatile int endwork = 0;
|
||||
|
||||
pthread_mutex_t fout_mutex;
|
||||
FILE *fout;
|
||||
|
||||
static void termhandler(int sig)
|
||||
{
|
||||
switch (sig) {
|
||||
|
@ -118,81 +109,6 @@ struct tstatstruct {
|
|||
VEC_STRUCT(tstatsvec,struct tstatstruct);
|
||||
#endif
|
||||
|
||||
typedef union {
|
||||
u8 raw[pkprefixlen + PUBLIC_LEN + 32];
|
||||
struct {
|
||||
u64 prefix[4];
|
||||
u64 key[4];
|
||||
u64 hash[4];
|
||||
} i;
|
||||
} pubonionunion;
|
||||
|
||||
|
||||
|
||||
#define BUF_APPEND(buf,offset,src,srclen) strncpy(&buf[offset],src,srclen); offset += srclen;
|
||||
#define BUF_APPEND_CSTR(buf,offset,src) BUF_APPEND(buf,offset,src,strlen(src))
|
||||
#define BUF_APPEND_CHAR(buf,offet,c) buf[offset++] = c;
|
||||
|
||||
static void writekeys(const char *hostname, const u8 *formated_secret, const u8 *formated_public)
|
||||
{
|
||||
char keysbuf[KEYS_LEN];
|
||||
size_t offset = 0;
|
||||
|
||||
BUF_APPEND_CSTR(keysbuf, offset, keys_field_generated);
|
||||
BUF_APPEND_CHAR(keysbuf, offset, '\n');
|
||||
|
||||
BUF_APPEND_CSTR(keysbuf, offset, keys_field_hostname);
|
||||
BUF_APPEND(keysbuf, offset, hostname, ONION_LEN);
|
||||
BUF_APPEND_CHAR(keysbuf, offset, '\n');
|
||||
|
||||
BUF_APPEND_CSTR(keysbuf, offset, keys_field_secretkey);
|
||||
char seckeybuf[SECKEY_LEN + NULLTERM_LEN];
|
||||
base64_to(seckeybuf, formated_secret, FORMATTED_SECRET_LEN);
|
||||
BUF_APPEND(keysbuf, offset, seckeybuf, SECKEY_LEN);
|
||||
BUF_APPEND_CHAR(keysbuf, offset, '\n');
|
||||
|
||||
BUF_APPEND_CSTR(keysbuf, offset, keys_field_publickey);
|
||||
char pubkeybuf[PUBKEY_LEN + NULLTERM_LEN];
|
||||
base64_to(pubkeybuf, formated_public, FORMATTED_PUBLIC_LEN);
|
||||
BUF_APPEND(keysbuf, offset, pubkeybuf, PUBKEY_LEN);
|
||||
BUF_APPEND_CHAR(keysbuf, offset, '\n');
|
||||
|
||||
BUF_APPEND_CSTR(keysbuf, offset, keys_field_time);
|
||||
char timebuf[TIME_LEN + NULLTERM_LEN];
|
||||
time_t timer;
|
||||
struct tm* tm_info;
|
||||
time(&timer);
|
||||
tm_info = localtime(&timer);
|
||||
strftime(timebuf, TIME_LEN + NULLTERM_LEN, "%Y-%m-%d %H:%M:%S", tm_info);
|
||||
BUF_APPEND(keysbuf, offset, timebuf, TIME_LEN);
|
||||
BUF_APPEND_CHAR(keysbuf, offset, '\n');
|
||||
|
||||
BUF_APPEND_CHAR(keysbuf, offset, '\n');
|
||||
|
||||
assert(offset == KEYS_LEN);
|
||||
|
||||
pthread_mutex_lock(&fout_mutex);
|
||||
fwrite(keysbuf,sizeof(keysbuf),1,fout);
|
||||
fflush(fout);
|
||||
pthread_mutex_unlock(&fout_mutex);
|
||||
}
|
||||
|
||||
#undef BUF_APPEND_CHAR
|
||||
#undef BUF_APPEND_CSTR
|
||||
#undef BUF_APPEND
|
||||
|
||||
static void printhostname(const char *hostname)
|
||||
{
|
||||
char buf[ONION_LEN + LINEFEED_LEN];
|
||||
strncpy(buf,hostname,ONION_LEN);
|
||||
buf[ONION_LEN] = '\n';
|
||||
|
||||
pthread_mutex_lock(&fout_mutex);
|
||||
fwrite(buf,sizeof(buf),1,fout);
|
||||
fflush(fout);
|
||||
pthread_mutex_unlock(&fout_mutex);
|
||||
}
|
||||
|
||||
static void onionready(char *sname,const u8 *secret,const u8 *pubonion)
|
||||
{
|
||||
if (endwork)
|
||||
|
@ -204,44 +120,60 @@ static void onionready(char *sname,const u8 *secret,const u8 *pubonion)
|
|||
pthread_mutex_unlock(&keysgenerated_mutex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (numneedgenerate) {
|
||||
++keysgenerated;
|
||||
if (keysgenerated >= numneedgenerate)
|
||||
if (keysgenerated == numneedgenerate)
|
||||
endwork = 1;
|
||||
pthread_mutex_unlock(&keysgenerated_mutex);
|
||||
}
|
||||
|
||||
if (fout) {
|
||||
if (yamloutput) {
|
||||
writekeys(&sname[printstartpos],secret,pubonion);
|
||||
if (!yamloutput) {
|
||||
if (createdir(sname,1) != 0) {
|
||||
pthread_mutex_lock(&fout_mutex);
|
||||
fprintf(stderr,"ERROR: could not create directory for key output\n");
|
||||
pthread_mutex_unlock(&fout_mutex);
|
||||
return;
|
||||
} else {
|
||||
printhostname(&sname[printstartpos]);
|
||||
}
|
||||
}
|
||||
|
||||
if (createdir(sname,1) != 0) {
|
||||
if (numneedgenerate)
|
||||
pthread_mutex_unlock(&keysgenerated_mutex);
|
||||
return;
|
||||
}
|
||||
strcpy(&sname[onionendpos],"/hs_ed25519_secret_key");
|
||||
writetofile(sname,secret,FORMATTED_SECRET_LEN,1);
|
||||
|
||||
strcpy(&sname[onionendpos],"/hs_ed25519_secret_key");
|
||||
writetofile(sname,secret,skprefixlen + SECRET_LEN,1);
|
||||
strcpy(&sname[onionendpos],"/hs_ed25519_public_key");
|
||||
writetofile(sname,pubonion,FORMATTED_PUBLIC_LEN,0);
|
||||
|
||||
strcpy(&sname[onionendpos],"/hostname");
|
||||
FILE *hfile = fopen(sname,"w");
|
||||
if (hfile) {
|
||||
strcpy(&sname[onionendpos],"/hostname");
|
||||
FILE *hfile = fopen(sname,"w");
|
||||
sname[onionendpos] = '\n';
|
||||
fwrite(&sname[direndpos],ONION_LEN + 1,1,hfile);
|
||||
fclose(hfile);
|
||||
}
|
||||
if (hfile) {
|
||||
fwrite(&sname[direndpos],ONION_LEN + 1,1,hfile);
|
||||
fclose(hfile);
|
||||
}
|
||||
if (fout) {
|
||||
pthread_mutex_lock(&fout_mutex);
|
||||
fwrite(&sname[printstartpos],printlen,1,fout);
|
||||
fflush(fout);
|
||||
pthread_mutex_unlock(&fout_mutex);
|
||||
}
|
||||
} else
|
||||
yamlout_writekeys(&sname[direndpos],pubonion,secret);
|
||||
}
|
||||
|
||||
strcpy(&sname[onionendpos],"/hs_ed25519_public_key");
|
||||
writetofile(sname,pubonion,pkprefixlen + PUBLIC_LEN,0);
|
||||
union pubonionunion {
|
||||
u8 raw[PKPREFIX_SIZE + PUBLIC_LEN + 32];
|
||||
struct {
|
||||
u64 prefix[4];
|
||||
u64 key[4];
|
||||
u64 hash[4];
|
||||
} i;
|
||||
} ;
|
||||
|
||||
static char *makesname()
|
||||
{
|
||||
char *sname = (char *) malloc(workdirlen + ONION_LEN + 63 + 1);
|
||||
if (!sname)
|
||||
abort();
|
||||
if (workdir)
|
||||
memcpy(sname,workdir,workdirlen);
|
||||
return sname;
|
||||
}
|
||||
|
||||
// little endian inc
|
||||
|
@ -271,10 +203,10 @@ static inline void shiftpk(u8 *dst,const u8 *src,size_t sbits)
|
|||
|
||||
static void *dowork(void *task)
|
||||
{
|
||||
pubonionunion pubonion;
|
||||
u8 * const pk = &pubonion.raw[pkprefixlen];
|
||||
u8 secret[skprefixlen + SECRET_LEN];
|
||||
u8 * const sk = &secret[skprefixlen];
|
||||
union pubonionunion pubonion;
|
||||
u8 * const pk = &pubonion.raw[PKPREFIX_SIZE];
|
||||
u8 secret[SKPREFIX_SIZE + SECRET_LEN];
|
||||
u8 * const sk = &secret[SKPREFIX_SIZE];
|
||||
u8 seed[SEED_LEN];
|
||||
u8 hashsrc[checksumstrlen + PUBLIC_LEN + 1];
|
||||
u8 wpk[PUBLIC_LEN + 1];
|
||||
|
@ -285,19 +217,15 @@ static void *dowork(void *task)
|
|||
#endif
|
||||
PREFILTER
|
||||
|
||||
memcpy(secret,skprefix,skprefixlen);
|
||||
memcpy(secret,skprefix,SKPREFIX_SIZE);
|
||||
wpk[PUBLIC_LEN] = 0;
|
||||
memset(&pubonion,0,sizeof(pubonion));
|
||||
memcpy(pubonion.raw,pkprefix,pkprefixlen);
|
||||
memcpy(pubonion.raw,pkprefix,PKPREFIX_SIZE);
|
||||
// write version later as it will be overwritten by hash
|
||||
memcpy(hashsrc,checksumstr,checksumstrlen);
|
||||
hashsrc[checksumstrlen + PUBLIC_LEN] = 0x03; // version
|
||||
|
||||
sname = (char *) malloc(workdirlen + ONION_LEN + 63 + 1);
|
||||
if (!sname)
|
||||
abort();
|
||||
if (workdir)
|
||||
memcpy(sname,workdir,workdirlen);
|
||||
sname = makesname();
|
||||
|
||||
initseed:
|
||||
randombytes(seed,sizeof(seed));
|
||||
|
@ -371,10 +299,10 @@ static void addsztoscalar32(u8 *dst,size_t v)
|
|||
|
||||
static void *dofastwork(void *task)
|
||||
{
|
||||
pubonionunion pubonion;
|
||||
u8 * const pk = &pubonion.raw[pkprefixlen];
|
||||
u8 secret[skprefixlen + SECRET_LEN];
|
||||
u8 * const sk = &secret[skprefixlen];
|
||||
union pubonionunion pubonion;
|
||||
u8 * const pk = &pubonion.raw[PKPREFIX_SIZE];
|
||||
u8 secret[SKPREFIX_SIZE + SECRET_LEN];
|
||||
u8 * const sk = &secret[SKPREFIX_SIZE];
|
||||
u8 seed[SEED_LEN];
|
||||
u8 hashsrc[checksumstrlen + PUBLIC_LEN + 1];
|
||||
u8 wpk[PUBLIC_LEN + 1];
|
||||
|
@ -387,19 +315,15 @@ static void *dofastwork(void *task)
|
|||
#endif
|
||||
PREFILTER
|
||||
|
||||
memcpy(secret,skprefix,skprefixlen);
|
||||
memcpy(secret,skprefix,SKPREFIX_SIZE);
|
||||
wpk[PUBLIC_LEN] = 0;
|
||||
memset(&pubonion,0,sizeof(pubonion));
|
||||
memcpy(pubonion.raw,pkprefix,pkprefixlen);
|
||||
memcpy(pubonion.raw,pkprefix,PKPREFIX_SIZE);
|
||||
// write version later as it will be overwritten by hash
|
||||
memcpy(hashsrc,checksumstr,checksumstrlen);
|
||||
hashsrc[checksumstrlen + PUBLIC_LEN] = 0x03; // version
|
||||
|
||||
sname = (char *) malloc(workdirlen + ONION_LEN + 63 + 1);
|
||||
if (!sname)
|
||||
abort();
|
||||
if (workdir)
|
||||
memcpy(sname,workdir,workdirlen);
|
||||
sname = makesname();
|
||||
|
||||
initseed:
|
||||
#ifdef STATISTICS
|
||||
|
@ -505,6 +429,7 @@ enum {
|
|||
Q_FAILOPENOUTPUT,
|
||||
Q_FAILTHREAD,
|
||||
Q_FAILTIME,
|
||||
Q_FAILOPENINPUT,
|
||||
} ;
|
||||
|
||||
static void e_additional()
|
||||
|
@ -551,173 +476,18 @@ static void setworkdir(const char *wd)
|
|||
|
||||
VEC_STRUCT(threadvec, pthread_t);
|
||||
|
||||
|
||||
int parseandcreate(const char *filepath, const char *hostname)
|
||||
{
|
||||
if (strlen(hostname) != ONION_LEN) {
|
||||
fprintf(stderr, "Invalid onion address \"%s\".\n", hostname);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char buf[16*1024];
|
||||
memset(buf, 0, sizeof(buf));
|
||||
FILE *fkeys = fopen(filepath, "r");
|
||||
if (fkeys == NULL) {
|
||||
fprintf(stderr, "Cannot open file with keys \"%s\" for reading.\n", filepath);
|
||||
return 2;
|
||||
}
|
||||
int error_number = 1;
|
||||
size_t readbytes = 0;
|
||||
while (1) {
|
||||
const size_t currentread = fread(
|
||||
buf + readbytes, // Possibly we already partially receive desired onion address
|
||||
sizeof(buf[0]),
|
||||
sizeof(buf) - readbytes - NULLTERM_LEN,
|
||||
fkeys);
|
||||
if (currentread == 0) {
|
||||
fprintf(stderr, "Not found desired hostname \"%s\" in file \"%s\".\n", hostname, filepath);
|
||||
error_number = 3;
|
||||
break;
|
||||
}
|
||||
readbytes += currentread;
|
||||
buf[readbytes] = '\0';
|
||||
char *pfound = strstr(buf, hostname);
|
||||
if (pfound == NULL) {
|
||||
if (readbytes > ONION_LEN) {
|
||||
memmove(buf, buf + readbytes - ONION_LEN, ONION_LEN);
|
||||
readbytes = ONION_LEN;
|
||||
}
|
||||
} else { // Got it!
|
||||
memmove(buf, pfound, readbytes - (pfound - buf));
|
||||
readbytes -= pfound - buf;
|
||||
buf[readbytes] = '\0';
|
||||
char *pendrecord = NULL;
|
||||
while (1) {
|
||||
const size_t currentread = fread(
|
||||
buf + readbytes,
|
||||
sizeof(buf[0]),
|
||||
sizeof(buf) - readbytes - NULLTERM_LEN,
|
||||
fkeys);
|
||||
readbytes += currentread;
|
||||
buf[readbytes] = '\0';
|
||||
pendrecord = strstr(buf, "\n\n");
|
||||
if (pendrecord != NULL || currentread == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pendrecord == NULL) {
|
||||
fprintf(stderr, "Looks like file with keys \"%s\" is incomplete, found hostname but not keys.\n", filepath);
|
||||
error_number = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
const char *const pfield_sec_begin = strstr(buf, keys_field_secretkey);
|
||||
if (pfield_sec_begin == NULL) {
|
||||
fprintf(stderr, "Cannot find field with secret key within generated section.\n");
|
||||
error_number = 5;
|
||||
break;
|
||||
}
|
||||
const char *const p_sec_begin = pfield_sec_begin + KEYS_FIELD_SECRETKEY_LEN;
|
||||
if (pendrecord - p_sec_begin < BASE64_TO_LEN(FORMATTED_SECRET_LEN)) {
|
||||
fprintf(stderr, "Generated section it too small to keep base64 encoding of secret key.\n");
|
||||
error_number = 6;
|
||||
break;
|
||||
}
|
||||
char secbuf[FORMATTED_SECRET_LEN];
|
||||
if (-1 == base64_from((u8*)secbuf, p_sec_begin, BASE64_TO_LEN(FORMATTED_SECRET_LEN))) {
|
||||
fprintf(stderr, "Invalid base64 encoding of secret key.\n");
|
||||
error_number = 7;
|
||||
break;
|
||||
}
|
||||
|
||||
const char *const pfield_pub_begin = strstr(buf, keys_field_publickey);
|
||||
if (pfield_pub_begin == NULL) {
|
||||
fprintf(stderr, "Cannot find field with public key within generated section.\n");
|
||||
error_number = 8;
|
||||
break;
|
||||
}
|
||||
const char *const p_pub_begin = pfield_pub_begin + KEYS_FIELD_PUBLICKEY_LEN;
|
||||
if (pendrecord - p_pub_begin < BASE64_TO_LEN(KEYS_FIELD_PUBLICKEY_LEN)) {
|
||||
fprintf(stderr, "Generated section it too small to keep base64 encoding of public key.\n");
|
||||
error_number = 9;
|
||||
break;
|
||||
}
|
||||
char pubbuf[FORMATTED_PUBLIC_LEN];
|
||||
if (-1 == base64_from((u8*)pubbuf, p_pub_begin, BASE64_TO_LEN(FORMATTED_PUBLIC_LEN))) {
|
||||
fprintf(stderr, "Invalid base64 encoding of secret key.\n");
|
||||
error_number = 10;
|
||||
break;
|
||||
}
|
||||
|
||||
char pathbuf[1024];
|
||||
const size_t keys_directory_path_len = workdirlen + strlen(hostname);
|
||||
if (keys_directory_path_len >= sizeof(pathbuf)) {
|
||||
fprintf(stderr, "Keys directory path to is too long: %ld, max allowed length is %ld.\n", keys_directory_path_len, sizeof(pathbuf));
|
||||
error_number = 11;
|
||||
break;
|
||||
}
|
||||
strncpy(pathbuf, workdir, workdirlen);
|
||||
strncpy(pathbuf + workdirlen, hostname, strlen(hostname));
|
||||
pathbuf[keys_directory_path_len] = '\0';
|
||||
if (-1 == createdir(pathbuf, use_secret_mode)) {
|
||||
fprintf(stderr, "Cannot create directory \"%s\" for key files.\n", pathbuf);
|
||||
error_number = 12;
|
||||
break;
|
||||
}
|
||||
|
||||
const size_t secretkey_filepath_len = keys_directory_path_len + PATH_SEPARATOR_LEN + strlen(secret_key_filename);
|
||||
if (secretkey_filepath_len >= sizeof(pathbuf)) {
|
||||
fprintf(stderr, "Path to file with secret key is too long %ld, max allowed length is %ld.\n", secretkey_filepath_len, sizeof(pathbuf));
|
||||
error_number = 13;
|
||||
break;
|
||||
}
|
||||
pathbuf[keys_directory_path_len] = '/';
|
||||
strncpy(pathbuf + keys_directory_path_len + PATH_SEPARATOR_LEN, secret_key_filename, strlen(secret_key_filename));
|
||||
pathbuf[secretkey_filepath_len] = '\0';
|
||||
if (-1 == writetofile(pathbuf, (u8*)secbuf, sizeof(secbuf), use_secret_mode)) {
|
||||
fprintf(stderr, "Can't write secret key to file \"%s\".\n", pathbuf);
|
||||
error_number = 14;
|
||||
break;
|
||||
}
|
||||
|
||||
const size_t publickey_filepath_len = keys_directory_path_len + PATH_SEPARATOR_LEN + strlen(public_key_filename);
|
||||
if (publickey_filepath_len >= sizeof(pathbuf)) {
|
||||
fprintf(stderr, "Path to file with public key is too long %ld, max allowed length is %ld.\n", publickey_filepath_len, sizeof(pathbuf));
|
||||
error_number = 15;
|
||||
break;
|
||||
}
|
||||
pathbuf[keys_directory_path_len] = '/';
|
||||
strncpy(pathbuf + keys_directory_path_len + PATH_SEPARATOR_LEN, public_key_filename, strlen(public_key_filename));
|
||||
pathbuf[publickey_filepath_len] = '\0';
|
||||
if (-1 == writetofile(pathbuf, (u8*)pubbuf, sizeof(pubbuf), use_public_mode)) {
|
||||
fprintf(stderr, "Can't write public key to file \"%s\".\n", pathbuf);
|
||||
error_number = 16;
|
||||
break;
|
||||
}
|
||||
|
||||
pathbuf[keys_directory_path_len] = '\0';
|
||||
fprintf(stderr, "Keys successfully exported to directory \"%s\".\n", pathbuf);
|
||||
error_number = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ferror(fkeys) || error_number) {
|
||||
fprintf(stderr, "Error #%d while parsing generated file \"%s\" or extracting keys.\n", error_number, filepath);
|
||||
}
|
||||
fclose(fkeys);
|
||||
return error_number;
|
||||
}
|
||||
|
||||
int main(int argc,char **argv)
|
||||
{
|
||||
const char *outfile = 0;
|
||||
const char *infile = 0;
|
||||
const char *hostname = 0;
|
||||
const char *arg;
|
||||
int ignoreargs = 0;
|
||||
int dirnameflag = 0;
|
||||
int numthreads = 0;
|
||||
int fastkeygen = 1;
|
||||
int outfileoverwrite;
|
||||
int yamlinput = 0;
|
||||
int outfileoverwrite = 0;
|
||||
struct threadvec threads;
|
||||
#ifdef STATISTICS
|
||||
struct statsvec stats;
|
||||
|
@ -732,8 +502,6 @@ int main(int argc,char **argv)
|
|||
|
||||
setvbuf(stderr,0,_IONBF,0);
|
||||
fout = stdout;
|
||||
pthread_mutex_init(&keysgenerated_mutex,0);
|
||||
pthread_mutex_init(&fout_mutex,0);
|
||||
|
||||
const char *progname = argv[0];
|
||||
if (argc <= 1) {
|
||||
|
@ -857,18 +625,23 @@ int main(int argc,char **argv)
|
|||
else if (*arg == 'y')
|
||||
yamloutput = 1;
|
||||
else if (*arg == 'Y') {
|
||||
const char *filepath = 0, *hostname = 0;
|
||||
if (argc--) {
|
||||
filepath = *argv++;
|
||||
if (argc--) {
|
||||
yamlinput = 1;
|
||||
if (argc) {
|
||||
--argc;
|
||||
infile = *argv++;
|
||||
if (!*infile)
|
||||
infile = 0;
|
||||
if (argc) {
|
||||
--argc;
|
||||
hostname = *argv++;
|
||||
return parseandcreate(filepath, hostname);
|
||||
if (!*hostname)
|
||||
hostname = 0;
|
||||
if (hostname && strlen(hostname) != ONION_LEN) {
|
||||
fprintf(stderr,"bad onion argument length\n");
|
||||
exit(Q_UNRECOGNISED);
|
||||
}
|
||||
}
|
||||
else
|
||||
e_additional();
|
||||
}
|
||||
else
|
||||
e_additional();
|
||||
}
|
||||
else {
|
||||
fprintf(stderr,"unrecognised argument: -%c\n",*arg);
|
||||
|
@ -889,6 +662,11 @@ int main(int argc,char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
if (!fout && yamloutput) {
|
||||
fprintf(stderr,"nil output with yaml mode does not make sense\n");
|
||||
exit(Q_FAILOPENOUTPUT); // define new err code?
|
||||
}
|
||||
|
||||
filters_prepare();
|
||||
|
||||
filters_print();
|
||||
|
@ -913,12 +691,41 @@ int main(int argc,char **argv)
|
|||
|
||||
if (!dirnameflag) {
|
||||
printstartpos = direndpos;
|
||||
printlen = ONION_LEN + 1;
|
||||
printlen = ONION_LEN + 1; // + '\n'
|
||||
} else {
|
||||
printstartpos = 0;
|
||||
printlen = onionendpos + 1;
|
||||
printlen = onionendpos + 1; // + '\n'
|
||||
}
|
||||
|
||||
if (yamlinput) {
|
||||
char *sname = makesname();
|
||||
FILE *fin = stdin;
|
||||
if (infile) {
|
||||
fin = fopen(infile,"r");
|
||||
if (!fin) {
|
||||
fprintf(stderr,"failed to open input file\n");
|
||||
return Q_FAILOPENINPUT;
|
||||
}
|
||||
}
|
||||
tret = yamlin_parseandcreate(fin,sname,hostname);
|
||||
if (infile) {
|
||||
fclose(fin);
|
||||
fin = 0;
|
||||
}
|
||||
free(sname);
|
||||
|
||||
if (tret)
|
||||
return tret;
|
||||
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (yamloutput)
|
||||
yamlout_init();
|
||||
|
||||
pthread_mutex_init(&keysgenerated_mutex,0);
|
||||
pthread_mutex_init(&fout_mutex,0);
|
||||
|
||||
if (numthreads <= 0) {
|
||||
numthreads = cpucount();
|
||||
if (numthreads <= 0)
|
||||
|
@ -1061,8 +868,13 @@ int main(int argc,char **argv)
|
|||
if (!quietflag)
|
||||
fprintf(stderr," done.\n");
|
||||
|
||||
if (yamloutput)
|
||||
yamlout_clean();
|
||||
|
||||
pthread_mutex_destroy(&keysgenerated_mutex);
|
||||
pthread_mutex_destroy(&fout_mutex);
|
||||
|
||||
done:
|
||||
filters_clean();
|
||||
|
||||
if (outfile)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue