static inline std::map< Identity,std::vector<InetAddress> > _mkSupernodeMap() throw(std::runtime_error) { std::map< Identity,std::vector<InetAddress> > sn; Identity id; std::vector<InetAddress> addrs; // Nothing special about a supernode... except that they are // designated as such. // cthulhu.zerotier.com - New York, New York, USA addrs.clear(); if (!id.fromString("271ee006a0:1:AgGXs3I+9CWrEmGMxc50x3E+trwtaa2ZMXDU6ezz92fFJXzlhRKGUY/uAToHDdH9XiLxtcA+kUQAZdC4Dy2xtqXxjw==:QgH5Nlx4oWEGVrwhNocqem+3VNd4qzt7RLrmuvqZvKPRS9R70LJYJQLlKZj0ri55Pzg+Mlwy4a4nAgfnRAWA+TW6R0EjSmq72MG585XGNfWBVk3LxMvxlNWErnVNFr2BQS9yzVp4pRjPLdCW4RB3dwEHBUgJ78rwMxQ6IghVCl8CjkDapg==")) throw std::runtime_error("invalid identity in Defaults"); addrs.push_back(InetAddress("198.199.73.93",ZT_DEFAULT_UDP_PORT)); sn[id] = addrs; // nyarlathotep.zerotier.com - San Francisco, California, USA addrs.clear(); if (!id.fromString("fa9be4008b:1:AwCHXEi/PJuhtOPUZxnBSMiuGvj6XeRMWu9R9aLR3JD1qluADLQzUPSP2+81Dqvgi2wkQ2cqEpOlDPeUCvtlZwdXEA==:QgH4usG/wzsoUCtO2LL3qkwugtoXEz1PUJbmUzY8vbwzc5bckmVPjMqb4q2CF71+QVPV1K6shIV2EKkBMRSS/D/44EGEwC6tjFGZqmmogaC0P1uQeukTAF4qta46YgC4YQx54/Vd/Yfl8n1Bwmgm0gBB4W1ZQir3p+wp37MGlEN0rlXxqA==")) throw std::runtime_error("invalid identity in Defaults"); addrs.push_back(InetAddress("198.199.97.220",ZT_DEFAULT_UDP_PORT)); sn[id] = addrs; // shub-niggurath.zerotier.com - Amsterdam, Netherlands addrs.clear(); if (!id.fromString("48099ecd05:1:AwHO7o1FdDj1nEArfchTDa6EG7Eh2GLdiH86BhcoNv0BHJN4tmrf0Y7/2SZiQFpTTwJf93iph84Dci5+k52u/qkHTQ==:QgGbir8CNxBFFPPj8Eo3Bnp2UmbnZxu/pOq3Ke0WaLBBhHzVuwM+88g7CaDxbZ0AY2VkFc9hmE3VG+xi7g0H86yfVUIBHZnb7N+DCtf8/mphZIHNgmasakRi4hU11kGyLi1nTVTnrmCfAb7w+8SCp64Q5RNvBC/Pvz7pxSwSdjIHkVqRaeo=")) throw std::runtime_error("invalid identity in Defaults"); addrs.push_back(InetAddress("198.211.127.172",ZT_DEFAULT_UDP_PORT)); sn[id] = addrs; return sn; }
static inline std::map< Identity,std::vector<InetAddress> > _mkSupernodeMap() { std::map< Identity,std::vector<InetAddress> > sn; Identity id; std::vector<InetAddress> addrs; // Nothing special about a supernode... except that they are // designated as such and trusted to provide WHOIS lookup. // cthulhu.zerotier.com - New York, New York, USA addrs.clear(); if (!id.fromString("8acf059fe3:0:482f6ee5dfe902319b419de5bdc765209c0ecda38c4d6e4fcf0d33658398b4527dcd22f93112fb9befd02fd78bf7261b333fc105d192a623ca9e50fc60b374a5")) throw std::runtime_error("invalid identity in Defaults"); addrs.push_back(InetAddress("162.243.77.111",ZT_DEFAULT_UDP_PORT)); sn[id] = addrs; // nyarlathotep.zerotier.com - San Francisco, California, USA addrs.clear(); if (!id.fromString("7e19876aba:0:2a6e2b2318930f60eb097f70d0f4b028b2cd6d3d0c63c014b9039ff35390e41181f216fb2e6fa8d95c1ee9667156411905c3dccfea78d8c6dfafba688170b3fa")) throw std::runtime_error("invalid identity in Defaults"); addrs.push_back(InetAddress("198.199.97.220",ZT_DEFAULT_UDP_PORT)); sn[id] = addrs; // shub-niggurath.zerotier.com - Amsterdam, Netherlands addrs.clear(); if (!id.fromString("36f63d6574:0:67a776487a1a99b32f413329f2b67c43fbf6152e42c6b66e89043e69d93e48314c7d709b58a83016bd2612dd89400b856e18c553da94892f7d3ca16bf2c92c24")) throw std::runtime_error("invalid identity in Defaults"); addrs.push_back(InetAddress("198.211.127.172",ZT_DEFAULT_UDP_PORT)); sn[id] = addrs; return sn; }
static Identity getIdFromArg(char *arg) { Identity id; if ((strlen(arg) > 32)&&(arg[10] == ':')) { // identity is a literal on the command line if (id.fromString(arg)) return id; } else { // identity is to be read from a file std::string idser; if (Utils::readFile(arg,idser)) { if (id.fromString(idser)) return id; } } return Identity(); }
int main(int argc,char **argv) { std::string buf; // Read root-topology-authority.secret signing authority, must be symlinked and online Identity topologyAuthority; if (OSUtils::readFile("root-topology-authority.secret",buf)) topologyAuthority.fromString(buf); else std::cerr << "Warning: root-topology-authority.secret not found, creating unsigned topology." << std::endl; Dictionary topology; // Read template.dict to populate default fields in root topology // if this file exists. Otherwise we just start empty. buf.clear(); if (OSUtils::readFile("template.dict",buf)) topology.fromString(buf); // Read all entries in supernodes/ that correspond to supernode entry dictionaries // and add them to topology under supernodes/ subkey. Dictionary supernodes; std::vector<std::string> supernodeDictionaries(OSUtils::listDirectory("supernodes")); for(std::vector<std::string>::const_iterator sn(supernodeDictionaries.begin());sn!=supernodeDictionaries.end();++sn) { if (sn->length() == 10) { buf.clear(); if (!OSUtils::readFile((std::string("supernodes/")+(*sn)).c_str(),buf)) { std::cerr << "Cannot read supernodes/" << *sn << std::endl; return 1; } supernodes[*sn] = buf; } } topology["supernodes"] = supernodes.toString(); if ((topologyAuthority)&&(topologyAuthority.hasPrivate())) { // Sign topology with root-topology-authority.secret if (!topology.sign(topologyAuthority,OSUtils::now())) { std::cerr << "Unable to sign!" << std::endl; return 1; } // Test signature to make sure signing worked Dictionary test(topology.toString()); if (!test.verify(topologyAuthority)) { std::cerr << "Test verification of signed dictionary failed!" << std::endl; return 1; } } // Output to stdout std::cout << topology.toString(); return 0; }
static int testIdentity() { Identity id; Buffer<512> buf; std::cout << "[identity] Fully validate known-good identity... "; std::cout.flush(); if (!id.fromString("b487ffe552:2:9b121d26968a86eceea96d689dfb364a13f645aea9530c6d0c00c457569751340e8ff9ddf46be38190dcdd6178ff555cc48012a47280fbdece35799d8c445104:902474096fc914f0d6320a9d19b9e52d23bcf652e98b3930432d07a8271be0e19a813d1e77ee24db3454ce0c6c4a35e18a3adc0d06ee3bf086b38bd26ff95b085b4f1fd1d4ce423b15bc362cd5f13079b58252fd38b98b67b45203bb81423780:24f7ce86df8e242e4d7d04b657cf37eddc1aa7b34b6f38821c35fe393a4a381e0eef6e7b8b4ceab35a51e6ab0b6cbeb7c7282bc21c0c60cb6a512e454ecd45c5")) { std::cout << "FAIL (1)" << std::endl; return -1; } if (!id.locallyValidate(true)) { std::cout << "FAIL (2)" << std::endl; return -1; } std::cout << "PASS" << std::endl; std::cout << "[identity] Generate identity... "; std::cout.flush(); uint64_t genstart = Utils::now(); id.generate(); uint64_t genend = Utils::now(); std::cout << "(took " << (genend - genstart) << "ms): " << id.toString(true) << std::endl; std::cout << "[identity] Locally validate identity: "; if (id.locallyValidate(false)) { std::cout << "PASS" << std::endl; } else { std::cout << "FAIL" << std::endl; return -1; } { Identity id2; buf.clear(); id.serialize(buf,true); id2.deserialize(buf); std::cout << "[identity] Serialize and deserialize (w/private): "; if ((id == id2)&&(id2.locallyValidate(false))) { std::cout << "PASS" << std::endl; } else { std::cout << "FAIL" << std::endl; return -1; } } { Identity id2; buf.clear(); id.serialize(buf,false); id2.deserialize(buf); std::cout << "[identity] Serialize and deserialize (no private): "; if ((id == id2)&&(id2.locallyValidate(false))) { std::cout << "PASS" << std::endl; } else { std::cout << "FAIL" << std::endl; return -1; } } { Identity id2; id2.fromString(id.toString(true).c_str()); std::cout << "[identity] Serialize and deserialize (ASCII w/private): "; if ((id == id2)&&(id2.locallyValidate(false))) { std::cout << "PASS" << std::endl; } else { std::cout << "FAIL" << std::endl; return -1; } } { Identity id2; id2.fromString(id.toString(false).c_str()); std::cout << "[identity] Serialize and deserialize (ASCII no private): "; if ((id == id2)&&(id2.locallyValidate(false))) { std::cout << "PASS" << std::endl; } else { std::cout << "FAIL" << std::endl; return -1; } } return 0; }