[network-manager-applet/lr/pkcs11: 4/9] wireless-security: pass around scheme for certificates along with the value



commit 85d265a4bb840bca0228bd40293c91acd1f61f63
Author: Lubomir Rintel <lkundrak v3 sk>
Date:   Fri Feb 17 19:01:01 2017 +0000

    wireless-security: pass around scheme for certificates along with the value
    
    Remove the assumptions everything is a PATH. In fact, it is, because the
    GtkFilePicker can only return a path, but we'll eventually replace it with a
    picker that can use PKCS#11 tokens.

 src/wireless-security/eap-method-tls.c |   99 ++++++++++++++++++++------------
 src/wireless-security/eap-method.c     |   36 ++++++++---
 src/wireless-security/eap-method.h     |    3 +
 3 files changed, 91 insertions(+), 47 deletions(-)
---
diff --git a/src/wireless-security/eap-method-tls.c b/src/wireless-security/eap-method-tls.c
index 8d17fa4..f5cd474 100644
--- a/src/wireless-security/eap-method-tls.c
+++ b/src/wireless-security/eap-method-tls.c
@@ -173,10 +173,11 @@ fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFla
        NMSetting8021x *s_8021x;
        NMSettingSecretFlags secret_flags;
        GtkWidget *widget, *passwd_entry;
-       char *ca_filename, *pk_filename, *cc_filename;
+       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);
@@ -199,21 +200,21 @@ fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFla
 
        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);
+       value = eap_method_filepicker_get_value (GTK_FILE_CHOOSER (widget), &scheme);
+       g_assert (value);
 
        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);
+       g_free (value);
 
        /* Save 802.1X password flags to the connection */
        secret_flags = nma_utils_menu_to_secret_flags (passwd_entry);
@@ -233,49 +234,49 @@ fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFla
                 */
                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 = eap_method_filepicker_get_value (GTK_FILE_CHOOSER (widget), &scheme);
+               g_assert (value);
 
                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 = eap_method_filepicker_get_value (GTK_FILE_CHOOSER (widget), &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)
