[network-manager-applet/lr/pkcs11: 17/21] wireless-security: make eap-tls use the NMACertificateChooser



commit 6e0d79dbcd53dc35afc58295dcdb63ac8d612224
Author: Lubomir Rintel <lkundrak v3 sk>
Date:   Wed Feb 22 18:50:40 2017 +0100

    wireless-security: make eap-tls use the NMACertificateChooser
    
    This makes it support PKCS#11 tokens for certificates and keys. Also, it
    supports PIN entry for the relevant objects.

 src/wireless-security/eap-method-fast.c   |    7 +-
 src/wireless-security/eap-method-leap.c   |   11 +-
 src/wireless-security/eap-method-peap.c   |    7 +-
 src/wireless-security/eap-method-simple.c |    9 +-
 src/wireless-security/eap-method-tls.c    |  699 +++++++++++++++--------------
 src/wireless-security/eap-method-tls.ui   |  117 +-----
 src/wireless-security/eap-method-ttls.c   |    7 +-
 src/wireless-security/eap-method.c        |    5 +-
 src/wireless-security/eap-method.h        |    6 +-
 src/wireless-security/wireless-security.c |   10 +-
 10 files changed, 403 insertions(+), 475 deletions(-)
---
diff --git a/src/wireless-security/eap-method-fast.c b/src/wireless-security/eap-method-fast.c
index ec1cd64..c1fc628 100644
--- a/src/wireless-security/eap-method-fast.c
+++ b/src/wireless-security/eap-method-fast.c
@@ -36,6 +36,7 @@
 struct _EAPMethodFAST {
        EAPMethod parent;
 
+       const char *password_flags_name;
        GtkSizeGroup *size_group;
        WirelessSecurity *sec_parent;
        gboolean is_editor;
@@ -126,7 +127,7 @@ add_to_size_group (EAPMethod *parent, GtkSizeGroup *group)
 }
 
 static void
-fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFlags flags)
+fill_connection (EAPMethod *parent, NMConnection *connection)
 {
        NMSetting8021x *s_8021x;
        GtkWidget *widget;
@@ -185,7 +186,7 @@ fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFla
        gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1);
        g_assert (eap);
 
-       eap_method_fill_connection (eap, connection, flags);
+       eap_method_fill_connection (eap, connection);
        eap_method_unref (eap);
 }
 
@@ -356,8 +357,8 @@ eap_method_fast_new (WirelessSecurity *ws_parent,
        if (!parent)
                return NULL;
 
-       parent->password_flags_name = NM_SETTING_802_1X_PASSWORD;
        method = (EAPMethodFAST *) parent;
+       method->password_flags_name = NM_SETTING_802_1X_PASSWORD;
        method->sec_parent = ws_parent;
        method->is_editor = is_editor;
 
diff --git a/src/wireless-security/eap-method-leap.c b/src/wireless-security/eap-method-leap.c
index 0087bdf..3cf6a26 100644
--- a/src/wireless-security/eap-method-leap.c
+++ b/src/wireless-security/eap-method-leap.c
@@ -38,6 +38,7 @@ struct _EAPMethodLEAP {
 
        gboolean editing_connection;
 
+       const char *password_flags_name;
        GtkEntry *username_entry;
        GtkEntry *password_entry;
        GtkToggleButton *show_password;
@@ -95,7 +96,7 @@ add_to_size_group (EAPMethod *parent, GtkSizeGroup *group)
 }
 
 static void
-fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFlags flags)
+fill_connection (EAPMethod *parent, NMConnection *connection)
 {
        EAPMethodLEAP *method = (EAPMethodLEAP *) parent;
        NMSetting8021x *s_8021x;
@@ -115,13 +116,13 @@ fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFla
 
        /* Save 802.1X password flags to the connection */
        secret_flags = nma_utils_menu_to_secret_flags (passwd_entry);
-       nm_setting_set_secret_flags (NM_SETTING (s_8021x), parent->password_flags_name,
+       nm_setting_set_secret_flags (NM_SETTING (s_8021x), method->password_flags_name,
                                     secret_flags, NULL);
 
        /* Update secret flags and popup when editing the connection */
        if (method->editing_connection)
                nma_utils_update_password_storage (passwd_entry, secret_flags,
-                                                  NM_SETTING (s_8021x), parent->password_flags_name);
+                                                  NM_SETTING (s_8021x), method->password_flags_name);
 }
 
 static void
@@ -206,8 +207,8 @@ eap_method_leap_new (WirelessSecurity *ws_parent,
        if (!parent)
                return NULL;
 
-       parent->password_flags_name = NM_SETTING_802_1X_PASSWORD;
        method = (EAPMethodLEAP *) parent;
+       method->password_flags_name = NM_SETTING_802_1X_PASSWORD;
        method->editing_connection = secrets_only ? FALSE : TRUE;
        method->ws_parent = ws_parent;
 
@@ -240,7 +241,7 @@ eap_method_leap_new (WirelessSecurity *ws_parent,
        /* Create password-storage popup menu for password entry under entry's secondary icon */
        if (connection)
                s_8021x = nm_connection_get_setting_802_1x (connection);
-       nma_utils_setup_password_storage (widget, 0, (NMSetting *) s_8021x, parent->password_flags_name,
+       nma_utils_setup_password_storage (widget, 0, (NMSetting *) s_8021x, method->password_flags_name,
                                          FALSE, secrets_only);
 
        widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "show_checkbutton_eapleap"));
diff --git a/src/wireless-security/eap-method-peap.c b/src/wireless-security/eap-method-peap.c
index 402887c..8a3baa3 100644
--- a/src/wireless-security/eap-method-peap.c
+++ b/src/wireless-security/eap-method-peap.c
@@ -35,6 +35,7 @@
 struct _EAPMethodPEAP {
        EAPMethod parent;
 
+       const char *password_flags_name;
        GtkSizeGroup *size_group;
        WirelessSecurity *sec_parent;
        gboolean is_editor;
@@ -134,7 +135,7 @@ add_to_size_group (EAPMethod *parent, GtkSizeGroup *group)
 }
 
 static void
-fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFlags flags)
+fill_connection (EAPMethod *parent, NMConnection *connection)
 {
        NMSetting8021x *s_8021x;
        NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
@@ -190,7 +191,7 @@ fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFla
        gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1);
        g_assert (eap);
 
-       eap_method_fill_connection (eap, connection, flags);
+       eap_method_fill_connection (eap, connection);
        eap_method_unref (eap);
 }
 static void
@@ -356,8 +357,8 @@ eap_method_peap_new (WirelessSecurity *ws_parent,
        if (!parent)
                return NULL;
 
-       parent->password_flags_name = NM_SETTING_802_1X_PASSWORD;
        method = (EAPMethodPEAP *) parent;
+       method->password_flags_name = NM_SETTING_802_1X_PASSWORD;
        method->sec_parent = ws_parent;
        method->is_editor = is_editor;
 
diff --git a/src/wireless-security/eap-method-simple.c b/src/wireless-security/eap-method-simple.c
index 80de964..66dc421 100644
--- a/src/wireless-security/eap-method-simple.c
+++ b/src/wireless-security/eap-method-simple.c
@@ -36,6 +36,7 @@ struct _EAPMethodSimple {
 
        WirelessSecurity *ws_parent;
 
+       const char *password_flags_name;
        EAPMethodSimpleType type;
        EAPMethodSimpleFlags flags;
 
@@ -126,7 +127,7 @@ static const EapType eap_table[EAP_METHOD_SIMPLE_TYPE_LAST] = {
 };
 
 static void
-fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFlags prev_flags)
+fill_connection (EAPMethod *parent, NMConnection *connection)
 {
        EAPMethodSimple *method = (EAPMethodSimple *) parent;
        NMSetting8021x *s_8021x;
@@ -181,7 +182,7 @@ fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFla
                g_assert (passwd_entry);
 
                nma_utils_update_password_storage (passwd_entry, flags,
-                                                  NM_SETTING (s_8021x), parent->password_flags_name);
+                                                  NM_SETTING (s_8021x), method->password_flags_name);
        }
 }
 
