diff --git a/src/charon/plugins/nm/gnome/auth-dialog/main.c b/src/charon/plugins/nm/gnome/auth-dialog/main.c
index ee9ba0bb9..92356c6ba 100644
--- a/src/charon/plugins/nm/gnome/auth-dialog/main.c
+++ b/src/charon/plugins/nm/gnome/auth-dialog/main.c
@@ -63,9 +63,9 @@ static char *lookup_password(char *name, char *service)
}
/**
- * check if this connection needs a password
+ * get the connection type
*/
-static gboolean need_password(char *id)
+static char* get_connection_type(char *id)
{
GConfClient *client;
char *key, *str;
@@ -75,14 +75,9 @@ static gboolean need_password(char *id)
key = g_strdup_printf("/system/networking/connections/%s/%s/%s",
id, NM_SETTING_VPN_SETTING_NAME, "method");
str = gconf_client_get_string(client, key, NULL);
- if (str && !strcmp(str, "eap"))
- {
- need_password = TRUE;
- }
- g_free(str);
g_free(key);
g_object_unref(client);
- return need_password;
+ return str;
}
int main (int argc, char *argv[])
@@ -92,7 +87,7 @@ int main (int argc, char *argv[])
GOptionContext *context;
GnomeProgram *program = NULL;
int exit_status = 1;
- char buf, *agent;
+ char buf, *agent, *type;
guint32 itemid;
GtkWidget *dialog;
GOptionEntry entries[] = {
@@ -131,14 +126,30 @@ int main (int argc, char *argv[])
return 1;
}
- if (need_password(id))
+ type = get_connection_type(id);
+ if (!type)
+ {
+ fprintf(stderr, "Connection lookup failed\n");
+ g_object_unref (program);
+ return 1;
+ }
+ if (!strcmp(type, "eap") || !strcmp(type, "key"))
{
pass = lookup_password(name, service);
if (!pass || retry)
{
- dialog = gnome_password_dialog_new(_("VPN password required"),
- _("Password required to establish VPN connection:"),
- NULL, NULL, TRUE);
+ if (!strcmp(type, "eap"))
+ {
+ dialog = gnome_password_dialog_new(_("VPN password required"),
+ _("EAP password required to establish VPN connection:"),
+ NULL, NULL, TRUE);
+ }
+ else
+ {
+ dialog = gnome_password_dialog_new(_("VPN password required"),
+ _("Private key decryption password required to establish VPN connection:"),
+ NULL, NULL, TRUE);
+ }
gnome_password_dialog_set_show_remember(GNOME_PASSWORD_DIALOG(dialog), TRUE);
gnome_password_dialog_set_show_username(GNOME_PASSWORD_DIALOG(dialog), FALSE);
if (pass)
diff --git a/src/charon/plugins/nm/gnome/properties/nm-strongswan-dialog.glade b/src/charon/plugins/nm/gnome/properties/nm-strongswan-dialog.glade
index f827ba2b3..f77eb42e7 100644
--- a/src/charon/plugins/nm/gnome/properties/nm-strongswan-dialog.glade
+++ b/src/charon/plugins/nm/gnome/properties/nm-strongswan-dialog.glade
@@ -37,28 +37,14 @@
6
6
-
- True
- Gateway certificate to use for gateway authentication.
-
-
- 1
- 2
- 1
- 2
-
-
-
-
+
True
0
- C_ertificate:
+ _Address:
True
- certificate-button
+ address-entry
- 1
- 2
GTK_FILL
@@ -77,18 +63,32 @@
-
+
True
0
- _Address:
+ C_ertificate:
True
- address-entry
+ certificate-button
+ 1
+ 2
GTK_FILL
+
+
+ True
+ Gateway certificate to use for gateway authentication.
+
+
+ 1
+ 2
+ 1
+ 2
+
+
@@ -124,33 +124,73 @@
True
- 3
+ 4
2
6
6
-
+
True
- Client certificate to use for client authentication.
+ Private key to use for client authentication. This key has to match the certificates public key and may be encrypted..
1
2
- 2
- 3
+ 3
+ 4
-
+
True
0
- Ce_rtificate:
+ Private _key:
True
- usercert-button
+ userkey-button
- 2
- 3
+ 3
+ 4
+ GTK_FILL
+
+
+
+
+
+ True
+ True
+ Authentication Method to use for authentication against the Gateway.
+
+
+
+ 1
+ 2
+
+
+
+
+ True
+ 0
+ Au_thentication:
+ True
+ method-combo
+
+
+ GTK_FILL
+
+
+
+
+
+ True
+ 0
+ _Username:
+ True
+ user-entry
+
+
+ 1
+ 2
GTK_FILL
@@ -171,43 +211,30 @@
-
+
True
0
- _Username:
+ Ce_rtificate:
True
- user-entry
+ usercert-button
- 1
- 2
+ 2
+ 3
GTK_FILL
-
+
True
- 0
- Au_thentication:
- True
- method-combo
-
-
- GTK_FILL
-
-
-
-
-
- True
- True
- Authentication Method to use for authentication against the Gateway.
-
+ Client certificate to use for client authentication.
1
2
+ 2
+ 3
diff --git a/src/charon/plugins/nm/gnome/properties/nm-strongswan.c b/src/charon/plugins/nm/gnome/properties/nm-strongswan.c
index 8d97a5560..24ca1502b 100644
--- a/src/charon/plugins/nm/gnome/properties/nm-strongswan.c
+++ b/src/charon/plugins/nm/gnome/properties/nm-strongswan.c
@@ -122,31 +122,50 @@ check_validity (StrongswanPluginUiWidget *self, GError **error)
return TRUE;
}
-static void
-settings_changed_cb (GtkWidget *widget, gpointer user_data)
+static void update_layout (GtkWidget *widget, StrongswanPluginUiWidgetPrivate *priv)
{
- g_signal_emit_by_name (STRONGSWAN_PLUGIN_UI_WIDGET (user_data), "changed");
+ switch (gtk_combo_box_get_active (GTK_COMBO_BOX (widget)))
+ {
+ default:
+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
+ /* FALL */
+ case 0:
+ gtk_widget_show (glade_xml_get_widget (priv->xml, "usercert-label"));
+ gtk_widget_show (glade_xml_get_widget (priv->xml, "usercert-button"));
+ gtk_widget_show (glade_xml_get_widget (priv->xml, "userkey-label"));
+ gtk_widget_show (glade_xml_get_widget (priv->xml, "userkey-button"));
+ gtk_widget_hide (glade_xml_get_widget (priv->xml, "user-label"));
+ gtk_widget_hide (glade_xml_get_widget (priv->xml, "user-entry"));
+ break;
+ case 1:
+ gtk_widget_show (glade_xml_get_widget (priv->xml, "usercert-label"));
+ gtk_widget_show (glade_xml_get_widget (priv->xml, "usercert-button"));
+ gtk_widget_hide (glade_xml_get_widget (priv->xml, "user-label"));
+ gtk_widget_hide (glade_xml_get_widget (priv->xml, "user-entry"));
+ gtk_widget_hide (glade_xml_get_widget (priv->xml, "userkey-label"));
+ gtk_widget_hide (glade_xml_get_widget (priv->xml, "userkey-button"));
+ break;
+ case 2:
+ gtk_widget_show (glade_xml_get_widget (priv->xml, "user-label"));
+ gtk_widget_show (glade_xml_get_widget (priv->xml, "user-entry"));
+ gtk_widget_hide (glade_xml_get_widget (priv->xml, "usercert-label"));
+ gtk_widget_hide (glade_xml_get_widget (priv->xml, "usercert-button"));
+ gtk_widget_hide (glade_xml_get_widget (priv->xml, "userkey-label"));
+ gtk_widget_hide (glade_xml_get_widget (priv->xml, "userkey-button"));
+ break;
+ }
+
}
static void
-method_changed_cb (GtkWidget *widget, gpointer user_data)
+settings_changed_cb (GtkWidget *widget, gpointer user_data)
{
StrongswanPluginUiWidget *self = STRONGSWAN_PLUGIN_UI_WIDGET (user_data);
StrongswanPluginUiWidgetPrivate *priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
- if (gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) == 0)
+ if (widget == glade_xml_get_widget (priv->xml, "method-combo"))
{
- gtk_widget_show (glade_xml_get_widget (priv->xml, "usercert-label"));
- gtk_widget_show (glade_xml_get_widget (priv->xml, "usercert-button"));
- gtk_widget_hide (glade_xml_get_widget (priv->xml, "user-label"));
- gtk_widget_hide (glade_xml_get_widget (priv->xml, "user-entry"));
- }
- else
- {
- gtk_widget_hide (glade_xml_get_widget (priv->xml, "usercert-label"));
- gtk_widget_hide (glade_xml_get_widget (priv->xml, "usercert-button"));
- gtk_widget_show (glade_xml_get_widget (priv->xml, "user-label"));
- gtk_widget_show (glade_xml_get_widget (priv->xml, "user-entry"));
+ update_layout(glade_xml_get_widget (priv->xml, "method-combo"), priv);
}
g_signal_emit_by_name (STRONGSWAN_PLUGIN_UI_WIDGET (user_data), "changed");
}
@@ -183,32 +202,27 @@ init_plugin_ui (StrongswanPluginUiWidget *self, NMConnection *connection, GError
g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (settings_changed_cb), self);
widget = glade_xml_get_widget (priv->xml, "method-combo");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (widget), _("Certificate/private key"));
gtk_combo_box_append_text (GTK_COMBO_BOX (widget), _("Certificate/ssh-agent"));
gtk_combo_box_append_text (GTK_COMBO_BOX (widget), _("EAP"));
value = g_hash_table_lookup (settings->data, "method");
if (value) {
- if (g_strcasecmp (value, "agent") == 0) {
+ if (g_strcasecmp (value, "key") == 0) {
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
}
- if (g_strcasecmp (value, "eap") == 0) {
+ if (g_strcasecmp (value, "agent") == 0) {
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 1);
}
+ if (g_strcasecmp (value, "eap") == 0) {
+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 2);
+ }
}
- g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (method_changed_cb), self);
if (gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) == -1)
{
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
}
- if (gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) != 0)
- {
- gtk_widget_hide (glade_xml_get_widget (priv->xml, "usercert-label"));
- gtk_widget_hide (glade_xml_get_widget (priv->xml, "usercert-button"));
- }
- else
- {
- gtk_widget_hide (glade_xml_get_widget (priv->xml, "user-label"));
- gtk_widget_hide (glade_xml_get_widget (priv->xml, "user-entry"));
- }
+ update_layout (widget, priv);
+ g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (settings_changed_cb), self);
widget = glade_xml_get_widget (priv->xml, "usercert-label");
gtk_widget_set_no_show_all (widget, TRUE);
@@ -219,6 +233,15 @@ init_plugin_ui (StrongswanPluginUiWidget *self, NMConnection *connection, GError
gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), value);
g_signal_connect (G_OBJECT (widget), "selection-changed", G_CALLBACK (settings_changed_cb), self);
+ widget = glade_xml_get_widget (priv->xml, "userkey-label");
+ gtk_widget_set_no_show_all (widget, TRUE);
+ widget = glade_xml_get_widget (priv->xml, "userkey-button");
+ gtk_widget_set_no_show_all (widget, TRUE);
+ value = g_hash_table_lookup (settings->data, "userkey");
+ if (value)
+ gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), value);
+ g_signal_connect (G_OBJECT (widget), "selection-changed", G_CALLBACK (settings_changed_cb), self);
+
widget = glade_xml_get_widget (priv->xml, "virtual-check");
value = g_hash_table_lookup (settings->data, "virtual");
if (value && strcmp(value, "yes") == 0)
@@ -290,8 +313,21 @@ update_connection (NMVpnPluginUiWidgetInterface *iface,
widget = glade_xml_get_widget (priv->xml, "method-combo");
switch (gtk_combo_box_get_active (GTK_COMBO_BOX (widget)))
{
- case 0:
default:
+ case 0:
+ widget = glade_xml_get_widget (priv->xml, "userkey-button");
+ str = (char *) gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
+ if (str) {
+ g_hash_table_insert (settings->data, g_strdup ("userkey"), g_strdup(str));
+ }
+ widget = glade_xml_get_widget (priv->xml, "usercert-button");
+ str = (char *) gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
+ if (str) {
+ g_hash_table_insert (settings->data, g_strdup ("usercert"), g_strdup(str));
+ }
+ str = "key";
+ break;
+ case 1:
widget = glade_xml_get_widget (priv->xml, "usercert-button");
str = (char *) gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
if (str) {
@@ -299,7 +335,7 @@ update_connection (NMVpnPluginUiWidgetInterface *iface,
}
str = "agent";
break;
- case 1:
+ case 2:
widget = glade_xml_get_widget (priv->xml, "user-entry");
str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
if (str && strlen (str)) {
diff --git a/src/charon/plugins/nm/nm_service.c b/src/charon/plugins/nm/nm_service.c
index 049a03ccb..e9edcf751 100644
--- a/src/charon/plugins/nm/nm_service.c
+++ b/src/charon/plugins/nm/nm_service.c
@@ -19,6 +19,7 @@
#include "nm_service.h"
#include
+#include
#include
#include
#include
@@ -174,6 +175,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
auth_info_t *auth;
auth_class_t auth_class = AUTH_CLASS_EAP;
certificate_t *cert = NULL;
+ bool agent = FALSE;
/**
* Read parameters
@@ -204,6 +206,11 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
auth_class = AUTH_CLASS_PSK;
}
else if (streq(str, "agent"))
+ {
+ auth_class = AUTH_CLASS_PUBKEY;
+ agent = TRUE;
+ }
+ else if (streq(str, "key"))
{
auth_class = AUTH_CLASS_PUBKEY;
}
@@ -253,9 +260,11 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
private_key_t *private = NULL;
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
- BUILD_FROM_FILE, str, BUILD_END);
+ BUILD_FROM_FILE, str, BUILD_END);
+
+ /* try agent */
str = g_hash_table_lookup(settings->data, "agent");
- if (str && cert)
+ if (agent && str && cert)
{
public = cert->get_public_key(cert);
if (public)
@@ -268,6 +277,25 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
public->destroy(public);
}
}
+ /* ... or key file */
+ str = g_hash_table_lookup(settings->data, "userkey");
+ if (!agent && str && cert)
+ {
+ chunk_t secret, chunk;
+ bool pgp = FALSE;
+
+ secret.ptr = g_hash_table_lookup(settings->data, "password");
+ if (secret.ptr)
+ {
+ secret.len = strlen(secret.ptr);
+ }
+ if (pem_asn1_load_file(str, &secret, &chunk, &pgp))
+ {
+ private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY,
+ KEY_RSA, BUILD_BLOB_ASN1_DER, chunk, BUILD_END);
+ free(chunk.ptr);
+ }
+ }
if (private)
{
user = cert->get_subject(cert);
@@ -359,7 +387,9 @@ static gboolean need_secrets(NMVPNPlugin *plugin, NMConnection *connection,
char **setting_name, GError **error)
{
NMSettingVPN *settings;
- char *method;
+ char *method, *path;
+ chunk_t secret = chunk_empty, key;
+ bool pgp = FALSE;
settings = NM_SETTING_VPN(nm_connection_get_setting(connection,
NM_TYPE_SETTING_VPN));
@@ -380,6 +410,23 @@ static gboolean need_secrets(NMVPNPlugin *plugin, NMConnection *connection,
return FALSE;
}
}
+ else if (streq(method, "key"))
+ {
+ path = g_hash_table_lookup(settings->data, "userkey");
+ if (path)
+ {
+ secret.ptr = g_hash_table_lookup(settings->data, "password");
+ if (secret.ptr)
+ {
+ secret.len = strlen(secret.ptr);
+ }
+ if (pem_asn1_load_file(path, &secret, &key, &pgp))
+ {
+ free(key.ptr);
+ return FALSE;
+ }
+ }
+ }
}
*setting_name = NM_SETTING_VPN_SETTING_NAME;
return TRUE;