X-Git-Url: https://www.tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Ftincctl.c;h=2fdab2a66a12a723096f361ad37ca52a28055ead;hb=a6448291834ca7419553a807ee367c719c2956d0;hp=cd2d3d8eab8806a42e01822548d4ea969660a2a5;hpb=696dc2ad9743c62e56a6d21addb8c4e8efbffec1;p=tinc diff --git a/src/tincctl.c b/src/tincctl.c index cd2d3d8e..2fdab2a6 100644 --- a/src/tincctl.c +++ b/src/tincctl.c @@ -1,6 +1,6 @@ /* tincctl.c -- Controlling a running tincd - Copyright (C) 2007-2017 Guus Sliepen + Copyright (C) 2007-2018 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -92,7 +92,7 @@ static struct option const long_options[] = { static void version(void) { printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE, BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR); - printf("Copyright (C) 1998-2017 Ivo Timmermans, Guus Sliepen and others.\n" + printf("Copyright (C) 1998-2018 Ivo Timmermans, Guus Sliepen and others.\n" "See the AUTHORS file for a complete list.\n\n" "tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n" "and you are welcome to redistribute it under certain conditions;\n" @@ -355,6 +355,8 @@ static FILE *ask_and_open(const char *filename, const char *what, const char *mo char buf[PATH_MAX]; char buf2[PATH_MAX]; +ask_filename: + /* Check stdin and stdout */ if(ask && tty) { /* Ask for a file and/or directory name. */ @@ -385,7 +387,17 @@ static FILE *ask_and_open(const char *filename, const char *what, const char *mo #endif /* The directory is a relative path or a filename. */ getcwd(directory, sizeof(directory)); - snprintf(buf2, sizeof(buf2), "%s" SLASH "%s", directory, filename); + + if(snprintf(buf2, sizeof(buf2), "%s" SLASH "%s", directory, filename) >= sizeof(buf2)) { + fprintf(stderr, "Filename too long: %s" SLASH "%s\n", directory, filename); + + if(ask && tty) { + goto ask_filename; + } else { + return NULL; + } + } + filename = buf2; } @@ -722,19 +734,20 @@ static bool remove_service(void) { SC_HANDLE manager = NULL; SC_HANDLE service = NULL; SERVICE_STATUS status = {0}; + bool success = false; manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if(!manager) { fprintf(stderr, "Could not open service manager: %s\n", winerror(GetLastError())); - return false; + goto exit; } service = OpenService(manager, identname, SERVICE_ALL_ACCESS); if(!service) { fprintf(stderr, "Could not open %s service: %s\n", identname, winerror(GetLastError())); - return false; + goto exit; } if(!ControlService(service, SERVICE_CONTROL_STOP, &status)) { @@ -745,12 +758,26 @@ static bool remove_service(void) { if(!DeleteService(service)) { fprintf(stderr, "Could not remove %s service: %s\n", identname, winerror(GetLastError())); - return false; + goto exit; } - fprintf(stderr, "%s service removed\n", identname); + success = true; - return true; +exit: + + if(service) { + CloseServiceHandle(service); + } + + if(manager) { + CloseServiceHandle(manager); + } + + if(success) { + fprintf(stderr, "%s service removed\n", identname); + } + + return success; } #endif @@ -810,6 +837,8 @@ bool connect_tincd(bool verbose) { strncpy(sa.sun_path, unixsocketname, sizeof(sa.sun_path)); + sa.sun_path[sizeof(sa.sun_path) - 1] = 0; + fd = socket(AF_UNIX, SOCK_STREAM, 0); if(fd < 0) { @@ -887,6 +916,8 @@ bool connect_tincd(bool verbose) { setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&one, sizeof(one)); #endif + sendline(fd, "%d ^%s %d", ID, controlcookie, TINC_CTL_VERSION_CURRENT); + char data[4096]; int version; @@ -900,8 +931,6 @@ bool connect_tincd(bool verbose) { return false; } - sendline(fd, "%d ^%s %d", ID, controlcookie, TINC_CTL_VERSION_CURRENT); - if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &version, &pid) != 3 || code != 4 || version != TINC_CTL_VERSION_CURRENT) { if(verbose) { fprintf(stderr, "Could not fully establish control socket connection\n"); @@ -1013,7 +1042,7 @@ static int cmd_start(int argc, char *argv[]) { #endif // Pass all log messages from the umbilical to stderr. - // A nul-byte right before closure means tincd started succesfully. + // A nul-byte right before closure means tincd started successfully. bool failure = true; char buf[1024]; ssize_t len; @@ -1146,7 +1175,12 @@ static int dump_invitations(void) { } char fname[PATH_MAX]; - snprintf(fname, sizeof(fname), "%s" SLASH "%s", dname, ent->d_name); + + if(snprintf(fname, sizeof(fname), "%s" SLASH "%s", dname, ent->d_name) >= sizeof(fname)) { + fprintf(stderr, "Filename too long: %s" SLASH "%s\n", dname, ent->d_name); + continue; + } + FILE *f = fopen(fname, "r"); if(!f) { @@ -1283,12 +1317,14 @@ static int cmd_dump(int argc, char *argv[]) { unsigned int options, status_int; node_status_t status; long int last_state_change; + int udp_ping_rtt; + uint64_t in_packets, in_bytes, out_packets, out_bytes; switch(req) { case REQ_DUMP_NODES: { - int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %d %d %d %d %x %x %4095s %4095s %d %hd %hd %hd %ld", node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_int, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change); + int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %d %d %d %d %x %x %4095s %4095s %d %hd %hd %hd %ld %d %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_int, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change, &udp_ping_rtt, &in_packets, &in_bytes, &out_packets, &out_bytes); - if(n != 17) { + if(n != 22) { fprintf(stderr, "Unable to parse node dump from tincd: %s\n", line); return 1; } @@ -1316,8 +1352,14 @@ static int cmd_dump(int argc, char *argv[]) { continue; } - printf("%s id %s at %s port %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %d (min %d max %d)\n", - node, id, host, port, cipher, digest, maclength, compression, options, status_int, nexthop, via, distance, pmtu, minmtu, maxmtu); + printf("%s id %s at %s port %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %d (min %d max %d) rx %"PRIu64" %"PRIu64" tx %"PRIu64" %"PRIu64, + node, id, host, port, cipher, digest, maclength, compression, options, status_int, nexthop, via, distance, pmtu, minmtu, maxmtu, in_packets, in_bytes, out_packets, out_bytes); + + if(udp_ping_rtt != -1) { + printf(" rtt %d.%03d", udp_ping_rtt / 1000, udp_ping_rtt % 1000); + } + + printf("\n"); } } break; @@ -1680,6 +1722,7 @@ const var_t variables[] = { {"Ed25519PrivateKeyFile", VAR_SERVER}, {"ExperimentalProtocol", VAR_SERVER}, {"Forwarding", VAR_SERVER}, + {"FWMark", VAR_SERVER}, {"GraphDumpFile", VAR_SERVER | VAR_OBSOLETE}, {"Hostnames", VAR_SERVER}, {"IffOneQueue", VAR_SERVER}, @@ -1859,7 +1902,7 @@ static int cmd_config(int argc, char *argv[]) { } } - /* Change "add" into "set" for variables that do not allow multiple occurences. + /* Change "add" into "set" for variables that do not allow multiple occurrences. Turn on warnings when it seems variables might be removed unintentionally. */ if(action == 1 && !(variables[i].type & VAR_MULTIPLE)) { @@ -1906,7 +1949,11 @@ static int cmd_config(int argc, char *argv[]) { FILE *tf = NULL; if(action >= -1) { - snprintf(tmpfile, sizeof(tmpfile), "%s.config.tmp", filename); + if(snprintf(tmpfile, sizeof(tmpfile), "%s.config.tmp", filename) >= sizeof(tmpfile)) { + fprintf(stderr, "Filename too long: %s.config.tmp\n", filename); + return 1; + } + tf = fopen(tmpfile, "w"); if(!tf) { @@ -2513,7 +2560,10 @@ static int cmd_import(int argc, char *argv[]) { fclose(out); } - snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, name); + if(snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, name) >= sizeof(filename)) { + fprintf(stderr, "Filename too long: %s" SLASH "%s\n", hosts_dir, name); + return 1; + } if(!force && !access(filename, F_OK)) { fprintf(stderr, "Host configuration file %s already exists, skipping.\n", filename); @@ -3240,7 +3290,7 @@ int main(int argc, char *argv[]) { static struct WSAData wsa_state; if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) { - fprintf(stderr, "System call `%s' failed: %s", "WSAStartup", winerror(GetLastError())); + fprintf(stderr, "System call `%s' failed: %s\n", "WSAStartup", winerror(GetLastError())); return false; }