+private_key_picker_helper (EAPMethod *parent, const char *value, NMSetting8021xCKScheme scheme, gboolean 
changed)
 {
        NMSetting8021x *setting;
        NMSetting8021xCKFormat cert_format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
@@ -287,7 +288,7 @@ private_key_picker_helper (EAPMethod *parent, const char *filename, gboolean cha
        password = gtk_entry_get_text (GTK_ENTRY (widget));
 
        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);
+       nm_setting_802_1x_set_private_key (setting, value, password, scheme, &cert_format, NULL);
        g_object_unref (setting);
 
        /* With PKCS#12, the client cert must be the same as the private key */
@@ -299,7 +300,7 @@ private_key_picker_helper (EAPMethod *parent, const char *filename, gboolean cha
                gtk_widget_set_sensitive (widget, TRUE);
 
        /* Warn the user if the private key is unencrypted */
-       if (!eap_method_is_encrypted_private_key (filename)) {
+       if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH && !eap_method_is_encrypted_private_key (value)) {
                GtkWidget *dialog;
                GtkWidget *toplevel;
                GtkWindow *parent_window = NULL;
@@ -326,12 +327,14 @@ static void
 private_key_picker_file_set_cb (GtkWidget *chooser, gpointer user_data)
 {
        EAPMethod *parent = (EAPMethod *) user_data;
-       char *filename;
+       NMSetting8021xCKScheme scheme;
+       char *value;
 
-       filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
-       if (filename)
-               private_key_picker_helper (parent, filename, TRUE);
-       g_free (filename);
+       value = eap_method_filepicker_get_value (GTK_FILE_CHOOSER (chooser), &scheme);
+       if (value)
+               private_key_picker_helper (parent, value, scheme, FALSE);
+
+       g_free (value);
 }
 
 static void reset_filter (GtkWidget *widget, GParamSpec *spec, gpointer user_data)
@@ -344,6 +347,7 @@ static void reset_filter (GtkWidget *widget, GParamSpec *spec, gpointer user_dat
 }
 
 typedef const char * (*PathFunc) (NMSetting8021x *setting);
+typedef const char * (*UriFunc) (NMSetting8021x *setting);
 typedef NMSetting8021xCKScheme (*SchemeFunc)  (NMSetting8021x *setting);
 
 static void
@@ -355,12 +359,14 @@ setup_filepicker (GtkBuilder *builder,
                   NMSetting8021x *s_8021x,
                   SchemeFunc scheme_func,
                   PathFunc path_func,
+                  UriFunc uri_func,
                   gboolean privkey,
                   gboolean client_cert)
 {
        GtkWidget *widget;
        GtkFileFilter *filter;
-       const char *filename = NULL;
+       NMSetting8021xCKScheme scheme = NM_SETTING_802_1X_CK_SCHEME_UNKNOWN;
+       const char *value = NULL;
 
        widget = GTK_WIDGET (gtk_builder_get_object (builder, name));
        g_assert (widget);
@@ -368,10 +374,16 @@ setup_filepicker (GtkBuilder *builder,
        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);
+               scheme = scheme_func (s_8021x);
+               switch (scheme) {
+               case NM_SETTING_802_1X_CK_SCHEME_PATH:
+                       value = path_func (s_8021x);
+                       if (value)
+                               gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), value);
+                       break;
+               default:
+                       g_warning ("don't know how to set %s to a value of unknown scheme %d",
+                                  name, scheme);
                }
        }
 
@@ -382,8 +394,8 @@ setup_filepicker (GtkBuilder *builder,
                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);
+               if (value)
+                       private_key_picker_helper (parent, value, scheme, FALSE);
        }
 
        g_signal_connect (G_OBJECT (widget), "selection-changed",
@@ -440,6 +452,16 @@ update_secrets (EAPMethod *parent, NMConnection *connection)
        }
 }
 
+#ifndef NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PKCS11
+/* Not available in libnm-glib */
+#define nm_setting_802_1x_get_phase2_client_cert_uri   NULL
+#define nm_setting_802_1x_get_client_cert_uri          NULL
+#define nm_setting_802_1x_get_phase2_ca_cert_uri       NULL
+#define nm_setting_802_1x_get_ca_cert_uri              NULL
+#define nm_setting_802_1x_get_phase2_private_key_uri   NULL
+#define nm_setting_802_1x_get_private_key_uri          NULL
+#endif
+
 EAPMethodTLS *
 eap_method_tls_new (WirelessSecurity *ws_parent,
                     NMConnection *connection,
@@ -496,18 +518,21 @@ eap_method_tls_new (WirelessSecurity *ws_parent,
                          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,
+                         phase2 ? nm_setting_802_1x_get_phase2_client_cert_uri : 
nm_setting_802_1x_get_client_cert_uri,
                          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,
+                         phase2 ? nm_setting_802_1x_get_phase2_ca_cert_uri : 
nm_setting_802_1x_get_ca_cert_uri,
                          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,
+                         phase2 ? nm_setting_802_1x_get_phase2_private_key_uri : 
nm_setting_802_1x_get_private_key_uri,
                          TRUE, FALSE);
 
        if (connection && eap_method_ca_cert_ignore_get (parent, connection)) {
diff --git a/src/wireless-security/eap-method.c b/src/wireless-security/eap-method.c
index cb733e8..7cc0eb7 100644
--- a/src/wireless-security/eap-method.c
+++ b/src/wireless-security/eap-method.c
@@ -206,6 +206,17 @@ eap_method_unref (EAPMethod *method)
        }
 }
 
