ef29c992fcf5d712974d050fda8d6c1588ad582a
[tinc] / src / tincctl.c
1 /*
2     tincctl.c -- Controlling a running tincd
3     Copyright (C) 2007-2021 Guus Sliepen <guus@tinc-vpn.org>
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License along
16     with this program; if not, write to the Free Software Foundation, Inc.,
17     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include "system.h"
21
22 #include <getopt.h>
23
24 #ifdef HAVE_READLINE
25 #include "readline/readline.h"
26 #include "readline/history.h"
27 #endif
28
29 #include "xalloc.h"
30 #include "protocol.h"
31 #include "control_common.h"
32 #include "crypto.h"
33 #include "ecdsagen.h"
34 #include "fsck.h"
35 #include "info.h"
36 #include "invitation.h"
37 #include "names.h"
38 #include "rsagen.h"
39 #include "utils.h"
40 #include "tincctl.h"
41 #include "top.h"
42 #include "version.h"
43 #include "subnet.h"
44 #include "keys.h"
45
46 #ifndef MSG_NOSIGNAL
47 #define MSG_NOSIGNAL 0
48 #endif
49
50 static char **orig_argv;
51
52 /* If nonzero, display usage information and exit. */
53 static bool show_help = false;
54
55 /* If nonzero, print the version on standard output and exit.  */
56 static bool show_version = false;
57
58 static char *name = NULL;
59 static char controlcookie[1025];
60 char *tinc_conf = NULL;
61 char *hosts_dir = NULL;
62 struct timeval now;
63
64 // Horrible global variables...
65 static int pid = 0;
66 int fd = -1;
67 char line[4096];
68 static int code;
69 static int req;
70 static int result;
71 bool force = false;
72 bool tty = true;
73 bool confbasegiven = false;
74 char *scriptinterpreter = NULL;
75 char *scriptextension = "";
76 static char *prompt;
77 char *device = NULL;
78 char *iface = NULL;
79 int debug_level = -1;
80
81 static struct option const long_options[] = {
82         {"batch", no_argument, NULL, 'b'},
83         {"config", required_argument, NULL, 'c'},
84         {"net", required_argument, NULL, 'n'},
85         {"help", no_argument, NULL, 1},
86         {"version", no_argument, NULL, 2},
87         {"pidfile", required_argument, NULL, 3},
88         {"force", no_argument, NULL, 4},
89         {NULL, 0, NULL, 0}
90 };
91
92 static void version(void) {
93         printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE,
94                BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR);
95         printf("Features:"
96 #ifdef HAVE_READLINE
97                " readline"
98 #endif
99 #ifdef HAVE_CURSES
100                " curses"
101 #endif
102 #ifndef DISABLE_LEGACY
103                " legacy_protocol"
104 #endif
105                "\n\n");
106         printf("Copyright (C) 1998-2018 Ivo Timmermans, Guus Sliepen and others.\n"
107                "See the AUTHORS file for a complete list.\n\n"
108                "tinc comes with ABSOLUTELY NO WARRANTY.  This is free software,\n"
109                "and you are welcome to redistribute it under certain conditions;\n"
110                "see the file COPYING for details.\n");
111 }
112
113 static void usage(bool status) {
114         if(status) {
115                 fprintf(stderr, "Try `%s --help\' for more information.\n", program_name);
116         } else {
117                 printf("Usage: %s [options] command\n\n", program_name);
118                 printf("Valid options are:\n"
119                        "  -b, --batch             Don't ask for anything (non-interactive mode).\n"
120                        "  -c, --config=DIR        Read configuration options from DIR.\n"
121                        "  -n, --net=NETNAME       Connect to net NETNAME.\n"
122                        "      --pidfile=FILENAME  Read control cookie from FILENAME.\n"
123                        "      --force             Force some commands to work despite warnings.\n"
124                        "      --help              Display this help and exit.\n"
125                        "      --version           Output version information and exit.\n"
126                        "\n"
127                        "Valid commands are:\n"
128                        "  init [name]                Create initial configuration files.\n"
129                        "  get VARIABLE               Print current value of VARIABLE\n"
130                        "  set VARIABLE VALUE         Set VARIABLE to VALUE\n"
131                        "  add VARIABLE VALUE         Add VARIABLE with the given VALUE\n"
132                        "  del VARIABLE [VALUE]       Remove VARIABLE [only ones with watching VALUE]\n"
133                        "  start [tincd options]      Start tincd.\n"
134                        "  stop                       Stop tincd.\n"
135                        "  restart [tincd options]    Restart tincd.\n"
136                        "  reload                     Partially reload configuration of running tincd.\n"
137                        "  pid                        Show PID of currently running tincd.\n"
138 #ifdef DISABLE_LEGACY
139                        "  generate-keys              Generate a new Ed25519 public/private key pair.\n"
140 #else
141                        "  generate-keys [bits]       Generate new RSA and Ed25519 public/private key pairs.\n"
142                        "  generate-rsa-keys [bits]   Generate a new RSA public/private key pair.\n"
143 #endif
144                        "  generate-ed25519-keys      Generate a new Ed25519 public/private key pair.\n"
145                        "  dump                       Dump a list of one of the following things:\n"
146                        "    [reachable] nodes        - all known nodes in the VPN\n"
147                        "    edges                    - all known connections in the VPN\n"
148                        "    subnets                  - all known subnets in the VPN\n"
149                        "    connections              - all meta connections with ourself\n"
150                        "    [di]graph                - graph of the VPN in dotty format\n"
151                        "    invitations              - outstanding invitations\n"
152                        "  info NODE|SUBNET|ADDRESS   Give information about a particular NODE, SUBNET or ADDRESS.\n"
153                        "  purge                      Purge unreachable nodes\n"
154                        "  debug N                    Set debug level\n"
155                        "  retry                      Retry all outgoing connections\n"
156                        "  disconnect NODE            Close meta connection with NODE\n"
157 #ifdef HAVE_CURSES
158                        "  top                        Show real-time statistics\n"
159 #endif
160                        "  pcap [snaplen]             Dump traffic in pcap format [up to snaplen bytes per packet]\n"
161                        "  log [level]                Dump log output [up to the specified level]\n"
162                        "  export                     Export host configuration of local node to standard output\n"
163                        "  export-all                 Export all host configuration files to standard output\n"
164                        "  import                     Import host configuration file(s) from standard input\n"
165                        "  exchange                   Same as export followed by import\n"
166                        "  exchange-all               Same as export-all followed by import\n"
167                        "  invite NODE [...]          Generate an invitation for NODE\n"
168                        "  join INVITATION            Join a VPN using an INVITATION\n"
169                        "  network [NETNAME]          List all known networks, or switch to the one named NETNAME.\n"
170                        "  fsck                       Check the configuration files for problems.\n"
171                        "  sign [FILE]                Generate a signed version of a file.\n"
172                        "  verify NODE [FILE]         Verify that a file was signed by the given NODE.\n"
173                        "\n");
174                 printf("Report bugs to tinc@tinc-vpn.org.\n");
175         }
176 }
177
178 static bool parse_options(int argc, char **argv) {
179         int r;
180         int option_index = 0;
181
182         while((r = getopt_long(argc, argv, "+bc:n:", long_options, &option_index)) != EOF) {
183                 switch(r) {
184                 case 0:   /* long option */
185                         break;
186
187                 case 'b':
188                         tty = false;
189                         break;
190
191                 case 'c': /* config file */
192                         free(confbase);
193                         confbase = xstrdup(optarg);
194                         confbasegiven = true;
195                         break;
196
197                 case 'n': /* net name given */
198                         free(netname);
199                         netname = xstrdup(optarg);
200                         break;
201
202                 case 1:   /* show help */
203                         show_help = true;
204                         break;
205
206                 case 2:   /* show version */
207                         show_version = true;
208                         break;
209
210                 case 3:   /* open control socket here */
211                         free(pidfilename);
212                         pidfilename = xstrdup(optarg);
213                         break;
214
215                 case 4:   /* force */
216                         force = true;
217                         break;
218
219                 case '?': /* wrong options */
220                         usage(true);
221                         free_names();
222                         return false;
223
224                 default:
225                         break;
226                 }
227         }
228
229         if(!netname && (netname = getenv("NETNAME"))) {
230                 netname = xstrdup(netname);
231         }
232
233         /* netname "." is special: a "top-level name" */
234
235         if(netname && (!*netname || !strcmp(netname, "."))) {
236                 free(netname);
237                 netname = NULL;
238         }
239
240         if(netname && (strpbrk(netname, "\\/") || *netname == '.')) {
241                 fprintf(stderr, "Invalid character in netname!\n");
242                 free_names();
243                 return false;
244         }
245
246         return true;
247 }
248
249 static FILE *ask_and_open(const char *filename, const char *what, const char *mode, bool ask, mode_t perms) {
250         FILE *r;
251         char directory[PATH_MAX] = ".";
252         char buf[PATH_MAX];
253         char buf2[PATH_MAX];
254
255 ask_filename:
256
257         /* Check stdin and stdout */
258         if(ask && tty) {
259                 /* Ask for a file and/or directory name. */
260                 fprintf(stderr, "Please enter a file to save %s to [%s]: ", what, filename);
261
262                 if(fgets(buf, sizeof(buf), stdin) == NULL) {
263                         fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno));
264                         return NULL;
265                 }
266
267                 size_t len = strlen(buf);
268
269                 if(len) {
270                         buf[--len] = 0;
271                 }
272
273                 if(len) {
274                         filename = buf;
275                 }
276         }
277
278 #ifdef HAVE_MINGW
279
280         if(filename[0] != '\\' && filename[0] != '/' && !strchr(filename, ':')) {
281 #else
282
283         if(filename[0] != '/') {
284 #endif
285                 /* The directory is a relative path or a filename. */
286                 getcwd(directory, sizeof(directory));
287
288                 if((size_t)snprintf(buf2, sizeof(buf2), "%s" SLASH "%s", directory, filename) >= sizeof(buf2)) {
289                         fprintf(stderr, "Filename too long: %s" SLASH "%s\n", directory, filename);
290
291                         if(ask && tty) {
292                                 goto ask_filename;
293                         } else {
294                                 return NULL;
295                         }
296                 }
297
298                 filename = buf2;
299         }
300
301         disable_old_keys(filename, what);
302
303         /* Open it first to keep the inode busy */
304
305         r = fopenmask(filename, mode, perms);
306
307         if(!r) {
308                 fprintf(stderr, "Error opening file `%s': %s\n", filename, strerror(errno));
309                 return NULL;
310         }
311
312         return r;
313 }
314
315 /*
316   Generate a public/private Ed25519 key pair, and ask for a file to store
317   them in.
318 */
319 static bool ed25519_keygen(bool ask) {
320         ecdsa_t *key;
321         FILE *f;
322         char fname[PATH_MAX];
323
324         fprintf(stderr, "Generating Ed25519 key pair:\n");
325
326         if(!(key = ecdsa_generate())) {
327                 fprintf(stderr, "Error during key generation!\n");
328                 return false;
329         } else {
330                 fprintf(stderr, "Done.\n");
331         }
332
333         snprintf(fname, sizeof(fname), "%s" SLASH "ed25519_key.priv", confbase);
334         f = ask_and_open(fname, "private Ed25519 key", "a", ask, 0600);
335
336         if(!f) {
337                 goto error;
338         }
339
340         if(!ecdsa_write_pem_private_key(key, f)) {
341                 fprintf(stderr, "Error writing private key!\n");
342                 goto error;
343         }
344
345         fclose(f);
346
347         if(name) {
348                 snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, name);
349         } else {
350                 snprintf(fname, sizeof(fname), "%s" SLASH "ed25519_key.pub", confbase);
351         }
352
353         f = ask_and_open(fname, "public Ed25519 key", "a", ask, 0666);
354
355         if(!f) {
356                 return false;
357         }
358
359         char *pubkey = ecdsa_get_base64_public_key(key);
360         fprintf(f, "Ed25519PublicKey = %s\n", pubkey);
361         free(pubkey);
362
363         fclose(f);
364         ecdsa_free(key);
365
366         return true;
367
368 error:
369
370         if(f) {
371                 fclose(f);
372         }
373
374         ecdsa_free(key);
375         return false;
376 }
377
378 #ifndef DISABLE_LEGACY
379 /*
380   Generate a public/private RSA key pair, and ask for a file to store
381   them in.
382 */
383 static bool rsa_keygen(int bits, bool ask) {
384         rsa_t *key;
385         FILE *f;
386         char fname[PATH_MAX];
387
388         // Make sure the key size is a multiple of 8 bits.
389         bits &= ~0x7;
390
391         // Make sure that a valid key size is used.
392         if(bits < 1024 || bits > 8192) {
393                 fprintf(stderr, "Invalid key size %d specified! It should be between 1024 and 8192 bits.\n", bits);
394                 return false;
395         } else if(bits < 2048) {
396                 fprintf(stderr, "WARNING: generating a weak %d bits RSA key! 2048 or more bits are recommended.\n", bits);
397         }
398
399         fprintf(stderr, "Generating %d bits keys:\n", bits);
400
401         if(!(key = rsa_generate(bits, 0x10001))) {
402                 fprintf(stderr, "Error during key generation!\n");
403                 return false;
404         } else {
405                 fprintf(stderr, "Done.\n");
406         }
407
408         snprintf(fname, sizeof(fname), "%s" SLASH "rsa_key.priv", confbase);
409         f = ask_and_open(fname, "private RSA key", "a", ask, 0600);
410
411         if(!f) {
412                 goto error;
413         }
414
415         if(!rsa_write_pem_private_key(key, f)) {
416                 fprintf(stderr, "Error writing private key!\n");
417                 goto error;
418         }
419
420         fclose(f);
421
422         if(name) {
423                 snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, name);
424         } else {
425                 snprintf(fname, sizeof(fname), "%s" SLASH "rsa_key.pub", confbase);
426         }
427
428         f = ask_and_open(fname, "public RSA key", "a", ask, 0666);
429
430         if(!f) {
431                 goto error;
432         }
433
434         if(!rsa_write_pem_public_key(key, f)) {
435                 fprintf(stderr, "Error writing public key!\n");
436                 goto error;
437         }
438
439         fclose(f);
440         rsa_free(key);
441
442         return true;
443
444 error:
445
446         if(f) {
447                 fclose(f);
448         }
449
450         rsa_free(key);
451         return false;
452 }
453 #endif
454
455 char buffer[4096];
456 size_t blen = 0;
457
458 bool recvline(int fd, char *line, size_t len) {
459         char *newline = NULL;
460
461         if(!fd) {
462                 return false;
463         }
464
465         while(!(newline = memchr(buffer, '\n', blen))) {
466                 ssize_t nrecv = recv(fd, buffer + blen, sizeof(buffer) - blen, 0);
467
468                 if(nrecv == -1 && sockerrno == EINTR) {
469                         continue;
470                 } else if(nrecv <= 0) {
471                         return false;
472                 }
473
474                 blen += nrecv;
475         }
476
477         if((size_t)(newline - buffer) >= len) {
478                 return false;
479         }
480
481         len = newline - buffer;
482
483         memcpy(line, buffer, len);
484         line[len] = 0;
485         memmove(buffer, newline + 1, blen - len - 1);
486         blen -= len + 1;
487
488         return true;
489 }
490
491 static bool recvdata(int fd, char *data, size_t len) {
492         while(blen < len) {
493                 ssize_t nrecv = recv(fd, buffer + blen, sizeof(buffer) - blen, 0);
494
495                 if(nrecv == -1 && sockerrno == EINTR) {
496                         continue;
497                 } else if(nrecv <= 0) {
498                         return false;
499                 }
500
501                 blen += nrecv;
502         }
503
504         memcpy(data, buffer, len);
505         memmove(buffer, buffer + len, blen - len);
506         blen -= len;
507
508         return true;
509 }
510
511 bool sendline(int fd, char *format, ...) {
512         static char buffer[4096];
513         char *p = buffer;
514         ssize_t blen;
515         va_list ap;
516
517         va_start(ap, format);
518         blen = vsnprintf(buffer, sizeof(buffer), format, ap);
519         buffer[sizeof(buffer) - 1] = 0;
520         va_end(ap);
521
522         if(blen < 1 || (size_t)blen >= sizeof(buffer)) {
523                 return false;
524         }
525
526         buffer[blen] = '\n';
527         blen++;
528
529         while(blen) {
530                 ssize_t nsend = send(fd, p, blen, MSG_NOSIGNAL);
531
532                 if(nsend == -1 && sockerrno == EINTR) {
533                         continue;
534                 } else if(nsend <= 0) {
535                         return false;
536                 }
537
538                 p += nsend;
539                 blen -= nsend;
540         }
541
542         return true;
543 }
544
545 static void pcap(int fd, FILE *out, uint32_t snaplen) {
546         sendline(fd, "%d %d %d", CONTROL, REQ_PCAP, snaplen);
547         char data[9018];
548
549         struct {
550                 uint32_t magic;
551                 uint16_t major;
552                 uint16_t minor;
553                 uint32_t tz_offset;
554                 uint32_t tz_accuracy;
555                 uint32_t snaplen;
556                 uint32_t ll_type;
557         } header = {
558                 0xa1b2c3d4,
559                 2, 4,
560                 0, 0,
561                 snaplen ? snaplen : sizeof(data),
562                 1,
563         };
564
565         struct {
566                 uint32_t tv_sec;
567                 uint32_t tv_usec;
568                 uint32_t len;
569                 uint32_t origlen;
570         } packet;
571
572         struct timeval tv;
573
574         fwrite(&header, sizeof(header), 1, out);
575         fflush(out);
576
577         char line[32];
578
579         while(recvline(fd, line, sizeof(line))) {
580                 int code, req;
581                 size_t len;
582                 int n = sscanf(line, "%d %d %zd", &code, &req, &len);
583                 gettimeofday(&tv, NULL);
584
585                 if(n != 3 || code != CONTROL || req != REQ_PCAP || len > sizeof(data)) {
586                         break;
587                 }
588
589                 if(!recvdata(fd, data, len)) {
590                         break;
591                 }
592
593                 packet.tv_sec = tv.tv_sec;
594                 packet.tv_usec = tv.tv_usec;
595                 packet.len = len;
596                 packet.origlen = len;
597                 fwrite(&packet, sizeof(packet), 1, out);
598                 fwrite(data, len, 1, out);
599                 fflush(out);
600         }
601 }
602
603 static void logcontrol(int fd, FILE *out, int level) {
604         sendline(fd, "%d %d %d", CONTROL, REQ_LOG, level);
605         char data[1024];
606         char line[32];
607
608         while(recvline(fd, line, sizeof(line))) {
609                 int code, req, len;
610                 int n = sscanf(line, "%d %d %d", &code, &req, &len);
611
612                 if(n != 3 || code != CONTROL || req != REQ_LOG || len < 0 || (size_t)len > sizeof(data)) {
613                         break;
614                 }
615
616                 if(!recvdata(fd, data, len)) {
617                         break;
618                 }
619
620                 fwrite(data, len, 1, out);
621                 fputc('\n', out);
622                 fflush(out);
623         }
624 }
625
626 static bool stop_tincd(void) {
627         if(!connect_tincd(true)) {
628                 return false;
629         }
630
631         sendline(fd, "%d %d", CONTROL, REQ_STOP);
632
633         while(recvline(fd, line, sizeof(line))) {
634                 // wait for tincd to close the connection...
635         }
636
637         close(fd);
638         pid = 0;
639         fd = -1;
640
641         return true;
642 }
643
644 #ifdef HAVE_MINGW
645 static bool remove_service(void) {
646         SC_HANDLE manager = NULL;
647         SC_HANDLE service = NULL;
648         SERVICE_STATUS status = {0};
649         bool success = false;
650
651         manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
652
653         if(!manager) {
654                 fprintf(stderr, "Could not open service manager: %s\n", winerror(GetLastError()));
655                 goto exit;
656         }
657
658         service = OpenService(manager, identname, SERVICE_ALL_ACCESS);
659
660         if(!service) {
661                 if(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST) {
662                         success = stop_tincd();
663                 } else {
664                         fprintf(stderr, "Could not open %s service: %s\n", identname, winerror(GetLastError()));
665                 }
666
667                 goto exit;
668         }
669
670         if(!ControlService(service, SERVICE_CONTROL_STOP, &status)) {
671                 fprintf(stderr, "Could not stop %s service: %s\n", identname, winerror(GetLastError()));
672         } else {
673                 fprintf(stderr, "%s service stopped\n", identname);
674         }
675
676         if(!DeleteService(service)) {
677                 fprintf(stderr, "Could not remove %s service: %s\n", identname, winerror(GetLastError()));
678                 goto exit;
679         }
680
681         success = true;
682
683 exit:
684
685         if(service) {
686                 CloseServiceHandle(service);
687         }
688
689         if(manager) {
690                 CloseServiceHandle(manager);
691         }
692
693         if(success) {
694                 fprintf(stderr, "%s service removed\n", identname);
695         }
696
697         return success;
698 }
699 #endif
700
701 bool connect_tincd(bool verbose) {
702         if(fd >= 0) {
703                 fd_set r;
704                 FD_ZERO(&r);
705                 FD_SET(fd, &r);
706                 struct timeval tv = {0, 0};
707
708                 if(select(fd + 1, &r, NULL, NULL, &tv)) {
709                         fprintf(stderr, "Previous connection to tincd lost, reconnecting.\n");
710                         close(fd);
711                         fd = -1;
712                 } else {
713                         return true;
714                 }
715         }
716
717         FILE *f = fopen(pidfilename, "r");
718
719         if(!f) {
720                 if(verbose) {
721                         fprintf(stderr, "Could not open pid file %s: %s\n", pidfilename, strerror(errno));
722                 }
723
724                 return false;
725         }
726
727         char host[129];
728         char port[129];
729
730         if(fscanf(f, "%20d %1024s %128s port %128s", &pid, controlcookie, host, port) != 4) {
731                 if(verbose) {
732                         fprintf(stderr, "Could not parse pid file %s\n", pidfilename);
733                 }
734
735                 fclose(f);
736                 return false;
737         }
738
739         fclose(f);
740
741 #ifndef HAVE_MINGW
742
743         if((pid == 0) || (kill(pid, 0) && (errno == ESRCH))) {
744                 fprintf(stderr, "Could not find tincd running at pid %d\n", pid);
745                 /* clean up the stale socket and pid file */
746                 unlink(pidfilename);
747                 unlink(unixsocketname);
748                 return false;
749         }
750
751         struct sockaddr_un sa = {
752                 .sun_family = AF_UNIX,
753         };
754
755         if(strlen(unixsocketname) >= sizeof(sa.sun_path)) {
756                 fprintf(stderr, "UNIX socket filename %s is too long!", unixsocketname);
757                 return false;
758         }
759
760         strncpy(sa.sun_path, unixsocketname, sizeof(sa.sun_path));
761
762         fd = socket(AF_UNIX, SOCK_STREAM, 0);
763
764         if(fd < 0) {
765                 if(verbose) {
766                         fprintf(stderr, "Cannot create UNIX socket: %s\n", sockstrerror(sockerrno));
767                 }
768
769                 return false;
770         }
771
772         if(connect(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
773                 if(verbose) {
774                         fprintf(stderr, "Cannot connect to UNIX socket %s: %s\n", unixsocketname, sockstrerror(sockerrno));
775                 }
776
777                 close(fd);
778                 fd = -1;
779                 return false;
780         }
781
782 #else
783         struct addrinfo hints = {
784                 .ai_family = AF_UNSPEC,
785                 .ai_socktype = SOCK_STREAM,
786                 .ai_protocol = IPPROTO_TCP,
787                 .ai_flags = 0,
788         };
789
790         struct addrinfo *res = NULL;
791
792         if(getaddrinfo(host, port, &hints, &res) || !res) {
793                 if(verbose) {
794                         fprintf(stderr, "Cannot resolve %s port %s: %s\n", host, port, sockstrerror(sockerrno));
795                 }
796
797                 return false;
798         }
799
800         fd = socket(res->ai_family, SOCK_STREAM, IPPROTO_TCP);
801
802         if(fd < 0) {
803                 if(verbose) {
804                         fprintf(stderr, "Cannot create TCP socket: %s\n", sockstrerror(sockerrno));
805                 }
806
807                 return false;
808         }
809
810         unsigned long arg = 0;
811
812         if(ioctlsocket(fd, FIONBIO, &arg) != 0) {
813                 if(verbose) {
814                         fprintf(stderr, "System call `%s' failed: %s\n", "ioctlsocket", sockstrerror(sockerrno));
815                 }
816         }
817
818         if(connect(fd, res->ai_addr, res->ai_addrlen) < 0) {
819                 if(verbose) {
820                         fprintf(stderr, "Cannot connect to %s port %s: %s\n", host, port, sockstrerror(sockerrno));
821                 }
822
823                 close(fd);
824                 fd = -1;
825                 return false;
826         }
827
828         freeaddrinfo(res);
829 #endif
830
831 #ifdef SO_NOSIGPIPE
832         static const int one = 1;
833         setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&one, sizeof(one));
834 #endif
835
836         sendline(fd, "%d ^%s %d", ID, controlcookie, TINC_CTL_VERSION_CURRENT);
837
838         char data[4096];
839         int version;
840
841         if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %4095s %d", &code, data, &version) != 3 || code != 0) {
842                 if(verbose) {
843                         fprintf(stderr, "Cannot read greeting from control socket: %s\n", sockstrerror(sockerrno));
844                 }
845
846                 close(fd);
847                 fd = -1;
848                 return false;
849         }
850
851         if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &version, &pid) != 3 || code != 4 || version != TINC_CTL_VERSION_CURRENT) {
852                 if(verbose) {
853                         fprintf(stderr, "Could not fully establish control socket connection\n");
854                 }
855
856                 close(fd);
857                 fd = -1;
858                 return false;
859         }
860
861         return true;
862 }
863
864
865 static int cmd_start(int argc, char *argv[]) {
866         if(connect_tincd(false)) {
867                 if(netname) {
868                         fprintf(stderr, "A tincd is already running for net `%s' with pid %d.\n", netname, pid);
869                 } else {
870                         fprintf(stderr, "A tincd is already running with pid %d.\n", pid);
871                 }
872
873                 return 0;
874         }
875
876         char *c;
877         char *slash = strrchr(program_name, '/');
878
879 #ifdef HAVE_MINGW
880
881         if((c = strrchr(program_name, '\\')) > slash) {
882                 slash = c;
883         }
884
885 #endif
886
887         char *default_c = "tincd";
888
889         if(slash++) {
890                 xasprintf(&c, "%.*stincd", (int)(slash - program_name), program_name);
891         } else {
892                 c = default_c;
893         }
894
895         int nargc = 0;
896         char **nargv = xzalloc((optind + argc) * sizeof(*nargv));
897
898         char *arg0 = c;
899 #ifdef HAVE_MINGW
900         /*
901            Windows has no real concept of an "argv array". A command line is just one string.
902            The CRT of the new process will decode the command line string to generate argv before calling main(), and (by convention)
903            it uses quotes to handle spaces in arguments.
904            Therefore we need to quote all arguments that might contain spaces. No, execvp() won't do that for us (see MSDN).
905            If we don't do that, then execvp() will run fine but any spaces in the filename contained in arg0 will bleed
906            into the next arguments when the spawned process' CRT parses its command line, resulting in chaos.
907         */
908         xasprintf(&arg0, "\"%s\"", arg0);
909 #endif
910         nargv[nargc++] = arg0;
911
912         for(int i = 1; i < optind; i++) {
913                 nargv[nargc++] = orig_argv[i];
914         }
915
916         for(int i = 1; i < argc; i++) {
917                 nargv[nargc++] = argv[i];
918         }
919
920 #ifdef HAVE_MINGW
921         int status = spawnvp(_P_WAIT, c, nargv);
922
923         free(nargv);
924
925         if(c != default_c) {
926                 free(c);
927         }
928
929         if(status == -1) {
930                 fprintf(stderr, "Error starting %s: %s\n", c, strerror(errno));
931                 return 1;
932         }
933
934         return status;
935 #else
936         int pfd[2] = {-1, -1};
937
938         if(socketpair(AF_UNIX, SOCK_STREAM, 0, pfd)) {
939                 fprintf(stderr, "Could not create umbilical socket: %s\n", strerror(errno));
940                 free(nargv);
941
942                 if(c != default_c) {
943                         free(c);
944                 }
945
946                 return 1;
947         }
948
949         pid_t pid = fork();
950
951         if(pid == -1) {
952                 fprintf(stderr, "Could not fork: %s\n", strerror(errno));
953                 free(nargv);
954
955                 if(c != default_c) {
956                         free(c);
957                 }
958
959                 return 1;
960         }
961
962         if(!pid) {
963                 close(pfd[0]);
964                 char buf[100];
965                 snprintf(buf, sizeof(buf), "%d", pfd[1]);
966                 setenv("TINC_UMBILICAL", buf, true);
967                 exit(execvp(c, nargv));
968         } else {
969                 close(pfd[1]);
970         }
971
972         free(nargv);
973
974 #ifdef SIGINT
975         signal(SIGINT, SIG_IGN);
976 #endif
977
978         // Pass all log messages from the umbilical to stderr.
979         // A nul-byte right before closure means tincd started successfully.
980         bool failure = true;
981         uint8_t buf[1024];
982         ssize_t len;
983
984         while((len = read(pfd[0], buf, sizeof(buf))) > 0) {
985                 failure = buf[len - 1];
986
987                 if(!failure) {
988                         len--;
989                 }
990
991                 write(2, buf, len);
992         }
993
994         if(len) {
995                 failure = true;
996         }
997
998         close(pfd[0]);
999
1000         // Make sure the child process is really gone.
1001         int status = -1;
1002         pid_t result = waitpid(pid, &status, 0);
1003
1004 #ifdef SIGINT
1005         signal(SIGINT, SIG_DFL);
1006 #endif
1007
1008         bool failed = failure || result != pid || !WIFEXITED(status) || WEXITSTATUS(status);
1009
1010         if(failed) {
1011                 fprintf(stderr, "Error starting %s\n", c);
1012         }
1013
1014         if(c != default_c) {
1015                 free(c);
1016         }
1017
1018         return failed ? EXIT_FAILURE : EXIT_SUCCESS;
1019 #endif
1020 }
1021
1022 static int cmd_stop(int argc, char *argv[]) {
1023         (void)argv;
1024
1025         if(argc > 1) {
1026                 fprintf(stderr, "Too many arguments!\n");
1027                 return 1;
1028         }
1029
1030 #ifdef HAVE_MINGW
1031         return remove_service() ? EXIT_SUCCESS : EXIT_FAILURE;
1032 #else
1033
1034         if(!stop_tincd()) {
1035                 if(pid) {
1036                         if(kill(pid, SIGTERM)) {
1037                                 fprintf(stderr, "Could not send TERM signal to process with PID %d: %s\n", pid, strerror(errno));
1038                                 return 1;
1039                         }
1040
1041                         fprintf(stderr, "Sent TERM signal to process with PID %d.\n", pid);
1042                         waitpid(pid, NULL, 0);
1043                         return 0;
1044                 }
1045
1046                 return 1;
1047         }
1048
1049         return 0;
1050 #endif
1051 }
1052
1053 static int cmd_restart(int argc, char *argv[]) {
1054         cmd_stop(1, argv);
1055         return cmd_start(argc, argv);
1056 }
1057
1058 static int cmd_reload(int argc, char *argv[]) {
1059         (void)argv;
1060
1061         if(argc > 1) {
1062                 fprintf(stderr, "Too many arguments!\n");
1063                 return 1;
1064         }
1065
1066         if(!connect_tincd(true)) {
1067                 return 1;
1068         }
1069
1070         sendline(fd, "%d %d", CONTROL, REQ_RELOAD);
1071
1072         if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_RELOAD || result) {
1073                 fprintf(stderr, "Could not reload configuration.\n");
1074                 return 1;
1075         }
1076
1077         return 0;
1078
1079 }
1080
1081 static int dump_invitations(void) {
1082         char dname[PATH_MAX];
1083         snprintf(dname, sizeof(dname), "%s" SLASH "invitations", confbase);
1084         DIR *dir = opendir(dname);
1085
1086         if(!dir) {
1087                 if(errno == ENOENT) {
1088                         fprintf(stderr, "No outstanding invitations.\n");
1089                         return 0;
1090                 }
1091
1092                 fprintf(stderr, "Cannot not read directory %s: %s\n", dname, strerror(errno));
1093                 return 1;
1094         }
1095
1096         struct dirent *ent;
1097
1098         bool found = false;
1099
1100         while((ent = readdir(dir))) {
1101                 char buf[MAX_STRING_SIZE];
1102
1103                 if(b64decode(ent->d_name, buf, 24) != 18) {
1104                         continue;
1105                 }
1106
1107                 char fname[PATH_MAX];
1108
1109                 if((size_t)snprintf(fname, sizeof(fname), "%s" SLASH "%s", dname, ent->d_name) >= sizeof(fname)) {
1110                         fprintf(stderr, "Filename too long: %s" SLASH "%s\n", dname, ent->d_name);
1111                         continue;
1112                 }
1113
1114                 FILE *f = fopen(fname, "r");
1115
1116                 if(!f) {
1117                         fprintf(stderr, "Cannot open %s: %s\n", fname, strerror(errno));
1118                         continue;
1119                 }
1120
1121                 buf[0] = 0;
1122
1123                 if(!fgets(buf, sizeof(buf), f)) {
1124                         fprintf(stderr, "Invalid invitation file %s\n", fname);
1125                         fclose(f);
1126                         continue;
1127                 }
1128
1129                 fclose(f);
1130
1131                 char *eol = buf + strlen(buf);
1132
1133                 while(strchr("\t \r\n", *--eol)) {
1134                         *eol = 0;
1135                 }
1136
1137                 if(strncmp(buf, "Name = ", 7) || !check_id(buf + 7)) {
1138                         fprintf(stderr, "Invalid invitation file %s\n", fname);
1139                         continue;
1140                 }
1141
1142                 found = true;
1143                 printf("%s %s\n", ent->d_name, buf + 7);
1144         }
1145
1146         closedir(dir);
1147
1148         if(!found) {
1149                 fprintf(stderr, "No outstanding invitations.\n");
1150         }
1151
1152         return 0;
1153 }
1154
1155 static int cmd_dump(int argc, char *argv[]) {
1156         bool only_reachable = false;
1157
1158         if(argc > 2 && !strcasecmp(argv[1], "reachable")) {
1159                 if(strcasecmp(argv[2], "nodes")) {
1160                         fprintf(stderr, "`reachable' only supported for nodes.\n");
1161                         usage(true);
1162                         return 1;
1163                 }
1164
1165                 only_reachable = true;
1166                 argv++;
1167                 argc--;
1168         }
1169
1170         if(argc != 2) {
1171                 fprintf(stderr, "Invalid number of arguments.\n");
1172                 usage(true);
1173                 return 1;
1174         }
1175
1176         if(!strcasecmp(argv[1], "invitations")) {
1177                 return dump_invitations();
1178         }
1179
1180         if(!connect_tincd(true)) {
1181                 return 1;
1182         }
1183
1184         int do_graph = 0;
1185
1186         if(!strcasecmp(argv[1], "nodes")) {
1187                 sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES);
1188         } else if(!strcasecmp(argv[1], "edges")) {
1189                 sendline(fd, "%d %d", CONTROL, REQ_DUMP_EDGES);
1190         } else if(!strcasecmp(argv[1], "subnets")) {
1191                 sendline(fd, "%d %d", CONTROL, REQ_DUMP_SUBNETS);
1192         } else if(!strcasecmp(argv[1], "connections")) {
1193                 sendline(fd, "%d %d", CONTROL, REQ_DUMP_CONNECTIONS);
1194         } else if(!strcasecmp(argv[1], "graph")) {
1195                 sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES);
1196                 sendline(fd, "%d %d", CONTROL, REQ_DUMP_EDGES);
1197                 do_graph = 1;
1198         } else if(!strcasecmp(argv[1], "digraph")) {
1199                 sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES);
1200                 sendline(fd, "%d %d", CONTROL, REQ_DUMP_EDGES);
1201                 do_graph = 2;
1202         } else {
1203                 fprintf(stderr, "Unknown dump type '%s'.\n", argv[1]);
1204                 usage(true);
1205                 return 1;
1206         }
1207
1208         if(do_graph == 1) {
1209                 printf("graph {\n");
1210         } else if(do_graph == 2) {
1211                 printf("digraph {\n");
1212         }
1213
1214         while(recvline(fd, line, sizeof(line))) {
1215                 char node1[4096], node2[4096];
1216                 int n = sscanf(line, "%d %d %4095s %4095s", &code, &req, node1, node2);
1217
1218                 if(n == 2) {
1219                         if(do_graph && req == REQ_DUMP_NODES) {
1220                                 continue;
1221                         } else {
1222                                 if(do_graph) {
1223                                         printf("}\n");
1224                                 }
1225
1226                                 return 0;
1227                         }
1228                 }
1229
1230                 if(n < 2) {
1231                         break;
1232                 }
1233
1234                 char node[4096];
1235                 char id[4096];
1236                 char from[4096];
1237                 char to[4096];
1238                 char subnet[4096];
1239                 char host[4096];
1240                 char port[4096];
1241                 char local_host[4096];
1242                 char local_port[4096];
1243                 char via[4096];
1244                 char nexthop[4096];
1245                 int cipher, digest, maclength, compression, distance, socket, weight;
1246                 short int pmtu, minmtu, maxmtu;
1247                 unsigned int options, status_int;
1248                 node_status_t status;
1249                 long int last_state_change;
1250                 int udp_ping_rtt;
1251                 uint64_t in_packets, in_bytes, out_packets, out_bytes;
1252
1253                 switch(req) {
1254                 case REQ_DUMP_NODES: {
1255                         int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %d %d %d %d %x %x %4095s %4095s %d %hd %hd %hd %ld %d %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_int, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change, &udp_ping_rtt, &in_packets, &in_bytes, &out_packets, &out_bytes);
1256
1257                         if(n != 22) {
1258                                 fprintf(stderr, "Unable to parse node dump from tincd: %s\n", line);
1259                                 return 1;
1260                         }
1261
1262                         memcpy(&status, &status_int, sizeof(status));
1263
1264                         if(do_graph) {
1265                                 const char *color = "black";
1266
1267                                 if(!strcmp(host, "MYSELF")) {
1268                                         color = "green";
1269                                 } else if(!status.reachable) {
1270                                         color = "red";
1271                                 } else if(strcmp(via, node)) {
1272                                         color = "orange";
1273                                 } else if(!status.validkey) {
1274                                         color = "black";
1275                                 } else if(minmtu > 0) {
1276                                         color = "green";
1277                                 }
1278
1279                                 printf(" \"%s\" [label = \"%s\", color = \"%s\"%s];\n", node, node, color, strcmp(host, "MYSELF") ? "" : ", style = \"filled\"");
1280                         } else {
1281                                 if(only_reachable && !status.reachable) {
1282                                         continue;
1283                                 }
1284
1285                                 printf("%s id %s at %s port %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %d (min %d max %d) rx %"PRIu64" %"PRIu64" tx %"PRIu64" %"PRIu64,
1286                                        node, id, host, port, cipher, digest, maclength, compression, options, status_int, nexthop, via, distance, pmtu, minmtu, maxmtu, in_packets, in_bytes, out_packets, out_bytes);
1287
1288                                 if(udp_ping_rtt != -1) {
1289                                         printf(" rtt %d.%03d", udp_ping_rtt / 1000, udp_ping_rtt % 1000);
1290                                 }
1291
1292                                 printf("\n");
1293                         }
1294                 }
1295                 break;
1296
1297                 case REQ_DUMP_EDGES: {
1298                         int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %4095s port %4095s %x %d", from, to, host, port, local_host, local_port, &options, &weight);
1299
1300                         if(n != 8) {
1301                                 fprintf(stderr, "Unable to parse edge dump from tincd.\n");
1302                                 return 1;
1303                         }
1304
1305                         if(do_graph) {
1306                                 float w = 1.0f + 65536.0f / (float)weight;
1307
1308                                 if(do_graph == 1 && strcmp(node1, node2) > 0) {
1309                                         printf(" \"%s\" -- \"%s\" [w = %f, weight = %f];\n", node1, node2, w, w);
1310                                 } else if(do_graph == 2) {
1311                                         printf(" \"%s\" -> \"%s\" [w = %f, weight = %f];\n", node1, node2, w, w);
1312                                 }
1313                         } else {
1314                                 printf("%s to %s at %s port %s local %s port %s options %x weight %d\n", from, to, host, port, local_host, local_port, options, weight);
1315                         }
1316                 }
1317                 break;
1318
1319                 case REQ_DUMP_SUBNETS: {
1320                         int n = sscanf(line, "%*d %*d %4095s %4095s", subnet, node);
1321
1322                         if(n != 2) {
1323                                 fprintf(stderr, "Unable to parse subnet dump from tincd.\n");
1324                                 return 1;
1325                         }
1326
1327                         printf("%s owner %s\n", strip_weight(subnet), node);
1328                 }
1329                 break;
1330
1331                 case REQ_DUMP_CONNECTIONS: {
1332                         int n = sscanf(line, "%*d %*d %4095s %4095s port %4095s %x %d %x", node, host, port, &options, &socket, &status_int);
1333
1334                         if(n != 6) {
1335                                 fprintf(stderr, "Unable to parse connection dump from tincd.\n");
1336                                 return 1;
1337                         }
1338
1339                         printf("%s at %s port %s options %x socket %d status %x\n", node, host, port, options, socket, status_int);
1340                 }
1341                 break;
1342
1343                 default:
1344                         fprintf(stderr, "Unable to parse dump from tincd.\n");
1345                         return 1;
1346                 }
1347         }
1348
1349         fprintf(stderr, "Error receiving dump.\n");
1350         return 1;
1351 }
1352
1353 static int cmd_purge(int argc, char *argv[]) {
1354         (void)argv;
1355
1356         if(argc > 1) {
1357                 fprintf(stderr, "Too many arguments!\n");
1358                 return 1;
1359         }
1360
1361         if(!connect_tincd(true)) {
1362                 return 1;
1363         }
1364
1365         sendline(fd, "%d %d", CONTROL, REQ_PURGE);
1366
1367         if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_PURGE || result) {
1368                 fprintf(stderr, "Could not purge old information.\n");
1369                 return 1;
1370         }
1371
1372         return 0;
1373 }
1374
1375 static int cmd_debug(int argc, char *argv[]) {
1376         if(argc != 2) {
1377                 fprintf(stderr, "Invalid number of arguments.\n");
1378                 return 1;
1379         }
1380
1381         if(!connect_tincd(true)) {
1382                 return 1;
1383         }
1384
1385         int debuglevel = atoi(argv[1]);
1386         int origlevel;
1387
1388         sendline(fd, "%d %d %d", CONTROL, REQ_SET_DEBUG, debuglevel);
1389
1390         if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &origlevel) != 3 || code != CONTROL || req != REQ_SET_DEBUG) {
1391                 fprintf(stderr, "Could not set debug level.\n");
1392                 return 1;
1393         }
1394
1395         fprintf(stderr, "Old level %d, new level %d.\n", origlevel, debuglevel);
1396         return 0;
1397 }
1398
1399 static int cmd_retry(int argc, char *argv[]) {
1400         (void)argv;
1401
1402         if(argc > 1) {
1403                 fprintf(stderr, "Too many arguments!\n");
1404                 return 1;
1405         }
1406
1407         if(!connect_tincd(true)) {
1408                 return 1;
1409         }
1410
1411         sendline(fd, "%d %d", CONTROL, REQ_RETRY);
1412
1413         if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_RETRY || result) {
1414                 fprintf(stderr, "Could not retry outgoing connections.\n");
1415                 return 1;
1416         }
1417
1418         return 0;
1419 }
1420
1421 static int cmd_connect(int argc, char *argv[]) {
1422         if(argc != 2) {
1423                 fprintf(stderr, "Invalid number of arguments.\n");
1424                 return 1;
1425         }
1426
1427         if(!check_id(argv[1])) {
1428                 fprintf(stderr, "Invalid name for node.\n");
1429                 return 1;
1430         }
1431
1432         if(!connect_tincd(true)) {
1433                 return 1;
1434         }
1435
1436         sendline(fd, "%d %d %s", CONTROL, REQ_CONNECT, argv[1]);
1437
1438         if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_CONNECT || result) {
1439                 fprintf(stderr, "Could not connect to %s.\n", argv[1]);
1440                 return 1;
1441         }
1442
1443         return 0;
1444 }
1445
1446 static int cmd_disconnect(int argc, char *argv[]) {
1447         if(argc != 2) {
1448                 fprintf(stderr, "Invalid number of arguments.\n");
1449                 return 1;
1450         }
1451
1452         if(!check_id(argv[1])) {
1453                 fprintf(stderr, "Invalid name for node.\n");
1454                 return 1;
1455         }
1456
1457         if(!connect_tincd(true)) {
1458                 return 1;
1459         }
1460
1461         sendline(fd, "%d %d %s", CONTROL, REQ_DISCONNECT, argv[1]);
1462
1463         if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_DISCONNECT || result) {
1464                 fprintf(stderr, "Could not disconnect %s.\n", argv[1]);
1465                 return 1;
1466         }
1467
1468         return 0;
1469 }
1470
1471 static int cmd_top(int argc, char *argv[]) {
1472         (void)argv;
1473
1474         if(argc > 1) {
1475                 fprintf(stderr, "Too many arguments!\n");
1476                 return 1;
1477         }
1478
1479 #ifdef HAVE_CURSES
1480
1481         if(!connect_tincd(true)) {
1482                 return 1;
1483         }
1484
1485         top(fd);
1486         return 0;
1487 #else
1488         fprintf(stderr, "This version of tinc was compiled without support for the curses library.\n");
1489         return 1;
1490 #endif
1491 }
1492
1493 static int cmd_pcap(int argc, char *argv[]) {
1494         if(argc > 2) {
1495                 fprintf(stderr, "Too many arguments!\n");
1496                 return 1;
1497         }
1498
1499         if(!connect_tincd(true)) {
1500                 return 1;
1501         }
1502
1503         pcap(fd, stdout, argc > 1 ? atoi(argv[1]) : 0);
1504         return 0;
1505 }
1506
1507 #ifdef SIGINT
1508 static void sigint_handler(int sig) {
1509         (void)sig;
1510
1511         fprintf(stderr, "\n");
1512         shutdown(fd, SHUT_RDWR);
1513 }
1514 #endif
1515
1516 static int cmd_log(int argc, char *argv[]) {
1517         if(argc > 2) {
1518                 fprintf(stderr, "Too many arguments!\n");
1519                 return 1;
1520         }
1521
1522         if(!connect_tincd(true)) {
1523                 return 1;
1524         }
1525
1526 #ifdef SIGINT
1527         signal(SIGINT, sigint_handler);
1528 #endif
1529
1530         logcontrol(fd, stdout, argc > 1 ? atoi(argv[1]) : -1);
1531
1532 #ifdef SIGINT
1533         signal(SIGINT, SIG_DFL);
1534 #endif
1535
1536         close(fd);
1537         fd = -1;
1538         return 0;
1539 }
1540
1541 static int cmd_pid(int argc, char *argv[]) {
1542         (void)argv;
1543
1544         if(argc > 1) {
1545                 fprintf(stderr, "Too many arguments!\n");
1546                 return 1;
1547         }
1548
1549         if(!connect_tincd(true) || !pid) {
1550                 return 1;
1551         }
1552
1553         printf("%d\n", pid);
1554         return 0;
1555 }
1556
1557 size_t rstrip(char *value) {
1558         size_t len = strlen(value);
1559
1560         while(len && strchr("\t\r\n ", value[len - 1])) {
1561                 value[--len] = 0;
1562         }
1563
1564         return len;
1565 }
1566
1567 char *get_my_name(bool verbose) {
1568         FILE *f = fopen(tinc_conf, "r");
1569
1570         if(!f) {
1571                 if(verbose) {
1572                         fprintf(stderr, "Could not open %s: %s\n", tinc_conf, strerror(errno));
1573                 }
1574
1575                 return NULL;
1576         }
1577
1578         char buf[4096];
1579         char *value;
1580
1581         while(fgets(buf, sizeof(buf), f)) {
1582                 size_t len = strcspn(buf, "\t =");
1583                 value = buf + len;
1584                 value += strspn(value, "\t ");
1585
1586                 if(*value == '=') {
1587                         value++;
1588                         value += strspn(value, "\t ");
1589                 }
1590
1591                 if(!rstrip(value)) {
1592                         continue;
1593                 }
1594
1595                 buf[len] = 0;
1596
1597                 if(strcasecmp(buf, "Name")) {
1598                         continue;
1599                 }
1600
1601                 if(*value) {
1602                         fclose(f);
1603                         return replace_name(value);
1604                 }
1605         }
1606
1607         fclose(f);
1608
1609         if(verbose) {
1610                 fprintf(stderr, "Could not find Name in %s.\n", tinc_conf);
1611         }
1612
1613         return NULL;
1614 }
1615
1616 ecdsa_t *get_pubkey(FILE *f) {
1617         char buf[4096];
1618         char *value;
1619
1620         while(fgets(buf, sizeof(buf), f)) {
1621                 size_t len = strcspn(buf, "\t =");
1622                 value = buf + len;
1623                 value += strspn(value, "\t ");
1624
1625                 if(*value == '=') {
1626                         value++;
1627                         value += strspn(value, "\t ");
1628                 }
1629
1630                 if(!rstrip(value)) {
1631                         continue;
1632                 }
1633
1634                 buf[len] = 0;
1635
1636                 if(strcasecmp(buf, "Ed25519PublicKey")) {
1637                         continue;
1638                 }
1639
1640                 if(*value) {
1641                         return ecdsa_set_base64_public_key(value);
1642                 }
1643         }
1644
1645         return NULL;
1646 }
1647
1648 const var_t variables[] = {
1649         /* Server configuration */
1650         {"AddressFamily", VAR_SERVER | VAR_SAFE},
1651         {"AutoConnect", VAR_SERVER | VAR_SAFE},
1652         {"BindToAddress", VAR_SERVER | VAR_MULTIPLE},
1653         {"BindToInterface", VAR_SERVER},
1654         {"Broadcast", VAR_SERVER | VAR_SAFE},
1655         {"BroadcastSubnet", VAR_SERVER | VAR_MULTIPLE | VAR_SAFE},
1656         {"ConnectTo", VAR_SERVER | VAR_MULTIPLE | VAR_SAFE},
1657         {"DecrementTTL", VAR_SERVER | VAR_SAFE},
1658         {"Device", VAR_SERVER},
1659         {"DeviceStandby", VAR_SERVER},
1660         {"DeviceType", VAR_SERVER},
1661         {"DirectOnly", VAR_SERVER | VAR_SAFE},
1662         {"Ed25519PrivateKeyFile", VAR_SERVER},
1663         {"ExperimentalProtocol", VAR_SERVER},
1664         {"Forwarding", VAR_SERVER},
1665         {"FWMark", VAR_SERVER},
1666         {"GraphDumpFile", VAR_SERVER | VAR_OBSOLETE},
1667         {"Hostnames", VAR_SERVER},
1668         {"IffOneQueue", VAR_SERVER},
1669         {"Interface", VAR_SERVER},
1670         {"InvitationExpire", VAR_SERVER},
1671         {"KeyExpire", VAR_SERVER | VAR_SAFE},
1672         {"ListenAddress", VAR_SERVER | VAR_MULTIPLE},
1673         {"LocalDiscovery", VAR_SERVER | VAR_SAFE},
1674         {"LogLevel", VAR_SERVER},
1675         {"MACExpire", VAR_SERVER | VAR_SAFE},
1676         {"MaxConnectionBurst", VAR_SERVER | VAR_SAFE},
1677         {"MaxOutputBufferSize", VAR_SERVER | VAR_SAFE},
1678         {"MaxTimeout", VAR_SERVER | VAR_SAFE},
1679         {"Mode", VAR_SERVER | VAR_SAFE},
1680         {"Name", VAR_SERVER},
1681         {"PingInterval", VAR_SERVER | VAR_SAFE},
1682         {"PingTimeout", VAR_SERVER | VAR_SAFE},
1683         {"PriorityInheritance", VAR_SERVER},
1684         {"PrivateKey", VAR_SERVER | VAR_OBSOLETE},
1685         {"PrivateKeyFile", VAR_SERVER},
1686         {"ProcessPriority", VAR_SERVER},
1687         {"Proxy", VAR_SERVER},
1688         {"ReplayWindow", VAR_SERVER | VAR_SAFE},
1689         {"ScriptsExtension", VAR_SERVER},
1690         {"ScriptsInterpreter", VAR_SERVER},
1691         {"StrictSubnets", VAR_SERVER | VAR_SAFE},
1692         {"TunnelServer", VAR_SERVER | VAR_SAFE},
1693         {"UDPDiscovery", VAR_SERVER | VAR_SAFE},
1694         {"UDPDiscoveryKeepaliveInterval", VAR_SERVER | VAR_SAFE},
1695         {"UDPDiscoveryInterval", VAR_SERVER | VAR_SAFE},
1696         {"UDPDiscoveryTimeout", VAR_SERVER | VAR_SAFE},
1697         {"MTUInfoInterval", VAR_SERVER | VAR_SAFE},
1698         {"UDPInfoInterval", VAR_SERVER | VAR_SAFE},
1699         {"UDPRcvBuf", VAR_SERVER},
1700         {"UDPSndBuf", VAR_SERVER},
1701         {"UPnP", VAR_SERVER},
1702         {"UPnPDiscoverWait", VAR_SERVER},
1703         {"UPnPRefreshPeriod", VAR_SERVER},
1704         {"VDEGroup", VAR_SERVER},
1705         {"VDEPort", VAR_SERVER},
1706         /* Host configuration */
1707         {"Address", VAR_HOST | VAR_MULTIPLE},
1708         {"Cipher", VAR_SERVER | VAR_HOST},
1709         {"ClampMSS", VAR_SERVER | VAR_HOST | VAR_SAFE},
1710         {"Compression", VAR_SERVER | VAR_HOST | VAR_SAFE},
1711         {"Digest", VAR_SERVER | VAR_HOST},
1712         {"Ed25519PublicKey", VAR_HOST},
1713         {"Ed25519PublicKeyFile", VAR_SERVER | VAR_HOST},
1714         {"IndirectData", VAR_SERVER | VAR_HOST | VAR_SAFE},
1715         {"MACLength", VAR_SERVER | VAR_HOST},
1716         {"PMTU", VAR_SERVER | VAR_HOST},
1717         {"PMTUDiscovery", VAR_SERVER | VAR_HOST},
1718         {"Port", VAR_HOST},
1719         {"PublicKey", VAR_HOST | VAR_OBSOLETE},
1720         {"PublicKeyFile", VAR_SERVER | VAR_HOST | VAR_OBSOLETE},
1721         {"Subnet", VAR_HOST | VAR_MULTIPLE | VAR_SAFE},
1722         {"TCPOnly", VAR_SERVER | VAR_HOST | VAR_SAFE},
1723         {"Weight", VAR_HOST | VAR_SAFE},
1724         {NULL, 0}
1725 };
1726
1727 static int cmd_config(int argc, char *argv[]) {
1728         if(argc < 2) {
1729                 fprintf(stderr, "Invalid number of arguments.\n");
1730                 return 1;
1731         }
1732
1733         if(strcasecmp(argv[0], "config")) {
1734                 argv--, argc++;
1735         }
1736
1737         int action = -2;
1738
1739         if(!strcasecmp(argv[1], "get")) {
1740                 argv++, argc--;
1741         } else if(!strcasecmp(argv[1], "add")) {
1742                 argv++, argc--, action = 1;
1743         } else if(!strcasecmp(argv[1], "del")) {
1744                 argv++, argc--, action = -1;
1745         } else if(!strcasecmp(argv[1], "replace") || !strcasecmp(argv[1], "set") || !strcasecmp(argv[1], "change")) {
1746                 argv++, argc--, action = 0;
1747         }
1748
1749         if(argc < 2) {
1750                 fprintf(stderr, "Invalid number of arguments.\n");
1751                 return 1;
1752         }
1753
1754         // Concatenate the rest of the command line
1755         strncpy(line, argv[1], sizeof(line) - 1);
1756
1757         for(int i = 2; i < argc; i++) {
1758                 strncat(line, " ", sizeof(line) - 1 - strlen(line));
1759                 strncat(line, argv[i], sizeof(line) - 1 - strlen(line));
1760         }
1761
1762         // Liberal parsing into node name, variable name and value.
1763         char *node = NULL;
1764         char *variable;
1765         char *value;
1766         size_t len;
1767
1768         len = strcspn(line, "\t =");
1769         value = line + len;
1770         value += strspn(value, "\t ");
1771
1772         if(*value == '=') {
1773                 value++;
1774                 value += strspn(value, "\t ");
1775         }
1776
1777         line[len] = '\0';
1778         variable = strchr(line, '.');
1779
1780         if(variable) {
1781                 node = line;
1782                 *variable++ = 0;
1783         } else {
1784                 variable = line;
1785         }
1786
1787         if(!*variable) {
1788                 fprintf(stderr, "No variable given.\n");
1789                 return 1;
1790         }
1791
1792         if(action >= 0 && !*value) {
1793                 fprintf(stderr, "No value for variable given.\n");
1794                 return 1;
1795         }
1796
1797         if(action < -1 && *value) {
1798                 action = 0;
1799         }
1800
1801         /* Some simple checks. */
1802         bool found = false;
1803         bool warnonremove = false;
1804
1805         for(int i = 0; variables[i].name; i++) {
1806                 if(strcasecmp(variables[i].name, variable)) {
1807                         continue;
1808                 }
1809
1810                 found = true;
1811                 variable = (char *)variables[i].name;
1812
1813                 if(!strcasecmp(variable, "Subnet") && *value) {
1814                         subnet_t s = {0};
1815
1816                         if(!str2net(&s, value)) {
1817                                 fprintf(stderr, "Malformed subnet definition %s\n", value);
1818                                 return 1;
1819                         }
1820
1821                         if(!subnetcheck(s)) {
1822                                 fprintf(stderr, "Network address and prefix length do not match: %s\n", value);
1823                                 return 1;
1824                         }
1825                 }
1826
1827                 /* Discourage use of obsolete variables. */
1828
1829                 if(variables[i].type & VAR_OBSOLETE && action >= 0) {
1830                         if(force) {
1831                                 fprintf(stderr, "Warning: %s is an obsolete variable!\n", variable);
1832                         } else {
1833                                 fprintf(stderr, "%s is an obsolete variable! Use --force to use it anyway.\n", variable);
1834                                 return 1;
1835                         }
1836                 }
1837
1838                 /* Don't put server variables in host config files */
1839
1840                 if(node && !(variables[i].type & VAR_HOST) && action >= 0) {
1841                         if(force) {
1842                                 fprintf(stderr, "Warning: %s is not a host configuration variable!\n", variable);
1843                         } else {
1844                                 fprintf(stderr, "%s is not a host configuration variable! Use --force to use it anyway.\n", variable);
1845                                 return 1;
1846                         }
1847                 }
1848
1849                 /* Should this go into our own host config file? */
1850
1851                 if(!node && !(variables[i].type & VAR_SERVER)) {
1852                         node = get_my_name(true);
1853
1854                         if(!node) {
1855                                 return 1;
1856                         }
1857                 }
1858
1859                 /* Change "add" into "set" for variables that do not allow multiple occurrences.
1860                    Turn on warnings when it seems variables might be removed unintentionally. */
1861
1862                 if(action == 1 && !(variables[i].type & VAR_MULTIPLE)) {
1863                         warnonremove = true;
1864                         action = 0;
1865                 } else if(action == 0 && (variables[i].type & VAR_MULTIPLE)) {
1866                         warnonremove = true;
1867                 }
1868
1869                 break;
1870         }
1871
1872         if(node && !check_id(node)) {
1873                 fprintf(stderr, "Invalid name for node.\n");
1874
1875                 if(node != line) {
1876                         free(node);
1877                 }
1878
1879                 return 1;
1880         }
1881
1882         if(!found) {
1883                 if(force || action < 0) {
1884                         fprintf(stderr, "Warning: %s is not a known configuration variable!\n", variable);
1885                 } else {
1886                         fprintf(stderr, "%s: is not a known configuration variable! Use --force to use it anyway.\n", variable);
1887
1888                         if(node && node != line) {
1889                                 free(node);
1890                         }
1891
1892                         return 1;
1893                 }
1894         }
1895
1896         // Open the right configuration file.
1897         char filename[PATH_MAX];
1898
1899         if(node) {
1900                 snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, node);
1901
1902                 if(node != line) {
1903                         free(node);
1904                         node = NULL;
1905                 }
1906         } else {
1907                 snprintf(filename, sizeof(filename), "%s", tinc_conf);
1908         }
1909
1910         FILE *f = fopen(filename, "r");
1911
1912         if(!f) {
1913                 fprintf(stderr, "Could not open configuration file %s: %s\n", filename, strerror(errno));
1914                 return 1;
1915         }
1916
1917         char tmpfile[PATH_MAX];
1918         FILE *tf = NULL;
1919
1920         if(action >= -1) {
1921                 if((size_t)snprintf(tmpfile, sizeof(tmpfile), "%s.config.tmp", filename) >= sizeof(tmpfile)) {
1922                         fprintf(stderr, "Filename too long: %s.config.tmp\n", filename);
1923                         return 1;
1924                 }
1925
1926                 tf = fopen(tmpfile, "w");
1927
1928                 if(!tf) {
1929                         fprintf(stderr, "Could not open temporary file %s: %s\n", tmpfile, strerror(errno));
1930                         fclose(f);
1931                         return 1;
1932                 }
1933         }
1934
1935         // Copy the file, making modifications on the fly, unless we are just getting a value.
1936         char buf1[4096];
1937         char buf2[4096];
1938         bool set = false;
1939         bool removed = false;
1940         found = false;
1941
1942         while(fgets(buf1, sizeof(buf1), f)) {
1943                 buf1[sizeof(buf1) - 1] = 0;
1944                 strncpy(buf2, buf1, sizeof(buf2));
1945
1946                 // Parse line in a simple way
1947                 char *bvalue;
1948
1949                 size_t len = strcspn(buf2, "\t =");
1950                 bvalue = buf2 + len;
1951                 bvalue += strspn(bvalue, "\t ");
1952
1953                 if(*bvalue == '=') {
1954                         bvalue++;
1955                         bvalue += strspn(bvalue, "\t ");
1956                 }
1957
1958                 rstrip(bvalue);
1959                 buf2[len] = '\0';
1960
1961                 // Did it match?
1962                 if(!strcasecmp(buf2, variable)) {
1963                         // Get
1964                         if(action < -1) {
1965                                 found = true;
1966                                 printf("%s\n", bvalue);
1967                                 // Del
1968                         } else if(action == -1) {
1969                                 if(!*value || !strcasecmp(bvalue, value)) {
1970                                         removed = true;
1971                                         continue;
1972                                 }
1973
1974                                 // Set
1975                         } else if(action == 0) {
1976                                 // Warn if "set" was used for variables that can occur multiple times
1977                                 if(warnonremove && strcasecmp(bvalue, value)) {
1978                                         fprintf(stderr, "Warning: removing %s = %s\n", variable, bvalue);
1979                                 }
1980
1981                                 // Already set? Delete the rest...
1982                                 if(set) {
1983                                         continue;
1984                                 }
1985
1986                                 // Otherwise, replace.
1987                                 if(fprintf(tf, "%s = %s\n", variable, value) < 0) {
1988                                         fprintf(stderr, "Error writing to temporary file %s: %s\n", tmpfile, strerror(errno));
1989                                         return 1;
1990                                 }
1991
1992                                 set = true;
1993                                 continue;
1994                                 // Add
1995                         } else if(action > 0) {
1996                                 // Check if we've already seen this variable with the same value
1997                                 if(!strcasecmp(bvalue, value)) {
1998                                         found = true;
1999                                 }
2000                         }
2001                 }
2002
2003                 if(action >= -1) {
2004                         // Copy original line...
2005                         if(fputs(buf1, tf) < 0) {
2006                                 fprintf(stderr, "Error writing to temporary file %s: %s\n", tmpfile, strerror(errno));
2007                                 return 1;
2008                         }
2009
2010                         // Add newline if it is missing...
2011                         if(*buf1 && buf1[strlen(buf1) - 1] != '\n') {
2012                                 if(fputc('\n', tf) < 0) {
2013                                         fprintf(stderr, "Error writing to temporary file %s: %s\n", tmpfile, strerror(errno));
2014                                         return 1;
2015                                 }
2016                         }
2017                 }
2018         }
2019
2020         // Make sure we read everything...
2021         if(ferror(f) || !feof(f)) {
2022                 fprintf(stderr, "Error while reading from configuration file %s: %s\n", filename, strerror(errno));
2023                 return 1;
2024         }
2025
2026         if(fclose(f)) {
2027                 fprintf(stderr, "Error closing configuration file %s: %s\n", filename, strerror(errno));
2028                 return 1;
2029         }
2030
2031         // Add new variable if necessary.
2032         if((action > 0 && !found) || (action == 0 && !set)) {
2033                 if(fprintf(tf, "%s = %s\n", variable, value) < 0) {
2034                         fprintf(stderr, "Error writing to temporary file %s: %s\n", tmpfile, strerror(errno));
2035                         return 1;
2036                 }
2037         }
2038
2039         if(action < -1) {
2040                 if(found) {
2041                         return 0;
2042                 } else {
2043                         fprintf(stderr, "No matching configuration variables found.\n");
2044                         return 1;
2045                 }
2046         }
2047
2048         // Make sure we wrote everything...
2049         if(fclose(tf)) {
2050                 fprintf(stderr, "Error closing temporary file %s: %s\n", tmpfile, strerror(errno));
2051                 return 1;
2052         }
2053
2054         // Could we find what we had to remove?
2055         if(action < 0 && !removed) {
2056                 remove(tmpfile);
2057                 fprintf(stderr, "No configuration variables deleted.\n");
2058                 return 1;
2059         }
2060
2061         // Replace the configuration file with the new one
2062 #ifdef HAVE_MINGW
2063
2064         if(remove(filename)) {
2065                 fprintf(stderr, "Error replacing file %s: %s\n", filename, strerror(errno));
2066                 return 1;
2067         }
2068
2069 #endif
2070
2071         if(rename(tmpfile, filename)) {
2072                 fprintf(stderr, "Error renaming temporary file %s to configuration file %s: %s\n", tmpfile, filename, strerror(errno));
2073                 return 1;
2074         }
2075
2076         // Silently try notifying a running tincd of changes.
2077         if(connect_tincd(false)) {
2078                 sendline(fd, "%d %d", CONTROL, REQ_RELOAD);
2079         }
2080
2081         return 0;
2082 }
2083
2084 static bool try_bind(int port) {
2085         struct addrinfo *ai = NULL, *aip;
2086         struct addrinfo hint = {
2087                 .ai_flags = AI_PASSIVE,
2088                 .ai_family = AF_UNSPEC,
2089                 .ai_socktype = SOCK_STREAM,
2090                 .ai_protocol = IPPROTO_TCP,
2091         };
2092
2093         bool success = true;
2094         char portstr[16];
2095         snprintf(portstr, sizeof(portstr), "%d", port);
2096
2097         if(getaddrinfo(NULL, portstr, &hint, &ai) || !ai) {
2098                 return false;
2099         }
2100
2101         for(aip = ai; aip; aip = aip->ai_next) {
2102                 int fd = socket(ai->ai_family, SOCK_STREAM, IPPROTO_TCP);
2103
2104                 if(!fd) {
2105                         success = false;
2106                         break;
2107                 }
2108
2109                 int result = bind(fd, ai->ai_addr, ai->ai_addrlen);
2110                 closesocket(fd);
2111
2112                 if(result) {
2113                         success = false;
2114                         break;
2115                 }
2116         }
2117
2118         freeaddrinfo(ai);
2119         return success;
2120 }
2121
2122 int check_port(const char *name) {
2123         if(try_bind(655)) {
2124                 return 655;
2125         }
2126
2127         fprintf(stderr, "Warning: could not bind to port 655. ");
2128
2129         for(int i = 0; i < 100; i++) {
2130                 int port = 0x1000 + (rand() & 0x7fff);
2131
2132                 if(try_bind(port)) {
2133                         char filename[PATH_MAX];
2134                         snprintf(filename, sizeof(filename), "%s" SLASH "hosts" SLASH "%s", confbase, name);
2135                         FILE *f = fopen(filename, "a");
2136
2137                         if(!f) {
2138                                 fprintf(stderr, "Could not open %s: %s\n", filename, strerror(errno));
2139                                 fprintf(stderr, "Please change tinc's Port manually.\n");
2140                                 return 0;
2141                         }
2142
2143                         fprintf(f, "Port = %d\n", port);
2144                         fclose(f);
2145                         fprintf(stderr, "Tinc will instead listen on port %d.\n", port);
2146                         return port;
2147                 }
2148         }
2149
2150         fprintf(stderr, "Please change tinc's Port manually.\n");
2151         return 0;
2152 }
2153
2154 static int cmd_init(int argc, char *argv[]) {
2155         if(!access(tinc_conf, F_OK)) {
2156                 fprintf(stderr, "Configuration file %s already exists!\n", tinc_conf);
2157                 return 1;
2158         }
2159
2160         if(argc > 2) {
2161                 fprintf(stderr, "Too many arguments!\n");
2162                 return 1;
2163         } else if(argc < 2) {
2164                 if(tty) {
2165                         char buf[1024];
2166                         fprintf(stderr, "Enter the Name you want your tinc node to have: ");
2167
2168                         if(!fgets(buf, sizeof(buf), stdin)) {
2169                                 fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno));
2170                                 return 1;
2171                         }
2172
2173                         size_t len = rstrip(buf);
2174
2175                         if(!len) {
2176                                 fprintf(stderr, "No name given!\n");
2177                                 return 1;
2178                         }
2179
2180                         name = strdup(buf);
2181                 } else {
2182                         fprintf(stderr, "No Name given!\n");
2183                         return 1;
2184                 }
2185         } else {
2186                 name = strdup(argv[1]);
2187
2188                 if(!*name) {
2189                         fprintf(stderr, "No Name given!\n");
2190                         return 1;
2191                 }
2192         }
2193
2194         if(!check_id(name)) {
2195                 fprintf(stderr, "Invalid Name! Only a-z, A-Z, 0-9 and _ are allowed characters.\n");
2196                 return 1;
2197         }
2198
2199         if(!confbase_given && mkdir(confdir, 0755) && errno != EEXIST) {
2200                 fprintf(stderr, "Could not create directory %s: %s\n", confdir, strerror(errno));
2201                 return 1;
2202         }
2203
2204         if(mkdir(confbase, 0777) && errno != EEXIST) {
2205                 fprintf(stderr, "Could not create directory %s: %s\n", confbase, strerror(errno));
2206                 return 1;
2207         }
2208
2209         if(mkdir(hosts_dir, 0777) && errno != EEXIST) {
2210                 fprintf(stderr, "Could not create directory %s: %s\n", hosts_dir, strerror(errno));
2211                 return 1;
2212         }
2213
2214         FILE *f = fopen(tinc_conf, "w");
2215
2216         if(!f) {
2217                 fprintf(stderr, "Could not create file %s: %s\n", tinc_conf, strerror(errno));
2218                 return 1;
2219         }
2220
2221         fprintf(f, "Name = %s\n", name);
2222         fclose(f);
2223
2224 #ifndef DISABLE_LEGACY
2225
2226         if(!rsa_keygen(2048, false)) {
2227                 return 1;
2228         }
2229
2230 #endif
2231
2232         if(!ed25519_keygen(false)) {
2233                 return 1;
2234         }
2235
2236         check_port(name);
2237
2238 #ifndef HAVE_MINGW
2239         char filename[PATH_MAX];
2240         snprintf(filename, sizeof(filename), "%s" SLASH "tinc-up", confbase);
2241
2242         if(access(filename, F_OK)) {
2243                 FILE *f = fopenmask(filename, "w", 0777);
2244
2245                 if(!f) {
2246                         fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno));
2247                         return 1;
2248                 }
2249
2250                 fprintf(f, "#!/bin/sh\n\necho 'Unconfigured tinc-up script, please edit '$0'!'\n\n#ifconfig $INTERFACE <your vpn IP address> netmask <netmask of whole VPN>\n");
2251                 fclose(f);
2252         }
2253
2254 #endif
2255
2256         return 0;
2257
2258 }
2259
2260 static int cmd_generate_keys(int argc, char *argv[]) {
2261 #ifdef DISABLE_LEGACY
2262         (void)argv;
2263
2264         if(argc > 1) {
2265 #else
2266
2267         if(argc > 2) {
2268 #endif
2269                 fprintf(stderr, "Too many arguments!\n");
2270                 return 1;
2271         }
2272
2273         if(!name) {
2274                 name = get_my_name(false);
2275         }
2276
2277 #ifndef DISABLE_LEGACY
2278
2279         if(!rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true)) {
2280                 return 1;
2281         }
2282
2283 #endif
2284
2285         if(!ed25519_keygen(true)) {
2286                 return 1;
2287         }
2288
2289         return 0;
2290 }
2291
2292 #ifndef DISABLE_LEGACY
2293 static int cmd_generate_rsa_keys(int argc, char *argv[]) {
2294         if(argc > 2) {
2295                 fprintf(stderr, "Too many arguments!\n");
2296                 return 1;
2297         }
2298
2299         if(!name) {
2300                 name = get_my_name(false);
2301         }
2302
2303         return !rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true);
2304 }
2305 #endif
2306
2307 static int cmd_generate_ed25519_keys(int argc, char *argv[]) {
2308         (void)argv;
2309
2310         if(argc > 1) {
2311                 fprintf(stderr, "Too many arguments!\n");
2312                 return 1;
2313         }
2314
2315         if(!name) {
2316                 name = get_my_name(false);
2317         }
2318
2319         return !ed25519_keygen(true);
2320 }
2321
2322 static int cmd_help(int argc, char *argv[]) {
2323         (void)argc;
2324         (void)argv;
2325
2326         usage(false);
2327         return 0;
2328 }
2329
2330 static int cmd_version(int argc, char *argv[]) {
2331         (void)argv;
2332
2333         if(argc > 1) {
2334                 fprintf(stderr, "Too many arguments!\n");
2335                 return 1;
2336         }
2337
2338         version();
2339         return 0;
2340 }
2341
2342 static int cmd_info(int argc, char *argv[]) {
2343         if(argc != 2) {
2344                 fprintf(stderr, "Invalid number of arguments.\n");
2345                 return 1;
2346         }
2347
2348         if(!connect_tincd(true)) {
2349                 return 1;
2350         }
2351
2352         return info(fd, argv[1]);
2353 }
2354
2355 static const char *conffiles[] = {
2356         "tinc.conf",
2357         "tinc-up",
2358         "tinc-down",
2359         "subnet-up",
2360         "subnet-down",
2361         "host-up",
2362         "host-down",
2363         NULL,
2364 };
2365
2366 static int cmd_edit(int argc, char *argv[]) {
2367         if(argc != 2) {
2368                 fprintf(stderr, "Invalid number of arguments.\n");
2369                 return 1;
2370         }
2371
2372         char filename[PATH_MAX] = "";
2373
2374         if(strncmp(argv[1], "hosts" SLASH, 6)) {
2375                 for(int i = 0; conffiles[i]; i++) {
2376                         if(!strcmp(argv[1], conffiles[i])) {
2377                                 snprintf(filename, sizeof(filename), "%s" SLASH "%s", confbase, argv[1]);
2378                                 break;
2379                         }
2380                 }
2381         } else {
2382                 argv[1] += 6;
2383         }
2384
2385         if(!*filename) {
2386                 snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, argv[1]);
2387                 char *dash = strchr(argv[1], '-');
2388
2389                 if(dash) {
2390                         *dash++ = 0;
2391
2392                         if((strcmp(dash, "up") && strcmp(dash, "down")) || !check_id(argv[1])) {
2393                                 fprintf(stderr, "Invalid configuration filename.\n");
2394                                 return 1;
2395                         }
2396                 }
2397         }
2398
2399         char *command;
2400 #ifndef HAVE_MINGW
2401         const char *editor = getenv("VISUAL");
2402
2403         if(!editor) {
2404                 editor = getenv("EDITOR");
2405         }
2406
2407         if(!editor) {
2408                 editor = "vi";
2409         }
2410
2411         xasprintf(&command, "\"%s\" \"%s\"", editor, filename);
2412 #else
2413         xasprintf(&command, "edit \"%s\"", filename);
2414 #endif
2415         int result = system(command);
2416         free(command);
2417
2418         if(result) {
2419                 return result;
2420         }
2421
2422         // Silently try notifying a running tincd of changes.
2423         if(connect_tincd(false)) {
2424                 sendline(fd, "%d %d", CONTROL, REQ_RELOAD);
2425         }
2426
2427         return 0;
2428 }
2429
2430 static int export(const char *name, FILE *out) {
2431         char filename[PATH_MAX];
2432         snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, name);
2433         FILE *in = fopen(filename, "r");
2434
2435         if(!in) {
2436                 fprintf(stderr, "Could not open configuration file %s: %s\n", filename, strerror(errno));
2437                 return 1;
2438         }
2439
2440         fprintf(out, "Name = %s\n", name);
2441         char buf[4096];
2442
2443         while(fgets(buf, sizeof(buf), in)) {
2444                 if(strcspn(buf, "\t =") != 4 || strncasecmp(buf, "Name", 4)) {
2445                         fputs(buf, out);
2446                 }
2447         }
2448
2449         if(ferror(in)) {
2450                 fprintf(stderr, "Error while reading configuration file %s: %s\n", filename, strerror(errno));
2451                 fclose(in);
2452                 return 1;
2453         }
2454
2455         fclose(in);
2456         return 0;
2457 }
2458
2459 static int cmd_export(int argc, char *argv[]) {
2460         (void)argv;
2461
2462         if(argc > 1) {
2463                 fprintf(stderr, "Too many arguments!\n");
2464                 return 1;
2465         }
2466
2467         char *name = get_my_name(true);
2468
2469         if(!name) {
2470                 return 1;
2471         }
2472
2473         int result = export(name, stdout);
2474
2475         if(!tty) {
2476                 fclose(stdout);
2477         }
2478
2479         free(name);
2480         return result;
2481 }
2482
2483 static int cmd_export_all(int argc, char *argv[]) {
2484         (void)argv;
2485
2486         if(argc > 1) {
2487                 fprintf(stderr, "Too many arguments!\n");
2488                 return 1;
2489         }
2490
2491         DIR *dir = opendir(hosts_dir);
2492
2493         if(!dir) {
2494                 fprintf(stderr, "Could not open host configuration directory %s: %s\n", hosts_dir, strerror(errno));
2495                 return 1;
2496         }
2497
2498         bool first = true;
2499         int result = 0;
2500         struct dirent *ent;
2501
2502         while((ent = readdir(dir))) {
2503                 if(!check_id(ent->d_name)) {
2504                         continue;
2505                 }
2506
2507                 if(first) {
2508                         first = false;
2509                 } else {
2510                         printf("#---------------------------------------------------------------#\n");
2511                 }
2512
2513                 result |= export(ent->d_name, stdout);
2514         }
2515
2516         closedir(dir);
2517
2518         if(!tty) {
2519                 fclose(stdout);
2520         }
2521
2522         return result;
2523 }
2524
2525 static int cmd_import(int argc, char *argv[]) {
2526         (void)argv;
2527
2528         if(argc > 1) {
2529                 fprintf(stderr, "Too many arguments!\n");
2530                 return 1;
2531         }
2532
2533         FILE *in = stdin;
2534         FILE *out = NULL;
2535
2536         char buf[4096];
2537         char name[4096];
2538         char filename[PATH_MAX] = "";
2539         int count = 0;
2540         bool firstline = true;
2541
2542         while(fgets(buf, sizeof(buf), in)) {
2543                 if(sscanf(buf, "Name = %4095s", name) == 1) {
2544                         firstline = false;
2545
2546                         if(!check_id(name)) {
2547                                 fprintf(stderr, "Invalid Name in input!\n");
2548                                 return 1;
2549                         }
2550
2551                         if(out) {
2552                                 fclose(out);
2553                         }
2554
2555                         if((size_t)snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, name) >= sizeof(filename)) {
2556                                 fprintf(stderr, "Filename too long: %s" SLASH "%s\n", hosts_dir, name);
2557                                 return 1;
2558                         }
2559
2560                         if(!force && !access(filename, F_OK)) {
2561                                 fprintf(stderr, "Host configuration file %s already exists, skipping.\n", filename);
2562                                 out = NULL;
2563                                 continue;
2564                         }
2565
2566                         out = fopen(filename, "w");
2567
2568                         if(!out) {
2569                                 fprintf(stderr, "Error creating configuration file %s: %s\n", filename, strerror(errno));
2570                                 return 1;
2571                         }
2572
2573                         count++;
2574                         continue;
2575                 } else if(firstline) {
2576                         fprintf(stderr, "Junk at the beginning of the input, ignoring.\n");
2577                         firstline = false;
2578                 }
2579
2580
2581                 if(!strcmp(buf, "#---------------------------------------------------------------#\n")) {
2582                         continue;
2583                 }
2584
2585                 if(out) {
2586                         if(fputs(buf, out) < 0) {
2587                                 fprintf(stderr, "Error writing to host configuration file %s: %s\n", filename, strerror(errno));
2588                                 return 1;
2589                         }
2590                 }
2591         }
2592
2593         if(out) {
2594                 fclose(out);
2595         }
2596
2597         if(count) {
2598                 fprintf(stderr, "Imported %d host configuration files.\n", count);
2599                 return 0;
2600         } else {
2601                 fprintf(stderr, "No host configuration files imported.\n");
2602                 return 1;
2603         }
2604 }
2605
2606 static int cmd_exchange(int argc, char *argv[]) {
2607         return cmd_export(argc, argv) ? 1 : cmd_import(argc, argv);
2608 }
2609
2610 static int cmd_exchange_all(int argc, char *argv[]) {
2611         return cmd_export_all(argc, argv) ? 1 : cmd_import(argc, argv);
2612 }
2613
2614 static int switch_network(char *name) {
2615         if(strcmp(name, ".")) {
2616                 if(!check_netname(name, false)) {
2617                         fprintf(stderr, "Invalid character in netname!\n");
2618                         return 1;
2619                 }
2620
2621                 if(!check_netname(name, true)) {
2622                         fprintf(stderr, "Warning: unsafe character in netname!\n");
2623                 }
2624         }
2625
2626         if(fd >= 0) {
2627                 close(fd);
2628                 fd = -1;
2629         }
2630
2631         free_names();
2632         netname = strcmp(name, ".") ? xstrdup(name) : NULL;
2633         make_names(false);
2634
2635         free(tinc_conf);
2636         free(hosts_dir);
2637         free(prompt);
2638
2639         xasprintf(&tinc_conf, "%s" SLASH "tinc.conf", confbase);
2640         xasprintf(&hosts_dir, "%s" SLASH "hosts", confbase);
2641         xasprintf(&prompt, "%s> ", identname);
2642
2643         return 0;
2644 }
2645
2646 static int cmd_network(int argc, char *argv[]) {
2647         if(argc > 2) {
2648                 fprintf(stderr, "Too many arguments!\n");
2649                 return 1;
2650         }
2651
2652         if(argc == 2) {
2653                 return switch_network(argv[1]);
2654         }
2655
2656         DIR *dir = opendir(confdir);
2657
2658         if(!dir) {
2659                 fprintf(stderr, "Could not read directory %s: %s\n", confdir, strerror(errno));
2660                 return 1;
2661         }
2662
2663         struct dirent *ent;
2664
2665         while((ent = readdir(dir))) {
2666                 if(*ent->d_name == '.') {
2667                         continue;
2668                 }
2669
2670                 if(!strcmp(ent->d_name, "tinc.conf")) {
2671                         printf(".\n");
2672                         continue;
2673                 }
2674
2675                 char fname[PATH_MAX];
2676                 snprintf(fname, sizeof(fname), "%s/%s/tinc.conf", confdir, ent->d_name);
2677
2678                 if(!access(fname, R_OK)) {
2679                         printf("%s\n", ent->d_name);
2680                 }
2681         }
2682
2683         closedir(dir);
2684
2685         return 0;
2686 }
2687
2688 static int cmd_fsck(int argc, char *argv[]) {
2689         (void)argv;
2690
2691         if(argc > 1) {
2692                 fprintf(stderr, "Too many arguments!\n");
2693                 return 1;
2694         }
2695
2696         return fsck(orig_argv[0]);
2697 }
2698
2699 static void *readfile(FILE *in, size_t *len) {
2700         size_t count = 0;
2701         size_t bufsize = 4096;
2702         char *buf = xmalloc(bufsize);
2703
2704         while(!feof(in)) {
2705                 size_t read = fread(buf + count, 1, bufsize - count, in);
2706
2707                 if(!read) {
2708                         break;
2709                 }
2710
2711                 count += read;
2712
2713                 if(count >= bufsize) {
2714                         bufsize *= 2;
2715                         buf = xrealloc(buf, bufsize);
2716                 }
2717         }
2718
2719         if(len) {
2720                 *len = count;
2721         }
2722
2723         return buf;
2724 }
2725
2726 static int cmd_sign(int argc, char *argv[]) {
2727         if(argc > 2) {
2728                 fprintf(stderr, "Too many arguments!\n");
2729                 return 1;
2730         }
2731
2732         if(!name) {
2733                 name = get_my_name(true);
2734
2735                 if(!name) {
2736                         return 1;
2737                 }
2738         }
2739
2740         char fname[PATH_MAX];
2741         snprintf(fname, sizeof(fname), "%s" SLASH "ed25519_key.priv", confbase);
2742         FILE *fp = fopen(fname, "r");
2743
2744         if(!fp) {
2745                 fprintf(stderr, "Could not open %s: %s\n", fname, strerror(errno));
2746                 return 1;
2747         }
2748
2749         ecdsa_t *key = ecdsa_read_pem_private_key(fp);
2750
2751         if(!key) {
2752                 fprintf(stderr, "Could not read private key from %s\n", fname);
2753                 fclose(fp);
2754                 return 1;
2755         }
2756
2757         fclose(fp);
2758
2759         FILE *in;
2760
2761         if(argc == 2) {
2762                 in = fopen(argv[1], "rb");
2763
2764                 if(!in) {
2765                         fprintf(stderr, "Could not open %s: %s\n", argv[1], strerror(errno));
2766                         ecdsa_free(key);
2767                         return 1;
2768                 }
2769         } else {
2770                 in = stdin;
2771         }
2772
2773         size_t len;
2774         char *data = readfile(in, &len);
2775
2776         if(in != stdin) {
2777                 fclose(in);
2778         }
2779
2780         if(!data) {
2781                 fprintf(stderr, "Error reading %s: %s\n", argv[1], strerror(errno));
2782                 ecdsa_free(key);
2783                 return 1;
2784         }
2785
2786         // Ensure we sign our name and current time as well
2787         long t = time(NULL);
2788         char *trailer;
2789         xasprintf(&trailer, " %s %ld", name, t);
2790         size_t trailer_len = strlen(trailer);
2791
2792         data = xrealloc(data, len + trailer_len);
2793         memcpy(data + len, trailer, trailer_len);
2794         free(trailer);
2795
2796         char sig[87];
2797
2798         if(!ecdsa_sign(key, data, len + trailer_len, sig)) {
2799                 fprintf(stderr, "Error generating signature\n");
2800                 free(data);
2801                 ecdsa_free(key);
2802                 return 1;
2803         }
2804
2805         b64encode(sig, sig, 64);
2806         ecdsa_free(key);
2807
2808         fprintf(stdout, "Signature = %s %ld %s\n", name, t, sig);
2809         fwrite(data, len, 1, stdout);
2810
2811         free(data);
2812         return 0;
2813 }
2814
2815 static int cmd_verify(int argc, char *argv[]) {
2816         if(argc < 2) {
2817                 fprintf(stderr, "Not enough arguments!\n");
2818                 return 1;
2819         }
2820
2821         if(argc > 3) {
2822                 fprintf(stderr, "Too many arguments!\n");
2823                 return 1;
2824         }
2825
2826         char *node = argv[1];
2827
2828         if(!strcmp(node, ".")) {
2829                 if(!name) {
2830                         name = get_my_name(true);
2831
2832                         if(!name) {
2833                                 return 1;
2834                         }
2835                 }
2836
2837                 node = name;
2838         } else if(!strcmp(node, "*")) {
2839                 node = NULL;
2840         } else {
2841                 if(!check_id(node)) {
2842                         fprintf(stderr, "Invalid node name\n");
2843                         return 1;
2844                 }
2845         }
2846
2847         FILE *in;
2848
2849         if(argc == 3) {
2850                 in = fopen(argv[2], "rb");
2851
2852                 if(!in) {
2853                         fprintf(stderr, "Could not open %s: %s\n", argv[2], strerror(errno));
2854                         return 1;
2855                 }
2856         } else {
2857                 in = stdin;
2858         }
2859
2860         size_t len;
2861         char *data = readfile(in, &len);
2862
2863         if(in != stdin) {
2864                 fclose(in);
2865         }
2866
2867         if(!data) {
2868                 fprintf(stderr, "Error reading %s: %s\n", argv[1], strerror(errno));
2869                 return 1;
2870         }
2871
2872         char *newline = memchr(data, '\n', len);
2873
2874         if(!newline || (newline - data > MAX_STRING_SIZE - 1)) {
2875                 fprintf(stderr, "Invalid input\n");
2876                 free(data);
2877                 return 1;
2878         }
2879
2880         *newline++ = '\0';
2881         size_t skip = newline - data;
2882
2883         char signer[MAX_STRING_SIZE] = "";
2884         char sig[MAX_STRING_SIZE] = "";
2885         long t = 0;
2886
2887         if(sscanf(data, "Signature = %s %ld %s", signer, &t, sig) != 3 || strlen(sig) != 86 || !t || !check_id(signer)) {
2888                 fprintf(stderr, "Invalid input\n");
2889                 free(data);
2890                 return 1;
2891         }
2892
2893         if(node && strcmp(node, signer)) {
2894                 fprintf(stderr, "Signature is not made by %s\n", node);
2895                 free(data);
2896                 return 1;
2897         }
2898
2899         if(!node) {
2900                 node = signer;
2901         }
2902
2903         char *trailer;
2904         xasprintf(&trailer, " %s %ld", signer, t);
2905         size_t trailer_len = strlen(trailer);
2906
2907         data = xrealloc(data, len + trailer_len);
2908         memcpy(data + len, trailer, trailer_len);
2909         free(trailer);
2910
2911         newline = data + skip;
2912
2913         char fname[PATH_MAX];
2914         snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, node);
2915         FILE *fp = fopen(fname, "r");
2916
2917         if(!fp) {
2918                 fprintf(stderr, "Could not open %s: %s\n", fname, strerror(errno));
2919                 free(data);
2920                 return 1;
2921         }
2922
2923         ecdsa_t *key = get_pubkey(fp);
2924
2925         if(!key) {
2926                 rewind(fp);
2927                 key = ecdsa_read_pem_public_key(fp);
2928         }
2929
2930         if(!key) {
2931                 fprintf(stderr, "Could not read public key from %s\n", fname);
2932                 fclose(fp);
2933                 free(data);
2934                 return 1;
2935         }
2936
2937         fclose(fp);
2938
2939         if(b64decode(sig, sig, 86) != 64 || !ecdsa_verify(key, newline, len + trailer_len - (newline - data), sig)) {
2940                 fprintf(stderr, "Invalid signature\n");
2941                 free(data);
2942                 ecdsa_free(key);
2943                 return 1;
2944         }
2945
2946         ecdsa_free(key);
2947
2948         fwrite(newline, len - (newline - data), 1, stdout);
2949
2950         free(data);
2951         return 0;
2952 }
2953
2954 static const struct {
2955         const char *command;
2956         int (*function)(int argc, char *argv[]);
2957         bool hidden;
2958 } commands[] = {
2959         {"start", cmd_start, false},
2960         {"stop", cmd_stop, false},
2961         {"restart", cmd_restart, false},
2962         {"reload", cmd_reload, false},
2963         {"dump", cmd_dump, false},
2964         {"list", cmd_dump, false},
2965         {"purge", cmd_purge, false},
2966         {"debug", cmd_debug, false},
2967         {"retry", cmd_retry, false},
2968         {"connect", cmd_connect, false},
2969         {"disconnect", cmd_disconnect, false},
2970         {"top", cmd_top, false},
2971         {"pcap", cmd_pcap, false},
2972         {"log", cmd_log, false},
2973         {"pid", cmd_pid, false},
2974         {"config", cmd_config, true},
2975         {"add", cmd_config, false},
2976         {"del", cmd_config, false},
2977         {"get", cmd_config, false},
2978         {"set", cmd_config, false},
2979         {"init", cmd_init, false},
2980         {"generate-keys", cmd_generate_keys, false},
2981 #ifndef DISABLE_LEGACY
2982         {"generate-rsa-keys", cmd_generate_rsa_keys, false},
2983 #endif
2984         {"generate-ed25519-keys", cmd_generate_ed25519_keys, false},
2985         {"help", cmd_help, false},
2986         {"version", cmd_version, false},
2987         {"info", cmd_info, false},
2988         {"edit", cmd_edit, false},
2989         {"export", cmd_export, false},
2990         {"export-all", cmd_export_all, false},
2991         {"import", cmd_import, false},
2992         {"exchange", cmd_exchange, false},
2993         {"exchange-all", cmd_exchange_all, false},
2994         {"invite", cmd_invite, false},
2995         {"join", cmd_join, false},
2996         {"network", cmd_network, false},
2997         {"fsck", cmd_fsck, false},
2998         {"sign", cmd_sign, false},
2999         {"verify", cmd_verify, false},
3000         {NULL, NULL, false},
3001 };
3002
3003 #ifdef HAVE_READLINE
3004 static char *complete_command(const char *text, int state) {
3005         static int i;
3006
3007         if(!state) {
3008                 i = 0;
3009         } else {
3010                 i++;
3011         }
3012
3013         while(commands[i].command) {
3014                 if(!commands[i].hidden && !strncasecmp(commands[i].command, text, strlen(text))) {
3015                         return xstrdup(commands[i].command);
3016                 }
3017
3018                 i++;
3019         }
3020
3021         return NULL;
3022 }
3023
3024 static char *complete_dump(const char *text, int state) {
3025         const char *matches[] = {"reachable", "nodes", "edges", "subnets", "connections", "graph", NULL};
3026         static int i;
3027
3028         if(!state) {
3029                 i = 0;
3030         } else {
3031                 i++;
3032         }
3033
3034         while(matches[i]) {
3035                 if(!strncasecmp(matches[i], text, strlen(text))) {
3036                         return xstrdup(matches[i]);
3037                 }
3038
3039                 i++;
3040         }
3041
3042         return NULL;
3043 }
3044
3045 static char *complete_config(const char *text, int state) {
3046         static int i;
3047
3048         if(!state) {
3049                 i = 0;
3050         } else {
3051                 i++;
3052         }
3053
3054         while(variables[i].name) {
3055                 char *dot = strchr(text, '.');
3056
3057                 if(dot) {
3058                         if((variables[i].type & VAR_HOST) && !strncasecmp(variables[i].name, dot + 1, strlen(dot + 1))) {
3059                                 char *match;
3060                                 xasprintf(&match, "%.*s.%s", (int)(dot - text), text, variables[i].name);
3061                                 return match;
3062                         }
3063                 } else {
3064                         if(!strncasecmp(variables[i].name, text, strlen(text))) {
3065                                 return xstrdup(variables[i].name);
3066                         }
3067                 }
3068
3069                 i++;
3070         }
3071
3072         return NULL;
3073 }
3074
3075 static char *complete_info(const char *text, int state) {
3076         static int i;
3077
3078         if(!state) {
3079                 i = 0;
3080
3081                 if(!connect_tincd(false)) {
3082                         return NULL;
3083                 }
3084
3085                 // Check the list of nodes
3086                 sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES);
3087                 sendline(fd, "%d %d", CONTROL, REQ_DUMP_SUBNETS);
3088         }
3089
3090         while(recvline(fd, line, sizeof(line))) {
3091                 char item[4096];
3092                 int n = sscanf(line, "%d %d %4095s", &code, &req, item);
3093
3094                 if(n == 2) {
3095                         i++;
3096
3097                         if(i >= 2) {
3098                                 break;
3099                         } else {
3100                                 continue;
3101                         }
3102                 }
3103
3104                 if(n != 3) {
3105                         fprintf(stderr, "Unable to parse dump from tincd, n = %d, i = %d.\n", n, i);
3106                         break;
3107                 }
3108
3109                 if(!strncmp(item, text, strlen(text))) {
3110                         return xstrdup(strip_weight(item));
3111                 }
3112         }
3113
3114         return NULL;
3115 }
3116
3117 static char *complete_nothing(const char *text, int state) {
3118         (void)text;
3119         (void)state;
3120         return NULL;
3121 }
3122
3123 static char **completion(const char *text, int start, int end) {
3124         (void)end;
3125         char **matches = NULL;
3126
3127         if(!start) {
3128                 matches = rl_completion_matches(text, complete_command);
3129         } else if(!strncasecmp(rl_line_buffer, "dump ", 5)) {
3130                 matches = rl_completion_matches(text, complete_dump);
3131         } else if(!strncasecmp(rl_line_buffer, "add ", 4)) {
3132                 matches = rl_completion_matches(text, complete_config);
3133         } else if(!strncasecmp(rl_line_buffer, "del ", 4)) {
3134                 matches = rl_completion_matches(text, complete_config);
3135         } else if(!strncasecmp(rl_line_buffer, "get ", 4)) {
3136                 matches = rl_completion_matches(text, complete_config);
3137         } else if(!strncasecmp(rl_line_buffer, "set ", 4)) {
3138                 matches = rl_completion_matches(text, complete_config);
3139         } else if(!strncasecmp(rl_line_buffer, "info ", 5)) {
3140                 matches = rl_completion_matches(text, complete_info);
3141         }
3142
3143         return matches;
3144 }
3145 #endif
3146
3147 static int cmd_shell(int argc, char *argv[]) {
3148         xasprintf(&prompt, "%s> ", identname);
3149         int result = 0;
3150         char buf[4096];
3151         char *line = NULL;
3152         int maxargs = argc + 16;
3153         char **nargv = xmalloc(maxargs * sizeof(*nargv));
3154
3155         for(int i = 0; i < argc; i++) {
3156                 nargv[i] = argv[i];
3157         }
3158
3159 #ifdef HAVE_READLINE
3160         rl_readline_name = "tinc";
3161         rl_completion_entry_function = complete_nothing;
3162         rl_attempted_completion_function = completion;
3163         rl_filename_completion_desired = 0;
3164         char *copy = NULL;
3165 #endif
3166
3167         while(true) {
3168 #ifdef HAVE_READLINE
3169
3170                 if(tty) {
3171                         free(copy);
3172                         free(line);
3173                         rl_basic_word_break_characters = "\t\n ";
3174                         line = readline(prompt);
3175                         copy = line ? xstrdup(line) : NULL;
3176                 } else {
3177                         line = fgets(buf, sizeof(buf), stdin);
3178                 }
3179
3180 #else
3181
3182                 if(tty) {
3183                         fputs(prompt, stdout);
3184                 }
3185
3186                 line = fgets(buf, sizeof(buf), stdin);
3187 #endif
3188
3189                 if(!line) {
3190                         break;
3191                 }
3192
3193                 /* Ignore comments */
3194
3195                 if(*line == '#') {
3196                         continue;
3197                 }
3198
3199                 /* Split */
3200
3201                 int nargc = argc;
3202                 char *p = line + strspn(line, " \t\n");
3203                 char *next = strtok(p, " \t\n");
3204
3205                 while(p && *p) {
3206                         if(nargc >= maxargs) {
3207                                 maxargs *= 2;
3208                                 nargv = xrealloc(nargv, maxargs * sizeof(*nargv));
3209                         }
3210
3211                         nargv[nargc++] = p;
3212                         p = next;
3213                         next = strtok(NULL, " \t\n");
3214                 }
3215
3216                 if(nargc == argc) {
3217                         continue;
3218                 }
3219
3220                 if(!strcasecmp(nargv[argc], "exit") || !strcasecmp(nargv[argc], "quit")) {
3221 #ifdef HAVE_READLINE
3222                         free(copy);
3223 #endif
3224                         free(nargv);
3225                         return result;
3226                 }
3227
3228                 bool found = false;
3229
3230                 for(int i = 0; commands[i].command; i++) {
3231                         if(!strcasecmp(nargv[argc], commands[i].command)) {
3232                                 result |= commands[i].function(nargc - argc - 1, nargv + argc + 1);
3233                                 found = true;
3234                                 break;
3235                         }
3236                 }
3237
3238 #ifdef HAVE_READLINE
3239
3240                 if(tty && found) {
3241                         add_history(copy);
3242                 }
3243
3244 #endif
3245
3246                 if(!found) {
3247                         fprintf(stderr, "Unknown command `%s'.\n", nargv[argc]);
3248                         result |= 1;
3249                 }
3250         }
3251
3252 #ifdef HAVE_READLINE
3253         free(copy);
3254 #endif
3255         free(nargv);
3256
3257         if(tty) {
3258                 printf("\n");
3259         }
3260
3261         return result;
3262 }
3263
3264 static void cleanup() {
3265         free(tinc_conf);
3266         free(hosts_dir);
3267         free_names();
3268 }
3269
3270 int main(int argc, char *argv[]) {
3271         program_name = argv[0];
3272         orig_argv = argv;
3273         tty = isatty(0) && isatty(1);
3274
3275         if(!parse_options(argc, argv)) {
3276                 return 1;
3277         }
3278
3279         make_names(false);
3280         xasprintf(&tinc_conf, "%s" SLASH "tinc.conf", confbase);
3281         xasprintf(&hosts_dir, "%s" SLASH "hosts", confbase);
3282         atexit(cleanup);
3283
3284         if(show_version) {
3285                 version();
3286                 return 0;
3287         }
3288
3289         if(show_help) {
3290                 usage(false);
3291                 return 0;
3292         }
3293
3294 #ifdef HAVE_MINGW
3295         static struct WSAData wsa_state;
3296
3297         if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) {
3298                 fprintf(stderr, "System call `%s' failed: %s\n", "WSAStartup", winerror(GetLastError()));
3299                 return false;
3300         }
3301
3302 #endif
3303
3304         gettimeofday(&now, NULL);
3305         srand(now.tv_sec + now.tv_usec);
3306         crypto_init();
3307
3308         if(optind >= argc) {
3309                 return cmd_shell(argc, argv);
3310         }
3311
3312         for(int i = 0; commands[i].command; i++) {
3313                 if(!strcasecmp(argv[optind], commands[i].command)) {
3314                         return commands[i].function(argc - optind, argv + optind);
3315                 }
3316         }
3317
3318         fprintf(stderr, "Unknown command `%s'.\n", argv[optind]);
3319         usage(true);
3320         return 1;
3321 }