[krb5-auth-dialog] Ease PKINT with smartcard setup



commit d7678acba9c4f60b7b7342ed52a6a41976e44c74
Author: Guido Günther <agx sigxcpu org>
Date:   Mon Jun 22 11:07:15 2009 +0200

    Ease PKINT with smartcard setup
    
    and add filechooser dialog for certificates

 configure.ac                                 |   10 +
 preferences/krb5-auth-dialog-preferences.c   |  160 +++++++++++++++-
 preferences/krb5-auth-dialog-preferences.xml |  271 ++++++++++++++++----------
 3 files changed, 332 insertions(+), 109 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 5b32f51..000c0bb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -57,6 +57,16 @@ if test x"$enable_debug" = x"yes"; then
    AC_DEFINE(ENABLE_DEBUG, 1, [whether debugging is enabled])
 fi
 
+dnl check for location of opensc-pkcs11 helper used for pkinit
+AC_ARG_WITH([pkcs11],
+        [AS_HELP_STRING([--with-pkcs11],
+          [set path of PKCS11 smartcard helper @<:@default=/usr/lib/opensc/opensc-pkcs11.so@:>@])],
+        [],
+        [with_pkcs11=/usr/lib/opensc/opensc-pkcs11.so])
+SC_PKCS11="$with_pkcs11"
+AC_SUBST(SC_PKCS11)
+AC_DEFINE_UNQUOTED([SC_PKCS11],["$SC_PKCS11"],[PKCS11 smartcard helper])
+
 
 AC_PATH_PROG([KRB5_CONFIG], krb5-config, none, $PATH:/usr/kerberos/bin)
 if test "x$KRB5_CONFIG" != "xnone"; then
diff --git a/preferences/krb5-auth-dialog-preferences.c b/preferences/krb5-auth-dialog-preferences.c
index 4edd565..442d4f3 100644
--- a/preferences/krb5-auth-dialog-preferences.c
+++ b/preferences/krb5-auth-dialog-preferences.c
@@ -36,6 +36,9 @@
 #include "krb5-auth-gconf-tools.h"
 #include "krb5-auth-tools.h"
 
