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