[network-manager-openvpn] core: add tls-remote support (bgo #455142)



commit 751fcfb0c1165c52d84ce42409e293984a09d35d
Author: Huzaifa S. Sidhpurwala <huzaifas redhat com>
Date:   Mon Jan 18 00:13:18 2010 -0800

    core: add tls-remote support (bgo #455142)
    
    import/export quoting changes and testcase by dcbw.

 properties/auth-helpers.c             |   15 ++-
 properties/import-export.c            |  115 ++++++++++------
 properties/nm-openvpn-dialog.glade    |  239 ++++++++++++++++++++++-----------
 properties/tests/conf/tls.ovpn        |    2 +
 properties/tests/test-import-export.c |    1 +
 src/nm-openvpn-service.c              |    8 +
 src/nm-openvpn-service.h              |    1 +
 7 files changed, 258 insertions(+), 123 deletions(-)
---
diff --git a/properties/auth-helpers.c b/properties/auth-helpers.c
index 28001a3..9120385 100644
--- a/properties/auth-helpers.c
+++ b/properties/auth-helpers.c
@@ -762,6 +762,7 @@ static const char *advanced_keys[] = {
 	NM_OPENVPN_KEY_TA_DIR,
 	NM_OPENVPN_KEY_TA,
 	NM_OPENVPN_KEY_RENEG_SECONDS,
+	NM_OPENVPN_KEY_TLS_REMOTE,
 	NULL
 };
 
@@ -1097,6 +1098,12 @@ advanced_dialog_new (GHashTable *hash, const char *contype)
 	value = g_hash_table_lookup (hash, NM_OPENVPN_KEY_AUTH);
 	populate_hmacauth_combo (GTK_COMBO_BOX (widget), value);
 
+	value = g_hash_table_lookup (hash, NM_OPENVPN_KEY_TLS_REMOTE);
+	if (value && strlen (value)) {
+		widget = glade_xml_get_widget (xml, "tls_remote_entry");
+		gtk_entry_set_text (GTK_ENTRY(widget), value);
+	}
+
 	if (   !strcmp (contype, NM_OPENVPN_CONTYPE_TLS)
 	    || !strcmp (contype, NM_OPENVPN_CONTYPE_PASSWORD_TLS)
 	    || !strcmp (contype, NM_OPENVPN_CONTYPE_PASSWORD)) {
@@ -1161,6 +1168,7 @@ advanced_dialog_new_hash_from_dialog (GtkWidget *dialog, GError **error)
 	GtkWidget *widget;
 	GladeXML *xml;
 	const char *contype = NULL;
+	const char *value = NULL;
 
 	g_return_val_if_fail (dialog != NULL, NULL);
 	if (error)
@@ -1235,7 +1243,12 @@ advanced_dialog_new_hash_from_dialog (GtkWidget *dialog, GError **error)
 				g_hash_table_insert (hash, g_strdup (NM_OPENVPN_KEY_AUTH), g_strdup (hmacauth));
 			}
 		}
-		
+
+		widget = glade_xml_get_widget (xml, "tls_remote_entry");
+		value = gtk_entry_get_text (GTK_ENTRY(widget));
+		if (value && strlen (value))
+			g_hash_table_insert (hash, g_strdup (NM_OPENVPN_KEY_TLS_REMOTE), g_strdup (value));
+
 		widget = glade_xml_get_widget (xml, "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 f3d1213..298c5f1 100644
--- a/properties/import-export.c
+++ b/properties/import-export.c
@@ -59,68 +59,81 @@
 #define TLS_AUTH_TAG "tls-auth"
 #define AUTH_TAG "auth "
 #define RENEG_SEC_TAG "reneg-sec"
+#define TLS_REMOTE_TAG "tls-remote"
 
-static gboolean
-handle_path_item (const char *line,
-                  const char *tag,
-                  const char *key,
-                  NMSettingVPN *s_vpn,
-                  const char *path,
-                  char **leftover)
+
+static char *
+unquote (const char *line, char **leftover)
 {
-	char *tmp, *file, *unquoted, *p, *full_path = NULL;
+	char *tmp, *item, *unquoted = NULL, *p;
 	gboolean quoted = FALSE;
 
 	if (leftover)
 		g_return_val_if_fail (*leftover == NULL, FALSE);
 
-	if (strncmp (line, tag, strlen (tag)))
-		return FALSE;
-
-	tmp = g_strdup (line + strlen (tag));
-	file = g_strstrip (tmp);
-	if (!strlen (file))
-		goto out;
-
-	/* If file isn't an absolute file name, add the default path */
-	if (!g_path_is_absolute (file)) {
-		full_path = g_build_filename (path, file, NULL);
-		file = full_path;
+	tmp = g_strdup (line);
+	item = g_strstrip (tmp);
+	if (!strlen (item)) {
+		g_free (tmp);
+		return NULL;
 	}
 
 	/* Simple unquote */
-	if ((file[0] == '"') || (file[0] == '\'')) {
+	if ((item[0] == '"') || (item[0] == '\'')) {
 		quoted = TRUE;
-		file++;
+		item++;
 	}
 
 	/* Unquote stuff using openvpn unquoting rules */
-	unquoted = g_malloc0 (strlen (file) + 1);
-	for (p = unquoted; *file; file++, p++) {
-		if (quoted && ((*file == '"') || (*file == '\'')))
+	unquoted = g_malloc0 (strlen (item) + 1);
+	for (p = unquoted; *item; item++, p++) {
+		if (quoted && ((*item == '"') || (*item == '\'')))
 			break;
-		else if (!quoted && isspace (*file))
+		else if (!quoted && isspace (*item))
 			break;
 
-		if (*file == '\\' && *(file+1) == '\\')
-			*p = *(++file);
-		else if (*file == '\\' && *(file+1) == '"')
-			*p = *(++file);
-		else if (*file == '\\' && *(file+1) == ' ')
-			*p = *(++file);
+		if (*item == '\\' && *(item+1) == '\\')
+			*p = *(++item);
+		else if (*item == '\\' && *(item+1) == '"')
+			*p = *(++item);
+		else if (*item == '\\' && *(item+1) == ' ')
+			*p = *(++item);
 		else
-			*p = *file;
+			*p = *item;
 	}
-	if (leftover && *file)
-		*leftover = file + 1;
+	if (leftover && *item)
+		*leftover = item + 1;
 
-	nm_setting_vpn_add_data_item (s_vpn, key, unquoted);
-	g_free (unquoted);
-
-out:
 	g_free (tmp);
-	if (full_path)
-		g_free (full_path);
+	return unquoted;
+}
+
+
+static gboolean
+handle_path_item (const char *line,
+                  const char *tag,
+                  const char *key,
+                  NMSettingVPN *s_vpn,
+                  const char *path,
+                  char **leftover)
+{
+	char *file, *full_path = NULL;
+
+	if (strncmp (line, tag, strlen (tag)))
+		return FALSE;
+
+	file = unquote (line + strlen (tag), leftover);
+	if (!file)
+		return FALSE;
+
+	/* If file isn't an absolute file name, add the default path */
+	if (!g_path_is_absolute (file))
+		full_path = g_build_filename (path, file, NULL);
+
+	nm_setting_vpn_add_data_item (s_vpn, key, full_path ? full_path : file);
+
+	g_free (file);
+	g_free (full_path);
 	return TRUE;
 }
 
@@ -327,6 +340,17 @@ do_import (const char *path, char **lines, GError **error)
 			continue;
 		}
 
+		/* tls-remote */
+		if (!strncmp (*line, TLS_REMOTE_TAG, strlen (TLS_REMOTE_TAG))) {
+			char *unquoted = unquote (*line + strlen (TLS_REMOTE_TAG), NULL);
+
+			if (unquoted) {
+				nm_setting_vpn_add_data_item (s_vpn, NM_OPENVPN_KEY_TLS_REMOTE, unquoted);
+				g_free (unquoted);
+			}
+			continue;
+		}
+
 		if (!strncmp (*line, IFCONFIG_TAG, strlen (IFCONFIG_TAG))) {
 			items = get_args (*line + strlen (IFCONFIG_TAG));
 			if (!items)
@@ -432,6 +456,7 @@ do_export (const char *path, NMConnection *connection, GError **error)
 	const char *port = NULL;
 	const char *local_ip = NULL;
 	const char *remote_ip = NULL;
+	const char *tls_remote = NULL;
 	gboolean success = FALSE;
 	gboolean device_tun = TRUE;
 	gboolean proto_udp = TRUE;
@@ -492,6 +517,11 @@ do_export (const char *path, NMConnection *connection, GError **error)
 			static_key_direction = value;
 	}
 
+	/* Export tls-remote value now*/
+	value = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_TLS_REMOTE);
+	if (value && strlen (value))
+		tls_remote = value;
+
 	/* Advanced values start */
 	value = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_PORT);
 	if (value && strlen (value))
@@ -568,6 +598,9 @@ do_export (const char *path, NMConnection *connection, GError **error)
 	if (local_ip && remote_ip)
 		fprintf (f, "ifconfig %s %s\n", local_ip, remote_ip);
 
+	if (tls_remote)
+		fprintf (f,"tls-remote \"%s\"\n", tls_remote);
+
 	/* Add hard-coded stuff */
 	fprintf (f,
 	         "nobind\n"
diff --git a/properties/nm-openvpn-dialog.glade b/properties/nm-openvpn-dialog.glade
index f8d011d..fe47622 100644
--- a/properties/nm-openvpn-dialog.glade
+++ b/properties/nm-openvpn-dialog.glade
@@ -1106,108 +1106,185 @@
               </packing>
             </child>
             <child>
-              <widget class="GtkTable" id="table7">
+              <widget class="GtkAlignment" id="alignment1">
                 <property name="visible">True</property>
-                <property name="border_width">12</property>
-                <property name="n_rows">2</property>
-                <property name="n_columns">2</property>
-                <property name="column_spacing">12</property>
-                <property name="row_spacing">6</property>
-                <child>
-                  <widget class="GtkCheckButton" id="tls_auth_checkbutton">
-                    <property name="label" translatable="yes">Use additional TLS authentication</property>
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">False</property>
-                    <property name="use_underline">True</property>
-                    <property name="draw_indicator">True</property>
-                  </widget>
-                  <packing>
-                    <property name="right_attach">2</property>
-                  </packing>
-                </child>
+                <property name="top_padding">12</property>
+                <property name="bottom_padding">12</property>
+                <property name="left_padding">12</property>
+                <property name="right_padding">12</property>
                 <child>
-                  <widget class="GtkTable" id="table8">
+                  <widget class="GtkVBox" id="vbox3">
                     <property name="visible">True</property>
-                    <property name="n_rows">3</property>
-                    <property name="n_columns">2</property>
-                    <property name="column_spacing">12</property>
-                    <property name="row_spacing">6</property>
-                    <child>
-                      <widget class="GtkLabel" id="direction_label">
-                        <property name="visible">True</property>
-                        <property name="xalign">0</property>
-                        <property name="label" translatable="yes">Key Direction:</property>
-                      </widget>
-                      <packing>
-                        <property name="top_attach">1</property>
-                        <property name="bottom_attach">2</property>
-                      </packing>
-                    </child>
+                    <property name="orientation">vertical</property>
+                    <property name="spacing">12</property>
                     <child>
-                      <widget class="GtkAlignment" id="alignment19">
+                      <widget class="GtkTable" id="table10">
                         <property name="visible">True</property>
-                        <property name="xalign">1</property>
-                        <property name="xscale">0</property>
+                        <property name="n_rows">2</property>
+                        <property name="n_columns">2</property>
+                        <property name="column_spacing">12</property>
+                        <property name="row_spacing">6</property>
                         <child>
-                          <widget class="GtkLabel" id="tls_dir_help_label">
+                          <widget class="GtkLabel" id="tls_remote_label">
                             <property name="visible">True</property>
                             <property name="xalign">0</property>
-                            <property name="label" translatable="yes">&lt;i&gt;If key direction is used, it must be the opposite of that used on the VPN peer.  For example, if the peer uses '1', this connection must use '0'.  If you are unsure what value to use, contact your system administrator.&lt;/i&gt;</property>
-                            <property name="use_markup">True</property>
-                            <property name="wrap">True</property>
+                            <property name="label" translatable="yes">Subject Match:</property>
                           </widget>
+                          <packing>
+                            <property name="x_options">GTK_FILL</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkAlignment" id="alignment26">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="xscale">0</property>
+                            <child>
+                              <widget class="GtkLabel" id="label33">
+                                <property name="visible">True</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">&lt;i&gt;Connect only to servers whose certificate matches the given subject.
+Example: /CN=myvpn.company.com&lt;/i&gt;</property>
+                                <property name="use_markup">True</property>
+                                <property name="wrap">True</property>
+                              </widget>
+                            </child>
+                          </widget>
+                          <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>
+                          <widget class="GtkEntry" id="tls_remote_entry">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="invisible_char">&#x25CF;</property>
+                          </widget>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <placeholder/>
                         </child>
                       </widget>
                       <packing>
-                        <property name="left_attach">1</property>
-                        <property name="right_attach">2</property>
-                        <property name="top_attach">2</property>
-                        <property name="bottom_attach">3</property>
-                        <property name="y_options"></property>
-                      </packing>
-                    </child>
-                    <child>
-                      <widget class="GtkFileChooserButton" id="tls_auth_chooser">
-                        <property name="visible">True</property>
-                      </widget>
-                      <packing>
-                        <property name="left_attach">1</property>
-                        <property name="right_attach">2</property>
+                        <property name="position">0</property>
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkComboBox" id="direction_combo">
+                      <widget class="GtkTable" id="table7">
                         <property name="visible">True</property>
-                        <property name="items" translatable="yes"> </property>
+                        <property name="n_rows">2</property>
+                        <property name="n_columns">2</property>
+                        <property name="column_spacing">12</property>
+                        <property name="row_spacing">6</property>
+                        <child>
+                          <widget class="GtkCheckButton" id="tls_auth_checkbutton">
+                            <property name="label" translatable="yes">Use additional TLS authentication</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">False</property>
+                            <property name="use_underline">True</property>
+                            <property name="draw_indicator">True</property>
+                          </widget>
+                          <packing>
+                            <property name="right_attach">2</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkTable" id="table8">
+                            <property name="visible">True</property>
+                            <property name="n_rows">3</property>
+                            <property name="n_columns">2</property>
+                            <property name="column_spacing">12</property>
+                            <property name="row_spacing">6</property>
+                            <child>
+                              <widget class="GtkLabel" id="direction_label">
+                                <property name="visible">True</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">Key Direction:</property>
+                              </widget>
+                              <packing>
+                                <property name="top_attach">1</property>
+                                <property name="bottom_attach">2</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkAlignment" id="alignment19">
+                                <property name="visible">True</property>
+                                <property name="xalign">1</property>
+                                <property name="xscale">0</property>
+                                <child>
+                                  <widget class="GtkLabel" id="tls_dir_help_label">
+                                    <property name="visible">True</property>
+                                    <property name="xalign">0</property>
+                                    <property name="label" translatable="yes">&lt;i&gt;If key direction is used, it must be the opposite of that used on the VPN peer.  For example, if the peer uses '1', this connection must use '0'.  If you are unsure what value to use, contact your system administrator.&lt;/i&gt;</property>
+                                    <property name="use_markup">True</property>
+                                    <property name="wrap">True</property>
+                                  </widget>
+                                </child>
+                              </widget>
+                              <packing>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
+                                <property name="top_attach">2</property>
+                                <property name="bottom_attach">3</property>
+                                <property name="y_options"></property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkFileChooserButton" id="tls_auth_chooser">
+                                <property name="visible">True</property>
+                              </widget>
+                              <packing>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkComboBox" id="direction_combo">
+                                <property name="visible">True</property>
+                                <property name="items" translatable="yes"> </property>
+                              </widget>
+                              <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>
+                              <widget class="GtkLabel" id="tls_auth_label">
+                                <property name="visible">True</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">Key File:</property>
+                              </widget>
+                            </child>
+                            <child>
+                              <placeholder/>
+                            </child>
+                          </widget>
+                          <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>
                       </widget>
                       <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>
+                        <property name="position">1</property>
                       </packing>
                     </child>
-                    <child>
-                      <widget class="GtkLabel" id="tls_auth_label">
-                        <property name="visible">True</property>
-                        <property name="xalign">0</property>
-                        <property name="label" translatable="yes">Key File:</property>
-                      </widget>
-                    </child>
-                    <child>
-                      <placeholder/>
-                    </child>
                   </widget>
-                  <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>
               </widget>
               <packing>
diff --git a/properties/tests/conf/tls.ovpn b/properties/tests/conf/tls.ovpn
index 5b33dad..ae11c78 100644
--- a/properties/tests/conf/tls.ovpn
+++ b/properties/tests/conf/tls.ovpn
@@ -14,6 +14,8 @@ ca keys/mg8.ca
 cert keys/clee.crt
 key keys/clee.key
 
+tls-remote "/CN=myvpn.company.com"
+
 comp-lzo
 verb 3
 
diff --git a/properties/tests/test-import-export.c b/properties/tests/test-import-export.c
index d0f5340..a1245ed 100644
--- a/properties/tests/test-import-export.c
+++ b/properties/tests/test-import-export.c
@@ -288,6 +288,7 @@ test_tls_import (NMVpnPluginUiInterface *plugin, const char *dir)
 	test_item ("tls-import-data", s_vpn, NM_OPENVPN_KEY_LOCAL_IP, NULL);
 	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");
 
 	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 c4da0c3..7405322 100644
--- a/src/nm-openvpn-service.c
+++ b/src/nm-openvpn-service.c
@@ -102,6 +102,7 @@ static ValidProperty valid_properties[] = {
 	{ NM_OPENVPN_KEY_TA_DIR,               G_TYPE_INT, 0, 1, FALSE },
 	{ NM_OPENVPN_KEY_USERNAME,             G_TYPE_STRING, 0, 0, FALSE },
 	{ NM_OPENVPN_KEY_RENEG_SECONDS,        G_TYPE_INT, 0, G_MAXINT, FALSE },
+	{ NM_OPENVPN_KEY_TLS_REMOTE,	       G_TYPE_STRING, 0, 0, FALSE },
 	{ NULL,                                G_TYPE_NONE, FALSE }
 };
 
@@ -746,6 +747,13 @@ nm_openvpn_start_openvpn_binary (NMOpenvpnPlugin *plugin,
 			add_openvpn_arg (args, tmp);
 	}
 
+	/* tls-remote */
+	tmp = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_TLS_REMOTE);
+	if (tmp && strlen (tmp)) {
+                add_openvpn_arg (args, "--tls-remote");
+                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 06bf21b..bd50d4f 100644
--- a/src/nm-openvpn-service.h
+++ b/src/nm-openvpn-service.h
@@ -56,6 +56,7 @@
 #define NM_OPENVPN_KEY_TA "ta"
 #define NM_OPENVPN_KEY_TA_DIR "ta-dir"
 #define NM_OPENVPN_KEY_USERNAME "username"
+#define NM_OPENVPN_KEY_TLS_REMOTE "tls-remote"
 
 #define NM_OPENVPN_KEY_PASSWORD "password"
 #define NM_OPENVPN_KEY_CERTPASS "cert-pass"



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]