X-Git-Url: https://www.tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Finvitation.c;h=b2e35f98b9ec0320435869efcd588ba4529bd515;hb=7ab400aebdc38e7ee5dafc0a2291bbbea25e3f7c;hp=4c8597a66708142f5b4f54240520e84f422b4bfa;hpb=a6448291834ca7419553a807ee367c719c2956d0;p=tinc diff --git a/src/invitation.c b/src/invitation.c index 4c8597a6..b2e35f98 100644 --- a/src/invitation.c +++ b/src/invitation.c @@ -111,6 +111,9 @@ char *get_my_hostname() { scan_for_hostname(tinc_conf, &hostname, &port); } + free(name); + name = NULL; + if(hostname) { goto done; } @@ -181,6 +184,7 @@ char *get_my_hostname() { if(!tty) { if(!hostname) { fprintf(stderr, "Could not determine the external address or hostname. Please set Address manually.\n"); + free(port); return NULL; } @@ -199,6 +203,7 @@ again: if(!fgets(line, sizeof(line), stdin)) { fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno)); free(hostname); + free(port); return NULL; } @@ -287,6 +292,7 @@ int cmd_invite(int argc, char *argv[]) { return 1; } + free(myname); myname = get_my_name(true); if(!myname) { @@ -354,7 +360,7 @@ int cmd_invite(int argc, char *argv[]) { char invname[PATH_MAX]; struct stat st; - if(snprintf(invname, sizeof(invname), "%s" SLASH "%s", filename, ent->d_name) >= sizeof(invname)) { + if((size_t)snprintf(invname, sizeof(invname), "%s" SLASH "%s", filename, ent->d_name) >= sizeof(invname)) { fprintf(stderr, "Filename too long: %s" SLASH "%s\n", filename, ent->d_name); continue; } @@ -405,6 +411,7 @@ int cmd_invite(int argc, char *argv[]) { if(!f) { fprintf(stderr, "Could not write %s: %s\n", filename, strerror(errno)); + free(key); return 1; } @@ -413,6 +420,7 @@ int cmd_invite(int argc, char *argv[]) { if(!ecdsa_write_pem_private_key(key, f)) { fprintf(stderr, "Could not write ECDSA private key\n"); fclose(f); + free(key); return 1; } @@ -442,6 +450,8 @@ int cmd_invite(int argc, char *argv[]) { sha512(fingerprint, strlen(fingerprint), hash); b64encode_urlsafe(hash, hash, 18); + free(key); + // Create a random cookie for this invitation. char cookie[25]; randomize(cookie, 18); @@ -454,6 +464,8 @@ int cmd_invite(int argc, char *argv[]) { sha512(buf, sizeof(buf), cookiehash); b64encode_urlsafe(cookiehash, cookiehash, 18); + free(fingerprint); + b64encode_urlsafe(cookie, cookie, 18); // Create a file containing the details of the invitation. @@ -553,7 +565,7 @@ static char *get_line(const char **data) { static char line[1024]; const char *end = strchr(*data, '\n'); - size_t len = end ? end - *data : strlen(*data); + size_t len = end ? (size_t)(end - *data) : strlen(*data); if(len >= sizeof(line)) { fprintf(stderr, "Maximum line length exceeded!\n"); @@ -633,7 +645,7 @@ static char *grep(const char *data, const char *var) { return xstrdup(p); } - if(e - p >= sizeof(value)) { + if((size_t)(e - p) >= sizeof(value)) { fprintf(stderr, "Maximum line length exceeded!\n"); return NULL; } @@ -644,13 +656,18 @@ static char *grep(const char *data, const char *var) { } static bool finalize_join(void) { - char *name = xstrdup(get_value(data, "Name")); + const char *temp_name = get_value(data, "Name"); - if(!name) { + if(!temp_name) { fprintf(stderr, "No Name found in invitation!\n"); return false; } + size_t len = strlen(temp_name); + char name[len + 1]; + memcpy(name, temp_name, len); + name[len] = 0; + if(!check_id(name)) { fprintf(stderr, "Invalid Name found in invitation!\n"); return false; @@ -829,8 +846,12 @@ make_names: fprintf(stderr, "Ignoring unknown variable '%s' in invitation.\n", l); continue; } else if(!(variables[i].type & VAR_SAFE)) { - fprintf(stderr, "Ignoring unsafe variable '%s' in invitation.\n", l); - continue; + if(force) { + fprintf(stderr, "Warning: unsafe variable '%s' in invitation.\n", l); + } else { + fprintf(stderr, "Ignoring unsafe variable '%s' in invitation.\n", l); + continue; + } } // Copy the safe variable to the right config file @@ -960,7 +981,7 @@ ask_netname: char newbase[PATH_MAX]; - if(snprintf(newbase, sizeof(newbase), CONFDIR SLASH "tinc" SLASH "%s", line) >= sizeof(newbase)) { + if((size_t)snprintf(newbase, sizeof(newbase), CONFDIR SLASH "tinc" SLASH "%s", line) >= sizeof(newbase)) { fprintf(stderr, "Filename too long: " CONFDIR SLASH "tinc" SLASH "%s\n", line); goto ask_netname; } @@ -976,7 +997,12 @@ ask_netname: char filename2[PATH_MAX]; snprintf(filename, sizeof(filename), "%s" SLASH "tinc-up.invitation", confbase); + +#ifdef HAVE_MINGW + snprintf(filename2, sizeof(filename2), "%s" SLASH "tinc-up.bat", confbase); +#else snprintf(filename2, sizeof(filename2), "%s" SLASH "tinc-up", confbase); +#endif if(valid_tinc_up) { if(tty) { @@ -1005,7 +1031,17 @@ ask_netname: if(response == 'e') { char *command; #ifndef HAVE_MINGW - xasprintf(&command, "\"%s\" \"%s\"", getenv("VISUAL") ? : getenv("EDITOR") ? : "vi", filename); + const char *editor = getenv("VISUAL"); + + if(!editor) { + editor = getenv("EDITOR"); + } + + if(!editor) { + editor = "vi"; + } + + xasprintf(&command, "\"%s\" \"%s\"", editor, filename); #else xasprintf(&command, "edit \"%s\"", filename); #endif @@ -1028,7 +1064,13 @@ ask_netname: } } } else { - fprintf(stderr, "A tinc-up script was generated, but has been left disabled.\n"); + if(force) { + rename(filename, filename2); + chmod(filename2, 0755); + fprintf(stderr, "tinc-up enabled.\n"); + } else { + fprintf(stderr, "A tinc-up script was generated, but has been left disabled.\n"); + } } } else { // A placeholder was generated. @@ -1042,11 +1084,15 @@ ask_netname: } -static bool invitation_send(void *handle, uint8_t type, const void *data, size_t len) { +static bool invitation_send(void *handle, uint8_t type, const void *vdata, size_t len) { + (void)handle; + (void)type; + const char *data = vdata; + while(len) { int result = send(sock, data, len, 0); - if(result == -1 && errno == EINTR) { + if(result == -1 && sockwouldblock(sockerrno)) { continue; } else if(result <= 0) { return false; @@ -1060,6 +1106,8 @@ static bool invitation_send(void *handle, uint8_t type, const void *data, size_t } static bool invitation_receive(void *handle, uint8_t type, const void *msg, uint16_t len) { + (void)handle; + switch(type) { case SPTPS_HANDSHAKE: return sptps_send_record(&sptps, 0, cookie, sizeof(cookie)); @@ -1199,6 +1247,7 @@ int cmd_join(int argc, char *argv[]) { struct addrinfo *ai = str2addrinfo(address, port, SOCK_STREAM); if(!ai) { + free(b64key); return 1; } @@ -1212,6 +1261,7 @@ next: if(!aip) { freeaddrinfo(ai); + free(b64key); return 1; } } @@ -1238,7 +1288,7 @@ next: // Tell him we have an invitation, and give him our throw-away key. int len = snprintf(line, sizeof(line), "0 ?%s %d.%d\n", b64key, PROT_MAJOR, PROT_MINOR); - if(len <= 0 || len >= sizeof(line)) { + if(len <= 0 || (size_t)len >= sizeof(line)) { abort(); } @@ -1258,6 +1308,11 @@ next: } freeaddrinfo(ai); + ai = NULL; + aip = NULL; + + free(b64key); + b64key = NULL; // Check if the hash of the key he gave us matches the hash in the URL. char *fingerprint = line + 2; @@ -1292,11 +1347,21 @@ next: while((len = recv(sock, line, sizeof(line), 0))) { if(len < 0) { - if(errno == EINTR) { + if(sockwouldblock(sockerrno)) { continue; } - fprintf(stderr, "Error reading data from %s port %s: %s\n", address, port, strerror(errno)); +#if HAVE_MINGW + + // If socket has been shut down, recv() on Windows returns -1 and sets sockerrno + // to WSAESHUTDOWN, while on UNIX-like operating systems recv() returns 0, so we + // have to do an explicit check here. + if(sockshutdown(sockerrno)) { + break; + } + +#endif + fprintf(stderr, "Error reading data from %s port %s: %s\n", address, port, sockstrerror(sockerrno)); return 1; }