aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am9
-rw-r--r--src/krb5-auth-applet.c94
-rw-r--r--src/krb5-auth-applet.h6
-rw-r--r--src/krb5-auth-dialog.c395
-rw-r--r--src/krb5-auth-dialog.schemas.in55
-rw-r--r--src/krb5-auth-gconf.c16
-rw-r--r--src/krb5-auth-notify.c19
-rw-r--r--src/krb5-auth-notify.h4
8 files changed, 429 insertions, 169 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 066e582..2837be8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -10,6 +10,13 @@ autostart_in_files = krb5-auth-dialog.desktop.in
autostart_DATA = $(autostart_in_files:.desktop.in=.desktop)
@INTLTOOL_DESKTOP_RULE@
+schemadir = $(sysconfdir)/gconf/schemas
+schema_in_files = $(PACKAGE).schemas.in
+schema_DATA = $(PACKAGE).schemas
+
+%.schemas: $(srcdir)/%.schemas.in
+ sed -e "s,::PACKAGE::,$(PACKAGE)," < $< > $@
+
krb5_auth_dialog_SOURCES = \
krb5-auth-dialog.c \
krb5-auth-dialog.h \
@@ -42,7 +49,9 @@ glade_DATA = \
EXTRA_DIST = \
$(glade_DATA) \
+ $(schama_in_files) \
$(autostart_in_files) \
krb5-auth-dialog.1.in
+CLEANFILES = $(schema_DATA)
DISTCLEANFILES = krb5-auth-dialog.desktop
diff --git a/src/krb5-auth-applet.c b/src/krb5-auth-applet.c
index 4a11d09..c915240 100644
--- a/src/krb5-auth-applet.c
+++ b/src/krb5-auth-applet.c
@@ -24,65 +24,97 @@
#include "krb5-auth-applet.h"
#include "krb5-auth-dialog.h"
-#ifdef HAVE_LIBNOTIFY
#include "krb5-auth-notify.h"
-#endif
#define NOTIFY_SECONDS 300
-/* update the tray icon's tooltip and icon */
-int
-ka_update_status(Krb5AuthApplet* applet, krb5_timestamp expiry)
+enum ka_icon {
+ inv_icon = 0,
+ exp_icon,
+ val_icon,
+};
+
+
+/* determine the new tooltip text */
+static char*
+ka_tooltip_text(Krb5AuthApplet* applet, int remaining)
{
- gchar* expiry_text;
- int now = time(0);
- int remaining = expiry - now;
- static int last_warn = 0;
- static gboolean expiry_notified = FALSE;
+ int hours, minutes;
+ gchar* tooltip_text;
if (remaining > 0) {
- int hours, minutes;
if (remaining >= 3600) {
hours = remaining / 3600;
minutes = (remaining % 3600) / 60;
- expiry_text = g_strdup_printf (_("Your credentials expire in %.2d:%.2dh"), hours, minutes);
+ tooltip_text = g_strdup_printf (_("Your credentials expire in %.2d:%.2dh"), hours, minutes);
} else {
minutes = remaining / 60;
- expiry_text = g_strdup_printf (ngettext(
+ tooltip_text = g_strdup_printf (ngettext(
"Your credentials expire in %d minute",
"Your credentials expire in %d minutes",
minutes), minutes);
}
- gtk_status_icon_set_from_icon_name (applet->tray_icon, applet->icons[1]);
-#ifdef HAVE_LIBNOTIFY
+ } else
+ tooltip_text = g_strdup (_("Your credentials have expired"));
+ return tooltip_text;
+}
+
+
+/* determine the current icon */
+static const char*
+ka_select_icon(Krb5AuthApplet* applet, int remaining)
+{
+ enum ka_icon tray_icon = inv_icon;
+
+ if (remaining > 0) {
+ if (remaining < applet->pw_prompt_secs &&
+ !applet->renewable)
+ tray_icon = exp_icon;
+ else
+ tray_icon = val_icon;
+ }
+
+ return applet->icons[tray_icon];
+}
+
+
+/* update the tray icon's tooltip and icon */
+int
+ka_update_status(Krb5AuthApplet* applet, krb5_timestamp expiry)
+{
+ int now = time(0);
+ int remaining = expiry - now;
+ static int last_warn = 0;
+ static gboolean expiry_notified = FALSE;
+ const char* tray_icon = ka_select_icon (applet, remaining);
+ char* tooltip_text = ka_tooltip_text (applet, remaining);
+
+ if (remaining > 0) {
if (expiry_notified) {
- ka_send_event_notification (applet, NOTIFY_URGENCY_NORMAL,
+ ka_send_event_notification (applet,
_("Network credentials valid"),
_("Your Kerberos credentials have been refreshed."), NULL);
expiry_notified = FALSE;
- } else if (remaining < applet->pw_prompt_secs && (now - last_warn) > NOTIFY_SECONDS) {
- ka_send_event_notification (applet, NOTIFY_URGENCY_NORMAL,
+ } else if (remaining < applet->pw_prompt_secs && (now - last_warn) > NOTIFY_SECONDS &&
+ !applet->renewable) {
+ ka_send_event_notification (applet,
_("Network credentials expiring"),
- expiry_text, NULL);
+ tooltip_text, NULL);
last_warn = now;
}
-#endif
} else {
- expiry_text = g_strdup (_("Your credentials have expired"));
- gtk_status_icon_set_from_icon_name (applet->tray_icon, applet->icons[0]);
-#ifdef HAVE_LIBNOTIFY
if (!expiry_notified) {
- ka_send_event_notification (applet, NOTIFY_URGENCY_NORMAL,
+ ka_send_event_notification (applet,
_("Network credentials expired"),
_("Your Kerberos credentails have expired."), NULL);
expiry_notified = TRUE;
last_warn = 0;
}
-#endif
}
- gtk_status_icon_set_tooltip (applet->tray_icon, expiry_text);
- g_free (expiry_text);
+ gtk_status_icon_set_from_icon_name (applet->tray_icon, tray_icon);
+ gtk_status_icon_set_tooltip (applet->tray_icon, tooltip_text);
+ g_free(tooltip_text);
return 0;
}
@@ -213,7 +245,7 @@ ka_create_tray_icon (Krb5AuthApplet* applet)
g_signal_connect (G_OBJECT(tray_icon),
"popup-menu",
G_CALLBACK(ka_tray_icon_on_menu), applet);
- gtk_status_icon_set_from_icon_name (tray_icon, applet->icons[0]);
+ gtk_status_icon_set_from_icon_name (tray_icon, applet->icons[exp_icon]);
gtk_status_icon_set_tooltip (tray_icon, PACKAGE);
return tray_icon;
}
@@ -222,8 +254,9 @@ ka_create_tray_icon (Krb5AuthApplet* applet)
int
ka_setup_icons (Krb5AuthApplet* applet)
{
- applet->icons[0] = "krb-no-valid-ticket";
- applet->icons[1] = "krb-valid-ticket";
+ applet->icons[val_icon] = "krb-valid-ticket";
+ applet->icons[exp_icon] = "krb-expiring-ticket";
+ applet->icons[inv_icon] = "krb-no-valid-ticket";
return TRUE;
}
@@ -240,6 +273,7 @@ ka_create_applet()
g_error ("Failure to create tray icon");
if (!(applet->context_menu = ka_create_context_menu (applet)))
g_error ("Failure to create context menu");
+ gtk_window_set_default_icon_name (applet->icons[val_icon]);
ka_show_tray_icon (applet);
return applet;
diff --git a/src/krb5-auth-applet.h b/src/krb5-auth-applet.h
index 062e148..e137794 100644
--- a/src/krb5-auth-applet.h
+++ b/src/krb5-auth-applet.h
@@ -35,7 +35,7 @@
typedef struct {
GtkStatusIcon* tray_icon; /* the tray icon */
GtkWidget* context_menu; /* the tray icon's context menu */
- const char* icons[2]; /* for expired and valid tickts */
+ const char* icons[3]; /* for invalid, expiring and valid tickts */
gboolean show_trayicon; /* show the trayicon */
/* The password dialog */
@@ -49,6 +49,8 @@ typedef struct {
NotifyNotification* notification;/* notification messages */
#endif /* HAVE_LIBNOTIFY */
char* principal; /* the principal to request */
+ gboolean renewable; /* credentials renewable? */
+ char* pk_userid; /* "userid" for pkint */
} Krb5AuthApplet;
Krb5AuthApplet* ka_create_applet();
@@ -59,7 +61,7 @@ gboolean ka_show_tray_icon(Krb5AuthApplet* applet);
#ifdef ENABLE_DEBUG
#define KA_DEBUG(fmt,...) \
- g_printf ("DEBUG: %s: " fmt "\n", __func__, __VA_ARGS__)
+ g_printf ("DEBUG: %s: " fmt "\n", __func__, ##__VA_ARGS__)
#else
#define KA_DEBUG(fmt,...) \
do { } while (0)
diff --git a/src/krb5-auth-dialog.c b/src/krb5-auth-dialog.c
index f376ffd..c8fc27c 100644
--- a/src/krb5-auth-dialog.c
+++ b/src/krb5-auth-dialog.c
@@ -43,16 +43,21 @@
#include <libnm_glib.h>
#endif
+#ifdef HAVE_HX509_ERR_H
+# include <hx509_err.h>
+#endif
+
static krb5_context kcontext;
static krb5_principal kprincipal;
static krb5_timestamp creds_expiry;
static krb5_timestamp canceled_creds_expiry;
static gboolean canceled;
-static gboolean invalid_password;
+static gboolean invalid_auth;
static gboolean always_run;
-static int grab_credentials (Krb5AuthApplet* applet, gboolean renewable);
-static gboolean get_tgt_from_ccache (krb5_context context, krb5_creds *creds);
+static int grab_credentials (Krb5AuthApplet* applet);
+static int ka_renew_credentials (Krb5AuthApplet* applet);
+static gboolean ka_get_tgt_from_ccache (krb5_context context, krb5_creds *creds);
/* YAY for different Kerberos implementations */
static int
@@ -124,18 +129,45 @@ get_principal_realm_data(krb5_principal p)
return p->realm.data;
#endif
}
+
+static const char*
+get_error_message(krb5_context context, krb5_error_code err)
+{
+ const char *msg = NULL;
+
+#if defined(HAVE_KRB5_GET_ERROR_MESSAGE)
+ msg = krb5_get_error_message(context, err);
+#else
+ msg = error_message(err);
+#endif
+ if (msg == NULL)
+ return "unknown error";
+ else
+ return msg;
+}
+
+static void
+ka_krb5_cc_clear_mcred(krb5_creds* mcred)
+{
+#if defined HAVE_KRB5_CC_CLEAR_MCRED
+ krb5_cc_clear_mcred(mcred);
+#else
+ memset(mcred, 0, sizeof(krb5_creds));
+#endif
+}
+
/* ***************************************************************** */
/* ***************************************************************** */
static gboolean
-credentials_expiring_real (Krb5AuthApplet* applet, gboolean *renewable)
+credentials_expiring_real (Krb5AuthApplet* applet)
{
krb5_creds my_creds;
krb5_timestamp now;
gboolean retval = FALSE;
- *renewable = FALSE;
+ applet->renewable = FALSE;
- if (!get_tgt_from_ccache (kcontext, &my_creds)) {
+ if (!ka_get_tgt_from_ccache (kcontext, &my_creds)) {
creds_expiry = 0;
retval = TRUE;
goto out;
@@ -152,7 +184,7 @@ credentials_expiring_real (Krb5AuthApplet* applet, gboolean *renewable)
/* If our creds are expiring, determine whether they are renewable */
if (retval && get_cred_renewable(&my_creds) && my_creds.times.renew_till > now) {
- *renewable = TRUE;
+ applet->renewable = TRUE;
}
krb5_free_cred_contents (kcontext, &my_creds);
@@ -215,13 +247,12 @@ static gboolean
krb5_auth_dialog_do_updates (gpointer data)
{
Krb5AuthApplet* applet = (Krb5AuthApplet*)data;
- gboolean refreshable;
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, &refreshable)) {
- KA_DEBUG("PW Dialog persist is %d", applet->pw_dialog_persist);
+ 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);
}
@@ -275,7 +306,7 @@ krb5_auth_dialog_setup (Krb5AuthApplet *applet,
wrong_text = NULL;
if (applet->pw_wrong_label) {
- if (invalid_password) {
+ if (invalid_auth) {
wrong_text = g_strdup (_("The password you entered is invalid"));
} else {
krb5_timestamp now;
@@ -313,7 +344,7 @@ auth_dialog_prompter (krb5_context ctx,
krb5_error_code errcode;
int i;
- errcode = KRB5_LIBOS_CANTREADPWD;
+ errcode = KRB5KRB_ERR_GENERIC;
canceled = FALSE;
canceled_creds_expiry = 0;
@@ -321,7 +352,7 @@ auth_dialog_prompter (krb5_context ctx,
const gchar *password = NULL;
int password_len = 0;
int response;
- guint32 source_id = 0;
+ guint32 source_id;
GtkWidget *entry;
@@ -338,7 +369,6 @@ auth_dialog_prompter (krb5_context ctx,
case GTK_RESPONSE_OK:
password = gtk_secure_entry_get_text (GTK_SECURE_ENTRY (entry));
password_len = strlen (password);
- errcode = 0;
break;
case GTK_RESPONSE_CANCEL:
canceled = TRUE;
@@ -350,16 +380,23 @@ auth_dialog_prompter (krb5_context ctx,
g_warning ("Unknown Response: %d", response);
g_assert_not_reached ();
}
-
g_source_remove (source_id);
- prompts[i].reply->data = (char *) password;
+ if (!password)
+ goto cleanup;
+ if (password_len+1 > prompts[i].reply->length) {
+ g_warning("Password too long %d/%d", password_len+1, prompts[i].reply->length);
+ goto cleanup;
+ }
+
+ memcpy(prompts[i].reply->data, (char *) password, password_len + 1);
prompts[i].reply->length = password_len;
+ errcode = 0;
}
-
+cleanup:
/* Reset this, so we know the next time we get a TRUE value, it is accurate. */
gtk_widget_hide (applet->pw_dialog);
- invalid_password = FALSE;
+ invalid_auth = FALSE;
return errcode;
}
@@ -394,72 +431,132 @@ network_state_cb (libnm_glib_ctx *context,
}
#endif
-
static gboolean
credentials_expiring (gpointer *data)
{
int retval;
gboolean give_up;
- gboolean renewable;
Krb5AuthApplet* applet = (Krb5AuthApplet*) data;
- KA_DEBUG("Checking expiry: %d", applet->pw_prompt_secs);
- if (credentials_expiring_real (applet, &renewable) && is_online && !applet->show_trayicon) {
+ KA_DEBUG("Checking expiry <%ds", applet->pw_prompt_secs);
+ if (credentials_expiring_real (applet) && is_online) {
+ KA_DEBUG("Expiry @ %ld", creds_expiry);
+
+ if (!ka_renew_credentials (applet)) {
+ KA_DEBUG("Credentials renewed");
+ goto out;
+ }
+
+ /* no popup when using a trayicon */
+ if (applet->show_trayicon)
+ goto out;
+
give_up = canceled && (creds_expiry == canceled_creds_expiry);
if (!give_up) {
do {
- retval = grab_credentials (applet, renewable);
+ retval = grab_credentials (applet);
give_up = canceled &&
(creds_expiry == canceled_creds_expiry);
} while ((retval != 0) &&
(retval != KRB5_REALM_CANT_RESOLVE) &&
(retval != KRB5_KDC_UNREACH) &&
- invalid_password &&
+ invalid_auth &&
!give_up);
}
}
+out:
ka_update_status(applet, creds_expiry);
return TRUE;
}
static void
-set_options_using_creds(const Krb5AuthApplet* applet,
- krb5_context context,
- krb5_creds *creds,
- krb5_get_init_creds_opt *opts)
+set_options_from_creds(const Krb5AuthApplet* applet,
+ krb5_context context,
+ krb5_creds *in,
+ krb5_get_init_creds_opt *out)
{
krb5_deltat renew_lifetime;
int flag;
- flag = get_cred_forwardable(creds) != 0;
- krb5_get_init_creds_opt_set_forwardable(opts, flag);
- flag = get_cred_proxiable(creds) != 0;
- krb5_get_init_creds_opt_set_proxiable(opts, flag);
- flag = get_cred_renewable(creds) != 0;
- if (flag && (creds->times.renew_till > creds->times.starttime)) {
- renew_lifetime = creds->times.renew_till -
- creds->times.starttime;
- krb5_get_init_creds_opt_set_renew_life(opts,
+#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_DEFAULT_FLAGS
+ krb5_get_init_creds_opt_set_default_flags(kcontext, PACKAGE,
+ krb5_principal_get_realm(kcontext, kprincipal), out);
+#endif
+
+ flag = get_cred_forwardable(in) != 0;
+ krb5_get_init_creds_opt_set_forwardable(out, flag);
+ flag = get_cred_proxiable(in) != 0;
+ krb5_get_init_creds_opt_set_proxiable(out, flag);
+ flag = get_cred_renewable(in) != 0;
+ if (flag && (in->times.renew_till > in->times.starttime)) {
+ renew_lifetime = in->times.renew_till -
+ in->times.starttime;
+ krb5_get_init_creds_opt_set_renew_life(out,
renew_lifetime);
}
- if (creds->times.endtime >
- creds->times.starttime + applet->pw_prompt_secs) {
- krb5_get_init_creds_opt_set_tkt_life(opts,
- creds->times.endtime -
- creds->times.starttime);
+ if (in->times.endtime >
+ in->times.starttime + applet->pw_prompt_secs) {
+ krb5_get_init_creds_opt_set_tkt_life(out,
+ in->times.endtime -
+ in->times.starttime);
}
/* This doesn't do a deep copy -- fix it later. */
- /* krb5_get_init_creds_opt_set_address_list(opts, creds->addresses); */
+ /* krb5_get_init_creds_opt_set_address_list(out, creds->addresses); */
+}
+
+
+static krb5_error_code
+ka_auth_pkinit(Krb5AuthApplet* applet, krb5_creds* creds)
+{
+#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;
+
+ retval = krb5_get_init_creds_opt_alloc (kcontext, &opts);
+ if (retval)
+ goto out;
+ set_options_from_creds (applet, kcontext, creds, opts);
+
+ retval = krb5_get_init_creds_opt_set_pkinit(kcontext, opts,
+ kprincipal,
+ applet->pk_userid,
+ NULL, /* x509 anchors */
+ NULL,
+ NULL,
+ 0, /* pk_use_enc_key */
+ auth_dialog_prompter,
+ applet, /* data */
+ NULL); /* passwd */
+ KA_DEBUG("pkinit returned with %d", retval);
+ if (retval)
+ goto out;
+
+ retval = krb5_get_init_creds_password(kcontext, creds, kprincipal,
+ NULL, auth_dialog_prompter, applet,
+ 0, NULL, opts);
+out:
+ krb5_get_init_creds_opt_free(kcontext, opts);
+ return retval;
+#else /* ENABLE_PKINIT */
+ return 0;
+#endif /* ! ENABLE_PKINIT */
}
+
+/* grab credentials interactively */
static int
-grab_credentials (Krb5AuthApplet* applet, gboolean renewable)
+grab_credentials (Krb5AuthApplet* applet)
{
krb5_error_code retval;
krb5_creds my_creds;
krb5_ccache ccache;
- krb5_get_init_creds_opt opts;
+ krb5_get_init_creds_opt *opt = NULL;
memset(&my_creds, 0, sizeof(my_creds));
@@ -475,103 +572,148 @@ grab_credentials (Krb5AuthApplet* applet, gboolean renewable)
if (retval)
return retval;
- krb5_get_init_creds_opt_init (&opts);
- if (get_tgt_from_ccache (kcontext, &my_creds)) {
- set_options_using_creds (applet, kcontext, &my_creds, &opts);
- creds_expiry = my_creds.times.endtime;
-
- if (renewable) {
- retval = get_renewed_creds (kcontext, &my_creds, kprincipal, ccache, NULL);
-
- /* If we succeeded in renewing the credentials, we store it. */
- if (retval == 0) {
- goto store;
- }
- /* Else, try to get new credentials, so just fall through */
- }
- krb5_free_cred_contents (kcontext, &my_creds);
+#if ENABLE_PKINIT
+ if (applet->pk_userid) { /* try pkinit */
+#else
+ if (0) {
+#endif
+ retval = ka_auth_pkinit(applet, &my_creds);
} else {
- creds_expiry = 0;
+ retval = krb5_get_init_creds_opt_alloc (kcontext, &opt);
+ if (retval)
+ goto out;
+ set_options_from_creds (applet, kcontext, &my_creds, opt);
+ retval = krb5_get_init_creds_password(kcontext, &my_creds, kprincipal,
+ NULL, auth_dialog_prompter, applet,
+ 0, NULL, opt);
}
-
- retval = krb5_get_init_creds_password(kcontext, &my_creds, kprincipal,
- NULL, auth_dialog_prompter, applet,
- 0, NULL, &opts);
- if (canceled) {
+ creds_expiry = my_creds.times.endtime;
+ if (canceled)
canceled_creds_expiry = creds_expiry;
- }
if (retval) {
switch (retval) {
case KRB5KDC_ERR_PREAUTH_FAILED:
case KRB5KRB_AP_ERR_BAD_INTEGRITY:
- /* Invalid password, try again. */
- invalid_password = TRUE;
+#ifdef HAVE_HX509_ERR_H
+ case HX509_PKCS11_LOGIN:
+#endif
+ /* Invalid password/pin, try again. */
+ invalid_auth = TRUE;
goto out;
default:
+ KA_DEBUG("Auth failed with %d: %s", retval,
+ get_error_message(kcontext, retval));
break;
}
goto out;
}
-
-store:
retval = krb5_cc_initialize(kcontext, ccache, kprincipal);
- if (retval) {
+ if (retval)
goto out;
- }
retval = krb5_cc_store_cred(kcontext, ccache, &my_creds);
- if (retval) {
+ if (retval)
goto out;
- }
- creds_expiry = my_creds.times.endtime;
out:
+ if (opt)
+ krb5_get_init_creds_opt_free(kcontext, opt);
krb5_free_cred_contents (kcontext, &my_creds);
krb5_cc_close (kcontext, ccache);
return retval;
}
-static gboolean
-get_tgt_from_ccache (krb5_context context, krb5_creds *creds)
+/* try to renew the credentials noninteractively */
+static int
+ka_renew_credentials (Krb5AuthApplet* applet)
{
+ krb5_error_code retval;
+ krb5_creds my_creds;
krb5_ccache ccache;
- krb5_creds mcreds;
- krb5_principal principal, tgt_principal;
- gboolean ret;
-
- memset(&ccache, 0, sizeof(ccache));
- ret = FALSE;
- if (krb5_cc_default(context, &ccache) == 0) {
- memset(&principal, 0, sizeof(principal));
- if (krb5_cc_get_principal(context, ccache, &principal) == 0) {
- memset(&tgt_principal, 0, sizeof(tgt_principal));
- if (krb5_build_principal_ext(context, &tgt_principal,
- get_principal_realm_length(principal),
- get_principal_realm_data(principal),
- KRB5_TGS_NAME_SIZE,
- KRB5_TGS_NAME,
- get_principal_realm_length(principal),
- get_principal_realm_data(principal),
- 0) == 0) {
- memset(creds, 0, sizeof(*creds));
- memset(&mcreds, 0, sizeof(mcreds));
- mcreds.client = principal;
- mcreds.server = tgt_principal;
- if (krb5_cc_retrieve_cred(context, ccache,
- 0,
- &mcreds,
- creds) == 0) {
- ret = TRUE;
- } else {
- memset(creds, 0, sizeof(*creds));
- }
- krb5_free_principal(context, tgt_principal);
- }
- krb5_free_principal(context, principal);
+ krb5_get_init_creds_opt opts;
+
+ if (kprincipal == NULL) {
+ retval = krb5_parse_name(kcontext, applet->principal,
+ &kprincipal);
+ if (retval)
+ return retval;
+ }
+
+ retval = krb5_cc_default (kcontext, &ccache);
+ if (retval)
+ return retval;
+
+ retval = ka_get_tgt_from_ccache (kcontext, &my_creds);
+ if (!retval) {
+ krb5_cc_close (kcontext, ccache);
+ return -1;
+ }
+
+ krb5_get_init_creds_opt_init (&opts);
+ set_options_from_creds (applet, kcontext, &my_creds, &opts);
+
+ if (applet->renewable) {
+ retval = get_renewed_creds (kcontext, &my_creds, kprincipal, ccache, NULL);
+ if (retval)
+ goto out;
+
+ retval = krb5_cc_initialize(kcontext, ccache, kprincipal);
+ if(retval) {
+ g_warning("krb5_cc_initialize: %s", get_error_message(kcontext, retval));
+ goto out;
+ }
+ retval = krb5_cc_store_cred(kcontext, ccache, &my_creds);
+ if (retval) {
+ g_warning("krb5_cc_store_cred: %s", get_error_message(kcontext, retval));
+ goto out;
}
- krb5_cc_close(context, ccache);
}
+out:
+ creds_expiry = my_creds.times.endtime;
+ krb5_free_cred_contents (kcontext, &my_creds);
+ krb5_cc_close (kcontext, ccache);
+ return retval;
+}
+
+
+/* get principal associated with the default credentials cache - if found store
+ * it in *creds, return FALSE otwerwise */
+static gboolean
+ka_get_tgt_from_ccache (krb5_context context, krb5_creds *creds)
+{
+ krb5_ccache ccache;
+ krb5_creds pattern;
+ krb5_principal principal;
+ gboolean ret = FALSE;
+
+ ka_krb5_cc_clear_mcred(&pattern);
+
+ if (krb5_cc_default(context, &ccache))
+ return FALSE;
+
+ if (krb5_cc_get_principal(context, ccache, &principal))
+ goto out;
+
+ if (krb5_build_principal_ext(context, &pattern.server,
+ get_principal_realm_length(principal),
+ get_principal_realm_data(principal),
+ KRB5_TGS_NAME_SIZE,
+ KRB5_TGS_NAME,
+ get_principal_realm_length(principal),
+ get_principal_realm_data(principal), 0)) {
+ goto out_free_princ;
+ }
+
+ pattern.client = principal;
+ if (!krb5_cc_retrieve_cred(context, ccache, 0, &pattern, creds))
+ ret = TRUE;
+ krb5_free_principal(context, pattern.server);
+
+out_free_princ:
+ krb5_free_principal(context, principal);
+out:
+ krb5_cc_close(context, ccache);
return ret;
}
@@ -583,11 +725,10 @@ using_krb5()
krb5_creds creds;
err = krb5_init_context(&kcontext);
- if (err) {
- return TRUE;
- }
+ if (err)
+ return FALSE;
- have_tgt = get_tgt_from_ccache(kcontext, &creds);
+ have_tgt = ka_get_tgt_from_ccache(kcontext, &creds);
if (have_tgt) {
krb5_copy_principal(kcontext, creds.client, &kprincipal);
krb5_free_cred_contents (kcontext, &creds);
@@ -604,20 +745,19 @@ ka_destroy_cache (GtkMenuItem *menuitem, gpointer data)
krb5_ccache ccache;
const char* cache;
krb5_error_code ret;
- gboolean renewable;
cache = krb5_cc_default_name(kcontext);
ret = krb5_cc_resolve(kcontext, cache, &ccache);
ret = krb5_cc_destroy (kcontext, ccache);
- credentials_expiring_real(applet, &renewable);
+ credentials_expiring_real(applet);
}
static void
ka_error_dialog(int err)
{
- const char* msg = error_message(err);
+ const char* msg = get_error_message(kcontext, err);
GtkWidget *dialog = gtk_message_dialog_new (NULL,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
@@ -633,18 +773,18 @@ void
ka_grab_credentials (Krb5AuthApplet* applet)
{
int retval;
- gboolean renewable, retry;
+ gboolean retry;
applet->pw_dialog_persist = TRUE;
do {
retry = TRUE;
- retval = grab_credentials (applet, FALSE);
+ retval = grab_credentials (applet);
+ if (invalid_auth)
+ continue;
switch (retval) {
- case KRB5KRB_AP_ERR_BAD_INTEGRITY:
- retry = TRUE;
- break;
case 0: /* success */
- case KRB5_LIBOS_CANTREADPWD: /* canceled */
+ case KRB5_LIBOS_PWDINTR: /* canceled (heimdal) */
+ case KRB5_LIBOS_CANTREADPWD: /* canceled (mit) */
retry = FALSE;
break;
case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN:
@@ -656,7 +796,7 @@ ka_grab_credentials (Krb5AuthApplet* applet)
} while(retry);
applet->pw_dialog_persist = FALSE;
- credentials_expiring_real(applet, &renewable);
+ credentials_expiring_real(applet);
}
@@ -679,7 +819,7 @@ ka_create_gtk_secure_entry (GladeXML *xml, gchar *func_name, gchar *name,
}
-static void
+static void
ka_secmem_init ()
{
/* Initialize secure memory. 1 is too small, so the default size
@@ -752,7 +892,6 @@ main (int argc, char *argv[])
applet->pw_dialog = glade_xml_get_widget (applet->pw_xml, "krb5_dialog");
g_set_application_name (_("Network Authentication"));
- gtk_window_set_default_icon_name (applet->icons[1]);
#ifdef ENABLE_NETWORK_MANAGER
nm_context = libnm_glib_init ();
diff --git a/src/krb5-auth-dialog.schemas.in b/src/krb5-auth-dialog.schemas.in
new file mode 100644
index 0000000..2a3a707
--- /dev/null
+++ b/src/krb5-auth-dialog.schemas.in
@@ -0,0 +1,55 @@
+<gconfschemafile>
+ <schemalist>
+ <schema>
+ <key>/schemas/apps/::PACKAGE::/show_trayicon</key>
+ <applyto>/apps/::PACKAGE::/show_trayicon</applyto>
+ <owner>::PACKAGE::</owner>
+ <type>bool</type>
+ <default>1</default>
+
+ <locale name="C">
+ <short>Show trayicon</short>
+ <long>Show a trayicon in the status area of the panel</long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/::PACKAGE::/principal</key>
+ <applyto>/apps/::PACKAGE::/principal</applyto>
+ <owner>::PACKAGE::</owner>
+ <type>string</type>
+ <default></default>
+
+ <locale name="C">
+ <short>Kerberos principal</short>
+ <long>The kerberos principal to acquire the ticket for</long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/::PACKAGE::/pk_userid</key>
+ <applyto>/apps/::PACKAGE::/pk_userid</applyto>
+ <owner>::PACKAGE::</owner>
+ <type>string</type>
+ <default></default>
+
+ <locale name="C">
+ <short>Pkinit identifier</short>
+ <long>The principal's public/private/certificate identifier when using pkinit</long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/::PACKAGE::/prompt_minutes</key>
+ <applyto>/apps/::PACKAGE::/prompt_minutes</applyto>
+ <owner>::PACKAGE::</owner>
+ <type>int</type>
+ <default>30</default>
+
+ <locale name="C">
+ <short>Prompt minutes before expiry</short>
+ <long>Start prompting/displaying notifications that many minutes before expiry</long>
+ </locale>
+ </schema>
+ </schemalist>
+</gconfschemafile>
diff --git a/src/krb5-auth-gconf.c b/src/krb5-auth-gconf.c
index 20d22ce..a11370c 100644
--- a/src/krb5-auth-gconf.c
+++ b/src/krb5-auth-gconf.c
@@ -26,6 +26,7 @@
#define KA_GCONF_PATH "/apps/" PACKAGE
#define KA_GCONF_KEY_PRINCIPAL KA_GCONF_PATH "/principal"
+#define KA_GCONF_KEY_PK_USERID KA_GCONF_PATH "/pk_userid"
#define KA_GCONF_KEY_PROMPT_MINS KA_GCONF_PATH "/prompt_minutes"
#define KA_GCONF_KEY_SHOW_TRAYICON KA_GCONF_PATH "/show_trayicon"
@@ -124,6 +125,18 @@ ka_gconf_set_principal (GConfClient* client, Krb5AuthApplet* applet)
static gboolean
+ka_gconf_set_pk_userid (GConfClient* client, Krb5AuthApplet* applet)
+{
+ g_free (applet->pk_userid);
+ if(!ka_gconf_get_string (client, KA_GCONF_KEY_PK_USERID, &applet->pk_userid)) {
+ applet->pk_userid = NULL;
+ }
+ KA_DEBUG("Setting pk_userid to %s", applet->pk_userid ? applet->pk_userid : "<disabled>");
+ return TRUE;
+}
+
+
+static gboolean
ka_gconf_set_prompt_mins (GConfClient* client, Krb5AuthApplet* applet)
{
if(!ka_gconf_get_int (client, KA_GCONF_KEY_PROMPT_MINS, &applet->pw_prompt_secs)) {
@@ -168,6 +181,8 @@ ka_gconf_key_changed_callback (GConfClient* client,
ka_gconf_set_prompt_mins (client, applet);
} else if (g_strcmp0 (key, KA_GCONF_KEY_SHOW_TRAYICON) == 0) {
ka_gconf_set_show_trayicon (client, applet);
+ } else if (g_strcmp0 (key, KA_GCONF_KEY_PK_USERID) == 0) {
+ ka_gconf_set_pk_userid (client, applet);
} else
g_warning("Received notification for unknown gconf key %s", key);
return;
@@ -195,6 +210,7 @@ ka_gconf_init (Krb5AuthApplet* applet, int argc, char* argv[])
ka_gconf_set_principal (client, applet);
ka_gconf_set_prompt_mins (client, applet);
ka_gconf_set_show_trayicon (client, applet);
+ ka_gconf_set_pk_userid(client, applet);
success = TRUE;
out:
diff --git a/src/krb5-auth-notify.c b/src/krb5-auth-notify.c
index 3186a47..019662e 100644
--- a/src/krb5-auth-notify.c
+++ b/src/krb5-auth-notify.c
@@ -18,15 +18,14 @@
*/
#include "config.h"
-
-#ifdef HAVE_LIBNOTIFY
-
#include "krb5-auth-applet.h"
#include "krb5-auth-notify.h"
+#ifdef HAVE_LIBNOTIFY
+#include <libnotify/notify.h>
+
void
ka_send_event_notification (Krb5AuthApplet *applet,
- NotifyUrgency urgency,
const char *summary,
const char *message,
const char *icon)
@@ -50,8 +49,18 @@ ka_send_event_notification (Krb5AuthApplet *applet,
applet->notification = \
notify_notification_new_with_status_icon(summary, message, notify_icon, applet->tray_icon);
- notify_notification_set_urgency (applet->notification, urgency);
+ notify_notification_set_urgency (applet->notification, NOTIFY_URGENCY_NORMAL);
notify_notification_show (applet->notification, NULL);
}
+#else /* HAVE_LIBNOTIFY */
+
+void
+ka_send_event_notification (Krb5AuthApplet *applet __attribute__((__unused__)),
+ const char *summary __attribute__((__unused__)),
+ const char *message __attribute__((__unused__)),
+ const char *icon __attribute__((__unused__)))
+{
+}
+
#endif /* HAVE_LIBNOTIFY */
diff --git a/src/krb5-auth-notify.h b/src/krb5-auth-notify.h
index 7d27b8a..9c0ce55 100644
--- a/src/krb5-auth-notify.h
+++ b/src/krb5-auth-notify.h
@@ -21,12 +21,8 @@
#ifndef KRB5_AUTH_NOTIFY_H
#define KRB5_AUTH_NOTIFY_H
-#include <libnotify/notify.h>
-
void ka_send_event_notification (Krb5AuthApplet *applet,
- NotifyUrgency urgency,
const char *summary,
const char *message,
const char *icon);
#endif
-
bgstack15