X-Git-Url: https://tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=src%2Finvitation.c;h=07594ff62aac312e6bf57e6534df54815aff13ff;hp=415c23772dcb09f6238839f92d2640fe352fd05c;hb=3273e3254107a4b89cd9963012d5fac8927c417c;hpb=9e3adef5cb31cb73fbbbd25d3fce115aac107714 diff --git a/src/invitation.c b/src/invitation.c index 415c2377..07594ff6 100644 --- a/src/invitation.c +++ b/src/invitation.c @@ -23,12 +23,14 @@ #include "crypto.h" #include "ecdsa.h" #include "ecdsagen.h" +#include "ifconfig.h" #include "invitation.h" #include "names.h" #include "netutl.h" #include "rsagen.h" #include "script.h" #include "sptps.h" +#include "subnet.h" #include "tincctl.h" #include "utils.h" #include "xalloc.h" @@ -335,7 +337,11 @@ int cmd_invite(int argc, char *argv[]) { return 1; } chmod(filename, 0600); - ecdsa_write_pem_private_key(key, f); + if(!ecdsa_write_pem_private_key(key, f)) { + fprintf(stderr, "Could not write ECDSA private key\n"); + fclose(f); + return 1; + } fclose(f); if(connect_tincd(false)) @@ -598,7 +604,20 @@ make_names: return false; } + snprintf(filename, sizeof filename, "%s" SLASH "tinc-up.invitation", confbase); + FILE *fup = fopen(filename, "w"); + if(!fup) { + fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno)); + fclose(f); + fclose(fh); + return false; + } + + fprintf(fup, "#!/bin/sh\n"); + long fuppos = ftell(fup); + // Filter first chunk on approved keywords, split between tinc.conf and hosts/Name + // Generate a tinc-up script from Ifconfig and Route keywords. // Other chunks go unfiltered to their respective host config files const char *p = data; char *l, *value; @@ -637,6 +656,24 @@ make_names: break; } + // Handle Ifconfig and Route statements + if(!found) { + if(!strcasecmp(l, "Ifconfig")) { + if(!strcasecmp(value, "dhcp")) + ifconfig_dhcp(fup); + else if(!strcasecmp(value, "dhcp6")) + ifconfig_dhcp6(fup); + else if(!strcasecmp(value, "slaac")) + ifconfig_slaac(fup); + else + ifconfig_address(fup, value); + continue; + } else if(!strcasecmp(l, "Route")) { + ifconfig_route(fup, value); + continue; + } + } + // Ignore unknown and unsafe variables if(!found) { fprintf(stderr, "Ignoring unknown variable '%s' in invitation.\n", l); @@ -651,6 +688,8 @@ make_names: } fclose(f); + bool valid_tinc_up = ifconfig_footer(fup); + fclose(fup); while(l && !strcasecmp(l, "Name")) { if(!check_id(value)) { @@ -704,6 +743,8 @@ make_names: snprintf(filename, sizeof filename, "%s" SLASH "ed25519_key.priv", confbase); f = fopenmask(filename, "w", 0600); + if(!f) + return false; if(!ecdsa_write_pem_private_key(key, f)) { fprintf(stderr, "Error writing private key!\n"); @@ -725,10 +766,14 @@ make_names: snprintf(filename, sizeof filename, "%s" SLASH "rsa_key.priv", confbase); f = fopenmask(filename, "w", 0600); - rsa_write_pem_private_key(rsa, f); + if(!f || !rsa_write_pem_private_key(rsa, f)) { + fprintf(stderr, "Could not write private RSA key\n"); + } else if(!rsa_write_pem_public_key(rsa, fh)) { + fprintf(stderr, "Could not write public RSA key\n"); + } + fclose(f); - rsa_write_pem_public_key(rsa, fh); fclose(fh); rsa_free(rsa); @@ -759,6 +804,60 @@ ask_netname: make_names(false); } + char filename2[PATH_MAX]; + snprintf(filename, sizeof filename, "%s" SLASH "tinc-up.invitation", confbase); + snprintf(filename2, sizeof filename2, "%s" SLASH "tinc-up", confbase); + + if(valid_tinc_up) { + if(tty) { + FILE *fup = fopen(filename, "r"); + if(fup) { + fprintf(stderr, "\nPlease review the following tinc-up script:\n\n"); + + char buf[MAXSIZE]; + while(fgets(buf, sizeof buf, fup)) + fputs(buf, stderr); + fclose(fup); + + int response = 0; + do { + fprintf(stderr, "\nDo you want to use this script [y]es/[n]o/[e]dit? "); + response = tolower(getchar()); + } while(!strchr("yne", response)); + + fprintf(stderr, "\n"); + + if(response == 'e') { + char *command; +#ifndef HAVE_MINGW + xasprintf(&command, "\"%s\" \"%s\"", getenv("VISUAL") ?: getenv("EDITOR") ?: "vi", filename); +#else + xasprintf(&command, "edit \"%s\"", filename); +#endif + if(system(command)) + response = 'n'; + else + response = 'y'; + free(command); + } + + if(response == 'y') { + rename(filename, filename2); + chmod(filename2, 0755); + fprintf(stderr, "tinc-up enabled.\n"); + } else { + fprintf(stderr, "tinc-up has been left disabled.\n"); + } + } + } else { + fprintf(stderr, "A tinc-up script was generated, but has been left disabled.\n"); + } + } else { + // A placeholder was generated. + rename(filename, filename2); + chmod(filename2, 0755); + } + fprintf(stderr, "Configuration stored in: %s\n", confbase); return true;