From 74e7e3edba263379941aa156fc47f76736459bac Mon Sep 17 00:00:00 2001 From: caillon Date: Tue, 1 Nov 2005 13:35:01 +0000 Subject: 2005-11-01 Christopher Aillon * Makefile.am: * krb5-auth-dialog.spec.in: * src/krb5-auth-dialog.c Patch from Nalin Dahyabhai - Fix the .spec file so that it doesn't choke due to translations. - Include the .spec file in the dist tarball so that 'rpmbuild -ts' will work. - Correct a compiler warning. - Set forwardable/proxiable/lifetime from the current ccache, if there is one. - Add a "--always" flag to let us pinch-hit for 'kinit'. - Add a "--auto" flag to override it. - Interpret a preauthentication failure as a bad password. - If we already have a ccache, use its default principal as our default, in case it differs from the local user name. If the default principal changes out from under us, pick it up, too. - Don't give a bogus lifetime if the ccache is deleted between checks. git-svn-id: http://svn.gnome.org/svn/krb5-auth-dialog/trunk@38 517b70f8-ed25-0410-8bf6-f5db08f7b76e --- src/krb5-auth-dialog.c | 173 +++++++++++++++++++++++++------------------------ 1 file changed, 89 insertions(+), 84 deletions(-) (limited to 'src') diff --git a/src/krb5-auth-dialog.c b/src/krb5-auth-dialog.c index 6795f0c..907531b 100644 --- a/src/krb5-auth-dialog.c +++ b/src/krb5-auth-dialog.c @@ -39,11 +39,12 @@ static GladeXML *xml = NULL; static krb5_context kcontext; static krb5_principal kprincipal; -static char* defname = NULL; static gboolean invalid_password; +static gboolean always_run; static gint creds_expiry; static int renew_credentials (); +static gboolean get_tgt_from_ccache (krb5_context context, krb5_creds *creds); static gboolean @@ -115,6 +116,7 @@ krb5_auth_dialog_setup (GtkWidget *dialog, /* Add our extra message hints, if any */ wrong_label = glade_xml_get_widget (xml, "krb5_wrong_label"); + wrong_text = NULL; if (wrong_label) { @@ -124,9 +126,7 @@ krb5_auth_dialog_setup (GtkWidget *dialog, { int minutes_left = (creds_expiry - time(0)) / 60; if (minutes_left > 0) - { wrong_text = g_strdup_printf (_("Your credentials expire in %d minutes"), minutes_left); - } else wrong_text = g_strdup (_("Your credentials have expired")); } @@ -241,77 +241,23 @@ network_state_cb (libnm_glib_ctx *context, static gboolean credentials_expiring_real (void) { - krb5_ccache cache = NULL; - krb5_cc_cursor cur; krb5_creds my_creds; - krb5_principal princ; - krb5_flags flags; - krb5_error_code code; - int exit_status = 0; - int expiry; - gboolean retval = FALSE; - memset (&my_creds, 0, sizeof(my_creds)); - - if ((code = krb5_cc_default(kcontext, &cache))) - return FALSE; - - flags = 0; /* turns off OPENCLOSE mode */ - if ((code = krb5_cc_set_flags(kcontext, cache, flags))) - { - if (code == KRB5_FCC_NOFILE) - { -#ifdef KRB5_KRB4_COMPAT - if (name == NULL) - do_v4_ccache(0); -#endif - } - gtk_exit(1); + if (!get_tgt_from_ccache (kcontext, &my_creds)) { + creds_expiry = 0; + return TRUE; } - if ((code = krb5_cc_get_principal(kcontext, cache, &princ))) - gtk_exit(1); - - if ((code = krb5_unparse_name(kcontext, princ, &defname))) - gtk_exit(1); - - if ((code = krb5_cc_start_seq_get(kcontext, cache, &cur))) - gtk_exit(1); - - while (!(code = krb5_cc_next_cred(kcontext, cache, &cur, &my_creds))) - { - if (my_creds.times.endtime - time(0) < SECONDS_BEFORE_PROMPTING) - { - retval = TRUE; - creds_expiry = my_creds.times.endtime; - } - - krb5_free_cred_contents(kcontext, &my_creds); + if (krb5_principal_compare (kcontext, my_creds.client, kprincipal)) { + krb5_free_principal(kcontext, kprincipal); + krb5_copy_principal(kcontext, my_creds.client, &kprincipal); } + creds_expiry = my_creds.times.endtime; + if (time(NULL) + SECONDS_BEFORE_PROMPTING > my_creds.times.endtime) + retval = TRUE; - if (code == KRB5_CC_END) - { - if ((code = krb5_cc_end_seq_get(kcontext, cache, &cur))) - exit(1); -#ifndef HEIMDAL - flags = KRB5_TC_OPENCLOSE; /* turns on OPENCLOSE mode, from klist.c */ -#endif - if ((code = krb5_cc_set_flags(kcontext, cache, flags))) - gtk_exit(1); -#ifdef KRB5_KRB4_COMPAT - if (name == NULL && !status_only) - do_v4_ccache(0); -#endif - if (exit_status) - gtk_exit(exit_status); - } - else - { - gtk_exit(1); - } - - krb5_cc_close(kcontext, cache); + krb5_free_cred_contents(kcontext, &my_creds); return retval; } @@ -325,27 +271,74 @@ credentials_expiring (gpointer *data) return TRUE; } +static void +set_options_using_creds(krb5_context context, + krb5_creds *creds, + krb5_get_init_creds_opt *opts) +{ + krb5_deltat renew_lifetime; + int flag; + + flag = (creds->ticket_flags & TKT_FLG_FORWARDABLE) != 0; + krb5_get_init_creds_opt_set_forwardable(opts, flag); + flag = (creds->ticket_flags & TKT_FLG_PROXIABLE) != 0; + krb5_get_init_creds_opt_set_proxiable(opts, flag); + flag = (creds->ticket_flags & TKT_FLG_RENEWABLE) != 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, + renew_lifetime); + } + if (creds->times.endtime > + creds->times.starttime + CREDENTIAL_CHECK_INTERVAL) { + krb5_get_init_creds_opt_set_tkt_life(opts, + creds->times.endtime - + creds->times.starttime); + } + /* This doesn't do a deep copy -- fix it later. */ + /* krb5_get_init_creds_opt_set_address_list(opts, creds->addresses); */ +} + static int renew_credentials (void) { krb5_error_code retval; krb5_creds my_creds; krb5_ccache ccache; + krb5_get_init_creds_opt opts; - retval = krb5_parse_name(kcontext, g_get_user_name (), &kprincipal); - if (retval) - return retval; + if (kprincipal == NULL) { + retval = krb5_parse_name(kcontext, g_get_user_name (), + &kprincipal); + if (retval) { + return retval; + } + } + + krb5_get_init_creds_opt_init(&opts); + if (get_tgt_from_ccache (kcontext, &my_creds)) + { + set_options_using_creds(kcontext, &my_creds, &opts); + creds_expiry = my_creds.times.endtime; + krb5_free_cred_contents(kcontext, &my_creds); + } else { + creds_expiry = 0; + } retval = krb5_get_init_creds_password(kcontext, &my_creds, kprincipal, NULL, krb5_gtk_prompter, 0, - 0, NULL, NULL); + 0, NULL, &opts); if (retval) { - if (retval == KRB5KRB_AP_ERR_BAD_INTEGRITY) - { - /* Invalid password, try again. */ - invalid_password = TRUE; - return renew_credentials(); + switch (retval) { + case KRB5KDC_ERR_PREAUTH_FAILED: + case KRB5KRB_AP_ERR_BAD_INTEGRITY: + /* Invalid password, try again. */ + invalid_password = TRUE; + return renew_credentials(); + default: + break; } return retval; } @@ -362,19 +355,18 @@ renew_credentials (void) if (retval) goto out; + creds_expiry = my_creds.times.endtime; + out: krb5_cc_close (kcontext, ccache); - if (kprincipal) - krb5_free_principal (kcontext, kprincipal); return retval; } -gboolean +static gboolean get_tgt_from_ccache (krb5_context context, krb5_creds *creds) { krb5_ccache ccache; - krb5_cc_cursor cursor; krb5_creds mcreds; krb5_principal principal, tgt_principal; gboolean ret; @@ -417,7 +409,7 @@ get_tgt_from_ccache (krb5_context context, krb5_creds *creds) return ret; } -gboolean +static gboolean using_krb5() { krb5_error_code err; @@ -429,8 +421,10 @@ using_krb5() return TRUE; have_tgt = get_tgt_from_ccache(kcontext, &creds); - if (have_tgt) + if (have_tgt) { + krb5_copy_principal(kcontext, creds.client, &kprincipal); krb5_free_cred_contents (kcontext, &creds); + } return have_tgt; } @@ -440,6 +434,14 @@ main (int argc, char *argv[]) { GtkWidget *dialog; GnomeClient *client; + int run_auto = 0, run_always = 0; + struct poptOption options[] = { + {"auto", 'a', 0, &run_auto, 0, + "Only run if an initialized ccache is found (default)", NULL}, + {"always", 'A', 0, &run_always, 0, + "Always run", NULL}, + {NULL}, + }; #ifdef ENABLE_NETWORK_MANAGER libnm_glib_ctx *nm_context; @@ -447,12 +449,15 @@ main (int argc, char *argv[]) #endif gnome_program_init (PACKAGE, VERSION, LIBGNOMEUI_MODULE, - argc, argv, GNOME_PARAM_NONE); + argc, argv, GNOME_PARAM_POPT_TABLE, options, + GNOME_PARAM_NONE); client = gnome_master_client (); gnome_client_set_restart_style (client, GNOME_RESTART_ANYWAY); - if (using_krb5 ()) + if (run_always && !run_auto) + always_run++; + if (using_krb5 () || always_run) { g_signal_connect (G_OBJECT (client), "die", G_CALLBACK (gtk_main_quit), NULL); -- cgit v1.2.3