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