[libnma/lr/gtk-4.0: 18/22] cert-chooser: fold file & pkcs11 choosers together




commit f70e84e316e3a879b6f2ada0fc974dc30e275ecf
Author: Lubomir Rintel <lkundrak v3 sk>
Date:   Mon Oct 11 10:26:58 2021 +0200

    cert-chooser: fold file & pkcs11 choosers together
    
    With GtkFileChooserButton gone from Gtk4, the NmaFileCertChooser lost
    its point. With better support for plain PEM files in NmaCertChooserButton,
    the NmaPkcs11CertChooser can replace it completely.
    
    Let's drop the machinery for providing different implementations of
    NmaFileCertChooser logic and keep what used to be NmaPkcs11CertChooser.

 Makefile.am                    |  10 +-
 meson.build                    |   1 -
 po/POTFILES.in                 |   2 -
 src/meson.build                |  14 +-
 src/nma-cert-chooser-private.h | 145 ---------
 src/nma-cert-chooser.c         | 655 ++++++++++++++++++++++++++++++++---------
 src/nma-file-cert-chooser.c    | 463 -----------------------------
 src/nma-pkcs11-cert-chooser.c  | 559 -----------------------------------
 8 files changed, 525 insertions(+), 1324 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 07e283f0..0edb36d0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -186,7 +186,6 @@ libnma_c_real = \
        src/init.c \
        src/nma-cert-chooser.c \
        src/nma-cert-chooser-button.c \
-       src/nma-file-cert-chooser.c \
        src/nma-bar-code-widget.c \
        src/nma-bar-code.c \
        \
@@ -213,7 +212,6 @@ EXTRA_DIST += \
        src/qrcodegen.h
 
 libnma_h_priv_real = \
-       src/nma-cert-chooser-private.h \
        src/nma-private.h \
        src/nma-ws/nma-eap-fast.h \
        src/nma-ws/nma-eap-leap.h \
@@ -234,8 +232,7 @@ libnma_h_priv_gcr = \
 
 libnma_c_gcr = \
        src/nma-pkcs11-token-login-dialog.c \
-       src/nma-pkcs11-cert-chooser-dialog.c \
-       src/nma-pkcs11-cert-chooser.c
+       src/nma-pkcs11-cert-chooser-dialog.c
 
 src_libnmadir = $(includedir)/libnma
 
@@ -760,7 +757,6 @@ CFILE_GLOB = $(top_srcdir)/src/*.c
 IGNORE_HFILES = \
        nma-resources.h \
        nma-version.h \
-       nma-cert-chooser-private.h \
        nma-private.h \
        nma-pkcs11-token-login-dialog.h \
        nma-pkcs11-cert-chooser-dialog.h \
@@ -769,11 +765,9 @@ IGNORE_HFILES = \
 
 mkdb_ignore_c_files = \
        nma-resources.c \
-       nma-file-cert-chooser.c \
        nma-pkcs11-token-login-dialog.c \
        nma-pkcs11-cert-chooser-dialog.c \
-       nma-cert-chooser-button.c \
-       nma-pkcs11-cert-chooser.c
+       nma-cert-chooser-button.c
 
 MKDB_OPTIONS = --ignore-files "$(IGNORE_HFILES) $(mkdb_ignore_c_files)"
 
diff --git a/meson.build b/meson.build
index 58b54a1f..1ef88aaf 100644
--- a/meson.build
+++ b/meson.build
@@ -306,7 +306,6 @@ if enable_gtk_doc
 
   private_headers = [
     'nma-cert-chooser-button.h',
-    'nma-cert-chooser-private.h',
     'nma-pkcs11-cert-chooser-dialog.h',
     'nma-pkcs11-token-login-dialog.h',
     'nma-resources.h',
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 2ed2ff93..8a3b2136 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -5,13 +5,11 @@ shared/nm-utils/nm-shared-utils.c
 src/nma-bar-code-widget.c
 src/nma-bar-code-widget.ui
 src/nma-cert-chooser-button.c
-src/nma-file-cert-chooser.c
 src/nma-mobile-providers.c
 src/nma-mobile-wizard.c
 src/nma-mobile-wizard.ui
 src/nma-pkcs11-cert-chooser-dialog.c
 src/nma-pkcs11-cert-chooser-dialog.ui
-src/nma-pkcs11-cert-chooser.c
 src/nma-pkcs11-token-login-dialog.c
 src/nma-pkcs11-token-login-dialog.ui
 src/nma-ui-utils.c
diff --git a/src/meson.build b/src/meson.build
index 72bcafdf..2064ddb0 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -17,13 +17,6 @@ version_header = configure_file(
 subdir('utils')
 subdir('nma-ws')
 
-cert_chooser_headers = files('nma-cert-chooser.h')
-
-cert_chooser_sources = files(
-  'nma-cert-chooser.c',
-  'nma-file-cert-chooser.c'
-)
-
 resource_data = nma_ws_resource_data + files(
   'nma-bar-code-widget.ui',
   'nma-mobile-wizard.ui',
@@ -39,9 +32,10 @@ built_sources = gnome.compile_resources(
   dependencies: resource_data
 )
 
-gir_headers = cert_chooser_headers + nma_ws_headers + files(
+gir_headers = nma_ws_headers + files(
   'nma-bar-code-widget.h',
   'nma-bar-code.h',
+  'nma-cert-chooser.h',
   'nma-mobile-providers.h',
   'nma-mobile-wizard.h',
   'nma-ui-utils.h',
@@ -54,10 +48,11 @@ install_headers(
   subdir: 'libnma'
 )
 
-gir_sources = [version_header] + cert_chooser_sources + nma_ws_sources + files(
+gir_sources = [version_header] + nma_ws_sources + files(
   'init.c',
   'nma-bar-code-widget.c',
   'nma-bar-code.c',
+  'nma-cert-chooser.c',
   'nma-cert-chooser-button.c',
   'nma-mobile-providers.c',
   'nma-mobile-wizard.c',
@@ -95,7 +90,6 @@ nma_deps = [ deps, gtk_dep ]
 nma_sources = [ gir_sources, built_sources ]
 if enable_gcr
   nma_sources += files(
-    'nma-pkcs11-cert-chooser.c',
     'nma-pkcs11-cert-chooser-dialog.c',
     'nma-pkcs11-token-login-dialog.c'
   )
diff --git a/src/nma-cert-chooser.c b/src/nma-cert-chooser.c
index 79e0d6b5..8eec3301 100644
--- a/src/nma-cert-chooser.c
+++ b/src/nma-cert-chooser.c
@@ -3,13 +3,77 @@
  *
  * Lubomir Rintel <lkundrak v3 sk>
  *
- * Copyright (C) 2017 Red Hat, Inc.
+ * Copyright (C) 2017,2021 Red Hat, Inc.
  */
 
 #include "nm-default.h"
