[network-manager-openvpn/bgo685790] core/ui: add 'remote-cert-tls' option (bgo #685790)
- From: JiÅÃ KlimeÅ <jklimes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [network-manager-openvpn/bgo685790] core/ui: add 'remote-cert-tls' option (bgo #685790)
- Date: Fri, 2 Nov 2012 14:01:57 +0000 (UTC)
commit 93ba531cd375cd35c8e7942a97989f5223971846
Author: JiÅÃ KlimeÅ <jklimes redhat com>
Date: Fri Nov 2 13:17:38 2012 +0100
core/ui: add 'remote-cert-tls' option (bgo #685790)
We already support 'tls-remote', i.e. verifying server's X509/common name.
However, it make sense to support 'remote-cert-tls' as well. It's another
important security option to protect against MITM attacks. For more info see
http://openvpn.net/index.php/open-source/documentation/howto.html#mitm
properties/auth-helpers.c | 74 ++++++++++++++++++++++++++++
properties/import-export.c | 23 +++++++++
properties/nm-openvpn-dialog.ui | 87 ++++++++++++++++++++++++++++++++-
properties/tests/conf/tls.ovpn | 1 +
properties/tests/test-import-export.c | 1 +
src/nm-openvpn-service.c | 10 +++-
src/nm-openvpn-service.h | 5 ++
7 files changed, 199 insertions(+), 2 deletions(-)
---
diff --git a/properties/auth-helpers.c b/properties/auth-helpers.c
index 8ced138..2aef793 100644
--- a/properties/auth-helpers.c
+++ b/properties/auth-helpers.c
@@ -947,6 +947,7 @@ static const char *advanced_keys[] = {
NM_OPENVPN_KEY_RENEG_SECONDS,
NM_OPENVPN_KEY_TLS_REMOTE,
NM_OPENVPN_KEY_REMOTE_RANDOM,
+ NM_OPENVPN_KEY_REMOTE_CERT_TLS,
NULL
};
@@ -1205,6 +1206,53 @@ populate_hmacauth_combo (GtkComboBox *box, const char *hmacauth)
}
static void
+remote_tls_cert_toggled_cb (GtkWidget *widget, gpointer user_data)
+{
+ GtkBuilder *builder = (GtkBuilder *) user_data;
+ gboolean use_remote_cert_tls = FALSE;
+
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "remote_cert_tls_checkbutton"));
+ use_remote_cert_tls = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "remote_cert_tls_label"));
+ gtk_widget_set_sensitive (widget, use_remote_cert_tls);
+
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "remote_cert_tls_combo"));
+ gtk_widget_set_sensitive (widget, use_remote_cert_tls);
+}
+
+#define REMOTE_CERT_COL_NAME 0
+#define REMOTE_CERT_COL_VALUE 1
+
+static void
+populate_remote_cert_tls_combo (GtkComboBox *box, const char *remote_cert)
+{
+ GtkListStore *store;
+ GtkTreeIter iter;
+
+ store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
+ gtk_combo_box_set_model (box, GTK_TREE_MODEL (store));
+
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ REMOTE_CERT_COL_NAME, _("Server"),
+ REMOTE_CERT_COL_VALUE, NM_OPENVPN_REM_CERT_TLS_SERVER,
+ -1);
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ REMOTE_CERT_COL_NAME, _("Client"),
+ REMOTE_CERT_COL_VALUE, NM_OPENVPN_REM_CERT_TLS_CLIENT,
+ -1);
+
+ if (g_strcmp0 (remote_cert, NM_OPENVPN_REM_CERT_TLS_CLIENT) == 0)
+ gtk_combo_box_set_active (box, 1);
+ else
+ gtk_combo_box_set_active (box, 0);
+
+ g_object_unref (store);
+}
+
+static void
tls_auth_toggled_cb (GtkWidget *widget, gpointer user_data)
{
GtkBuilder *builder = (GtkBuilder *) user_data;
@@ -1550,6 +1598,17 @@ advanced_dialog_new (GHashTable *hash, const char *contype)
gtk_entry_set_text (GTK_ENTRY(widget), value);
}
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "remote_cert_tls_checkbutton"));
+ value = g_hash_table_lookup (hash, NM_OPENVPN_KEY_REMOTE_CERT_TLS);
+ if (value && strlen (value))
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
+ g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (remote_tls_cert_toggled_cb), builder);
+ remote_tls_cert_toggled_cb (widget, builder);
+
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "remote_cert_tls_combo"));
+ value = g_hash_table_lookup (hash, NM_OPENVPN_KEY_REMOTE_CERT_TLS);
+ populate_remote_cert_tls_combo (GTK_COMBO_BOX (widget), value);
+
if ( !strcmp (contype, NM_OPENVPN_CONTYPE_TLS)
|| !strcmp (contype, NM_OPENVPN_CONTYPE_PASSWORD_TLS)
|| !strcmp (contype, NM_OPENVPN_CONTYPE_PASSWORD)) {
@@ -1777,6 +1836,21 @@ advanced_dialog_new_hash_from_dialog (GtkWidget *dialog, GError **error)
if (value && strlen (value))
g_hash_table_insert (hash, g_strdup (NM_OPENVPN_KEY_TLS_REMOTE), g_strdup (value));
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "remote_cert_tls_checkbutton"));
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) {
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "remote_cert_tls_combo"));
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
+ if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter)) {
+ char *remote_cert = NULL;
+
+ gtk_tree_model_get (model, &iter, REMOTE_CERT_COL_VALUE, &remote_cert, -1);
+ if (remote_cert)
+ g_hash_table_insert (hash,
+ g_strdup (NM_OPENVPN_KEY_REMOTE_CERT_TLS),
+ remote_cert);
+ }
+ }
+
widget = GTK_WIDGET (gtk_builder_get_object (builder, "tls_auth_checkbutton"));
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) {
char *filename;
diff --git a/properties/import-export.c b/properties/import-export.c
index 8a451cf..9fc6e0e 100644
--- a/properties/import-export.c
+++ b/properties/import-export.c
@@ -70,6 +70,7 @@
#define TLS_AUTH_TAG "tls-auth "
#define TLS_CLIENT_TAG "tls-client"
#define TLS_REMOTE_TAG "tls-remote "
+#define REMOTE_CERT_TLS_TAG "remote-cert-tls "
#define TUNMTU_TAG "tun-mtu "
@@ -605,6 +606,20 @@ do_import (const char *path, char **lines, GError **error)
continue;
}
+ if (!strncmp (*line, REMOTE_CERT_TLS_TAG, strlen (REMOTE_CERT_TLS_TAG))) {
+ items = get_args (*line + strlen (REMOTE_CERT_TLS_TAG), &nitems);
+ if (nitems == 1) {
+ if ( !strcmp (items[0], NM_OPENVPN_REM_CERT_TLS_CLIENT)
+ || !strcmp (items[0], NM_OPENVPN_REM_CERT_TLS_SERVER)) {
+ nm_setting_vpn_add_data_item (s_vpn, NM_OPENVPN_KEY_REMOTE_CERT_TLS, items[0]);
+ } else
+ g_warning ("%s: unknown %s option '%s'", __func__, REMOTE_CERT_TLS_TAG, *line);
+ }
+
+ g_strfreev (items);
+ continue;
+ }
+
if (!strncmp (*line, IFCONFIG_TAG, strlen (IFCONFIG_TAG))) {
items = get_args (*line + strlen (IFCONFIG_TAG), &nitems);
if (nitems == 2) {
@@ -726,6 +741,7 @@ do_export (const char *path, NMConnection *connection, GError **error)
const char *local_ip = NULL;
const char *remote_ip = NULL;
const char *tls_remote = NULL;
+ const char *remote_cert_tls = NULL;
const char *tls_auth = NULL;
const char *tls_auth_dir = NULL;
gboolean success = FALSE;
@@ -841,6 +857,10 @@ do_export (const char *path, NMConnection *connection, GError **error)
if (value && strlen (value))
tls_auth_dir = value;
+ value = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_REMOTE_CERT_TLS);
+ if (value && strlen (value))
+ remote_cert_tls = value;
+
/* Advanced values end */
fprintf (f, "client\n");
@@ -910,6 +930,9 @@ do_export (const char *path, NMConnection *connection, GError **error)
if (tls_remote)
fprintf (f,"tls-remote \"%s\"\n", tls_remote);
+ if (remote_cert_tls)
+ fprintf (f,"remote-cert-tls %s\n", remote_cert_tls);
+
if (tls_auth) {
fprintf (f, "tls-auth %s%s%s\n",
tls_auth,
diff --git a/properties/nm-openvpn-dialog.ui b/properties/nm-openvpn-dialog.ui
index 35d905a..6c32e7f 100644
--- a/properties/nm-openvpn-dialog.ui
+++ b/properties/nm-openvpn-dialog.ui
@@ -100,6 +100,17 @@
</row>
</data>
</object>
+ <object class="GtkListStore" id="model7">
+ <columns>
+ <!-- column-name gchararray -->
+ <column type="gchararray"/>
+ </columns>
+ <data>
+ <row>
+ <col id="0" translatable="yes"> </col>
+ </row>
+ </data>
+ </object>
<object class="GtkDialog" id="openvpn-advanced-dialog">
<property name="can_focus">False</property>
<property name="border_width">5</property>
@@ -645,6 +656,80 @@ config: tls-remote</property>
</packing>
</child>
<child>
+ <object class="GtkTable" id="table12">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">3</property>
+ <child>
+ <object class="GtkCheckButton" id="remote_cert_tls_checkbutton">
+ <property name="label" translatable="yes">_Verify peer (server) certificate usage signature</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="tooltip_text" translatable="yes">Require that peer certificate was signed with an explicit key usage and extended key usage based on RFC3280 TLS rules.</property>
+ </object>
+ <packing>
+ <property name="right_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="remote_cert_tls_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Remote peer certificate TLS type:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">remote_cert_tls_combo</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="x_padding">12</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="remote_cert_tls_combo">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="model">model7</property>
+ <property name="tooltip_text" translatable="yes">Require that peer certificate was signed with an explicit key usage and extended key usage based on RFC3280 TLS rules.
+config: remote-cert-tls client|server</property>
+ <child>
+ <object class="GtkCellRendererText" id="renderer9"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="padding">6</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkTable" id="table7">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -778,7 +863,7 @@ config: tls-auth <file> [direction]</property>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
- <property name="position">1</property>
+ <property name="position">2</property>
</packing>
</child>
</object>
diff --git a/properties/tests/conf/tls.ovpn b/properties/tests/conf/tls.ovpn
index 2748519..8309c89 100644
--- a/properties/tests/conf/tls.ovpn
+++ b/properties/tests/conf/tls.ovpn
@@ -15,6 +15,7 @@ cert keys/clee.crt
key keys/clee.key
tls-auth keys/46.key 1
+remote-cert-tls server
tls-remote "/CN=myvpn.company.com"
comp-lzo
diff --git a/properties/tests/test-import-export.c b/properties/tests/test-import-export.c
index 025b12d..5f0c92e 100644
--- a/properties/tests/test-import-export.c
+++ b/properties/tests/test-import-export.c
@@ -284,6 +284,7 @@ test_tls_import (NMVpnPluginUiInterface *plugin, const char *dir)
test_item ("tls-import-data", s_vpn, NM_OPENVPN_KEY_REMOTE_IP, NULL);
test_item ("tls-import-data", s_vpn, NM_OPENVPN_KEY_AUTH, NULL);
test_item ("tls-import-data", s_vpn, NM_OPENVPN_KEY_TLS_REMOTE, "/CN=myvpn.company.com");
+ test_item ("tls-import-data", s_vpn, NM_OPENVPN_KEY_REMOTE_CERT_TLS, "server");
expected_path = g_strdup_printf ("%s/keys/mg8.ca", dir);
test_item ("tls-import-data", s_vpn, NM_OPENVPN_KEY_CA, expected_path);
diff --git a/src/nm-openvpn-service.c b/src/nm-openvpn-service.c
index 660fd2f..5eaed74 100644
--- a/src/nm-openvpn-service.c
+++ b/src/nm-openvpn-service.c
@@ -119,7 +119,8 @@ static ValidProperty valid_properties[] = {
{ NM_OPENVPN_KEY_TA, G_TYPE_STRING, 0, 0, FALSE },
{ NM_OPENVPN_KEY_TA_DIR, G_TYPE_INT, 0, 1, FALSE },
{ NM_OPENVPN_KEY_TAP_DEV, G_TYPE_BOOLEAN, 0, 0, FALSE },
- { NM_OPENVPN_KEY_TLS_REMOTE, G_TYPE_STRING, 0, 0, FALSE },
+ { NM_OPENVPN_KEY_TLS_REMOTE, G_TYPE_STRING, 0, 0, FALSE },
+ { NM_OPENVPN_KEY_REMOTE_CERT_TLS, G_TYPE_STRING, 0, 0, FALSE },
{ NM_OPENVPN_KEY_TUNNEL_MTU, G_TYPE_INT, 0, G_MAXINT, FALSE },
{ NM_OPENVPN_KEY_USERNAME, G_TYPE_STRING, 0, 0, FALSE },
{ NM_OPENVPN_KEY_PASSWORD"-flags", G_TYPE_STRING, 0, 0, FALSE },
@@ -890,6 +891,13 @@ nm_openvpn_start_openvpn_binary (NMOpenvpnPlugin *plugin,
add_openvpn_arg (args, tmp);
}
+ /* remote-cert-tls */
+ tmp = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_REMOTE_CERT_TLS);
+ if (tmp && strlen (tmp)) {
+ add_openvpn_arg (args, "--remote-cert-tls");
+ add_openvpn_arg (args, tmp);
+ }
+
/* Reneg seconds */
tmp = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_RENEG_SECONDS);
if (tmp && strlen (tmp)) {
diff --git a/src/nm-openvpn-service.h b/src/nm-openvpn-service.h
index 9266a64..a60fa89 100644
--- a/src/nm-openvpn-service.h
+++ b/src/nm-openvpn-service.h
@@ -66,6 +66,7 @@
#define NM_OPENVPN_KEY_USERNAME "username"
#define NM_OPENVPN_KEY_TAP_DEV "tap-dev"
#define NM_OPENVPN_KEY_TLS_REMOTE "tls-remote"
+#define NM_OPENVPN_KEY_REMOTE_CERT_TLS "remote-cert-tls"
#define NM_OPENVPN_KEY_PASSWORD "password"
#define NM_OPENVPN_KEY_CERTPASS "cert-pass"
@@ -92,6 +93,10 @@
#define NM_OPENVPN_CONTYPE_PASSWORD "password"
#define NM_OPENVPN_CONTYPE_PASSWORD_TLS "password-tls"
+/* arguments of "--remote-cert-tls" */
+#define NM_OPENVPN_REM_CERT_TLS_CLIENT "client"
+#define NM_OPENVPN_REM_CERT_TLS_SERVER "server"
+
typedef struct {
NMVPNPlugin parent;
} NMOpenvpnPlugin;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]