Merge branch 'master' into 1.1
[tinc] / src / protocol_subnet.c
index 6e7d706..e592721 100644 (file)
@@ -45,7 +45,7 @@ bool send_add_subnet(connection_t *c, const subnet_t *subnet)
        return send_request(c, "%d %lx %s %s", ADD_SUBNET, random(), subnet->owner->name, netstr);
 }
 
-bool add_subnet_h(connection_t *c)
+bool add_subnet_h(connection_t *c, char *request)
 {
        char subnetstr[MAX_STRING_SIZE];
        char name[MAX_STRING_SIZE];
@@ -54,13 +54,13 @@ bool add_subnet_h(connection_t *c)
 
        cp();
 
-       if(sscanf(c->buffer, "%*d %*x " MAX_STRING " " MAX_STRING, name, subnetstr) != 2) {
+       if(sscanf(request, "%*d %*x " MAX_STRING " " MAX_STRING, name, subnetstr) != 2) {
                logger(LOG_ERR, _("Got bad %s from %s (%s)"), "ADD_SUBNET", c->name,
                           c->hostname);
                return false;
        }
 
-       /* Check if owner name is valid */
+       /* Check if owner name is valid */
 
        if(!check_id(name)) {
                logger(LOG_ERR, _("Got bad %s from %s (%s): %s"), "ADD_SUBNET", c->name,
@@ -76,7 +76,7 @@ bool add_subnet_h(connection_t *c)
                return false;
        }
 
-       if(seen_request(c->buffer))
+       if(seen_request(request))
                return true;
 
        /* Check if the owner of the new subnet is in the connection list */
@@ -127,8 +127,11 @@ bool add_subnet_h(connection_t *c)
                        free_subnet(allowed);
                }
 
-               if(!cfg)
+               if(!cfg) {
+                       logger(LOG_WARNING, _("Unauthorized %s from %s (%s) for %s"),
+                               "ADD_SUBNET", c->name, c->hostname, subnetstr);
                        return false;
+               }
 
                free_subnet(allowed);
        }
@@ -144,7 +147,7 @@ bool add_subnet_h(connection_t *c)
        /* Tell the rest */
 
        if(!tunnelserver)
-               forward_request(c);
+               forward_request(c, request);
 
        return true;
 }
@@ -161,7 +164,7 @@ bool send_del_subnet(connection_t *c, const subnet_t *s)
        return send_request(c, "%d %lx %s %s", DEL_SUBNET, random(), s->owner->name, netstr);
 }
 
-bool del_subnet_h(connection_t *c)
+bool del_subnet_h(connection_t *c, char *request)
 {
        char subnetstr[MAX_STRING_SIZE];
        char name[MAX_STRING_SIZE];
@@ -170,13 +173,13 @@ bool del_subnet_h(connection_t *c)
 
        cp();
 
-       if(sscanf(c->buffer, "%*d %*x " MAX_STRING " " MAX_STRING, name, subnetstr) != 2) {
+       if(sscanf(request, "%*d %*x " MAX_STRING " " MAX_STRING, name, subnetstr) != 2) {
                logger(LOG_ERR, _("Got bad %s from %s (%s)"), "DEL_SUBNET", c->name,
                           c->hostname);
                return false;
        }
 
-       /* Check if owner name is valid */
+       /* Check if owner name is valid */
 
        if(!check_id(name)) {
                logger(LOG_ERR, _("Got bad %s from %s (%s): %s"), "DEL_SUBNET", c->name,
@@ -184,19 +187,6 @@ bool del_subnet_h(connection_t *c)
                return false;
        }
 
-       /* Check if the owner of the new subnet is in the connection list */
-
-       owner = lookup_node(name);
-
-       if(!owner) {
-               ifdebug(PROTOCOL) logger(LOG_WARNING, _("Got %s from %s (%s) for %s which is not in our node tree"),
-                                  "DEL_SUBNET", c->name, c->hostname, name);
-               return true;
-       }
-
-       if(tunnelserver && owner != myself && owner != c->node)
-               return false;
-
        /* Check if subnet string is valid */
 
        if(!str2net(&s, subnetstr)) {
@@ -205,9 +195,26 @@ bool del_subnet_h(connection_t *c)
                return false;
        }
 
-       if(seen_request(c->buffer))
+       if(seen_request(request))
                return true;
 
+       /* Check if the owner of the subnet being deleted is in the connection list */
+
+       owner = lookup_node(name);
+
+       if(tunnelserver && owner != myself && owner != c->node) {
+               /* in case of tunnelserver, ignore indirect subnet deletion */
+               ifdebug(PROTOCOL) logger(LOG_WARNING, _("Ignoring indirect %s from %s (%s) for %s"),
+                                  "DEL_SUBNET", c->name, c->hostname, subnetstr);
+               return true;
+       }
+
+       if(!owner) {
+               ifdebug(PROTOCOL) logger(LOG_WARNING, _("Got %s from %s (%s) for %s which is not in our node tree"),
+                                  "DEL_SUBNET", c->name, c->hostname, name);
+               return true;
+       }
+
        /* If everything is correct, delete the subnet from the list of the owner */
 
        s.owner = owner;
@@ -232,7 +239,7 @@ bool del_subnet_h(connection_t *c)
        /* Tell the rest */
 
        if(!tunnelserver)
-               forward_request(c);
+               forward_request(c, request);
 
        /* Finally, delete it. */