X-Git-Url: https://tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Ftincctl.c;h=f133e2def81086456033a59ea74cb1f28b47ccc7;hb=8f8424445810aa7d5e9d4d537494e64811a8e29f;hp=16fa4b18bc4896cd00bba02f6db9f670d8bbbdf9;hpb=8f2db4afddf109e59c7ec0cdb7ad79db75d698e5;p=tinc diff --git a/src/tincctl.c b/src/tincctl.c index 16fa4b18..f133e2de 100644 --- a/src/tincctl.c +++ b/src/tincctl.c @@ -39,12 +39,6 @@ #include "tincctl.h" #include "top.h" -#ifdef HAVE_MINGW -#define SCRIPTEXTENSION ".bat" -#else -#define SCRIPTEXTENSION "" -#endif - static char **orig_argv; static int orig_argc; @@ -211,6 +205,23 @@ static bool parse_options(int argc, char **argv) { return true; } +/* Open a file with the desired permissions, minus the umask. + Also, if we want to create an executable file, we call fchmod() + to set the executable bits. */ + +FILE *fopenmask(const char *filename, const char *mode, mode_t perms) { + mode_t mask = umask(0); + perms &= ~mask; + umask(~perms); + FILE *f = fopen(filename, mode); +#ifdef HAVE_FCHMOD + if((perms & 0444) && f) + fchmod(fileno(f), perms); +#endif + umask(mask); + return f; +} + static void disable_old_keys(const char *filename, const char *what) { char tmpfile[PATH_MAX] = ""; char buf[1024]; @@ -225,17 +236,9 @@ static void disable_old_keys(const char *filename, const char *what) { snprintf(tmpfile, sizeof tmpfile, "%s.tmp", filename); - w = fopen(tmpfile, "w"); - -#ifdef HAVE_FCHMOD - /* Let the temporary file have the same permissions as the original. */ - - if(w) { - struct stat st = {.st_mode = 0600}; - fstat(fileno(r), &st); - fchmod(fileno(w), st.st_mode); - } -#endif + struct stat st = {.st_mode = 0600}; + fstat(fileno(r), &st); + w = fopenmask(tmpfile, "w", st.st_mode); while(fgets(buf, sizeof buf, r)) { if(!block && !strncmp(buf, "-----BEGIN ", 11)) { @@ -298,7 +301,7 @@ static void disable_old_keys(const char *filename, const char *what) { unlink(tmpfile); } -static FILE *ask_and_open(const char *filename, const char *what, const char *mode, bool ask) { +static FILE *ask_and_open(const char *filename, const char *what, const char *mode, bool ask, mode_t perms) { FILE *r; char *directory; char buf[PATH_MAX]; @@ -338,7 +341,7 @@ static FILE *ask_and_open(const char *filename, const char *what, const char *mo /* Open it first to keep the inode busy */ - r = fopen(filename, mode); + r = fopenmask(filename, mode, perms); if(!r) { fprintf(stderr, "Error opening file `%s': %s\n", filename, strerror(errno)); @@ -366,17 +369,12 @@ static bool ecdsa_keygen(bool ask) { fprintf(stderr, "Done.\n"); xasprintf(&privname, "%s" SLASH "ecdsa_key.priv", confbase); - f = ask_and_open(privname, "private ECDSA key", "a", ask); + f = ask_and_open(privname, "private ECDSA key", "a", ask, 0600); free(privname); if(!f) return false; -#ifdef HAVE_FCHMOD - /* Make it unreadable for others. */ - fchmod(fileno(f), 0600); -#endif - if(!ecdsa_write_pem_private_key(key, f)) { fprintf(stderr, "Error writing private key!\n"); ecdsa_free(key); @@ -391,7 +389,7 @@ static bool ecdsa_keygen(bool ask) { else xasprintf(&pubname, "%s" SLASH "ecdsa_key.pub", confbase); - f = ask_and_open(pubname, "public ECDSA key", "a", ask); + f = ask_and_open(pubname, "public ECDSA key", "a", ask, 0666); free(pubname); if(!f) @@ -425,17 +423,12 @@ static bool rsa_keygen(int bits, bool ask) { fprintf(stderr, "Done.\n"); xasprintf(&privname, "%s" SLASH "rsa_key.priv", confbase); - f = ask_and_open(privname, "private RSA key", "a", ask); + f = ask_and_open(privname, "private RSA key", "a", ask, 0600); free(privname); if(!f) return false; -#ifdef HAVE_FCHMOD - /* Make it unreadable for others. */ - fchmod(fileno(f), 0600); -#endif - if(!rsa_write_pem_private_key(key, f)) { fprintf(stderr, "Error writing private key!\n"); fclose(f); @@ -450,7 +443,7 @@ static bool rsa_keygen(int bits, bool ask) { else xasprintf(&pubname, "%s" SLASH "rsa_key.pub", confbase); - f = ask_and_open(pubname, "public RSA key", "a", ask); + f = ask_and_open(pubname, "public RSA key", "a", ask, 0666); free(pubname); if(!f) @@ -1686,6 +1679,35 @@ static bool try_bind(int port) { return true; } +int check_port(char *name) { + if(try_bind(655)) + return 655; + + fprintf(stderr, "Warning: could not bind to port 655. "); + + for(int i = 0; i < 100; i++) { + int port = 0x1000 + (rand() & 0x7fff); + if(try_bind(port)) { + char *filename; + xasprintf(&filename, "%s" SLASH "hosts" SLASH "%s", confbase, name); + FILE *f = fopen(filename, "a"); + free(filename); + if(!f) { + fprintf(stderr, "Please change tinc's Port manually.\n"); + return 0; + } + + fprintf(f, "Port = %d\n", port); + fclose(f); + fprintf(stderr, "Tinc will instead listen on port %d.\n", port); + return port; + } + } + + fprintf(stderr, "Please change tinc's Port manually.\n"); + return 0; +} + static int cmd_init(int argc, char *argv[]) { if(!access(tinc_conf, F_OK)) { fprintf(stderr, "Configuration file %s already exists!\n", tinc_conf); @@ -1727,17 +1749,17 @@ static int cmd_init(int argc, char *argv[]) { return 1; } - if(mkdir(confdir, 0755) && errno != EEXIST) { - fprintf(stderr, "Could not create directory %s: %s\n", CONFDIR, strerror(errno)); + if(strcmp(confdir, confbase) && mkdir(confdir, 0755) && errno != EEXIST) { + fprintf(stderr, "Could not create directory %s: %s\n", confdir, strerror(errno)); return 1; } - if(mkdir(confbase, 0755) && errno != EEXIST) { + if(mkdir(confbase, 0777) && errno != EEXIST) { fprintf(stderr, "Could not create directory %s: %s\n", confbase, strerror(errno)); return 1; } - if(mkdir(hosts_dir, 0755) && errno != EEXIST) { + if(mkdir(hosts_dir, 0777) && errno != EEXIST) { fprintf(stderr, "Could not create directory %s: %s\n", hosts_dir, strerror(errno)); return 1; } @@ -1754,47 +1776,17 @@ static int cmd_init(int argc, char *argv[]) { if(!rsa_keygen(2048, false) || !ecdsa_keygen(false)) return 1; - - if(!try_bind(655)) { - srand(time(NULL)); - int port = 0; - for(int i = 0; i < 100; i++) { - port = 0x1000 + (rand() & 0x7fff); - if(try_bind(port)) - break; - port = 0; - } - if(port) { - char *filename; - xasprintf(&filename, "%s" SLASH "hosts" SLASH "%s", confbase, name); - FILE *f = fopen(filename, "a"); - free(filename); - if(!f) { - port = 0; - } else { - fprintf(f, "Port = %d\n", port); - fclose(f); - } - } - - if(!port) - fprintf(stderr, "Warning: could not bind to port 655. Please change tinc's Port manually.\n"); - else - fprintf(stderr, "Warning: could not bind to port 655. Tinc will instead listen on port %d.\n", port); - } + check_port(name); #ifndef HAVE_MINGW char *filename; xasprintf(&filename, "%s" SLASH "tinc-up", confbase); if(access(filename, F_OK)) { - FILE *f = fopen(filename, "w"); + FILE *f = fopenmask(filename, "w", 0777); if(!f) { fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno)); return 1; } - mode_t mask = umask(0); - umask(mask); - fchmod(fileno(f), 0755 & ~mask); fprintf(f, "#!/bin/sh\n\necho 'Unconfigured tinc-up script, please edit!'\n\n#ifconfig $INTERFACE netmask \n"); fclose(f); } @@ -2372,6 +2364,7 @@ int main(int argc, char *argv[]) { return 0; } + srand(time(NULL)); crypto_init(); tty = isatty(0) && isatty(1);