cjdroute2.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683
  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 "client/AdminClient.h"
  16. #include "admin/angel/Core.h"
  17. #include "admin/angel/InterfaceWaiter.h"
  18. #include "client/Configurator.h"
  19. #include "benc/Dict.h"
  20. #include "benc/Int.h"
  21. #include "benc/List.h"
  22. #include "benc/serialization/BencSerializer.h"
  23. #include "benc/serialization/json/JsonBencSerializer.h"
  24. #include "benc/serialization/standard/BencMessageReader.h"
  25. #include "benc/serialization/standard/BencMessageWriter.h"
  26. #include "crypto/AddressCalc.h"
  27. #include "crypto/CryptoAuth.h"
  28. #include "dht/Address.h"
  29. #include "exception/Except.h"
  30. #include "interface/Iface.h"
  31. #include "io/FileReader.h"
  32. #include "io/FileWriter.h"
  33. #include "io/Reader.h"
  34. #include "io/Writer.h"
  35. #include "memory/Allocator.h"
  36. #include "memory/MallocAllocator.h"
  37. #include "util/ArchInfo.h"
  38. #include "util/Assert.h"
  39. #include "util/Base32.h"
  40. #include "util/CString.h"
  41. #include "util/events/UDPAddrIface.h"
  42. #include "util/events/Time.h"
  43. #include "util/events/EventBase.h"
  44. #include "util/events/Pipe.h"
  45. #include "util/events/Process.h"
  46. #include "util/Hex.h"
  47. #include "util/log/Log.h"
  48. #include "util/log/FileWriterLog.h"
  49. #include "util/SysInfo.h"
  50. #include "util/version/Version.h"
  51. #include "net/Benchmark.h"
  52. #include "crypto_scalarmult_curve25519.h"
  53. #include <stdint.h>
  54. #include <stdio.h>
  55. #include <unistd.h>
  56. #define DEFAULT_TUN_DEV "tun0"
  57. static int genAddress(uint8_t addressOut[40],
  58. uint8_t privateKeyHexOut[65],
  59. uint8_t publicKeyBase32Out[53],
  60. struct Random* rand)
  61. {
  62. struct Address address;
  63. uint8_t privateKey[32];
  64. for (;;) {
  65. Random_bytes(rand, privateKey, 32);
  66. crypto_scalarmult_curve25519_base(address.key, privateKey);
  67. // Brute force for keys until one matches FC00:/8
  68. if (AddressCalc_addressForPublicKey(address.ip6.bytes, address.key)) {
  69. Hex_encode(privateKeyHexOut, 65, privateKey, 32);
  70. Base32_encode(publicKeyBase32Out, 53, address.key, 32);
  71. Address_printShortIp(addressOut, &address);
  72. return 0;
  73. }
  74. }
  75. }
  76. static int genconf(struct Random* rand, bool eth)
  77. {
  78. uint8_t password[32];
  79. uint8_t password2[32];
  80. uint8_t password3[32];
  81. uint8_t password4[32];
  82. Random_base32(rand, password, 32);
  83. Random_base32(rand, password2, 32);
  84. Random_base32(rand, password3, 32);
  85. Random_base32(rand, password4, 32);
  86. uint16_t port = 0;
  87. while (port <= 1024) {
  88. port = Random_uint16(rand);
  89. }
  90. uint8_t publicKeyBase32[53];
  91. uint8_t address[40];
  92. uint8_t privateKeyHex[65];
  93. genAddress(address, privateKeyHex, publicKeyBase32, rand);
  94. printf("{\n");
  95. printf(" // Private key:\n"
  96. " // Your confidentiality and data integrity depend on this key, keep it secret!\n"
  97. " \"privateKey\": \"%s\",\n\n", privateKeyHex);
  98. printf(" // This key corresponds to the public key and ipv6 address:\n"
  99. " \"publicKey\": \"%s.k\",\n", publicKeyBase32);
  100. printf(" \"ipv6\": \"%s\",\n", address);
  101. printf("\n"
  102. " // Anyone connecting and offering these passwords on connection will be allowed.\n"
  103. " //\n"
  104. " // WARNING: Currently there is no key derivation done on the password field,\n"
  105. " // DO NOT USE A PASSWORD HERE use something which is truly random and\n"
  106. " // cannot be guessed.\n"
  107. " // Including a username in the beginning of the password string is encouraged\n"
  108. " // to aid in remembering which users are who.\n"
  109. " //\n"
  110. " \"authorizedPasswords\":\n"
  111. " [\n"
  112. " // A unique string which is known to the client and server.\n"
  113. " {\"password\": \"%s\"}\n", password);
  114. printf("\n"
  115. " // More passwords should look like this.\n"
  116. " // {\"password\": \"%s\"},\n", password2);
  117. printf(" // {\"password\": \"%s\"},\n", password3);
  118. printf(" // {\"password\": \"%s\"},\n", password4);
  119. printf("\n"
  120. " // Below is an example of your connection credentials\n"
  121. " // that you can give to other people so they can connect\n"
  122. " // to you using your default password (from above)\n"
  123. " // Adding a unique password for each user is advisable\n"
  124. " // so that leaks can be isolated.\n"
  125. " //\n"
  126. " // \"your.external.ip.goes.here:%u\":{", port);
  127. printf("\"password\":\"%s\",", password);
  128. printf("\"publicKey\":\"%s.k\"}\n", publicKeyBase32);
  129. printf(" ],\n"
  130. "\n"
  131. " // Settings for administering and extracting information from your router.\n"
  132. " // This interface provides functions which can be called through a UDP socket.\n"
  133. " // See admin/Readme.md for more information about the API and try:\n"
  134. " // ./tools/cexec\n"
  135. " // For a list of functions which can be called.\n"
  136. " // For example: ./tools/cexec 'memory()'\n"
  137. " // will call a function which gets the core's current memory consumption.\n"
  138. " // ./tools/cjdnslog\n"
  139. " // is a tool which uses this admin interface to get logs from cjdns.\n"
  140. " \"admin\":\n"
  141. " {\n"
  142. " // Port to bind the admin RPC server to.\n"
  143. " \"bind\": \"127.0.0.1:11234\",\n"
  144. "\n"
  145. " // Password for admin RPC server.\n"
  146. " // This is a static password by default, so that tools like\n"
  147. " // ./tools/cexec can use the API without you creating a\n"
  148. " // config file at ~/.cjdnsadmin first. If you decide to\n"
  149. " // expose the admin API to the network, change the password!\n"
  150. " \"password\": \"NONE\"\n");
  151. printf(" },\n"
  152. "\n"
  153. " // Interfaces to connect to the switch core.\n"
  154. " \"interfaces\":\n"
  155. " {\n"
  156. " // The interface which connects over UDP/IP based VPN tunnel.\n"
  157. " \"UDPInterface\":\n"
  158. " [\n"
  159. " {\n"
  160. " // Bind to this port.\n"
  161. " \"bind\": \"0.0.0.0:%u\",\n", port);
  162. printf("\n"
  163. " // Nodes to connect to (IPv4 only).\n"
  164. " \"connectTo\":\n"
  165. " {\n"
  166. " // Add connection credentials here to join the network\n"
  167. " // Ask somebody who is already connected.\n"
  168. " }\n"
  169. " },\n"
  170. " {\n"
  171. " // Bind to this port.\n"
  172. " \"bind\": \"[::]:%u\",\n", port);
  173. printf("\n"
  174. " // Nodes to connect to (IPv6 only).\n"
  175. " \"connectTo\":\n"
  176. " {\n"
  177. " // Add connection credentials here to join the network\n"
  178. " // Ask somebody who is already connected.\n"
  179. " }\n"
  180. " }\n"
  181. " ]\n");
  182. #ifdef HAS_ETH_INTERFACE
  183. printf("\n");
  184. if (!eth) {
  185. printf(" /*\n");
  186. }
  187. printf(" \"ETHInterface\":\n"
  188. " [\n"
  189. " // Alternatively bind to just one device and either beacon and/or\n"
  190. " // connect to a specified MAC address\n"
  191. " {\n"
  192. " // Bind to this device (interface name, not MAC)\n"
  193. " // \"all\" is a pseudo-name which will try to connect to all devices.\n"
  194. " \"bind\": \"all\",\n"
  195. "\n"
  196. " // Auto-connect to other cjdns nodes on the same network.\n"
  197. " // Options:\n"
  198. " //\n"
  199. " // 0 -- Disabled.\n"
  200. " //\n"
  201. " // 1 -- Accept beacons, this will cause cjdns to accept incoming\n"
  202. " // beacon messages and try connecting to the sender.\n"
  203. " //\n"
  204. " // 2 -- Accept and send beacons, this will cause cjdns to broadcast\n"
  205. " // messages on the local network which contain a randomly\n"
  206. " // generated per-session password, other nodes which have this\n"
  207. " // set to 1 or 2 will hear the beacon messages and connect\n"
  208. " // automatically.\n"
  209. " //\n"
  210. " \"beacon\": 2,\n"
  211. "\n"
  212. " // Node(s) to connect to manually\n"
  213. " // Note: does not work with \"all\" pseudo-device-name\n"
  214. " \"connectTo\":\n"
  215. " {\n"
  216. " // Credentials for connecting look similar to UDP credientials\n"
  217. " // except they begin with the mac address, for example:\n"
  218. " // \"01:02:03:04:05:06\":{\"password\":\"a\",\"publicKey\":\"b\"}\n"
  219. " }\n"
  220. " }\n"
  221. " ]\n");
  222. if (!eth) {
  223. printf(" */\n");
  224. }
  225. printf("\n");
  226. #endif
  227. printf(" },\n"
  228. "\n"
  229. " // Configuration for the router.\n"
  230. " \"router\":\n"
  231. " {\n"
  232. " // The interface which is used for connecting to the cjdns network.\n"
  233. " \"interface\":\n"
  234. " {\n"
  235. " // The type of interface (only TUNInterface is supported for now)\n"
  236. " \"type\": \"TUNInterface\"\n"
  237. #ifndef __APPLE__
  238. "\n"
  239. " // The name of a persistent TUN device to use.\n"
  240. " // This for starting cjdroute as its own user.\n"
  241. " // *MOST USERS DON'T NEED THIS*\n"
  242. " //\"tunDevice\": \"" DEFAULT_TUN_DEV "\"\n"
  243. #endif
  244. " },\n"
  245. "\n"
  246. " // System for tunneling IPv4 and ICANN IPv6 through cjdns.\n"
  247. " // This is using the cjdns switch layer as a VPN carrier.\n"
  248. " \"ipTunnel\":\n"
  249. " {\n"
  250. " // Nodes allowed to connect to us.\n"
  251. " // When a node with the given public key connects, give them the\n"
  252. " // ip4 and/or ip6 addresses listed.\n"
  253. " \"allowedConnections\":\n"
  254. " [\n"
  255. " // Give the client an address on 192.168.1.0/24, and an address\n"
  256. " // it thinks has all of IPv6 behind it.\n"
  257. " // {\n"
  258. " // \"publicKey\": "
  259. "\"f64hfl7c4uxt6krmhPutTheRealAddressOfANodeHere7kfm5m0.k\",\n"
  260. " // \"ip4Address\": \"192.168.1.24\",\n"
  261. " // \"ip4Prefix\": 24,\n"
  262. " // \"ip6Address\": \"2001:123:ab::10\",\n"
  263. " // \"ip6Prefix\": 0\n"
  264. " // },\n"
  265. "\n"
  266. " // It's ok to only specify one address.\n"
  267. " // {\n"
  268. " // \"publicKey\": "
  269. "\"ydq8csdk8p8ThisIsJustAnExampleAddresstxuyqdf27hvn2z0.k\",\n"
  270. " // \"ip4Address\": \"192.168.1.25\",\n"
  271. " // \"ip4Prefix\": 24\n"
  272. " // }\n"
  273. " ],\n"
  274. "\n"
  275. " \"outgoingConnections\":\n"
  276. " [\n"
  277. " // Connect to one or more machines and ask them for IP addresses.\n"
  278. " // \"6743gf5tw80ExampleExampleExampleExamplevlyb23zfnuzv0.k\",\n"
  279. " // \"pw9tfmr8pcrExampleExampleExampleExample8rhg1pgwpwf80.k\",\n"
  280. " // \"g91lxyxhq0kExampleExampleExampleExample6t0mknuhw75l0.k\"\n"
  281. " ]\n"
  282. " }\n"
  283. " },\n"
  284. "\n");
  285. printf(" // Dropping permissions.\n"
  286. " // In the event of a serious security exploit in cjdns, leak of confidential\n"
  287. " // network traffic and/or keys is highly likely but the following rules are\n"
  288. " // designed to prevent the attack from spreading to the system on which cjdns\n"
  289. " // is running.\n"
  290. " // Counter-intuitively, cjdns is *more* secure if it is started as root because\n"
  291. " // non-root users do not have permission to use chroot or change usernames,\n"
  292. " // limiting the effectiveness of the mitigations herein.\n"
  293. " \"security\":\n"
  294. " [\n"
  295. " // Change the user id to sandbox the cjdns process after it starts.\n"
  296. " // If keepNetAdmin is set to 0, IPTunnel will be unable to set IP addresses\n"
  297. " // and ETHInterface will be unable to hot-add new interfaces\n"
  298. " // Use { \"setuser\": 0 } to disable.\n"
  299. " // Default: enabled with keepNetAdmin\n"
  300. " { \"setuser\": \"nobody\", \"keepNetAdmin\": 1 },\n"
  301. "\n"
  302. " // Chroot changes the filesystem root directory which cjdns sees, blocking it\n"
  303. " // from accessing files outside of the chroot sandbox, if the user does not\n"
  304. " // have permission to use chroot(), this will fail quietly.\n"
  305. " // Use { \"chroot\": 0 } to disable.\n"
  306. " // Default: enabled (using \"/var/run\")\n"
  307. " { \"chroot\": \"/var/run/\" },\n"
  308. "\n"
  309. " // Nofiles is a deprecated security feature which prevents cjdns from opening\n"
  310. " // any files at all, using this will block setting of IP addresses and\n"
  311. " // hot-adding ETHInterface devices but for users who do not need this, it\n"
  312. " // provides a formidable sandbox.\n"
  313. " // Default: disabled\n"
  314. " { \"nofiles\": 0 },\n"
  315. "\n"
  316. " // Noforks will prevent cjdns from spawning any new processes or threads,\n"
  317. " // this prevents many types of exploits from attacking the wider system.\n"
  318. " // Default: enabled\n"
  319. " { \"noforks\": 1 },\n"
  320. "\n"
  321. " // Seccomp is the most advanced sandboxing feature in cjdns, it uses\n"
  322. " // SECCOMP_BPF to filter the system calls which cjdns is able to make on a\n"
  323. " // linux system, strictly limiting it's access to the outside world\n"
  324. " // This will fail quietly on any non-linux system\n"
  325. " // Default: enabled\n"
  326. " { \"seccomp\": 1 },\n"
  327. "\n"
  328. " // The client sets up the core using a sequence of RPC calls, the responses\n"
  329. " // to these calls are verified but in the event that the client crashes\n"
  330. " // setup of the core completes, it could leave the core in an insecure state\n"
  331. " // This call constitutes the client telling the core that the security rules\n"
  332. " // have been fully applied and the core may run. Without it, the core will\n"
  333. " // exit within a few seconds with return code 232.\n"
  334. " // Default: enabled\n"
  335. " { \"setupComplete\": 1 }\n"
  336. " ],\n"
  337. "\n"
  338. " // Logging\n"
  339. " \"logging\":\n"
  340. " {\n"
  341. " // Uncomment to have cjdns log to stdout rather than making logs available\n"
  342. " // via the admin socket.\n"
  343. " // \"logTo\":\"stdout\"\n"
  344. " },\n"
  345. "\n"
  346. " // If set to non-zero, cjdns will not fork to the background.\n"
  347. " // Recommended for use in conjunction with \"logTo\":\"stdout\".\n");
  348. if (Defined(win32)) {
  349. printf(" \"noBackground\":1,\n");
  350. }
  351. else {
  352. printf(" \"noBackground\":0,\n");
  353. }
  354. printf("}\n");
  355. return 0;
  356. }
  357. static int usage(struct Allocator* alloc, char* appName)
  358. {
  359. char* sysInfo = SysInfo_describe(SysInfo_detect(), alloc);
  360. printf("Cjdns %s %s\n"
  361. "Usage:\n"
  362. " cjdroute --help This information\n"
  363. " cjdroute --genconf [--no-eth] Generate a configuration file, write it to stdout\n"
  364. " if --no-eth is specified then eth beaconing will\n"
  365. " be disabled.\n"
  366. " cjdroute --bench Run some cryptography performance benchmarks.\n"
  367. " cjdroute --version Print the protocol version which this node speaks.\n"
  368. " cjdroute --cleanconf < conf Print a clean (valid json) version of the config.\n"
  369. " cjdroute --nobg Never fork to the background no matter the config.\n"
  370. "\n"
  371. "To get the router up and running.\n"
  372. "Step 1:\n"
  373. " Generate a new configuration file.\n"
  374. " cjdroute --genconf > cjdroute.conf\n"
  375. "\n"
  376. "Step 2:\n"
  377. " Find somebody to connect to.\n"
  378. " Check out the IRC channel or http://hyperboria.net/\n"
  379. " for information about how to meet new people and make connect to them.\n"
  380. " Read more here: https://github.com/cjdelisle/cjdns/#2-find-a-friend\n"
  381. "\n"
  382. "Step 3:\n"
  383. " Add that somebody's node to your cjdroute.conf file.\n"
  384. " https://github.com/cjdelisle/cjdns/#3-connect-your-node-to-your-friends-node\n"
  385. "\n"
  386. "Step 4:\n"
  387. " Fire it up!\n"
  388. " sudo cjdroute < cjdroute.conf\n"
  389. "\n"
  390. "For more information about other functions and non-standard setups, see README.md\n",
  391. ArchInfo_getArchStr(), sysInfo);
  392. return 0;
  393. }
  394. struct CheckRunningInstanceContext
  395. {
  396. struct EventBase* base;
  397. struct Allocator* alloc;
  398. struct AdminClient_Result* res;
  399. };
  400. static void checkRunningInstanceCallback(struct AdminClient_Promise* p,
  401. struct AdminClient_Result* res)
  402. {
  403. struct CheckRunningInstanceContext* ctx = p->userData;
  404. // Prevent this from freeing until after we drop out of the loop.
  405. Allocator_adopt(ctx->alloc, p->alloc);
  406. ctx->res = res;
  407. EventBase_endLoop(ctx->base);
  408. }
  409. static void checkRunningInstance(struct Allocator* allocator,
  410. struct EventBase* base,
  411. String* addr,
  412. String* password,
  413. struct Log* logger,
  414. struct Except* eh)
  415. {
  416. struct Allocator* alloc = Allocator_child(allocator);
  417. struct Sockaddr_storage pingAddrStorage;
  418. if (Sockaddr_parse(addr->bytes, &pingAddrStorage)) {
  419. Except_throw(eh, "Unable to parse [%s] as an ip address port, eg: 127.0.0.1:11234",
  420. addr->bytes);
  421. }
  422. struct UDPAddrIface* udp = UDPAddrIface_new(base, NULL, alloc, NULL, logger);
  423. struct AdminClient* adminClient =
  424. AdminClient_new(&udp->generic, &pingAddrStorage.addr, password, base, logger, alloc);
  425. // 100 milliseconds is plenty to wait for a process to respond on the same machine.
  426. adminClient->millisecondsToWait = 100;
  427. Dict* pingArgs = Dict_new(alloc);
  428. struct AdminClient_Promise* pingPromise =
  429. AdminClient_rpcCall(String_new("ping", alloc), pingArgs, adminClient, alloc);
  430. struct CheckRunningInstanceContext* ctx =
  431. Allocator_malloc(alloc, sizeof(struct CheckRunningInstanceContext));
  432. ctx->base = base;
  433. ctx->alloc = alloc;
  434. ctx->res = NULL;
  435. pingPromise->callback = checkRunningInstanceCallback;
  436. pingPromise->userData = ctx;
  437. EventBase_beginLoop(base);
  438. Assert_true(ctx->res);
  439. if (ctx->res->err != AdminClient_Error_TIMEOUT) {
  440. Except_throw(eh, "Startup failed: cjdroute is already running. [%d]", ctx->res->err);
  441. }
  442. Allocator_free(alloc);
  443. }
  444. static void onCoreExit(int64_t exit_status, int term_signal)
  445. {
  446. Assert_failure("Core exited with status [%d], signal [%d]\n", (int)exit_status, term_signal);
  447. }
  448. int main(int argc, char** argv)
  449. {
  450. #ifdef Log_KEYS
  451. fprintf(stderr, "Log_LEVEL = KEYS, EXPECT TO SEE PRIVATE KEYS IN YOUR LOGS!\n");
  452. #endif
  453. if (argc > 1 && (!CString_strcmp("angel", argv[1]) || !CString_strcmp("core", argv[1]))) {
  454. return Core_main(argc, argv);
  455. }
  456. Assert_ifParanoid(argc > 0);
  457. struct Except* eh = NULL;
  458. // Allow it to allocate 8MB
  459. struct Allocator* allocator = MallocAllocator_new(1<<23);
  460. struct Random* rand = Random_new(allocator, NULL, eh);
  461. struct EventBase* eventBase = EventBase_new(allocator);
  462. if (argc >= 2) {
  463. // one argument
  464. if ((CString_strcmp(argv[1], "--help") == 0) || (CString_strcmp(argv[1], "-h") == 0)) {
  465. return usage(allocator, argv[0]);
  466. } else if (CString_strcmp(argv[1], "--genconf") == 0) {
  467. bool eth = 1;
  468. for (int i = 1; i < argc; i++) {
  469. if (!CString_strcmp(argv[i], "--no-eth")) {
  470. eth = 0;
  471. }
  472. }
  473. return genconf(rand, eth);
  474. } else if (CString_strcmp(argv[1], "--pidfile") == 0) {
  475. // deprecated
  476. fprintf(stderr, "'--pidfile' option is deprecated.\n");
  477. return 0;
  478. } else if (CString_strcmp(argv[1], "--reconf") == 0) {
  479. // Performed after reading the configuration
  480. } else if (CString_strcmp(argv[1], "--bench") == 0) {
  481. Benchmark_runAll();
  482. return 0;
  483. } else if ((CString_strcmp(argv[1], "--version") == 0)
  484. || (CString_strcmp(argv[1], "-v") == 0))
  485. {
  486. printf("Cjdns protocol version: %d\n", Version_CURRENT_PROTOCOL);
  487. return 0;
  488. } else if (CString_strcmp(argv[1], "--cleanconf") == 0) {
  489. // Performed after reading configuration
  490. } else if (CString_strcmp(argv[1], "--nobg") == 0) {
  491. // Performed while reading configuration
  492. } else {
  493. fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], argv[1]);
  494. fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]);
  495. return -1;
  496. }
  497. } else if (argc > 2) {
  498. // more than one argument?
  499. fprintf(stderr, "%s: too many arguments [%s]\n", argv[0], argv[1]);
  500. fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]);
  501. // because of '--pidfile $filename'?
  502. if (CString_strcmp(argv[1], "--pidfile") == 0)
  503. {
  504. fprintf(stderr, "\n'--pidfile' option is deprecated.\n");
  505. }
  506. return -1;
  507. }
  508. if (isatty(STDIN_FILENO)) {
  509. // We were started from a terminal
  510. // The chances an user wants to type in a configuration
  511. // bij hand are pretty slim so we show him the usage
  512. return usage(allocator, argv[0]);
  513. } else {
  514. // We assume stdin is a configuration file and that we should
  515. // start routing
  516. }
  517. struct Reader* stdinReader = FileReader_new(stdin, allocator);
  518. Dict config;
  519. if (JsonBencSerializer_get()->parseDictionary(stdinReader, allocator, &config)) {
  520. fprintf(stderr, "Failed to parse configuration.\n");
  521. return -1;
  522. }
  523. if (argc == 2 && CString_strcmp(argv[1], "--cleanconf") == 0) {
  524. struct Writer* stdoutWriter = FileWriter_new(stdout, allocator);
  525. JsonBencSerializer_get()->serializeDictionary(stdoutWriter, &config);
  526. printf("\n");
  527. return 0;
  528. }
  529. int forceNoBackground = 0;
  530. if (argc == 2 && CString_strcmp(argv[1], "--nobg") == 0) {
  531. forceNoBackground = 1;
  532. }
  533. struct Log* logger = FileWriterLog_new(stdout, allocator);
  534. // --------------------- Get Admin --------------------- //
  535. Dict* configAdmin = Dict_getDict(&config, String_CONST("admin"));
  536. String* adminPass = Dict_getString(configAdmin, String_CONST("password"));
  537. String* adminBind = Dict_getString(configAdmin, String_CONST("bind"));
  538. if (!adminPass) {
  539. adminPass = String_newBinary(NULL, 32, allocator);
  540. Random_base32(rand, (uint8_t*) adminPass->bytes, 32);
  541. adminPass->len = CString_strlen(adminPass->bytes);
  542. }
  543. if (!adminBind) {
  544. Except_throw(eh, "You must specify admin.bind in the cjdroute.conf file.");
  545. }
  546. // --------------------- Welcome to cjdns ---------------------- //
  547. char* sysInfo = SysInfo_describe(SysInfo_detect(), allocator);
  548. Log_info(logger, "Cjdns %s %s", ArchInfo_getArchStr(), sysInfo);
  549. // --------------------- Check for running instance --------------------- //
  550. Log_info(logger, "Checking for running instance...");
  551. checkRunningInstance(allocator, eventBase, adminBind, adminPass, logger, eh);
  552. // --------------------- Setup Pipes to Angel --------------------- //
  553. struct Allocator* corePipeAlloc = Allocator_child(allocator);
  554. char corePipeName[64] = "client-core-";
  555. Random_base32(rand, (uint8_t*)corePipeName+CString_strlen(corePipeName), 31);
  556. Assert_ifParanoid(EventBase_eventCount(eventBase) == 0);
  557. struct Pipe* corePipe = Pipe_named(corePipeName, eventBase, eh, corePipeAlloc);
  558. Assert_ifParanoid(EventBase_eventCount(eventBase) == 2);
  559. corePipe->logger = logger;
  560. char* args[] = { "core", corePipeName, NULL };
  561. // --------------------- Spawn Angel --------------------- //
  562. String* privateKey = Dict_getString(&config, String_CONST("privateKey"));
  563. char* corePath = Process_getPath(allocator);
  564. if (!corePath) {
  565. Except_throw(eh, "Can't find a usable cjdns core executable, "
  566. "make sure it is in the same directory as cjdroute");
  567. }
  568. if (!privateKey) {
  569. Except_throw(eh, "Need to specify privateKey.");
  570. }
  571. Process_spawn(corePath, args, eventBase, allocator, onCoreExit);
  572. // --------------------- Pre-Configure Core ------------------------- //
  573. Dict* preConf = Dict_new(allocator);
  574. Dict* adminPreConf = Dict_new(allocator);
  575. Dict_putDict(preConf, String_CONST("admin"), adminPreConf, allocator);
  576. Dict_putString(preConf, String_CONST("privateKey"), privateKey, allocator);
  577. Dict_putString(adminPreConf, String_CONST("bind"), adminBind, allocator);
  578. Dict_putString(adminPreConf, String_CONST("pass"), adminPass, allocator);
  579. Dict* logging = Dict_getDict(&config, String_CONST("logging"));
  580. if (logging) {
  581. Dict_putDict(preConf, String_CONST("logging"), logging, allocator);
  582. }
  583. struct Message* toCoreMsg = Message_new(0, 1024, allocator);
  584. BencMessageWriter_write(preConf, toCoreMsg, eh);
  585. Iface_CALL(corePipe->iface.send, toCoreMsg, &corePipe->iface);
  586. Log_debug(logger, "Sent [%d] bytes to core", toCoreMsg->length);
  587. // --------------------- Get Response from Core --------------------- //
  588. struct Message* fromCoreMsg =
  589. InterfaceWaiter_waitForData(&corePipe->iface, eventBase, allocator, eh);
  590. Dict* responseFromCore = BencMessageReader_read(fromCoreMsg, allocator, eh);
  591. // --------------------- Close the Core Pipe --------------------- //
  592. Allocator_free(corePipeAlloc);
  593. corePipe = NULL;
  594. // --------------------- Get Admin Addr/Port/Passwd --------------------- //
  595. Dict* responseFromCoreAdmin = Dict_getDict(responseFromCore, String_CONST("admin"));
  596. adminBind = Dict_getString(responseFromCoreAdmin, String_CONST("bind"));
  597. if (!adminBind) {
  598. Except_throw(eh, "didn't get address and port back from core");
  599. }
  600. struct Sockaddr_storage adminAddr;
  601. if (Sockaddr_parse(adminBind->bytes, &adminAddr)) {
  602. Except_throw(eh, "Unable to parse [%s] as an ip address port, eg: 127.0.0.1:11234",
  603. adminBind->bytes);
  604. }
  605. Assert_ifParanoid(EventBase_eventCount(eventBase) == 1);
  606. // --------------------- Configuration ------------------------- //
  607. Configurator_config(&config,
  608. &adminAddr.addr,
  609. adminPass,
  610. eventBase,
  611. logger,
  612. allocator);
  613. // --------------------- noBackground ------------------------ //
  614. int64_t* noBackground = Dict_getInt(&config, String_CONST("noBackground"));
  615. if (forceNoBackground || (noBackground && *noBackground)) {
  616. Log_debug(logger, "Keeping cjdns client alive because %s",
  617. (forceNoBackground) ? "--nobg was specified on the command line"
  618. : "noBackground was set in the configuration");
  619. EventBase_beginLoop(eventBase);
  620. }
  621. // Freeing this allocator here causes the core to be terminated in the epoll syscall.
  622. //Allocator_free(allocator);
  623. return 0;
  624. }