From 48aaa648751e31defde64995d72cbe755af0e9ad Mon Sep 17 00:00:00 2001 From: Valentin Date: Tue, 2 Oct 2018 16:07:07 +0200 Subject: [PATCH] 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"