cjdroute2.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. #include "admin/Admin.h"
  16. #include "admin/AdminClient.h"
  17. #include "admin/angel/InterfaceWaiter.h"
  18. #include "admin/angel/AngelInit.h"
  19. #include "admin/angel/Core.h"
  20. #include "admin/AuthorizedPasswords.h"
  21. #include "admin/Configurator.h"
  22. #include "benc/Int.h"
  23. #include "crypto/AddressCalc.h"
  24. #include "crypto/CryptoAuth.h"
  25. #include "crypto/CryptoAuth_benchmark.h"
  26. #include "dht/ReplyModule.h"
  27. #include "dht/SerializationModule.h"
  28. #include "dht/dhtcore/RouterModule_admin.h"
  29. #include "exception/Except.h"
  30. #include "interface/Interface.h"
  31. #include "interface/UDPInterface_admin.h"
  32. #include "io/Reader.h"
  33. #include "io/ArrayReader.h"
  34. #include "io/ArrayWriter.h"
  35. #include "io/FileReader.h"
  36. #include "io/Writer.h"
  37. #include "io/FileWriter.h"
  38. #include "benc/serialization/BencSerializer.h"
  39. #include "benc/serialization/json/JsonBencSerializer.h"
  40. #include "benc/serialization/standard/StandardBencSerializer.h"
  41. #include "util/log/Log.h"
  42. #include "memory/MallocAllocator.h"
  43. #include "memory/Allocator.h"
  44. #include "net/Ducttape.h"
  45. #include "net/DefaultInterfaceController.h"
  46. #include "net/SwitchPinger.h"
  47. #include "net/SwitchPinger_admin.h"
  48. #include "switch/SwitchCore.h"
  49. #include "util/CString.h"
  50. #include "util/ArchInfo.h"
  51. #include "util/SysInfo.h"
  52. #include "util/events/EventBase.h"
  53. #include "util/events/Pipe.h"
  54. #include "util/events/Process.h"
  55. #include "util/Assert.h"
  56. #include "util/Base32.h"
  57. #include "util/Hex.h"
  58. #include "util/Security.h"
  59. #include "util/log/WriterLog.h"
  60. #include "util/version/Version.h"
  61. #include "crypto_scalarmult_curve25519.h"
  62. #include <stdint.h>
  63. #include <stdio.h>
  64. #include <unistd.h>
  65. #define DEFAULT_TUN_DEV "tun0"
  66. static int genAddress(uint8_t addressOut[40],
  67. uint8_t privateKeyHexOut[65],
  68. uint8_t publicKeyBase32Out[53],
  69. struct Random* rand)
  70. {
  71. struct Address address;
  72. uint8_t privateKey[32];
  73. for (;;) {
  74. Random_bytes(rand, privateKey, 32);
  75. crypto_scalarmult_curve25519_base(address.key, privateKey);
  76. // Brute force for keys until one matches FC00:/8
  77. if (AddressCalc_addressForPublicKey(address.ip6.bytes, address.key)) {
  78. Hex_encode(privateKeyHexOut, 65, privateKey, 32);
  79. Base32_encode(publicKeyBase32Out, 53, address.key, 32);
  80. Address_printIp(addressOut, &address);
  81. return 0;
  82. }
  83. }
  84. }
  85. static int genconf(struct Random* rand)
  86. {
  87. uint8_t password[32];
  88. uint8_t password2[32];
  89. uint8_t password3[32];
  90. uint8_t password4[32];
  91. Random_base32(rand, password, 32);
  92. Random_base32(rand, password2, 32);
  93. Random_base32(rand, password3, 32);
  94. Random_base32(rand, password4, 32);
  95. uint8_t adminPassword[32];
  96. Random_base32(rand, adminPassword, 32);
  97. uint16_t port = 0;
  98. while (port <= 1024) {
  99. port = Random_uint16(rand);
  100. }
  101. uint8_t publicKeyBase32[53];
  102. uint8_t address[40];
  103. uint8_t privateKeyHex[65];
  104. genAddress(address, privateKeyHex, publicKeyBase32, rand);
  105. printf("{\n");
  106. printf(" // Private key:\n"
  107. " // Your confidentiality and data integrity depend on this key, keep it secret!\n"
  108. " \"privateKey\": \"%s\",\n\n", privateKeyHex);
  109. printf(" // This key corresponds to the public key and ipv6 address:\n"
  110. " \"publicKey\": \"%s.k\",\n", publicKeyBase32);
  111. printf(" \"ipv6\": \"%s\",\n", address);
  112. printf("\n"
  113. " // Anyone connecting and offering these passwords on connection will be allowed.\n"
  114. " //\n"
  115. " // WARNING: Currently there is no key derivation done on the password field,\n"
  116. " // DO NOT USE A PASSWORD HERE use something which is truly random and\n"
  117. " // cannot be guessed.\n"
  118. " // Including a username in the beginning of the password string is encouraged\n"
  119. " // to aid in remembering which users are who.\n"
  120. " //\n"
  121. " \"authorizedPasswords\":\n"
  122. " [\n"
  123. " // A unique string which is known to the client and server.\n"
  124. " {\"password\": \"%s\"}\n", password);
  125. printf("\n"
  126. " // More passwords should look like this.\n"
  127. " // {\"password\": \"%s\"},\n", password2);
  128. printf(" // {\"password\": \"%s\"},\n", password3);
  129. printf(" // {\"password\": \"%s\"},\n", password4);
  130. printf("\n"
  131. " // Below is an example of your connection credentials\n"
  132. " // that you can give to other people so they can connect\n"
  133. " // to you using your default password (from above) \n"
  134. " // Adding a unique password for each user is advisable\n"
  135. " // so that leaks can be isolated. \n"
  136. " //\n"
  137. " // \"your.external.ip.goes.here:%u\":{", port);
  138. printf("\"password\":\"%s\",", password);
  139. printf("\"publicKey\":\"%s.k\"}\n", publicKeyBase32);
  140. printf(" ],\n"
  141. "\n"
  142. " // Settings for administering and extracting information from your router.\n"
  143. " // This interface provides functions which can be called through a UDP socket.\n"
  144. " // See admin/Readme.md for more information about the API and try:\n"
  145. " // ./contrib/python/cexec 'functions'\n"
  146. " // For a list of functions which can be called.\n"
  147. " // For example: ./contrib/python/cexec 'memory()'\n"
  148. " // will call a function which gets the core's current memory consumption.\n"
  149. " // ./contrib/python/cjdnslog\n"
  150. " // is a tool which uses this admin interface to get logs from cjdns.\n"
  151. " \"admin\":\n"
  152. " {\n"
  153. " // Port to bind the admin RPC server to.\n"
  154. " \"bind\": \"127.0.0.1:11234\",\n"
  155. "\n"
  156. " // Password for admin RPC server.\n"
  157. " \"password\": \"%s\"\n", adminPassword);
  158. printf(" },\n"
  159. "\n"
  160. "\n\n" // TODO(cjd): Why is this needed and where are these newlines going?!!
  161. "\n"
  162. " // Interfaces to connect to the switch core.\n"
  163. " \"interfaces\":\n"
  164. " {\n"
  165. " // The interface which connects over UDP/IP based VPN tunnel.\n"
  166. " \"UDPInterface\":\n"
  167. " [\n"
  168. " {\n"
  169. " // Bind to this port.\n"
  170. " \"bind\": \"0.0.0.0:%u\",\n", port);
  171. printf("\n"
  172. " // Nodes to connect to.\n"
  173. " \"connectTo\":\n"
  174. " {\n"
  175. " // Add connection credentials here to join the network\n"
  176. " // Ask somebody who is already connected.\n"
  177. " }\n"
  178. " }\n"
  179. " ]\n");
  180. #ifdef HAS_ETH_INTERFACE
  181. printf("\n"
  182. " /*\n"
  183. " \"ETHInterface\":\n"
  184. " [\n"
  185. " {\n"
  186. " // Bind to this device (interface name, not MAC etc.)\n"
  187. " \"bind\": \"eth0\",\n"
  188. "\n"
  189. " // Auto-connect to other cjdns nodes on the same network.\n"
  190. " // Options:\n"
  191. " //\n"
  192. " // 0 -- Disabled.\n"
  193. " //\n"
  194. " // 1 -- Accept beacons, this will cause cjdns to accept incoming\n"
  195. " // beacon messages and try connecting to the sender.\n"
  196. " //\n"
  197. " // 2 -- Accept and send beacons, this will cause cjdns to broadcast\n"
  198. " // messages on the local network which contain a randomly\n"
  199. " // generated per-session password, other nodes which have this\n"
  200. " // set to 1 or 2 will hear the beacon messages and connect\n"
  201. " // automatically.\n"
  202. " //\n"
  203. " \"beacon\": 2,\n"
  204. "\n"
  205. " // Node(s) to connect to manually.\n"
  206. " \"connectTo\":\n"
  207. " {\n"
  208. " // Credentials for connecting look similar to UDP credientials\n"
  209. " // except they begin with the mac address, for example:\n"
  210. " // \"01:02:03:04:05:06\":{\"password\":\"a\",\"publicKey\":\"b\"}\n"
  211. " }\n"
  212. " }\n"
  213. " ]\n"
  214. " */\n"
  215. "\n");
  216. #endif
  217. printf(" },\n"
  218. "\n"
  219. " // Configuration for the router.\n"
  220. " \"router\":\n"
  221. " {\n"
  222. " // The interface which is used for connecting to the cjdns network.\n"
  223. " \"interface\":\n"
  224. " {\n"
  225. " // The type of interface (only TUNInterface is supported for now)\n"
  226. " \"type\": \"TUNInterface\"\n"
  227. #ifndef __APPLE__
  228. "\n"
  229. " // The name of a persistent TUN device to use.\n"
  230. " // This for starting cjdroute as its own user.\n"
  231. " // *MOST USERS DON'T NEED THIS*\n"
  232. " //\"tunDevice\": \"" DEFAULT_TUN_DEV "\"\n"
  233. #endif
  234. " },\n"
  235. "\n"
  236. " // System for tunneling IPv4 and ICANN IPv6 through cjdns.\n"
  237. " // This is using the cjdns switch layer as a VPN carrier.\n"
  238. " \"ipTunnel\":\n"
  239. " {\n"
  240. " // Nodes allowed to connect to us.\n"
  241. " // When a node with the given public key connects, give them the\n"
  242. " // ip4 and/or ip6 addresses listed.\n"
  243. " \"allowedConnections\":\n"
  244. " [\n"
  245. " // {\n"
  246. " // \"publicKey\": "
  247. "\"f64hfl7c4uxt6krmhPutTheRealAddressOfANodeHere7kfm5m0.k\",\n"
  248. " // \"ip4Address\": \"192.168.1.24\",\n"
  249. " // \"ip6Address\": \"2001:123:ab::10\"\n"
  250. " // },\n"
  251. "\n"
  252. " // It's ok to only specify one address.\n"
  253. " // {\n"
  254. " // \"publicKey\": "
  255. "\"ydq8csdk8p8ThisIsJustAnExampleAddresstxuyqdf27hvn2z0.k\",\n"
  256. " // \"ip4Address\": \"192.168.1.24\",\n"
  257. " // \"ip6Address\": \"2001:123:ab::10\"\n"
  258. " // }\n"
  259. " ],\n"
  260. "\n"
  261. " \"outgoingConnections\":\n"
  262. " [\n"
  263. " // Connect to one or more machines and ask them for IP addresses.\n"
  264. " // \"6743gf5tw80ExampleExampleExampleExamplevlyb23zfnuzv0.k\",\n"
  265. " // \"pw9tfmr8pcrExampleExampleExampleExample8rhg1pgwpwf80.k\",\n"
  266. " // \"g91lxyxhq0kExampleExampleExampleExample6t0mknuhw75l0.k\"\n"
  267. " ]\n"
  268. " }\n"
  269. " },\n"
  270. "\n"
  271. " // Tear down inactive CryptoAuth sessions after this number of seconds\n"
  272. " // to make them more forgiving in the event that they become desynchronized.\n"
  273. " \"resetAfterInactivitySeconds\": 100,\n"
  274. "\n"
  275. " // Dropping permissions.\n"
  276. " \"security\":\n"
  277. " [\n"
  278. " // Change the user id to this user after starting up and getting resources.\n"
  279. " {\n"
  280. " \"setuser\": \"nobody\",\n"
  281. "\n"
  282. " // Exempt the Angel process from setting userId, the Angel is a small\n"
  283. " // isolated piece of code which exists outside of the core's strict\n"
  284. " // sandbox but does not handle network traffic.\n"
  285. " // This must be enabled for IpTunnel to automatically set IP addresses\n"
  286. " // for the TUN device.\n"
  287. " \"exemptAngel\": 1\n"
  288. " }\n"
  289. " ],\n"
  290. "\n"
  291. " // Logging\n"
  292. " \"logging\":\n"
  293. " {\n"
  294. " // Uncomment to have cjdns log to stdout rather than making logs available\n"
  295. " // via the admin socket.\n"
  296. " // \"logTo\":\"stdout\"\n"
  297. " },\n"
  298. "\n"
  299. " // If set to non-zero, cjdns will not fork to the background.\n"
  300. " // Recommended for use in conjunction with \"logTo\":\"stdout\".\n"
  301. " \"noBackground\":0,\n"
  302. "\n");
  303. printf(" // DNS, this server will be available at address fc00::1\n"
  304. " \"dns\":\n"
  305. " {\n"
  306. " // Who to trust\n"
  307. " \"keys\": [\n"
  308. " \"7kuc3jcyql3cm8lx5zdj8vc0tkz8679kyx83utbm1ub5bxpf4mf1.mittens.h\",\n"
  309. " \"tvlxu5rbcj76rfdmsw9xd3kjn79fhv6kpvl2hzv98637j4rdj1b1.tom.h\",\n"
  310. " \"kkxfwnm3upf0jv35jq4lx0dn0z3m9bh71gv84cdjlcp68w1qckt1.maru.h\",\n"
  311. " \"02wmqfu7v0kdq17fwv68hk646bdvhcr8ybk2ycy7ddzv21n5nb60.scruffy.h\"\n"
  312. " ],\n"
  313. "\n"
  314. " // Who to ask, if a request fails the next one will be tried\n"
  315. " \"servers\": [\n"
  316. " \"[fc71:ec46:57a0:2bbc:537d:b680:3630:93e4]:9001\",\n"
  317. " \"[fc8e:9a1c:27c3:281b:29b1:1a04:3701:c125]:9001\",\n"
  318. " \"[fcad:0450:4a40:9778:14e2:e442:6678:3161]:9001\",\n"
  319. " \"[fc2f:baa8:4a89:2db5:6789:aa75:07e6:4cb2]:9001\"\n"
  320. " ],\n"
  321. "\n"
  322. " // At least this many of \"keys\" must agree or else the request will fail.\n"
  323. " \"minSignatures\":2\n"
  324. " }\n"
  325. "\n"
  326. "}\n");
  327. return 0;
  328. }
  329. static int usage(struct Allocator* alloc, char* appName)
  330. {
  331. char* archInfo = ArchInfo_describe(ArchInfo_detect(), alloc);
  332. char* sysInfo = SysInfo_describe(SysInfo_detect(), alloc);
  333. printf("Cjdns %s %s\n"
  334. "Usage: %s [--help] [--genconf] [--bench] [--version] [--cleanconf]\n"
  335. "\n"
  336. "To get the router up and running.\n"
  337. "Step 1:\n"
  338. " Generate a new configuration file.\n"
  339. " %s --genconf > cjdroute.conf\n"
  340. "\n"
  341. "Step 2:\n"
  342. " Find somebody to connect to.\n"
  343. " Check out the IRC channel or http://hyperboria.net/\n"
  344. " for information about how to meet new people and make connect to them.\n"
  345. "\n"
  346. "Step 3:\n"
  347. " Fire it up!\n"
  348. " sudo %s < cjdroute.conf\n"
  349. "\n"
  350. "For more information about other functions and non-standard setups, see README.md\n",
  351. archInfo, sysInfo, appName, appName, appName);
  352. return 0;
  353. }
  354. static int benchmark()
  355. {
  356. struct Allocator* alloc = MallocAllocator_new(1<<22);
  357. struct EventBase* base = EventBase_new(alloc);
  358. struct Writer* logWriter = FileWriter_new(stdout, alloc);
  359. struct Log* logger = WriterLog_new(logWriter, alloc);
  360. CryptoAuth_benchmark(base, logger, alloc);
  361. return 0;
  362. }
  363. struct CheckRunningInstanceContext
  364. {
  365. struct EventBase* base;
  366. struct Allocator* alloc;
  367. struct AdminClient_Result* res;
  368. };
  369. static void checkRunningInstanceCallback(struct AdminClient_Promise* p,
  370. struct AdminClient_Result* res)
  371. {
  372. struct CheckRunningInstanceContext* ctx = p->userData;
  373. // Prevent this from freeing until after we drop out of the loop.
  374. Allocator_adopt(ctx->alloc, p->alloc);
  375. ctx->res = res;
  376. EventBase_endLoop(ctx->base);
  377. }
  378. static void checkRunningInstance(struct Allocator* allocator,
  379. struct EventBase* base,
  380. String* addr,
  381. String* password,
  382. struct Log* logger,
  383. struct Except* eh)
  384. {
  385. struct Allocator* alloc = Allocator_child(allocator);
  386. struct Sockaddr_storage pingAddrStorage;
  387. if (Sockaddr_parse(addr->bytes, &pingAddrStorage)) {
  388. Except_throw(eh, "Unable to parse [%s] as an ip address port, eg: 127.0.0.1:11234",
  389. addr->bytes);
  390. }
  391. struct AdminClient* adminClient =
  392. AdminClient_new(&pingAddrStorage.addr, password, base, logger, alloc);
  393. // 100 milliseconds is plenty to wait for a process to respond on the same machine.
  394. adminClient->millisecondsToWait = 100;
  395. Dict* pingArgs = Dict_new(alloc);
  396. struct AdminClient_Promise* pingPromise =
  397. AdminClient_rpcCall(String_new("ping", alloc), pingArgs, adminClient, alloc);
  398. struct CheckRunningInstanceContext* ctx =
  399. Allocator_malloc(alloc, sizeof(struct CheckRunningInstanceContext));
  400. ctx->base = base;
  401. ctx->alloc = alloc;
  402. ctx->res = NULL;
  403. pingPromise->callback = checkRunningInstanceCallback;
  404. pingPromise->userData = ctx;
  405. EventBase_beginLoop(base);
  406. Assert_true(ctx->res);
  407. if (ctx->res->err != AdminClient_Error_TIMEOUT) {
  408. Except_throw(eh, "Startup failed: cjdroute is already running. [%d]", ctx->res->err);
  409. }
  410. Allocator_free(alloc);
  411. }
  412. int main(int argc, char** argv)
  413. {
  414. #ifdef Log_KEYS
  415. fprintf(stderr, "Log_LEVEL = KEYS, EXPECT TO SEE PRIVATE KEYS IN YOUR LOGS!\n");
  416. #endif
  417. if (isatty(STDIN_FILENO) || argc < 2) {
  418. // Fall through.
  419. } else if (!CString_strcmp("angel", argv[1])) {
  420. return AngelInit_main(argc, argv);
  421. } else if (!CString_strcmp("core", argv[1])) {
  422. return Core_main(argc, argv);
  423. }
  424. Assert_ifParanoid(argc > 0);
  425. struct Except* eh = NULL;
  426. // Allow it to allocate 8MB
  427. struct Allocator* allocator = MallocAllocator_new(1<<23);
  428. struct Random* rand = Random_new(allocator, NULL, eh);
  429. struct EventBase* eventBase = EventBase_new(allocator);
  430. if (argc == 2) {
  431. // one argument
  432. if ((CString_strcmp(argv[1], "--help") == 0) || (CString_strcmp(argv[1], "-h") == 0)) {
  433. return usage(allocator, argv[0]);
  434. } else if (CString_strcmp(argv[1], "--genconf") == 0) {
  435. return genconf(rand);
  436. } else if (CString_strcmp(argv[1], "--pidfile") == 0) {
  437. // deprecated
  438. fprintf(stderr, "'--pidfile' option is deprecated.\n");
  439. return 0;
  440. } else if (CString_strcmp(argv[1], "--reconf") == 0) {
  441. // Performed after reading the configuration
  442. } else if (CString_strcmp(argv[1], "--bench") == 0) {
  443. return benchmark();
  444. } else if ((CString_strcmp(argv[1], "--version") == 0)
  445. || (CString_strcmp(argv[1], "-v") == 0))
  446. {
  447. printf("Cjdns protocol version: %d\n", Version_CURRENT_PROTOCOL);
  448. return 0;
  449. } else if (CString_strcmp(argv[1], "--cleanconf") == 0) {
  450. // Performed after reading configuration
  451. } else {
  452. fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], argv[1]);
  453. fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]);
  454. return -1;
  455. }
  456. } else if (argc > 2) {
  457. // more than one argument?
  458. fprintf(stderr, "%s: too many arguments\n", argv[0]);
  459. fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]);
  460. // because of '--pidfile $filename'?
  461. if (CString_strcmp(argv[1], "--pidfile") == 0)
  462. {
  463. fprintf(stderr, "\n'--pidfile' option is deprecated.\n");
  464. }
  465. return -1;
  466. }
  467. if (isatty(STDIN_FILENO)) {
  468. // We were started from a terminal
  469. // The chances an user wants to type in a configuration
  470. // bij hand are pretty slim so we show him the usage
  471. return usage(allocator, argv[0]);
  472. } else {
  473. // We assume stdin is a configuration file and that we should
  474. // start routing
  475. }
  476. struct Reader* stdinReader = FileReader_new(stdin, allocator);
  477. Dict config;
  478. if (JsonBencSerializer_get()->parseDictionary(stdinReader, allocator, &config)) {
  479. fprintf(stderr, "Failed to parse configuration.\n");
  480. return -1;
  481. }
  482. if (argc == 2 && CString_strcmp(argv[1], "--cleanconf") == 0) {
  483. struct Writer* stdoutWriter = FileWriter_new(stdout, allocator);
  484. JsonBencSerializer_get()->serializeDictionary(stdoutWriter, &config);
  485. printf("\n");
  486. return 0;
  487. }
  488. struct Writer* logWriter = FileWriter_new(stdout, allocator);
  489. struct Log* logger = WriterLog_new(logWriter, allocator);
  490. // --------------------- Get Admin --------------------- //
  491. Dict* configAdmin = Dict_getDict(&config, String_CONST("admin"));
  492. String* adminPass = Dict_getString(configAdmin, String_CONST("password"));
  493. String* adminBind = Dict_getString(configAdmin, String_CONST("bind"));
  494. if (!adminPass) {
  495. adminPass = String_newBinary(NULL, 32, allocator);
  496. Random_base32(rand, (uint8_t*) adminPass->bytes, 32);
  497. adminPass->len = CString_strlen(adminPass->bytes);
  498. }
  499. if (!adminBind) {
  500. Except_throw(eh, "You must specify admin.bind in the cjdroute.conf file.");
  501. }
  502. // --------------------- Welcome to cjdns ---------------------- //
  503. char* archInfo = ArchInfo_describe(ArchInfo_detect(), allocator);
  504. char* sysInfo = SysInfo_describe(SysInfo_detect(), allocator);
  505. Log_info(logger, "Cjdns %s %s", archInfo, sysInfo);
  506. // --------------------- Check for running instance --------------------- //
  507. Log_info(logger, "Checking for running instance...");
  508. checkRunningInstance(allocator, eventBase, adminBind, adminPass, logger, eh);
  509. // --------------------- Setup Pipes to Angel --------------------- //
  510. char angelPipeName[64] = "client-angel-";
  511. Random_base32(rand, (uint8_t*)angelPipeName+13, 31);
  512. Assert_ifParanoid(EventBase_eventCount(eventBase) == 0);
  513. struct Pipe* angelPipe = Pipe_named(angelPipeName, eventBase, eh, allocator);
  514. Assert_ifParanoid(EventBase_eventCount(eventBase) == 2);
  515. angelPipe->logger = logger;
  516. char* args[] = { "angel", angelPipeName, NULL };
  517. // --------------------- Spawn Angel --------------------- //
  518. String* privateKey = Dict_getString(&config, String_CONST("privateKey"));
  519. char* corePath = Process_getPath(allocator);
  520. if (!corePath) {
  521. Except_throw(eh, "Can't find a usable cjdns core executable, "
  522. "make sure it is in the same directory as cjdroute");
  523. }
  524. if (!privateKey) {
  525. Except_throw(eh, "Need to specify privateKey.");
  526. }
  527. Log_info(logger, "Forking angel to background.");
  528. Process_spawn(corePath, args, eventBase, allocator);
  529. // --------------------- Get user for angel to setuid() ---------------------- //
  530. String* securityUser = NULL;
  531. List* securityConf = Dict_getList(&config, String_CONST("security"));
  532. for (int i = 0; i < List_size(securityConf); i++) {
  533. securityUser = Dict_getString(List_getDict(securityConf, i), String_CONST("setuser"));
  534. if (securityUser) {
  535. int64_t* ea = Dict_getInt(List_getDict(securityConf, i), String_CONST("exemptAngel"));
  536. if (ea && *ea) {
  537. securityUser = NULL;
  538. }
  539. break;
  540. }
  541. }
  542. // --------------------- Pre-Configure Angel ------------------------- //
  543. Dict* preConf = Dict_new(allocator);
  544. Dict* adminPreConf = Dict_new(allocator);
  545. Dict_putDict(preConf, String_CONST("admin"), adminPreConf, allocator);
  546. Dict_putString(adminPreConf, String_CONST("core"), String_new(corePath, allocator), allocator);
  547. Dict_putString(preConf, String_CONST("privateKey"), privateKey, allocator);
  548. Dict_putString(adminPreConf, String_CONST("bind"), adminBind, allocator);
  549. Dict_putString(adminPreConf, String_CONST("pass"), adminPass, allocator);
  550. if (securityUser) {
  551. Dict_putString(adminPreConf, String_CONST("user"), securityUser, allocator);
  552. }
  553. Dict* logging = Dict_getDict(&config, String_CONST("logging"));
  554. if (logging) {
  555. Dict_putDict(preConf, String_CONST("logging"), logging, allocator);
  556. }
  557. #define CONFIG_BUFF_SIZE 1024
  558. uint8_t buff[CONFIG_BUFF_SIZE] = {0};
  559. struct Writer* toAngelWriter = ArrayWriter_new(buff, CONFIG_BUFF_SIZE - 1, allocator);
  560. if (StandardBencSerializer_get()->serializeDictionary(toAngelWriter, preConf)) {
  561. Except_throw(eh, "Failed to serialize pre-configuration");
  562. }
  563. struct Message* toAngelMsg = &(struct Message) {
  564. .bytes = buff,
  565. .length = toAngelWriter->bytesWritten
  566. };
  567. toAngelMsg = Message_clone(toAngelMsg, allocator);
  568. Interface_sendMessage(&angelPipe->iface, toAngelMsg);
  569. Log_keys(logger, "Sent [%s] to angel process.", buff);
  570. // --------------------- Get Response from Angel --------------------- //
  571. struct Message* fromAngelMsg =
  572. InterfaceWaiter_waitForData(&angelPipe->iface, eventBase, allocator, eh);
  573. Dict responseFromAngel;
  574. struct Reader* responseFromAngelReader =
  575. ArrayReader_new(fromAngelMsg->bytes, fromAngelMsg->length, allocator);
  576. if (StandardBencSerializer_get()->parseDictionary(responseFromAngelReader,
  577. allocator,
  578. &responseFromAngel))
  579. {
  580. Except_throw(eh, "Failed to parse pre-configuration response [%s]", buff);
  581. }
  582. // --------------------- Get Admin Addr/Port/Passwd --------------------- //
  583. Dict* responseFromAngelAdmin = Dict_getDict(&responseFromAngel, String_CONST("admin"));
  584. adminBind = Dict_getString(responseFromAngelAdmin, String_CONST("bind"));
  585. if (!adminBind) {
  586. Except_throw(eh, "didn't get address and port back from angel");
  587. }
  588. struct Sockaddr_storage adminAddr;
  589. if (Sockaddr_parse(adminBind->bytes, &adminAddr)) {
  590. Except_throw(eh, "Unable to parse [%s] as an ip address port, eg: 127.0.0.1:11234",
  591. adminBind->bytes);
  592. }
  593. // sanity check, Pipe_named() creates 2 events, see above.
  594. Assert_ifParanoid(EventBase_eventCount(eventBase) == 2);
  595. // --------------------- Configuration ------------------------- //
  596. Configurator_config(&config,
  597. &adminAddr.addr,
  598. adminPass,
  599. eventBase,
  600. logger,
  601. allocator);
  602. // --------------------- noBackground ------------------------ //
  603. int64_t* noBackground = Dict_getInt(&config, String_CONST("noBackground"));
  604. if (noBackground && *noBackground) {
  605. EventBase_beginLoop(eventBase);
  606. }
  607. //Allocator_free(allocator);
  608. return 0;
  609. }