[network-manager-openvpn] core/ui: add HTTP Proxy support (bgo #440031)
- From: Dan Williams <dcbw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [network-manager-openvpn] core/ui: add HTTP Proxy support (bgo #440031)
- Date: Thu, 19 Aug 2010 03:19:30 +0000 (UTC)
commit 2eee51aedace28af0f39349baee130f4121428e7
Author: Dan Williams <dcbw redhat com>
Date: Wed Aug 18 22:16:45 2010 -0500
core/ui: add HTTP Proxy support (bgo #440031)
Based off patches by:
Tomas Kovacik <nail nodomain sk>
Florian Klink <flokli flokli de>
properties/auth-helpers.c | 173 ++++++++++++++++++++++++++++--
properties/auth-helpers.h | 4 +
properties/import-export.c | 94 ++++++++++++++++
properties/nm-openvpn-dialog.glade | 211 ++++++++++++++++++++++++++++++++++++
properties/nm-openvpn.c | 12 ++-
src/nm-openvpn-service.c | 118 +++++++++++++++------
src/nm-openvpn-service.h | 5 +
7 files changed, 577 insertions(+), 40 deletions(-)
---
diff --git a/properties/auth-helpers.c b/properties/auth-helpers.c
index 33db4dc..c660ebe 100644
--- a/properties/auth-helpers.c
+++ b/properties/auth-helpers.c
@@ -1,7 +1,7 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/***************************************************************************
*
- * Copyright (C) 2008 Dan Williams, <dcbw redhat com>
+ * Copyright (C) 2008 - 2010 Dan Williams, <dcbw redhat com>
* Copyright (C) 2008 Tambet Ingo, <tambet gmail com>
*
* This program is free software; you can redistribute it and/or modify
@@ -845,6 +845,10 @@ static const char *advanced_keys[] = {
NM_OPENVPN_KEY_FRAGMENT_SIZE,
NM_OPENVPN_KEY_TAP_DEV,
NM_OPENVPN_KEY_PROTO_TCP,
+ NM_OPENVPN_KEY_HTTP_PROXY,
+ NM_OPENVPN_KEY_HTTP_PROXY_PORT,
+ NM_OPENVPN_KEY_HTTP_PROXY_RETRY,
+ NM_OPENVPN_KEY_HTTP_PROXY_USERNAME,
NM_OPENVPN_KEY_CIPHER,
NM_OPENVPN_KEY_AUTH,
NM_OPENVPN_KEY_TA_DIR,
@@ -874,11 +878,21 @@ advanced_dialog_new_hash_from_connection (NMConnection *connection,
{
GHashTable *hash;
NMSettingVPN *s_vpn;
+ const char *secret;
hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
s_vpn = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN);
nm_setting_vpn_foreach_data_item (s_vpn, copy_values, hash);
+
+ /* HTTP Proxy password is special */
+ secret = nm_setting_vpn_get_secret (s_vpn, NM_OPENVPN_KEY_HTTP_PROXY_PASSWORD);
+ if (secret) {
+ g_hash_table_insert (hash,
+ g_strdup (NM_OPENVPN_KEY_HTTP_PROXY_PASSWORD),
+ g_strdup (secret));
+ }
+
return hash;
}
@@ -1116,6 +1130,38 @@ tls_auth_toggled_cb (GtkWidget *widget, gpointer user_data)
gtk_widget_set_sensitive (widget, use_auth);
}
+#define PROXY_TYPE_NONE 0
+#define PROXY_TYPE_HTTP 1
+
+static void
+proxy_type_changed (GtkComboBox *combo, gpointer user_data)
+{
+ GladeXML *xml = GLADE_XML (user_data);
+ gboolean sensitive;
+ GtkWidget *widget;
+ guint32 i = 0;
+ const char *widgets[] = {
+ "proxy_desc_label", "proxy_server_label", "proxy_server_entry",
+ "proxy_port_label", "proxy_port_spinbutton", "proxy_retry_checkbutton",
+ "proxy_username_label", "proxy_password_label", "proxy_username_entry",
+ "proxy_password_entry", NULL
+ };
+
+ sensitive = (gtk_combo_box_get_active (combo) == PROXY_TYPE_HTTP);
+ while (widgets[i]) {
+ widget = glade_xml_get_widget (xml, widgets[i++]);
+ gtk_widget_set_sensitive (widget, sensitive);
+ }
+
+ /* HTTP Proxy option requires TCP; but don't reset the TCP checkbutton
+ * to false when the user disables HTTP proxy; leave it checked.
+ */
+ widget = glade_xml_get_widget (xml, "tcp_checkbutton");
+ if (sensitive == TRUE)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
+ gtk_widget_set_sensitive (widget, !sensitive);
+}
+
#define TA_DIR_COL_NAME 0
#define TA_DIR_COL_NUM 1
@@ -1125,8 +1171,11 @@ advanced_dialog_new (GHashTable *hash, const char *contype)
GladeXML *xml;
GtkWidget *dialog = NULL;
char *glade_file = NULL;
- GtkWidget *widget;
- const char *value;
+ GtkWidget *widget, *combo;
+ const char *value, *value2;
+ GtkListStore *store;
+ GtkTreeIter iter;
+ guint32 active = 0;
g_return_val_if_fail (hash != NULL, NULL);
@@ -1170,6 +1219,56 @@ advanced_dialog_new (GHashTable *hash, const char *contype)
gtk_widget_set_sensitive (widget, FALSE);
}
+ /* Proxy support */
+ combo = glade_xml_get_widget (xml, "proxy_type_combo");
+
+ store = gtk_list_store_new (1, G_TYPE_STRING);
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 0, _("Not required"), -1);
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 0, _("HTTP Proxy"), -1);
+
+ value = g_hash_table_lookup (hash, NM_OPENVPN_KEY_HTTP_PROXY);
+ value2 = g_hash_table_lookup (hash, NM_OPENVPN_KEY_HTTP_PROXY_PORT);
+ if (value && strlen (value) && value2 && strlen (value2)) {
+ long int tmp = 8080;
+
+ active = 1;
+
+ widget = glade_xml_get_widget (xml, "proxy_server_entry");
+ gtk_entry_set_text (GTK_ENTRY (widget), value);
+
+ errno = 0;
+ tmp = strtol (value2, NULL, 10);
+ if (errno != 0 || tmp < 1 || tmp > 65535)
+ tmp = 8080;
+ widget = glade_xml_get_widget (xml, "proxy_port_spinbutton");
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), (gdouble) tmp);
+
+ widget = glade_xml_get_widget (xml, "proxy_retry_checkbutton");
+ value = g_hash_table_lookup (hash, NM_OPENVPN_KEY_HTTP_PROXY_RETRY);
+ if (value && !strcmp (value, "yes"))
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
+
+ value = g_hash_table_lookup (hash, NM_OPENVPN_KEY_HTTP_PROXY_USERNAME);
+ if (value && strlen (value)) {
+ widget = glade_xml_get_widget (xml, "proxy_username_entry");
+ gtk_entry_set_text (GTK_ENTRY (widget), value);
+ }
+
+ value = g_hash_table_lookup (hash, NM_OPENVPN_KEY_HTTP_PROXY_PASSWORD);
+ if (value && strlen (value)) {
+ widget = glade_xml_get_widget (xml, "proxy_password_entry");
+ gtk_entry_set_text (GTK_ENTRY (widget), value);
+ }
+ }
+
+ gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (store));
+ g_object_unref (store);
+ gtk_combo_box_set_active (GTK_COMBO_BOX (combo), active);
+ proxy_type_changed (GTK_COMBO_BOX (combo), xml);
+ g_signal_connect (G_OBJECT (combo), "changed", G_CALLBACK (proxy_type_changed), xml);
+
widget = glade_xml_get_widget (xml, "port_checkbutton");
g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (port_toggled_cb), xml);
@@ -1291,10 +1390,9 @@ advanced_dialog_new (GHashTable *hash, const char *contype)
if ( !strcmp (contype, NM_OPENVPN_CONTYPE_TLS)
|| !strcmp (contype, NM_OPENVPN_CONTYPE_PASSWORD_TLS)
|| !strcmp (contype, NM_OPENVPN_CONTYPE_PASSWORD)) {
- GtkListStore *store;
- GtkTreeIter iter;
- int direction = -1, active = -1;
+ int direction = -1;
+ active = -1;
widget = glade_xml_get_widget (xml, "tls_auth_checkbutton");
value = g_hash_table_lookup (hash, NM_OPENVPN_KEY_TA);
if (value && strlen (value))
@@ -1352,7 +1450,7 @@ advanced_dialog_new_hash_from_dialog (GtkWidget *dialog, GError **error)
GtkWidget *widget;
GladeXML *xml;
const char *contype = NULL;
- const char *value = NULL;
+ const char *value;
g_return_val_if_fail (dialog != NULL, NULL);
if (error)
@@ -1399,6 +1497,46 @@ advanced_dialog_new_hash_from_dialog (GtkWidget *dialog, GError **error)
g_hash_table_insert (hash, g_strdup (NM_OPENVPN_KEY_PORT), g_strdup_printf ("%d", port));
}
+ /* HTTP proxy support */
+ widget = glade_xml_get_widget (xml, "proxy_type_combo");
+ if (gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) == PROXY_TYPE_HTTP) {
+ widget = glade_xml_get_widget (xml, "proxy_server_entry");
+ value = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
+
+ if (value && strlen (value)) {
+ int proxy_port;
+
+ g_hash_table_insert (hash, g_strdup (NM_OPENVPN_KEY_HTTP_PROXY), g_strdup (value));
+
+ widget = glade_xml_get_widget (xml, "proxy_port_spinbutton");
+ proxy_port = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (widget));
+ if (!proxy_port)
+ proxy_port = 8080;
+ g_hash_table_insert (hash, g_strdup (NM_OPENVPN_KEY_HTTP_PROXY_PORT),
+ g_strdup_printf ("%d", proxy_port));
+
+ widget = glade_xml_get_widget (xml, "proxy_retry_checkbutton");
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
+ g_hash_table_insert (hash, g_strdup (NM_OPENVPN_KEY_HTTP_PROXY_RETRY), g_strdup ("yes"));
+
+ widget = glade_xml_get_widget (xml, "proxy_username_entry");
+ value = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
+ if (value && strlen (value)) {
+ g_hash_table_insert (hash,
+ g_strdup (NM_OPENVPN_KEY_HTTP_PROXY_USERNAME),
+ g_strdup (value));
+ }
+
+ widget = glade_xml_get_widget (xml, "proxy_password_entry");
+ value = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
+ if (value && strlen (value)) {
+ g_hash_table_insert (hash,
+ g_strdup (NM_OPENVPN_KEY_HTTP_PROXY_PASSWORD),
+ g_strdup (value));
+ }
+ }
+ }
+
widget = glade_xml_get_widget (xml, "lzo_checkbutton");
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
g_hash_table_insert (hash, g_strdup (NM_OPENVPN_KEY_COMP_LZO), g_strdup ("yes"));
@@ -1483,3 +1621,24 @@ advanced_dialog_new_hash_from_dialog (GtkWidget *dialog, GError **error)
return hash;
}
+gboolean
+advanced_save_secrets (GHashTable *advanced,
+ const char *uuid,
+ const char *name)
+{
+ const char *secret;
+ GnomeKeyringResult result;
+ gboolean ret;
+
+ secret = g_hash_table_lookup (advanced, NM_OPENVPN_KEY_HTTP_PROXY_PASSWORD);
+ if (secret && strlen (secret)) {
+ result = keyring_helpers_save_secret (uuid, name, NULL, NM_OPENVPN_KEY_HTTP_PROXY_PASSWORD, secret);
+ ret = result == GNOME_KEYRING_RESULT_OK;
+ if (!ret)
+ g_warning ("%s: failed to save HTTP proxy password to keyring.", __func__);
+ } else
+ ret = keyring_helpers_delete_secret (uuid, NM_OPENVPN_KEY_HTTP_PROXY_PASSWORD);
+
+ return ret;
+}
+
diff --git a/properties/auth-helpers.h b/properties/auth-helpers.h
index d3af84b..8dcb618 100644
--- a/properties/auth-helpers.h
+++ b/properties/auth-helpers.h
@@ -63,6 +63,10 @@ gboolean auth_widget_save_secrets (GladeXML *xml,
const char *uuid,
const char *name);
+gboolean advanced_save_secrets (GHashTable *advanced,
+ const char *uuid,
+ const char *name);
+
GtkFileFilter *tls_file_chooser_filter_new (gboolean pkcs_allowed);
GtkFileFilter *sk_file_chooser_filter_new (void);
diff --git a/properties/import-export.c b/properties/import-export.c
index f9731d2..31186bd 100644
--- a/properties/import-export.c
+++ b/properties/import-export.c
@@ -58,6 +58,8 @@
#define PKCS12_TAG "pkcs12 "
#define PORT_TAG "port "
#define PROTO_TAG "proto "
+#define PROXY_TAG "http-proxy "
+#define PROXY_RETRY_TAG "http-proxy-retry"
#define REMOTE_TAG "remote "
#define RENEG_SEC_TAG "reneg-sec "
#define RPORT_TAG "rport "
@@ -197,6 +199,46 @@ parse_port (const char *str, const char *line)
return NULL;
}
+static gboolean
+parse_http_proxy_auth (const char *str, char **out_user, char **out_pass)
+{
+ char *contents = NULL;
+ GError *error = NULL;
+ char **lines, **iter;
+
+ g_return_val_if_fail (out_user != NULL, FALSE);
+ g_return_val_if_fail (out_pass != NULL, FALSE);
+
+ if (!str || !strcmp (str, "stdin") || !strcmp (str, "auto"))
+ return TRUE;
+
+ /* Grab user/pass from authfile */
+ if (!g_file_get_contents (str, &contents, NULL, &error)) {
+ g_warning ("%s: unable to read HTTP proxy authfile '%s': (%d) %s",
+ __func__, str, error ? error->code : -1,
+ error && error->message ? error->message : "(unknown)");
+ g_clear_error (&error);
+ return FALSE;
+ }
+
+ lines = g_strsplit_set (contents, "\n\r", 0);
+ for (iter = lines; iter && *iter; iter++) {
+ if (!strlen (*iter))
+ continue;
+ if (!*out_user)
+ *out_user = g_strdup (g_strstrip (*iter));
+ else if (!*out_pass) {
+ *out_pass = g_strdup (g_strstrip (*iter));
+ break;
+ }
+ }
+ if (lines)
+ g_strfreev (lines);
+ g_free (contents);
+
+ return *out_user && *out_pass;
+}
+
NMConnection *
do_import (const char *path, char **lines, GError **error)
{
@@ -347,6 +389,58 @@ do_import (const char *path, char **lines, GError **error)
continue;
}
+ if (!strncmp (*line, PROXY_RETRY_TAG, strlen (PROXY_RETRY_TAG))) {
+ nm_setting_vpn_add_data_item (s_vpn,
+ g_strdup (NM_OPENVPN_KEY_HTTP_PROXY_RETRY),
+ g_strdup ("yes"));
+ continue;
+ }
+
+ if (!strncmp (*line, PROXY_TAG, strlen (PROXY_TAG))) {
+ gboolean success = FALSE;
+
+ items = get_args (*line + strlen (PROXY_TAG));
+ if (!items)
+ continue;
+
+ if (g_strv_length (items) >= 2) {
+ glong port;
+ char *s_port = NULL;
+ char *user = NULL, *pass = NULL;
+
+ if (g_strv_length (items) >= 3)
+ success = parse_http_proxy_auth (items[2], &user, &pass);
+
+ if (success) {
+ success = FALSE;
+ errno = 0;
+ port = strtol (items[1], NULL, 10);
+ if ((errno == 0) && (port > 0) && (port < 65536)) {
+ s_port = g_strdup_printf ("%d", (guint32) port);
+ success = TRUE;
+ }
+ }
+
+ if (success) {
+ nm_setting_vpn_add_data_item (s_vpn, NM_OPENVPN_KEY_HTTP_PROXY, items[0]);
+ nm_setting_vpn_add_data_item (s_vpn, NM_OPENVPN_KEY_HTTP_PROXY_PORT, s_port);
+ if (user)
+ nm_setting_vpn_add_data_item (s_vpn, NM_OPENVPN_KEY_HTTP_PROXY_USERNAME, user);
+ if (pass)
+ nm_setting_vpn_add_secret (s_vpn, NM_OPENVPN_KEY_HTTP_PROXY_PASSWORD, pass);
+ }
+ g_free (s_port);
+ g_free (user);
+ g_free (pass);
+ }
+
+ if (!success)
+ g_warning ("%s: invalid http proxy port in option '%s'", __func__, *line);
+
+ g_strfreev (items);
+ continue;
+ }
+
if (!strncmp (*line, REMOTE_TAG, strlen (REMOTE_TAG))) {
items = get_args (*line + strlen (REMOTE_TAG));
if (!items)
diff --git a/properties/nm-openvpn-dialog.glade b/properties/nm-openvpn-dialog.glade
index 2e30529..af4c9dc 100644
--- a/properties/nm-openvpn-dialog.glade
+++ b/properties/nm-openvpn-dialog.glade
@@ -1394,6 +1394,217 @@ Example: /CN=myvpn.company.com</i></property>
<property name="type">tab</property>
</packing>
</child>
+ <child>
+ <widget class="GtkAlignment" id="alignment2">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="yscale">0</property>
+ <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="table1">
+ <property name="visible">True</property>
+ <property name="n_rows">6</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkComboBox" id="proxy_type_combo">
+ <property name="visible">True</property>
+ <property name="button_sensitivity">on</property>
+ <property name="items" translatable="yes">Not required</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Proxy Type:</property>
+ <property name="justify">right</property>
+ </widget>
+ <packing>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="proxy_desc_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes"><i>Select this option if your organization requires the use of a proxy server to access the Internet.</i></property>
+ <property name="use_markup">True</property>
+ <property name="wrap">True</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="proxy_server_label">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Server Address:</property>
+ </widget>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkAlignment" id="alignment4">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="xscale">0</property>
+ <child>
+ <widget class="GtkHBox" id="hbox2">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkEntry" id="proxy_server_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="proxy_port_label">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Port:</property>
+ <property name="justify">right</property>
+ </widget>
+ <packing>
+ <property name="padding">6</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSpinButton" id="proxy_port_spinbutton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <property name="width_chars">5</property>
+ <property name="adjustment">8080 1 65535 1 10 0</property>
+ <property name="climb_rate">1</property>
+ <property name="numeric">True</property>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </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>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="proxy_retry_checkbutton">
+ <property name="label" translatable="yes">Retry indefinitely when errors occur</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="proxy_username_label">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Proxy Username:</property>
+ <property name="justify">right</property>
+ </widget>
+ <packing>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="proxy_password_label">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Proxy Password:</property>
+ <property name="justify">right</property>
+ </widget>
+ <packing>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="proxy_username_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="proxy_password_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="visibility">False</property>
+ <property name="invisible_char">●</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label32">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Proxies</property>
+ </widget>
+ <packing>
+ <property name="position">3</property>
+ <property name="tab_fill">False</property>
+ <property name="type">tab</property>
+ </packing>
+ </child>
</widget>
<packing>
<property name="expand">False</property>
diff --git a/properties/nm-openvpn.c b/properties/nm-openvpn.c
index b885368..11dbe19 100644
--- a/properties/nm-openvpn.c
+++ b/properties/nm-openvpn.c
@@ -5,7 +5,7 @@
* nm-openvpn.c : GNOME UI dialogs for configuring openvpn VPN connections
*
* Copyright (C) 2005 Tim Niemueller <tim niemueller de>
- * Copyright (C) 2008 Dan Williams, <dcbw redhat com>
+ * Copyright (C) 2008 - 2010 Dan Williams, <dcbw redhat com>
* Based on work by David Zeuthen, <davidz redhat com>
*
* This program is free software; you can redistribute it and/or modify
@@ -395,7 +395,13 @@ hash_copy_advanced (gpointer key, gpointer data, gpointer user_data)
NMSettingVPN *s_vpn = NM_SETTING_VPN (user_data);
const char *value = (const char *) data;
- nm_setting_vpn_add_data_item (s_vpn, (const char *) key, value);
+ g_return_if_fail (value && strlen (value));
+
+ /* HTTP Proxy password is a secret, not a data item */
+ if (!strcmp (value, NM_OPENVPN_KEY_HTTP_PROXY_PASSWORD))
+ nm_setting_vpn_add_secret (s_vpn, (const char *) key, value);
+ else
+ nm_setting_vpn_add_data_item (s_vpn, (const char *) key, value);
}
static const char *
@@ -479,6 +485,8 @@ save_secrets (NMVpnPluginUiWidgetInterface *iface,
auth_type = get_auth_type (priv->xml);
if (auth_type)
ret = auth_widget_save_secrets (priv->xml, auth_type, uuid, id);
+ if (ret)
+ ret = advanced_save_secrets (priv->advanced, uuid, id);
if (!ret)
g_set_error (error, OPENVPN_PLUGIN_UI_ERROR,
diff --git a/src/nm-openvpn-service.c b/src/nm-openvpn-service.c
index b242243..2e27a82 100644
--- a/src/nm-openvpn-service.c
+++ b/src/nm-openvpn-service.c
@@ -70,6 +70,8 @@ typedef struct {
char *username;
char *password;
char *priv_key_pass;
+ char *proxy_username;
+ char *proxy_password;
GIOChannel *socket_channel;
guint socket_channel_eventid;
} NMOpenvpnPluginIOData;
@@ -102,6 +104,10 @@ static ValidProperty valid_properties[] = {
{ NM_OPENVPN_KEY_MSSFIX, G_TYPE_BOOLEAN, 0, 0, FALSE },
{ NM_OPENVPN_KEY_PROTO_TCP, G_TYPE_BOOLEAN, 0, 0, FALSE },
{ NM_OPENVPN_KEY_PORT, G_TYPE_INT, 1, 65535, FALSE },
+ { NM_OPENVPN_KEY_HTTP_PROXY, G_TYPE_STRING, 0, 0, FALSE },
+ { NM_OPENVPN_KEY_HTTP_PROXY_PORT, G_TYPE_INT, 1, 65535, FALSE },
+ { NM_OPENVPN_KEY_HTTP_PROXY_RETRY, G_TYPE_BOOLEAN, 0, 0, FALSE },
+ { NM_OPENVPN_KEY_HTTP_PROXY_USERNAME, G_TYPE_STRING, 0, 0, FALSE },
{ NM_OPENVPN_KEY_REMOTE, G_TYPE_STRING, 0, 0, FALSE },
{ NM_OPENVPN_KEY_REMOTE_IP, G_TYPE_STRING, 0, 0, TRUE },
{ NM_OPENVPN_KEY_RENEG_SECONDS, G_TYPE_INT, 0, G_MAXINT, FALSE },
@@ -120,6 +126,7 @@ static ValidProperty valid_secrets[] = {
{ NM_OPENVPN_KEY_PASSWORD, G_TYPE_STRING, 0, 0, FALSE },
{ NM_OPENVPN_KEY_CERTPASS, G_TYPE_STRING, 0, 0, FALSE },
{ NM_OPENVPN_KEY_NOSECRET, G_TYPE_STRING, 0, 0, FALSE },
+ { NM_OPENVPN_KEY_HTTP_PROXY_PASSWORD, G_TYPE_STRING, 0, 0, FALSE },
{ NULL, G_TYPE_NONE, FALSE }
};
@@ -283,8 +290,20 @@ nm_openvpn_disconnect_management_socket (NMOpenvpnPlugin *plugin)
g_io_channel_unref (io_data->socket_channel);
g_free (io_data->username);
+ g_free (io_data->proxy_username);
+
+ if (io_data->password)
+ memset (io_data->password, 0, strlen (io_data->password));
g_free (io_data->password);
+ if (io_data->priv_key_pass)
+ memset (io_data->priv_key_pass, 0, strlen (io_data->priv_key_pass));
+ g_free (io_data->priv_key_pass);
+
+ if (io_data->proxy_password)
+ memset (io_data->proxy_password, 0, strlen (io_data->proxy_password));
+ g_free (io_data->proxy_password);
+
g_free (priv->io_data);
priv->io_data = NULL;
}
@@ -338,6 +357,33 @@ get_detail (const char *input, const char *prefix)
return ret;
}
+static void
+write_user_pass (GIOChannel *channel,
+ const char *authtype,
+ const char *user,
+ const char *pass)
+{
+ char *quser, *qpass, *buf;
+
+ /* Quote strings passed back to openvpn */
+ quser = ovpn_quote_string (user);
+ qpass = ovpn_quote_string (pass);
+ buf = g_strdup_printf ("username \"%s\" \"%s\"\n"
+ "password \"%s\" \"%s\"\n",
+ authtype, quser,
+ authtype, qpass);
+ memset (qpass, 0, strlen (qpass));
+ g_free (qpass);
+ g_free (quser);
+
+ /* Will always write everything in blocking channels (on success) */
+ g_io_channel_write_chars (channel, buf, strlen (buf), NULL, NULL);
+ g_io_channel_flush (channel, NULL);
+
+ memset (buf, 0, strlen (buf));
+ g_free (buf);
+}
+
static gboolean
handle_management_socket (NMVPNPlugin *plugin,
GIOChannel *source,
@@ -347,7 +393,6 @@ handle_management_socket (NMVPNPlugin *plugin,
NMOpenvpnPluginIOData *io_data = NM_OPENVPN_PLUGIN_GET_PRIVATE (plugin)->io_data;
gboolean again = TRUE;
char *str = NULL, *auth = NULL, *buf;
- gsize written;
if (!(condition & G_IO_IN))
return TRUE;
@@ -361,25 +406,9 @@ handle_management_socket (NMVPNPlugin *plugin,
auth = get_detail (str, ">PASSWORD:Need '");
if (auth) {
if (strcmp (auth, "Auth") == 0) {
- if (io_data->username != NULL && io_data->password != NULL) {
- char *quser, *qpass;
-
- /* Quote strings passed back to openvpn */
- quser = ovpn_quote_string (io_data->username);
- qpass = ovpn_quote_string (io_data->password);
- buf = g_strdup_printf ("username \"%s\" \"%s\"\n"
- "password \"%s\" \"%s\"\n",
- auth, quser,
- auth, qpass);
- memset (qpass, 0, strlen (qpass));
- g_free (qpass);
- g_free (quser);
-
- /* Will always write everything in blocking channels (on success) */
- g_io_channel_write_chars (source, buf, strlen (buf), &written, NULL);
- g_io_channel_flush (source, NULL);
- g_free (buf);
- } else
+ if (io_data->username != NULL && io_data->password != NULL)
+ write_user_pass (source, auth, io_data->username, io_data->password);
+ else
nm_warning ("Auth requested but one of username or password is missing");
} else if (!strcmp (auth, "Private Key")) {
if (io_data->priv_key_pass) {
@@ -392,11 +421,16 @@ handle_management_socket (NMVPNPlugin *plugin,
g_free (qpass);
/* Will always write everything in blocking channels (on success) */
- g_io_channel_write_chars (source, buf, strlen (buf), &written, NULL);
+ g_io_channel_write_chars (source, buf, strlen (buf), NULL, NULL);
g_io_channel_flush (source, NULL);
g_free (buf);
} else
nm_warning ("Certificate password requested but private key password == NULL");
+ } else if (strcmp (auth, "HTTP Proxy") == 0) {
+ if (io_data->proxy_username != NULL && io_data->proxy_password != NULL)
+ write_user_pass (source, auth, io_data->proxy_username, io_data->proxy_password);
+ else
+ nm_warning ("HTTP Proxy auth requested but either proxy username or password is missing");
} else {
nm_warning ("No clue what to send for username/password request for '%s'", auth);
if (out_failure)
@@ -686,7 +720,7 @@ nm_openvpn_start_openvpn_binary (NMOpenvpnPlugin *plugin,
GError **error)
{
NMOpenvpnPluginPrivate *priv = NM_OPENVPN_PLUGIN_GET_PRIVATE (plugin);
- const char *openvpn_binary, *auth, *connection_type, *tmp;
+ const char *openvpn_binary, *auth, *connection_type, *tmp, *tmp2;
GPtrArray *args;
GSource *openvpn_watch;
GPid pid;
@@ -734,6 +768,19 @@ nm_openvpn_start_openvpn_binary (NMOpenvpnPlugin *plugin,
add_openvpn_arg (args, tmp);
}
+ tmp = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_HTTP_PROXY);
+ tmp2 = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_HTTP_PROXY_PORT);
+ if (tmp && strlen (tmp) && tmp2 && strlen (tmp2)) {
+ add_openvpn_arg (args, "--http-proxy");
+ add_openvpn_arg (args, tmp);
+ add_openvpn_arg (args, tmp2);
+ add_openvpn_arg (args, "'auto'"); /* Automatic proxy auth method detection */
+ }
+
+ tmp = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_HTTP_PROXY_RETRY);
+ if (tmp && strlen (tmp))
+ add_openvpn_arg (args, "--http-proxy-retry");
+
tmp = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_COMP_LZO);
if (tmp && !strcmp (tmp, "yes"))
add_openvpn_arg (args, "--comp-lzo");
@@ -988,24 +1035,28 @@ nm_openvpn_start_openvpn_binary (NMOpenvpnPlugin *plugin,
*/
if ( !strcmp (connection_type, NM_OPENVPN_CONTYPE_TLS)
|| !strcmp (connection_type, NM_OPENVPN_CONTYPE_PASSWORD)
- || !strcmp (connection_type, NM_OPENVPN_CONTYPE_PASSWORD_TLS)) {
- NMOpenvpnPluginIOData *io_data;
+ || !strcmp (connection_type, NM_OPENVPN_CONTYPE_PASSWORD_TLS)
+ || nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_HTTP_PROXY_USERNAME)) {
- io_data = g_new0 (NMOpenvpnPluginIOData, 1);
+ priv->io_data = g_malloc0 (sizeof (NMOpenvpnPluginIOData));
tmp = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_USERNAME);
- io_data->username = tmp ? g_strdup (tmp) : NULL;
+ priv->io_data->username = tmp ? g_strdup (tmp) : NULL;
/* Use the default username if it wasn't overridden by the user */
- if (!io_data->username && default_username)
- io_data->username = g_strdup (default_username);
+ if (!priv->io_data->username && default_username)
+ priv->io_data->username = g_strdup (default_username);
tmp = nm_setting_vpn_get_secret (s_vpn, NM_OPENVPN_KEY_PASSWORD);
- io_data->password = tmp ? g_strdup (tmp) : NULL;
+ priv->io_data->password = tmp ? g_strdup (tmp) : NULL;
tmp = nm_setting_vpn_get_secret (s_vpn, NM_OPENVPN_KEY_CERTPASS);
- io_data->priv_key_pass = tmp ? g_strdup (tmp) : NULL;
+ priv->io_data->priv_key_pass = tmp ? g_strdup (tmp) : NULL;
- priv->io_data = io_data;
+ tmp = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_HTTP_PROXY_USERNAME);
+ priv->io_data->proxy_username = tmp ? g_strdup (tmp) : NULL;
+
+ tmp = nm_setting_vpn_get_secret (s_vpn, NM_OPENVPN_KEY_HTTP_PROXY_PASSWORD);
+ priv->io_data->proxy_password = tmp ? g_strdup (tmp) : NULL;
nm_openvpn_schedule_connect_timer (plugin);
}
@@ -1049,6 +1100,11 @@ check_need_secrets (NMSettingVPN *s_vpn, gboolean *need_secrets)
/* Static key doesn't need passwords */
}
+ /* HTTP Proxy might require a password; assume so if there's an HTTP proxy username */
+ tmp = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_HTTP_PROXY_USERNAME);
+ if (tmp && !nm_setting_vpn_get_secret (s_vpn, NM_OPENVPN_KEY_HTTP_PROXY_PASSWORD))
+ *need_secrets = TRUE;
+
return ctype;
}
diff --git a/src/nm-openvpn-service.h b/src/nm-openvpn-service.h
index f1e3f0d..c8a7619 100644
--- a/src/nm-openvpn-service.h
+++ b/src/nm-openvpn-service.h
@@ -50,6 +50,10 @@
#define NM_OPENVPN_KEY_MSSFIX "mssfix"
#define NM_OPENVPN_KEY_PORT "port"
#define NM_OPENVPN_KEY_PROTO_TCP "proto-tcp"
+#define NM_OPENVPN_KEY_HTTP_PROXY "http-proxy"
+#define NM_OPENVPN_KEY_HTTP_PROXY_PORT "http-proxy-port"
+#define NM_OPENVPN_KEY_HTTP_PROXY_RETRY "http-proxy-retry"
+#define NM_OPENVPN_KEY_HTTP_PROXY_USERNAME "http-proxy-username"
#define NM_OPENVPN_KEY_REMOTE "remote"
#define NM_OPENVPN_KEY_REMOTE_IP "remote-ip"
#define NM_OPENVPN_KEY_STATIC_KEY "static-key"
@@ -63,6 +67,7 @@
#define NM_OPENVPN_KEY_PASSWORD "password"
#define NM_OPENVPN_KEY_CERTPASS "cert-pass"
+#define NM_OPENVPN_KEY_HTTP_PROXY_PASSWORD "http-proxy-password"
/* Internal auth-dialog -> service token indicating that no secrets are
* required for the connection.
*/
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]