Allow environment variables to be used for Name.
authorGuus Sliepen <guus@tinc-vpn.org>
Thu, 29 Mar 2012 15:45:25 +0000 (16:45 +0100)
committerGuus Sliepen <guus@tinc-vpn.org>
Thu, 29 Mar 2012 15:45:25 +0000 (16:45 +0100)
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
doc/tinc.texi
src/net.h
src/net_setup.c
src/tincd.c

index f6b0da465658341540b0c25337d61190c37c3953..560ae4799e9d2f4c422455a456316c563deff3b6 100644 (file)
@@ -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
index d0fb70dec4556f849430c010a08f56ea5e9fa795..84e3495c96115e58ed84d885d4cb6590a2a29b9e 100644 (file)
@@ -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
index b6f54f2fad964849c8595f934abb0e93c9a8e2ba..7ff603c6014d3b0456fd74b9b8dca5a5eb2b1f40 100644 (file)
--- 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);
index d3940e72b36aa698404a9e70ac1c47167d03a17a..a179228be7f5075f0bfcd2e23e257a768e76602c 100644 (file)
@@ -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);
index 148e13e444ef2c7ef8188e04baa3e1a189504a55..4f03db6f57558c9eca149d9423664fd007428bc3 100644 (file)
@@ -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;
 }