aboutsummaryrefslogtreecommitdiff
path: root/src/krb5-auth-dialog.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/krb5-auth-dialog.c')
-rw-r--r--src/krb5-auth-dialog.c202
1 files changed, 135 insertions, 67 deletions
diff --git a/src/krb5-auth-dialog.c b/src/krb5-auth-dialog.c
index 3beaa8b..dfd5ef5 100644
--- a/src/krb5-auth-dialog.c
+++ b/src/krb5-auth-dialog.c
@@ -2,6 +2,8 @@
* Copyright (C) 2004,2005,2006 Red Hat, Inc.
* Authored by Christopher Aillon <caillon@redhat.com>
*
+ * Copyright (C) 2008,2009 Guido Guenther <agx@sigxcup.org>
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
@@ -55,8 +57,8 @@ static gboolean canceled;
static gboolean invalid_auth;
static gboolean always_run;
-static int grab_credentials (Krb5AuthApplet* applet);
-static int ka_renew_credentials (Krb5AuthApplet* applet);
+static int grab_credentials (KaApplet* applet);
+static int ka_renew_credentials (KaApplet* applet);
static gboolean ka_get_tgt_from_ccache (krb5_context context, krb5_creds *creds);
/* YAY for different Kerberos implementations */
@@ -160,13 +162,13 @@ ka_krb5_cc_clear_mcred(krb5_creds* mcred)
/* ***************************************************************** */
static gboolean
-credentials_expiring_real (Krb5AuthApplet* applet)
+credentials_expiring_real (KaApplet* applet)
{
krb5_creds my_creds;
krb5_timestamp now;
gboolean retval = FALSE;
- applet->renewable = FALSE;
+ ka_applet_set_tgt_renewable(applet, FALSE);
if (!ka_get_tgt_from_ccache (kcontext, &my_creds)) {
creds_expiry = 0;
retval = TRUE;
@@ -179,18 +181,18 @@ credentials_expiring_real (Krb5AuthApplet* applet)
}
creds_expiry = my_creds.times.endtime;
if ((krb5_timeofday(kcontext, &now) == 0) &&
- (now + applet->pw_prompt_secs > my_creds.times.endtime))
+ (now + ka_applet_get_pw_prompt_secs(applet) > my_creds.times.endtime))
retval = TRUE;
/* If our creds are expiring, determine whether they are renewable */
if (retval && get_cred_renewable(&my_creds) && my_creds.times.renew_till > now) {
- applet->renewable = TRUE;
+ ka_applet_set_tgt_renewable(applet, TRUE);
}
krb5_free_cred_contents (kcontext, &my_creds);
out:
- ka_update_status(applet, creds_expiry);
+ ka_applet_update_status(applet, creds_expiry);
return retval;
}
@@ -246,25 +248,21 @@ krb5_auth_dialog_wrong_label_update_expiry (GtkWidget* label)
static gboolean
krb5_auth_dialog_do_updates (gpointer data)
{
- Krb5AuthApplet* applet = (Krb5AuthApplet*)data;
+ KaApplet* applet = KA_APPLET(data);
g_return_val_if_fail (applet != NULL, FALSE);
-
/* Update creds_expiry and close the applet if we got the creds by other means (e.g. kinit) */
- if (!credentials_expiring_real(applet)) {
- KA_DEBUG("PW Dialog persist: %d", applet->pw_dialog_persist);
- if (!applet->pw_dialog_persist)
- gtk_widget_hide(applet->pw_dialog);
- }
+ if (!credentials_expiring_real(applet))
+ ka_applet_hide_pw_dialog(applet, FALSE);
/* Update the expiry information in the dialog */
- krb5_auth_dialog_wrong_label_update_expiry (applet->pw_wrong_label);
+ krb5_auth_dialog_wrong_label_update_expiry (ka_applet_get_pw_label(applet));
return TRUE;
}
static void
-krb5_auth_dialog_setup (Krb5AuthApplet *applet,
+krb5_auth_dialog_setup (KaApplet *applet,
const gchar *krb5prompt,
gboolean hide_password)
{
@@ -275,7 +273,6 @@ krb5_auth_dialog_setup (Krb5AuthApplet *applet,
gchar *prompt;
int pw4len;
-
if (krb5prompt == NULL) {
prompt = g_strdup (_("Please enter your Kerberos password."));
} else {
@@ -295,17 +292,19 @@ krb5_auth_dialog_setup (Krb5AuthApplet *applet,
}
/* Clear the password entry field */
- entry = glade_xml_get_widget (applet->pw_xml, "krb5_entry");
+ entry = glade_xml_get_widget (ka_applet_get_pwdialog_xml(applet),
+ "krb5_entry");
gtk_secure_entry_set_text (GTK_SECURE_ENTRY (entry), "");
/* Use the prompt label that krb5 provides us */
- label = glade_xml_get_widget (applet->pw_xml, "krb5_message_label");
+ label = glade_xml_get_widget (ka_applet_get_pwdialog_xml(applet),
+ "krb5_message_label");
gtk_label_set_text (GTK_LABEL (label), prompt);
/* Add our extra message hints, if any */
wrong_text = NULL;
- if (applet->pw_wrong_label) {
+ if (ka_applet_get_pw_label(applet)) {
if (invalid_auth) {
wrong_text = g_strdup (_("The password you entered is invalid"));
} else {
@@ -322,11 +321,11 @@ krb5_auth_dialog_setup (Krb5AuthApplet *applet,
if (wrong_text) {
wrong_markup = g_strdup_printf ("<span size=\"smaller\" style=\"italic\">%s</span>", wrong_text);
- gtk_label_set_markup (GTK_LABEL (applet->pw_wrong_label), wrong_markup);
+ gtk_label_set_markup (GTK_LABEL (ka_applet_get_pw_label(applet)), wrong_markup);
g_free(wrong_text);
g_free(wrong_markup);
} else {
- gtk_label_set_text (GTK_LABEL (applet->pw_wrong_label), "");
+ gtk_label_set_text (GTK_LABEL (ka_applet_get_pw_label(applet)), "");
}
g_free (prompt);
}
@@ -340,7 +339,7 @@ auth_dialog_prompter (krb5_context ctx,
int num_prompts,
krb5_prompt prompts[])
{
- Krb5AuthApplet* applet = (Krb5AuthApplet*)data;
+ KaApplet* applet = KA_APPLET(data);
krb5_error_code errcode;
int i;
@@ -359,11 +358,11 @@ auth_dialog_prompter (krb5_context ctx,
errcode = KRB5_LIBOS_CANTREADPWD;
krb5_auth_dialog_setup (applet, (gchar *) prompts[i].prompt, prompts[i].hidden);
- entry = glade_xml_get_widget (applet->pw_xml, "krb5_entry");
+ entry = glade_xml_get_widget (ka_applet_get_pwdialog_xml(applet), "krb5_entry");
gtk_widget_grab_focus (entry);
source_id = g_timeout_add_seconds (5, (GSourceFunc)krb5_auth_dialog_do_updates, applet);
- response = gtk_dialog_run (GTK_DIALOG (applet->pw_dialog));
+ response = ka_applet_run_pw_dialog (applet);
switch (response)
{
case GTK_RESPONSE_OK:
@@ -394,8 +393,8 @@ auth_dialog_prompter (krb5_context ctx,
errcode = 0;
}
cleanup:
+ ka_applet_hide_pw_dialog (applet, TRUE);
/* Reset this, so we know the next time we get a TRUE value, it is accurate. */
- gtk_widget_hide (applet->pw_dialog);
invalid_auth = FALSE;
return errcode;
@@ -431,14 +430,15 @@ network_state_cb (libnm_glib_ctx *context,
}
#endif
+/* credentials expiring timer */
static gboolean
credentials_expiring (gpointer *data)
{
int retval;
gboolean give_up;
- Krb5AuthApplet* applet = (Krb5AuthApplet*) data;
+ KaApplet* applet = KA_APPLET(data);
- KA_DEBUG("Checking expiry <%ds", applet->pw_prompt_secs);
+ KA_DEBUG("Checking expiry <%ds", ka_applet_get_pw_prompt_secs(applet));
if (credentials_expiring_real (applet) && is_online) {
KA_DEBUG("Expiry @ %ld", creds_expiry);
@@ -448,7 +448,7 @@ credentials_expiring (gpointer *data)
}
/* no popup when using a trayicon */
- if (applet->show_trayicon)
+ if (ka_applet_get_show_trayicon(applet))
goto out;
give_up = canceled && (creds_expiry == canceled_creds_expiry);
@@ -465,13 +465,13 @@ credentials_expiring (gpointer *data)
}
}
out:
- ka_update_status(applet, creds_expiry);
+ ka_applet_update_status(applet, creds_expiry);
return TRUE;
}
static void
-set_options_from_creds(const Krb5AuthApplet* applet,
+set_options_from_creds(const KaApplet* applet,
krb5_context context,
krb5_creds *in,
krb5_get_init_creds_opt *out)
@@ -496,7 +496,7 @@ set_options_from_creds(const Krb5AuthApplet* applet,
renew_lifetime);
}
if (in->times.endtime >
- in->times.starttime + applet->pw_prompt_secs) {
+ in->times.starttime + ka_applet_get_pw_prompt_secs(applet)) {
krb5_get_init_creds_opt_set_tkt_life(out,
in->times.endtime -
in->times.starttime);
@@ -507,16 +507,13 @@ set_options_from_creds(const Krb5AuthApplet* applet,
static krb5_error_code
-ka_auth_pkinit(Krb5AuthApplet* applet, krb5_creds* creds)
+ka_auth_pkinit(KaApplet* applet, krb5_creds* creds, const char* pk_userid)
{
#ifdef ENABLE_PKINIT
krb5_get_init_creds_opt *opts = NULL;
krb5_error_code retval;
- KA_DEBUG("pkinit with %s", applet->pk_userid);
-
- if (!applet->pk_userid)
- return 0;
+ KA_DEBUG("pkinit with '%s'", pk_userid);
retval = krb5_get_init_creds_opt_alloc (kcontext, &opts);
if (retval)
@@ -525,7 +522,7 @@ ka_auth_pkinit(Krb5AuthApplet* applet, krb5_creds* creds)
retval = krb5_get_init_creds_opt_set_pkinit(kcontext, opts,
kprincipal,
- applet->pk_userid,
+ pk_userid,
NULL, /* x509 anchors */
NULL,
NULL,
@@ -549,35 +546,54 @@ out:
}
+krb5_error_code
+ka_parse_name(KaApplet* applet, krb5_context kcontext, krb5_principal* kprinc)
+{
+ krb5_error_code ret;
+ gchar *principal = NULL;
+
+ g_object_get(applet, "principal", &principal,
+ NULL);
+
+ ret = krb5_parse_name(kcontext, principal,
+ kprinc);
+
+ g_free(principal);
+ return ret;
+}
+
+
/* grab credentials interactively */
static int
-grab_credentials (Krb5AuthApplet* applet)
+grab_credentials (KaApplet* applet)
{
krb5_error_code retval;
krb5_creds my_creds;
krb5_ccache ccache;
krb5_get_init_creds_opt *opt = NULL;
+ gchar *pk_userid = NULL;
+
+ g_object_get(applet, "pk-userid", &pk_userid,
+ NULL);
memset(&my_creds, 0, sizeof(my_creds));
if (kprincipal == NULL) {
- retval = krb5_parse_name(kcontext, applet->principal,
- &kprincipal);
- if (retval) {
- return retval;
- }
+ retval = ka_parse_name(applet, kcontext, &kprincipal);
+ if (retval)
+ goto out2;
}
retval = krb5_cc_default (kcontext, &ccache);
if (retval)
- return retval;
+ goto out2;
#if ENABLE_PKINIT
- if (applet->pk_userid) { /* try pkinit */
+ if (pk_userid && strlen(pk_userid)) { /* try pkinit */
#else
if (0) {
#endif
- retval = ka_auth_pkinit(applet, &my_creds);
+ retval = ka_auth_pkinit(applet, &my_creds, pk_userid);
} else {
retval = krb5_get_init_creds_opt_alloc (kcontext, &opt);
if (retval)
@@ -620,13 +636,15 @@ out:
krb5_get_init_creds_opt_free(kcontext, opt);
krb5_free_cred_contents (kcontext, &my_creds);
krb5_cc_close (kcontext, ccache);
+out2:
+ g_free(pk_userid);
return retval;
}
/* try to renew the credentials noninteractively */
static int
-ka_renew_credentials (Krb5AuthApplet* applet)
+ka_renew_credentials (KaApplet* applet)
{
krb5_error_code retval;
krb5_creds my_creds;
@@ -634,8 +652,7 @@ ka_renew_credentials (Krb5AuthApplet* applet)
krb5_get_init_creds_opt opts;
if (kprincipal == NULL) {
- retval = krb5_parse_name(kcontext, applet->principal,
- &kprincipal);
+ retval = ka_parse_name(applet, kcontext, &kprincipal);
if (retval)
return retval;
}
@@ -653,7 +670,7 @@ ka_renew_credentials (Krb5AuthApplet* applet)
krb5_get_init_creds_opt_init (&opts);
set_options_from_creds (applet, kcontext, &my_creds, &opts);
- if (applet->renewable) {
+ if (ka_applet_get_tgt_renewable(applet)) {
retval = get_renewed_creds (kcontext, &my_creds, kprincipal, ccache, NULL);
if (retval)
goto out;
@@ -741,7 +758,7 @@ using_krb5()
void
ka_destroy_cache (GtkMenuItem *menuitem, gpointer data)
{
- Krb5AuthApplet* applet = (Krb5AuthApplet*) data;
+ KaApplet *applet = KA_APPLET(data);
krb5_ccache ccache;
const char* cache;
krb5_error_code ret;
@@ -768,14 +785,66 @@ ka_error_dialog(int err)
}
-/* this is done on leftclick, update the tooltip immediately */
-void
-ka_grab_credentials (Krb5AuthApplet* applet)
+/*
+ * check if we have valid credentials for the requested principal - if not, grab them
+ * principal: requested principal - if empty use default
+ */
+gboolean
+ka_check_credentials (KaApplet *applet, const char* newprincipal)
+{
+ gboolean renewable;
+ gboolean success = FALSE;
+ int retval;
+ char* principal;
+
+ g_object_get(applet, "principal", &principal,
+ NULL);
+
+ if (strlen(newprincipal)) {
+ krb5_principal knewprinc;
+
+ /* no ticket cache: is requested princ the one from our config? */
+ if (!kprincipal && g_strcmp0(principal, newprincipal)) {
+ KA_DEBUG("Requested principal %s not %s", principal, newprincipal);
+ goto out;
+ }
+
+ /* ticket cache: check if the requested principal is the one we have */
+ retval = krb5_parse_name(kcontext, newprincipal, &knewprinc);
+ if (retval) {
+ g_warning ("Cannot parse principal '%s'", newprincipal);
+ goto out;
+ }
+ if (kprincipal && !krb5_principal_compare (kcontext, kprincipal, knewprinc)) {
+ KA_DEBUG("Current Principal '%s' not '%s'", principal, newprincipal);
+ krb5_free_principal(kcontext, knewprinc);
+ goto out;
+ }
+ krb5_free_principal(kcontext, knewprinc);
+ }
+
+ if (credentials_expiring_real (applet)) {
+ if (!is_online)
+ success = FALSE;
+ else
+ success = ka_grab_credentials (applet);
+ } else
+ success = TRUE;
+out:
+ g_free (principal);
+ return success;
+}
+
+
+/* initiate grabbing of credentials (e.g. on leftclick of tray icon) */
+gboolean
+ka_grab_credentials (KaApplet* applet)
{
int retval;
gboolean retry;
+ int success = FALSE;
- applet->pw_dialog_persist = TRUE;
+ ka_applet_set_pw_dialog_persist(applet, TRUE);
do {
retry = TRUE;
retval = grab_credentials (applet);
@@ -783,6 +852,7 @@ ka_grab_credentials (Krb5AuthApplet* applet)
continue;
switch (retval) {
case 0: /* success */
+ success = TRUE;
case KRB5_LIBOS_PWDINTR: /* canceled (heimdal) */
case KRB5_LIBOS_CANTREADPWD: /* canceled (mit) */
retry = FALSE;
@@ -795,8 +865,10 @@ ka_grab_credentials (Krb5AuthApplet* applet)
}
} while(retry);
- applet->pw_dialog_persist = FALSE;
+ ka_applet_set_pw_dialog_persist(applet, FALSE);
credentials_expiring_real(applet);
+
+ return success;
}
@@ -835,7 +907,7 @@ ka_secmem_init ()
int
main (int argc, char *argv[])
{
- Krb5AuthApplet *applet;
+ KaApplet *applet;
GOptionContext *context;
GError *error = NULL;
@@ -878,20 +950,15 @@ main (int argc, char *argv[])
always_run = TRUE;
}
if (using_krb5 () || always_run) {
- applet = ka_create_applet ();
+ g_set_application_name (_("Network Authentication"));
+ glade_set_custom_handler (&ka_create_gtk_secure_entry, NULL);
+
+ applet = ka_applet_create ();
if (!applet)
return 1;
if (!ka_gconf_init (applet, argc, argv))
return 1;
- /* setup the pw dialog */
- glade_set_custom_handler (&ka_create_gtk_secure_entry, NULL);
- applet->pw_xml = glade_xml_new (GLADEDIR "krb5-auth-dialog.glade", NULL, NULL);
- applet->pw_wrong_label = glade_xml_get_widget (applet->pw_xml, "krb5_wrong_label");
- applet->pw_dialog = glade_xml_get_widget (applet->pw_xml, "krb5_dialog");
-
- g_set_application_name (_("Network Authentication"));
-
#ifdef ENABLE_NETWORK_MANAGER
nm_context = libnm_glib_init ();
if (!nm_context) {
@@ -910,6 +977,7 @@ main (int argc, char *argv[])
if (credentials_expiring ((gpointer)applet)) {
g_timeout_add_seconds (CREDENTIAL_CHECK_INTERVAL, (GSourceFunc)credentials_expiring, applet);
}
+ ka_dbus_service(applet);
gtk_main ();
}
bgstack15