@@ -303,8 +304,8 @@ eap_method_simple_new (WirelessSecurity *ws_parent,
        if (!parent)
                return NULL;
 
-       parent->password_flags_name = NM_SETTING_802_1X_PASSWORD;
        method = (EAPMethodSimple *) parent;
+       method->password_flags_name = NM_SETTING_802_1X_PASSWORD;
        method->ws_parent = ws_parent;
        method->flags = flags;
        method->type = type;
@@ -339,7 +340,7 @@ eap_method_simple_new (WirelessSecurity *ws_parent,
        /* Create password-storage popup menu for password entry under entry's secondary icon */
        if (connection)
                s_8021x = nm_connection_get_setting_802_1x (connection);
-       nma_utils_setup_password_storage (widget, 0, (NMSetting *) s_8021x, parent->password_flags_name,
+       nma_utils_setup_password_storage (widget, 0, (NMSetting *) s_8021x, method->password_flags_name,
                                          FALSE, flags & EAP_METHOD_SIMPLE_FLAG_SECRETS_ONLY);
 
        g_signal_connect (method->password_entry, "notify::secondary-icon-name",
diff --git a/src/wireless-security/eap-method-tls.c b/src/wireless-security/eap-method-tls.c
index 8d17fa4..3c889f0 100644
--- a/src/wireless-security/eap-method-tls.c
+++ b/src/wireless-security/eap-method-tls.c
@@ -2,6 +2,7 @@
 /* NetworkManager Applet -- allow user control over networking
  *
  * Dan Williams <dcbw redhat com>
+ * Lubomir Rintel <lkundrak v3 sk>
  *
  * 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
@@ -17,7 +18,7 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * Copyright 2007 - 2014 Red Hat, Inc.
+ * Copyright 2007 - 2017 Red Hat, Inc.
  */
 
 #include "nm-default.h"
@@ -29,36 +30,31 @@
 #include "wireless-security.h"
 #include "helpers.h"
 #include "nma-ui-utils.h"
+#include "nma-cert-chooser.h"
 #include "utils.h"
 
 struct _EAPMethodTLS {
        EAPMethod parent;
 
+#ifdef NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD
+/* libnm-glib doesn't support these. */
+       const char *ca_cert_password_flags_name;
+       const char *client_cert_password_flags_name;
+#endif
+       const char *client_key_password_flags_name;
+
        gboolean editing_connection;
+       GtkWidget *ca_cert_chooser;
+       GtkWidget *client_cert_chooser;
 };
 
 
-static void
-show_toggled_cb (GtkCheckButton *button, EAPMethod *method)
-{
-       GtkWidget *widget;
-       gboolean visible;
-
-       widget = GTK_WIDGET (gtk_builder_get_object (method->builder, "eap_tls_private_key_password_entry"));
-       g_assert (widget);
-
-       visible = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
-       gtk_entry_set_visibility (GTK_ENTRY (widget), visible);
-}
-
 static gboolean
 validate (EAPMethod *parent, GError **error)
 {
-       NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
+       EAPMethodTLS *method = (EAPMethodTLS *) parent;
        GtkWidget *widget;
-       const char *password, *identity;
-       GError *local = NULL;
-       gboolean ret = TRUE;
+       const char *identity;
 
        widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_identity_entry"));
        g_assert (widget);
@@ -66,78 +62,34 @@ validate (EAPMethod *parent, GError **error)
        if (!identity || !strlen (identity)) {
                widget_set_error (widget);
                g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("missing EAP-TLS identity"));
-               ret = FALSE;
-       } else {
-               widget_unset_error (widget);
-       }
-
-       if (!eap_method_validate_filepicker (parent->builder, "eap_tls_ca_cert_button", TYPE_CA_CERT, NULL, 
NULL, &local)) {
-               widget_set_error (GTK_WIDGET (gtk_builder_get_object (parent->builder, 
"eap_tls_ca_cert_button")));
-               if (ret) {
-                       g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid EAP-TLS CA certificate: 
%s"), local->message);
-                       ret = FALSE;
-               }
-               g_clear_error (&local);
-       } else if (eap_method_ca_cert_required (parent->builder, "eap_tls_ca_cert_not_required_checkbox", 
"eap_tls_ca_cert_button")) {
-               widget_set_error (GTK_WIDGET (gtk_builder_get_object (parent->builder, 
"eap_tls_ca_cert_button")));
-               if (ret) {
-                       g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid EAP-TLS CA 
certificate: no certificate specified"));
-                       ret = FALSE;
-               }
-       }
-
-       widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_password_entry"));
-       g_assert (widget);
-       password = gtk_entry_get_text (GTK_ENTRY (widget));
-       if (!password || !strlen (password)) {
-               widget_set_error (widget);
-               if (ret) {
-                       g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid EAP-TLS 
password: missing"));
-                       ret = FALSE;
-               }
+               return FALSE;
        } else {
                widget_unset_error (widget);
        }
 
-       if (!eap_method_validate_filepicker (parent->builder,
-                                            "eap_tls_private_key_button",
-                                            TYPE_PRIVATE_KEY,
-                                            password,
-                                            &format,
-                                            &local)) {
-               if (ret) {
-                       g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid EAP-TLS private-key: 
%s"), local->message);
-                       ret = FALSE;
-               }
-               g_clear_error (&local);
-               widget_set_error (GTK_WIDGET (gtk_builder_get_object (parent->builder, 
"eap_tls_private_key_button")));
-       }
+       if (   gtk_widget_get_sensitive (method->ca_cert_chooser)
+           && !nma_cert_chooser_validate (NMA_CERT_CHOOSER (method->ca_cert_chooser), error))
+               return FALSE;
 
-       if (format != NM_SETTING_802_1X_CK_FORMAT_PKCS12) {
-               if (!eap_method_validate_filepicker (parent->builder, "eap_tls_user_cert_button", 
TYPE_CLIENT_CERT, NULL, NULL, &local)) {
-                       if (ret) {
-                               g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid EAP-TLS 
user-certificate: %s"), local->message);
-                               ret = FALSE;
-                       }
-                       g_clear_error (&local);
-                       widget_set_error (GTK_WIDGET (gtk_builder_get_object (parent->builder, 
"eap_tls_user_cert_button")));
-               }
-       }
+       if (!nma_cert_chooser_validate (NMA_CERT_CHOOSER (method->client_cert_chooser), error))
+               return FALSE;
 
-       return ret;
+       return TRUE;
 }
 
 static void
 ca_cert_not_required_toggled (GtkWidget *ignored, gpointer user_data)
 {
-       EAPMethod *parent = user_data;
+       EAPMethodTLS *method = (EAPMethodTLS *) user_data;
 
-       eap_method_ca_cert_not_required_toggled (parent->builder, "eap_tls_ca_cert_not_required_checkbox", 
"eap_tls_ca_cert_button");
+       gtk_widget_set_sensitive (method->ca_cert_chooser,
+                                 !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ignored)));
 }
 
 static void
 add_to_size_group (EAPMethod *parent, GtkSizeGroup *group)
 {
+       EAPMethodTLS *method = (EAPMethodTLS *) parent;
        GtkWidget *widget;
 
        widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, 
"eap_tls_ca_cert_not_required_checkbox"));
@@ -148,35 +100,23 @@ add_to_size_group (EAPMethod *parent, GtkSizeGroup *group)
        g_assert (widget);
        gtk_size_group_add_widget (group, widget);
 
