summaryrefslogtreecommitdiffstats
path: root/src
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 /src
parent1f48dbbdb2a6edc6718f6c7b349c34043dc45601 (diff)
downloadkrb5-bf461a42b8f2d3fc3769e5166583799de7512a93.tar.gz
krb5-bf461a42b8f2d3fc3769e5166583799de7512a93.tar.xz
krb5-bf461a42b8f2d3fc3769e5166583799de7512a93.zip
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
Diffstat (limited to 'src')
-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 819efbf5ba..3abc3f95ce 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 548836f8d0..d280f59974 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 832724f32a..1ada9e2130 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);
}