summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandra Ellwood <lxs@mit.edu>2008-09-29 18:52:53 +0000
committerAlexandra Ellwood <lxs@mit.edu>2008-09-29 18:52:53 +0000
commitbf461a42b8f2d3fc3769e5166583799de7512a93 (patch)
tree5dd65eef016bcffa4d94889fe2ca07adbf15a1a8
parent1f48dbbdb2a6edc6718f6c7b349c34043dc45601 (diff)
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
-rw-r--r--src/kim/lib/kim_ui.c227
-rw-r--r--src/kim/lib/kim_ui_private.h1
-rw-r--r--src/kim/lib/mac/kim_os_ui_gui.c2
3 files changed, 138 insertions, 92 deletions
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;
}
@@ -99,6 +119,10 @@ kim_error kim_ui_enter_identity (kim_ui_context *in_context,
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,
out_identity);
@@ -135,6 +159,10 @@ kim_error kim_ui_select_identity (kim_ui_context *in_context,
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,
in_hints,
@@ -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);
@@ -285,6 +317,10 @@ kim_error kim_ui_change_password (kim_ui_context *in_context,
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,
in_identity,
@@ -320,58 +356,6 @@ kim_error kim_ui_change_password (kim_ui_context *in_context,
}
/* ------------------------------------------------------------------------ */
-/* 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,
kim_identity in_identity,
@@ -386,6 +370,10 @@ kim_error kim_ui_handle_error (kim_ui_context *in_context,
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,
in_identity,
@@ -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);
}