-       widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_user_cert_label"));
-       g_assert (widget);
-       gtk_size_group_add_widget (group, widget);
-
-       widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_label"));
-       g_assert (widget);
-       gtk_size_group_add_widget (group, widget);
-
-       widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_label"));
-       g_assert (widget);
-       gtk_size_group_add_widget (group, widget);
-
-       widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_password_label"));
-       g_assert (widget);
-       gtk_size_group_add_widget (group, widget);
+       nma_cert_chooser_add_to_size_group (NMA_CERT_CHOOSER (method->client_cert_chooser), group);
+       nma_cert_chooser_add_to_size_group (NMA_CERT_CHOOSER (method->ca_cert_chooser), group);
 }
 
 static void
-fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFlags flags)
+fill_connection (EAPMethod *parent, NMConnection *connection)
 {
        EAPMethodTLS *method = (EAPMethodTLS *) parent;
        NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
        NMSetting8021x *s_8021x;
        NMSettingSecretFlags secret_flags;
-       GtkWidget *widget, *passwd_entry;
-       char *ca_filename, *pk_filename, *cc_filename;
+       GtkWidget *widget;
+       char *value;
        const char *password = NULL;
        GError *error = NULL;
        gboolean ca_cert_error = FALSE;
+       NMSetting8021xCKScheme scheme;
 
        s_8021x = nm_connection_get_setting_802_1x (connection);
        g_assert (s_8021x);
@@ -191,39 +131,53 @@ fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFla
        g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, gtk_entry_get_text (GTK_ENTRY (widget)), NULL);
 
        /* TLS private key */
