Send connman mailing list submissions to
        [email protected]

To subscribe or unsubscribe via email, send a message with subject or
body 'help' to
        [email protected]

You can reach the person managing the list at
        [email protected]

When replying, please edit your Subject line so it is more specific
than "Re: Contents of connman digest..."

Today's Topics:

   1. [PATCH v1 10/11] doc: Document WireGuard VPN plugin
      (Daniel Wagner)
   2. [PATCH v1 11/11] vpn: Add WireGuard support (Daniel Wagner)
   3. The order of a OpenVpn service with topology subnet cannot be changed due 
to a missing route
      (Thomas Achleitner)
   4. Re: The order of a OpenVpn service with topology subnet cannot be changed 
due to a missing route
      (Daniel Wagner)
   5. [PATCH] timeserver: reload nameservers when service nameservers change
      (Vivien Henriet)
   6. [PATCH] timeserver: reload nameservers when service nameservers change
      (Vivien Henriet)


----------------------------------------------------------------------

Date: Tue,  5 Nov 2019 11:26:30 +0100
From: Daniel Wagner <[email protected]>
Subject: [PATCH v1 10/11] doc: Document WireGuard VPN plugin
To: [email protected]
Cc: Daniel Wagner <[email protected]>
Message-ID: <[email protected]>

---
 doc/vpn-config-format.txt | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/doc/vpn-config-format.txt b/doc/vpn-config-format.txt
index 13a88bc7310c..d92cdc0bb2a3 100644
--- a/doc/vpn-config-format.txt
+++ b/doc/vpn-config-format.txt
@@ -279,6 +279,16 @@ PPTP VPN supports following options (see pptp(8) and 
pppd(8) for details)
  PPPD.NoVJ           novj                 No Van Jacobson compression (O)
 
 
+WireGuard VPN supports following options
+ Option name                              Description
+ WireGuard.Address                        Internal IP address 
(local/netmask/peer)
+ WireGuard.ListPort                       Local listen port (optional)
+ WireGuard.PrivateKey                     Private key of interface
+ WireGuard.PublicKey                      Public key of peer
+ WireGuard.AllowedIPs                     See Cryptokey Routing
+ WireGuard.EndpointPort                   Endpoint listen port (optional)
+
+
 Example
 =======
 
@@ -317,3 +327,15 @@ Domain = my.home.network
 OpenVPN.CACert = /etc/certs/cacert.pem
 OpenVPN.Cert = /etc/certs/cert.pem
 OpenVPN.Key = /etc/certs/cert.key
+
+[provider_wireguard]
+Type = WireGuard
+Name = Wireguard VPN Tunnel
+Host = 3.2.5.6
+Domain = my.home.network
+WireGuard.Address = 10.2.0.2/24
+WireGuard.ListenPort = 47824
+WireGuard.PrivateKey = qKIj010hDdWSjQQyVCnEgthLXusBgm3I6HWrJUaJymc=
+WireGuard.PublicKey = zzqUfWGIil6QxrAGz77HE5BGUEdD2PgHYnCg3CDKagE=
+WireGuard.AllowedIPs = 0.0.0.0/0, ::/0
+WireGuard.EndpointPort = 51820
-- 
2.23.0

------------------------------

Date: Tue,  5 Nov 2019 11:26:38 +0100
From: Daniel Wagner <[email protected]>
Subject: [PATCH v1 11/11] vpn: Add WireGuard support
To: [email protected]
Cc: Daniel Wagner <[email protected]>
Message-ID: <[email protected]>

Implement a bare minimum for WireGuard support. The parser only
understands minium, e.g. only one peer. To create and manage the
WireGuard devices the upstream example code is used.
---
 vpn/plugins/wireguard.c | 330 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 329 insertions(+), 1 deletion(-)

diff --git a/vpn/plugins/wireguard.c b/vpn/plugins/wireguard.c
index e110eb545943..e55f2fcc8bf9 100644
--- a/vpn/plugins/wireguard.c
+++ b/vpn/plugins/wireguard.c
@@ -21,24 +21,352 @@
 #include <config.h>
 #endif
 
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <net/if.h>
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
 #include <glib.h>
 
 #define CONNMAN_API_SUBJECT_TO_CHANGE
 #include <connman/plugin.h>
