From 84727bfec693cfbb0f3194c6b9f84086e414f38b Mon Sep 17 00:00:00 2001 From: Jonathan Date: Thu, 27 Sep 2018 13:46:29 +0200 Subject: [PATCH 1/2] Syntax highlighting --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 63f6dcf..16c9561 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Once the installation is completed, the Plugin can be used per NetworkManager (u When a new WireGuard connection is created and configured via the NetworkManager GUI (can also be called via `nm-connection-editor`), it is the Connection Editor Plugin which is executed. When the connection is activated, it is the service plugin that is being called. -A very basic testing suite is provided in the form of the Python script `examples/dbus/dbus.py`, which looks up the Plugin via name on D-BUS and sends it a Connect() instruction. More or less the same thing (and more) can however be achieved by just using NetworkManager after installing the package, so there should not be a need for this - except for the fact that the script is easily modifiable. +A very basic testing suite is provided in the form of the Python script `examples/dbus/dbus.py`, which looks up the Plugin via name on D-Bus and sends it a Connect() instruction. More or less the same thing (and more) can however be achieved by just using NetworkManager after installing the package, so there should not be a need for this - except for the fact that the script is easily modifiable. ### Viewing Logs @@ -41,18 +41,18 @@ The logs that are created by NetworkManager can be viewed with `journalctl -u Ne Over the course of the project, I created some files that are not required for the project itself, but rather for its development. Here is a brief overview over some of them: * `includes2strings.py`: Searches the input for `-I` flags (useful for extracting the include dirs from a Makefile) -* `examples/dbus/dbus.py`: A small script that tests the availability of the Plugin and its responsiveness to D-BUS messages +* `examples/dbus/dbus.py`: A small script that tests the availability of the Plugin and its responsiveness to D-Bus messages ### Configuration -#### D-BUS Allowance +#### D-Bus Allowance -D-BUS does not allow just anybody to own any D-BUS service name they like. Thus, it may be necessary to tell D-BUS that it is not forbidden to use the name `org.freedesktop.NetworkManager.wireguard`. +D-Bus does not allow just anybody to own any D-Bus service name they like. Thus, it may be necessary to tell D-Bus that it is not forbidden to use the name `org.freedesktop.NetworkManager.wireguard`. This can be achieved by placing an appropriate file (like `nm-wireguard-service.conf`) inside the directory `/etc/dbus-1/system.d` or similar. The following is an example for the content of such a file: -~~~~ +~~~~xml @@ -72,7 +72,7 @@ The following is an example for the content of such a file: NetworkManager has to be told where the plugins live in order to be able to call them. This is done via `service.name` files, which usually reside in `/etc/NetworkManager/VPN` or `/usr/lib/NetworkManager/VPN` (e.g. `/usr/lib/NetworkManager/VPN/nm-wireguard-service.name`). An example for the content of these files would be: -~~~~ +~~~~ini # This file is obsoleted by a file in /usr/local/lib/NetworkManager/VPN [VPN Connection] @@ -98,10 +98,10 @@ supports-hints=false ### Service (the Plugin itself) -The service is responsible for setting up a VPN connection with the supplied parameters. For this, it has to implement a [D-BUS interface](https://developer.gnome.org/NetworkManager/stable/gdbus-org.freedesktop.NetworkManager.VPN.Plugin.html) and listen to incoming requests, which will be sent by NetworkManager in due time (i.e. when the user tells NM to set up the appropriate VPN connection). +The service is responsible for setting up a VPN connection with the supplied parameters. For this, it has to implement a [D-Bus interface](https://developer.gnome.org/NetworkManager/stable/gdbus-org.freedesktop.NetworkManager.VPN.Plugin.html) and listen to incoming requests, which will be sent by NetworkManager in due time (i.e. when the user tells NM to set up the appropriate VPN connection). If the binary service is not running at the time when NM wants to set up the connection, it will try to start the binary ad hoc. -In principle, this piece of software can be written in any language, but in order to make the implementation sane, there should at least exist convenient D-BUS bindings for the language. Further, there are parts of the code already implemented in C, which might make it more convenient to just stick to that. +In principle, this piece of software can be written in any language, but in order to make the implementation sane, there should at least exist convenient D-Bus bindings for the language. Further, there are parts of the code already implemented in C, which might make it more convenient to just stick to that. ### Auth-Dialog @@ -157,7 +157,7 @@ Saved connections are stored in `/etc/NetworkManager/system-connections`, with o This guarantees that nobody can have a look at the saved system-wide connections (and their stored secrets) that isn't supposed to. An example of such a system-connection file would be (one can see that the user-input data is stored as key-value pairs with internally used keys in the vpn section): -~~~~ +~~~~ini [connection] id=wiretest uuid=8298d5ea-73d5-499b-9376-57409a7a2331 From 48aaa648751e31defde64995d72cbe755af0e9ad Mon Sep 17 00:00:00 2001 From: Valentin Date: Tue, 2 Oct 2018 16:07:07 +0200 Subject: [PATCH 2/2] Support for Persistent Keep Alive parameter --- properties/nm-wireguard-dialog.ui | 39 ++++++++++++++++++++++++++++ properties/nm-wireguard-editor.c | 34 +++++++++++++++++++++++- shared/import-export.c | 43 ++++++++++++++++++++++++++++++- shared/nm-service-defines.h | 1 + shared/utils.h | 1 + 5 files changed, 116 insertions(+), 2 deletions(-) diff --git a/properties/nm-wireguard-dialog.ui b/properties/nm-wireguard-dialog.ui index 1639fbd..24ea69e 100644 --- a/properties/nm-wireguard-dialog.ui +++ b/properties/nm-wireguard-dialog.ui @@ -2323,6 +2323,45 @@ config: http-proxy-retry or socks-proxy-retry 4 + + + True + False + + + True + False + Persis. Keepalive: + 15 + 15 + + + + + + False + False + 0 + + + + + True + True + + + True + True + 1 + + + + + False + True + 4 + + False diff --git a/properties/nm-wireguard-editor.c b/properties/nm-wireguard-editor.c index a2e780c..68e3283 100644 --- a/properties/nm-wireguard-editor.c +++ b/properties/nm-wireguard-editor.c @@ -98,6 +98,19 @@ check_interface_mtu_entry(const char *str) return TRUE; } +static gboolean +check_peer_persistent_keep_alive_entry(const char *str) +{ + if(is_empty(str)){ + return TRUE; + } + else if(!g_ascii_string_to_unsigned(str, 10, 0, 450, NULL, NULL)){ + return FALSE; + } + + return TRUE; +} + static gboolean check_peer_preshared_key(const char *str) { @@ -269,6 +282,9 @@ check_validity (WireguardEditor *self, GError **error) if(!check(priv, "peer_psk_entry", check_peer_preshared_key, NM_WG_KEY_PRESHARED_KEY, TRUE, error)){ success = FALSE; } + if(!check(priv, "peer_persistent_keep_alive_entry", check_peer_persistent_keep_alive_entry, NM_WG_KEY_PERSISTENT_KEEP_ALIVE, TRUE, error)){ + success = FALSE; + } // pre-up, post-up, pre-down, post-down are scripts and don't get validated if(ip4_ok && ip6_ok){ @@ -359,7 +375,7 @@ init_editor_plugin (WireguardEditor *self, NMConnection *connection, GError **er } g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self); - // Interface Private Key + // Interface MTU widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_mtu_entry")); g_return_val_if_fail (widget != NULL, FALSE); if (s_vpn) { @@ -439,6 +455,15 @@ init_editor_plugin (WireguardEditor *self, NMConnection *connection, GError **er } g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self); + // Peer Persistent Keep Alive + widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "peer_persistent_keep_alive_entry")); + g_return_val_if_fail (widget != NULL, FALSE); + if (s_vpn) { + value = nm_setting_vpn_get_data_item (s_vpn, NM_WG_KEY_PERSISTENT_KEEP_ALIVE); + if (value) + gtk_entry_set_text (GTK_ENTRY (widget), value); + } + g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self); // Peer Public Key widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "peer_public_key_entry")); @@ -602,6 +627,13 @@ update_connection (NMVpnEditor *iface, if (str && str[0]){ nm_setting_vpn_add_data_item (s_vpn, NM_WG_KEY_ENDPOINT, str); } + + // persistent keep alive + widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "peer_persistent_keep_alive_entry")); + str = gtk_entry_get_text (GTK_ENTRY (widget)); + if (str && str[0]){ + nm_setting_vpn_add_data_item (s_vpn, NM_WG_KEY_PERSISTENT_KEEP_ALIVE, str); + } nm_connection_add_setting (connection, NM_SETTING (s_vpn)); valid = TRUE; diff --git a/shared/import-export.c b/shared/import-export.c index 9d0ecda..41cdfbc 100644 --- a/shared/import-export.c +++ b/shared/import-export.c @@ -567,6 +567,30 @@ parse_mtu(const char **line, guint64 *mtu, char **out_error) return success; } + +// parse Persistent Keep Alive value (max 0-5min? (450)) +static gboolean +parse_persistent_keep_alive(const char **line, guint64 *pka, char **out_error) +{ + int idx = 0; + char *tmp = NULL; + gboolean success = TRUE; + + if(!_parse_common(line, &idx, out_error)){ + return FALSE; + } + + tmp = g_strdup(line[idx]); + if(!g_ascii_string_to_unsigned(tmp, 10, 0, 450, pka, NULL)){ + *out_error = g_strdup_printf("'%s' is not a valid Persistent Keep Alive assignment! (max '%d')", tmp, 450); + *pka = -1; + success = FALSE; + } + + g_free(tmp); + return success; +} + // parse the line and check if there were any IP4 and IP6 included // (if there are more than just one IP4, the later take precedence; same for IP6) // @@ -876,7 +900,7 @@ do_import (const char *path, const char *contents, gsize contents_len, GError ** } setting_vpn_add_data_item_int64(s_vpn, NM_WG_KEY_MTU, mtu); - printf("%s = %ld\n", NM_WG_KEY_DNS, mtu); + printf("%s = %ld\n", NMV_WG_TAG_MTU, mtu); continue; } @@ -1005,6 +1029,17 @@ do_import (const char *path, const char *contents, gsize contents_len, GError ** printf("%s = %s\n", NMV_WG_TAG_PRESHARED_KEY, psk); continue; } + + if (NM_IN_STRSET (params[0], NMV_WG_TAG_PERSISTENT_KEEP_ALIVE)){ + guint64 pka = 0; + if(!parse_persistent_keep_alive(params, &pka, &line_error)){ + goto handle_line_error; + } + + setting_vpn_add_data_item_int64(s_vpn, NM_WG_KEY_PERSISTENT_KEEP_ALIVE, pka); + printf("%s = %lu\n", NMV_WG_TAG_PERSISTENT_KEEP_ALIVE, pka); + continue; + } /* currently we ignore any unknown options and skip over them. */ continue; @@ -1118,6 +1153,7 @@ create_config_string (NMConnection *connection, GError **error) const char *allowed_ips; const char *endpoint; const char *psk; + const char *pka; char *value = NULL; char **ip_list, **ip_iter; GArray *ips; @@ -1143,6 +1179,7 @@ create_config_string (NMConnection *connection, GError **error) allowed_ips = _arg_is_set(nm_setting_vpn_get_data_item(s_vpn, NM_WG_KEY_ALLOWED_IPS)); endpoint = _arg_is_set(nm_setting_vpn_get_data_item(s_vpn, NM_WG_KEY_ENDPOINT)); psk = _arg_is_set(nm_setting_vpn_get_data_item(s_vpn, NM_WG_KEY_PRESHARED_KEY)); + pka = _arg_is_set(nm_setting_vpn_get_data_item(s_vpn, NM_WG_KEY_PERSISTENT_KEEP_ALIVE)); if(!ip4 && !ip6){ g_set_error_literal(error, @@ -1233,6 +1270,10 @@ create_config_string (NMConnection *connection, GError **error) if(psk){ args_write_line(f, NMV_WG_TAG_PRESHARED_KEY, "=", psk); } + + if(pka && *pka > 0){ + args_write_line(f, NMV_WG_TAG_PERSISTENT_KEEP_ALIVE, "=", pka); + } return g_steal_pointer (&f); } diff --git a/shared/nm-service-defines.h b/shared/nm-service-defines.h index d2cdbb4..7f5a240 100644 --- a/shared/nm-service-defines.h +++ b/shared/nm-service-defines.h @@ -42,6 +42,7 @@ #define NM_WG_KEY_ALLOWED_IPS "peer-allowed-ips" #define NM_WG_KEY_ENDPOINT "peer-endpoint" #define NM_WG_KEY_PRESHARED_KEY "peer-preshared-key" +#define NM_WG_KEY_PERSISTENT_KEEP_ALIVE "peer-persistent-keep-alive" #define NM_OPENVPN_KEY_AUTH "auth" #define NM_OPENVPN_KEY_CA "ca" diff --git a/shared/utils.h b/shared/utils.h index 4c542cd..a1170ce 100644 --- a/shared/utils.h +++ b/shared/utils.h @@ -37,6 +37,7 @@ #define NMV_WG_TAG_PUBLIC_KEY "PublicKey" #define NMV_WG_TAG_ALLOWED_IPS "AllowedIPs" #define NMV_WG_TAG_ENDPOINT "Endpoint" +#define NMV_WG_TAG_PERSISTENT_KEEP_ALIVE "PersistentKeepalive" #define NMV_OVPN_TAG_AUTH "auth" #define NMV_OVPN_TAG_AUTH_NOCACHE "auth-nocache"