-       widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_password_entry"));
-       g_assert (widget);
-       password = gtk_entry_get_text (GTK_ENTRY (widget));
-       g_assert (password);
-       passwd_entry = widget;
-
-       widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_button"));
-       g_assert (widget);
-       pk_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
-       g_assert (pk_filename);
+       password = g_strdup (nma_cert_chooser_get_key_password (NMA_CERT_CHOOSER 
(method->client_cert_chooser)));
+       value = nma_cert_chooser_get_key (NMA_CERT_CHOOSER (method->client_cert_chooser), &scheme);
 
        if (parent->phase2) {
-               if (!nm_setting_802_1x_set_phase2_private_key (s_8021x, pk_filename, password, 
NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) {
-                       g_warning ("Couldn't read phase2 private key '%s': %s", pk_filename, error ? 
error->message : "(unknown)");
+               if (!nm_setting_802_1x_set_phase2_private_key (s_8021x, value, password, scheme, &format, 
&error)) {
+                       g_warning ("Couldn't read phase2 private key '%s': %s", value, error ? error->message 
: "(unknown)");
                        g_clear_error (&error);
                }
        } else {
-               if (!nm_setting_802_1x_set_private_key (s_8021x, pk_filename, password, 
NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) {
-                       g_warning ("Couldn't read private key '%s': %s", pk_filename, error ? error->message 
: "(unknown)");
+               if (!nm_setting_802_1x_set_private_key (s_8021x, value, password, scheme, &format, &error)) {
+                       g_warning ("Couldn't read private key '%s': %s", value, error ? error->message : 
"(unknown)");
                        g_clear_error (&error);
                }
        }
-       g_free (pk_filename);
 
-       /* Save 802.1X password flags to the connection */
-       secret_flags = nma_utils_menu_to_secret_flags (passwd_entry);
-       nm_setting_set_secret_flags (NM_SETTING (s_8021x), parent->password_flags_name,
+#ifdef NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD
+/* libnm-glib doesn't support these. */
+       /* Save CA certificate PIN password flags to the connection */
+       secret_flags = nma_cert_chooser_get_cert_password_flags (NMA_CERT_CHOOSER (method->ca_cert_chooser));
+       nm_setting_set_secret_flags (NM_SETTING (s_8021x), method->ca_cert_password_flags_name,
                                     secret_flags, NULL);
+       if (method->editing_connection) {
+               /* Update secret flags and popup when editing the connection */
+               nma_cert_chooser_update_cert_password_storage (NMA_CERT_CHOOSER (method->ca_cert_chooser),
+                                                              secret_flags, NM_SETTING (s_8021x),
+                                                              method->ca_cert_password_flags_name);
+       }
 
-       /* Update secret flags and popup when editing the connection */
+       /* Save user certificate PIN password flags to the connection */
+       secret_flags = nma_cert_chooser_get_cert_password_flags (NMA_CERT_CHOOSER 
(method->client_cert_chooser));
+       nm_setting_set_secret_flags (NM_SETTING (s_8021x), method->client_cert_password_flags_name,
+                                    secret_flags, NULL);
        if (method->editing_connection) {
-               nma_utils_update_password_storage (passwd_entry, secret_flags,
-                                                  NM_SETTING (s_8021x), parent->password_flags_name);
+               nma_cert_chooser_update_cert_password_storage (NMA_CERT_CHOOSER (method->client_cert_chooser),
+                                                              secret_flags, NM_SETTING (s_8021x),
+                                                              method->client_cert_password_flags_name);
+       }
+#endif
+
+       /* Save user private key password flags to the connection */
+       secret_flags = nma_cert_chooser_get_key_password_flags (NMA_CERT_CHOOSER 
(method->client_cert_chooser));
+       nm_setting_set_secret_flags (NM_SETTING (s_8021x), method->client_key_password_flags_name,
+                                    secret_flags, NULL);
+       if (method->editing_connection) {
+               nma_cert_chooser_update_key_password_storage (NMA_CERT_CHOOSER (method->client_cert_chooser),
+                                                             secret_flags, NM_SETTING (s_8021x),
+                                                             method->client_key_password_flags_name);
        }
 
        /* TLS client certificate */
@@ -231,213 +185,269 @@ fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFla
                /* If the key is pkcs#12 nm_setting_802_1x_set_private_key() already
                 * set the client certificate for us.
                 */
-               widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_user_cert_button"));
-               g_assert (widget);
-               cc_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
-               g_assert (cc_filename);
-
+               value = nma_cert_chooser_get_cert (NMA_CERT_CHOOSER (method->client_cert_chooser), &scheme);
                format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
                if (parent->phase2) {
-                       if (!nm_setting_802_1x_set_phase2_client_cert (s_8021x, cc_filename, 
NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) {
-                               g_warning ("Couldn't read phase2 client certificate '%s': %s", cc_filename, 
error ? error->message : "(unknown)");
+                       if (!nm_setting_802_1x_set_phase2_client_cert (s_8021x, value, scheme, &format, 
&error)) {
+                               g_warning ("Couldn't read phase2 client certificate '%s': %s", value, error ? 
error->message : "(unknown)");
                                g_clear_error (&error);
                        }
                } else {
-                       if (!nm_setting_802_1x_set_client_cert (s_8021x, cc_filename, 
NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) {
-                               g_warning ("Couldn't read client certificate '%s': %s", cc_filename, error ? 
error->message : "(unknown)");
+                       if (!nm_setting_802_1x_set_client_cert (s_8021x, value, scheme, &format, &error)) {
+                               g_warning ("Couldn't read client certificate '%s': %s", value, error ? 
error->message : "(unknown)");
                                g_clear_error (&error);
                        }
                }
-               g_free (cc_filename);
+               g_free (value);
        }
 
        /* TLS CA certificate */
-       widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_button"));
-       g_assert (widget);
-       ca_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
-
+       value = nma_cert_chooser_get_cert (NMA_CERT_CHOOSER (method->ca_cert_chooser), &scheme);
        format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
        if (parent->phase2) {
-               if (!nm_setting_802_1x_set_phase2_ca_cert (s_8021x, ca_filename, 
NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) {
-                       g_warning ("Couldn't read phase2 CA certificate '%s': %s", ca_filename, error ? 
error->message : "(unknown)");
+               if (!nm_setting_802_1x_set_phase2_ca_cert (s_8021x, value, scheme, &format, &error)) {
+                       g_warning ("Couldn't read phase2 CA certificate '%s': %s", value, error ? 
error->message : "(unknown)");
                        g_clear_error (&error);
                        ca_cert_error = TRUE;
                }
        } else {
-               if (!nm_setting_802_1x_set_ca_cert (s_8021x, ca_filename, NM_SETTING_802_1X_CK_SCHEME_PATH, 
&format, &error)) {
-                       g_warning ("Couldn't read CA certificate '%s': %s", ca_filename, error ? 
error->message : "(unknown)");
+               if (!nm_setting_802_1x_set_ca_cert (s_8021x, value, scheme, &format, &error)) {
+                       g_warning ("Couldn't read CA certificate '%s': %s", value, error ? error->message : 
"(unknown)");
                        g_clear_error (&error);
                        ca_cert_error = TRUE;
                }
        }
-       eap_method_ca_cert_ignore_set (parent, connection, ca_filename, ca_cert_error);
-       g_free (ca_filename);
+       eap_method_ca_cert_ignore_set (parent, connection, value, ca_cert_error);
+       g_free (value);
 }
 
-static void
-private_key_picker_helper (EAPMethod *parent, const char *filename, gboolean changed)
+static GError *
+client_cert_validate_cb (NMACertChooser *cert_chooser, gpointer user_data)
 {
-       NMSetting8021x *setting;
-       NMSetting8021xCKFormat cert_format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
-       const char *password;
-       GtkWidget *widget;
-
-       widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_password_entry"));
-       g_assert (widget);
-       password = gtk_entry_get_text (GTK_ENTRY (widget));
+       NMSetting8021xCKScheme scheme;
+        NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
+       gs_unref_object NMSetting8021x *setting = NULL;
+       gs_free char *value = NULL;
+       GError *local = NULL;
 
        setting = (NMSetting8021x *) nm_setting_802_1x_new ();
-       nm_setting_802_1x_set_private_key (setting, filename, password, NM_SETTING_802_1X_CK_SCHEME_PATH, 
&cert_format, NULL);
-       g_object_unref (setting);
-
-       /* With PKCS#12, the client cert must be the same as the private key */
-       widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_user_cert_button"));
-       if (cert_format == NM_SETTING_802_1X_CK_FORMAT_PKCS12) {
-               gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (widget));
-               gtk_widget_set_sensitive (widget, FALSE);
-       } else if (changed)
-               gtk_widget_set_sensitive (widget, TRUE);
-
-       /* Warn the user if the private key is unencrypted */
-       if (!eap_method_is_encrypted_private_key (filename)) {
-               GtkWidget *dialog;
-               GtkWidget *toplevel;
-               GtkWindow *parent_window = NULL;
-
-               toplevel = gtk_widget_get_toplevel (parent->ui_widget);
-               if (gtk_widget_is_toplevel (toplevel))
-                       parent_window = GTK_WINDOW (toplevel);
-
-               dialog = gtk_message_dialog_new (parent_window,
-                                                GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
-                                                GTK_MESSAGE_WARNING,
-                                                GTK_BUTTONS_OK,
-                                                "%s",
-                                                _("Unencrypted private keys are insecure"));
-               gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
-                                                         "%s",
-                                                         _("The selected private key does not appear to be 
protected by a password. This could allow your security credentials to be compromised. Please select a 
password-protected private key.\n\n(You can password-protect your private key with openssl)"));
-               gtk_dialog_run (GTK_DIALOG (dialog));
-               gtk_widget_destroy (dialog);
+
+       value = nma_cert_chooser_get_cert (cert_chooser, &scheme);
+       if (!value) {
+               return g_error_new_literal (NMA_ERROR, NMA_ERROR_GENERIC,
+                                           _("no user certificate selected"));
+       }
+       if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) {
+               if (!g_file_test (value, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) {
+                       return g_error_new_literal (NMA_ERROR, NMA_ERROR_GENERIC,
+                                                   _("selected user certificate file does not exist"));
+               }
        }
+
+       if (!nm_setting_802_1x_set_client_cert (setting, value, scheme, &format, &local))
+               return local;
+
+       return NULL;
 }
 
-static void
-private_key_picker_file_set_cb (GtkWidget *chooser, gpointer user_data)
+static GError *
+client_key_validate_cb (NMACertChooser *cert_chooser, gpointer user_data)
+{
+       NMSetting8021xCKScheme scheme;
+       gs_free char *value = NULL;
+
+
+       value = nma_cert_chooser_get_key (cert_chooser, &scheme);
+       if (!value) {
+               return g_error_new_literal (NMA_ERROR, NMA_ERROR_GENERIC,
+                                           _("no key selected"));
+       }
+       if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) {
+               if (!g_file_test (value, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) {
+                       return g_error_new_literal (NMA_ERROR, NMA_ERROR_GENERIC,
+                                                   _("selected key file does not exist"));
+               }
+       }
+
+       return NULL;
+}
+
+static GError *
+client_key_password_validate_cb (NMACertChooser *cert_chooser, gpointer user_data)
 {
-       EAPMethod *parent = (EAPMethod *) user_data;
-       char *filename;
+       NMSetting8021xCKScheme scheme;
+       NMSettingSecretFlags secret_flags;
+       gs_unref_object NMSetting8021x *setting = NULL;
+       gs_free char *value = NULL;
+       const char *password = NULL;
+       GError *local = NULL;
+
+       secret_flags = nma_cert_chooser_get_key_password_flags (cert_chooser);
+       if (   secret_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED
+           || secret_flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED)
+               return NULL;
 
-       filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
-       if (filename)
-               private_key_picker_helper (parent, filename, TRUE);
-       g_free (filename);
+       setting = (NMSetting8021x *) nm_setting_802_1x_new ();
+
+       value = nma_cert_chooser_get_key (cert_chooser, &scheme);
+       password = nma_cert_chooser_get_key_password (cert_chooser);
+       if (!nm_setting_802_1x_set_private_key (setting, value, password, scheme, NULL, &local))
+               return local;
+
+       return NULL;
 }
 
-static void reset_filter (GtkWidget *widget, GParamSpec *spec, gpointer user_data)
+static GError *
+ca_cert_validate_cb (NMACertChooser *cert_chooser, gpointer user_data)
 {
-       if (!gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (widget))) {
-               g_signal_handlers_block_by_func (widget, reset_filter, user_data);
-               gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (widget), GTK_FILE_FILTER (user_data));
-               g_signal_handlers_unblock_by_func (widget, reset_filter, user_data);
+       NMSetting8021xCKScheme scheme;
+        NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
+       gs_unref_object NMSetting8021x *setting = NULL;
+       gs_free char *value = NULL;
+       GError *local = NULL;
+
+       setting = (NMSetting8021x *) nm_setting_802_1x_new ();
+
+       value = nma_cert_chooser_get_cert (cert_chooser, &scheme);
+       if (!value) {
+               return g_error_new_literal (NMA_ERROR, NMA_ERROR_GENERIC,
+                                           _("no CA certificate selected"));
+       }
+       if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) {
+               if (!g_file_test (value, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) {
+                       return g_error_new_literal (NMA_ERROR, NMA_ERROR_GENERIC,
+                                                   _("selected CA certificate file does not exist"));
+               }
        }
+
+       if (!nm_setting_802_1x_set_ca_cert (setting, value, scheme, &format, &local))
+               return local;
+
+       return NULL;
+}
+
+static void
+client_cert_fixup_pkcs12 (NMACertChooser *cert_chooser, gpointer user_data)
+{
+       NMSetting8021xCKScheme cert_scheme, key_scheme;
+        NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
+       gs_free char *cert_value = NULL;
+       gs_free char *key_value = NULL;
+       gs_unref_object NMSetting8021x *setting = NULL;
+
+       setting = (NMSetting8021x *) nm_setting_802_1x_new ();
+
+       cert_value = nma_cert_chooser_get_cert (cert_chooser, &cert_scheme);
+       key_value = nma_cert_chooser_get_key (cert_chooser, &key_scheme);
+
+       if (   !cert_value || key_value
+           || !nm_setting_802_1x_set_client_cert (setting, cert_value, cert_scheme, &format, NULL))
+               return;
+
+       if (format == NM_SETTING_802_1X_CK_FORMAT_PKCS12)
+               nma_cert_chooser_set_key (cert_chooser, cert_value, cert_scheme);
 }
 
 typedef const char * (*PathFunc) (NMSetting8021x *setting);
+typedef const char * (*UriFunc) (NMSetting8021x *setting);
 typedef NMSetting8021xCKScheme (*SchemeFunc)  (NMSetting8021x *setting);
+typedef const char * (*PasswordFunc) (NMSetting8021x *setting);
 
 static void
-setup_filepicker (GtkBuilder *builder,
-                  const char *name,
-                  const char *title,
-                  WirelessSecurity *ws_parent,
-                  EAPMethod *parent,
-                  NMSetting8021x *s_8021x,
-                  SchemeFunc scheme_func,
-                  PathFunc path_func,
-                  gboolean privkey,
-                  gboolean client_cert)
+setup_cert_chooser (NMACertChooser *cert_chooser,
+                    NMSetting8021x *s_8021x,
+                    SchemeFunc cert_scheme_func,
+                    PathFunc cert_path_func,
+                    UriFunc cert_uri_func,
+                    PasswordFunc cert_password_func,
+                    SchemeFunc key_scheme_func,
+                    PathFunc key_path_func,
+                    UriFunc key_uri_func,
+                    PasswordFunc key_password_func)
 {
-       GtkWidget *widget;
-       GtkFileFilter *filter;
-       const char *filename = NULL;
-
-       widget = GTK_WIDGET (gtk_builder_get_object (builder, name));
-       g_assert (widget);
-       gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (widget), TRUE);
-       gtk_file_chooser_button_set_title (GTK_FILE_CHOOSER_BUTTON (widget), title);
-
-       if (s_8021x && path_func && scheme_func) {
-               if (scheme_func (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH) {
-                       filename = path_func (s_8021x);
-                       if (filename)
-                               gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), filename);
+       NMSetting8021xCKScheme scheme = NM_SETTING_802_1X_CK_SCHEME_UNKNOWN;
+       const char *value = NULL;
+
+
+       if (s_8021x && cert_path_func && cert_uri_func && cert_scheme_func) {
+               scheme = cert_scheme_func (s_8021x);
+               switch (scheme) {
+               case NM_SETTING_802_1X_CK_SCHEME_PATH:
+                       value = cert_path_func (s_8021x);
+                       break;
+#ifdef NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PKCS11
+/* Not available in libnm-glib */
+               case NM_SETTING_802_1X_CK_SCHEME_PKCS11:
+                       value = cert_uri_func (s_8021x);
+                       if (cert_password_func)
+                               nma_cert_chooser_set_cert_password (cert_chooser, cert_password_func 
(s_8021x));
+                       break;
+#endif
+               case NM_SETTING_802_1X_CK_SCHEME_UNKNOWN:
+                       /* No CA set. */
+                       break;
+               default:
+                       g_warning ("unhandled certificate scheme %d", scheme);
                }
-       }
 
-       /* Connect a special handler for private keys to intercept PKCS#12 key types
-        * and desensitize the user cert button.
-        */
-       if (privkey) {
-               g_signal_connect (G_OBJECT (widget), "selection-changed",
-                                 (GCallback) private_key_picker_file_set_cb,
-                                 parent);
-               if (filename)
-                       private_key_picker_helper (parent, filename, FALSE);
        }
+       nma_cert_chooser_set_cert (cert_chooser, value, scheme);
+
+       if (s_8021x && key_path_func && key_uri_func && key_scheme_func) {
+               scheme = key_scheme_func (s_8021x);
+               switch (scheme) {
+               case NM_SETTING_802_1X_CK_SCHEME_PATH:
+                       value = key_path_func (s_8021x);
+                       break;
+#ifdef NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PKCS11
+/* Not available in libnm-glib */
+               case NM_SETTING_802_1X_CK_SCHEME_PKCS11:
+                       value = key_uri_func (s_8021x);
+                       break;
+#endif
+               case NM_SETTING_802_1X_CK_SCHEME_UNKNOWN:
+                       /* No certificate set. */
+                       break;
+               default:
+                       g_warning ("unhandled key scheme %d", scheme);
+               }
 
-       g_signal_connect (G_OBJECT (widget), "selection-changed",
-                         (GCallback) wireless_security_changed_cb,
-                         ws_parent);
-
-       filter = eap_method_default_file_chooser_filter_new (privkey);
-       gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (widget), filter);
+               nma_cert_chooser_set_key (cert_chooser, value, scheme);
+       }
 
-       /* For some reason, GTK+ calls set_current_filter (..., NULL) from 
-        * gtkfilechooserdefault.c::show_and_select_files_finished_loading() on our
-        * dialog; so force-reset the filter to what we want it to be whenever
-        * it gets cleared.
-        */
-       if (client_cert)
-               g_signal_connect (G_OBJECT (widget), "notify::filter", (GCallback) reset_filter, filter);
+       if (s_8021x && key_password_func)
+               nma_cert_chooser_set_key_password (cert_chooser, key_password_func (s_8021x));
 }
 
+#ifndef NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PKCS11
+/* Not available in libnm-glib */
+#define nm_setting_802_1x_get_ca_cert_password             NULL
+#define nm_setting_802_1x_get_ca_cert_uri                  NULL
+#define nm_setting_802_1x_get_client_cert_password         NULL
+#define nm_setting_802_1x_get_client_cert_uri              NULL
+#define nm_setting_802_1x_get_private_key_uri              NULL
+#define nm_setting_802_1x_get_phase2_ca_cert_password      NULL
+#define nm_setting_802_1x_get_phase2_ca_cert_uri           NULL
+#define nm_setting_802_1x_get_phase2_client_cert_password  NULL
+#define nm_setting_802_1x_get_phase2_client_cert_uri       NULL
+#define nm_setting_802_1x_get_phase2_private_key_uri       NULL
+#endif
+
 static void
 update_secrets (EAPMethod *parent, NMConnection *connection)
 {
-       NMSetting8021x *s_8021x;
-       HelperSecretFunc password_func;
-       SchemeFunc scheme_func;
-       PathFunc path_func;
-       const char *filename;
-       GtkWidget *widget;
-
-       if (parent->phase2) {
-               password_func = (HelperSecretFunc) nm_setting_802_1x_get_phase2_private_key_password;
-               scheme_func = nm_setting_802_1x_get_phase2_private_key_scheme;
-               path_func = nm_setting_802_1x_get_phase2_private_key_path;
-       } else {
-               password_func = (HelperSecretFunc) nm_setting_802_1x_get_private_key_password;
-               scheme_func = nm_setting_802_1x_get_private_key_scheme;
-               path_func = nm_setting_802_1x_get_private_key_path;
-       }
-
-       helper_fill_secret_entry (connection,
-                                 parent->builder,
-                                 "eap_tls_private_key_password_entry",
-                                 NM_TYPE_SETTING_802_1X,
-                                 password_func);
+       EAPMethodTLS *method = (EAPMethodTLS *) parent;
 
-       /* Set the private key filepicker button path if we have a private key */
-       s_8021x = nm_connection_get_setting_802_1x (connection);
-       if (s_8021x && (scheme_func (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH)) {
-               filename = path_func (s_8021x);
-               if (filename) {
-                       widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, 
"eap_tls_private_key_button"));
-                       g_assert (widget);
-                       gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), filename);
-               }
-       }
+       setup_cert_chooser (NMA_CERT_CHOOSER (method->client_cert_chooser),
+                           nm_connection_get_setting_802_1x (connection),
+                           NULL,
+                           NULL,
+                           NULL,
+                           parent->phase2 ? nm_setting_802_1x_get_phase2_client_cert_password : 
nm_setting_802_1x_get_client_cert_password,
+                           parent->phase2 ? nm_setting_802_1x_get_phase2_private_key_scheme : 
nm_setting_802_1x_get_private_key_scheme,
+                           parent->phase2 ? nm_setting_802_1x_get_phase2_private_key_path : 
nm_setting_802_1x_get_private_key_path,
+                           parent->phase2 ? nm_setting_802_1x_get_phase2_private_key_uri : 
nm_setting_802_1x_get_private_key_uri,
+                           parent->phase2 ? nm_setting_802_1x_get_phase2_private_key_password : 
nm_setting_802_1x_get_private_key_password);
 }
 
 EAPMethodTLS *
@@ -465,10 +475,19 @@ eap_method_tls_new (WirelessSecurity *ws_parent,
        if (!parent)
                return NULL;
 
-       parent->password_flags_name = phase2 ?
-                                       NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD :
-                                       NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD;
        method = (EAPMethodTLS *) parent;
+#ifdef NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD
+/* libnm-glib doesn't support these. */
+       method->ca_cert_password_flags_name = phase2
+                                             ? NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD
+                                             : NM_SETTING_802_1X_CLIENT_CERT_PASSWORD;
+       method->client_cert_password_flags_name = phase2
+                                                 ? NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD
+                                                 : NM_SETTING_802_1X_CLIENT_CERT_PASSWORD;
+#endif
+       method->client_key_password_flags_name = phase2
+                                                ? NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD
+                                                : NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD;
        method->editing_connection = secrets_only ? FALSE : TRUE;
 
        if (connection)
@@ -491,71 +510,95 @@ eap_method_tls_new (WirelessSecurity *ws_parent,
        if (s_8021x && nm_setting_802_1x_get_identity (s_8021x))
                gtk_entry_set_text (GTK_ENTRY (widget), nm_setting_802_1x_get_identity (s_8021x));
 
-       setup_filepicker (parent->builder, "eap_tls_user_cert_button",
-                         _("Choose your personal certificate"),
-                         ws_parent, parent, s_8021x,
-                         phase2 ? nm_setting_802_1x_get_phase2_client_cert_scheme : 
nm_setting_802_1x_get_client_cert_scheme,
-                         phase2 ? nm_setting_802_1x_get_phase2_client_cert_path : 
nm_setting_802_1x_get_client_cert_path,
-                         FALSE, TRUE);
-       setup_filepicker (parent->builder, "eap_tls_ca_cert_button",
-                         _("Choose a Certificate Authority certificate"),
-                         ws_parent, parent, s_8021x,
-                         phase2 ? nm_setting_802_1x_get_phase2_ca_cert_scheme : 
nm_setting_802_1x_get_ca_cert_scheme,
-                         phase2 ? nm_setting_802_1x_get_phase2_ca_cert_path : 
nm_setting_802_1x_get_ca_cert_path,
-                         FALSE, FALSE);
-       setup_filepicker (parent->builder, "eap_tls_private_key_button",
-                         _("Choose your private key"),
-                         ws_parent, parent, s_8021x,
-                         phase2 ? nm_setting_802_1x_get_phase2_private_key_scheme : 
nm_setting_802_1x_get_private_key_scheme,
-                         phase2 ? nm_setting_802_1x_get_phase2_private_key_path : 
nm_setting_802_1x_get_private_key_path,
-                         TRUE, FALSE);
-
-       if (connection && eap_method_ca_cert_ignore_get (parent, connection)) {
-               widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_button"));
-               ca_not_required = !gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
-       }
-       widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, 
"eap_tls_ca_cert_not_required_checkbox"));
-       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), ca_not_required);
+       widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_grid"));
+       g_assert (widget);
 
-       /* Fill secrets, if any */
-       if (connection)
-               update_secrets (parent, connection);
+       method->client_cert_chooser = nma_cert_chooser_new ("User",
+                                                           secrets_only ? NMA_CERT_CHOOSER_FLAG_PASSWORDS : 
0);
+       gtk_grid_attach (GTK_GRID (widget), method->client_cert_chooser, 0, 1, 2, 1);
+       gtk_widget_show (method->client_cert_chooser);
+
+       g_signal_connect (method->client_cert_chooser, "cert-validate",
+                         G_CALLBACK (client_cert_validate_cb),
+                         NULL);
+       g_signal_connect (method->client_cert_chooser,
+                         "key-validate",
+                         G_CALLBACK (client_key_validate_cb),
+                         NULL);
+       g_signal_connect (method->client_cert_chooser,
+                         "key-password-validate",
+                         G_CALLBACK (client_key_password_validate_cb),
+                         NULL);
+       g_signal_connect (method->client_cert_chooser,
+                         "changed",
+                         G_CALLBACK (client_cert_fixup_pkcs12),
+                         ws_parent);
+       g_signal_connect (method->client_cert_chooser,
+                         "changed",
+                         G_CALLBACK (wireless_security_changed_cb),
+                         ws_parent);
 
-       widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_password_entry"));
-       g_assert (widget);
-       g_signal_connect (G_OBJECT (widget), "changed",
-                         (GCallback) wireless_security_changed_cb,
+       setup_cert_chooser (NMA_CERT_CHOOSER (method->client_cert_chooser), s_8021x,
+                           phase2 ? nm_setting_802_1x_get_phase2_client_cert_scheme : 
nm_setting_802_1x_get_client_cert_scheme,
+                           phase2 ? nm_setting_802_1x_get_phase2_client_cert_path : 
nm_setting_802_1x_get_client_cert_path,
+                           phase2 ? nm_setting_802_1x_get_phase2_client_cert_uri : 
nm_setting_802_1x_get_client_cert_uri,
+                           phase2 ? nm_setting_802_1x_get_phase2_client_cert_password : 
nm_setting_802_1x_get_client_cert_password,
+                           phase2 ? nm_setting_802_1x_get_phase2_private_key_scheme : 
nm_setting_802_1x_get_private_key_scheme,
+                           phase2 ? nm_setting_802_1x_get_phase2_private_key_path : 
nm_setting_802_1x_get_private_key_path,
+                           phase2 ? nm_setting_802_1x_get_phase2_private_key_uri : 
nm_setting_802_1x_get_private_key_uri,
+                           phase2 ? nm_setting_802_1x_get_phase2_private_key_password : 
nm_setting_802_1x_get_private_key_password);
+
+       method->ca_cert_chooser = nma_cert_chooser_new ("CA",
+                                                         NMA_CERT_CHOOSER_FLAG_CERT
+                                                       | (secrets_only ? NMA_CERT_CHOOSER_FLAG_PASSWORDS : 
0));
+       gtk_grid_attach (GTK_GRID (widget), method->ca_cert_chooser, 0, 2, 2, 1);
+       gtk_widget_show (method->ca_cert_chooser);
+
+       g_signal_connect (method->ca_cert_chooser,
+                         "cert-validate",
+                         G_CALLBACK (ca_cert_validate_cb),
+                         NULL);
+       g_signal_connect (method->ca_cert_chooser,
+                         "changed",
+                         G_CALLBACK (wireless_security_changed_cb),
                          ws_parent);
 
-       /* Create password-storage popup menu for password entry under entry's secondary icon */
-       nma_utils_setup_password_storage (widget, 0, (NMSetting *) s_8021x, parent->password_flags_name,
-                                         FALSE, secrets_only);
+       setup_cert_chooser (NMA_CERT_CHOOSER (method->ca_cert_chooser), s_8021x,
+                           phase2 ? nm_setting_802_1x_get_phase2_ca_cert_scheme : 
nm_setting_802_1x_get_ca_cert_scheme,
+                           phase2 ? nm_setting_802_1x_get_phase2_ca_cert_path : 
nm_setting_802_1x_get_ca_cert_path,
+                           phase2 ? nm_setting_802_1x_get_phase2_ca_cert_uri : 
nm_setting_802_1x_get_ca_cert_uri,
+                           phase2 ? nm_setting_802_1x_get_phase2_ca_cert_password : 
nm_setting_802_1x_get_ca_cert_password,
+                           NULL,
+                           NULL,
+                           NULL,
+                           NULL);
 
-       widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "show_checkbutton_eaptls"));
-       g_assert (widget);
-       g_signal_connect (G_OBJECT (widget), "toggled",
-                         (GCallback) show_toggled_cb,
-                         parent);
-
-       if (secrets_only) {
-               widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_identity_entry"));
-               gtk_widget_set_sensitive (widget, FALSE);
-               widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_user_cert_label"));
-               gtk_widget_hide (widget);
-               widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_user_cert_button"));
-               gtk_widget_hide (widget);
-               widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_label"));
-               gtk_widget_hide (widget);
-               widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_button"));
-               gtk_widget_hide (widget);
-               widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_label"));
-               gtk_widget_hide (widget);
-               widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_button"));
-               gtk_widget_hide (widget);
-               widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, 
"eap_tls_ca_cert_not_required_checkbox"));
-               gtk_widget_hide (widget);
+       if (connection && eap_method_ca_cert_ignore_get (parent, connection)) {
+               gchar *ca_cert;
+               NMSetting8021xCKScheme scheme;
+
+               ca_cert = nma_cert_chooser_get_cert (NMA_CERT_CHOOSER (method->ca_cert_chooser), &scheme);
+               if (ca_cert)
+                       g_free (ca_cert);
+               else
+                       ca_not_required = TRUE;
        }
+       widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, 
"eap_tls_ca_cert_not_required_checkbox"));
+       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), ca_not_required);
+
+       /* Create password-storage popup menus for password entries under their secondary icon */
+#ifdef NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD
+/* libnm-glib doesn't support these. */
+       nma_cert_chooser_setup_cert_password_storage (NMA_CERT_CHOOSER (method->ca_cert_chooser),
+                                                     0, (NMSetting *) s_8021x, 
method->ca_cert_password_flags_name,
+                                                     FALSE, secrets_only);
+       nma_cert_chooser_setup_cert_password_storage (NMA_CERT_CHOOSER (method->client_cert_chooser),
+                                                     0, (NMSetting *) s_8021x, 
method->client_cert_password_flags_name,
+                                                     FALSE, secrets_only);
+#endif
+       nma_cert_chooser_setup_key_password_storage (NMA_CERT_CHOOSER (method->client_cert_chooser),
+                                                    0, (NMSetting *) s_8021x, 
method->client_key_password_flags_name,
+                                                    FALSE, secrets_only);
 
        return method;
 }