+#include <connman/log.h>
 #include <connman/task.h>
+#include <connman/ipconfig.h>
+#include <connman/inet.h>
 #include <connman/dbus.h>
+#include <connman/setting.h>
 #include <connman/vpn-dbus.h>
 
+#include "../vpn-provider.h"
+#include "../vpn.h"
+
 #include "vpn.h"
 #include "wireguard.h"
 
-static int wg_init(void)
+static int parse_key(const char *str, wg_key key)
 {
+       unsigned char *buf;
+       size_t len;
+
+       buf = g_base64_decode(str, &len);
+
+       if (len != 32) {
+               g_free(buf);
+               return -EINVAL;
+       }
+
+       memcpy(key, buf, 32);
+
+       g_free(buf);
        return 0;
 }
 
+static int parse_allowed_ips(const char *allowed_ips, wg_peer *peer)
+{
+       struct wg_allowedip *curaip, *allowedip;
+       char buf[INET6_ADDRSTRLEN];
+       char **tokens, **toks;
+       char *send;
+       int i;
+
+       curaip = NULL;
+       tokens = g_strsplit(allowed_ips, ", ", -1);
+       for (i = 0; tokens[i]; i++) {
+               toks = g_strsplit(tokens[i], "/", -1);
+               if (g_strv_length(toks) != 2) {
+                       DBG("Ignore AllowedIPs value %s", tokens[i]);
+                       g_strfreev(toks);
+                       continue;
+               }
+
+               allowedip = g_malloc0(sizeof(*allowedip));
+
+               if (inet_pton(AF_INET, toks[0], buf) == 1) {
+                       allowedip->family = AF_INET;
+                       memcpy(&allowedip->ip4, buf, sizeof(allowedip->ip4));
+               } else if (inet_pton(AF_INET6, toks[0], buf) == 1) {
+                       allowedip->family = AF_INET6;
+                       memcpy(&allowedip->ip6, buf, sizeof(allowedip->ip6));
+               } else {
+                       DBG("Ignore AllowedIPs value %s", tokens[i]);
+                       g_free(allowedip);
+                       g_strfreev(toks);
+                       continue;
+               }
+
+               allowedip->cidr = g_ascii_strtoull(toks[1], &send, 10);
+
+               if (!curaip)
+                       peer->first_allowedip = allowedip;
+               else
+                       curaip->next_allowedip = allowedip;
+
+               curaip = allowedip;
+       }
+
+       peer->last_allowedip = curaip;
+       g_strfreev(tokens);
+
+       return 0;
+}
+
+static int parse_endpoint(const char *host, const char *port, wg_peer *peer)
+{
+       struct addrinfo hints;
+       struct addrinfo *result, *rp;
+       int sk;
+
+       memset(&hints, 0, sizeof(struct addrinfo));
+       hints.ai_family = AF_UNSPEC;
+       hints.ai_socktype = SOCK_DGRAM;
+       hints.ai_flags = 0;
+       hints.ai_protocol = 0;
+
+       if (getaddrinfo(host, port, &hints, &result) < 0) {
+               DBG("Failed to resolve host address");
+               return -EINVAL;
+       }
+
+       for (rp = result; rp; rp = rp->ai_next) {
+               sk = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
+               if (sk < 0)
+                       continue;
+               if (connect(sk, rp->ai_addr, rp->ai_addrlen) != -1) {
+                       /* success */
+                       close(sk);
+                       break;
+               }
+
+               close(sk);
+       }
+       freeaddrinfo(result);
+
+       if (!rp)
+               return -EINVAL;
+
+       memcpy(&peer->endpoint.addr, rp->ai_addr, rp->ai_addrlen);
+
+       return 0;
+}
+
+static int parse_address(const char *address, const char *gateway,
+               struct connman_ipaddress **ipaddress)
+{
+       char buf[INET6_ADDRSTRLEN];
+       unsigned char prefixlen;
+       char **tokens;
+       char *end, *netmask;
+       int err;
+
+       tokens = g_strsplit(address, "/", -1);
+       if (g_strv_length(tokens) != 2) {
+               g_strfreev(tokens);
+               return -EINVAL;
+       }
+
+       prefixlen = g_ascii_strtoull(tokens[1], &end, 10);
+
+       if (inet_pton(AF_INET, tokens[0], buf) == 1) {
+               netmask = g_strdup_printf("%d.%d.%d.%d",
+                               ((0xffffffff << (32 - prefixlen)) >> 24) & 0xff,
+                               ((0xffffffff << (32 - prefixlen)) >> 16) & 0xff,
+                               ((0xffffffff << (32 - prefixlen)) >> 8) & 0xff,
+                               ((0xffffffff << (32 - prefixlen)) >> 0) & 0xff);
+
+               *ipaddress = connman_ipaddress_alloc(AF_INET);
+               err = connman_ipaddress_set_ipv4(*ipaddress, tokens[0],
+                                               netmask, gateway);
+               g_free(netmask);
+       } else if (inet_pton(AF_INET6, tokens[0], buf) == 1) {
+               *ipaddress = connman_ipaddress_alloc(AF_INET6);
+               err = connman_ipaddress_set_ipv6(*ipaddress, tokens[0],
+                                               prefixlen, gateway);
+       } else {
+               DBG("Invalid Wireguard.Address value");
+               err = -EINVAL;
+       }
+
+       g_strfreev(tokens);
+       if (err)
+               connman_ipaddress_free(*ipaddress);
+
+       return err;
+}
+
+struct ifname_data {
+       char *ifname;
+       bool found;
+};
+
+static void ifname_check_cb(int index, void *user_data)
+{
+       struct ifname_data *data = (struct ifname_data *)user_data;
+       char *ifname;
+
+       ifname = connman_inet_ifname(index);
+
+       if (!g_strcmp0(ifname, data->ifname))
+               data->found = true;
+}
+
+static char *get_ifname(void)
+{
+       struct ifname_data data;
+       int i;
+
+       for (i = 0; i < 256; i++) {
+               data.ifname = g_strdup_printf("wg%d", i);
+               data.found = false;
+               __vpn_ipconfig_foreach(ifname_check_cb, &data);
+
+               if (!data.found)
+                       return data.ifname;
+
+               g_free(data.ifname);
+       }
+
+       return NULL;
+}
+
+struct wireguard_info {
+       struct wg_device device;
+       struct wg_peer peer;
+};
+
+static int wg_connect(struct vpn_provider *provider,
+                       struct connman_task *task, const char *if_name,
+                       vpn_provider_connect_cb_t cb,
+                       const char *dbus_sender, void *user_data)
+{
+       struct connman_ipaddress *ipaddress = NULL;
+       struct wireguard_info *info;
+       const char *option, *gateway;
+       char *ifname;
+       int err = -EINVAL;
+
+       info = g_malloc(sizeof(struct wireguard_info));
+       info->peer.flags = WGPEER_HAS_PUBLIC_KEY | WGPEER_REPLACE_ALLOWEDIPS;
+       info->device.flags = WGDEVICE_HAS_PRIVATE_KEY | 
WGDEVICE_HAS_LISTEN_PORT;
+       info->device.first_peer = &info->peer;
+       info->device.last_peer = &info->peer;
+
+       vpn_provider_set_plugin_data(provider, info);
+
+       option = vpn_provider_get_string(provider, "WireGuard.ListenPort");
+       if (option) {
+               char *end;
+               info->device.listen_port = g_ascii_strtoull(option, &end, 10);
+       }
+
+       option = vpn_provider_get_string(provider, "WireGuard.PrivateKey");
+       if (!option) {
+               DBG("WireGuard.PrivateKey is missing");
+               goto done;
+       }
+       err = parse_key(option, info->device.private_key);
+       if (err)
+               goto done;
+
+       option = vpn_provider_get_string(provider, "WireGuard.PublicKey");
+       if (!option) {
+               DBG("WireGuard.PublicKey is missing");
+               goto done;
+       }
+       err = parse_key(option, info->peer.public_key);
+       if (err)
+               goto done;
+
+       option = vpn_provider_get_string(provider, "WireGuard.AllowedIPs");
+       if (!option) {
+               DBG("WireGuard.AllowedIPs is missing");
+               goto done;
+       }
+       err = parse_allowed_ips(option, &info->peer);
+       if (err)
+               goto done;
+
+       option = vpn_provider_get_string(provider, "Wireguard.EndpointPort");
+       if (!option)
+               option = "51820";
+
+       gateway = vpn_provider_get_string(provider, "Host");
+       err = parse_endpoint(gateway, option, &info->peer);
+       if (err)
+               goto done;
+
+       option = vpn_provider_get_string(provider, "WireGuard.Address");
+       if (!option) {
+               DBG("Missing WireGuard.Address configuration");
+               goto done;
+       }
+       err = parse_address(option, gateway, &ipaddress);
+       if (err)
+               goto done;
+
+       ifname = get_ifname();
+       if (!ifname) {
+               DBG("Failed to find an usable device name");
+               err = -ENOENT;
+               goto done;
+       }
+       stpncpy(info->device.name, ifname, sizeof(info->device.name));
+       g_free(ifname);
+
+       err = wg_add_device(info->device.name);
+       if (err) {
+               DBG("Failed to creating WireGuard device %s", 
info->device.name);
+               goto done;
+       }
+
+       err = wg_set_device(&info->device);
+       if (err) {
+               DBG("Failed to configure WireGuard device %s", 
info->device.name);
+               wg_del_device(info->device.name);
+       }
+
+       vpn_set_ifname(provider, info->device.name);
+       if (ipaddress)
+               vpn_provider_set_ipaddress(provider, ipaddress);
+
+done:
+       if (cb)
+               cb(provider, user_data, err);
+
+       connman_ipaddress_free(ipaddress);
+
+       return err;
+}
+
+static void wg_disconnect(struct vpn_provider *provider)
+{
+       struct wireguard_info *info;
+
+       info = vpn_provider_get_plugin_data(provider);
+       wg_del_device(info->device.name);
+
+       g_free(info);
+}
+
+static struct vpn_driver vpn_driver = {
+       .flags          = VPN_FLAG_NO_TUN | VPN_FLAG_NO_DAEMON,
+       .connect        = wg_connect,
+       .disconnect     = wg_disconnect,
+};
+
+static int wg_init(void)
+{
+       return vpn_register("wireguard", &vpn_driver, NULL);
+}
+
 static void wg_exit(void)
 {
+       vpn_unregister("wireguard");
 }
 
 CONNMAN_PLUGIN_DEFINE(wireguard, "WireGuard VPN plugin", VERSION,
-- 
2.23.0

------------------------------

Date: Tue, 5 Nov 2019 13:15:29 +0100
From: Thomas Achleitner <[email protected]>
Subject: The order of a OpenVpn service with topology subnet cannot be
        changed due to a missing route
To: connman <[email protected]>
Message-ID: <[email protected]>
Content-Type: text/plain; charset="utf-8"; format=flowed

Hi,


one of our clients uses a server configuration with topology subnet and 
does not push a route from server.

This causes an error when moving the vpn service below the ethernet service

and the default gateway then is the vpn connection.


 From the openvpn log i get

Tue Nov  5 09:29:02 2019 SENT CONTROL [test.vpn]: 'PUSH_REQUEST' (status=1)
Tue Nov  5 09:29:02 2019 PUSH: Received control message: 
'PUSH_REPLY,route-gateway 10.8.0.1,topology subnet,ping 10,ping-restart 
120,ifconfig 10.8.0.3 255.255.255.0,peer-id 0'


and the journalctl log states

Nov 05 11:19:46 blue-x21150002 connmand[278]: vpn0 {create} index 12 
type 65534 <NONE>
Nov 05 11:19:46 blue-x21150002 connmand[278]: vpn0 {update} flags 4240 
<DOWN>
Nov 05 11:19:46 blue-x21150002 connmand[278]: vpn0 {newlink} index 12 
address 00:00:00:00:00:00 mtu 1500
Nov 05 11:19:46 blue-x21150002 connmand[278]: vpn0 {newlink} index 12 
operstate 2 <DOWN>
Nov 05 11:19:47 blue-x21150002 connman-vpnd[259]: vpn0 {create} index 12 
type 65534 <NONE>
Nov 05 11:19:47 blue-x21150002 connman-vpnd[259]: vpn0 {update} flags 
4240 <DOWN>
Nov 05 11:19:47 blue-x21150002 connman-vpnd[259]: vpn0 {newlink} index 
12 operstate 2 <DOWN>
Nov 05 11:19:49 blue-x21150002 connmand[278]: vpn0 {update} flags 102609 
<UP,RUNNING,LOWER_UP>
Nov 05 11:19:49 blue-x21150002 connmand[278]: vpn0 {newlink} index 12 
address 00:00:00:00:00:00 mtu 1500
Nov 05 11:19:49 blue-x21150002 connmand[278]: vpn0 {newlink} index 12 
operstate 6 <UP>
Nov 05 11:19:49 blue-x21150002 connman-vpnd[259]: vpn0 {update} flags 
102609 <UP,RUNNING,LOWER_UP>
Nov 05 11:19:49 blue-x21150002 connman-vpnd[259]: vpn0 {newlink} index 
12 operstate 6 <UP>
Nov 05 11:19:49 blue-x21150002 connmand[278]: vpn0 {add} address 
10.8.0.3/24 label vpn0 family 2
Nov 05 11:19:49 blue-x21150002 connmand[278]: vpn0 {add} route 10.8.0.0 
gw 0.0.0.0 scope 253 <LINK>
Nov 05 11:19:50 blue-x21150002 connmand[278]: Setting domainname to test.vpn
Nov 05 11:19:50 blue-x21150002 connmand[278]: ipconfig state 4 ipconfig 
method 1
Nov 05 11:19:50 blue-x21150002 connmand[278]: eth0 {add} route 
185.48.116.146 gw 192.168.30.4 scope 0 <UNIVERSE>
Nov 05 11:19:50 blue-x21150002 connmand[278]: eth0 {del} route 0.0.0.0 
gw 192.168.30.4 scope 0 <UNIVERSE>
Nov 05 11:19:50 blue-x21150002 connmand[278]: vpn0 {add} route 0.0.0.0 
gw 0.0.0.0 scope 253 <LINK>
Nov 05 11:19:50 blue-x21150002 connmand[278]: Cannot move service. No 
routes defined for provider test_vpn_test_vpn

i wrote a patch for removing the check and after applying the connection 
works

--- a/src/service.c 2019-11-05 12:31:42.310731141 +0100
+++ b/src/service.c 2019-11-05 12:34:54.042859743 +0100
@@ -4820,17 +4820,6 @@
          return __connman_error_invalid_service(msg);

      if (target->type == CONNMAN_SERVICE_TYPE_VPN) {
-        /*
-         * We only allow VPN route splitting if there are
-         * routes defined for a given VPN.
-         */
-        if (!__connman_provider_check_routes(target->provider)) {
-            connman_info("Cannot move service. "
-                "No routes defined for provider %s",
- __connman_provider_get_ident(target->provider));
-            return __connman_error_invalid_service(msg);
-        }
-
          set_split_routing(target, true);
      } else
          set_split_routing(target, false);



Can this cause any other trouble?


Thank you!


Best regards,

Thomas


------------------------------

Date: Tue, 5 Nov 2019 18:13:12 +0100
From: Daniel Wagner <[email protected]>
Subject: Re: The order of a OpenVpn service with topology subnet
        cannot be changed due to a missing route
To: Thomas Achleitner <[email protected]>
Cc: connman <[email protected]>
Message-ID: <[email protected]>
Content-Type: text/plain; charset=iso-8859-1

Hi Thomas,

On Tue, Nov 05, 2019 at 01:15:29PM +0100, Thomas Achleitner wrote:
> i wrote a patch for removing the check and after applying the connection
> works
> 
> --- a/src/service.c 2019-11-05 12:31:42.310731141 +0100
> +++ b/src/service.c 2019-11-05 12:34:54.042859743 +0100
> @@ -4820,17 +4820,6 @@
>          return __connman_error_invalid_service(msg);
> 
>      if (target->type == CONNMAN_SERVICE_TYPE_VPN) {
> -        /*
> -         * We only allow VPN route splitting if there are
> -         * routes defined for a given VPN.
> -         */
> -        if (!__connman_provider_check_routes(target->provider)) {
> -            connman_info("Cannot move service. "
> -                "No routes defined for provider %s",
> - __connman_provider_get_ident(target->provider));
> -            return __connman_error_invalid_service(msg);
> -        }
> -
>          set_split_routing(target, true);
>      } else
>          set_split_routing(target, false);
> 
> 
> 
> Can this cause any other trouble?

The check is there to make sure ConnMan is able to reach the VPN
provider. If the server is reachable it all will work just
find. Though this is only possible in this specific network setup.

One thing you should do is verify with tcpdump/wireshark, that your
traffic is on the right interface.

Thanks,
Daniel

------------------------------

Date: Tue,  5 Nov 2019 20:24:12 +0100
From: Vivien Henriet <[email protected]>
Subject: [PATCH] timeserver: reload nameservers when service
        nameservers change
To: [email protected]
Cc: Vivien Henriet <[email protected]>
Message-ID: <[email protected]>

This is to fix an issue where connman is unable to resolve ntp hostnames.
When a service switch from a autoconf link local address (169.254.0.0/16)
to an address configured by dhcp, timeserver was not notified and thus
was not reloaded its resolver's nameserver. As a consequence, hostnames
of ntp server were not resolved.

Change-Id: Icfcaba44de922947d03e507008921011bab014d5
---
 src/service.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/src/service.c b/src/service.c
index 552b788f..b7a69f10 100644
--- a/src/service.c
+++ b/src/service.c
@@ -997,8 +997,12 @@ static int nameservers_changed_cb(void *user_data)
 
        service->nameservers_timeout = 0;
        if ((is_idle(service->state) && !service->nameservers) ||
-                       is_connected(service->state))
-               dns_changed(service);
+                       is_connected(service->state)) {
+    dns_changed(service);
+    if (service == connman_service_get_default())
+      __connman_timeserver_sync(service);
+  }
+
 
        return FALSE;
 }
