2008-06-26 Dan Williams <dcbw@redhat.com>

Implement the Advanced... dialog



git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3772 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams 2008-06-26 17:01:11 +00:00
parent ee805389c8
commit 1ad0ec8a31
6 changed files with 828 additions and 6 deletions

View file

@ -1,3 +1,7 @@
2008-06-26 Dan Williams <dcbw@redhat.com>
Implement the Advanced... dialog
2008-06-23 Dan Williams <dcbw@redhat.com>
* Convert to new NM VPN UI plugin format

View file

@ -3,6 +3,7 @@
auth-dialog/gnome-two-password-dialog.c
auth-dialog/main.c
nm-openvpn.desktop.in
properties/auth-helpers.c
properties/nm-openvpn.c
properties/nm-openvpn-dialog.glade
src/nm-openvpn-service.c

View file

@ -4,6 +4,7 @@
* nm-openvpn.c : GNOME UI dialogs for configuring openvpn VPN connections
*
* Copyright (C) 2008 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
* it under the terms of the GNU General Public License as published by
@ -254,7 +255,7 @@ validate_tls (GladeXML *xml, const char *prefix, GError **error)
return FALSE;
}
return FALSE;
return TRUE;
}
gboolean
@ -266,15 +267,14 @@ auth_widget_check_validity (GladeXML *xml, gint contype, GError **error)
switch (contype) {
case NM_OPENVPN_CONTYPE_TLS:
if (!validate_tls (xml, "tls", error))
is_valid = FALSE;
is_valid = validate_tls (xml, "tls", error);
break;
case NM_OPENVPN_CONTYPE_PASSWORD_TLS:
if (!validate_tls (xml, "pw_tls", error)) {
is_valid = FALSE;
is_valid = validate_tls (xml, "pw_tls", error);
if (!is_valid)
break;
}
widget = glade_xml_get_widget (xml, "pw_tls_username_entry");
str = gtk_entry_get_text (GTK_ENTRY (widget));
if (!str || !strlen (str)) {
@ -583,3 +583,403 @@ sk_file_chooser_filter_new (void)
return filter;
}
static void
nm_gvalue_destroy (gpointer data)
{
GValue *value = (GValue *) data;
g_value_unset (value);
g_slice_free (GValue, value);
}
static const char *advanced_keys[] = {
NM_OPENVPN_KEY_PORT,
NM_OPENVPN_KEY_COMP_LZO,
NM_OPENVPN_KEY_TAP_DEV,
NM_OPENVPN_KEY_PROTO_TCP,
NM_OPENVPN_KEY_CIPHER,
NM_OPENVPN_KEY_TA_DIR,
NM_OPENVPN_KEY_TA,
NULL
};
static void
copy_values (gpointer key, gpointer data, gpointer user_data)
{
GHashTable *hash = (GHashTable *) user_data;
GValue *value = (GValue *) data;
const char **i;
for (i = &advanced_keys[0]; *i; i++) {
if (strcmp ((const char *) key, *i))
continue;
if (G_VALUE_HOLDS_STRING (value)) {
g_hash_table_insert (hash,
g_strdup ((const char *) key),
str_to_gvalue (g_value_get_string (value)));
} else if (G_VALUE_HOLDS_INT (value)) {
g_hash_table_insert (hash,
g_strdup ((const char *) key),
int_to_gvalue (g_value_get_int (value)));
} else if (G_VALUE_HOLDS_BOOLEAN (value)) {
g_hash_table_insert (hash,
g_strdup ((const char *) key),
bool_to_gvalue (g_value_get_boolean (value)));
}
}
}
GHashTable *
advanced_dialog_new_hash_from_connection (NMConnection *connection,
GError **error)
{
GHashTable *hash;
NMSettingVPNProperties *s_vpn_props;
GValue *value;
hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, nm_gvalue_destroy);
s_vpn_props = (NMSettingVPNProperties *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN_PROPERTIES);
if (s_vpn_props && s_vpn_props->data)
g_hash_table_foreach (s_vpn_props->data, copy_values, hash);
return hash;
}
static void
port_toggled_cb (GtkWidget *check, gpointer user_data)
{
GladeXML *xml = (GladeXML *) user_data;
GtkWidget *widget;
widget = glade_xml_get_widget (xml, "port_spinbutton");
gtk_widget_set_sensitive (widget, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check)));
}
static const char *
nm_find_openvpn (void)
{
static const char *openvpn_binary_paths[] = {
"/usr/sbin/openvpn",
"/sbin/openvpn",
NULL
};
const char **openvpn_binary = openvpn_binary_paths;
while (*openvpn_binary != NULL) {
if (g_file_test (*openvpn_binary, G_FILE_TEST_EXISTS))
break;
openvpn_binary++;
}
return *openvpn_binary;
}
#define TLS_CIPHER_COL_NAME 0
#define TLS_CIPHER_COL_DEFAULT 1
static void
populate_cipher_combo (GtkComboBox *box, const char *user_cipher)
{
GtkListStore *store;
GtkTreeIter iter;
const char *openvpn_binary = NULL;
gchar *cmdline, *tmp, *token;
gboolean user_added = FALSE;
openvpn_binary = nm_find_openvpn ();
if (!openvpn_binary)
return;
cmdline = g_strdup_printf("/bin/sh -c \"%s --show-ciphers | /bin/awk '/^[A-Z][A-Z0-9]+-/ { print $1 }'\"", openvpn_binary);
if (!g_spawn_command_line_sync(cmdline, &tmp, NULL, NULL, NULL))
goto end;
token = strtok(tmp, "\n");
store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
gtk_combo_box_set_model (box, GTK_TREE_MODEL (store));
/* Add default option which won't pass --cipher to openvpn */
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
TLS_CIPHER_COL_NAME, _("Default"),
TLS_CIPHER_COL_DEFAULT, TRUE, -1);
while (token) {
if (strlen (token)) {
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
TLS_CIPHER_COL_NAME, token,
TLS_CIPHER_COL_DEFAULT, FALSE, -1);
if (user_cipher && !strcmp (token, user_cipher)) {
gtk_combo_box_set_active_iter (box, &iter);
user_added = TRUE;
}
}
token = strtok (NULL, "\n");
}
/* Add the user-specified cipher if it exists wasn't found by openvpn */
if (user_cipher && !user_added) {
gtk_list_store_insert (store, &iter, 1);
gtk_list_store_set (store, &iter,
TLS_CIPHER_COL_NAME, user_cipher,
TLS_CIPHER_COL_DEFAULT, FALSE -1);
gtk_combo_box_set_active_iter (box, &iter);
} else if (!user_added) {
gtk_combo_box_set_active (box, 0);
}
g_object_unref (G_OBJECT (store));
end:
g_free(tmp);
}
static void
tls_auth_toggled_cb (GtkWidget *widget, gpointer user_data)
{
GladeXML *xml = (GladeXML *) user_data;
gboolean use_auth = FALSE;
widget = glade_xml_get_widget (xml, "tls_auth_checkbutton");
use_auth = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
widget = glade_xml_get_widget (xml, "tls_dir_help_label");
gtk_widget_set_sensitive (widget, use_auth);
widget = glade_xml_get_widget (xml, "direction_label");
gtk_widget_set_sensitive (widget, use_auth);
widget = glade_xml_get_widget (xml, "tls_auth_label");
gtk_widget_set_sensitive (widget, use_auth);
widget = glade_xml_get_widget (xml, "tls_auth_chooser");
gtk_widget_set_sensitive (widget, use_auth);
widget = glade_xml_get_widget (xml, "direction_combo");
gtk_widget_set_sensitive (widget, use_auth);
}
#define TA_DIR_COL_NAME 0
#define TA_DIR_COL_NUM 1
GtkWidget *
advanced_dialog_new (GHashTable *hash, int contype)
{
GladeXML *xml;
GtkWidget *dialog = NULL;
char *glade_file = NULL;
GtkWidget *widget;
GValue *value;
g_return_val_if_fail (hash != NULL, NULL);
glade_file = g_strdup_printf ("%s/%s", GLADEDIR, "nm-openvpn-dialog.glade");
xml = glade_xml_new (glade_file, "openvpn-advanced-dialog", GETTEXT_PACKAGE);
if (xml == NULL)
goto out;
dialog = glade_xml_get_widget (xml, "openvpn-advanced-dialog");
if (!dialog) {
g_object_unref (G_OBJECT (xml));
goto out;
}
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
g_object_set_data_full (G_OBJECT (dialog), "glade-xml",
xml, (GDestroyNotify) g_object_unref);
g_object_set_data (G_OBJECT (dialog), "connection-type", GINT_TO_POINTER (contype));
widget = glade_xml_get_widget (xml, "port_checkbutton");
g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (port_toggled_cb), xml);
value = g_hash_table_lookup (hash, NM_OPENVPN_KEY_PORT);
if (value && G_VALUE_HOLDS_INT (value)) {
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
widget = glade_xml_get_widget (xml, "port_spinbutton");
gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget),
(gdouble) g_value_get_int (value));
gtk_widget_set_sensitive (widget, TRUE);
} else {
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE);
widget = glade_xml_get_widget (xml, "port_spinbutton");
gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), 1194.0);
gtk_widget_set_sensitive (widget, FALSE);
}
value = g_hash_table_lookup (hash, NM_OPENVPN_KEY_COMP_LZO);
if (value && G_VALUE_HOLDS_BOOLEAN (value)) {
widget = glade_xml_get_widget (xml, "lzo_checkbutton");
if (g_value_get_boolean (value))
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
}
value = g_hash_table_lookup (hash, NM_OPENVPN_KEY_PROTO_TCP);
if (value && G_VALUE_HOLDS_BOOLEAN (value)) {
widget = glade_xml_get_widget (xml, "tcp_checkbutton");
if (g_value_get_boolean (value))
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
}
value = g_hash_table_lookup (hash, NM_OPENVPN_KEY_TAP_DEV);
if (value && G_VALUE_HOLDS_BOOLEAN (value)) {
widget = glade_xml_get_widget (xml, "tap_checkbutton");
if (g_value_get_boolean (value))
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
}
if (contype != NM_OPENVPN_CONTYPE_TLS && contype != NM_OPENVPN_CONTYPE_PASSWORD_TLS) {
widget = glade_xml_get_widget (xml, "options_notebook");
gtk_notebook_remove_page (GTK_NOTEBOOK (widget), 1);
} else {
char *user_cipher = NULL;
GtkListStore *store;
GtkTreeIter iter;
int direction = -1, active = -1;
widget = glade_xml_get_widget (xml, "cipher_combo");
value = g_hash_table_lookup (hash, NM_OPENVPN_KEY_CIPHER);
if (value && G_VALUE_HOLDS_STRING (value))
user_cipher = (char *) g_value_get_string (value);
populate_cipher_combo (GTK_COMBO_BOX (widget), user_cipher);
widget = glade_xml_get_widget (xml, "tls_auth_checkbutton");
value = g_hash_table_lookup (hash, NM_OPENVPN_KEY_TA);
if (value && G_VALUE_HOLDS_STRING (value)) {
if (strlen (g_value_get_string (value)))
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
}
g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (tls_auth_toggled_cb), xml);
tls_auth_toggled_cb (widget, xml);
widget = glade_xml_get_widget (xml, "direction_combo");
value = g_hash_table_lookup (hash, NM_OPENVPN_KEY_TA_DIR);
if (value && G_VALUE_HOLDS_STRING (value)) {
direction = (int) strtol (g_value_get_string (value), NULL, 10);
/* If direction is not 0 or 1, use no direction */
if (direction != 0 && direction != 1)
direction = -1;
}
store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, TA_DIR_COL_NAME, _("None"), TA_DIR_COL_NUM, -1, -1);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, TA_DIR_COL_NAME, "0", TA_DIR_COL_NUM, 0, -1);
if (direction == 0)
active = 1;
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, TA_DIR_COL_NAME, "1", TA_DIR_COL_NUM, 1, -1);
if (direction == 1)
active = 2;
gtk_combo_box_set_model (GTK_COMBO_BOX (widget), GTK_TREE_MODEL (store));
g_object_unref (store);
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), active < 0 ? 0 : active);
value = g_hash_table_lookup (hash, NM_OPENVPN_KEY_TA);
if (value && G_VALUE_HOLDS_STRING (value)) {
widget = glade_xml_get_widget (xml, "tls_auth_chooser");
gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), g_value_get_string (value));
}
}
out:
g_free (glade_file);
return dialog;
}
GHashTable *
advanced_dialog_new_hash_from_dialog (GtkWidget *dialog, GError **error)
{
GHashTable *hash;
GtkWidget *widget;
GladeXML *xml;
int contype = NM_OPENVPN_CONTYPE_INVALID;
g_return_val_if_fail (dialog != NULL, NULL);
if (error)
g_return_val_if_fail (*error == NULL, NULL);
xml = g_object_get_data (G_OBJECT (dialog), "glade-xml");
g_return_val_if_fail (xml != NULL, NULL);
hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, nm_gvalue_destroy);
widget = glade_xml_get_widget (xml, "port_checkbutton");
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) {
int port;
widget = glade_xml_get_widget (xml, "port_spinbutton");
port = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (widget));
g_hash_table_insert (hash, g_strdup (NM_OPENVPN_KEY_PORT), int_to_gvalue (port));
}
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), bool_to_gvalue (TRUE));
widget = glade_xml_get_widget (xml, "tcp_checkbutton");
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
g_hash_table_insert (hash, g_strdup (NM_OPENVPN_KEY_PROTO_TCP), bool_to_gvalue (TRUE));
widget = glade_xml_get_widget (xml, "tap_checkbutton");
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
g_hash_table_insert (hash, g_strdup (NM_OPENVPN_KEY_TAP_DEV), bool_to_gvalue (TRUE));
contype = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dialog), "connection-type"));
if (contype == NM_OPENVPN_CONTYPE_TLS || contype == NM_OPENVPN_CONTYPE_PASSWORD_TLS) {
GtkTreeModel *model;
GtkTreeIter iter;
widget = glade_xml_get_widget (xml, "cipher_combo");
model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter)) {
char *cipher = NULL;
gboolean is_default = TRUE;
gtk_tree_model_get (model, &iter,
TLS_CIPHER_COL_NAME, &cipher,
TLS_CIPHER_COL_DEFAULT, &is_default, -1);
if (!is_default && cipher) {
g_hash_table_insert (hash, g_strdup (NM_OPENVPN_KEY_CIPHER),
str_to_gvalue (cipher));
}
}
widget = glade_xml_get_widget (xml, "tls_auth_checkbutton");
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) {
char *filename;
widget = glade_xml_get_widget (xml, "tls_auth_chooser");
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
if (filename && strlen (filename)) {
g_hash_table_insert (hash, g_strdup (NM_OPENVPN_KEY_TA),
str_to_gvalue (filename));
}
g_free (filename);
widget = glade_xml_get_widget (xml, "direction_combo");
model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter)) {
int direction = -1;
gtk_tree_model_get (model, &iter, TA_DIR_COL_NUM, &direction, -1);
if (direction >= 0) {
char str_dir[2] = { '0', '\0' };
str_dir[0] = (direction == 0) ? '0' : '1';
g_hash_table_insert (hash, g_strdup (NM_OPENVPN_KEY_TA_DIR),
str_to_gvalue (str_dir));
}
}
}
}
return hash;
}