-
diff --git a/src/wireless-security/eap-method-tls.ui b/src/wireless-security/eap-method-tls.ui
index 94bad98..1e47d6f 100644
--- a/src/wireless-security/eap-method-tls.ui
+++ b/src/wireless-security/eap-method-tls.ui
@@ -8,7 +8,7 @@
     <property name="show_tabs">False</property>
     <property name="show_border">False</property>
     <child>
-      <object class="GtkGrid">
+      <object class="GtkGrid" id="eap_tls_grid">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
         <property name="row_spacing">6</property>
@@ -40,17 +40,6 @@
           </packing>
         </child>
         <child>
-          <object class="GtkFileChooserButton" id="eap_tls_ca_cert_button">
-            <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">2</property>
-          </packing>
-        </child>
-        <child>
           <object class="GtkCheckButton" id="eap_tls_ca_cert_not_required_checkbox">
             <property name="label" translatable="yes">No CA certificate is _required</property>
             <property name="visible">True</property>
@@ -67,111 +56,13 @@
           </packing>
         </child>
         <child>
-          <object class="GtkFileChooserButton" id="eap_tls_private_key_button">
-            <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">4</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkEntry" id="eap_tls_private_key_password_entry">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="hexpand">True</property>
-            <property name="visibility">False</property>
-            <property name="activates_default">True</property>
-          </object>
-          <packing>
-            <property name="left_attach">1</property>
-            <property name="top_attach">5</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkCheckButton" id="show_checkbutton_eaptls">
-            <property name="label" translatable="yes">Sho_w password</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">False</property>
-            <property name="halign">start</property>
-            <property name="hexpand">True</property>
-            <property name="use_underline">True</property>
-            <property name="draw_indicator">True</property>
-          </object>
-          <packing>
-            <property name="left_attach">1</property>
-            <property name="top_attach">6</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkFileChooserButton" id="eap_tls_user_cert_button">
-            <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="eap_tls_user_cert_label">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="label" translatable="yes">_User certificate:</property>
-            <property name="use_underline">True</property>
-            <property name="mnemonic_widget">eap_tls_user_cert_button</property>
-            <property name="xalign">0</property>
-          </object>
-          <packing>
-            <property name="left_attach">0</property>
-            <property name="top_attach">1</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkLabel" id="eap_tls_ca_cert_label">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="label" translatable="yes">C_A certificate:</property>
-            <property name="use_underline">True</property>
-            <property name="mnemonic_widget">eap_tls_ca_cert_button</property>
-            <property name="xalign">0</property>
-          </object>
-          <packing>
-            <property name="left_attach">0</property>
-            <property name="top_attach">2</property>
-          </packing>
+          <placeholder/>
         </child>
         <child>