+#include "nma-private.h"
+
+#include "nma-ui-utils.h"
 #include "nma-cert-chooser.h"
+#include "nma-cert-chooser-button.h"
+#include "utils.h"
+
+#if GTK_CHECK_VERSION(4,0,0)
+#define gtk3_widget_set_no_show_all(widget, show)
+#else
+#define gtk3_widget_set_no_show_all(widget, show) gtk_widget_set_no_show_all (widget, show);
+#endif
 
-#include "nma-cert-chooser-private.h"
+#ifdef GCK
+#include <gck/gck.h>
+#else
+typedef void GckAttribute;
+typedef void GckAttributes;
+typedef int GckUriFlags;
+typedef struct {
+       GckAttributes *attributes;
+} GckUriData;
+
+#define GCK_URI_FOR_OBJECT 0
+#define CKA_CLASS 0
+
+static GckUriData *
+gck_uri_parse (const gchar *string, GckUriFlags flags, GError **error)
+{
+       return NULL;
+}
+
+static const GckAttribute *
+gck_attributes_find (GckAttributes *attrs, gulong attr_type)
+{
+       return NULL;
+}
+
+static void
+gck_uri_data_free (GckUriData *uri_data)
+{
+}
+#endif
+
+typedef struct {
+        GtkWidget *key_button_label;
+        GtkWidget *key_password_label;
+        GtkWidget *cert_button_label;
+        GtkWidget *cert_password_label;
+        GtkWidget *key_button;
+        GtkWidget *key_password;
+        GtkWidget *cert_button;
+        GtkWidget *cert_password;
+        GtkWidget *show_password;
+
+       NMACertChooserFlags flags;
+       char *title;
+} NMACertChooserPrivate;
+
+struct _NMACertChooser {
+        GtkGrid parent;
+        NMACertChooserPrivate _priv;
+};
+
+struct _NMACertChooserClass {
+        GtkGridClass parent_class;
+};
 
 /**
  * SECTION:nma-cert-chooser
@@ -47,13 +111,6 @@ static guint signals[LAST_SIGNAL] = { 0 };
 G_DEFINE_TYPE (NMACertChooser, nma_cert_chooser, GTK_TYPE_GRID)
 
 #define NMA_CERT_CHOOSER_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMACertChooser, NMA_IS_CERT_CHOOSER)
-#define NMA_CERT_CHOOSER_GET_VTABLE(o) (NMA_CERT_CHOOSER_GET_PRIVATE (o)->vtable)
-
-/*****************************************************************************/
-
-static void _chooser_clear_cert (NMACertChooser *cert_chooser);
-
-/*****************************************************************************/
 
 static gboolean
 accu_validation_error (GSignalInvocationHint *ihint,
@@ -116,13 +173,26 @@ void
 nma_cert_chooser_set_cert_uri (NMACertChooser *cert_chooser,
                                const gchar *uri)
 {
+       NMACertChooserPrivate *priv;
+
        g_return_if_fail (NMA_IS_CERT_CHOOSER (cert_chooser));
+       priv = NMA_CERT_CHOOSER_GET_PRIVATE (cert_chooser);
 
-       if (!uri) {
-               _chooser_clear_cert (cert_chooser);
+       if (uri == NULL || g_str_has_prefix (uri, NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH)) {
+               gtk_widget_set_sensitive (priv->cert_password, FALSE);
+               gtk_widget_set_sensitive (priv->cert_password_label, FALSE);
+       } else if (g_str_has_prefix (uri, NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PKCS11)) {
+               gtk_widget_set_sensitive (priv->cert_password, TRUE);
+               gtk_widget_set_sensitive (priv->cert_password_label, TRUE);
+               gtk_widget_show (priv->cert_password);
+               gtk_widget_show (priv->cert_password_label);
+               gtk_widget_show (priv->show_password);
+       } else {
+               g_warning ("The certificate '%s' uses an unknown scheme\n", uri);
                return;
        }
-       NMA_CERT_CHOOSER_GET_VTABLE (cert_chooser)->set_cert_uri (cert_chooser, uri);
+
+       nma_cert_chooser_button_set_uri (NMA_CERT_CHOOSER_BUTTON (priv->cert_button), uri);
 }
 
 /**
@@ -144,12 +214,8 @@ nma_cert_chooser_set_cert (NMACertChooser *cert_chooser,
 
        g_return_if_fail (NMA_IS_CERT_CHOOSER (cert_chooser));
 
-       if (!value) {
-               _chooser_clear_cert (cert_chooser);
-               return;
-       }
-
-       uri = value_with_scheme_to_uri (value, scheme);
+       if (value)
+               uri = value_with_scheme_to_uri (value, scheme);
        nma_cert_chooser_set_cert_uri (cert_chooser, uri);
 }
 
@@ -166,9 +232,12 @@ nma_cert_chooser_set_cert (NMACertChooser *cert_chooser,
 gchar *
 nma_cert_chooser_get_cert_uri (NMACertChooser *cert_chooser)
 {
+       NMACertChooserPrivate *priv;
+
        g_return_val_if_fail (NMA_IS_CERT_CHOOSER (cert_chooser), NULL);
+       priv = NMA_CERT_CHOOSER_GET_PRIVATE (cert_chooser);
 
-       return NMA_CERT_CHOOSER_GET_VTABLE (cert_chooser)->get_cert_uri (cert_chooser);
+       return g_strdup (nma_cert_chooser_button_get_uri (NMA_CERT_CHOOSER_BUTTON (priv->cert_button)));
 }
 
 /**
@@ -205,16 +274,15 @@ nma_cert_chooser_get_cert (NMACertChooser *cert_chooser, NMSetting8021xCKScheme
 void
 nma_cert_chooser_set_cert_password (NMACertChooser *cert_chooser, const gchar *password)
 {
-       const NMACertChooserVtable *vtable;
+       NMACertChooserPrivate *priv;
 
        g_return_if_fail (NMA_IS_CERT_CHOOSER (cert_chooser));
        g_return_if_fail (password);
+       priv = NMA_CERT_CHOOSER_GET_PRIVATE (cert_chooser);
 
-       vtable = NMA_CERT_CHOOSER_GET_VTABLE (cert_chooser);
-       if (vtable->set_cert_password)
-               vtable->set_cert_password (cert_chooser, password);
-       else
-               g_warning ("Can't set certificate password");
+       g_return_if_fail (priv->cert_password != NULL);
+       if (password)
+               gtk_editable_set_text (GTK_EDITABLE (priv->cert_password), password);
 }
 
 /**
@@ -230,40 +298,16 @@ nma_cert_chooser_set_cert_password (NMACertChooser *cert_chooser, const gchar *p
 const gchar *
 nma_cert_chooser_get_cert_password (NMACertChooser *cert_chooser)
 {
-       const NMACertChooserVtable *vtable;
+       NMACertChooserPrivate *priv;
+       const gchar *text;
 
        g_return_val_if_fail (NMA_IS_CERT_CHOOSER (cert_chooser), NULL);
+       priv = NMA_CERT_CHOOSER_GET_PRIVATE (cert_chooser);
 
-       vtable = NMA_CERT_CHOOSER_GET_VTABLE (cert_chooser);
-       if (!vtable->get_cert_password)
-               return NULL;
-       return vtable->get_cert_password (cert_chooser);
-}
-
-static void
-_chooser_clear_cert (NMACertChooser *cert_chooser)
-{
-       const NMACertChooserVtable *vtable;
-
-       g_return_if_fail (NMA_IS_CERT_CHOOSER (cert_chooser));
-
-       vtable = NMA_CERT_CHOOSER_GET_VTABLE (cert_chooser);
-       if (vtable->clear_cert)
-               vtable->clear_cert (cert_chooser);
-}
-
-
-static void
-_chooser_clear_key (NMACertChooser *cert_chooser)
-{
-       const NMACertChooserVtable *vtable;
-
-       g_return_if_fail (NMA_IS_CERT_CHOOSER (cert_chooser));
+       g_return_val_if_fail (priv->cert_password != NULL, NULL);
+       text = gtk_editable_get_text (GTK_EDITABLE (priv->cert_password));
 
-       vtable = NMA_CERT_CHOOSER_GET_VTABLE (cert_chooser);
-       if (vtable->clear_key)
-               vtable->clear_key (cert_chooser);
-       nma_cert_chooser_set_cert_password (cert_chooser, "");
+       return text && text[0] ? text : NULL;
 }
 
 /**
@@ -279,14 +323,26 @@ void
 nma_cert_chooser_set_key_uri (NMACertChooser *cert_chooser,
                               const gchar *uri)
 {
+       NMACertChooserPrivate *priv;
+
        g_return_if_fail (NMA_IS_CERT_CHOOSER (cert_chooser));
+       priv = NMA_CERT_CHOOSER_GET_PRIVATE (cert_chooser);
 
-       if (!uri) {
-               _chooser_clear_key (cert_chooser);
-               return;
+       if (uri) {
+               gtk_widget_set_sensitive (priv->key_button, TRUE);
+               gtk_widget_set_sensitive (priv->key_button_label, TRUE);
+               gtk_widget_set_sensitive (priv->key_password, TRUE);
+               gtk_widget_set_sensitive (priv->key_password_label, TRUE);
+               gtk_widget_show (priv->key_password);
+               gtk_widget_show (priv->key_password_label);
+               gtk_widget_show (priv->show_password);
+       } else {
+               gtk_widget_set_sensitive (priv->key_password, FALSE);
+               gtk_widget_set_sensitive (priv->key_password_label, FALSE);
+               nma_cert_chooser_set_cert_password (cert_chooser, "");
        }
 
-       NMA_CERT_CHOOSER_GET_VTABLE (cert_chooser)->set_key_uri (cert_chooser, uri);
+       nma_cert_chooser_button_set_uri (NMA_CERT_CHOOSER_BUTTON (priv->key_button), uri);
 }
 
 /**
@@ -308,12 +364,8 @@ nma_cert_chooser_set_key (NMACertChooser *cert_chooser,
 
        g_return_if_fail (NMA_IS_CERT_CHOOSER (cert_chooser));
 
-       if (!value) {
-               _chooser_clear_key (cert_chooser);
-               return;
-       }
-
-       uri = value_with_scheme_to_uri (value, scheme);
+       if (value)
+               uri = value_with_scheme_to_uri (value, scheme);
        nma_cert_chooser_set_key_uri (cert_chooser, uri);
 }
 
@@ -352,9 +404,12 @@ nma_cert_chooser_get_key (NMACertChooser *cert_chooser, NMSetting8021xCKScheme *
 gchar *
 nma_cert_chooser_get_key_uri (NMACertChooser *cert_chooser)
 {
+       NMACertChooserPrivate *priv;
+
        g_return_val_if_fail (NMA_IS_CERT_CHOOSER (cert_chooser), NULL);
+       priv = NMA_CERT_CHOOSER_GET_PRIVATE (cert_chooser);
 
-       return NMA_CERT_CHOOSER_GET_VTABLE (cert_chooser)->get_key_uri (cert_chooser);
+       return g_strdup (nma_cert_chooser_button_get_uri (NMA_CERT_CHOOSER_BUTTON (priv->key_button)));
 }
 
 /**
@@ -369,10 +424,15 @@ nma_cert_chooser_get_key_uri (NMACertChooser *cert_chooser)
 void
 nma_cert_chooser_set_key_password (NMACertChooser *cert_chooser, const gchar *password)
 {
+       NMACertChooserPrivate *priv;
+
        g_return_if_fail (NMA_IS_CERT_CHOOSER (cert_chooser));
        g_return_if_fail (password);
+       priv = NMA_CERT_CHOOSER_GET_PRIVATE (cert_chooser);
 
-       NMA_CERT_CHOOSER_GET_VTABLE (cert_chooser)->set_key_password (cert_chooser, password);
+       g_return_if_fail (priv->key_password != NULL);
+       if (password)
+               gtk_editable_set_text (GTK_EDITABLE (priv->key_password), password);
 }
 
 /**
@@ -388,9 +448,16 @@ nma_cert_chooser_set_key_password (NMACertChooser *cert_chooser, const gchar *pa
 const gchar *
 nma_cert_chooser_get_key_password (NMACertChooser *cert_chooser)
 {
+       NMACertChooserPrivate *priv;
+       const gchar *text;
+
        g_return_val_if_fail (NMA_IS_CERT_CHOOSER (cert_chooser), NULL);
+       priv = NMA_CERT_CHOOSER_GET_PRIVATE (cert_chooser);
 
-       return NMA_CERT_CHOOSER_GET_VTABLE (cert_chooser)->get_key_password (cert_chooser);
+       g_return_val_if_fail (priv->key_password != NULL, NULL);
+       text = gtk_editable_get_text (GTK_EDITABLE (priv->key_password));
+
+       return text && text[0] ? text : NULL;
 }
 
 /**
@@ -409,9 +476,15 @@ nma_cert_chooser_get_key_password (NMACertChooser *cert_chooser)
 void
 nma_cert_chooser_add_to_size_group (NMACertChooser *cert_chooser, GtkSizeGroup *group)
 {
+       NMACertChooserPrivate *priv;
+
        g_return_if_fail (NMA_IS_CERT_CHOOSER (cert_chooser));
+       priv = NMA_CERT_CHOOSER_GET_PRIVATE (cert_chooser);
 
-       NMA_CERT_CHOOSER_GET_VTABLE (cert_chooser)->add_to_size_group (cert_chooser, group);
+       gtk_size_group_add_widget (group, priv->cert_button_label);
+       gtk_size_group_add_widget (group, priv->cert_password_label);
+       gtk_size_group_add_widget (group, priv->key_button_label);
+       gtk_size_group_add_widget (group, priv->key_password_label);
 }
 
 /**
@@ -430,9 +503,61 @@ nma_cert_chooser_add_to_size_group (NMACertChooser *cert_chooser, GtkSizeGroup *
 gboolean
 nma_cert_chooser_validate (NMACertChooser *cert_chooser, GError **error)
 {
+       NMACertChooserPrivate *priv;
+       GError *local = NULL;
+
        g_return_val_if_fail (NMA_IS_CERT_CHOOSER (cert_chooser), TRUE);
+       priv = NMA_CERT_CHOOSER_GET_PRIVATE (cert_chooser);
+
+       if (!nma_cert_chooser_button_get_uri (NMA_CERT_CHOOSER_BUTTON (priv->cert_button))) {
+               g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("No certificate set"));
+               return FALSE;
+       }
 
-       return NMA_CERT_CHOOSER_GET_VTABLE (cert_chooser)->validate (cert_chooser, error);
+       g_signal_emit_by_name (cert_chooser, "cert-validate", &local);
+       if (local) {
+               widget_set_error (priv->cert_button);
+               g_propagate_error (error, local);
+               return FALSE;
+       } else {
+               widget_unset_error (priv->cert_button);
+       }
+
+       g_signal_emit_by_name (cert_chooser, "cert-password-validate", &local);
+       if (local) {
+               widget_set_error (priv->cert_password);
+               g_propagate_error (error, local);
+               return FALSE;
+       } else {
+               widget_unset_error (priv->cert_password);
+       }
+
+       if (gtk_widget_get_visible (priv->key_button)) {
+               if (!nma_cert_chooser_button_get_uri (NMA_CERT_CHOOSER_BUTTON (priv->cert_button))) {
+                       g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("No key set"));
+                       return FALSE;
+               }
+
+               g_signal_emit_by_name (cert_chooser, "key-validate", &local);
+               if (local) {
+                       widget_set_error (priv->key_button);
+                       g_propagate_error (error, local);
+                       return FALSE;
+               } else {
+                       widget_unset_error (priv->key_button);
+               }
+
+               g_signal_emit_by_name (cert_chooser, "key-password-validate", &local);
+               if (local) {
+                       widget_set_error (priv->key_password);
+                       g_propagate_error (error, local);
+                       return FALSE;
+               } else {
+                       widget_unset_error (priv->key_password);
+               }
+       }
+
+       return TRUE;
 }
 
 /**
@@ -457,19 +582,17 @@ nma_cert_chooser_setup_cert_password_storage (NMACertChooser *cert_chooser,
                                               gboolean with_not_required,
                                               gboolean ask_mode)
 {
-       const NMACertChooserVtable *vtable;
+       NMACertChooserPrivate *priv;
 
        g_return_if_fail (NMA_IS_CERT_CHOOSER (cert_chooser));
+       priv = NMA_CERT_CHOOSER_GET_PRIVATE (cert_chooser);
 
-       vtable = NMA_CERT_CHOOSER_GET_VTABLE (cert_chooser);
-       if (vtable->setup_cert_password_storage) {
-               vtable->setup_cert_password_storage (cert_chooser,
-                                                    initial_flags,
-                                                    setting,
-                                                    password_flags_name,
-                                                    with_not_required,
-                                                    ask_mode);
-       }
+       nma_utils_setup_password_storage (priv->cert_password,
+                                         initial_flags,
+                                         setting,
+                                         password_flags_name,
+                                         with_not_required,
+                                         ask_mode);
 }
 
 /**
@@ -490,17 +613,15 @@ nma_cert_chooser_update_cert_password_storage (NMACertChooser *cert_chooser,
                                                NMSetting *setting,
                                                const char *password_flags_name)
 {
-       const NMACertChooserVtable *vtable;
+       NMACertChooserPrivate *priv;
 
        g_return_if_fail (NMA_IS_CERT_CHOOSER (cert_chooser));
+       priv = NMA_CERT_CHOOSER_GET_PRIVATE (cert_chooser);
 
-       vtable = NMA_CERT_CHOOSER_GET_VTABLE (cert_chooser);
-       if (vtable->update_cert_password_storage) {
-               vtable->update_cert_password_storage (cert_chooser,
-                                                     secret_flags,
-                                                     setting,
-                                                     password_flags_name);
-       }
+       nma_utils_update_password_storage (priv->cert_password,
+                                          secret_flags,
+                                          setting,
+                                          password_flags_name);
 }
 
 /**
@@ -519,18 +640,15 @@ nma_cert_chooser_update_cert_password_storage (NMACertChooser *cert_chooser,
 NMSettingSecretFlags
 nma_cert_chooser_get_cert_password_flags (NMACertChooser *cert_chooser)
 {
-       const NMACertChooserVtable *vtable;
+       NMACertChooserPrivate *priv;
 
        g_return_val_if_fail (NMA_IS_CERT_CHOOSER (cert_chooser),
                              NM_SETTING_SECRET_FLAG_NONE);
+       priv = NMA_CERT_CHOOSER_GET_PRIVATE (cert_chooser);
 
-       vtable = NMA_CERT_CHOOSER_GET_VTABLE (cert_chooser);
-       if (!vtable->get_cert_password_flags)
-               return NM_SETTING_SECRET_FLAG_NONE;
-       return vtable->get_cert_password_flags (cert_chooser);
+       return nma_utils_menu_to_secret_flags (priv->cert_password);
 }
 
-
 /**
  * nma_cert_chooser_setup_key_password_storage:
  * @cert_chooser: certificate chooser button instance
@@ -553,14 +671,17 @@ nma_cert_chooser_setup_key_password_storage (NMACertChooser *cert_chooser,
                                              gboolean with_not_required,
                                              gboolean ask_mode)
 {
+       NMACertChooserPrivate *priv;
+
        g_return_if_fail (NMA_IS_CERT_CHOOSER (cert_chooser));
+       priv = NMA_CERT_CHOOSER_GET_PRIVATE (cert_chooser);
 
-       NMA_CERT_CHOOSER_GET_VTABLE (cert_chooser)->setup_key_password_storage (cert_chooser,
-                                                                               initial_flags,
-                                                                               setting,
-                                                                               password_flags_name,
-                                                                               with_not_required,
-                                                                               ask_mode);
+       nma_utils_setup_password_storage (priv->key_password,
+                                         initial_flags,
+                                         setting,
+                                         password_flags_name,
+                                         with_not_required,
+                                         ask_mode);
 }
 
 /**
@@ -581,12 +702,15 @@ nma_cert_chooser_update_key_password_storage (NMACertChooser *cert_chooser,
                                                NMSetting *setting,
                                                const char *password_flags_name)
 {
+       NMACertChooserPrivate *priv;
+
        g_return_if_fail (NMA_IS_CERT_CHOOSER (cert_chooser));
+       priv = NMA_CERT_CHOOSER_GET_PRIVATE (cert_chooser);
 
-       NMA_CERT_CHOOSER_GET_VTABLE (cert_chooser)->update_key_password_storage (cert_chooser,
-                                                                                secret_flags,
-                                                                                setting,
-                                                                                password_flags_name);
+       nma_utils_update_password_storage (priv->key_password,
+                                          secret_flags,
+                                          setting,
+                                          password_flags_name);
 }
 
 /**
@@ -605,59 +729,223 @@ nma_cert_chooser_update_key_password_storage (NMACertChooser *cert_chooser,
 NMSettingSecretFlags
 nma_cert_chooser_get_key_password_flags (NMACertChooser *cert_chooser)
 {
+       NMACertChooserPrivate *priv;
+
        g_return_val_if_fail (NMA_IS_CERT_CHOOSER (cert_chooser),
                              NM_SETTING_SECRET_FLAG_NONE);
+       priv = NMA_CERT_CHOOSER_GET_PRIVATE (cert_chooser);
 
-       return NMA_CERT_CHOOSER_GET_VTABLE (cert_chooser)->get_key_password_flags (cert_chooser);
+       return nma_utils_menu_to_secret_flags (priv->key_password);
 }
 
-static GObject *
-constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties)
+static void
+cert_changed_cb (NMACertChooserButton *button, gpointer user_data)
 {
-       GObject *object;
-       NMACertChooser *cert_chooser;
-       NMACertChooserFlags flags = NMA_CERT_CHOOSER_FLAG_NONE;
-       NMACertChooserPrivate *priv;
-       int i;
-       const gchar *title = NULL;
+       NMACertChooserPrivate *priv = NMA_CERT_CHOOSER_GET_PRIVATE (NMA_CERT_CHOOSER (user_data));
+       GckUriData *uri_data;
+       gchar *pin = NULL;
+       const gchar *uri;
 
-       object = G_OBJECT_CLASS (nma_cert_chooser_parent_class)->constructor (type,
-                                                                             n_construct_properties,
-                                                                             construct_properties);
-       cert_chooser = NMA_CERT_CHOOSER (object);
-       priv = NMA_CERT_CHOOSER_GET_PRIVATE (cert_chooser);
+       uri = nma_cert_chooser_button_get_uri (button);
+       if (!uri)
+               return;
+       uri_data = gck_uri_parse (uri, GCK_URI_FOR_OBJECT, NULL);
+
+       if (nma_cert_chooser_button_get_remember_pin (button))
+               pin = nma_cert_chooser_button_get_pin (button);
+       if (pin)
+               gtk_editable_set_text (GTK_EDITABLE (priv->cert_password), pin);
+
+       gtk_widget_set_sensitive (priv->cert_password, uri_data != NULL);
+       gtk_widget_set_sensitive (priv->cert_password_label, uri_data != NULL);
+
+       if (!gtk_widget_get_sensitive (priv->key_button)) {
+               gtk_widget_set_sensitive (priv->key_button, TRUE);
+               gtk_widget_set_sensitive (priv->key_button_label, TRUE);
+
+               if (uri_data) {
+                       /* URI that is good both for a certificate and for a key. */
+                       if (!gck_attributes_find (uri_data->attributes, CKA_CLASS)) {
+                               nma_cert_chooser_button_set_uri (NMA_CERT_CHOOSER_BUTTON (priv->key_button), 
uri);
+                               gtk_widget_set_sensitive (priv->key_password, TRUE);
+                               gtk_widget_set_sensitive (priv->key_password_label, TRUE);
+                               if (pin)
+                                       gtk_editable_set_text (GTK_EDITABLE (priv->key_password), pin);
+                       }
+               }
+       }
+
+       if (uri_data)
+               gck_uri_data_free (uri_data);
+       if (pin)
+               g_free (pin);
+
+       g_signal_emit_by_name (user_data, "changed");
+}
+
+static void
+show_toggled_cb (GtkCheckButton *button, gpointer user_data)
+{
+       NMACertChooserPrivate *priv = NMA_CERT_CHOOSER_GET_PRIVATE (NMA_CERT_CHOOSER (user_data));
+       gboolean active;
+
+       active = gtk_check_button_get_active (GTK_CHECK_BUTTON (button));
+       gtk_entry_set_visibility (GTK_ENTRY (priv->cert_password), active);
+       if (priv->key_password)
+               gtk_entry_set_visibility (GTK_ENTRY (priv->key_password), active);
+}
+
+static void
+cert_password_changed_cb (GtkEntry *entry, gpointer user_data)
+{
+       g_signal_emit_by_name (user_data, "changed");
+}
 
