nm: Make EAP-TLS configurable
authorTobias Brunner <tobias@strongswan.org>
Wed, 5 Feb 2020 15:01:08 +0000 (16:01 +0100)
committerTobias Brunner <tobias@strongswan.org>
Fri, 14 Feb 2020 12:50:32 +0000 (13:50 +0100)
A new combo field allows selecting where the certificate/key is stored.

src/frontends/gnome/auth-dialog/main.c
src/frontends/gnome/po/de.po
src/frontends/gnome/properties/nm-strongswan-dialog.ui
src/frontends/gnome/properties/nm-strongswan.c

index b4432aa..b63f746 100644 (file)
@@ -106,8 +106,8 @@ static void keyfile_print_stdout (GKeyFile *keyfile)
        g_free (data);
 }
 
-static gboolean get_secrets(const char *type, const char *uuid, const char *name, gboolean retry,
-                                                       gboolean allow_interaction, gboolean external_ui_mode,
+static gboolean get_secrets(const char *type, const char *cert_source, const char *uuid, const char *name,
+                                                       gboolean retry, gboolean allow_interaction, gboolean external_ui_mode,
                                                        const char *in_pw, char **out_pw, NMSettingSecretFlags flags)
 {
        NMAVpnPasswordDialog *dialog;
@@ -137,21 +137,24 @@ static gboolean get_secrets(const char *type, const char *uuid, const char *name
                prompt = g_strdup_printf (_("EAP password required to establish VPN connection '%s'."),
                                                                  name);
        }
-       else if (!strcmp(type, "key"))
-       {
-               prompt = g_strdup_printf (_("Private key decryption password required to establish VPN connection '%s'."),
-                                                                 name);
-       }
        else if (!strcmp(type, "psk"))
        {
                prompt = g_strdup_printf (_("Pre-shared key required to establish VPN connection '%s' (min. 20 characters)."),
                                                                  name);
                minlen = 20;
        }
-       else /* smartcard */
+       else /* certificate auth of some kind */
        {
-               prompt = g_strdup_printf (_("Smartcard PIN required to establish VPN connection '%s'."),
-                                                                 name);
+               if (!strcmp(cert_source, "smartcard"))
+               {
+                       prompt = g_strdup_printf (_("Smartcard PIN required to establish VPN connection '%s'."),
+                                                                         name);
+               }
+               else
+               {
+                       prompt = g_strdup_printf (_("Private key decryption password required to establish VPN connection '%s'."),
+                                                                         name);
+               }
        }
        if (external_ui_mode)
        {
@@ -246,11 +249,12 @@ static void wait_for_quit (void)
 int main (int argc, char *argv[])
 {
        gboolean retry = FALSE, allow_interaction = FALSE, external_ui_mode = FALSE;
+       gboolean need_secret = FALSE;
        gchar *name = NULL, *uuid = NULL, *service = NULL, *pass = NULL;
        GHashTable *data = NULL, *secrets = NULL;
        NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE;
        GOptionContext *context;
-       char *agent, *type;
+       char *agent, *type, *cert_source;
        int status = 0;
        GOptionEntry entries[] = {
                { "reprompt", 'r', 0, G_OPTION_ARG_NONE, &retry, "Reprompt for passwords", NULL},
@@ -300,57 +304,71 @@ int main (int argc, char *argv[])
                status = 1;
                goto out;
        }
+       cert_source = g_hash_table_lookup (data, "cert-source") ?: type;
 
-       if (!strcmp(type, "eap") || !strcmp(type, "key") ||
-               !strcmp(type, "psk") || !strcmp(type, "smartcard"))
+       if (!strcmp(type, "cert") ||
+               !strcmp(type, "eap-tls") ||
+               !strcmp(type, "key") ||
+               !strcmp(type, "agent") ||
+               !strcmp(type, "smartcard"))
        {
-               nm_vpn_service_plugin_get_secret_flags (secrets, "password", &flags);
-               if (!get_secrets(type, uuid, name, retry, allow_interaction, external_ui_mode,
-                                                g_hash_table_lookup (secrets, "password"), &pass, flags))
+               if (!strcmp(cert_source, "agent"))
                {
-                       status = 1;
+                       agent = getenv("SSH_AUTH_SOCK");
+                       if (agent)
+                       {
+                               if (external_ui_mode)
+                               {
+                                       GKeyFile *keyfile;
+
+                                       keyfile = g_key_file_new ();
+
+                                       g_key_file_set_integer (keyfile, UI_KEYFILE_GROUP, "Version", 2);
+                                       g_key_file_set_string (keyfile, UI_KEYFILE_GROUP, "Description", "SSH agent");
+                                       g_key_file_set_string (keyfile, UI_KEYFILE_GROUP, "Title", _("Authenticate VPN"));
+
+                                       keyfile_add_entry_info (keyfile, "agent", agent, "SSH agent socket", TRUE, FALSE);
+
+                                       keyfile_print_stdout (keyfile);
+                                       g_key_file_unref (keyfile);
+                               }
+                               else
+                               {
+                                       print_secret("agent", g_strdup (agent));
+                                       wait_for_quit ();
+                               }
+                       }
+                       else if (allow_interaction)
+                       {
+                               GtkWidget *dialog;
+                               dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_ERROR,
+                                                         GTK_BUTTONS_OK,
+                                                         _("Configuration uses ssh-agent for authentication, "
+                                                         "but ssh-agent is not running!"));
+                               gtk_dialog_run (GTK_DIALOG (dialog));
+                               gtk_widget_destroy (dialog);
+                       }
                }
-               else if (!external_ui_mode)
+               else
                {
-                       print_secret("password", pass);
-                       wait_for_quit ();
+                       need_secret = TRUE;
                }
        }
-       else if (!strcmp(type, "agent"))
+
+       if (need_secret ||
+               !strcmp(type, "eap") ||
+               !strcmp(type, "psk"))
        {
-               agent = getenv("SSH_AUTH_SOCK");
-               if (agent)
+               nm_vpn_service_plugin_get_secret_flags (secrets, "password", &flags);
+               if (!get_secrets(type, cert_source, uuid, name, retry, allow_interaction,
+                                                external_ui_mode, g_hash_table_lookup (secrets, "password"), &pass, flags))
                {
-                       if (external_ui_mode)
-                       {
-                               GKeyFile *keyfile;
-
-                               keyfile = g_key_file_new ();
-
-                               g_key_file_set_integer (keyfile, UI_KEYFILE_GROUP, "Version", 2);
-                               g_key_file_set_string (keyfile, UI_KEYFILE_GROUP, "Description", "SSH agent");
-                               g_key_file_set_string (keyfile, UI_KEYFILE_GROUP, "Title", _("Authenticate VPN"));
-
-                               keyfile_add_entry_info (keyfile, "agent", agent, "SSH agent socket", TRUE, FALSE);
-
-                               keyfile_print_stdout (keyfile);
-                               g_key_file_unref (keyfile);
-                       }
-                       else
-                       {
-                               print_secret("agent", g_strdup (agent));
-                               wait_for_quit ();
-                       }
+                       status = 1;
                }
-               else if (allow_interaction)
+               else if (!external_ui_mode)
                {
-                       GtkWidget *dialog;
-                       dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_ERROR,
-                                                 GTK_BUTTONS_OK,
-                                                 _("Configuration uses ssh-agent for authentication, "
-                                                 "but ssh-agent is not running!"));
-                       gtk_dialog_run (GTK_DIALOG (dialog));
-                       gtk_widget_destroy (dialog);
+                       print_secret("password", pass);
+                       wait_for_quit ();
                }
        }
 
index f190488..84a4cd9 100644 (file)
@@ -1,5 +1,5 @@
 # Translations for NetworkManager-strongswan.
-# Copyright (C) 2010-2019 Tobias Brunner
+# Copyright (C) 2010-2020 Tobias Brunner
 # Copyright (C) 2010 Martin Willi
 # This file is distributed under the same license as the
 # NetworkManager-strongswan package.
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: NetworkManager-strongswan\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-12-19 17:08+0100\n"
+"POT-Creation-Date: 2020-02-07 16:59+0100\n"
 "PO-Revision-Date: 2019-12-18 17:10+0100\n"
 "Last-Translator: Tobias Brunner\n"
 "Language-Team: de <info@strongswan.org>\n"
@@ -25,26 +25,34 @@ msgstr "IPsec/IKEv2 (strongswan)"
 msgid "IPsec with the IKEv2 key exchange protocol."
 msgstr "IPsec mit dem IKEv2 Protokoll."
 
-#: ../properties/nm-strongswan.c:330
+#: ../properties/nm-strongswan.c:335
+msgid "EAP (Username/Password)"
+msgstr "EAP (Benutzername/Passwort)"
+
+#: ../properties/nm-strongswan.c:336
+msgid "Certificate"
+msgstr "Zertifikat"
+
+#: ../properties/nm-strongswan.c:337
+msgid "EAP-TLS"
+msgstr "EAP-TLS"
+
+#: ../properties/nm-strongswan.c:338
+msgid "Pre-shared key"
+msgstr "Pre-shared Key"
+
+#: ../properties/nm-strongswan.c:365
 msgid "Certificate/private key"
 msgstr "Zertifikat/Privater Schlüssel"
 
-#: ../properties/nm-strongswan.c:331
+#: ../properties/nm-strongswan.c:366
 msgid "Certificate/ssh-agent"
 msgstr "Zertifikat/ssh-agent"
 
-#: ../properties/nm-strongswan.c:332
+#: ../properties/nm-strongswan.c:367
 msgid "Smartcard"
 msgstr "Smartcard"
 
-#: ../properties/nm-strongswan.c:333
-msgid "EAP"
-msgstr "EAP"
-
-#: ../properties/nm-strongswan.c:334
-msgid "Pre-shared key"
-msgstr "Pre-shared Key"
-
 #: ../properties/nm-strongswan-dialog.ui.h:1
 msgid "<b>Server</b>"
 msgstr "<b>Server</b>"
@@ -116,14 +124,18 @@ msgid "Ce_rtificate:"
 msgstr "Ze_rtifikat:"
 
 #: ../properties/nm-strongswan-dialog.ui.h:15
+msgid "Certificate _file:"
+msgstr "Z_ertifikatsdatei:"
+
+#: ../properties/nm-strongswan-dialog.ui.h:16
 msgid "Client certificate to use for client authentication."
 msgstr "Zertifikat des Clients für dessen Authentisierung."
 
-#: ../properties/nm-strongswan-dialog.ui.h:16
+#: ../properties/nm-strongswan-dialog.ui.h:17
 msgid "Private _key:"
 msgstr "Privater _Schlüssel:"
 
-#: ../properties/nm-strongswan-dialog.ui.h:17
+#: ../properties/nm-strongswan-dialog.ui.h:18
 msgid ""
 "Private key to use for client authentication. This key has to match the "
 "certificates public key and may be encrypted."
@@ -131,19 +143,19 @@ msgstr ""
 "Privater Schlüssel für die Authentisierung des Clients. Dieser Schlüssel "
 "muss zum konfigurierten Zertifikat passen und kann verschlüsselt sein."
 
-#: ../properties/nm-strongswan-dialog.ui.h:18
+#: ../properties/nm-strongswan-dialog.ui.h:19
 msgid "_Username:"
 msgstr "_Benutzername:"
 
-#: ../properties/nm-strongswan-dialog.ui.h:19
+#: ../properties/nm-strongswan-dialog.ui.h:20
 msgid "The username (identity) to use for authentication against the server."
 msgstr "Benutzername/Identität für die Authentisierung gegenüber dem Server."
 
-#: ../properties/nm-strongswan-dialog.ui.h:20
+#: ../properties/nm-strongswan-dialog.ui.h:21
 msgid "_Password:"
 msgstr "_Passwort:"
 
-#: ../properties/nm-strongswan-dialog.ui.h:21
+#: ../properties/nm-strongswan-dialog.ui.h:22
 msgid ""
 "The password to use for authentication against the server (min. 20 "
 "characters for PSKs)."
@@ -151,23 +163,23 @@ msgstr ""
 "Das Passwort für die Authentisierung gegenüber dem Server (min. 20 Zeichen "
 "für PSKs)."
 
-#: ../properties/nm-strongswan-dialog.ui.h:22
+#: ../properties/nm-strongswan-dialog.ui.h:23
 msgid "(Use icon to change password storage policy)"
 msgstr "(Icon verwenden, um Passwort-Richtlinie zu ändern)"
 
-#: ../properties/nm-strongswan-dialog.ui.h:23
+#: ../properties/nm-strongswan-dialog.ui.h:24
 msgid "_Show password"
 msgstr "Passwort _anzeigen"
 
-#: ../properties/nm-strongswan-dialog.ui.h:24
+#: ../properties/nm-strongswan-dialog.ui.h:25
 msgid "<b>Options</b>"
 msgstr "<b>Optionen</b>"
 
-#: ../properties/nm-strongswan-dialog.ui.h:25
+#: ../properties/nm-strongswan-dialog.ui.h:26
 msgid "Request an _inner IP address"
 msgstr "_Innere IP-Adresse beziehen"
 
-#: ../properties/nm-strongswan-dialog.ui.h:26
+#: ../properties/nm-strongswan-dialog.ui.h:27
 msgid ""
 "The server may provide addresses from a pool to use for communication in the "
 "VPN. Check to request such an address."
@@ -176,11 +188,11 @@ msgstr ""
 "Kommunikation im dahinterliegenden Netz verwenden kann. Aktivieren, um eine "
 "solche Adresse zu beziehen."
 
-#: ../properties/nm-strongswan-dialog.ui.h:27
+#: ../properties/nm-strongswan-dialog.ui.h:28
 msgid "En_force UDP encapsulation"
 msgstr "Erzwingen einer zusätzlichen Einbettung der Datenpakete in _UDP"
 
-#: ../properties/nm-strongswan-dialog.ui.h:28
+#: ../properties/nm-strongswan-dialog.ui.h:29
 msgid ""
 "Some firewalls block ESP traffic. Enforcing UDP capsulation even if no NAT "
 "situation is detected might help in such cases."
@@ -189,11 +201,11 @@ msgstr ""
 "erzwingen einer zustzlichen Einbettung in UDP, auch wenn kein NAT-Router "
 "detektiert wurde, kann in solchen Situationen hilfreich sein."
 
-#: ../properties/nm-strongswan-dialog.ui.h:29
+#: ../properties/nm-strongswan-dialog.ui.h:30
 msgid "Use IP c_ompression"
 msgstr "IP-Pakete k_omprimieren"
 
-#: ../properties/nm-strongswan-dialog.ui.h:30
+#: ../properties/nm-strongswan-dialog.ui.h:31
 msgid ""
 "IPComp compresses raw IP packets before they get encrypted. This saves some "
 "bandwidth, but uses more processing power."
@@ -201,27 +213,27 @@ msgstr ""
 "IPComp komprimiert IP-Pakete, bevor sie verschlüsselt werden. Diese Option "
 "kann Bandbreite sparen, benötigt jedoch zusätzliche Rechenleistung."
 
-#: ../properties/nm-strongswan-dialog.ui.h:31
+#: ../properties/nm-strongswan-dialog.ui.h:32
 msgid "<b>Cipher proposals</b>"
 msgstr "<b>Algorithmen</b>"
 
-#: ../properties/nm-strongswan-dialog.ui.h:32
+#: ../properties/nm-strongswan-dialog.ui.h:33
 msgid "_Enable custom proposals"
 msgstr "_Eigene Algorithmen verwenden"
 
-#: ../properties/nm-strongswan-dialog.ui.h:33
+#: ../properties/nm-strongswan-dialog.ui.h:34
 msgid "_IKE:"
 msgstr "_IKE:"
 
-#: ../properties/nm-strongswan-dialog.ui.h:34
+#: ../properties/nm-strongswan-dialog.ui.h:35
 msgid "A list of proposals for IKE separated by \";\""
 msgstr "Eine Liste von Proposals für IKE getrennt mit \";\""
 
-#: ../properties/nm-strongswan-dialog.ui.h:35
+#: ../properties/nm-strongswan-dialog.ui.h:36
 msgid "_ESP:"
 msgstr "_ESP:"
 
-#: ../properties/nm-strongswan-dialog.ui.h:36
+#: ../properties/nm-strongswan-dialog.ui.h:37
 msgid "A list of proposals for ESP separated by \";\""
 msgstr "Eine Liste von Proposals für ESP getrennt mit \";\""
 
@@ -234,37 +246,37 @@ msgstr ""
 #: ../auth-dialog/main.c:142
 #, c-format
 msgid ""
-"Private key decryption password required to establish VPN connection '%s'."
-msgstr ""
-"Der Private Schlüssel für die Erstellung des VPN-Tunnels '%s' ist durch ein "
-"Passwort geschützt."
-
-#: ../auth-dialog/main.c:147
-#, c-format
-msgid ""
 "Pre-shared key required to establish VPN connection '%s' (min. 20 "
 "characters)."
 msgstr ""
 "Für die Erstellung des VPN-Tunnels '%s' ist ein Pre-shared Key erforderlich "
 "(min. 20 Zeichen)."
 
-#: ../auth-dialog/main.c:153
+#: ../auth-dialog/main.c:150
 #, c-format
 msgid "Smartcard PIN required to establish VPN connection '%s'."
 msgstr ""
 "Die Smartcard für die Erstellung des VPN-Tunnels '%s' ist durch eine PIN "
 "geschützt."
 
-#: ../auth-dialog/main.c:164 ../auth-dialog/main.c:182
-#: ../auth-dialog/main.c:332
+#: ../auth-dialog/main.c:155
+#, c-format
+msgid ""
+"Private key decryption password required to establish VPN connection '%s'."
+msgstr ""
+"Der Private Schlüssel für die Erstellung des VPN-Tunnels '%s' ist durch ein "
+"Passwort geschützt."
+
+#: ../auth-dialog/main.c:167 ../auth-dialog/main.c:185
+#: ../auth-dialog/main.c:328
 msgid "Authenticate VPN"
 msgstr "VPN Authentisierung"
 
-#: ../auth-dialog/main.c:166
+#: ../auth-dialog/main.c:169
 msgid "Password:"
 msgstr "Passwort:"
 
-#: ../auth-dialog/main.c:350
+#: ../auth-dialog/main.c:346
 msgid ""
 "Configuration uses ssh-agent for authentication, but ssh-agent is not "
 "running!"
index 48dee96..004177b 100644 (file)
               </packing>
             </child>
             <child>
-              <object class="GtkLabel" id="usercert-label">
+              <object class="GtkLabel" id="cert-label">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
                 <property name="label" translatable="yes">Ce_rtificate:</property>
               </packing>
             </child>
             <child>
+              <object class="GtkComboBoxText" id="cert-combo">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="hexpand">True</property>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="usercert-label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Certificate _file:</property>
+                <property name="use_underline">True</property>
+                <property name="xalign">0</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">2</property>
+              </packing>
+            </child>
+            <child>
               <object class="GtkFileChooserButton" id="usercert-button">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
               </object>
               <packing>
                 <property name="left_attach">1</property>
-                <property name="top_attach">1</property>
+                <property name="top_attach">2</property>
               </packing>
             </child>
             <child>
               </object>
               <packing>
                 <property name="left_attach">0</property>
-                <property name="top_attach">2</property>
+                <property name="top_attach">3</property>
               </packing>
             </child>
             <child>
               </object>
               <packing>
                 <property name="left_attach">1</property>
-                <property name="top_attach">2</property>
+                <property name="top_attach">3</property>
               </packing>
             </child>
             <child>
               </object>
               <packing>
                 <property name="left_attach">0</property>
-                <property name="top_attach">3</property>
+                <property name="top_attach">4</property>
               </packing>
             </child>
             <child>
               </object>
               <packing>
                 <property name="left_attach">1</property>
-                <property name="top_attach">3</property>
+                <property name="top_attach">4</property>
               </packing>
             </child>
             <child>
               </object>
               <packing>
                 <property name="left_attach">0</property>
-                <property name="top_attach">4</property>
+                <property name="top_attach">5</property>
               </packing>
             </child>
             <child>
               </object>
               <packing>
                 <property name="left_attach">1</property>
-                <property name="top_attach">4</property>
+                <property name="top_attach">5</property>
               </packing>
             </child>
             <child>
               </object>
               <packing>
                 <property name="left_attach">1</property>
-                <property name="top_attach">5</property>
+                <property name="top_attach">6</property>
               </packing>
             </child>
             <child>
index 7f12a26..d84f63c 100644 (file)
@@ -1,8 +1,8 @@
 /*
- * Copyright (C) 2015 Lubomir Rintel
- * Copyright (C) 2013 Tobias Brunner
+ * Copyright (C) 2013-2020 Tobias Brunner
  * Copyright (C) 2008 Martin Willi
  * HSR Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2015 Lubomir Rintel
  * Copyright (C) 2005 David Zeuthen
  * Copyright (C) 2005-2008 Dan Williams
  *
@@ -130,7 +130,7 @@ check_validity (StrongswanPluginUiWidget *self, GError **error)
        widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "method-combo"));
        switch (gtk_combo_box_get_active (GTK_COMBO_BOX (widget)))
        {
-               case 4:
+               case 3:
                {
                        widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-entry"));
                        str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
@@ -146,57 +146,61 @@ check_validity (StrongswanPluginUiWidget *self, GError **error)
        return TRUE;
 }
 
-static void update_sensitive (GtkWidget *widget, StrongswanPluginUiWidgetPrivate *priv)
+static void update_user_pass_fields (StrongswanPluginUiWidgetPrivate *priv, gboolean enabled)
+{
+       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-label")), enabled);
+       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-entry")), enabled);
+       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-show")), enabled);
+       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-label")), enabled);
+       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-entry")), enabled);
+}
+
+static void update_cert_fields (StrongswanPluginUiWidgetPrivate *priv, gboolean enabled)
 {
+       GtkWidget *widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "cert-combo"));
+       gboolean cert = FALSE, key = FALSE;
+
        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_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-label")), TRUE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-button")), TRUE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-label")), TRUE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-button")), TRUE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-label")), FALSE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-entry")), FALSE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-show")), FALSE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-label")), FALSE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-entry")), FALSE);
+                       cert = key = TRUE;
                        break;
                case 1:
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-label")), TRUE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-button")), TRUE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-label")), FALSE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-entry")), FALSE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-show")), FALSE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-label")), FALSE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-entry")), FALSE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-label")), FALSE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-button")), FALSE);
+                       cert = TRUE;
                        break;
                case 2:
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-label")), FALSE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-button")), FALSE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-label")), FALSE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-entry")), FALSE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-show")), FALSE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-label")), FALSE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-entry")), FALSE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-label")), FALSE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-button")), FALSE);
                        break;
+       }
+
+       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "cert-label")), enabled);
+       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "cert-combo")), enabled);
+       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-label")), enabled && cert);
+       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-button")), enabled && cert);
+       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-label")), enabled && key);
+       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-button")), enabled && key);
+}
+
+static void update_sensitive (StrongswanPluginUiWidgetPrivate *priv)
+{
+       GtkWidget *widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "method-combo"));
+
+       switch (gtk_combo_box_get_active (GTK_COMBO_BOX (widget)))
+       {
+               default:
+                       gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
+                       /* FALL */
+               case 0:
                case 3:
-               case 4:
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-label")), TRUE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-entry")), TRUE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-show")), TRUE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-label")), TRUE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-entry")), TRUE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-label")), FALSE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-button")), FALSE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-label")), FALSE);
-                       gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-button")), FALSE);
+                       update_user_pass_fields (priv, TRUE);
+                       update_cert_fields (priv, FALSE);
+                       break;
+               case 1:
+               case 2:
+                       update_user_pass_fields (priv, FALSE);
+                       update_cert_fields (priv, TRUE);
                        break;
        }
 