-          <object class="GtkLabel" id="eap_tls_private_key_label">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="label" translatable="yes">Private _key:</property>
-            <property name="use_underline">True</property>
-            <property name="mnemonic_widget">eap_tls_private_key_button</property>
-            <property name="xalign">0</property>
-          </object>
-          <packing>
-            <property name="left_attach">0</property>
-            <property name="top_attach">4</property>
-          </packing>
+          <placeholder/>
         </child>
         <child>
-          <object class="GtkLabel" id="eap_tls_private_key_password_label">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="label" translatable="yes">_Private key password:</property>
-            <property name="use_underline">True</property>
-            <property name="mnemonic_widget">eap_tls_private_key_password_entry</property>
-            <property name="xalign">0</property>
-          </object>
-          <packing>
-            <property name="left_attach">0</property>
-            <property name="top_attach">5</property>
-          </packing>
+          <placeholder/>
         </child>
         <child>
           <placeholder/>
diff --git a/src/wireless-security/eap-method-ttls.c b/src/wireless-security/eap-method-ttls.c
index 2d9de48..2598cb4 100644
--- a/src/wireless-security/eap-method-ttls.c
+++ b/src/wireless-security/eap-method-ttls.c
@@ -35,6 +35,7 @@
 struct _EAPMethodTTLS {
        EAPMethod parent;
 
+       const char *password_flags_name;
        GtkSizeGroup *size_group;
        WirelessSecurity *sec_parent;
        gboolean is_editor;
@@ -130,7 +131,7 @@ add_to_size_group (EAPMethod *parent, GtkSizeGroup *group)
 }
 
 static void
-fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFlags flags)
+fill_connection (EAPMethod *parent, NMConnection *connection)
 {
        NMSetting8021x *s_8021x;
        NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
@@ -171,7 +172,7 @@ fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFla
        gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1);
        g_assert (eap);
 
-       eap_method_fill_connection (eap, connection, flags);
+       eap_method_fill_connection (eap, connection);
        eap_method_unref (eap);
 }
 
@@ -405,8 +406,8 @@ eap_method_ttls_new (WirelessSecurity *ws_parent,
        if (!parent)
                return NULL;
 
-       parent->password_flags_name = NM_SETTING_802_1X_PASSWORD;
        method = (EAPMethodTTLS *) parent;
+       method->password_flags_name = NM_SETTING_802_1X_PASSWORD;
        method->sec_parent = ws_parent;
        method->is_editor = is_editor;
 
diff --git a/src/wireless-security/eap-method.c b/src/wireless-security/eap-method.c
index c92eb7c..b25fbe1 100644
--- a/src/wireless-security/eap-method.c
+++ b/src/wireless-security/eap-method.c
@@ -70,14 +70,13 @@ eap_method_add_to_size_group (EAPMethod *method, GtkSizeGroup *group)
 
 void
 eap_method_fill_connection (EAPMethod *method,
-                            NMConnection *connection,
-                            NMSettingSecretFlags flags)
+                            NMConnection *connection)
 {
        g_return_if_fail (method != NULL);
        g_return_if_fail (connection != NULL);
 
        g_assert (method->fill_connection);
-       return (*(method->fill_connection)) (method, connection, flags);
+       return (*(method->fill_connection)) (method, connection);
 }
 
 void