+char *
+eap_method_filepicker_get_value (GtkFileChooser *chooser, NMSetting8021xCKScheme *scheme)
+{
+       char *value;
+
+       value = gtk_file_chooser_get_uri (chooser);
+
+       *scheme = NM_SETTING_802_1X_CK_SCHEME_PATH;
+       return gtk_file_chooser_get_filename (chooser);
+}
+
 gboolean
 eap_method_validate_filepicker (GtkBuilder *builder,
                                 const char *name,
@@ -215,9 +226,10 @@ eap_method_validate_filepicker (GtkBuilder *builder,
                                 GError **error)
 {
        GtkWidget *widget;
-       char *filename;
+       char *value;
        NMSetting8021x *setting;
        gboolean success = TRUE;
+       NMSetting8021xCKScheme scheme = NM_SETTING_802_1X_CK_SCHEME_UNKNOWN;
 
        if (item_type == TYPE_PRIVATE_KEY) {
                if (!password || *password == '\0')
@@ -226,8 +238,10 @@ eap_method_validate_filepicker (GtkBuilder *builder,
 
        widget = GTK_WIDGET (gtk_builder_get_object (builder, name));
        g_assert (widget);
-       filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
-       if (!filename) {
+
+       value = eap_method_filepicker_get_value (GTK_FILE_CHOOSER (widget), &scheme);
+
+       if (!value) {
                if (item_type != TYPE_CA_CERT) {
                        success = FALSE;
                        g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("no file selected"));
@@ -235,22 +249,24 @@ eap_method_validate_filepicker (GtkBuilder *builder,
                goto out;
        }
 
-       if (!g_file_test (filename, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) {
-               success = FALSE;
-               goto out;
+       if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) {
+               if (g_file_test (value, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) {
+                       success = FALSE;
+                       goto out;
+               }
        }
 
        setting = (NMSetting8021x *) nm_setting_802_1x_new ();
 
        success = FALSE;
        if (item_type == TYPE_PRIVATE_KEY) {
-               if (nm_setting_802_1x_set_private_key (setting, filename, password, 
NM_SETTING_802_1X_CK_SCHEME_PATH, out_format, error))
+               if (nm_setting_802_1x_set_private_key (setting, value, password, scheme, out_format, error))
                        success = TRUE;
        } else if (item_type == TYPE_CLIENT_CERT) {
-               if (nm_setting_802_1x_set_client_cert (setting, filename, NM_SETTING_802_1X_CK_SCHEME_PATH, 
out_format, error))
+               if (nm_setting_802_1x_set_client_cert (setting, value, scheme, out_format, error))
                        success = TRUE;
        } else if (item_type == TYPE_CA_CERT) {
-               if (nm_setting_802_1x_set_ca_cert (setting, filename, NM_SETTING_802_1X_CK_SCHEME_PATH, 
out_format, error))
+               if (nm_setting_802_1x_set_ca_cert (setting, value, scheme, out_format, error))
                        success = TRUE;
        } else
                g_warning ("%s: invalid item type %d.", __func__, item_type);
@@ -258,7 +274,7 @@ eap_method_validate_filepicker (GtkBuilder *builder,
        g_object_unref (setting);
 
 out:
-       g_free (filename);
+       g_free (value);
 
        if (!success && error && !*error)
                g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("unspecified error validating 
eap-method file"));
diff --git a/src/wireless-security/eap-method.h b/src/wireless-security/eap-method.h
index eee91b6..a85e083 100644
--- a/src/wireless-security/eap-method.h
+++ b/src/wireless-security/eap-method.h
@@ -96,6 +96,9 @@ GtkFileFilter * eap_method_default_file_chooser_filter_new (gboolean privkey);
 
 gboolean eap_method_is_encrypted_private_key (const char *path);
 
+char *eap_method_filepicker_get_value (GtkFileChooser *chooser,
+                                       NMSetting8021xCKScheme *scheme);
+
 #define TYPE_CLIENT_CERT 0
 #define TYPE_CA_CERT     1
 #define TYPE_PRIVATE_KEY 2


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