View file

@ -29,6 +29,7 @@
#include <gtk/gtkfilefilter.h>
#include <glade/glade.h>
#include <nm-connection.h>
#include <nm-setting-vpn-properties.h>
typedef void (*ChangedCallback) (GtkWidget *widget, gpointer user_data);
@ -57,4 +58,10 @@ GtkFileFilter *tls_file_chooser_filter_new (void);
GtkFileFilter *sk_file_chooser_filter_new (void);
GtkWidget *advanced_dialog_new (GHashTable *hash, int contype);
GHashTable *advanced_dialog_new_hash_from_connection (NMConnection *connection, GError **error);
GHashTable *advanced_dialog_new_hash_from_dialog (GtkWidget *dialog, GError **error);
#endif

View file

@ -656,4 +656,299 @@
</widget>
</child>
</widget>
<widget class="GtkDialog" id="openvpn-advanced-dialog">
<property name="border_width">5</property>
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
<property name="destroy_with_parent">True</property>
<property name="icon_name">stock-preferences</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="skip_pager_hint">True</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox1">
<property name="visible">True</property>
<property name="spacing">2</property>
<child>
<widget class="GtkNotebook" id="options_notebook">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="border_width">12</property>
<property name="spacing">6</property>
<child>
<widget class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<property name="spacing">6</property>
<child>
<widget class="GtkCheckButton" id="port_checkbutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Use custom gateway p_ort:</property>
<property name="use_underline">True</property>
<property name="response_id">0</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="expand">False</property>
</packing>
</child>
<child>
<widget class="GtkSpinButton" id="port_spinbutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="adjustment">1194 1 65535 1 10 10</property>
<property name="numeric">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="lzo_checkbutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Use L_ZO data compression</property>
<property name="use_underline">True</property>
<property name="response_id">0</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="tcp_checkbutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Use a _TCP connection</property>
<property name="use_underline">True</property>
<property name="response_id">0</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="tap_checkbutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Use a TA_P device</property>
<property name="use_underline">True</property>
<property name="response_id">0</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">3</property>
</packing>
</child>
</widget>
</child>
<child>
<widget class="GtkLabel" id="label13">
<property name="visible">True</property>
<property name="label" translatable="yes">General</property>
</widget>
<packing>
<property name="type">tab</property>
<property name="tab_fill">False</property>
</packing>
</child>
<child>
<widget class="GtkTable" id="table7">
<property name="visible">True</property>
<property name="border_width">12</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>
<placeholder/>
</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="tls_auth_label">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Key File:</property>
</widget>
</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="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>
<placeholder/>
</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="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>
</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="tls_auth_checkbutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Use additional TLS authentication</property>
<property name="response_id">0</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<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="label19">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Cipher:</property>
</widget>
<packing>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
<child>
<widget class="GtkComboBox" id="cipher_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="y_options">GTK_EXPAND</property>
</packing>
</child>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label18">
<property name="visible">True</property>
<property name="label" translatable="yes">Certificates (TLS)</property>
</widget>
<packing>
<property name="type">tab</property>
<property name="position">1</property>
<property name="tab_fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="cancel_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="label" translatable="yes">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="response_id">-6</property>
</widget>
</child>
<child>
<widget class="GtkButton" id="ok_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="label" translatable="yes">gtk-ok</property>
<property name="use_stock">True</property>
<property name="response_id">-5</property>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