@@ -208,9 +212,10 @@ 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 (widget == GTK_WIDGET (gtk_builder_get_object (priv->builder, "method-combo")))
+       if (widget == GTK_WIDGET (gtk_builder_get_object (priv->builder, "method-combo")) ||
+               widget == GTK_WIDGET (gtk_builder_get_object (priv->builder, "cert-combo")))
        {
-               update_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "method-combo")), priv);
+               update_sensitive (priv);
        }
        g_signal_emit_by_name (STRONGSWAN_PLUGIN_UI_WIDGET (user_data), "changed");
 }
@@ -284,7 +289,7 @@ init_plugin_ui (StrongswanPluginUiWidget *self, NMConnection *connection, GError
        StrongswanPluginUiWidgetPrivate *priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
        NMSettingVpn *settings;
        GtkWidget *widget;
-       const char *value;
+       const char *value, *method;
 
        settings = NM_SETTING_VPN(nm_connection_get_setting(connection, NM_TYPE_SETTING_VPN));
        widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "address-entry"));
@@ -327,14 +332,47 @@ init_plugin_ui (StrongswanPluginUiWidget *self, NMConnection *connection, GError
        init_password_icon (self, settings, "password", "passwd-entry");
 
        widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "method-combo"));
+       gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("EAP (Username/Password)"));
+       gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("Certificate"));
+       gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("EAP-TLS"));
+       gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("Pre-shared key"));
+       method = value = nm_setting_vpn_get_data_item (settings, "method");
+       if (value) {
+               if (g_strcmp0 (value, "eap") == 0) {
+                       gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
+               }
+               if (g_strcmp0 (value, "cert") == 0 ||
+                       g_strcmp0 (value, "key") == 0 ||
+                       g_strcmp0 (value, "agent") == 0 ||
+                       g_strcmp0 (value, "smartcard") == 0)
+               {
+                       gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 1);
+               }
+               if (g_strcmp0 (value, "eap-tls") == 0) {
+                       gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 2);
+               }
+               if (g_strcmp0 (value, "psk") == 0) {
+                       gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 3);
+               }
+       }
+       if (gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) == -1)
+       {
+               gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
+       }
+       g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (settings_changed_cb), self);
+
+       widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "cert-combo"));
        gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("Certificate/private key"));
        gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("Certificate/ssh-agent"));
        gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("Smartcard"));
