]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network/wireguard: do not resolve Endpoint= if an IP address is specified
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 29 Nov 2021 13:07:29 +0000 (22:07 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 1 Dec 2021 23:36:22 +0000 (08:36 +0900)
Also verify the domain name and port.

src/network/netdev/wireguard.c

index f254b05f86efbb724b42df21fb763780961353ba..2a802a3739c8f3197781362560d318f96b0d8ca9 100644 (file)
@@ -12,6 +12,7 @@
 #include "sd-resolve.h"
 
 #include "alloc-util.h"
+#include "dns-domain.h"
 #include "event-util.h"
 #include "fd-util.h"
 #include "fileio.h"
@@ -723,65 +724,90 @@ int config_parse_wireguard_endpoint(
                 void *userdata) {
 
         _cleanup_(wireguard_peer_free_or_set_invalidp) WireguardPeer *peer = NULL;
-        const char *begin, *end;
+        _cleanup_free_ char *host = NULL;
+        union in_addr_union addr;
+        const char *p;
+        uint16_t port;
         Wireguard *w;
-        size_t len;
-        int r;
+        int family, r;
 
-        assert(data);
+        assert(filename);
         assert(rvalue);
+        assert(userdata);
 
-        w = WIREGUARD(data);
+        w = WIREGUARD(userdata);
         assert(w);
 
-        if (rvalue[0] == '[') {
-                begin = &rvalue[1];
-                end = strchr(rvalue, ']');
-                if (!end) {
-                        log_syntax(unit, LOG_WARNING, filename, line, 0,
-                                   "Unable to find matching brace of endpoint, ignoring assignment: %s",
-                                   rvalue);
-                        return 0;
-                }
-                len = end - begin;
-                ++end;
-                if (*end != ':' || !*(end + 1)) {
-                        log_syntax(unit, LOG_WARNING, filename, line, 0,
-                                   "Unable to find port of endpoint, ignoring assignment: %s",
-                                   rvalue);
-                        return 0;
-                }
-                ++end;
-        } else {
-                begin = rvalue;
-                end = strrchr(rvalue, ':');
-                if (!end || !*(end + 1)) {
-                        log_syntax(unit, LOG_WARNING, filename, line, 0,
-                                   "Unable to find port of endpoint, ignoring assignment: %s",
-                                   rvalue);
-                        return 0;
-                }
-                len = end - begin;
-                ++end;
-        }
-
         r = wireguard_peer_new_static(w, filename, section_line, &peer);
         if (r < 0)
                 return log_oom();
 
-        r = free_and_strndup(&peer->endpoint_host, begin, len);
-        if (r < 0)
+        r = in_addr_port_ifindex_name_from_string_auto(rvalue, &family, &addr, &port, NULL, NULL);
+        if (r >= 0) {
+                if (family == AF_INET)
+                        peer->endpoint.in = (struct sockaddr_in) {
+                                .sin_family = AF_INET,
+                                .sin_addr = addr.in,
+                                .sin_port = htobe16(port),
+                        };
+                else if (family == AF_INET6)
+                        peer->endpoint.in6 = (struct sockaddr_in6) {
+                                .sin6_family = AF_INET6,
+                                .sin6_addr = addr.in6,
+                                .sin6_port = htobe16(port),
+                        };
+                else
+                        assert_not_reached();
+
+                peer->endpoint_host = mfree(peer->endpoint_host);
+                peer->endpoint_port = mfree(peer->endpoint_port);
+                set_remove(w->peers_with_unresolved_endpoint, peer);
+
+                TAKE_PTR(peer);
+                return 0;
+        }
+
+        p = strrchr(rvalue, ':');
+        if (!p) {
+                log_syntax(unit, LOG_WARNING, filename, line, 0,
+                           "Unable to find port of endpoint, ignoring assignment: %s",
+                           rvalue);
+                return 0;
+        }
+
+        host = strndup(rvalue, p - rvalue);
+        if (!host)
                 return log_oom();
 
-        r = free_and_strdup(&peer->endpoint_port, end);
+        if (!dns_name_is_valid(host)) {
+                log_syntax(unit, LOG_WARNING, filename, line, 0,
+                           "Invalid domain name of endpoint, ignoring assignment: %s",
+                           rvalue);
+                return 0;
+        }
+
+        p++;
+        r = parse_ip_port(p, &port);
+        if (r < 0) {
+                log_syntax(unit, LOG_WARNING, filename, line, r,
+                           "Invalid port of endpoint, ignoring assignment: %s",
+                           rvalue);
+                return 0;
+        }
+
+        peer->endpoint = (union sockaddr_union) {};
+
+        free_and_replace(peer->endpoint_host, host);
+
+        r = free_and_strdup(&peer->endpoint_port, p);
         if (r < 0)
                 return log_oom();
 
         r = set_ensure_put(&w->peers_with_unresolved_endpoint, NULL, peer);
         if (r < 0)
                 return log_oom();
-        TAKE_PTR(peer); /* The peer may already have been in the hash map, that is fine too. */
 
+        TAKE_PTR(peer); /* The peer may already have been in the hash map, that is fine too. */
         return 0;
 }