[network-manager-openvpn/th/tls-remote-workaround-bgo776045: 3/4] service: for OpenVPN 2.4 and newer, handle removed --tls-remote option via --verify-x509-name
- From: Thomas Haller <thaller src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [network-manager-openvpn/th/tls-remote-workaround-bgo776045: 3/4] service: for OpenVPN 2.4 and newer, handle removed --tls-remote option via --verify-x509-name
- Date: Mon, 13 Feb 2017 13:31:28 +0000 (UTC)
commit dbb6f1a33ccbe36cad06df2549dbeeca485da0da
Author: Thomas Haller <thaller redhat com>
Date: Mon Feb 13 12:30:26 2017 +0100
service: for OpenVPN 2.4 and newer, handle removed --tls-remote option via --verify-x509-name
The tls-remote option got removed from OpenVPN 2.4. This requires users
to fix their existing configurations to use verify-x509-name instead.
Using tls-remote on a recent OpenVPN binary thus fails the connection,
which is an annoyance for the user. Let the plugin automatically convert
the "tls-remote $NAME" option to "verify-x509-name $NAME name". Note
that the two options are not entirely equivalent, thus the is a chance
that this wrongly rejects a server that would have worked before, or
ever worse, that it wronlgy accepts a server that should be rejected.
Still do it as in most cases it will probably work correctly.
The user is still strongly encouraged to update his configuration.
https://bugzilla.gnome.org/show_bug.cgi?id=776045
https://bugzilla.redhat.com/show_bug.cgi?id=1421241
src/nm-openvpn-service.c | 87 ++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 85 insertions(+), 2 deletions(-)
---
diff --git a/src/nm-openvpn-service.c b/src/nm-openvpn-service.c
index 29a3ff1..ff9aa70 100644
--- a/src/nm-openvpn-service.c
+++ b/src/nm-openvpn-service.c
@@ -87,6 +87,13 @@ NMOpenvpnPlugin *nm_openvpn_plugin_new (const char *bus_name);
/*****************************************************************************/
+typedef enum {
+ OPENVPN_BINARY_VERSION_INVALID,
+ OPENVPN_BINARY_VERSION_UNKNOWN,
+ OPENVPN_BINARY_VERSION_2_3_OR_OLDER,
+ OPENVPN_BINARY_VERSION_2_4_OR_NEWER,
+} OpenvpnBinaryVersion;
+
typedef struct {
GPid pid;
guint watch_id;
@@ -228,6 +235,64 @@ openvpn_binary_find_exepath (void)
return NULL;
}
+static OpenvpnBinaryVersion
+openvpn_binary_detect_version (const char *exepath)
+{
+ gs_free char *s_stdout = NULL;
+ const char *s;
+ int exit_code;
+ int n;
+
+ g_return_val_if_fail (exepath && exepath[0] == '/', OPENVPN_BINARY_VERSION_UNKNOWN);
+
+ if (!g_spawn_sync (NULL,
+ (char *[]) { (char *) exepath, "--version", NULL },
+ NULL,
+ G_SPAWN_STDERR_TO_DEV_NULL,
+ NULL,
+ NULL,
+ &s_stdout,
+ NULL,
+ &exit_code,
+ NULL))
+ return OPENVPN_BINARY_VERSION_UNKNOWN;
+
+ if ( !WIFEXITED (exit_code)
+ || WEXITSTATUS (exit_code) != 1) {
+ /* expect return code 1 (OPENVPN_EXIT_STATUS_USAGE) */
+ return OPENVPN_BINARY_VERSION_UNKNOWN;
+ }
+
+ /* the output for --version starts with title_string, which starts with PACKAGE_STRING,
+ * which looks like "OpenVPN 2.#...". Do a strict parsing here... */
+ if ( !s_stdout
+ || !g_str_has_prefix (s_stdout, "OpenVPN 2."))
+ return OPENVPN_BINARY_VERSION_UNKNOWN;
+ s = &s_stdout[NM_STRLEN ("OpenVPN 2.")];
+
+ if (!g_ascii_isdigit (s[0]))
+ return OPENVPN_BINARY_VERSION_UNKNOWN;
+
+ n = 0;
+ do {
+ if (n > G_MAXINT / 100)
+ return OPENVPN_BINARY_VERSION_UNKNOWN;
+ n = (n * 10) + (s[0] - '0');
+ } while (g_ascii_isdigit ((++s)[0]));
+
+ if (n <= 3)
+ return OPENVPN_BINARY_VERSION_2_3_OR_OLDER;
+ return OPENVPN_BINARY_VERSION_2_4_OR_NEWER;
+}
+
+static OpenvpnBinaryVersion
+openvpn_binary_detect_version_cached (const char *exepath, OpenvpnBinaryVersion *cached)
+{
+ if (G_UNLIKELY (*cached == OPENVPN_BINARY_VERSION_INVALID))
+ *cached = openvpn_binary_detect_version (exepath);
+ return *cached;
+}
+
/*****************************************************************************/
static void
@@ -1142,12 +1207,14 @@ nm_openvpn_start_openvpn_binary (NMOpenvpnPlugin *plugin,
gboolean dev_type_is_tap;
char *stmp;
const char *defport, *proto_tcp;
+ const char *tls_remote = NULL;
const char *nm_openvpn_user, *nm_openvpn_group, *nm_openvpn_chroot;
gs_free char *bus_name = NULL;
NMSettingVpn *s_vpn;
const char *connection_type;
gint64 v_int64;
char sbuf_64[65];
+ OpenvpnBinaryVersion openvpn_binary_version = OPENVPN_BINARY_VERSION_INVALID;
s_vpn = nm_connection_get_setting_vpn (connection);
if (!s_vpn) {
@@ -1474,8 +1541,17 @@ nm_openvpn_start_openvpn_binary (NMOpenvpnPlugin *plugin,
/* tls-remote */
tmp = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_TLS_REMOTE);
if (tmp && tmp[0]) {
- add_openvpn_arg (args, "--tls-remote");
- add_openvpn_arg (args, tmp);
+ if (openvpn_binary_detect_version_cached (openvpn_binary, &openvpn_binary_version) !=
OPENVPN_BINARY_VERSION_2_4_OR_NEWER) {
+ _LOGW ("the tls-remote option is deprecated and removed from OpenVPN 2.4. Update your
connection to use verify-x509-name");
+ add_openvpn_arg (args, "--tls-remote");
+ add_openvpn_arg (args, tmp);
+ } else {
+ _LOGW ("the tls-remote option is deprecated and removed from OpenVPN 2.4. For
compatibility, the plugin uses \"verify-x509-name\" \"%s\" \"name\" instead. Update your connection to use
verify-x509-name", tmp);
+ add_openvpn_arg (args, "--verify-x509-name");
+ add_openvpn_arg (args, tmp);
+ add_openvpn_arg (args, "name");
+ }
+ tls_remote = tmp;
}
/* verify-x509-name */
@@ -1484,6 +1560,13 @@ nm_openvpn_start_openvpn_binary (NMOpenvpnPlugin *plugin,
const char *name;
gs_free char *type = NULL;
+ if (tls_remote) {
+ g_set_error (error, NM_VPN_PLUGIN_ERROR,
+ NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+ _("Invalid configuration with tls-remote and verify-x509-name."));
+ return FALSE;
+ }
+
name = strchr (tmp, ':');
if (name) {
type = g_strndup (tmp, name - tmp);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]