-- 
2.21.0

------------------------------

Date: Tue,  5 Nov 2019 20:27:18 +0100
From: Vivien Henriet <[email protected]>
Subject: [PATCH] timeserver: reload nameservers when service
        nameservers change
To: [email protected]
Cc: Vivien Henriet <[email protected]>
Message-ID: <[email protected]>

This is to fix an issue where connman is unable to resolve ntp hostnames.
When a service switch from a autoconf link local address (169.254.0.0/16)
to an address configured by dhcp, timeserver was not notified and thus
was not reloaded its resolver's nameserver. As a consequence, hostnames
of ntp server were not resolved.

Change-Id: Icfcaba44de922947d03e507008921011bab014d5
---
 src/service.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/service.c b/src/service.c
index 552b788f..7e1446b7 100644
--- a/src/service.c
+++ b/src/service.c
@@ -997,8 +997,12 @@ static int nameservers_changed_cb(void *user_data)
 
        service->nameservers_timeout = 0;
        if ((is_idle(service->state) && !service->nameservers) ||
-                       is_connected(service->state))
+                       is_connected(service->state)) {
                dns_changed(service);
+               if (service == connman_service_get_default())
+                       __connman_timeserver_sync(service);
+       }
+
 
        return FALSE;
 }
-- 
2.21.0

------------------------------

Subject: Digest Footer

_______________________________________________
connman mailing list -- [email protected]
To unsubscribe send an email to [email protected]


------------------------------

End of connman Digest, Vol 49, Issue 5
**************************************

Reply via email to