Reformat all code using astyle.
[tinc] / src / tincctl.c
1 /*
2     tincctl.c -- Controlling a running tincd
3     Copyright (C) 2007-2017 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-2017 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
726         manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
727
728         if(!manager) {
729                 fprintf(stderr, "Could not open service manager: %s\n", winerror(GetLastError()));
730                 return false;
731         }
732
733         service = OpenService(manager, identname, SERVICE_ALL_ACCESS);
734
735         if(!service) {
736                 fprintf(stderr, "Could not open %s service: %s\n", identname, winerror(GetLastError()));
737                 return false;
738         }
739
740         if(!ControlService(service, SERVICE_CONTROL_STOP, &status)) {
741                 fprintf(stderr, "Could not stop %s service: %s\n", identname, winerror(GetLastError()));
742         } else {
743                 fprintf(stderr, "%s service stopped\n", identname);
744         }
745
746         if(!DeleteService(service)) {
747                 fprintf(stderr, "Could not remove %s service: %s\n", identname, winerror(GetLastError()));
748                 return false;
749         }
750
751         fprintf(stderr, "%s service removed\n", identname);
752
753         return true;
754 }
755 #endif
756
757 bool connect_tincd(bool verbose) {
758         if(fd >= 0) {
759                 fd_set r;
760                 FD_ZERO(&r);
761                 FD_SET(fd, &r);
762                 struct timeval tv = {0, 0};
763
764                 if(select(fd + 1, &r, NULL, NULL, &tv)) {
765                         fprintf(stderr, "Previous connection to tincd lost, reconnecting.\n");
766                         close(fd);
767                         fd = -1;
768                 } else {
769                         return true;
770                 }
771         }
772
773         FILE *f = fopen(pidfilename, "r");
774
775         if(!f) {
776                 if(verbose) {
777                         fprintf(stderr, "Could not open pid file %s: %s\n", pidfilename, strerror(errno));
778                 }
779
780                 return false;
781         }
782
783         char host[129];
784         char port[129];
785
786         if(fscanf(f, "%20d %1024s %128s port %128s", &pid, controlcookie, host, port) != 4) {
787                 if(verbose) {
788                         fprintf(stderr, "Could not parse pid file %s\n", pidfilename);
789                 }
790
791                 fclose(f);
792                 return false;
793         }
794
795         fclose(f);
796
797 #ifndef HAVE_MINGW
798
799         if((pid == 0) || (kill(pid, 0) && (errno == ESRCH))) {
800                 fprintf(stderr, "Could not find tincd running at pid %d\n", pid);
801                 /* clean up the stale socket and pid file */
802                 unlink(pidfilename);
803                 unlink(unixsocketname);
804                 return false;
805         }
806
807         struct sockaddr_un sa;
808
809         sa.sun_family = AF_UNIX;
810
811         strncpy(sa.sun_path, unixsocketname, sizeof(sa.sun_path));
812
813         fd = socket(AF_UNIX, SOCK_STREAM, 0);
814
815         if(fd < 0) {
816                 if(verbose) {
817                         fprintf(stderr, "Cannot create UNIX socket: %s\n", sockstrerror(sockerrno));
818                 }
819
820                 return false;
821         }
822
823         if(connect(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
824                 if(verbose) {
825                         fprintf(stderr, "Cannot connect to UNIX socket %s: %s\n", unixsocketname, sockstrerror(sockerrno));
826                 }
827
828                 close(fd);
829                 fd = -1;
830                 return false;
831         }
832
833 #else
834         struct addrinfo hints = {
835                 .ai_family = AF_UNSPEC,
836                 .ai_socktype = SOCK_STREAM,
837                 .ai_protocol = IPPROTO_TCP,
838                 .ai_flags = 0,
839         };
840
841         struct addrinfo *res = NULL;
842
843         if(getaddrinfo(host, port, &hints, &res) || !res) {
844                 if(verbose) {
845                         fprintf(stderr, "Cannot resolve %s port %s: %s", host, port, sockstrerror(sockerrno));
846                 }
847
848                 return false;
849         }
850
851         fd = socket(res->ai_family, SOCK_STREAM, IPPROTO_TCP);
852
853         if(fd < 0) {
854                 if(verbose) {
855                         fprintf(stderr, "Cannot create TCP socket: %s\n", sockstrerror(sockerrno));
856                 }
857
858                 return false;
859         }
860
861 #ifdef HAVE_MINGW
862         unsigned long arg = 0;
863
864         if(ioctlsocket(fd, FIONBIO, &arg) != 0) {
865                 if(verbose) {
866                         fprintf(stderr, "ioctlsocket failed: %s", sockstrerror(sockerrno));
867                 }
868         }
869
870 #endif
871
872         if(connect(fd, res->ai_addr, res->ai_addrlen) < 0) {
873                 if(verbose) {
874                         fprintf(stderr, "Cannot connect to %s port %s: %s\n", host, port, sockstrerror(sockerrno));
875                 }
876
877                 close(fd);
878                 fd = -1;
879                 return false;
880         }
881
882         freeaddrinfo(res);
883 #endif
884
885 #ifdef SO_NOSIGPIPE
886         static const int one = 1;
887         setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&one, sizeof(one));
888 #endif
889
890         char data[4096];
891         int version;
892
893         if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %4095s %d", &code, data, &version) != 3 || code != 0) {
894                 if(verbose) {
895                         fprintf(stderr, "Cannot read greeting from control socket: %s\n", sockstrerror(sockerrno));
896                 }
897
898                 close(fd);
899                 fd = -1;
900                 return false;
901         }
902
903         sendline(fd, "%d ^%s %d", ID, controlcookie, TINC_CTL_VERSION_CURRENT);
904
905         if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &version, &pid) != 3 || code != 4 || version != TINC_CTL_VERSION_CURRENT) {
906                 if(verbose) {
907                         fprintf(stderr, "Could not fully establish control socket connection\n");
908                 }
909
910                 close(fd);
911                 fd = -1;
912                 return false;
913         }
914
915         return true;
916 }
917
918
919 static int cmd_start(int argc, char *argv[]) {
920         if(connect_tincd(false)) {
921                 if(netname) {
922                         fprintf(stderr, "A tincd is already running for net `%s' with pid %d.\n", netname, pid);
923                 } else {
924                         fprintf(stderr, "A tincd is already running with pid %d.\n", pid);
925                 }
926
927                 return 0;
928         }
929
930         char *c;
931         char *slash = strrchr(program_name, '/');
932
933 #ifdef HAVE_MINGW
934
935         if((c = strrchr(program_name, '\\')) > slash) {
936                 slash = c;
937         }
938
939 #endif
940
941         if(slash++) {
942                 xasprintf(&c, "%.*stincd", (int)(slash - program_name), program_name);
943         } else {
944                 c = "tincd";
945         }
946
947         int nargc = 0;
948         char **nargv = xzalloc((optind + argc) * sizeof(*nargv));
949
950         char *arg0 = c;
951 #ifdef HAVE_MINGW
952         /*
953            Windows has no real concept of an "argv array". A command line is just one string.
954            The CRT of the new process will decode the command line string to generate argv before calling main(), and (by convention)
955            it uses quotes to handle spaces in arguments.
956            Therefore we need to quote all arguments that might contain spaces. No, execvp() won't do that for us (see MSDN).
957            If we don't do that, then execvp() will run fine but any spaces in the filename contained in arg0 will bleed
958            into the next arguments when the spawned process' CRT parses its command line, resulting in chaos.
959         */
960         xasprintf(&arg0, "\"%s\"", arg0);
961 #endif
962         nargv[nargc++] = arg0;
963
964         for(int i = 1; i < optind; i++) {
965                 nargv[nargc++] = orig_argv[i];
966         }
967
968         for(int i = 1; i < argc; i++) {
969                 nargv[nargc++] = argv[i];
970         }
971
972 #ifdef HAVE_MINGW
973         int status = spawnvp(_P_WAIT, c, nargv);
974
975         if(status == -1) {
976                 fprintf(stderr, "Error starting %s: %s\n", c, strerror(errno));
977                 return 1;
978         }
979
980         return status;
981 #else
982         int pfd[2] = {-1, -1};
983
984         if(socketpair(AF_UNIX, SOCK_STREAM, 0, pfd)) {
985                 fprintf(stderr, "Could not create umbilical socket: %s\n", strerror(errno));
986                 free(nargv);
987                 return 1;
988         }
989
990         pid_t pid = fork();
991
992         if(pid == -1) {
993                 fprintf(stderr, "Could not fork: %s\n", strerror(errno));
994                 free(nargv);
995                 return 1;
996         }
997
998         if(!pid) {
999                 close(pfd[0]);
1000                 char buf[100];
1001                 snprintf(buf, sizeof(buf), "%d", pfd[1]);
1002                 setenv("TINC_UMBILICAL", buf, true);
1003                 exit(execvp(c, nargv));
1004         } else {
1005                 close(pfd[1]);
1006         }
1007
1008         free(nargv);
1009
1010         int status = -1, result;
1011 #ifdef SIGINT
1012         signal(SIGINT, SIG_IGN);
1013 #endif
1014
1015         // Pass all log messages from the umbilical to stderr.
1016         // A nul-byte right before closure means tincd started succesfully.
1017         bool failure = true;
1018         char buf[1024];
1019         ssize_t len;
1020
1021         while((len = read(pfd[0], buf, sizeof(buf))) > 0) {
1022                 failure = buf[len - 1];
1023
1024                 if(!failure) {
1025                         len--;
1026                 }
1027
1028                 write(2, buf, len);
1029         }
1030
1031         if(len) {
1032                 failure = true;
1033         }
1034
1035         close(pfd[0]);
1036
1037         // Make sure the child process is really gone.
1038         result = waitpid(pid, &status, 0);
1039
1040 #ifdef SIGINT
1041         signal(SIGINT, SIG_DFL);
1042 #endif
1043
1044         if(failure || result != pid || !WIFEXITED(status) || WEXITSTATUS(status)) {
1045                 fprintf(stderr, "Error starting %s\n", c);
1046                 return 1;
1047         }
1048
1049         return 0;
1050 #endif
1051 }
1052
1053 static int cmd_stop(int argc, char *argv[]) {
1054         if(argc > 1) {
1055                 fprintf(stderr, "Too many arguments!\n");
1056                 return 1;
1057         }
1058
1059 #ifndef HAVE_MINGW
1060
1061         if(!connect_tincd(true)) {
1062                 if(pid) {
1063                         if(kill(pid, SIGTERM)) {
1064                                 fprintf(stderr, "Could not send TERM signal to process with PID %d: %s\n", pid, strerror(errno));
1065                                 return 1;
1066                         }
1067
1068                         fprintf(stderr, "Sent TERM signal to process with PID %d.\n", pid);
1069                         waitpid(pid, NULL, 0);
1070                         return 0;
1071                 }
1072
1073                 return 1;
1074         }
1075
1076         sendline(fd, "%d %d", CONTROL, REQ_STOP);
1077
1078         while(recvline(fd, line, sizeof(line))) {
1079                 // Wait for tincd to close the connection...
1080         }
1081
1082 #else
1083
1084         if(!remove_service()) {
1085                 return 1;
1086         }
1087
1088 #endif
1089         close(fd);
1090         pid = 0;
1091         fd = -1;
1092
1093         return 0;
1094 }
1095
1096 static int cmd_restart(int argc, char *argv[]) {
1097         cmd_stop(1, argv);
1098         return cmd_start(argc, argv);
1099 }
1100
1101 static int cmd_reload(int argc, char *argv[]) {
1102         if(argc > 1) {
1103                 fprintf(stderr, "Too many arguments!\n");
1104                 return 1;
1105         }
1106
1107         if(!connect_tincd(true)) {
1108                 return 1;
1109         }
1110
1111         sendline(fd, "%d %d", CONTROL, REQ_RELOAD);
1112
1113         if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_RELOAD || result) {
1114                 fprintf(stderr, "Could not reload configuration.\n");
1115                 return 1;
1116         }
1117
1118         return 0;
1119
1120 }
1121
1122 static int dump_invitations(void) {
1123         char dname[PATH_MAX];
1124         snprintf(dname, sizeof(dname), "%s" SLASH "invitations", confbase);
1125         DIR *dir = opendir(dname);
1126
1127         if(!dir) {
1128                 if(errno == ENOENT) {
1129                         fprintf(stderr, "No outstanding invitations.\n");
1130                         return 0;
1131                 }
1132
1133                 fprintf(stderr, "Cannot not read directory %s: %s\n", dname, strerror(errno));
1134                 return 1;
1135         }
1136
1137         struct dirent *ent;
1138
1139         bool found = false;
1140
1141         while((ent = readdir(dir))) {
1142                 char buf[MAX_STRING_SIZE];
1143
1144                 if(b64decode(ent->d_name, buf, 24) != 18) {
1145                         continue;
1146                 }
1147
1148                 char fname[PATH_MAX];
1149                 snprintf(fname, sizeof(fname), "%s" SLASH "%s", dname, ent->d_name);
1150                 FILE *f = fopen(fname, "r");
1151
1152                 if(!f) {
1153                         fprintf(stderr, "Cannot open %s: %s\n", fname, strerror(errno));
1154                         continue;
1155                 }
1156
1157                 buf[0] = 0;
1158
1159                 if(!fgets(buf, sizeof(buf), f)) {
1160                         fprintf(stderr, "Invalid invitation file %s", fname);
1161                         fclose(f);
1162                         continue;
1163                 }
1164
1165                 fclose(f);
1166
1167                 char *eol = buf + strlen(buf);
1168
1169                 while(strchr("\t \r\n", *--eol)) {
1170                         *eol = 0;
1171                 }
1172
1173                 if(strncmp(buf, "Name = ", 7) || !check_id(buf + 7)) {
1174                         fprintf(stderr, "Invalid invitation file %s", fname);
1175                         continue;
1176                 }
1177
1178                 found = true;
1179                 printf("%s %s\n", ent->d_name, buf + 7);
1180         }
1181
1182         closedir(dir);
1183
1184         if(!found) {
1185                 fprintf(stderr, "No outstanding invitations.\n");
1186         }
1187
1188         return 0;
1189 }
1190
1191 static int cmd_dump(int argc, char *argv[]) {
1192         bool only_reachable = false;
1193
1194         if(argc > 2 && !strcasecmp(argv[1], "reachable")) {
1195                 if(strcasecmp(argv[2], "nodes")) {
1196                         fprintf(stderr, "`reachable' only supported for nodes.\n");
1197                         usage(true);
1198                         return 1;
1199                 }
1200
1201                 only_reachable = true;
1202                 argv++;
1203                 argc--;
1204         }
1205
1206         if(argc != 2) {
1207                 fprintf(stderr, "Invalid number of arguments.\n");
1208                 usage(true);
1209                 return 1;
1210         }
1211
1212         if(!strcasecmp(argv[1], "invitations")) {
1213                 return dump_invitations();
1214         }
1215
1216         if(!connect_tincd(true)) {
1217                 return 1;
1218         }
1219
1220         int do_graph = 0;
1221
1222         if(!strcasecmp(argv[1], "nodes")) {
1223                 sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES);
1224         } else if(!strcasecmp(argv[1], "edges")) {
1225                 sendline(fd, "%d %d", CONTROL, REQ_DUMP_EDGES);
1226         } else if(!strcasecmp(argv[1], "subnets")) {
1227                 sendline(fd, "%d %d", CONTROL, REQ_DUMP_SUBNETS);
1228         } else if(!strcasecmp(argv[1], "connections")) {
1229                 sendline(fd, "%d %d", CONTROL, REQ_DUMP_CONNECTIONS);
1230         } else if(!strcasecmp(argv[1], "graph")) {
1231                 sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES);
1232                 sendline(fd, "%d %d", CONTROL, REQ_DUMP_EDGES);
1233                 do_graph = 1;
1234         } else if(!strcasecmp(argv[1], "digraph")) {
1235                 sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES);
1236                 sendline(fd, "%d %d", CONTROL, REQ_DUMP_EDGES);
1237                 do_graph = 2;
1238         } else {
1239                 fprintf(stderr, "Unknown dump type '%s'.\n", argv[1]);
1240                 usage(true);
1241                 return 1;
1242         }
1243
1244         if(do_graph == 1) {
1245                 printf("graph {\n");
1246         } else if(do_graph == 2) {
1247                 printf("digraph {\n");
1248         }
1249
1250         while(recvline(fd, line, sizeof(line))) {
1251                 char node1[4096], node2[4096];
1252                 int n = sscanf(line, "%d %d %4095s %4095s", &code, &req, node1, node2);
1253
1254                 if(n == 2) {
1255                         if(do_graph && req == REQ_DUMP_NODES) {
1256                                 continue;
1257                         } else {
1258                                 if(do_graph) {
1259                                         printf("}\n");
1260                                 }
1261
1262                                 return 0;
1263                         }
1264                 }
1265
1266                 if(n < 2) {
1267                         break;
1268                 }
1269
1270                 char node[4096];
1271                 char id[4096];
1272                 char from[4096];
1273                 char to[4096];
1274                 char subnet[4096];
1275                 char host[4096];
1276                 char port[4096];
1277                 char local_host[4096];
1278                 char local_port[4096];
1279                 char via[4096];
1280                 char nexthop[4096];
1281                 int cipher, digest, maclength, compression, distance, socket, weight;
1282                 short int pmtu, minmtu, maxmtu;
1283                 unsigned int options, status_int;
1284                 node_status_t status;
1285                 long int last_state_change;
1286
1287                 switch(req) {
1288                 case REQ_DUMP_NODES: {
1289                         int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %d %d %d %d %x %x %4095s %4095s %d %hd %hd %hd %ld", node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_int, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change);
1290
1291                         if(n != 17) {
1292                                 fprintf(stderr, "Unable to parse node dump from tincd: %s\n", line);
1293                                 return 1;
1294                         }
1295
1296                         memcpy(&status, &status_int, sizeof(status));
1297
1298                         if(do_graph) {
1299                                 const char *color = "black";
1300
1301                                 if(!strcmp(host, "MYSELF")) {
1302                                         color = "green";
1303                                 } else if(!status.reachable) {
1304                                         color = "red";
1305                                 } else if(strcmp(via, node)) {
1306                                         color = "orange";
1307                                 } else if(!status.validkey) {
1308                                         color = "black";
1309                                 } else if(minmtu > 0) {
1310                                         color = "green";
1311                                 }
1312
1313                                 printf(" %s [label = \"%s\", color = \"%s\"%s];\n", node, node, color, strcmp(host, "MYSELF") ? "" : ", style = \"filled\"");
1314                         } else {
1315                                 if(only_reachable && !status.reachable) {
1316                                         continue;
1317                                 }
1318
1319                                 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)\n",
1320                                        node, id, host, port, cipher, digest, maclength, compression, options, status_int, nexthop, via, distance, pmtu, minmtu, maxmtu);
1321                         }
1322                 }
1323                 break;
1324
1325                 case REQ_DUMP_EDGES: {
1326                         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);
1327
1328                         if(n != 8) {
1329                                 fprintf(stderr, "Unable to parse edge dump from tincd.\n");
1330                                 return 1;
1331                         }
1332
1333                         if(do_graph) {
1334                                 float w = 1 + 65536.0 / weight;
1335
1336                                 if(do_graph == 1 && strcmp(node1, node2) > 0) {
1337                                         printf(" %s -- %s [w = %f, weight = %f];\n", node1, node2, w, w);
1338                                 } else if(do_graph == 2) {
1339                                         printf(" %s -> %s [w = %f, weight = %f];\n", node1, node2, w, w);
1340                                 }
1341                         } else {
1342                                 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);
1343                         }
1344                 }
1345                 break;
1346
1347                 case REQ_DUMP_SUBNETS: {
1348                         int n = sscanf(line, "%*d %*d %4095s %4095s", subnet, node);
1349
1350                         if(n != 2) {
1351                                 fprintf(stderr, "Unable to parse subnet dump from tincd.\n");
1352                                 return 1;
1353                         }
1354
1355                         printf("%s owner %s\n", strip_weight(subnet), node);
1356                 }
1357                 break;
1358
1359                 case REQ_DUMP_CONNECTIONS: {
1360                         int n = sscanf(line, "%*d %*d %4095s %4095s port %4095s %x %d %x", node, host, port, &options, &socket, &status_int);
1361
1362                         if(n != 6) {
1363                                 fprintf(stderr, "Unable to parse connection dump from tincd.\n");
1364                                 return 1;
1365                         }
1366
1367                         printf("%s at %s port %s options %x socket %d status %x\n", node, host, port, options, socket, status_int);
1368                 }
1369                 break;
1370
1371                 default:
1372                         fprintf(stderr, "Unable to parse dump from tincd.\n");
1373                         return 1;
1374                 }
1375         }
1376
1377         fprintf(stderr, "Error receiving dump.\n");
1378         return 1;
1379 }
1380
1381 static int cmd_purge(int argc, char *argv[]) {
1382         if(argc > 1) {
1383                 fprintf(stderr, "Too many arguments!\n");
1384                 return 1;
1385         }
1386
1387         if(!connect_tincd(true)) {
1388                 return 1;
1389         }
1390
1391         sendline(fd, "%d %d", CONTROL, REQ_PURGE);
1392
1393         if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_PURGE || result) {
1394                 fprintf(stderr, "Could not purge old information.\n");
1395                 return 1;
1396         }
1397
1398         return 0;
1399 }
1400
1401 static int cmd_debug(int argc, char *argv[]) {
1402         if(argc != 2) {
1403                 fprintf(stderr, "Invalid number of arguments.\n");
1404                 return 1;
1405         }
1406
1407         if(!connect_tincd(true)) {
1408                 return 1;
1409         }
1410
1411         int debuglevel = atoi(argv[1]);
1412         int origlevel;
1413
1414         sendline(fd, "%d %d %d", CONTROL, REQ_SET_DEBUG, debuglevel);
1415
1416         if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &origlevel) != 3 || code != CONTROL || req != REQ_SET_DEBUG) {
1417                 fprintf(stderr, "Could not set debug level.\n");
1418                 return 1;
1419         }
1420
1421         fprintf(stderr, "Old level %d, new level %d.\n", origlevel, debuglevel);
1422         return 0;
1423 }
1424
1425 static int cmd_retry(int argc, char *argv[]) {
1426         if(argc > 1) {
1427                 fprintf(stderr, "Too many arguments!\n");
1428                 return 1;
1429         }
1430
1431         if(!connect_tincd(true)) {
1432                 return 1;
1433         }
1434
1435         sendline(fd, "%d %d", CONTROL, REQ_RETRY);
1436
1437         if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_RETRY || result) {
1438                 fprintf(stderr, "Could not retry outgoing connections.\n");
1439                 return 1;
1440         }
1441
1442         return 0;
1443 }
1444
1445 static int cmd_connect(int argc, char *argv[]) {
1446         if(argc != 2) {
1447                 fprintf(stderr, "Invalid number of arguments.\n");
1448                 return 1;
1449         }
1450
1451         if(!check_id(argv[1])) {
1452                 fprintf(stderr, "Invalid name for node.\n");
1453                 return 1;
1454         }
1455
1456         if(!connect_tincd(true)) {
1457                 return 1;
1458         }
1459
1460         sendline(fd, "%d %d %s", CONTROL, REQ_CONNECT, argv[1]);
1461
1462         if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_CONNECT || result) {
1463                 fprintf(stderr, "Could not connect to %s.\n", argv[1]);
1464                 return 1;
1465         }
1466
1467         return 0;
1468 }
1469
1470 static int cmd_disconnect(int argc, char *argv[]) {
1471         if(argc != 2) {
1472                 fprintf(stderr, "Invalid number of arguments.\n");
1473                 return 1;
1474         }
1475
1476         if(!check_id(argv[1])) {
1477                 fprintf(stderr, "Invalid name for node.\n");
1478                 return 1;
1479         }
1480
1481         if(!connect_tincd(true)) {
1482                 return 1;
1483         }
1484
1485         sendline(fd, "%d %d %s", CONTROL, REQ_DISCONNECT, argv[1]);
1486
1487         if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_DISCONNECT || result) {
1488                 fprintf(stderr, "Could not disconnect %s.\n", argv[1]);
1489                 return 1;
1490         }
1491
1492         return 0;
1493 }
1494
1495 static int cmd_top(int argc, char *argv[]) {
1496         if(argc > 1) {
1497                 fprintf(stderr, "Too many arguments!\n");
1498                 return 1;
1499         }
1500
1501 #ifdef HAVE_CURSES
1502
1503         if(!connect_tincd(true)) {
1504                 return 1;
1505         }
1506
1507         top(fd);
1508         return 0;
1509 #else
1510         fprintf(stderr, "This version of tinc was compiled without support for the curses library.\n");
1511         return 1;
1512 #endif
1513 }
1514
1515 static int cmd_pcap(int argc, char *argv[]) {
1516         if(argc > 2) {
1517                 fprintf(stderr, "Too many arguments!\n");
1518                 return 1;
1519         }
1520
1521         if(!connect_tincd(true)) {
1522                 return 1;
1523         }
1524
1525         pcap(fd, stdout, argc > 1 ? atoi(argv[1]) : 0);
1526         return 0;
1527 }
1528
1529 #ifdef SIGINT
1530 static void sigint_handler(int sig) {
1531         fprintf(stderr, "\n");
1532         shutdown(fd, SHUT_RDWR);
1533 }
1534 #endif
1535
1536 static int cmd_log(int argc, char *argv[]) {
1537         if(argc > 2) {
1538                 fprintf(stderr, "Too many arguments!\n");
1539                 return 1;
1540         }
1541
1542         if(!connect_tincd(true)) {
1543                 return 1;
1544         }
1545
1546 #ifdef SIGINT
1547         signal(SIGINT, sigint_handler);
1548 #endif
1549
1550         logcontrol(fd, stdout, argc > 1 ? atoi(argv[1]) : -1);
1551
1552 #ifdef SIGINT
1553         signal(SIGINT, SIG_DFL);
1554 #endif
1555
1556         close(fd);
1557         fd = -1;
1558         return 0;
1559 }
1560
1561 static int cmd_pid(int argc, char *argv[]) {
1562         if(argc > 1) {
1563                 fprintf(stderr, "Too many arguments!\n");
1564                 return 1;
1565         }
1566
1567         if(!connect_tincd(true) || !pid) {
1568                 return 1;
1569         }
1570
1571         printf("%d\n", pid);
1572         return 0;
1573 }
1574
1575 int rstrip(char *value) {
1576         int len = strlen(value);
1577
1578         while(len && strchr("\t\r\n ", value[len - 1])) {
1579                 value[--len] = 0;
1580         }
1581
1582         return len;
1583 }
1584
1585 char *get_my_name(bool verbose) {
1586         FILE *f = fopen(tinc_conf, "r");
1587
1588         if(!f) {
1589                 if(verbose) {
1590                         fprintf(stderr, "Could not open %s: %s\n", tinc_conf, strerror(errno));
1591                 }
1592
1593                 return NULL;
1594         }
1595
1596         char buf[4096];
1597         char *value;
1598
1599         while(fgets(buf, sizeof(buf), f)) {
1600                 int len = strcspn(buf, "\t =");
1601                 value = buf + len;
1602                 value += strspn(value, "\t ");
1603
1604                 if(*value == '=') {
1605                         value++;
1606                         value += strspn(value, "\t ");
1607                 }
1608
1609                 if(!rstrip(value)) {
1610                         continue;
1611                 }
1612
1613                 buf[len] = 0;
1614
1615                 if(strcasecmp(buf, "Name")) {
1616                         continue;
1617                 }
1618
1619                 if(*value) {
1620                         fclose(f);
1621                         return replace_name(value);
1622                 }
1623         }
1624
1625         fclose(f);
1626
1627         if(verbose) {
1628                 fprintf(stderr, "Could not find Name in %s.\n", tinc_conf);
1629         }
1630
1631         return NULL;
1632 }
1633
1634 ecdsa_t *get_pubkey(FILE *f) {
1635         char buf[4096];
1636         char *value;
1637
1638         while(fgets(buf, sizeof(buf), f)) {
1639                 int len = strcspn(buf, "\t =");
1640                 value = buf + len;
1641                 value += strspn(value, "\t ");
1642
1643                 if(*value == '=') {
1644                         value++;
1645                         value += strspn(value, "\t ");
1646                 }
1647
1648                 if(!rstrip(value)) {
1649                         continue;
1650                 }
1651
1652                 buf[len] = 0;
1653
1654                 if(strcasecmp(buf, "Ed25519PublicKey")) {
1655                         continue;
1656                 }
1657
1658                 if(*value) {
1659                         return ecdsa_set_base64_public_key(value);
1660                 }
1661         }
1662
1663         return NULL;
1664 }
1665
1666 const var_t variables[] = {
1667         /* Server configuration */
1668         {"AddressFamily", VAR_SERVER},
1669         {"AutoConnect", VAR_SERVER | VAR_SAFE},
1670         {"BindToAddress", VAR_SERVER | VAR_MULTIPLE},
1671         {"BindToInterface", VAR_SERVER},
1672         {"Broadcast", VAR_SERVER | VAR_SAFE},
1673         {"BroadcastSubnet", VAR_SERVER | VAR_MULTIPLE | VAR_SAFE},
1674         {"ConnectTo", VAR_SERVER | VAR_MULTIPLE | VAR_SAFE},
1675         {"DecrementTTL", VAR_SERVER},
1676         {"Device", VAR_SERVER},
1677         {"DeviceStandby", VAR_SERVER},
1678         {"DeviceType", VAR_SERVER},
1679         {"DirectOnly", VAR_SERVER},
1680         {"Ed25519PrivateKeyFile", VAR_SERVER},
1681         {"ExperimentalProtocol", VAR_SERVER},
1682         {"Forwarding", VAR_SERVER},
1683         {"GraphDumpFile", VAR_SERVER | VAR_OBSOLETE},
1684         {"Hostnames", VAR_SERVER},
1685         {"IffOneQueue", VAR_SERVER},
1686         {"Interface", VAR_SERVER},
1687         {"InvitationExpire", VAR_SERVER},
1688         {"KeyExpire", VAR_SERVER},
1689         {"ListenAddress", VAR_SERVER | VAR_MULTIPLE},
1690         {"LocalDiscovery", VAR_SERVER},
1691         {"LogLevel", VAR_SERVER},
1692         {"MACExpire", VAR_SERVER},
1693         {"MaxConnectionBurst", VAR_SERVER},
1694         {"MaxOutputBufferSize", VAR_SERVER},
1695         {"MaxTimeout", VAR_SERVER},
1696         {"Mode", VAR_SERVER | VAR_SAFE},
1697         {"Name", VAR_SERVER},
1698         {"PingInterval", VAR_SERVER},
1699         {"PingTimeout", VAR_SERVER},
1700         {"PriorityInheritance", VAR_SERVER},
1701         {"PrivateKey", VAR_SERVER | VAR_OBSOLETE},
1702         {"PrivateKeyFile", VAR_SERVER},
1703         {"ProcessPriority", VAR_SERVER},
1704         {"Proxy", VAR_SERVER},
1705         {"ReplayWindow", VAR_SERVER},
1706         {"ScriptsExtension", VAR_SERVER},
1707         {"ScriptsInterpreter", VAR_SERVER},
1708         {"StrictSubnets", VAR_SERVER},
1709         {"TunnelServer", VAR_SERVER},
1710         {"UDPDiscovery", VAR_SERVER},
1711         {"UDPDiscoveryKeepaliveInterval", VAR_SERVER},
1712         {"UDPDiscoveryInterval", VAR_SERVER},
1713         {"UDPDiscoveryTimeout", VAR_SERVER},
1714         {"MTUInfoInterval", VAR_SERVER},
1715         {"UDPInfoInterval", VAR_SERVER},
1716         {"UDPRcvBuf", VAR_SERVER},
1717         {"UDPSndBuf", VAR_SERVER},
1718         {"UPnP", VAR_SERVER},
1719         {"UPnPDiscoverWait", VAR_SERVER},
1720         {"UPnPRefreshPeriod", VAR_SERVER},
1721         {"VDEGroup", VAR_SERVER},
1722         {"VDEPort", VAR_SERVER},
1723         /* Host configuration */
1724         {"Address", VAR_HOST | VAR_MULTIPLE},
1725         {"Cipher", VAR_SERVER | VAR_HOST},
1726         {"ClampMSS", VAR_SERVER | VAR_HOST},
1727         {"Compression", VAR_SERVER | VAR_HOST},
1728         {"Digest", VAR_SERVER | VAR_HOST},
1729         {"Ed25519PublicKey", VAR_HOST},
1730         {"Ed25519PublicKeyFile", VAR_SERVER | VAR_HOST},
1731         {"IndirectData", VAR_SERVER | VAR_HOST},
1732         {"MACLength", VAR_SERVER | VAR_HOST},
1733         {"PMTU", VAR_SERVER | VAR_HOST},
1734         {"PMTUDiscovery", VAR_SERVER | VAR_HOST},
1735         {"Port", VAR_HOST},
1736         {"PublicKey", VAR_HOST | VAR_OBSOLETE},
1737         {"PublicKeyFile", VAR_SERVER | VAR_HOST | VAR_OBSOLETE},
1738         {"Subnet", VAR_HOST | VAR_MULTIPLE | VAR_SAFE},
1739         {"TCPOnly", VAR_SERVER | VAR_HOST},
1740         {"Weight", VAR_HOST | VAR_SAFE},
1741         {NULL, 0}
1742 };
1743
1744 static int cmd_config(int argc, char *argv[]) {
1745         if(argc < 2) {
1746                 fprintf(stderr, "Invalid number of arguments.\n");
1747                 return 1;
1748         }
1749
1750         if(strcasecmp(argv[0], "config")) {
1751                 argv--, argc++;
1752         }
1753
1754         int action = -2;
1755
1756         if(!strcasecmp(argv[1], "get")) {
1757                 argv++, argc--;
1758         } else if(!strcasecmp(argv[1], "add")) {
1759                 argv++, argc--, action = 1;
1760         } else if(!strcasecmp(argv[1], "del")) {
1761                 argv++, argc--, action = -1;
1762         } else if(!strcasecmp(argv[1], "replace") || !strcasecmp(argv[1], "set") || !strcasecmp(argv[1], "change")) {
1763                 argv++, argc--, action = 0;
1764         }
1765
1766         if(argc < 2) {
1767                 fprintf(stderr, "Invalid number of arguments.\n");
1768                 return 1;
1769         }
1770
1771         // Concatenate the rest of the command line
1772         strncpy(line, argv[1], sizeof(line) - 1);
1773
1774         for(int i = 2; i < argc; i++) {
1775                 strncat(line, " ", sizeof(line) - 1 - strlen(line));
1776                 strncat(line, argv[i], sizeof(line) - 1 - strlen(line));
1777         }
1778
1779         // Liberal parsing into node name, variable name and value.
1780         char *node = NULL;
1781         char *variable;
1782         char *value;
1783         int len;
1784
1785         len = strcspn(line, "\t =");
1786         value = line + len;
1787         value += strspn(value, "\t ");
1788
1789         if(*value == '=') {
1790                 value++;
1791                 value += strspn(value, "\t ");
1792         }
1793
1794         line[len] = '\0';
1795         variable = strchr(line, '.');
1796
1797         if(variable) {
1798                 node = line;
1799                 *variable++ = 0;
1800         } else {
1801                 variable = line;
1802         }
1803
1804         if(!*variable) {
1805                 fprintf(stderr, "No variable given.\n");
1806                 return 1;
1807         }
1808
1809         if(action >= 0 && !*value) {
1810                 fprintf(stderr, "No value for variable given.\n");
1811                 return 1;
1812         }
1813
1814         if(action < -1 && *value) {
1815                 action = 0;
1816         }
1817
1818         /* Some simple checks. */
1819         bool found = false;
1820         bool warnonremove = false;
1821
1822         for(int i = 0; variables[i].name; i++) {
1823                 if(strcasecmp(variables[i].name, variable)) {
1824                         continue;
1825                 }
1826
1827                 found = true;
1828                 variable = (char *)variables[i].name;
1829
1830                 /* Discourage use of obsolete variables. */
1831
1832                 if(variables[i].type & VAR_OBSOLETE && action >= 0) {
1833                         if(force) {
1834                                 fprintf(stderr, "Warning: %s is an obsolete variable!\n", variable);
1835                         } else {
1836                                 fprintf(stderr, "%s is an obsolete variable! Use --force to use it anyway.\n", variable);
1837                                 return 1;
1838                         }
1839                 }
1840
1841                 /* Don't put server variables in host config files */
1842
1843                 if(node && !(variables[i].type & VAR_HOST) && action >= 0) {
1844                         if(force) {
1845                                 fprintf(stderr, "Warning: %s is not a host configuration variable!\n", variable);
1846                         } else {
1847                                 fprintf(stderr, "%s is not a host configuration variable! Use --force to use it anyway.\n", variable);
1848                                 return 1;
1849                         }
1850                 }
1851
1852                 /* Should this go into our own host config file? */
1853
1854                 if(!node && !(variables[i].type & VAR_SERVER)) {
1855                         node = get_my_name(true);
1856
1857                         if(!node) {
1858                                 return 1;
1859                         }
1860                 }
1861
1862                 /* Change "add" into "set" for variables that do not allow multiple occurences.
1863                    Turn on warnings when it seems variables might be removed unintentionally. */
1864
1865                 if(action == 1 && !(variables[i].type & VAR_MULTIPLE)) {
1866                         warnonremove = true;
1867                         action = 0;
1868                 } else if(action == 0 && (variables[i].type & VAR_MULTIPLE)) {
1869                         warnonremove = true;
1870                 }
1871
1872                 break;
1873         }
1874
1875         if(node && !check_id(node)) {
1876                 fprintf(stderr, "Invalid name for node.\n");
1877                 return 1;
1878         }
1879
1880         if(!found) {
1881                 if(force || action < 0) {
1882                         fprintf(stderr, "Warning: %s is not a known configuration variable!\n", variable);
1883                 } else {
1884                         fprintf(stderr, "%s: is not a known configuration variable! Use --force to use it anyway.\n", variable);
1885                         return 1;
1886                 }
1887         }
1888
1889         // Open the right configuration file.
1890         char filename[PATH_MAX];
1891
1892         if(node) {
1893                 snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, node);
1894         } else {
1895                 snprintf(filename, sizeof(filename), "%s", tinc_conf);
1896         }
1897
1898         FILE *f = fopen(filename, "r");
1899
1900         if(!f) {
1901                 fprintf(stderr, "Could not open configuration file %s: %s\n", filename, strerror(errno));
1902                 return 1;
1903         }
1904
1905         char tmpfile[PATH_MAX];
1906         FILE *tf = NULL;
1907
1908         if(action >= -1) {
1909                 snprintf(tmpfile, sizeof(tmpfile), "%s.config.tmp", filename);
1910                 tf = fopen(tmpfile, "w");
1911
1912                 if(!tf) {
1913                         fprintf(stderr, "Could not open temporary file %s: %s\n", tmpfile, strerror(errno));
1914                         fclose(f);
1915                         return 1;
1916                 }
1917         }
1918
1919         // Copy the file, making modifications on the fly, unless we are just getting a value.
1920         char buf1[4096];
1921         char buf2[4096];
1922         bool set = false;
1923         bool removed = false;
1924         found = false;
1925
1926         while(fgets(buf1, sizeof(buf1), f)) {
1927                 buf1[sizeof(buf1) - 1] = 0;
1928                 strncpy(buf2, buf1, sizeof(buf2));
1929
1930                 // Parse line in a simple way
1931                 char *bvalue;
1932                 int len;
1933
1934                 len = strcspn(buf2, "\t =");
1935                 bvalue = buf2 + len;
1936                 bvalue += strspn(bvalue, "\t ");
1937
1938                 if(*bvalue == '=') {
1939                         bvalue++;
1940                         bvalue += strspn(bvalue, "\t ");
1941                 }
1942
1943                 rstrip(bvalue);
1944                 buf2[len] = '\0';
1945
1946                 // Did it match?
1947                 if(!strcasecmp(buf2, variable)) {
1948                         // Get
1949                         if(action < -1) {
1950                                 found = true;
1951                                 printf("%s\n", bvalue);
1952                                 // Del
1953                         } else if(action == -1) {
1954                                 if(!*value || !strcasecmp(bvalue, value)) {
1955                                         removed = true;
1956                                         continue;
1957                                 }
1958
1959                                 // Set
1960                         } else if(action == 0) {
1961                                 // Warn if "set" was used for variables that can occur multiple times
1962                                 if(warnonremove && strcasecmp(bvalue, value)) {
1963                                         fprintf(stderr, "Warning: removing %s = %s\n", variable, bvalue);
1964                                 }
1965
1966                                 // Already set? Delete the rest...
1967                                 if(set) {
1968                                         continue;
1969                                 }
1970
1971                                 // Otherwise, replace.
1972                                 if(fprintf(tf, "%s = %s\n", variable, value) < 0) {
1973                                         fprintf(stderr, "Error writing to temporary file %s: %s\n", tmpfile, strerror(errno));
1974                                         return 1;
1975                                 }
1976
1977                                 set = true;
1978                                 continue;
1979                                 // Add
1980                         } else if(action > 0) {
1981                                 // Check if we've already seen this variable with the same value
1982                                 if(!strcasecmp(bvalue, value)) {
1983                                         found = true;
1984                                 }
1985                         }
1986                 }
1987
1988                 if(action >= -1) {
1989                         // Copy original line...
1990                         if(fputs(buf1, tf) < 0) {
1991                                 fprintf(stderr, "Error writing to temporary file %s: %s\n", tmpfile, strerror(errno));
1992                                 return 1;
1993                         }
1994
1995                         // Add newline if it is missing...
1996                         if(*buf1 && buf1[strlen(buf1) - 1] != '\n') {
1997                                 if(fputc('\n', tf) < 0) {
1998                                         fprintf(stderr, "Error writing to temporary file %s: %s\n", tmpfile, strerror(errno));
1999                                         return 1;
2000                                 }
2001                         }
2002                 }
2003         }
2004
2005         // Make sure we read everything...
2006         if(ferror(f) || !feof(f)) {
2007                 fprintf(stderr, "Error while reading from configuration file %s: %s\n", filename, strerror(errno));
2008                 return 1;
2009         }
2010
2011         if(fclose(f)) {
2012                 fprintf(stderr, "Error closing configuration file %s: %s\n", filename, strerror(errno));
2013                 return 1;
2014         }
2015
2016         // Add new variable if necessary.
2017         if((action > 0 && !found) || (action == 0 && !set)) {
2018                 if(fprintf(tf, "%s = %s\n", variable, value) < 0) {
2019                         fprintf(stderr, "Error writing to temporary file %s: %s\n", tmpfile, strerror(errno));
2020                         return 1;
2021                 }
2022         }
2023
2024         if(action < -1) {
2025                 if(found) {
2026                         return 0;
2027                 } else {
2028                         fprintf(stderr, "No matching configuration variables found.\n");
2029                         return 1;
2030                 }
2031         }
2032
2033         // Make sure we wrote everything...
2034         if(fclose(tf)) {
2035                 fprintf(stderr, "Error closing temporary file %s: %s\n", tmpfile, strerror(errno));
2036                 return 1;
2037         }
2038
2039         // Could we find what we had to remove?
2040         if(action < 0 && !removed) {
2041                 remove(tmpfile);
2042                 fprintf(stderr, "No configuration variables deleted.\n");
2043                 return 1;
2044         }
2045
2046         // Replace the configuration file with the new one
2047 #ifdef HAVE_MINGW
2048
2049         if(remove(filename)) {
2050                 fprintf(stderr, "Error replacing file %s: %s\n", filename, strerror(errno));
2051                 return 1;
2052         }
2053
2054 #endif
2055
2056         if(rename(tmpfile, filename)) {
2057                 fprintf(stderr, "Error renaming temporary file %s to configuration file %s: %s\n", tmpfile, filename, strerror(errno));
2058                 return 1;
2059         }
2060
2061         // Silently try notifying a running tincd of changes.
2062         if(connect_tincd(false)) {
2063                 sendline(fd, "%d %d", CONTROL, REQ_RELOAD);
2064         }
2065
2066         return 0;
2067 }
2068
2069 static bool try_bind(int port) {
2070         struct addrinfo *ai = NULL, *aip;
2071         struct addrinfo hint = {
2072                 .ai_flags = AI_PASSIVE,
2073                 .ai_family = AF_UNSPEC,
2074                 .ai_socktype = SOCK_STREAM,
2075                 .ai_protocol = IPPROTO_TCP,
2076         };
2077
2078         bool success = true;
2079         char portstr[16];
2080         snprintf(portstr, sizeof(portstr), "%d", port);
2081
2082         if(getaddrinfo(NULL, portstr, &hint, &ai) || !ai) {
2083                 return false;
2084         }
2085
2086         for(aip = ai; aip; aip = aip->ai_next) {
2087                 int fd = socket(ai->ai_family, SOCK_STREAM, IPPROTO_TCP);
2088
2089                 if(!fd) {
2090                         success = false;
2091                         break;
2092                 }
2093
2094                 int result = bind(fd, ai->ai_addr, ai->ai_addrlen);
2095                 closesocket(fd);
2096
2097                 if(result) {
2098                         success = false;
2099                         break;
2100                 }
2101         }
2102
2103         freeaddrinfo(ai);
2104         return success;
2105 }
2106
2107 int check_port(char *name) {
2108         if(try_bind(655)) {
2109                 return 655;
2110         }
2111
2112         fprintf(stderr, "Warning: could not bind to port 655. ");
2113
2114         for(int i = 0; i < 100; i++) {
2115                 int port = 0x1000 + (rand() & 0x7fff);
2116
2117                 if(try_bind(port)) {
2118                         char filename[PATH_MAX];
2119                         snprintf(filename, sizeof(filename), "%s" SLASH "hosts" SLASH "%s", confbase, name);
2120                         FILE *f = fopen(filename, "a");
2121
2122                         if(!f) {
2123                                 fprintf(stderr, "Could not open %s: %s\n", filename, strerror(errno));
2124                                 fprintf(stderr, "Please change tinc's Port manually.\n");
2125                                 return 0;
2126                         }
2127
2128                         fprintf(f, "Port = %d\n", port);
2129                         fclose(f);
2130                         fprintf(stderr, "Tinc will instead listen on port %d.\n", port);
2131                         return port;
2132                 }
2133         }
2134
2135         fprintf(stderr, "Please change tinc's Port manually.\n");
2136         return 0;
2137 }
2138
2139 static int cmd_init(int argc, char *argv[]) {
2140         if(!access(tinc_conf, F_OK)) {
2141                 fprintf(stderr, "Configuration file %s already exists!\n", tinc_conf);
2142                 return 1;
2143         }
2144
2145         if(argc > 2) {
2146                 fprintf(stderr, "Too many arguments!\n");
2147                 return 1;
2148         } else if(argc < 2) {
2149                 if(tty) {
2150                         char buf[1024];
2151                         fprintf(stderr, "Enter the Name you want your tinc node to have: ");
2152
2153                         if(!fgets(buf, sizeof(buf), stdin)) {
2154                                 fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno));
2155                                 return 1;
2156                         }
2157
2158                         int len = rstrip(buf);
2159
2160                         if(!len) {
2161                                 fprintf(stderr, "No name given!\n");
2162                                 return 1;
2163                         }
2164
2165                         name = strdup(buf);
2166                 } else {
2167                         fprintf(stderr, "No Name given!\n");
2168                         return 1;
2169                 }
2170         } else {
2171                 name = strdup(argv[1]);
2172
2173                 if(!*name) {
2174                         fprintf(stderr, "No Name given!\n");
2175                         return 1;
2176                 }
2177         }
2178
2179         if(!check_id(name)) {
2180                 fprintf(stderr, "Invalid Name! Only a-z, A-Z, 0-9 and _ are allowed characters.\n");
2181                 return 1;
2182         }
2183
2184         if(!confbase_given && mkdir(confdir, 0755) && errno != EEXIST) {
2185                 fprintf(stderr, "Could not create directory %s: %s\n", confdir, strerror(errno));
2186                 return 1;
2187         }
2188
2189         if(mkdir(confbase, 0777) && errno != EEXIST) {
2190                 fprintf(stderr, "Could not create directory %s: %s\n", confbase, strerror(errno));
2191                 return 1;
2192         }
2193
2194         if(mkdir(hosts_dir, 0777) && errno != EEXIST) {
2195                 fprintf(stderr, "Could not create directory %s: %s\n", hosts_dir, strerror(errno));
2196                 return 1;
2197         }
2198
2199         FILE *f = fopen(tinc_conf, "w");
2200
2201         if(!f) {
2202                 fprintf(stderr, "Could not create file %s: %s\n", tinc_conf, strerror(errno));
2203                 return 1;
2204         }
2205
2206         fprintf(f, "Name = %s\n", name);
2207         fclose(f);
2208
2209 #ifndef DISABLE_LEGACY
2210
2211         if(!rsa_keygen(2048, false)) {
2212                 return 1;
2213         }
2214
2215 #endif
2216
2217         if(!ed25519_keygen(false)) {
2218                 return 1;
2219         }
2220
2221         check_port(name);
2222
2223 #ifndef HAVE_MINGW
2224         char filename[PATH_MAX];
2225         snprintf(filename, sizeof(filename), "%s" SLASH "tinc-up", confbase);
2226
2227         if(access(filename, F_OK)) {
2228                 FILE *f = fopenmask(filename, "w", 0777);
2229
2230                 if(!f) {
2231                         fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno));
2232                         return 1;
2233                 }
2234
2235                 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");
2236                 fclose(f);
2237         }
2238
2239 #endif
2240
2241         return 0;
2242
2243 }
2244
2245 static int cmd_generate_keys(int argc, char *argv[]) {
2246 #ifdef DISABLE_LEGACY
2247
2248         if(argc > 1) {
2249 #else
2250
2251         if(argc > 2) {
2252 #endif
2253                 fprintf(stderr, "Too many arguments!\n");
2254                 return 1;
2255         }
2256
2257         if(!name) {
2258                 name = get_my_name(false);
2259         }
2260
2261 #ifndef DISABLE_LEGACY
2262
2263         if(!rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true)) {
2264                 return 1;
2265         }
2266
2267 #endif
2268
2269         if(!ed25519_keygen(true)) {
2270                 return 1;
2271         }
2272
2273         return 0;
2274 }
2275
2276 #ifndef DISABLE_LEGACY
2277 static int cmd_generate_rsa_keys(int argc, char *argv[]) {
2278         if(argc > 2) {
2279                 fprintf(stderr, "Too many arguments!\n");
2280                 return 1;
2281         }
2282
2283         if(!name) {
2284                 name = get_my_name(false);
2285         }
2286
2287         return !rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true);
2288 }
2289 #endif
2290
2291 static int cmd_generate_ed25519_keys(int argc, char *argv[]) {
2292         if(argc > 1) {
2293                 fprintf(stderr, "Too many arguments!\n");
2294                 return 1;
2295         }
2296
2297         if(!name) {
2298                 name = get_my_name(false);
2299         }
2300
2301         return !ed25519_keygen(true);
2302 }
2303
2304 static int cmd_help(int argc, char *argv[]) {
2305         usage(false);
2306         return 0;
2307 }
2308
2309 static int cmd_version(int argc, char *argv[]) {
2310         if(argc > 1) {
2311                 fprintf(stderr, "Too many arguments!\n");
2312                 return 1;
2313         }
2314
2315         version();
2316         return 0;
2317 }
2318
2319 static int cmd_info(int argc, char *argv[]) {
2320         if(argc != 2) {
2321                 fprintf(stderr, "Invalid number of arguments.\n");
2322                 return 1;
2323         }
2324
2325         if(!connect_tincd(true)) {
2326                 return 1;
2327         }
2328
2329         return info(fd, argv[1]);
2330 }
2331
2332 static const char *conffiles[] = {
2333         "tinc.conf",
2334         "tinc-up",
2335         "tinc-down",
2336         "subnet-up",
2337         "subnet-down",
2338         "host-up",
2339         "host-down",
2340         NULL,
2341 };
2342
2343 static int cmd_edit(int argc, char *argv[]) {
2344         if(argc != 2) {
2345                 fprintf(stderr, "Invalid number of arguments.\n");
2346                 return 1;
2347         }
2348
2349         char filename[PATH_MAX] = "";
2350
2351         if(strncmp(argv[1], "hosts" SLASH, 6)) {
2352                 for(int i = 0; conffiles[i]; i++) {
2353                         if(!strcmp(argv[1], conffiles[i])) {
2354                                 snprintf(filename, sizeof(filename), "%s" SLASH "%s", confbase, argv[1]);
2355                                 break;
2356                         }
2357                 }
2358         } else {
2359                 argv[1] += 6;
2360         }
2361
2362         if(!*filename) {
2363                 snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, argv[1]);
2364                 char *dash = strchr(argv[1], '-');
2365
2366                 if(dash) {
2367                         *dash++ = 0;
2368
2369                         if((strcmp(dash, "up") && strcmp(dash, "down")) || !check_id(argv[1])) {
2370                                 fprintf(stderr, "Invalid configuration filename.\n");
2371                                 return 1;
2372                         }
2373                 }
2374         }
2375
2376         char *command;
2377 #ifndef HAVE_MINGW
2378         xasprintf(&command, "\"%s\" \"%s\"", getenv("VISUAL") ? : getenv("EDITOR") ? : "vi", filename);
2379 #else
2380         xasprintf(&command, "edit \"%s\"", filename);
2381 #endif
2382         int result = system(command);
2383         free(command);
2384
2385         if(result) {
2386                 return result;
2387         }
2388
2389         // Silently try notifying a running tincd of changes.
2390         if(connect_tincd(false)) {
2391                 sendline(fd, "%d %d", CONTROL, REQ_RELOAD);
2392         }
2393
2394         return 0;
2395 }
2396
2397 static int export(const char *name, FILE *out) {
2398         char filename[PATH_MAX];
2399         snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, name);
2400         FILE *in = fopen(filename, "r");
2401
2402         if(!in) {
2403                 fprintf(stderr, "Could not open configuration file %s: %s\n", filename, strerror(errno));
2404                 return 1;
2405         }
2406
2407         fprintf(out, "Name = %s\n", name);
2408         char buf[4096];
2409
2410         while(fgets(buf, sizeof(buf), in)) {
2411                 if(strcspn(buf, "\t =") != 4 || strncasecmp(buf, "Name", 4)) {
2412                         fputs(buf, out);
2413                 }
2414         }
2415
2416         if(ferror(in)) {
2417                 fprintf(stderr, "Error while reading configuration file %s: %s\n", filename, strerror(errno));
2418                 fclose(in);
2419                 return 1;
2420         }
2421
2422         fclose(in);
2423         return 0;
2424 }
2425
2426 static int cmd_export(int argc, char *argv[]) {
2427         if(argc > 1) {
2428                 fprintf(stderr, "Too many arguments!\n");
2429                 return 1;
2430         }
2431
2432         char *name = get_my_name(true);
2433
2434         if(!name) {
2435                 return 1;
2436         }
2437
2438         int result = export(name, stdout);
2439
2440         if(!tty) {
2441                 fclose(stdout);
2442         }
2443
2444         free(name);
2445         return result;
2446 }
2447
2448 static int cmd_export_all(int argc, char *argv[]) {
2449         if(argc > 1) {
2450                 fprintf(stderr, "Too many arguments!\n");
2451                 return 1;
2452         }
2453
2454         DIR *dir = opendir(hosts_dir);
2455
2456         if(!dir) {
2457                 fprintf(stderr, "Could not open host configuration directory %s: %s\n", hosts_dir, strerror(errno));
2458                 return 1;
2459         }
2460
2461         bool first = true;
2462         int result = 0;
2463         struct dirent *ent;
2464
2465         while((ent = readdir(dir))) {
2466                 if(!check_id(ent->d_name)) {
2467                         continue;
2468                 }
2469
2470                 if(first) {
2471                         first = false;
2472                 } else {
2473                         printf("#---------------------------------------------------------------#\n");
2474                 }
2475
2476                 result |= export(ent->d_name, stdout);
2477         }
2478
2479         closedir(dir);
2480
2481         if(!tty) {
2482                 fclose(stdout);
2483         }
2484
2485         return result;
2486 }
2487
2488 static int cmd_import(int argc, char *argv[]) {
2489         if(argc > 1) {
2490                 fprintf(stderr, "Too many arguments!\n");
2491                 return 1;
2492         }
2493
2494         FILE *in = stdin;
2495         FILE *out = NULL;
2496
2497         char buf[4096];
2498         char name[4096];
2499         char filename[PATH_MAX] = "";
2500         int count = 0;
2501         bool firstline = true;
2502
2503         while(fgets(buf, sizeof(buf), in)) {
2504                 if(sscanf(buf, "Name = %4095s", name) == 1) {
2505                         firstline = false;
2506
2507                         if(!check_id(name)) {
2508                                 fprintf(stderr, "Invalid Name in input!\n");
2509                                 return 1;
2510                         }
2511
2512                         if(out) {
2513                                 fclose(out);
2514                         }
2515
2516                         snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, name);
2517
2518                         if(!force && !access(filename, F_OK)) {
2519                                 fprintf(stderr, "Host configuration file %s already exists, skipping.\n", filename);
2520                                 out = NULL;
2521                                 continue;
2522                         }
2523
2524                         out = fopen(filename, "w");
2525
2526                         if(!out) {
2527                                 fprintf(stderr, "Error creating configuration file %s: %s\n", filename, strerror(errno));
2528                                 return 1;
2529                         }
2530
2531                         count++;
2532                         continue;
2533                 } else if(firstline) {
2534                         fprintf(stderr, "Junk at the beginning of the input, ignoring.\n");
2535                         firstline = false;
2536                 }
2537
2538
2539                 if(!strcmp(buf, "#---------------------------------------------------------------#\n")) {
2540                         continue;
2541                 }
2542
2543                 if(out) {
2544                         if(fputs(buf, out) < 0) {
2545                                 fprintf(stderr, "Error writing to host configuration file %s: %s\n", filename, strerror(errno));
2546                                 return 1;
2547                         }
2548                 }
2549         }
2550
2551         if(out) {
2552                 fclose(out);
2553         }
2554
2555         if(count) {
2556                 fprintf(stderr, "Imported %d host configuration files.\n", count);
2557                 return 0;
2558         } else {
2559                 fprintf(stderr, "No host configuration files imported.\n");
2560                 return 1;
2561         }
2562 }
2563
2564 static int cmd_exchange(int argc, char *argv[]) {
2565         return cmd_export(argc, argv) ? : cmd_import(argc, argv);
2566 }
2567
2568 static int cmd_exchange_all(int argc, char *argv[]) {
2569         return cmd_export_all(argc, argv) ? : cmd_import(argc, argv);
2570 }
2571
2572 static int switch_network(char *name) {
2573         if(strcmp(name, ".")) {
2574                 if(!check_netname(name, false)) {
2575                         fprintf(stderr, "Invalid character in netname!\n");
2576                         return 1;
2577                 }
2578
2579                 if(!check_netname(name, true)) {
2580                         fprintf(stderr, "Warning: unsafe character in netname!\n");
2581                 }
2582         }
2583
2584         if(fd >= 0) {
2585                 close(fd);
2586                 fd = -1;
2587         }
2588
2589         free_names();
2590         netname = strcmp(name, ".") ? xstrdup(name) : NULL;
2591         make_names(false);
2592
2593         free(tinc_conf);
2594         free(hosts_dir);
2595         free(prompt);
2596
2597         xasprintf(&tinc_conf, "%s" SLASH "tinc.conf", confbase);
2598         xasprintf(&hosts_dir, "%s" SLASH "hosts", confbase);
2599         xasprintf(&prompt, "%s> ", identname);
2600
2601         return 0;
2602 }
2603
2604 static int cmd_network(int argc, char *argv[]) {
2605         if(argc > 2) {
2606                 fprintf(stderr, "Too many arguments!\n");
2607                 return 1;
2608         }
2609
2610         if(argc == 2) {
2611                 return switch_network(argv[1]);
2612         }
2613
2614         DIR *dir = opendir(confdir);
2615
2616         if(!dir) {
2617                 fprintf(stderr, "Could not read directory %s: %s\n", confdir, strerror(errno));
2618                 return 1;
2619         }
2620
2621         struct dirent *ent;
2622
2623         while((ent = readdir(dir))) {
2624                 if(*ent->d_name == '.') {
2625                         continue;
2626                 }
2627
2628                 if(!strcmp(ent->d_name, "tinc.conf")) {
2629                         printf(".\n");
2630                         continue;
2631                 }
2632
2633                 char fname[PATH_MAX];
2634                 snprintf(fname, sizeof(fname), "%s/%s/tinc.conf", confdir, ent->d_name);
2635
2636                 if(!access(fname, R_OK)) {
2637                         printf("%s\n", ent->d_name);
2638                 }
2639         }
2640
2641         closedir(dir);
2642
2643         return 0;
2644 }
2645
2646 static int cmd_fsck(int argc, char *argv[]) {
2647         if(argc > 1) {
2648                 fprintf(stderr, "Too many arguments!\n");
2649                 return 1;
2650         }
2651
2652         return fsck(orig_argv[0]);
2653 }
2654
2655 static void *readfile(FILE *in, size_t *len) {
2656         size_t count = 0;
2657         size_t alloced = 4096;
2658         char *buf = xmalloc(alloced);
2659
2660         while(!feof(in)) {
2661                 size_t read = fread(buf + count, 1, alloced - count, in);
2662
2663                 if(!read) {
2664                         break;
2665                 }
2666
2667                 count += read;
2668
2669                 if(count >= alloced) {
2670                         alloced *= 2;
2671                         buf = xrealloc(buf, alloced);
2672                 }
2673         }
2674
2675         if(len) {
2676                 *len = count;
2677         }
2678
2679         return buf;
2680 }
2681
2682 static int cmd_sign(int argc, char *argv[]) {
2683         if(argc > 2) {
2684                 fprintf(stderr, "Too many arguments!\n");
2685                 return 1;
2686         }
2687
2688         if(!name) {
2689                 name = get_my_name(true);
2690
2691                 if(!name) {
2692                         return 1;
2693                 }
2694         }
2695
2696         char fname[PATH_MAX];
2697         snprintf(fname, sizeof(fname), "%s" SLASH "ed25519_key.priv", confbase);
2698         FILE *fp = fopen(fname, "r");
2699
2700         if(!fp) {
2701                 fprintf(stderr, "Could not open %s: %s\n", fname, strerror(errno));
2702                 return 1;
2703         }
2704
2705         ecdsa_t *key = ecdsa_read_pem_private_key(fp);
2706
2707         if(!key) {
2708                 fprintf(stderr, "Could not read private key from %s\n", fname);
2709                 fclose(fp);
2710                 return 1;
2711         }
2712
2713         fclose(fp);
2714
2715         FILE *in;
2716
2717         if(argc == 2) {
2718                 in = fopen(argv[1], "rb");
2719
2720                 if(!in) {
2721                         fprintf(stderr, "Could not open %s: %s\n", argv[1], strerror(errno));
2722                         ecdsa_free(key);
2723                         return 1;
2724                 }
2725         } else {
2726                 in = stdin;
2727         }
2728
2729         size_t len;
2730         char *data = readfile(in, &len);
2731
2732         if(in != stdin) {
2733                 fclose(in);
2734         }
2735
2736         if(!data) {
2737                 fprintf(stderr, "Error reading %s: %s\n", argv[1], strerror(errno));
2738                 ecdsa_free(key);
2739                 return 1;
2740         }
2741
2742         // Ensure we sign our name and current time as well
2743         long t = time(NULL);
2744         char *trailer;
2745         xasprintf(&trailer, " %s %ld", name, t);
2746         int trailer_len = strlen(trailer);
2747
2748         data = xrealloc(data, len + trailer_len);
2749         memcpy(data + len, trailer, trailer_len);
2750         free(trailer);
2751
2752         char sig[87];
2753
2754         if(!ecdsa_sign(key, data, len + trailer_len, sig)) {
2755                 fprintf(stderr, "Error generating signature\n");
2756                 free(data);
2757                 ecdsa_free(key);
2758                 return 1;
2759         }
2760
2761         b64encode(sig, sig, 64);
2762         ecdsa_free(key);
2763
2764         fprintf(stdout, "Signature = %s %ld %s\n", name, t, sig);
2765         fwrite(data, len, 1, stdout);
2766
2767         free(data);
2768         return 0;
2769 }
2770
2771 static int cmd_verify(int argc, char *argv[]) {
2772         if(argc < 2) {
2773                 fprintf(stderr, "Not enough arguments!\n");
2774                 return 1;
2775         }
2776
2777         if(argc > 3) {
2778                 fprintf(stderr, "Too many arguments!\n");
2779                 return 1;
2780         }
2781
2782         char *node = argv[1];
2783
2784         if(!strcmp(node, ".")) {
2785                 if(!name) {
2786                         name = get_my_name(true);
2787
2788                         if(!name) {
2789                                 return 1;
2790                         }
2791                 }
2792
2793                 node = name;
2794         } else if(!strcmp(node, "*")) {
2795                 node = NULL;
2796         } else {
2797                 if(!check_id(node)) {
2798                         fprintf(stderr, "Invalid node name\n");
2799                         return 1;
2800                 }
2801         }
2802
2803         FILE *in;
2804
2805         if(argc == 3) {
2806                 in = fopen(argv[2], "rb");
2807
2808                 if(!in) {
2809                         fprintf(stderr, "Could not open %s: %s\n", argv[2], strerror(errno));
2810                         return 1;
2811                 }
2812         } else {
2813                 in = stdin;
2814         }
2815
2816         size_t len;
2817         char *data = readfile(in, &len);
2818
2819         if(in != stdin) {
2820                 fclose(in);
2821         }
2822
2823         if(!data) {
2824                 fprintf(stderr, "Error reading %s: %s\n", argv[1], strerror(errno));
2825                 return 1;
2826         }
2827
2828         char *newline = memchr(data, '\n', len);
2829
2830         if(!newline || (newline - data > MAX_STRING_SIZE - 1)) {
2831                 fprintf(stderr, "Invalid input\n");
2832                 free(data);
2833                 return 1;
2834         }
2835
2836         *newline++ = '\0';
2837         size_t skip = newline - data;
2838
2839         char signer[MAX_STRING_SIZE] = "";
2840         char sig[MAX_STRING_SIZE] = "";
2841         long t = 0;
2842
2843         if(sscanf(data, "Signature = %s %ld %s", signer, &t, sig) != 3 || strlen(sig) != 86 || !t || !check_id(signer)) {
2844                 fprintf(stderr, "Invalid input\n");
2845                 free(data);
2846                 return 1;
2847         }
2848
2849         if(node && strcmp(node, signer)) {
2850                 fprintf(stderr, "Signature is not made by %s\n", node);
2851                 free(data);
2852                 return 1;
2853         }
2854
2855         if(!node) {
2856                 node = signer;
2857         }
2858
2859         char *trailer;
2860         xasprintf(&trailer, " %s %ld", signer, t);
2861         int trailer_len = strlen(trailer);
2862
2863         data = xrealloc(data, len + trailer_len);
2864         memcpy(data + len, trailer, trailer_len);
2865         free(trailer);
2866
2867         newline = data + skip;
2868
2869         char fname[PATH_MAX];
2870         snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, node);
2871         FILE *fp = fopen(fname, "r");
2872
2873         if(!fp) {
2874                 fprintf(stderr, "Could not open %s: %s\n", fname, strerror(errno));
2875                 free(data);
2876                 return 1;
2877         }
2878
2879         ecdsa_t *key = get_pubkey(fp);
2880
2881         if(!key) {
2882                 rewind(fp);
2883                 key = ecdsa_read_pem_public_key(fp);
2884         }
2885
2886         if(!key) {
2887                 fprintf(stderr, "Could not read public key from %s\n", fname);
2888                 fclose(fp);
2889                 free(data);
2890                 return 1;
2891         }
2892
2893         fclose(fp);
2894
2895         if(b64decode(sig, sig, 86) != 64 || !ecdsa_verify(key, newline, len + trailer_len - (newline - data), sig)) {
2896                 fprintf(stderr, "Invalid signature\n");
2897                 free(data);
2898                 ecdsa_free(key);
2899                 return 1;
2900         }
2901
2902         ecdsa_free(key);
2903
2904         fwrite(newline, len - (newline - data), 1, stdout);
2905
2906         free(data);
2907         return 0;
2908 }
2909
2910 static const struct {
2911         const char *command;
2912         int (*function)(int argc, char *argv[]);
2913         bool hidden;
2914 } commands[] = {
2915         {"start", cmd_start},
2916         {"stop", cmd_stop},
2917         {"restart", cmd_restart},
2918         {"reload", cmd_reload},
2919         {"dump", cmd_dump},
2920         {"list", cmd_dump},
2921         {"purge", cmd_purge},
2922         {"debug", cmd_debug},
2923         {"retry", cmd_retry},
2924         {"connect", cmd_connect},
2925         {"disconnect", cmd_disconnect},
2926         {"top", cmd_top},
2927         {"pcap", cmd_pcap},
2928         {"log", cmd_log},
2929         {"pid", cmd_pid},
2930         {"config", cmd_config, true},
2931         {"add", cmd_config},
2932         {"del", cmd_config},
2933         {"get", cmd_config},
2934         {"set", cmd_config},
2935         {"init", cmd_init},
2936         {"generate-keys", cmd_generate_keys},
2937 #ifndef DISABLE_LEGACY
2938         {"generate-rsa-keys", cmd_generate_rsa_keys},
2939 #endif
2940         {"generate-ed25519-keys", cmd_generate_ed25519_keys},
2941         {"help", cmd_help},
2942         {"version", cmd_version},
2943         {"info", cmd_info},
2944         {"edit", cmd_edit},
2945         {"export", cmd_export},
2946         {"export-all", cmd_export_all},
2947         {"import", cmd_import},
2948         {"exchange", cmd_exchange},
2949         {"exchange-all", cmd_exchange_all},
2950         {"invite", cmd_invite},
2951         {"join", cmd_join},
2952         {"network", cmd_network},
2953         {"fsck", cmd_fsck},
2954         {"sign", cmd_sign},
2955         {"verify", cmd_verify},
2956         {NULL, NULL},
2957 };
2958
2959 #ifdef HAVE_READLINE
2960 static char *complete_command(const char *text, int state) {
2961         static int i;
2962
2963         if(!state) {
2964                 i = 0;
2965         } else {
2966                 i++;
2967         }
2968
2969         while(commands[i].command) {
2970                 if(!commands[i].hidden && !strncasecmp(commands[i].command, text, strlen(text))) {
2971                         return xstrdup(commands[i].command);
2972                 }
2973
2974                 i++;
2975         }
2976
2977         return NULL;
2978 }
2979
2980 static char *complete_dump(const char *text, int state) {
2981         const char *matches[] = {"reachable", "nodes", "edges", "subnets", "connections", "graph", NULL};
2982         static int i;
2983
2984         if(!state) {
2985                 i = 0;
2986         } else {
2987                 i++;
2988         }
2989
2990         while(matches[i]) {
2991                 if(!strncasecmp(matches[i], text, strlen(text))) {
2992                         return xstrdup(matches[i]);
2993                 }
2994
2995                 i++;
2996         }
2997
2998         return NULL;
2999 }
3000
3001 static char *complete_config(const char *text, int state) {
3002         static int i;
3003
3004         if(!state) {
3005                 i = 0;
3006         } else {
3007                 i++;
3008         }
3009
3010         while(variables[i].name) {
3011                 char *dot = strchr(text, '.');
3012
3013                 if(dot) {
3014                         if((variables[i].type & VAR_HOST) && !strncasecmp(variables[i].name, dot + 1, strlen(dot + 1))) {
3015                                 char *match;
3016                                 xasprintf(&match, "%.*s.%s", (int)(dot - text), text, variables[i].name);
3017                                 return match;
3018                         }
3019                 } else {
3020                         if(!strncasecmp(variables[i].name, text, strlen(text))) {
3021                                 return xstrdup(variables[i].name);
3022                         }
3023                 }
3024
3025                 i++;
3026         }
3027
3028         return NULL;
3029 }
3030
3031 static char *complete_info(const char *text, int state) {
3032         static int i;
3033
3034         if(!state) {
3035                 i = 0;
3036
3037                 if(!connect_tincd(false)) {
3038                         return NULL;
3039                 }
3040
3041                 // Check the list of nodes
3042                 sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES);
3043                 sendline(fd, "%d %d", CONTROL, REQ_DUMP_SUBNETS);
3044         }
3045
3046         while(recvline(fd, line, sizeof(line))) {
3047                 char item[4096];
3048                 int n = sscanf(line, "%d %d %4095s", &code, &req, item);
3049
3050                 if(n == 2) {
3051                         i++;
3052
3053                         if(i >= 2) {
3054                                 break;
3055                         } else {
3056                                 continue;
3057                         }
3058                 }
3059
3060                 if(n != 3) {
3061                         fprintf(stderr, "Unable to parse dump from tincd, n = %d, i = %d.\n", n, i);
3062                         break;
3063                 }
3064
3065                 if(!strncmp(item, text, strlen(text))) {
3066                         return xstrdup(strip_weight(item));
3067                 }
3068         }
3069
3070         return NULL;
3071 }
3072
3073 static char *complete_nothing(const char *text, int state) {
3074         return NULL;
3075 }
3076
3077 static char **completion(const char *text, int start, int end) {
3078         char **matches = NULL;
3079
3080         if(!start) {
3081                 matches = rl_completion_matches(text, complete_command);
3082         } else if(!strncasecmp(rl_line_buffer, "dump ", 5)) {
3083                 matches = rl_completion_matches(text, complete_dump);
3084         } else if(!strncasecmp(rl_line_buffer, "add ", 4)) {
3085                 matches = rl_completion_matches(text, complete_config);
3086         } else if(!strncasecmp(rl_line_buffer, "del ", 4)) {
3087                 matches = rl_completion_matches(text, complete_config);
3088         } else if(!strncasecmp(rl_line_buffer, "get ", 4)) {
3089                 matches = rl_completion_matches(text, complete_config);
3090         } else if(!strncasecmp(rl_line_buffer, "set ", 4)) {
3091                 matches = rl_completion_matches(text, complete_config);
3092         } else if(!strncasecmp(rl_line_buffer, "info ", 5)) {
3093                 matches = rl_completion_matches(text, complete_info);
3094         }
3095
3096         return matches;
3097 }
3098 #endif
3099
3100 static int cmd_shell(int argc, char *argv[]) {
3101         xasprintf(&prompt, "%s> ", identname);
3102         int result = 0;
3103         char buf[4096];
3104         char *line = NULL;
3105         int maxargs = argc + 16;
3106         char **nargv = xmalloc(maxargs * sizeof(*nargv));
3107
3108         for(int i = 0; i < argc; i++) {
3109                 nargv[i] = argv[i];
3110         }
3111
3112 #ifdef HAVE_READLINE
3113         rl_readline_name = "tinc";
3114         rl_completion_entry_function = complete_nothing;
3115         rl_attempted_completion_function = completion;
3116         rl_filename_completion_desired = 0;
3117         char *copy = NULL;
3118 #endif
3119
3120         while(true) {
3121 #ifdef HAVE_READLINE
3122
3123                 if(tty) {
3124                         free(copy);
3125                         free(line);
3126                         rl_basic_word_break_characters = "\t\n ";
3127                         line = readline(prompt);
3128
3129                         if(line) {
3130                                 copy = xstrdup(line);
3131                         }
3132                 } else {
3133                         line = fgets(buf, sizeof(buf), stdin);
3134                 }
3135
3136 #else
3137
3138                 if(tty) {
3139                         fputs(prompt, stdout);
3140                 }
3141
3142                 line = fgets(buf, sizeof(buf), stdin);
3143 #endif
3144
3145                 if(!line) {
3146                         break;
3147                 }
3148
3149                 /* Ignore comments */
3150
3151                 if(*line == '#') {
3152                         continue;
3153                 }
3154
3155                 /* Split */
3156
3157                 int nargc = argc;
3158                 char *p = line + strspn(line, " \t\n");
3159                 char *next = strtok(p, " \t\n");
3160
3161                 while(p && *p) {
3162                         if(nargc >= maxargs) {
3163                                 maxargs *= 2;
3164                                 nargv = xrealloc(nargv, maxargs * sizeof(*nargv));
3165                         }
3166
3167                         nargv[nargc++] = p;
3168                         p = next;
3169                         next = strtok(NULL, " \t\n");
3170                 }
3171
3172                 if(nargc == argc) {
3173                         continue;
3174                 }
3175
3176                 if(!strcasecmp(nargv[argc], "exit") || !strcasecmp(nargv[argc], "quit")) {
3177                         free(nargv);
3178                         return result;
3179                 }
3180
3181                 bool found = false;
3182
3183                 for(int i = 0; commands[i].command; i++) {
3184                         if(!strcasecmp(nargv[argc], commands[i].command)) {
3185                                 result |= commands[i].function(nargc - argc - 1, nargv + argc + 1);
3186                                 found = true;
3187                                 break;
3188                         }
3189                 }
3190
3191 #ifdef HAVE_READLINE
3192
3193                 if(tty && found) {
3194                         add_history(copy);
3195                 }
3196
3197 #endif
3198
3199                 if(!found) {
3200                         fprintf(stderr, "Unknown command `%s'.\n", nargv[argc]);
3201                         result |= 1;
3202                 }
3203         }
3204
3205         free(nargv);
3206
3207         if(tty) {
3208                 printf("\n");
3209         }
3210
3211         return result;
3212 }
3213
3214
3215 int main(int argc, char *argv[]) {
3216         program_name = argv[0];
3217         orig_argv = argv;
3218         orig_argc = argc;
3219         tty = isatty(0) && isatty(1);
3220
3221         if(!parse_options(argc, argv)) {
3222                 return 1;
3223         }
3224
3225         make_names(false);
3226         xasprintf(&tinc_conf, "%s" SLASH "tinc.conf", confbase);
3227         xasprintf(&hosts_dir, "%s" SLASH "hosts", confbase);
3228
3229         if(show_version) {
3230                 version();
3231                 return 0;
3232         }
3233
3234         if(show_help) {
3235                 usage(false);
3236                 return 0;
3237         }
3238
3239 #ifdef HAVE_MINGW
3240         static struct WSAData wsa_state;
3241
3242         if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) {
3243                 fprintf(stderr, "System call `%s' failed: %s", "WSAStartup", winerror(GetLastError()));
3244                 return false;
3245         }
3246
3247 #endif
3248
3249         srand(time(NULL));
3250         crypto_init();
3251
3252         if(optind >= argc) {
3253                 return cmd_shell(argc, argv);
3254         }
3255
3256         for(int i = 0; commands[i].command; i++) {
3257                 if(!strcasecmp(argv[optind], commands[i].command)) {
3258                         return commands[i].function(argc - optind, argv + optind);
3259                 }
3260         }
3261
3262         fprintf(stderr, "Unknown command `%s'.\n", argv[optind]);
3263         usage(true);
3264         return 1;
3265 }