-       gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("EAP"));
-       gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("Pre-shared key"));
-       value = nm_setting_vpn_get_data_item (settings, "method");
+       value = nm_setting_vpn_get_data_item (settings, "cert-source");
+       if (!value) {
+               value = method;
+       }
        if (value) {
-               if (g_strcmp0 (value, "key") == 0) {
+               if (g_strcmp0 (value, "file") == 0 ||
+                       g_strcmp0 (value, "key") == 0)
+               {
                        gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
                }
                if (g_strcmp0 (value, "agent") == 0) {
@@ -343,19 +381,13 @@ init_plugin_ui (StrongswanPluginUiWidget *self, NMConnection *connection, GError
                if (g_strcmp0 (value, "smartcard") == 0) {
                        gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 2);
                }
-               if (g_strcmp0 (value, "eap") == 0) {
-                       gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 3);
-               }
-               if (g_strcmp0 (value, "psk") == 0) {
-                       gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 4);
-               }
        }
        if (gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) == -1)
        {
                gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
        }
-       update_sensitive (widget, priv);
        g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (settings_changed_cb), self);
+       update_sensitive (priv);
 
        widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-button"));
        value = nm_setting_vpn_get_data_item (settings, "usercert");
@@ -464,6 +496,70 @@ save_password_and_flags (NMSettingVpn *settings, GtkBuilder *builder,
        nm_setting_set_secret_flags (NM_SETTING (settings), secret_key, flags, NULL);
 }
 