-       for (i = 0; i < n_construct_properties; i++) {
-               if (strcmp (construct_properties[i].pspec->name, "title") == 0)
-                       title = g_value_get_string (construct_properties[i].value);
-               if (strcmp (construct_properties[i].pspec->name, "flags") == 0)
-                       flags |= g_value_get_uint (construct_properties[i].value);
+static void
+key_password_changed_cb (GtkEntry *entry, gpointer user_data)
+{
+       g_signal_emit_by_name (user_data, "changed");
+}
+
+static void
+key_changed_cb (NMACertChooserButton *button, gpointer user_data)
+{
+       NMACertChooserPrivate *priv = NMA_CERT_CHOOSER_GET_PRIVATE (NMA_CERT_CHOOSER (user_data));
+       gchar *pin = NULL;
+
+       if (nma_cert_chooser_button_get_remember_pin (button))
+               pin = nma_cert_chooser_button_get_pin (button);
+       if (pin) {
+               gtk_editable_set_text (GTK_EDITABLE (priv->key_password), pin);
+               g_free (pin);
        }
-       priv->vtable = &nma_cert_chooser_vtable_file;
-#if GTK_CHECK_VERSION(3,90,0) ? WITH_GCR_GTK4 : WITH_GCR
-       if ((flags & NMA_CERT_CHOOSER_FLAG_PEM) == 0)
-               priv->vtable = &nma_cert_chooser_vtable_pkcs11;
-#endif
 
-       /* Initialize the vtable and construct-time properties */
-       priv->vtable->init (cert_chooser);
-       priv->vtable->set_flags (cert_chooser, flags);
-       priv->vtable->set_title (cert_chooser, title);
+       gtk_widget_set_sensitive (priv->key_password, TRUE);
+       gtk_widget_set_sensitive (priv->key_password_label, TRUE);
+       g_signal_emit_by_name (user_data, "changed");
+}
+
+static void
+constructed (GObject *object)
+{
+       NMACertChooser *cert_chooser = NMA_CERT_CHOOSER (object);
+       NMACertChooserPrivate *priv = NMA_CERT_CHOOSER_GET_PRIVATE (cert_chooser);
+       NMACertChooserButtonFlags button_flags = NMA_CERT_CHOOSER_BUTTON_FLAG_NONE;
+       gs_free gchar *mnemonic_escaped = NULL;
+       gchar *text;
+       char **split;
+
+       G_OBJECT_CLASS (nma_cert_chooser_parent_class)->constructed (object);
+
+       split = g_strsplit (priv->title, "_", -1);
+       mnemonic_escaped = g_strjoinv("__", split);
+       g_strfreev (split);
+
+       if (priv->flags & NMA_CERT_CHOOSER_FLAG_PEM)
+               button_flags |= NMA_CERT_CHOOSER_BUTTON_FLAG_PEM;
+
+       /* The certificate chooser */
+
+       priv->cert_button = nma_cert_chooser_button_new (button_flags);
+
+       gtk_grid_attach (GTK_GRID (cert_chooser), priv->cert_button, 1, 0, 1, 1);
+       gtk_widget_set_hexpand (priv->cert_button, TRUE);
+       gtk_widget_show (priv->cert_button);
+       gtk3_widget_set_no_show_all (priv->cert_button, TRUE);
+
+       g_signal_connect (priv->cert_button, "changed",
+                         G_CALLBACK (cert_changed_cb), cert_chooser);
+
+       text = g_strdup_printf (_("Choose a %s Certificate"), priv->title);
+       nma_cert_chooser_button_set_title (NMA_CERT_CHOOSER_BUTTON (priv->cert_button), text);
+       g_free (text);
+
+       text = g_strdup_printf (_("%s _certificate"), mnemonic_escaped);
+       gtk_label_set_text_with_mnemonic (GTK_LABEL (priv->cert_button_label), text);
+       g_free (text);
+
+       text = g_strdup_printf (_("%s certificate _password"), mnemonic_escaped);
+       gtk_label_set_text_with_mnemonic (GTK_LABEL (priv->cert_password_label), text);
+       g_free (text);
 
-       return object;
+       /* The key chooser */
+
+       priv->key_button = nma_cert_chooser_button_new (button_flags |
+                                                       NMA_CERT_CHOOSER_BUTTON_FLAG_KEY);
+
+       gtk_grid_attach (GTK_GRID (cert_chooser), priv->key_button, 1, 2, 1, 1);
+       gtk_widget_set_hexpand (priv->key_button, TRUE);
+       gtk_widget_set_sensitive (priv->key_button, FALSE);
+       gtk_widget_show (priv->key_button);
+       gtk3_widget_set_no_show_all (priv->key_button, TRUE);
+
+        g_signal_connect (priv->key_button, "changed",
+                         G_CALLBACK (key_changed_cb), cert_chooser);
+
+       text = g_strdup_printf (_("Choose a key for %s Certificate"), priv->title);
+       nma_cert_chooser_button_set_title (NMA_CERT_CHOOSER_BUTTON (priv->key_button), text);
+       g_free (text);
+
+       text = g_strdup_printf (_("%s private _key"), mnemonic_escaped);
+       gtk_label_set_text_with_mnemonic (GTK_LABEL (priv->key_button_label), text);
+       g_free (text);
+
+       text = g_strdup_printf (_("%s key _password"), mnemonic_escaped);
+       gtk_label_set_text_with_mnemonic (GTK_LABEL (priv->key_password_label), text);
+       g_free (text);
+
+       /* Hide irrelevant things */
+
+       if (priv->flags & NMA_CERT_CHOOSER_FLAG_CERT) {
+               gtk_widget_hide (priv->key_button);
+               gtk_widget_hide (priv->key_button_label);
+               gtk_widget_hide (priv->key_password);
+               gtk_widget_hide (priv->key_password_label);
+       }
+
+       if (priv->flags & NMA_CERT_CHOOSER_FLAG_PASSWORDS) {
+               gtk_widget_hide (priv->cert_button);
+               gtk_widget_hide (priv->cert_button_label);
+               gtk_widget_hide (priv->key_button);
+               gtk_widget_hide (priv->key_button_label);
+
+               /* With FLAG_PASSWORDS the user can't pick a different key or a
+                * certificate, so there's no point in showing inactive password
+                * inputs. */
+               if (!gtk_widget_get_sensitive (priv->cert_password)) {
+                       gtk_widget_hide (priv->cert_password);
+                       gtk_widget_hide (priv->cert_password_label);
+               }
+               if (!gtk_widget_get_sensitive (priv->key_password)) {
+                       gtk_widget_hide (priv->key_password);
+                       gtk_widget_hide (priv->key_password_label);
+               }
+               if (   !gtk_widget_get_visible (priv->cert_password)
+                   && !gtk_widget_get_visible (priv->key_password)) {
+                       gtk_widget_hide (priv->show_password);
+               }
+       }
+
+       if (priv->flags & NMA_CERT_CHOOSER_FLAG_PEM) {
+               gtk_widget_hide (priv->cert_password);
+               gtk_widget_hide (priv->cert_password_label);
+       }
 }
 
 static void
 set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
 {
        NMACertChooser *cert_chooser = NMA_CERT_CHOOSER (object);
+       NMACertChooserPrivate *priv = NMA_CERT_CHOOSER_GET_PRIVATE (cert_chooser);
 
        g_return_if_fail (NMA_IS_CERT_CHOOSER (cert_chooser));
 
        switch (property_id) {
        case PROP_TITLE:
+               priv->title = g_strdup (g_value_get_string (value));
+               break;
        case PROP_FLAGS:
-               /* Just ignore these, should be set at construct time */
+               priv->flags = g_value_get_uint (value);
                break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -665,6 +953,16 @@ set_property (GObject *object, guint property_id, const GValue *value, GParamSpe
        }
 }
 
+static void
+dispose (GObject *object)
+{
+       NMACertChooserPrivate *priv = NMA_CERT_CHOOSER_GET_PRIVATE (object);
+
+       nm_clear_g_free (&priv->title);
+
+       G_OBJECT_CLASS (nma_cert_chooser_parent_class)->dispose (object);
+}
+
 static void
 nma_cert_chooser_class_init (NMACertChooserClass *klass)
 {
@@ -672,8 +970,9 @@ nma_cert_chooser_class_init (NMACertChooserClass *klass)
 
        g_type_class_add_private (object_class, sizeof (NMACertChooserPrivate));
 
-       object_class->constructor = constructor;
+       object_class->constructed = constructed;
        object_class->set_property = set_property;
+       object_class->dispose = dispose;
 
        /**
         * NMACertChooser::title:
@@ -799,8 +1098,92 @@ nma_cert_chooser_class_init (NMACertChooserClass *klass)
 }
 
 static void
-nma_cert_chooser_init (NMACertChooser *file_cert_chooser)
+nma_cert_chooser_init (NMACertChooser *cert_chooser)
 {
+       NMACertChooserPrivate *priv = NMA_CERT_CHOOSER_GET_PRIVATE (cert_chooser);
+
+       gtk_grid_insert_column (GTK_GRID (cert_chooser), 2);
+       gtk_grid_set_row_spacing (GTK_GRID (cert_chooser), 6);
+       gtk_grid_set_column_spacing (GTK_GRID (cert_chooser), 6);
+
+       /* Show password row */
+
+       gtk_grid_insert_row (GTK_GRID (cert_chooser), 0);
+       priv->show_password = gtk_check_button_new_with_mnemonic _("Sho_w passwords");
+       gtk_grid_attach (GTK_GRID (cert_chooser), priv->show_password, 1, 2, 1, 1);
+       gtk_widget_show (priv->show_password);
+       gtk3_widget_set_no_show_all (priv->show_password, TRUE);
+       g_signal_connect (priv->show_password, "toggled",
+                         G_CALLBACK (show_toggled_cb), cert_chooser);
+
+       /* The key chooser row */
+
+       gtk_grid_insert_row (GTK_GRID (cert_chooser), 0);
+
+       priv->key_button_label = gtk_label_new (NULL);
+       g_object_set (priv->key_button_label, "xalign", (gfloat) 1, NULL);
+       gtk_label_set_mnemonic_widget (GTK_LABEL (priv->key_button_label), priv->key_button);
+       gtk_grid_attach (GTK_GRID (cert_chooser), priv->key_button_label, 0, 0, 1, 1);
+       gtk_widget_set_sensitive (priv->key_button_label, FALSE);
+       gtk_widget_show (priv->key_button_label);
+       gtk3_widget_set_no_show_all (priv->key_button_label, TRUE);
+
+       /* The key password entry row */
+
+       gtk_grid_insert_row (GTK_GRID (cert_chooser), 1);
+
+       priv->key_password = gtk_entry_new ();
+       gtk_entry_set_visibility (GTK_ENTRY (priv->key_password), FALSE);
+       gtk_grid_attach (GTK_GRID (cert_chooser), priv->key_password, 1, 1, 1, 1);
+       gtk_widget_set_hexpand (priv->key_password, TRUE);
+       gtk_widget_set_sensitive (priv->key_password, FALSE);
+       gtk_widget_show (priv->key_password);
+       gtk3_widget_set_no_show_all (priv->key_password, TRUE);
+
+       g_signal_connect (priv->key_password, "changed",
+                         G_CALLBACK (key_password_changed_cb), cert_chooser);
+
+       priv->key_password_label = gtk_label_new (NULL);
+       g_object_set (priv->key_password_label, "xalign", (gfloat) 1, NULL);
+       gtk_label_set_mnemonic_widget (GTK_LABEL (priv->key_password_label), priv->key_password);
+       gtk_grid_attach (GTK_GRID (cert_chooser), priv->key_password_label, 0, 1, 1, 1);
+       gtk_widget_set_sensitive (priv->key_password_label, FALSE);
+       gtk_widget_show (priv->key_password_label);
+       gtk3_widget_set_no_show_all (priv->key_password_label, TRUE);
+
+       /* The certificate chooser row */
+
+       gtk_grid_insert_row (GTK_GRID (cert_chooser), 0);
+
+       priv->cert_button_label = gtk_label_new (NULL);
+       g_object_set (priv->cert_button_label, "xalign", (gfloat) 1, NULL);
+       gtk_label_set_mnemonic_widget (GTK_LABEL (priv->cert_button_label), priv->cert_button);
+       gtk_grid_attach (GTK_GRID (cert_chooser), priv->cert_button_label, 0, 0, 1, 1);
+       gtk_widget_show (priv->cert_button_label);
+       gtk3_widget_set_no_show_all (priv->cert_button_label, TRUE);
+
+       /* The cert password entry row */
+
+       gtk_grid_insert_row (GTK_GRID (cert_chooser), 1);
+
+       priv->cert_password = gtk_entry_new ();
+       gtk_entry_set_visibility (GTK_ENTRY (priv->cert_password), FALSE);
+       gtk_grid_attach (GTK_GRID (cert_chooser), priv->cert_password, 1, 1, 1, 1);
+       gtk_widget_set_hexpand (priv->cert_password, TRUE);
+       gtk_widget_set_sensitive (priv->cert_password, FALSE);
+       gtk_widget_show (priv->cert_password);
+       gtk3_widget_set_no_show_all (priv->cert_password, TRUE);
+
+       g_signal_connect (priv->cert_password, "changed",
+                         G_CALLBACK (cert_password_changed_cb), cert_chooser);
+
+       priv->cert_password_label = gtk_label_new (NULL);
+       g_object_set (priv->cert_password_label, "xalign", (gfloat) 1, NULL);
+       gtk_label_set_mnemonic_widget (GTK_LABEL (priv->cert_password_label), priv->cert_password);
+       gtk_grid_attach (GTK_GRID (cert_chooser), priv->cert_password_label, 0, 1, 1, 1);
+       gtk_widget_set_sensitive (priv->cert_password_label, FALSE);
+       gtk_widget_show (priv->cert_password_label);
+       gtk3_widget_set_no_show_all (priv->cert_password_label, TRUE);
 }
 
 /**


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