From 535a55100bb77f107c85361e9f72a194e92bc8bc Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Thu, 29 Mar 2012 16:45:25 +0100 Subject: [PATCH] Allow environment variables to be used for Name. When the Name starts with a $, the rest will be interpreted as the name of an environment variable containing the real Name. When Name is $HOST, but this environment variable does not exist, gethostname() will be used to set the Name. In both cases, illegal characters will be converted to underscores. --- doc/tinc.conf.5.in | 13 +++++++++++++ doc/tinc.texi | 5 +++++ src/net.h | 1 + src/net_setup.c | 46 +++++++++++++++++++++++++++++++++++++++------- src/tincd.c | 12 ++---------- 5 files changed, 60 insertions(+), 17 deletions(-) diff --git a/doc/tinc.conf.5.in b/doc/tinc.conf.5.in index f6b0da46..560ae479 100644 --- a/doc/tinc.conf.5.in +++ b/doc/tinc.conf.5.in @@ -394,6 +394,19 @@ while no routing table is managed. .It Va Name Li = Ar name Bq required This is the name which identifies this tinc daemon. It must be unique for the virtual private network this daemon will connect to. +The Name may only consist of alphanumeric and underscore characters. + +If +.Va Name +starts with a +.Li $ , +then the contents of the environment variable that follows will be used. +In that case, invalid characters will be converted to underscores. +If +.Va Name +is +.Li $HOST , +but no such environment variable exist, the hostname will be read using the gethostnname() system call. .It Va PingInterval Li = Ar seconds Pq 60 The number of seconds of inactivity that diff --git a/doc/tinc.texi b/doc/tinc.texi index d0fb70de..84e3495c 100644 --- a/doc/tinc.texi +++ b/doc/tinc.texi @@ -993,6 +993,11 @@ This only has effect when Mode is set to "switch". This is a symbolic name for this connection. The name should consist only of alfanumeric and underscore characters (a-z, A-Z, 0-9 and _). +If Name starts with a $, then the contents of the environment variable that follows will be used. +In that case, invalid characters will be converted to underscores. +If Name is $HOST, but no such environment variable exist, +the hostname will be read using the gethostnname() system call. + @cindex PingInterval @item PingInterval = <@var{seconds}> (60) The number of seconds of inactivity that tinc will wait before sending a diff --git a/src/net.h b/src/net.h index b6f54f2f..7ff603c6 100644 --- a/src/net.h +++ b/src/net.h @@ -138,6 +138,7 @@ extern int setup_vpn_in_socket(const sockaddr_t *); extern void send_packet(const struct node_t *, vpn_packet_t *); extern void receive_tcppacket(struct connection_t *, const char *, int); extern void broadcast_packet(const struct node_t *, vpn_packet_t *); +extern char *get_name(void); extern bool setup_network(void); extern void setup_outgoing_connection(struct outgoing_t *); extern void try_outgoing_connections(void); diff --git a/src/net_setup.c b/src/net_setup.c index d3940e72..a179228b 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -269,6 +269,44 @@ void load_all_subnets(void) { closedir(dir); } +char *get_name(void) { + char *name = NULL; + + get_config_string(lookup_config(config_tree, "Name"), &name); + + if(!name) + return NULL; + + if(*name == '$') { + char *envname = getenv(name + 1); + if(!envname) { + if(strcmp(name + 1, "HOST")) { + fprintf(stderr, "Invalid Name: environment variable %s does not exist\n", name + 1); + return false; + } + envname = alloca(32); + if(gethostname(envname, 32)) { + fprintf(stderr, "Could not get hostname: %s\n", strerror(errno)); + return false; + } + envname[31] = 0; + } + free(name); + name = xstrdup(envname); + for(char *c = name; *c; c++) + if(!isalnum(*c)) + *c = '_'; + } + + if(!check_id(name)) { + logger(LOG_ERR, "Invalid name for myself!"); + free(name); + return false; + } + + return name; +} + /* Configure node_t myself and set up the local sockets (listen only) */ @@ -293,17 +331,11 @@ static bool setup_myself(void) { myself->connection->options = 0; myself->connection->protocol_version = PROT_CURRENT; - if(!get_config_string(lookup_config(config_tree, "Name"), &name)) { /* Not acceptable */ + if(!(name = get_name())) { logger(LOG_ERR, "Name for tinc daemon required!"); return false; } - if(!check_id(name)) { - logger(LOG_ERR, "Invalid name for myself!"); - free(name); - return false; - } - myself->name = name; myself->connection->name = xstrdup(name); xasprintf(&fname, "%s/hosts/%s", confbase, name); diff --git a/src/tincd.c b/src/tincd.c index 148e13e4..4f03db6f 100644 --- a/src/tincd.c +++ b/src/tincd.c @@ -337,16 +337,9 @@ static void indicator(int a, int b, void *p) { static bool keygen(int bits) { RSA *rsa_key; FILE *f; - char *name = NULL; + char *name = get_name(); char *filename; - get_config_string(lookup_config(config_tree, "Name"), &name); - - if(name && !check_id(name)) { - fprintf(stderr, "Invalid name for myself!\n"); - return false; - } - fprintf(stderr, "Generating %d bits keys:\n", bits); rsa_key = RSA_generate_key(bits, 0x10001, indicator, NULL); @@ -386,8 +379,7 @@ static bool keygen(int bits) { PEM_write_RSAPublicKey(f, rsa_key); fclose(f); free(filename); - if(name) - free(name); + free(name); return true; } -- 2.20.1