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