View file

@ -82,6 +82,9 @@ typedef struct {
GladeXML *xml;
GtkWidget *widget;
GtkSizeGroup *group;
GtkWindowGroup *window_group;
gboolean window_added;
GHashTable *advanced;
} OpenvpnPluginUiWidgetPrivate;
@ -185,6 +188,73 @@ auth_combo_changed_cb (GtkWidget *combo, gpointer user_data)
stuff_changed_cb (combo, self);
}
static void
advanced_dialog_close_cb (GtkWidget *dialog, gpointer user_data)
{
OpenvpnPluginUiWidget *self = OPENVPN_PLUGIN_UI_WIDGET (user_data);
OpenvpnPluginUiWidgetPrivate *priv = OPENVPN_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
gtk_widget_hide (dialog);
/* gtk_widget_destroy() will remove the window from the window group */
gtk_widget_destroy (dialog);
}
static void
advanced_dialog_response_cb (GtkWidget *dialog, gint response, gpointer user_data)
{
OpenvpnPluginUiWidget *self = OPENVPN_PLUGIN_UI_WIDGET (user_data);
OpenvpnPluginUiWidgetPrivate *priv = OPENVPN_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
GError *error = NULL;
if (priv->advanced)
g_hash_table_destroy (priv->advanced);
priv->advanced = advanced_dialog_new_hash_from_dialog (dialog, &error);
if (!priv->advanced) {
g_message ("%s: error reading advanced settings: %s", __func__, error->message);
g_error_free (error);
}
advanced_dialog_close_cb (dialog, self);
stuff_changed_cb (NULL, self);
}
static void
advanced_button_clicked_cb (GtkWidget *button, gpointer user_data)
{
OpenvpnPluginUiWidget *self = OPENVPN_PLUGIN_UI_WIDGET (user_data);
OpenvpnPluginUiWidgetPrivate *priv = OPENVPN_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
GtkWidget *dialog, *toplevel, *widget;
GtkTreeModel *model;
GtkTreeIter iter;
int contype = NM_OPENVPN_CONTYPE_INVALID;
toplevel = gtk_widget_get_toplevel (priv->widget);
g_return_if_fail (GTK_WIDGET_TOPLEVEL (toplevel));
widget = glade_xml_get_widget (priv->xml, "auth_combo");
model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter))
gtk_tree_model_get (model, &iter, COL_AUTH_TYPE, &contype, -1);
dialog = advanced_dialog_new (priv->advanced, contype);
if (!dialog) {
g_warning ("%s: failed to create the Advanced dialog!", __func__);
return;
}
gtk_window_group_add_window (priv->window_group, GTK_WINDOW (dialog));
if (!priv->window_added) {
gtk_window_group_add_window (priv->window_group, GTK_WINDOW (toplevel));
priv->window_added = TRUE;
}
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (toplevel));
g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (advanced_dialog_response_cb), self);
g_signal_connect (G_OBJECT (dialog), "close", G_CALLBACK (advanced_dialog_close_cb), self);
gtk_widget_show_all (dialog);
}
static gboolean
init_plugin_ui (OpenvpnPluginUiWidget *self, NMConnection *connection, GError **error)
{
@ -286,6 +356,9 @@ init_plugin_ui (OpenvpnPluginUiWidget *self, NMConnection *connection, GError **
g_signal_connect (widget, "changed", G_CALLBACK (auth_combo_changed_cb), self);
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), active < 0 ? 0 : active);
widget = glade_xml_get_widget (priv->xml, "advanced_button");
g_signal_connect (G_OBJECT (widget), "clicked", G_CALLBACK (advanced_button_clicked_cb), self);
return TRUE;
}
@ -334,6 +407,31 @@ int_to_gvalue (gint i)
return value;
}
static void
hash_copy_advanced (gpointer key, gpointer data, gpointer user_data)
{
GHashTable *hash = (GHashTable *) user_data;
GValue *value = (GValue *) data;
const char *i;
if (G_VALUE_HOLDS_STRING (value)) {
g_hash_table_insert (hash,
g_strdup ((const char *) key),
str_to_gvalue (g_value_get_string (value)));
} else if (G_VALUE_HOLDS_INT (value)) {
g_hash_table_insert (hash,
g_strdup ((const char *) key),
int_to_gvalue (g_value_get_int (value)));
} else if (G_VALUE_HOLDS_BOOLEAN (value)) {
g_hash_table_insert (hash,
g_strdup ((const char *) key),
bool_to_gvalue (g_value_get_boolean (value)));
} else {
g_warning ("%s: unhandled key '%s' of type '%s'",
__func__, (const char *) key, G_VALUE_TYPE_NAME (value));
}
}
static gboolean
update_connection (NMVpnPluginUiWidgetInterface *iface,
NMConnection *connection,
@ -388,6 +486,9 @@ update_connection (NMVpnPluginUiWidgetInterface *iface,
}
}
if (priv->advanced)
g_hash_table_foreach (priv->advanced, hash_copy_advanced, s_vpn_props->data);
nm_connection_add_setting (connection, NM_SETTING (s_vpn_props));
valid = TRUE;
@ -432,11 +533,19 @@ nm_vpn_plugin_ui_widget_interface_new (NMConnection *connection, GError **error)
}
g_object_ref_sink (priv->widget);
priv->window_group = gtk_window_group_new ();
if (!init_plugin_ui (OPENVPN_PLUGIN_UI_WIDGET (object), connection, error)) {
g_object_unref (object);
return NULL;
}
priv->advanced = advanced_dialog_new_hash_from_connection (connection, error);
if (!priv->advanced) {
g_object_unref (object);
return NULL;
}
return object;
}
@ -449,12 +558,18 @@ dispose (GObject *object)
if (priv->group)
g_object_unref (priv->group);
if (priv->window_group)
g_object_unref (priv->window_group);
if (priv->widget)
g_object_unref (priv->widget);
if (priv->xml)
g_object_unref (priv->xml);
if (priv->advanced)
g_hash_table_destroy (priv->advanced);
G_OBJECT_CLASS (openvpn_plugin_ui_widget_parent_class)->dispose (object);
}