diff --git a/src/wireless-security/eap-method.h b/src/wireless-security/eap-method.h
index eee91b6..333fa14 100644
--- a/src/wireless-security/eap-method.h
+++ b/src/wireless-security/eap-method.h
@@ -26,7 +26,7 @@
 typedef struct _EAPMethod EAPMethod;
 
 typedef void        (*EMAddToSizeGroupFunc) (EAPMethod *method, GtkSizeGroup *group);
-typedef void        (*EMFillConnectionFunc) (EAPMethod *method, NMConnection *connection, 
NMSettingSecretFlags flags);
+typedef void        (*EMFillConnectionFunc) (EAPMethod *method, NMConnection *connection);
 typedef void        (*EMUpdateSecretsFunc)  (EAPMethod *method, NMConnection *connection);
 typedef void        (*EMDestroyFunc)        (EAPMethod *method);
 typedef gboolean    (*EMValidateFunc)       (EAPMethod *method, GError **error);
@@ -39,7 +39,6 @@ struct _EAPMethod {
        GtkWidget *ui_widget;
 
        const char *default_field;
-       const char *password_flags_name;
 
        gboolean phase2;
        gboolean secrets_only;
@@ -61,8 +60,7 @@ gboolean eap_method_validate (EAPMethod *method, GError **error);
 void eap_method_add_to_size_group (EAPMethod *method, GtkSizeGroup *group);
 
 void eap_method_fill_connection (EAPMethod *method,
-                                 NMConnection *connection,
-                                 NMSettingSecretFlags flags);
+                                 NMConnection *connection);
 
 void eap_method_update_secrets (EAPMethod *method, NMConnection *connection);
 
diff --git a/src/wireless-security/wireless-security.c b/src/wireless-security/wireless-security.c
index e88e503..bdaa825 100644
--- a/src/wireless-security/wireless-security.c
+++ b/src/wireless-security/wireless-security.c
@@ -524,7 +524,6 @@ ws_802_1x_fill_connection (WirelessSecurity *sec,
        GtkWidget *widget;
        NMSettingWirelessSecurity *s_wireless_sec;
        NMSetting8021x *s_8021x;
-       NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE;
        EAPMethod *eap = NULL;
        GtkTreeModel *model;
        GtkTreeIter iter;
@@ -536,13 +535,6 @@ ws_802_1x_fill_connection (WirelessSecurity *sec,
        gtk_tree_model_get (model, &iter, AUTH_METHOD_COLUMN, &eap, -1);
        g_assert (eap);
 
-       /* Get previous pasword flags, if any. Otherwise default to agent-owned secrets */
-       s_8021x = nm_connection_get_setting_802_1x (connection);
-       if (s_8021x)
-               nm_setting_get_secret_flags (NM_SETTING (s_8021x), eap->password_flags_name, &secret_flags, 
NULL);
-       else
-               secret_flags = NM_SETTING_SECRET_FLAG_AGENT_OWNED;
-
        /* Blow away the old wireless security setting by adding a clear one */
        s_wireless_sec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
        nm_connection_add_setting (connection, (NMSetting *) s_wireless_sec);
@@ -551,7 +543,7 @@ ws_802_1x_fill_connection (WirelessSecurity *sec,
        s_8021x = (NMSetting8021x *) nm_setting_802_1x_new ();
        nm_connection_add_setting (connection, (NMSetting *) s_8021x);
 
-       eap_method_fill_connection (eap, connection, secret_flags);
+       eap_method_fill_connection (eap, connection);
        eap_method_unref (eap);
 }
 


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