+
+static void
+save_file_chooser (NMSettingVpn *settings, GtkBuilder *builder,
+                                  const char *name, const char *key)
+{
+       GtkWidget *chooser;
+       char *str;
+
+       chooser = GTK_WIDGET (gtk_builder_get_object (builder, name));
+       str = (char *) gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
+       if (str) {
+               nm_setting_vpn_add_data_item (settings, key, str);
+       }
+}
+
+static void
+save_entry (NMSettingVpn *settings, GtkBuilder *builder,
+                       const char *name, const char *key)
+{
+       GtkWidget *entry;
+       const char *str;
+
+       entry = GTK_WIDGET (gtk_builder_get_object (builder, name));
+       str = (char *) gtk_entry_get_text (GTK_ENTRY (entry));
+       if (str && strlen (str)) {
+               nm_setting_vpn_add_data_item (settings, key, str);
+       }
+}
+
+static void
+save_cert (NMSettingVpn *settings, GtkBuilder *builder)
+{
+       GtkWidget *widget;
+       gboolean cert = FALSE, key = FALSE;
+       char *str;
+
+       widget = GTK_WIDGET (gtk_builder_get_object (builder, "cert-combo"));
+       switch (gtk_combo_box_get_active (GTK_COMBO_BOX (widget)))
+       {
+               default:
+               case 0:
+                       cert = key = TRUE;
+                       str = "file";
+                       break;
+               case 1:
+                       cert = TRUE;
+                       str = "agent";
+                       break;
+               case 2:
+                       nm_setting_set_secret_flags (NM_SETTING (settings), "password",
+                                                                                NM_SETTING_SECRET_FLAG_NOT_SAVED, NULL);
+                       str = "smartcard";
+                       break;
+       }
+       nm_setting_vpn_add_data_item (settings, "cert-source", str);
+
+       if (cert) {
+               save_file_chooser (settings, builder, "usercert-button", "usercert");
+       }
+       if (key) {
+               save_file_chooser (settings, builder, "userkey-button", "userkey");
+       }
+}
+
 static gboolean
 update_connection (NMVpnEditor *iface,
                                   NMConnection *connection,
@@ -483,75 +579,30 @@ update_connection (NMVpnEditor *iface,
        g_object_set (settings, NM_SETTING_VPN_SERVICE_TYPE,
                                  NM_DBUS_SERVICE_STRONGSWAN, NULL);
 
-       widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "address-entry"));
-       str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
-       if (str && strlen (str)) {
-               nm_setting_vpn_add_data_item (settings, "address", str);
-       }
-
-       widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "certificate-button"));
-       str = (char *) gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
-       if (str) {
-               nm_setting_vpn_add_data_item (settings, "certificate", str);
-       }
-
-       widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "remote-identity-entry"));
-       str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
-       if (str && strlen (str)) {
-               nm_setting_vpn_add_data_item (settings, "remote-identity", str);
-       }
-
-       widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "server-port-entry"));
-       str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
-       if (str && strlen (str)) {
-               nm_setting_vpn_add_data_item (settings, "server-port", str);
-       }
+       save_entry (settings, priv->builder, "address-entry", "address");
+       save_file_chooser (settings, priv->builder, "certificate-button", "certificate");
+       save_entry (settings, priv->builder, "remote-identity-entry", "remote-identity");
+       save_entry (settings, priv->builder, "server-port-entry", "server-port");
 
        widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "method-combo"));
        switch (gtk_combo_box_get_active (GTK_COMBO_BOX (widget)))
        {
                default:
                case 0:
-                       widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-button"));
-                       str = (char *) gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
-                       if (str) {
-                               nm_setting_vpn_add_data_item (settings, "userkey", str);
-                       }
-                       widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-button"));
-                       str = (char *) gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
-                       if (str) {
-                               nm_setting_vpn_add_data_item (settings, "usercert", str);
-                       }
-                       str = "key";
+                       save_entry (settings, priv->builder, "user-entry", "user");
+                       save_password_and_flags (settings, priv->builder, "passwd-entry", "password");
+                       str = "eap";
                        break;
                case 1:
-                       widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-button"));
-                       str = (char *) gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
-                       if (str) {
-                               nm_setting_vpn_add_data_item (settings, "usercert", str);
-                       }
-                       str = "agent";
+                       save_cert (settings, priv->builder);
+                       str = "cert";
                        break;
                case 2:
-                       nm_setting_set_secret_flags (NM_SETTING (settings), "password",
-                                                                                NM_SETTING_SECRET_FLAG_NOT_SAVED, NULL);
-                       str = "smartcard";
+                       save_cert (settings, priv->builder);
+                       str = "eap-tls";
                        break;
                case 3:
-                       widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-entry"));
-                       str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
-                       if (str && strlen (str)) {
-                               nm_setting_vpn_add_data_item (settings, "user", str);
-                       }
-                       save_password_and_flags (settings, priv->builder, "passwd-entry", "password");
-                       str = "eap";
-                       break;
-               case 4:
-                       widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-entry"));
-                       str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
-                       if (str && strlen (str)) {
-                               nm_setting_vpn_add_data_item (settings, "user", str);
-                       }
+                       save_entry (settings, priv->builder, "user-entry", "user");
                        save_password_and_flags (settings, priv->builder, "passwd-entry", "password");
                        str = "psk";
                        break;