Rename base64 funcs to show they're not RFC-compliant.
[tinc] / src / tincctl.c
index ec43469..a144636 100644 (file)
 #include "top.h"
 #include "version.h"
 #include "subnet.h"
+#include "keys.h"
 
 #ifndef MSG_NOSIGNAL
 #define MSG_NOSIGNAL 0
 #endif
 
 static char **orig_argv;
-static int orig_argc;
 
 /* If nonzero, display usage information and exit. */
 static bool show_help = false;
@@ -71,7 +71,6 @@ static int result;
 bool force = false;
 bool tty = true;
 bool confbasegiven = false;
-bool netnamegiven = false;
 char *scriptinterpreter = NULL;
 char *scriptextension = "";
 static char *prompt;
@@ -247,127 +246,6 @@ 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 & 0777);
-       FILE *f = fopen(filename, mode);
-
-       if(!f) {
-               fprintf(stderr, "Could not open %s: %s\n", filename, strerror(errno));
-               return NULL;
-       }
-
-#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];
-       bool disabled = false;
-       bool block = false;
-       bool error = false;
-
-       FILE *r = fopen(filename, "r");
-       FILE *w = NULL;
-
-       if(!r) {
-               return;
-       }
-
-       int result = snprintf(tmpfile, sizeof(tmpfile), "%s.tmp", filename);
-
-       if(result < sizeof(tmpfile)) {
-               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)) {
-                       if((strstr(buf, " ED25519 ") && strstr(what, "Ed25519")) || (strstr(buf, " RSA ") && strstr(what, "RSA"))) {
-                               disabled = true;
-                               block = true;
-                       }
-               }
-
-               bool ed25519pubkey = !strncasecmp(buf, "Ed25519PublicKey", 16) && strchr(" \t=", buf[16]) && strstr(what, "Ed25519");
-
-               if(ed25519pubkey) {
-                       disabled = true;
-               }
-
-               if(w) {
-                       if(block || ed25519pubkey) {
-                               fputc('#', w);
-                       }
-
-                       if(fputs(buf, w) < 0) {
-                               error = true;
-                               break;
-                       }
-               }
-
-               if(block && !strncmp(buf, "-----END ", 9)) {
-                       block = false;
-               }
-       }
-
-       if(w)
-               if(fclose(w) < 0) {
-                       error = true;
-               }
-
-       if(ferror(r) || fclose(r) < 0) {
-               error = true;
-       }
-
-       if(disabled) {
-               if(!w || error) {
-                       fprintf(stderr, "Warning: old key(s) found, remove them by hand!\n");
-
-                       if(w) {
-                               unlink(tmpfile);
-                       }
-
-                       return;
-               }
-
-#ifdef HAVE_MINGW
-               // We cannot atomically replace files on Windows.
-               char bakfile[PATH_MAX] = "";
-               snprintf(bakfile, sizeof(bakfile), "%s.bak", filename);
-
-               if(rename(filename, bakfile) || rename(tmpfile, filename)) {
-                       rename(bakfile, filename);
-#else
-
-               if(rename(tmpfile, filename)) {
-#endif
-                       fprintf(stderr, "Warning: old key(s) found, remove them by hand!\n");
-               } else  {
-#ifdef HAVE_MINGW
-                       unlink(bakfile);
-#endif
-                       fprintf(stderr, "Warning: old key(s) found and disabled.\n");
-               }
-       }
-
-       unlink(tmpfile);
-}
-
 static FILE *ask_and_open(const char *filename, const char *what, const char *mode, bool ask, mode_t perms) {
        FILE *r;
        char directory[PATH_MAX] = ".";
@@ -585,15 +463,15 @@ bool recvline(int fd, char *line, size_t len) {
        }
 
        while(!(newline = memchr(buffer, '\n', blen))) {
-               int result = recv(fd, buffer + blen, sizeof(buffer) - blen, 0);
+               ssize_t nrecv = recv(fd, buffer + blen, sizeof(buffer) - blen, 0);
 
-               if(result == -1 && sockerrno == EINTR) {
+               if(nrecv == -1 && sockerrno == EINTR) {
                        continue;
-               } else if(result <= 0) {
+               } else if(nrecv <= 0) {
                        return false;
                }
 
-               blen += result;
+               blen += nrecv;
        }
 
        if((size_t)(newline - buffer) >= len) {
@@ -612,15 +490,15 @@ bool recvline(int fd, char *line, size_t len) {
 
 static bool recvdata(int fd, char *data, size_t len) {
        while(blen < len) {
-               int result = recv(fd, buffer + blen, sizeof(buffer) - blen, 0);
+               ssize_t nrecv = recv(fd, buffer + blen, sizeof(buffer) - blen, 0);
 
-               if(result == -1 && sockerrno == EINTR) {
+               if(nrecv == -1 && sockerrno == EINTR) {
                        continue;
-               } else if(result <= 0) {
+               } else if(nrecv <= 0) {
                        return false;
                }
 
-               blen += result;
+               blen += nrecv;
        }
 
        memcpy(data, buffer, len);
@@ -633,7 +511,7 @@ static bool recvdata(int fd, char *data, size_t len) {
 bool sendline(int fd, char *format, ...) {
        static char buffer[4096];
        char *p = buffer;
-       int blen;
+       ssize_t blen;
        va_list ap;
 
        va_start(ap, format);
@@ -649,16 +527,16 @@ bool sendline(int fd, char *format, ...) {
        blen++;
 
        while(blen) {
-               int result = send(fd, p, blen, MSG_NOSIGNAL);
+               ssize_t nsend = send(fd, p, blen, MSG_NOSIGNAL);
 
-               if(result == -1 && sockerrno == EINTR) {
+               if(nsend == -1 && sockerrno == EINTR) {
                        continue;
-               } else if(result <= 0) {
+               } else if(nsend <= 0) {
                        return false;
                }
 
-               p += result;
-               blen -= result;
+               p += nsend;
+               blen -= nsend;
        }
 
        return true;
@@ -699,11 +577,12 @@ static void pcap(int fd, FILE *out, uint32_t snaplen) {
        char line[32];
 
        while(recvline(fd, line, sizeof(line))) {
-               int code, req, len;
-               int n = sscanf(line, "%d %d %d", &code, &req, &len);
+               int code, req;
+               size_t len;
+               int n = sscanf(line, "%d %d %zd", &code, &req, &len);
                gettimeofday(&tv, NULL);
 
-               if(n != 3 || code != CONTROL || req != REQ_PCAP || len < 0 || (size_t)len > sizeof(data)) {
+               if(n != 3 || code != CONTROL || req != REQ_PCAP || len > sizeof(data)) {
                        break;
                }
 
@@ -1092,7 +971,6 @@ static int cmd_start(int argc, char *argv[]) {
 
        free(nargv);
 
-       int status = -1, result;
 #ifdef SIGINT
        signal(SIGINT, SIG_IGN);
 #endif
@@ -1100,7 +978,7 @@ static int cmd_start(int argc, char *argv[]) {
        // Pass all log messages from the umbilical to stderr.
        // A nul-byte right before closure means tincd started successfully.
        bool failure = true;
-       char buf[1024];
+       uint8_t buf[1024];
        ssize_t len;
 
        while((len = read(pfd[0], buf, sizeof(buf))) > 0) {
@@ -1120,7 +998,8 @@ static int cmd_start(int argc, char *argv[]) {
        close(pfd[0]);
 
        // Make sure the child process is really gone.
-       result = waitpid(pid, &status, 0);
+       int status = -1;
+       pid_t result = waitpid(pid, &status, 0);
 
 #ifdef SIGINT
        signal(SIGINT, SIG_DFL);
@@ -1221,7 +1100,7 @@ static int dump_invitations(void) {
        while((ent = readdir(dir))) {
                char buf[MAX_STRING_SIZE];
 
-               if(b64decode(ent->d_name, buf, 24) != 18) {
+               if(b64decode_tinc(ent->d_name, buf, 24) != 18) {
                        continue;
                }
 
@@ -1424,7 +1303,7 @@ static int cmd_dump(int argc, char *argv[]) {
                        }
 
                        if(do_graph) {
-                               float w = 1 + 65536.0 / weight;
+                               float w = 1.0f + 65536.0f / (float)weight;
 
                                if(do_graph == 1 && strcmp(node1, node2) > 0) {
                                        printf(" \"%s\" -- \"%s\" [w = %f, weight = %f];\n", node1, node2, w, w);
@@ -1675,8 +1554,8 @@ static int cmd_pid(int argc, char *argv[]) {
        return 0;
 }
 
-int rstrip(char *value) {
-       int len = strlen(value);
+size_t rstrip(char *value) {
+       size_t len = strlen(value);
 
        while(len && strchr("\t\r\n ", value[len - 1])) {
                value[--len] = 0;
@@ -1700,7 +1579,7 @@ char *get_my_name(bool verbose) {
        char *value;
 
        while(fgets(buf, sizeof(buf), f)) {
-               int len = strcspn(buf, "\t =");
+               size_t len = strcspn(buf, "\t =");
                value = buf + len;
                value += strspn(value, "\t ");
 
@@ -1739,7 +1618,7 @@ ecdsa_t *get_pubkey(FILE *f) {
        char *value;
 
        while(fgets(buf, sizeof(buf), f)) {
-               int len = strcspn(buf, "\t =");
+               size_t len = strcspn(buf, "\t =");
                value = buf + len;
                value += strspn(value, "\t ");
 
@@ -1931,11 +1810,12 @@ static int cmd_config(int argc, char *argv[]) {
                found = true;
                variable = (char *)variables[i].name;
 
-               if(!strcasecmp(variable, "Subnet")) {
+               if(!strcasecmp(variable, "Subnet") && *value) {
                        subnet_t s = {0};
 
                        if(!str2net(&s, value)) {
                                fprintf(stderr, "Malformed subnet definition %s\n", value);
+                               return 1;
                        }
 
                        if(!subnetcheck(s)) {
@@ -2065,9 +1945,8 @@ static int cmd_config(int argc, char *argv[]) {
 
                // Parse line in a simple way
                char *bvalue;
-               int len;
 
-               len = strcspn(buf2, "\t =");
+               size_t len = strcspn(buf2, "\t =");
                bvalue = buf2 + len;
                bvalue += strspn(bvalue, "\t ");
 
@@ -2291,7 +2170,7 @@ static int cmd_init(int argc, char *argv[]) {
                                return 1;
                        }
 
-                       int len = rstrip(buf);
+                       size_t len = rstrip(buf);
 
                        if(!len) {
                                fprintf(stderr, "No name given!\n");
@@ -2908,7 +2787,7 @@ static int cmd_sign(int argc, char *argv[]) {
        long t = time(NULL);
        char *trailer;
        xasprintf(&trailer, " %s %ld", name, t);
-       int trailer_len = strlen(trailer);
+       size_t trailer_len = strlen(trailer);
 
        data = xrealloc(data, len + trailer_len);
        memcpy(data + len, trailer, trailer_len);
@@ -2923,7 +2802,7 @@ static int cmd_sign(int argc, char *argv[]) {
                return 1;
        }
 
-       b64encode(sig, sig, 64);
+       b64encode_tinc(sig, sig, 64);
        ecdsa_free(key);
 
        fprintf(stdout, "Signature = %s %ld %s\n", name, t, sig);
@@ -3023,7 +2902,7 @@ static int cmd_verify(int argc, char *argv[]) {
 
        char *trailer;
        xasprintf(&trailer, " %s %ld", signer, t);
-       int trailer_len = strlen(trailer);
+       size_t trailer_len = strlen(trailer);
 
        data = xrealloc(data, len + trailer_len);
        memcpy(data + len, trailer, trailer_len);
@@ -3057,7 +2936,7 @@ static int cmd_verify(int argc, char *argv[]) {
 
        fclose(fp);
 
-       if(b64decode(sig, sig, 86) != 64 || !ecdsa_verify(key, newline, len + trailer_len - (newline - data), sig)) {
+       if(b64decode_tinc(sig, sig, 86) != 64 || !ecdsa_verify(key, newline, len + trailer_len - (newline - data), sig)) {
                fprintf(stderr, "Invalid signature\n");
                free(data);
                ecdsa_free(key);
@@ -3391,7 +3270,6 @@ static void cleanup() {
 int main(int argc, char *argv[]) {
        program_name = argv[0];
        orig_argv = argv;
-       orig_argc = argc;
        tty = isatty(0) && isatty(1);
 
        if(!parse_options(argc, argv)) {