+#define PKINIT_SMARTCARD "PKCS11:" SC_PKCS11
+#define PKINIT_FILE "FILE:"
+
 #define N_LISTENERS 8
 
 typedef struct {
@@ -45,7 +48,10 @@ typedef struct {
   GtkWidget *dialog;
   GtkWidget *principal_entry;
   GtkWidget *pkuserid_entry;
+  GtkWidget *pkuserid_button;
+  GtkWidget *smartcard_toggle;
   GtkWidget *pkanchors_entry;
+  GtkWidget *pkanchors_button;
   GtkWidget *forwardable_toggle;
   GtkWidget *proxiable_toggle;
   GtkWidget *renewable_toggle;
@@ -185,7 +191,7 @@ ka_preferences_dialog_setup_pkuserid_entry (KaPreferencesDialog *dialog)
       g_free (pkuserid);
 
   g_signal_connect (dialog->pkuserid_entry, "changed",
-      G_CALLBACK (ka_preferences_dialog_pkuserid_changed), dialog);
+                    G_CALLBACK (ka_preferences_dialog_pkuserid_changed), dialog);
   if (!gconf_client_key_is_writable (dialog->client, KA_GCONF_KEY_PK_USERID, NULL)) {
       gtk_widget_set_sensitive (dialog->pkuserid_entry, FALSE);
   }
@@ -241,7 +247,7 @@ ka_preferences_dialog_pkanchors_changed (GtkEntry *entry,
 static void
 ka_preferences_dialog_setup_pkanchors_entry (KaPreferencesDialog *dialog)
 {
-  char     *pkanchors = NULL;
+  char *pkanchors = NULL;
 
   dialog->pkanchors_entry = GTK_WIDGET(gtk_builder_get_object (dialog->xml, "pkanchors_entry"));
   g_assert (dialog->pkanchors_entry != NULL);
@@ -269,8 +275,153 @@ ka_preferences_dialog_setup_pkanchors_entry (KaPreferencesDialog *dialog)
 
 
 static void
+ka_preferences_toggle_pkuserid_entry (gboolean state, KaPreferencesDialog *dialog)
+{
+  gtk_widget_set_sensitive (dialog->pkuserid_entry, state);
+  gtk_widget_set_sensitive (dialog->pkuserid_button, state);
+}
+
+
+static void
+ka_preferences_dialog_smartcard_toggled (GtkToggleButton *toggle,
+                                         KaPreferencesDialog *dialog)
+{
+  gboolean smartcard = gtk_toggle_button_get_active (toggle);
+  static gchar *old_path = NULL;
+
+  if (smartcard) {
+      const char *path;
+
+      path = gtk_entry_get_text (GTK_ENTRY(dialog->pkuserid_entry));
+      if (g_strcmp0 (path, PKINIT_SMARTCARD)) {
+          g_free (old_path);
+          old_path = g_strdup (path);
+      }
+      ka_preferences_toggle_pkuserid_entry (FALSE, dialog);
+      gconf_client_set_string (dialog->client, KA_GCONF_KEY_PK_USERID, PKINIT_SMARTCARD, NULL);
+  } else {
+      ka_preferences_toggle_pkuserid_entry (TRUE, dialog);
+      if (old_path)
+          gconf_client_set_string (dialog->client, KA_GCONF_KEY_PK_USERID, old_path, NULL);
+      else
+          gconf_client_unset (dialog->client, KA_GCONF_KEY_PK_USERID, NULL);
+  }
+}
+
+
+static void
+ka_preferences_dialog_setup_smartcard_toggle(KaPreferencesDialog *dialog)
+{
+  char *pkuserid = NULL;
+
+  dialog->smartcard_toggle = GTK_WIDGET(gtk_builder_get_object (dialog->xml, "smartcard_toggle"));
+  g_assert (dialog->smartcard_toggle != NULL);
+
+  if (!ka_gconf_get_string (dialog->client, KA_GCONF_KEY_PK_USERID, &pkuserid))
+      g_warning ("Getting pkanchors failed");
+
+  g_signal_connect (dialog->smartcard_toggle, "toggled",
+              G_CALLBACK (ka_preferences_dialog_smartcard_toggled), dialog);
+
+  if (!g_strcmp0 (pkuserid, PKINIT_SMARTCARD))
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->smartcard_toggle), TRUE);
+  else
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->smartcard_toggle), FALSE);
+
+  if (pkuserid)
+      g_free (pkuserid);
+}
+
+
+static void
+ka_preferences_dialog_browse_certs (KaPreferencesDialog *dialog, GtkEntry *entry)
+{
+  GtkWidget *filechooser;
+  GtkFileFilter *cert_filter, *all_filter;
+  gchar *filename = NULL;
+  const gchar *current;
+  gint ret;
+
+  filechooser = gtk_file_chooser_dialog_new(_("Choose Certificate"),
+                                            GTK_WINDOW(dialog->dialog),
+                                            GTK_FILE_CHOOSER_ACTION_OPEN,
+                                            GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                            GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+                                            NULL);
+
+  current = gtk_entry_get_text (entry);
+  if (current && g_str_has_prefix (current, PKINIT_FILE) &&
+      strlen(current) > strlen (PKINIT_FILE)) {
+      gtk_file_chooser_select_filename (GTK_FILE_CHOOSER(filechooser),
+                                        (const gchar*)&current[strlen(PKINIT_FILE)]);
+  }
+
+  cert_filter = g_object_ref_sink (gtk_file_filter_new ());
+  gtk_file_filter_add_mime_type (cert_filter, "application/x-x509-ca-cert");
+  gtk_file_filter_set_name (cert_filter, _("X509 Certificates"));
+  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (filechooser), cert_filter);
+  all_filter = g_object_ref_sink (gtk_file_filter_new ());
+  gtk_file_filter_add_pattern (all_filter, "*");
+  gtk_file_filter_set_name (all_filter, _("all files"));
+  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (filechooser), all_filter);
+
+  ret = gtk_dialog_run (GTK_DIALOG(filechooser));
+  if (ret == GTK_RESPONSE_ACCEPT)
+     filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(filechooser));
+  gtk_widget_destroy (GTK_WIDGET(filechooser));
+
+  if (filename) {
+      gchar *cert = g_strconcat( PKINIT_FILE, filename, NULL);
+      gtk_entry_set_text (entry, cert);
+      g_free (filename);
+      g_free (cert);
+  }
+  g_object_unref (cert_filter);
+  g_object_unref (all_filter);
+}
+
+static void
+ka_preferences_dialog_browse_pkuserids (GtkButton *button G_GNUC_UNUSED,
+                                       KaPreferencesDialog *dialog)
+{
+  ka_preferences_dialog_browse_certs (dialog,
+                                      GTK_ENTRY(dialog->pkuserid_entry));
+}
+
+static void
+ka_preferences_dialog_browse_pkanchors(GtkButton *button G_GNUC_UNUSED,
+                                       KaPreferencesDialog *dialog)
+{
+  ka_preferences_dialog_browse_certs (dialog,
+                                      GTK_ENTRY(dialog->pkanchors_entry));
+}
+
+static void
+ka_preferences_dialog_setup_pkuserid_button (KaPreferencesDialog *dialog)
+{
+  dialog->pkuserid_button = GTK_WIDGET(gtk_builder_get_object (dialog->xml, "pkuserid_button"));
+  g_assert (dialog->pkuserid_button != NULL);
+
+  g_signal_connect (dialog->pkuserid_button, "clicked",
+                    G_CALLBACK (ka_preferences_dialog_browse_pkuserids), dialog);
+
+}
+
+static void
+ka_preferences_dialog_setup_pkanchors_button (KaPreferencesDialog *dialog)
+{
+  dialog->pkanchors_button = GTK_WIDGET(gtk_builder_get_object (dialog->xml, "pkanchors_button"));
+  g_assert (dialog->pkanchors_button != NULL);
+
+  g_signal_connect (dialog->pkanchors_button, "clicked",
+                    G_CALLBACK (ka_preferences_dialog_browse_pkanchors), dialog);
+
+}
+
+
+static void
 ka_preferences_dialog_forwardable_toggled (GtkToggleButton *toggle,
-                                     KaPreferencesDialog *dialog)
+                                           KaPreferencesDialog *dialog)
 {
   gboolean forwardable;
 
@@ -602,7 +753,10 @@ ka_preferences_dialog_init(KaPreferencesDialog* dialog)
 
   ka_preferences_dialog_setup_principal_entry (dialog);
   ka_preferences_dialog_setup_pkuserid_entry (dialog);
+  ka_preferences_dialog_setup_pkuserid_button (dialog);
+  ka_preferences_dialog_setup_smartcard_toggle (dialog);
   ka_preferences_dialog_setup_pkanchors_entry(dialog);
+  ka_preferences_dialog_setup_pkanchors_button (dialog);
   ka_preferences_dialog_setup_forwardable_toggle (dialog);
   ka_preferences_dialog_setup_proxiable_toggle (dialog);
   ka_preferences_dialog_setup_renewable_toggle (dialog);
diff --git a/preferences/krb5-auth-dialog-preferences.xml b/preferences/krb5-auth-dialog-preferences.xml
index 6ac12bc..14b8598 100644
--- a/preferences/krb5-auth-dialog-preferences.xml
+++ b/preferences/krb5-auth-dialog-preferences.xml
@@ -63,131 +63,186 @@
                             <property name="visible">True</property>
                             <property name="spacing">6</property>
                             <child>
-                              <object class="GtkLabel" id="label6">
+                              <object class="GtkFrame" id="frame4">
                                 <property name="visible">True</property>
-                                <property name="xalign">0</property>
-                                <property name="label" translatable="yes">Kerberos principal:</property>
-                              </object>
-                              <packing>
-                                <property name="expand">False</property>
-                                <property name="fill">False</property>
-                                <property name="position">0</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <object class="GtkHBox" id="hbox5">
-                                <property name="visible">True</property>
-                                <property name="spacing">6</property>
-                                <child>
-                                  <object class="GtkLabel" id="label8">
-                                    <property name="visible">True</property>
-                                    <property name="label">    </property>
-                                  </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
-                                    <property name="position">0</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkEntry" id="principal_entry">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="activates_default">True</property>
-                                  </object>
-                                  <packing>
-                                    <property name="position">1</property>
-                                  </packing>
-                                </child>
-                              </object>
-                              <packing>
-                                <property name="position">1</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <object class="GtkLabel" id="label7">
-                                <property name="visible">True</property>
-                                <property name="xalign">0</property>
-                                <property name="label" translatable="yes">PKINIT userid:</property>
-                              </object>
-                              <packing>
-                                <property name="expand">False</property>
-                                <property name="fill">False</property>
-                                <property name="position">2</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <object class="GtkHBox" id="hbox6">
-                                <property name="visible">True</property>
-                                <property name="spacing">6</property>
+                                <property name="label_xalign">0</property>
+                                <property name="shadow_type">none</property>
                                 <child>
-                                  <object class="GtkLabel" id="label9">
+                                  <object class="GtkAlignment" id="alignment4">
                                     <property name="visible">True</property>
-                                    <property name="label">    </property>
+                                    <property name="left_padding">12</property>
+                                    <child>
+                                      <object class="GtkEntry" id="principal_entry">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="activates_default">True</property>
+                                      </object>
+                                    </child>
                                   </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
-                                    <property name="position">0</property>
-                                  </packing>
                                 </child>
-                                <child>
-                                  <object class="GtkEntry" id="pkuserid_entry">
+                                <child type="label">
+                                  <object class="GtkLabel" id="label3">
                                     <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="tooltip_text" translatable="yes">The principal's public/private/certificate identifier. Leave empty if not using PKINIT.</property>
-                                    <property name="activates_default">True</property>
+                                    <property name="label" translatable="yes">Kerberos principal:</property>
+                                    <property name="use_markup">True</property>
                                   </object>
-                                  <packing>
-                                    <property name="position">1</property>
-                                  </packing>
                                 </child>
                               </object>
                               <packing>
-                                <property name="position">3</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <object class="GtkLabel" id="label3">
-                                <property name="visible">True</property>
-                                <property name="xalign">0</property>
-                                <property name="label" translatable="yes">PKINIT anchors:</property>
-                              </object>
-                              <packing>
-                                <property name="expand">False</property>
-                                <property name="fill">False</property>
-                                <property name="position">4</property>
+                                <property name="position">0</property>
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkHBox" id="hbox12">
+                              <object class="GtkFrame" id="frame1">
                                 <property name="visible">True</property>
-                                <property name="spacing">6</property>
+                                <property name="label_xalign">0</property>
+                                <property name="shadow_type">none</property>
                                 <child>
-                                  <object class="GtkLabel" id="label20">
+                                  <object class="GtkAlignment" id="alignment1">
                                     <property name="visible">True</property>
-                                    <property name="label">    </property>
+                                    <property name="left_padding">12</property>
+                                    <child>
+                                      <object class="GtkVBox" id="vbox6">
+                                        <property name="visible">True</property>
+                                        <property name="orientation">vertical</property>
+                                        <child>
+                                          <object class="GtkFrame" id="frame2">
+                                            <property name="visible">True</property>
+                                            <property name="label_xalign">0</property>
+                                            <property name="shadow_type">none</property>
+                                            <child>
+                                              <object class="GtkAlignment" id="alignment2">
+                                                <property name="visible">True</property>
+                                                <property name="left_padding">24</property>
+                                                <child>
+                                                  <object class="GtkVBox" id="vbox11">
+                                                    <property name="visible">True</property>
+                                                    <property name="orientation">vertical</property>
+                                                    <child>
+                                                      <object class="GtkCheckButton" id="smartcard_toggle">
+                                                        <property name="label" translatable="yes">Use Smartcard</property>
+                                                        <property name="visible">True</property>
+                                                        <property name="can_focus">True</property>
+                                                        <property name="receives_default">False</property>
+                                                        <property name="tooltip_text" translatable="yes">If checked, use a security token (Smartcard) to authenticate.</property>
+                                                        <property name="draw_indicator">True</property>
+                                                      </object>
+                                                      <packing>
+                                                        <property name="position">0</property>
+                                                      </packing>
+                                                    </child>
+                                                    <child>
+                                                      <object class="GtkHBox" id="hbox13">
+                                                        <property name="visible">True</property>
+                                                        <child>
+                                                          <object class="GtkEntry" id="pkuserid_entry">
+                                                            <property name="visible">True</property>
+                                                            <property name="can_focus">True</property>
+                                                            <property name="tooltip_text" translatable="yes">Certificate and private key used for authentication</property>
+                                                            <property name="activates_default">True</property>
+                                                          </object>
+                                                          <packing>
+                                                            <property name="position">0</property>
+                                                          </packing>
+                                                        </child>
+                                                        <child>
+                                                          <object class="GtkButton" id="pkuserid_button">
+                                                            <property name="label" translatable="yes">_Browse...</property>
+                                                            <property name="visible">True</property>
+                                                            <property name="can_focus">True</property>
+                                                            <property name="receives_default">True</property>
+                                                            <property name="use_underline">True</property>
+                                                          </object>
+                                                          <packing>
+                                                            <property name="expand">False</property>
+                                                            <property name="position">1</property>
+                                                          </packing>
+                                                        </child>
+                                                      </object>
+                                                      <packing>
+                                                        <property name="position">1</property>
+                                                      </packing>
+                                                    </child>
+                                                  </object>
+                                                </child>
+                                              </object>
+                                            </child>
+                                            <child type="label">
+                                              <object class="GtkLabel" id="label21">
+                                                <property name="visible">True</property>
+                                                <property name="label" translatable="yes">Userid:</property>
+                                                <property name="use_markup">True</property>
+                                              </object>
+                                            </child>
+                                          </object>
+                                          <packing>
+                                            <property name="position">0</property>
+                                          </packing>
+                                        </child>
+                                        <child>
+                                          <object class="GtkFrame" id="frame3">
+                                            <property name="visible">True</property>
+                                            <property name="label_xalign">0</property>
+                                            <property name="shadow_type">none</property>
+                                            <child>
+                                              <object class="GtkAlignment" id="alignment3">
+                                                <property name="visible">True</property>
+                                                <property name="left_padding">24</property>
+                                                <child>
+                                                  <object class="GtkHBox" id="hbox6">
+                                                    <property name="visible">True</property>
+                                                    <child>
+                                                      <object class="GtkEntry" id="pkanchors_entry">
+                                                        <property name="visible">True</property>
+                                                        <property name="can_focus">True</property>
+                                                        <property name="activates_default">True</property>
+                                                      </object>
+                                                      <packing>
+                                                        <property name="position">0</property>
+                                                      </packing>
+                                                    </child>
+                                                    <child>
+                                                      <object class="GtkButton" id="pkanchors_button">
+                                                        <property name="label" translatable="yes">_Browse...</property>
+                                                        <property name="visible">True</property>
+                                                        <property name="can_focus">True</property>
+                                                        <property name="receives_default">True</property>
+                                                        <property name="use_underline">True</property>
+                                                      </object>
+                                                      <packing>
+                                                        <property name="expand">False</property>
+                                                        <property name="position">1</property>
+                                                      </packing>
+                                                    </child>
+                                                  </object>
+                                                </child>
+                                              </object>
+                                            </child>
+                                            <child type="label">
+                                              <object class="GtkLabel" id="label22">
+                                                <property name="visible">True</property>
+                                                <property name="label" translatable="yes">X509 trust anchors:</property>
+                                                <property name="use_markup">True</property>
+                                              </object>
+                                            </child>
+                                          </object>
+                                          <packing>
+                                            <property name="position">1</property>
+                                          </packing>
+                                        </child>
+                                      </object>
+                                    </child>
                                   </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
-                                    <property name="position">0</property>
-                                  </packing>
                                 </child>
-                                <child>
-                                  <object class="GtkEntry" id="pkanchors_entry">
+                                <child type="label">
+                                  <object class="GtkLabel" id="fram1">
                                     <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="tooltip_text" translatable="yes">Path to CA certificates used as trust anchors for PKINIT</property>
-                                    <property name="activates_default">True</property>
+                                    <property name="label" translatable="yes">PKINIT:</property>
                                   </object>
-                                  <packing>
-                                    <property name="position">1</property>
-                                  </packing>
                                 </child>
                               </object>
                               <packing>
-                                <property name="position">5</property>
+                                <property name="position">1</property>
                               </packing>
                             </child>
                           </object>
@@ -444,7 +499,7 @@
                             <child>
                               <object class="GtkLabel" id="label15">
                                 <property name="visible">True</property>
-                                <property name="label" comments="Used in combination: 'Warn x minutes before expiry'" translatable="yes">Warn</property>
+                                <property name="label" translatable="yes" comments="Used in combination: 'Warn x minutes before expiry'">Warn</property>
                               </object>
                               <packing>
                                 <property name="expand">False</property>
@@ -457,7 +512,7 @@
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="tooltip_text" translatable="yes">Send notification about ticket expiry that many minutes before it finally expires</property>
-                                <property name="activates_default">True</property>
+                                <property name="invisible_char">&#x25CF;</property>
                                 <property name="adjustment">adjustment1</property>
                               </object>
                               <packing>
@@ -469,7 +524,7 @@
                             <child>
                               <object class="GtkLabel" id="label16">
                                 <property name="visible">True</property>
-                                <property name="label" comments="Used in combination: 'Warn x minutes before expiry'" translatable="yes">minutes before expiry</property>
+                                <property name="label" translatable="yes" comments="Used in combination: 'Warn x minutes before expiry'">minutes before expiry</property>
                               </object>
                               <packing>
                                 <property name="expand">False</property>
@@ -657,8 +712,12 @@
       <action-widget response="0">button1</action-widget>
     </action-widgets>
   </object>
+  <object class="GtkImage" id="image1">
+    <property name="visible">True</property>
+    <property name="stock">gtk-missing-image</property>
+  </object>
   <object class="GtkAdjustment" id="adjustment1">
-    <property name="upper">100</property>
+    <property name="upper">1000</property>
     <property name="step_increment">1</property>
     <property name="page_increment">10</property>
     <property name="page_size">10</property>



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