diff --git a/iguana/SuperNET.c b/iguana/SuperNET.c index e41d4f443..bce99e92f 100644 --- a/iguana/SuperNET.c +++ b/iguana/SuperNET.c @@ -98,10 +98,10 @@ void SuperNET_myipaddr(struct supernet_info *myinfo,struct iguana_info *coin,str //printf("myipaddr.%s self.%x your.%x\n",myinfo->ipaddr,myinfo->myaddr.selfipbits,myinfo->myaddr.myipbits); } -uint16_t SuperNET_checkc(struct supernet_info *myinfo,bits256 otherpub,uint64_t tag) +uint16_t SuperNET_checkc(bits256 privkey,bits256 otherpub,uint64_t tag) { uint8_t buf[40]; bits256 check,seed,seed2; - seed = curve25519_shared(myinfo->privkey,otherpub); + seed = curve25519_shared(privkey,otherpub); vcalc_sha256(0,seed2.bytes,seed.bytes,sizeof(seed)); memcpy(buf,seed2.bytes,sizeof(seed)); iguana_rwnum(1,&buf[sizeof(seed)],sizeof(tag),&tag); @@ -109,7 +109,7 @@ uint16_t SuperNET_checkc(struct supernet_info *myinfo,bits256 otherpub,uint64_t return(check.ushorts[0]); } -int32_t SuperNET_json2bits(struct supernet_info *myinfo,bits256 seed2,uint8_t *serialized,int32_t *complenp,uint8_t *compressed,int32_t maxsize,char *destip,bits256 destpub,cJSON *json) +int32_t SuperNET_json2bits(char *myipaddr,bits256 sessionpriv,bits256 sessionpub,bits256 seed2,uint8_t *serialized,int32_t *complenp,uint8_t *compressed,int32_t maxsize,char *destip,bits256 destpub,cJSON *json) { uint16_t apinum,checkc=0; uint32_t ipbits,crc; uint64_t tag; char *hexmsg; int32_t n,numbits,len = sizeof(uint32_t); @@ -118,14 +118,17 @@ int32_t SuperNET_json2bits(struct supernet_info *myinfo,bits256 seed2,uint8_t *s OS_randombytes((uint8_t *)&tag,sizeof(tag)); ipbits = (uint32_t)calc_ipbits(destip); len += iguana_rwnum(1,&serialized[len],sizeof(uint32_t),&ipbits); - ipbits = (uint32_t)calc_ipbits(myinfo->ipaddr); + ipbits = (uint32_t)calc_ipbits(myipaddr); len += iguana_rwnum(1,&serialized[len],sizeof(uint32_t),&ipbits); - len += iguana_rwbignum(1,&serialized[len],sizeof(myinfo->myaddr.pubkey),myinfo->myaddr.pubkey.bytes); + len += iguana_rwbignum(1,&serialized[len],sizeof(sessionpub),sessionpub.bytes); len += iguana_rwnum(1,&serialized[len],sizeof(tag),&tag); - checkc = SuperNET_checkc(myinfo,destpub,tag); + checkc = SuperNET_checkc(sessionpriv,destpub,tag); len += iguana_rwnum(1,&serialized[len],sizeof(checkc),&checkc); if ( (apinum= SuperNET_API2num(jstr(json,"agent"),jstr(json,"method"))) == 0xffff ) + { + printf("agent.(%s) method.(%s) is not found\n",jstr(json,"agent"),jstr(json,"method")); return(-1); + } len += iguana_rwnum(1,&serialized[len],sizeof(apinum),&apinum); if ( (hexmsg= jstr(json,"message")) != 0 ) { @@ -162,7 +165,7 @@ int32_t SuperNET_json2bits(struct supernet_info *myinfo,bits256 seed2,uint8_t *s return(len); } -cJSON *SuperNET_bits2json(struct supernet_info *myinfo,bits256 sharedseed,uint8_t *serialized,uint8_t *space,int32_t datalen,int32_t iscompressed) +cJSON *SuperNET_bits2json(bits256 sharedseed,uint8_t *serialized,uint8_t *space,int32_t datalen,int32_t iscompressed) { char destip[64],method[64],checkstr[5],agent[64],myipaddr[64],str[65],*hexmsg; uint64_t tag; uint16_t apinum,checkc; uint32_t destipbits,myipbits; bits256 seed2,senderpub; @@ -242,12 +245,12 @@ cJSON *SuperNET_bits2json(struct supernet_info *myinfo,bits256 sharedseed,uint8_ int32_t iguana_send_supernet(struct iguana_info *coin,struct iguana_peer *addr,char *jsonstr,int32_t delaymillis) { - int32_t datalen,complen,qlen = -1; uint8_t *serialized,*compressed; cJSON *json; + int32_t datalen,complen,qlen = -1; uint8_t *serialized,*compressed; cJSON *json; struct supernet_info *myinfo = SuperNET_MYINFO(0); if ( (json= cJSON_Parse(jsonstr)) != 0 ) { compressed = malloc(sizeof(struct iguana_msghdr) + IGUANA_MAXPACKETSIZE); serialized = malloc(sizeof(struct iguana_msghdr) + IGUANA_MAXPACKETSIZE); - datalen = SuperNET_json2bits(SuperNET_MYINFO(0),addr->sharedseed,&serialized[sizeof(struct iguana_msghdr)],&complen,&compressed[sizeof(struct iguana_msghdr)],IGUANA_MAXPACKETSIZE,addr->ipaddr,addr->pubkey,json); + datalen = SuperNET_json2bits(myinfo->ipaddr,myinfo->privkey,myinfo->myaddr.pubkey,addr->sharedseed,&serialized[sizeof(struct iguana_msghdr)],&complen,&compressed[sizeof(struct iguana_msghdr)],IGUANA_MAXPACKETSIZE,addr->ipaddr,addr->pubkey,json); printf("SUPERSEND.(%s) -> (%s) delaymillis.%d datalen.%d\n",jsonstr,addr->ipaddr,delaymillis,datalen); if ( datalen >= 0 ) { @@ -450,7 +453,7 @@ char *SuperNET_p2p(struct iguana_info *coin,struct iguana_peer *addr,int32_t *de *delaymillisp = 0; if ( compressed != 0 ) space = malloc(sizeof(struct iguana_msghdr) + IGUANA_MAXPACKETSIZE); - if ( (json= SuperNET_bits2json(myinfo,addr->sharedseed,data,space,datalen,compressed)) != 0 ) + if ( (json= SuperNET_bits2json(addr->sharedseed,data,space,datalen,compressed)) != 0 ) { senderpub = jbits256(json,"mypub"); if ( memcmp(senderpub.bytes,addr->pubkey.bytes,sizeof(senderpub)) != 0 ) @@ -458,7 +461,7 @@ char *SuperNET_p2p(struct iguana_info *coin,struct iguana_peer *addr,int32_t *de if ( (checkstr= jstr(json,"check")) != 0 ) { decode_hex((uint8_t *)&othercheckc,sizeof(othercheckc),checkstr); - checkc = SuperNET_checkc(myinfo,senderpub,j64bits(json,"tag")); + checkc = SuperNET_checkc(myinfo->privkey,senderpub,j64bits(json,"tag")); if ( checkc == othercheckc ) addr->validpub++; else if ( addr->validpub > 0 ) diff --git a/iguana/SuperNET.h b/iguana/SuperNET.h index b5e5b4193..221a17117 100644 --- a/iguana/SuperNET.h +++ b/iguana/SuperNET.h @@ -75,8 +75,9 @@ struct supernet_agent struct supernet_address { - bits256 pubkey,iphash; - uint32_t selfipbits,myipbits; int32_t confirmed,totalconfirmed; + bits256 pubkey,iphash,persistent; + uint32_t selfipbits,myipbits; int32_t confirmed,totalconfirmed; uint64_t nxt64bits; + char NXTADDR[32]; }; struct supernet_info @@ -84,7 +85,7 @@ struct supernet_info char ipaddr[64],transport[8]; int32_t APISLEEP; int32_t iamrelay; int32_t Debuglevel,readyflag,dead,POLLTIMEOUT; char rpcsymbol[16],LBpoint[64],PUBpoint[64]; //int32_t pullsock,subclient,lbclient,lbserver,servicesock,pubglobal,pubrelays,numservers; - bits256 privkey; + bits256 privkey,persistent_priv; uint8_t *recvbuf[6]; struct supernet_address myaddr; int32_t LBsock,PUBsock,reqsock,subsock,networktimeout,maxdelay; @@ -116,6 +117,8 @@ char *SuperNET_DHTsend(struct supernet_info *myinfo,bits256 routehash,char *hexm uint16_t SuperNET_API2num(char *agent,char *method); int32_t SuperNET_num2API(char *agent,char *method,uint16_t num); bits256 SuperNET_sharedseed(struct supernet_info *myinfo,bits256 otherpub); +cJSON *SuperNET_bits2json(bits256 sharedseed,uint8_t *serialized,uint8_t *space,int32_t datalen,int32_t iscompressed); +int32_t SuperNET_json2bits(char *myipaddr,bits256 sessionpriv,bits256 sessionpub,bits256 seed2,uint8_t *serialized,int32_t *complenp,uint8_t *compressed,int32_t maxsize,char *destip,bits256 destpub,cJSON *json); #endif diff --git a/iguana/iguana_json.c b/iguana/iguana_json.c index 5d971d6e5..55af2c00e 100755 --- a/iguana/iguana_json.c +++ b/iguana/iguana_json.c @@ -664,6 +664,12 @@ TWO_STRINGS(SuperNET,html,agentform,htmlfile) fclose(fp); return(jprint(retjson,1)); } + +ZERO_ARGS(SuperNET,saveconf) +{ + return(clonestr("{\"result\":\"saveconf here\"}")); +} + #undef IGUANA_ARGS #include "../includes/iguana_apiundefs.h" diff --git a/iguana/main.c b/iguana/main.c index 16b749d66..298b886f0 100644 --- a/iguana/main.c +++ b/iguana/main.c @@ -256,37 +256,10 @@ void sigcontinue_func() { printf("\nSIGCONT\n"); signal(SIGCONT,sigcontinue_func void iguana_main(void *arg) { - char helperstr[64],*tmpstr,*helperargs,*ipaddr,*coinargs=0,*secret,*jsonstr = arg; - int32_t i,len,flag,c; cJSON *json; uint8_t secretbuf[512]; int64_t allocsize; + FILE *fp; cJSON *json; uint8_t *space,secretbuf[512]; uint32_t r; int64_t allocsize; + char helperstr[64],fname[512],*wallet2,*wallet2str,*tmpstr,*confstr,*helperargs,*ipaddr,*coinargs=0,*secret,*jsonstr = arg; + int32_t i,len,flag,c,datalen; bits256 acct,seed,checkhash,wallethash,wallet2shared,wallet2priv,wallet2pub; memset(&MYINFO,0,sizeof(MYINFO)); - if ( (ipaddr= OS_filestr(&allocsize,"ipaddr")) != 0 ) - { - printf("got ipaddr.(%s)\n",ipaddr); - len = (int32_t)strlen(ipaddr) - 1; - while ( len > 8 && ((c= ipaddr[len]) == '\r' || c == '\n' || c == ' ' || c == '\t') ) - ipaddr[len] = 0, len--; - printf("got ipaddr.(%s) %x\n",ipaddr,is_ipaddr(ipaddr)); - if ( is_ipaddr(ipaddr) != 0 ) - { - strcpy(MYINFO.ipaddr,ipaddr); - MYINFO.myaddr.selfipbits = (uint32_t)calc_ipbits(ipaddr); - } - free(ipaddr); - } - if ( MYINFO.myaddr.selfipbits == 0 ) - { - strcpy(MYINFO.ipaddr,"127.0.0.1"); - MYINFO.myaddr.selfipbits = (uint32_t)calc_ipbits(MYINFO.ipaddr); - } - signal(SIGINT,sigint_func); - signal(SIGILL,sigillegal_func); - signal(SIGHUP,sighangup_func); - //signal(SIGKILL,sigkill_func); - signal(SIGABRT,sigabort_func); - signal(SIGQUIT,sigquit_func); - signal(SIGCHLD,sigchild_func); - signal(SIGALRM,sigalarm_func); - signal(SIGCONT,sigcontinue_func); mycalloc(0,0,0); iguana_initQ(&helperQ,"helperQ"); OS_ensure_directory("confs"); @@ -298,12 +271,14 @@ void iguana_main(void *arg) API_json = jobj(API_json,"API"); free(tmpstr); } - OS_randombytes(MYINFO.privkey.bytes,sizeof(MYINFO.privkey)); + memset(wallet2shared.bytes,0,sizeof(wallet2shared)); + wallethash = GENESIS_PRIVKEY; + wallet2pub = GENESIS_PUBKEY; if ( jsonstr != 0 && (json= cJSON_Parse(jsonstr)) != 0 ) { if ( jobj(json,"numhelpers") != 0 ) IGUANA_NUMHELPERS = juint(json,"numhelpers"); - if ( (secret= jstr(json,"secret")) != 0 ) + if ( (secret= jstr(json,"wallet")) != 0 ) { len = (int32_t)strlen(secret); if ( is_hexstr(secret,0) != 0 && len == 128 ) @@ -311,13 +286,150 @@ void iguana_main(void *arg) len >>= 1; decode_hex(secretbuf,len,secret); } else vcalc_sha256(0,secretbuf,(void *)secret,len), len = sizeof(bits256); - memcpy(MYINFO.privkey.bytes,secretbuf,sizeof(MYINFO.privkey)); + memcpy(wallethash.bytes,secretbuf,sizeof(wallethash)); + } + if ( (wallet2= jstr(json,"keyfile")) != 0 ) + { + if ( (wallet2str= OS_filestr(&allocsize,wallet2)) != 0 ) + { + r = calc_crc32(0,wallet2str,(int32_t)allocsize); + r %= 32; + for (i=0; i pub.%s shared.%s\n",wallet2,bits256_str(str,wallet2pub),bits256_str(str2,wallet2shared)); + free(wallet2str); + } } if ( jobj(json,"coins") != 0 ) coinargs = jsonstr; } + OS_randombytes(MYINFO.persistent_priv.bytes,sizeof(MYINFO.privkey)); + MYINFO.myaddr.persistent = curve25519(MYINFO.persistent_priv,curve25519_basepoint9()); + vcalc_sha256(0,acct.bytes,(void *)MYINFO.myaddr.persistent.bytes,sizeof(bits256)); + MYINFO.myaddr.nxt64bits = acct.txid; + RS_encode(MYINFO.myaddr.NXTADDR,MYINFO.myaddr.nxt64bits); + if ( bits256_nonz(wallet2shared) > 0 ) + sprintf(fname,"confs/iguana.%llu",(long long)wallet2shared.txid); + else sprintf(fname,"confs/iguana.conf"); + printf("check conf.(%s)\n",fname); + if ( (confstr= OS_filestr(&allocsize,fname)) != 0 ) + { + datalen = (int32_t)strlen(confstr); + if ( bits256_nonz(wallet2shared) > 0 ) + { + space = malloc(IGUANA_MAXPACKETSIZE); + json = SuperNET_bits2json(wallet2shared,(uint8_t *)confstr,space,datalen,1); + free(space); + printf("decoded.(%s)\n",jprint(json,0)); + } else json = cJSON_Parse(confstr), printf("CONF.(%s)\n",confstr); + if ( json != 0 ) + { + if ( (ipaddr= jstr(json,"ipaddr")) != 0 && is_ipaddr(ipaddr) != 0 ) + strcpy(MYINFO.ipaddr,ipaddr); + if ( (secret= jstr(json,"secret")) != 0 ) + { + MYINFO.myaddr.nxt64bits = conv_NXTpassword(MYINFO.persistent_priv.bytes,MYINFO.myaddr.persistent.bytes,(uint8_t *)secret,(int32_t)strlen(secret)); + RS_encode(MYINFO.myaddr.NXTADDR,MYINFO.myaddr.nxt64bits); + } + else + { + MYINFO.persistent_priv = jbits256(json,"persistent_priv"); + if ( bits256_nonz(MYINFO.persistent_priv) == 0 ) + { + printf("null persistent_priv? generate new one\n"); + OS_randombytes(MYINFO.persistent_priv.bytes,sizeof(MYINFO.privkey)); + } + MYINFO.myaddr.persistent = jbits256(json,"persistent_pub"); + checkhash = curve25519(MYINFO.persistent_priv,curve25519_basepoint9()); + } + free_json(json); + if ( memcmp(checkhash.bytes,MYINFO.myaddr.persistent.bytes,sizeof(checkhash)) != 0 ) + { + printf("persistent pubkey mismatches one in iguana.conf\n"); + MYINFO.myaddr.persistent = checkhash; + confstr = 0; + } + } else printf("Cant parse.(%s)\n",confstr), confstr = 0; + if ( confstr != 0 ) + free(confstr); + } + else if ( (ipaddr= OS_filestr(&allocsize,"ipaddr")) != 0 ) + { + printf("got ipaddr.(%s)\n",ipaddr); + len = (int32_t)strlen(ipaddr) - 1; + while ( len > 8 && ((c= ipaddr[len]) == '\r' || c == '\n' || c == ' ' || c == '\t') ) + ipaddr[len] = 0, len--; + printf("got ipaddr.(%s) %x\n",ipaddr,is_ipaddr(ipaddr)); + if ( is_ipaddr(ipaddr) != 0 ) + { + strcpy(MYINFO.ipaddr,ipaddr); + MYINFO.myaddr.selfipbits = (uint32_t)calc_ipbits(ipaddr); + } + free(ipaddr); + } + if ( MYINFO.myaddr.selfipbits == 0 ) + { + strcpy(MYINFO.ipaddr,"127.0.0.1"); + MYINFO.myaddr.selfipbits = (uint32_t)calc_ipbits(MYINFO.ipaddr); + } + OS_randombytes(MYINFO.privkey.bytes,sizeof(MYINFO.privkey)); MYINFO.myaddr.pubkey = curve25519(MYINFO.privkey,curve25519_basepoint9()); - char str[65],str2[65]; printf("PRIV.%s PUB.%s\n",bits256_str(str,MYINFO.privkey),bits256_str(str2,MYINFO.myaddr.pubkey)); + vcalc_sha256(0,acct.bytes,(void *)MYINFO.myaddr.persistent.bytes,sizeof(bits256)); + MYINFO.myaddr.nxt64bits = acct.txid; + RS_encode(MYINFO.myaddr.NXTADDR,MYINFO.myaddr.nxt64bits); + char str[65],str2[65]; printf("%s %llu PRIV.%s PUB.%s persistent.%llx %llx\n",MYINFO.myaddr.NXTADDR,(long long)MYINFO.myaddr.nxt64bits,bits256_str(str,MYINFO.privkey),bits256_str(str2,MYINFO.myaddr.pubkey),(long long)MYINFO.persistent_priv.txid,(long long)MYINFO.myaddr.persistent.txid); + if ( confstr == 0 ) + { + uint8_t *compressed,*serialized; int32_t complen,maxsize = IGUANA_MAXPACKETSIZE; + json = cJSON_CreateObject(); + jaddstr(json,"agent","SuperNET"); + jaddstr(json,"method","saveconf"); + jaddstr(json,"myipaddr",MYINFO.ipaddr); + jaddbits256(json,"persistent_priv",MYINFO.persistent_priv); + jaddbits256(json,"persistent_pub",MYINFO.myaddr.persistent); + compressed = calloc(1,maxsize); + serialized = calloc(1,maxsize); + if ( strcmp("confs/iguana.conf",fname) != 0 ) + { + //sprintf(fname,"confs/iguana.%llu",(long long)wallet2shared.txid); + if ( SuperNET_json2bits(MYINFO.ipaddr,wallethash,curve25519(wallethash,curve25519_basepoint9()),wallet2shared,serialized,&complen,compressed,maxsize,MYINFO.ipaddr,wallet2pub,json) > 0 ) + { + printf("save (%s) <- %d\n",fname,complen); + if ( (fp= fopen(fname,"wb")) != 0 ) + { + fwrite(compressed,1,complen,fp); + fclose(fp); + } + } else printf("error saving.(%s) json2bits.(%s)\n",fname,jprint(json,0)); + } + else + { + char *str = jprint(json,0); + //sprintf(fname,"confs/iguana.conf"); + printf("save (%s) <- (%s)\n",fname,str); + if ( (fp= fopen(fname,"wb")) != 0 ) + { + fwrite(str,1,strlen(str),fp); + fclose(fp); + } + free(str); + } + free(compressed), free(serialized); + free_json(json); + } + signal(SIGINT,sigint_func); + signal(SIGILL,sigillegal_func); + signal(SIGHUP,sighangup_func); + //signal(SIGKILL,sigkill_func); + signal(SIGABRT,sigabort_func); + signal(SIGQUIT,sigquit_func); + signal(SIGCHLD,sigchild_func); + signal(SIGALRM,sigalarm_func); + signal(SIGCONT,sigcontinue_func); if ( IGUANA_NUMHELPERS == 0 ) IGUANA_NUMHELPERS = 1; for (i=0; i