From: Alexandra Ellwood Date: Mon, 29 Sep 2008 18:52:53 +0000 (+0000) Subject: UI should lazy init so that init and fini are only called if one X-Git-Tag: krb5-1.7-alpha1~391 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=bf461a42b8f2d3fc3769e5166583799de7512a93;p=krb5.git UI should lazy init so that init and fini are only called if one of the UI calls is called. The problem is that when you call krb5_get_init_creds_* you don't know if it will call the prompter or not. (It won't if the password is saved in the keychain or if pkinit succeeds.) ticket: 6055 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@20780 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/kim/lib/kim_ui.c b/src/kim/lib/kim_ui.c index 819efbf5b..3abc3f95c 100644 --- a/src/kim/lib/kim_ui.c +++ b/src/kim/lib/kim_ui.c @@ -40,18 +40,17 @@ static kim_prompt_type kim_ui_ptype2ktype (krb5_prompt_type type) return kim_prompt_type_preauth; } - #pragma mark - /* ------------------------------------------------------------------------ */ -kim_error kim_ui_init (kim_ui_context *io_context) +static kim_error kim_ui_init_lazy (kim_ui_context *io_context) { kim_error err = KIM_NO_ERROR; if (!err && !io_context) { err = check_error (KIM_NULL_PARAMETER_ERR); } - if (!err) { + if (!err && !io_context->initialized) { #ifndef LEAN_CLIENT kim_ui_environment environment = kim_library_ui_environment (); @@ -78,9 +77,30 @@ kim_error kim_ui_init (kim_ui_context *io_context) err = check_error (KIM_NO_UI_ERR); } #endif /* LEAN_CLIENT */ + + if (!err) { + io_context->initialized = 1; + } } + return check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +kim_error kim_ui_init (kim_ui_context *io_context) +{ + kim_error err = KIM_NO_ERROR; + + if (!err && !io_context) { err = check_error (KIM_NULL_PARAMETER_ERR); } + if (!err) { + /* Lazy initialization so we only actually initialize if a prompt + * gets called. This is important because krb5_get_init_creds_* + * can't tell us if a prompt is going to get called in advance */ + io_context->initialized = 0; io_context->identity = NULL; io_context->prompt_count = 0; } @@ -98,6 +118,10 @@ kim_error kim_ui_enter_identity (kim_ui_context *in_context, if (!err && !in_context ) { err = check_error (KIM_NULL_PARAMETER_ERR); } if (!err && !out_identity) { err = check_error (KIM_NULL_PARAMETER_ERR); } + if (!err) { + err = kim_ui_init_lazy (in_context); + } + if (!err) { if (in_context->type == kim_ui_type_gui_plugin) { err = kim_ui_plugin_enter_identity (in_context, @@ -134,6 +158,10 @@ kim_error kim_ui_select_identity (kim_ui_context *in_context, if (!err && !in_hints ) { err = check_error (KIM_NULL_PARAMETER_ERR); } if (!err && !out_identity) { err = check_error (KIM_NULL_PARAMETER_ERR); } + if (!err) { + err = kim_ui_init_lazy (in_context); + } + if (!err) { if (in_context->type == kim_ui_type_gui_plugin) { err = kim_ui_plugin_select_identity (in_context, @@ -201,44 +229,48 @@ krb5_error_code kim_ui_prompter (krb5_context in_krb5_context, if (!got_saved_password) { context->prompt_count++; - - if (context->type == kim_ui_type_gui_plugin) { - err = kim_ui_plugin_auth_prompt (context, - context->identity, - type, - in_prompts[i].hidden, - in_name, - in_banner, - in_prompts[i].prompt, - &reply); - + + err = kim_ui_init_lazy (in_context); + + if (!err) { + if (context->type == kim_ui_type_gui_plugin) { + err = kim_ui_plugin_auth_prompt (context, + context->identity, + type, + in_prompts[i].hidden, + in_name, + in_banner, + in_prompts[i].prompt, + &reply); + #ifndef LEAN_CLIENT - } else if (context->type == kim_ui_type_gui_builtin) { - err = kim_os_ui_gui_auth_prompt (context, - context->identity, - type, - in_prompts[i].hidden, - in_name, - in_banner, - in_prompts[i].prompt, - &reply); - - } else if (context->type == kim_ui_type_cli) { - err = kim_ui_cli_auth_prompt (context, - context->identity, - type, - in_prompts[i].hidden, - in_name, - in_banner, - in_prompts[i].prompt, - &reply); + } else if (context->type == kim_ui_type_gui_builtin) { + err = kim_os_ui_gui_auth_prompt (context, + context->identity, + type, + in_prompts[i].hidden, + in_name, + in_banner, + in_prompts[i].prompt, + &reply); + + } else if (context->type == kim_ui_type_cli) { + err = kim_ui_cli_auth_prompt (context, + context->identity, + type, + in_prompts[i].hidden, + in_name, + in_banner, + in_prompts[i].prompt, + &reply); #endif /* LEAN_CLIENT */ - - } else { - err = check_error (KIM_NO_UI_ERR); + + } else { + err = check_error (KIM_NO_UI_ERR); + } } } - + if (!err) { uint32_t reply_len = strlen (reply); @@ -284,6 +316,10 @@ kim_error kim_ui_change_password (kim_ui_context *in_context, if (!err && !out_new_password ) { err = check_error (KIM_NULL_PARAMETER_ERR); } if (!err && !out_verify_password) { err = check_error (KIM_NULL_PARAMETER_ERR); } + if (!err) { + err = kim_ui_init_lazy (in_context); + } + if (!err) { if (in_context->type == kim_ui_type_gui_plugin) { err = kim_ui_plugin_change_password (in_context, @@ -319,58 +355,6 @@ kim_error kim_ui_change_password (kim_ui_context *in_context, return check_error (err); } -/* ------------------------------------------------------------------------ */ -/* Helper function */ - -kim_error kim_ui_handle_kim_error (kim_ui_context *in_context, - kim_identity in_identity, - enum kim_ui_error_type in_type, - kim_error in_error) -{ - kim_error err = KIM_NO_ERROR; - kim_string message = NULL; - kim_string description = NULL; - - if (!err) { - /* Do this first so last error doesn't get overwritten */ - err = kim_string_create_for_last_error (&description, in_error); - } - - if (!err && !in_context) { err = check_error (KIM_NULL_PARAMETER_ERR); } - - if (!err) { - kim_string key = NULL; - - switch (in_type) { - case kim_ui_error_type_authentication: - key = "Kerberos Login Failed:"; - break; - - case kim_ui_error_type_change_password: - key = "Kerberos Change Password Failed:"; - break; - - case kim_ui_error_type_selection: - case kim_ui_error_type_generic: - default: - key = "Kerberos Operation Failed:"; - break; - } - - err = kim_os_string_create_localized (&message, key); - } - - if (!err) { - err = kim_ui_handle_error (in_context, in_identity, - in_error, message, description); - } - - kim_string_free (&description); - kim_string_free (&message); - - return check_error (err); -} - /* ------------------------------------------------------------------------ */ kim_error kim_ui_handle_error (kim_ui_context *in_context, @@ -385,6 +369,10 @@ kim_error kim_ui_handle_error (kim_ui_context *in_context, if (!err && !in_error_message ) { err = check_error (KIM_NULL_PARAMETER_ERR); } if (!err && !in_error_description) { err = check_error (KIM_NULL_PARAMETER_ERR); } + if (!err) { + err = kim_ui_init_lazy (in_context); + } + if (!err) { if (in_context->type == kim_ui_type_gui_plugin) { err = kim_ui_plugin_handle_error (in_context, @@ -422,7 +410,9 @@ kim_error kim_ui_handle_error (kim_ui_context *in_context, void kim_ui_free_string (kim_ui_context *in_context, char **io_string) { - if (in_context && io_string && *io_string) { + kim_error err = kim_ui_init_lazy (in_context); + + if (!err && in_context && io_string && *io_string) { if (in_context->type == kim_ui_type_gui_plugin) { kim_ui_plugin_free_string (in_context, io_string); @@ -436,7 +426,6 @@ void kim_ui_free_string (kim_ui_context *in_context, kim_ui_cli_free_string (in_context, io_string); #endif /* LEAN_CLIENT */ - } } } @@ -449,7 +438,7 @@ kim_error kim_ui_fini (kim_ui_context *io_context) if (!err && !io_context) { err = check_error (KIM_NULL_PARAMETER_ERR); } - if (!err) { + if (!err && io_context->initialized) { if (io_context->type == kim_ui_type_gui_plugin) { err = kim_ui_plugin_fini (io_context); @@ -468,3 +457,57 @@ kim_error kim_ui_fini (kim_ui_context *io_context) return check_error (err); } + +#pragma mark - + +/* ------------------------------------------------------------------------ */ +/* Helper function */ + +kim_error kim_ui_handle_kim_error (kim_ui_context *in_context, + kim_identity in_identity, + enum kim_ui_error_type in_type, + kim_error in_error) +{ + kim_error err = KIM_NO_ERROR; + kim_string message = NULL; + kim_string description = NULL; + + if (!err) { + /* Do this first so last error doesn't get overwritten */ + err = kim_string_create_for_last_error (&description, in_error); + } + + if (!err && !in_context) { err = check_error (KIM_NULL_PARAMETER_ERR); } + + if (!err) { + kim_string key = NULL; + + switch (in_type) { + case kim_ui_error_type_authentication: + key = "Kerberos Login Failed:"; + break; + + case kim_ui_error_type_change_password: + key = "Kerberos Change Password Failed:"; + break; + + case kim_ui_error_type_selection: + case kim_ui_error_type_generic: + default: + key = "Kerberos Operation Failed:"; + break; + } + + err = kim_os_string_create_localized (&message, key); + } + + if (!err) { + err = kim_ui_handle_error (in_context, in_identity, + in_error, message, description); + } + + kim_string_free (&description); + kim_string_free (&message); + + return check_error (err); +} diff --git a/src/kim/lib/kim_ui_private.h b/src/kim/lib/kim_ui_private.h index 548836f8d..d280f5997 100644 --- a/src/kim/lib/kim_ui_private.h +++ b/src/kim/lib/kim_ui_private.h @@ -45,6 +45,7 @@ enum kim_ui_error_type { /* declare struct on stack. Deep contents will be freed by kim_ui_fini. */ typedef struct kim_ui_context { + kim_boolean initialized; enum kim_ui_type type; void *tcontext; kim_identity identity; diff --git a/src/kim/lib/mac/kim_os_ui_gui.c b/src/kim/lib/mac/kim_os_ui_gui.c index 832724f32..1ada9e213 100644 --- a/src/kim/lib/mac/kim_os_ui_gui.c +++ b/src/kim/lib/mac/kim_os_ui_gui.c @@ -58,6 +58,8 @@ kim_error kim_os_ui_gui_init (kim_ui_context *io_context) k5_ipc_stream request = NULL; k5_ipc_stream reply = NULL; + if (!err && !io_context) { err = check_error (KIM_NULL_PARAMETER_ERR); } + if (!err) { err = kim_library_get_application_name (&name); }