summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandra Ellwood <lxs@mit.edu>2008-09-29 20:48:43 +0000
committerAlexandra Ellwood <lxs@mit.edu>2008-09-29 20:48:43 +0000
commit49f4372f3f635a6f8722d430d86a480db7db6e79 (patch)
tree10187dafbd0ea26dedd6d5cda5bb54a38d8c62de
parentbf461a42b8f2d3fc3769e5166583799de7512a93 (diff)
downloadkrb5-49f4372f3f635a6f8722d430d86a480db7db6e79.tar.gz
krb5-49f4372f3f635a6f8722d430d86a480db7db6e79.tar.xz
krb5-49f4372f3f635a6f8722d430d86a480db7db6e79.zip
Added support for disabling password saving, both globally
and also per prompt via the UI. ticket: 6055 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@20781 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r--src/include/kim/kim_ui_plugin.h7
-rw-r--r--src/kim/agent/mac/ServerDemux.h1
-rw-r--r--src/kim/agent/mac/ServerDemux.m12
-rw-r--r--src/kim/lib/kim_credential.c33
-rw-r--r--src/kim/lib/kim_identity.c19
-rw-r--r--src/kim/lib/kim_identity_private.h10
-rw-r--r--src/kim/lib/kim_ui.c26
-rw-r--r--src/kim/lib/kim_ui_cli.c9
-rw-r--r--src/kim/lib/kim_ui_cli_private.h4
-rw-r--r--src/kim/lib/kim_ui_gui_private.h4
-rw-r--r--src/kim/lib/kim_ui_plugin.c8
-rw-r--r--src/kim/lib/kim_ui_plugin_private.h4
-rw-r--r--src/kim/lib/kim_ui_private.h1
-rw-r--r--src/kim/lib/mac/kim_os_identity.c37
-rw-r--r--src/kim/lib/mac/kim_os_ui_gui.c26
15 files changed, 172 insertions, 29 deletions
diff --git a/src/include/kim/kim_ui_plugin.h b/src/include/kim/kim_ui_plugin.h
index 0f6895ffc6..99923e5103 100644
--- a/src/include/kim/kim_ui_plugin.h
+++ b/src/include/kim/kim_ui_plugin.h
@@ -88,14 +88,19 @@ typedef struct kim_ui_plugin_ftable_v0 {
kim_identity *out_identity);
/* Present UI to display authentication to the user */
+ /* If in_allow_save_reply is FALSE do not display UI to allow the user
+ * to save their password. In this case the value of out_save_reply will
+ * be ignored. */
kim_error (*auth_prompt) (void *in_context,
kim_identity in_identity,
kim_prompt_type in_type,
+ kim_boolean in_allow_save_reply,
kim_boolean in_hide_reply,
kim_string in_title,
kim_string in_message,
kim_string in_description,
- char **out_reply);
+ char **out_reply,
+ kim_boolean *out_save_reply);
/* Prompt to change the identity's password.
* May be combined with an auth_prompt if additional auth is required,
diff --git a/src/kim/agent/mac/ServerDemux.h b/src/kim/agent/mac/ServerDemux.h
index 12afa36c2c..1f1de5964c 100644
--- a/src/kim/agent/mac/ServerDemux.h
+++ b/src/kim/agent/mac/ServerDemux.h
@@ -43,6 +43,7 @@ int32_t kim_handle_reply_select_identity (mach_port_t in_reply_port,
int32_t kim_handle_reply_auth_prompt (mach_port_t in_reply_port,
kim_string in_prompt_response,
+ kim_boolean in_allow_save_response,
int32_t in_error);
int32_t kim_handle_reply_change_password (mach_port_t in_reply_port,
diff --git a/src/kim/agent/mac/ServerDemux.m b/src/kim/agent/mac/ServerDemux.m
index bc8525b0d6..a70a668c43 100644
--- a/src/kim/agent/mac/ServerDemux.m
+++ b/src/kim/agent/mac/ServerDemux.m
@@ -267,6 +267,7 @@ static int32_t kim_handle_request_auth_prompt (mach_port_t in_client_port,
int32_t err = 0;
char *identity_string = NULL;
int32_t type = 0;
+ int32_t allow_save_reply = 0;
int32_t hide_reply = 0;
char *title = NULL;
char *message = NULL;
@@ -281,6 +282,10 @@ static int32_t kim_handle_request_auth_prompt (mach_port_t in_client_port,
}
if (!err) {
+ err = k5_ipc_stream_read_int32 (in_request_stream, &allow_save_reply);
+ }
+
+ if (!err) {
err = k5_ipc_stream_read_int32 (in_request_stream, &hide_reply);
}
@@ -299,7 +304,7 @@ static int32_t kim_handle_request_auth_prompt (mach_port_t in_client_port,
if (!err) {
NSLog (@"Got auth prompt with identity '%s', type '%d', hide '%d', title '%s', message '%s', description '%s'",
identity_string, type, hide_reply, title, message, description);
- err = kim_handle_reply_auth_prompt (in_reply_port, "ydobon", 0);
+ err = kim_handle_reply_auth_prompt (in_reply_port, "ydobon", 0, 0);
#warning Send auth prompt message to main thread with 2 ports and arguments
}
@@ -315,6 +320,7 @@ static int32_t kim_handle_request_auth_prompt (mach_port_t in_client_port,
int32_t kim_handle_reply_auth_prompt (mach_port_t in_reply_port,
kim_string in_prompt_response,
+ kim_boolean in_allow_save_response,
int32_t in_error)
{
int32_t err = 0;
@@ -332,6 +338,10 @@ int32_t kim_handle_reply_auth_prompt (mach_port_t in_reply_port,
err = k5_ipc_stream_write_string (reply, in_prompt_response);
}
+ if (!err && !in_error) {
+ err = k5_ipc_stream_write_int32 (reply, in_allow_save_response);
+ }
+
if (!err) {
err = k5_ipc_server_send_reply (in_reply_port, reply);
}
diff --git a/src/kim/lib/kim_credential.c b/src/kim/lib/kim_credential.c
index ee2ec0448e..64561896d5 100644
--- a/src/kim/lib/kim_credential.c
+++ b/src/kim/lib/kim_credential.c
@@ -278,10 +278,41 @@ kim_error kim_credential_create_new (kim_credential *out_credential,
&credential->creds));
}
+ if (!err && context.password_to_save) {
+ /* If we were successful, save any password we got */
+ err = kim_os_identity_set_saved_password (identity,
+ context.password_to_save);
+
+
+ }
if (err == KRB5KDC_ERR_KEY_EXP) {
+ kim_string new_password = NULL;
+
err = kim_identity_change_password_common (identity, 1,
- &context);
+ &context,
+ &new_password);
+
+ if (!err) {
+ /* set counter to zero so we can tell if we got prompted */
+ context.prompt_count = 0;
+
+ err = krb5_error (credential->context,
+ krb5_get_init_creds_password (credential->context,
+ &creds,
+ principal,
+ (char *) new_password,
+ kim_ui_prompter,
+ &context,
+ start_time,
+ service,
+ opts));
+
+ prompt_count = context.prompt_count; /* remember if we got prompts */
+ if (!err) { free_creds = 1; }
+ }
+
+ kim_string_free (&new_password);
}
if (!err || err == KIM_USER_CANCELED_ERR) {
diff --git a/src/kim/lib/kim_identity.c b/src/kim/lib/kim_identity.c
index b431ae8b8d..10604e6d07 100644
--- a/src/kim/lib/kim_identity.c
+++ b/src/kim/lib/kim_identity.c
@@ -673,7 +673,8 @@ static kim_error kim_identity_change_password_with_credential (kim_identity i
kim_error kim_identity_change_password_common (kim_identity in_identity,
kim_boolean in_old_password_expired,
- kim_ui_context *in_ui_context)
+ kim_ui_context *in_ui_context,
+ kim_string *out_new_password)
{
kim_error err = KIM_NO_ERROR;
kim_boolean done = 0;
@@ -700,7 +701,9 @@ kim_error kim_identity_change_password_common (kim_identity in_identity,
if (!err) {
kim_comparison comparison;
- err = kim_string_compare (new_password, verify_password, &comparison);
+ err = kim_string_compare (new_password,
+ verify_password,
+ &comparison);
if (!err && !kim_comparison_is_equal_to (comparison)) {
err = check_error (KIM_PASSWORD_MISMATCH_ERR);
}
@@ -748,9 +751,8 @@ kim_error kim_identity_change_password_common (kim_identity in_identity,
kim_ui_error_type_change_password,
err);
- if (was_prompted) {
- /* User was prompted and might have entered bad info
- * so let them try again. */
+ if (was_prompted || err == KIM_PASSWORD_MISMATCH_ERR) {
+ /* User could have entered bad info so let them try again. */
err = terr;
}
@@ -758,6 +760,10 @@ kim_error kim_identity_change_password_common (kim_identity in_identity,
/* password change succeeded or the user gave up */
done = 1;
+ if (!err && out_new_password) {
+ err = kim_string_copy (out_new_password, new_password);
+ }
+
if (!err) {
kim_error terr = KIM_NO_ERROR;
kim_string saved_password = NULL;
@@ -801,7 +807,8 @@ kim_error kim_identity_change_password (kim_identity in_identity)
}
if (!err) {
- err = kim_identity_change_password_common (in_identity, 0, &context);
+ err = kim_identity_change_password_common (in_identity, 0,
+ &context, NULL);
}
if (ui_inited) {
diff --git a/src/kim/lib/kim_identity_private.h b/src/kim/lib/kim_identity_private.h
index f8ef4d6299..2a212aa1cc 100644
--- a/src/kim/lib/kim_identity_private.h
+++ b/src/kim/lib/kim_identity_private.h
@@ -39,16 +39,20 @@ kim_error kim_identity_is_tgt_service (kim_identity in_identity,
kim_error kim_os_identity_create_for_username (kim_identity *out_identity);
+
+kim_boolean kim_os_identity_allow_save_password (void);
+
kim_error kim_os_identity_get_saved_password (kim_identity in_identity,
kim_string *out_password);
kim_error kim_os_identity_set_saved_password (kim_identity in_identity,
kim_string in_password);
+kim_error kim_os_identity_remove_saved_password (kim_identity in_identity);
+
kim_error kim_identity_change_password_common (kim_identity in_identity,
kim_boolean in_old_password_expired,
- kim_ui_context *in_ui_context);
-
-kim_error kim_os_identity_remove_saved_password (kim_identity in_identity);
+ kim_ui_context *in_ui_context,
+ kim_string *out_new_password);
#endif /* KIM_IDENTITY_PRIVATE_H */
diff --git a/src/kim/lib/kim_ui.c b/src/kim/lib/kim_ui.c
index 3abc3f95ce..b585ff7a01 100644
--- a/src/kim/lib/kim_ui.c
+++ b/src/kim/lib/kim_ui.c
@@ -103,6 +103,7 @@ kim_error kim_ui_init (kim_ui_context *io_context)
io_context->initialized = 0;
io_context->identity = NULL;
io_context->prompt_count = 0;
+ io_context->password_to_save = NULL;
}
return check_error (err);
@@ -228,6 +229,9 @@ krb5_error_code kim_ui_prompter (krb5_context in_krb5_context,
}
if (!got_saved_password) {
+ kim_boolean save_reply = FALSE;
+ kim_boolean allow_save_password = kim_os_identity_allow_save_password ();
+
context->prompt_count++;
err = kim_ui_init_lazy (in_context);
@@ -237,38 +241,52 @@ krb5_error_code kim_ui_prompter (krb5_context in_krb5_context,
err = kim_ui_plugin_auth_prompt (context,
context->identity,
type,
+ allow_save_password,
in_prompts[i].hidden,
in_name,
in_banner,
in_prompts[i].prompt,
- &reply);
+ &reply,
+ &save_reply);
#ifndef LEAN_CLIENT
} else if (context->type == kim_ui_type_gui_builtin) {
err = kim_os_ui_gui_auth_prompt (context,
context->identity,
type,
+ allow_save_password,
in_prompts[i].hidden,
in_name,
in_banner,
in_prompts[i].prompt,
- &reply);
+ &reply,
+ &save_reply);
} else if (context->type == kim_ui_type_cli) {
err = kim_ui_cli_auth_prompt (context,
context->identity,
type,
+ allow_save_password,
in_prompts[i].hidden,
in_name,
in_banner,
in_prompts[i].prompt,
- &reply);
+ &reply,
+ &save_reply);
#endif /* LEAN_CLIENT */
} else {
err = check_error (KIM_NO_UI_ERR);
}
}
+
+ if (!err && type == kim_prompt_type_password) {
+ kim_string_free (&context->password_to_save);
+
+ if (allow_save_password && save_reply) {
+ err = kim_string_copy (&context->password_to_save, reply);
+ }
+ }
}
if (!err) {
@@ -453,6 +471,8 @@ kim_error kim_ui_fini (kim_ui_context *io_context)
} else {
err = check_error (KIM_NO_UI_ERR);
}
+
+ kim_string_free (&io_context->password_to_save);
}
return check_error (err);
diff --git a/src/kim/lib/kim_ui_cli.c b/src/kim/lib/kim_ui_cli.c
index f26e328822..cd7cea601f 100644
--- a/src/kim/lib/kim_ui_cli.c
+++ b/src/kim/lib/kim_ui_cli.c
@@ -152,11 +152,13 @@ kim_error kim_ui_cli_select_identity (kim_ui_context *in_context,
kim_error kim_ui_cli_auth_prompt (kim_ui_context *in_context,
kim_identity in_identity,
kim_prompt_type in_type,
+ kim_boolean in_allow_save_reply,
kim_boolean in_hide_reply,
kim_string in_title,
kim_string in_message,
kim_string in_description,
- char **out_reply)
+ char **out_reply,
+ kim_boolean *out_save_reply)
{
kim_error err = KIM_NO_ERROR;
@@ -210,6 +212,11 @@ kim_error kim_ui_cli_auth_prompt (kim_ui_context *in_context,
err = kim_string_create_from_buffer ((kim_string *) out_reply,
prompts[0].reply->data,
prompts[0].reply->length);
+ if (!err) {
+ /* always allow password saving */
+ *out_save_reply = (in_allow_save_reply &&
+ in_type == kim_prompt_type_password);
+ }
}
if (k5context) { krb5_free_context (k5context); }
diff --git a/src/kim/lib/kim_ui_cli_private.h b/src/kim/lib/kim_ui_cli_private.h
index 872fb4b226..5059196003 100644
--- a/src/kim/lib/kim_ui_cli_private.h
+++ b/src/kim/lib/kim_ui_cli_private.h
@@ -46,11 +46,13 @@ kim_error kim_ui_cli_select_identity (kim_ui_context *in_context,
kim_error kim_ui_cli_auth_prompt (kim_ui_context *in_context,
kim_identity in_identity,
kim_prompt_type in_type,
+ kim_boolean in_allow_save_reply,
kim_boolean in_hide_reply,
kim_string in_title,
kim_string in_message,
kim_string in_description,
- char **out_reply);
+ char **out_reply,
+ kim_boolean *out_save_reply);
kim_error kim_ui_cli_change_password (kim_ui_context *in_context,
kim_identity in_identity,
diff --git a/src/kim/lib/kim_ui_gui_private.h b/src/kim/lib/kim_ui_gui_private.h
index b89cf348fa..dd2f2a9e5c 100644
--- a/src/kim/lib/kim_ui_gui_private.h
+++ b/src/kim/lib/kim_ui_gui_private.h
@@ -46,11 +46,13 @@ kim_error kim_os_ui_gui_select_identity (kim_ui_context *in_context,
kim_error kim_os_ui_gui_auth_prompt (kim_ui_context *in_context,
kim_identity in_identity,
kim_prompt_type in_type,
+ kim_boolean in_allow_save_reply,
kim_boolean in_hide_reply,
kim_string in_title,
kim_string in_message,
kim_string in_description,
- char **out_reply);
+ char **out_reply,
+ kim_boolean *out_save_reply);
kim_error kim_os_ui_gui_change_password (kim_ui_context *in_context,
kim_identity in_identity,
diff --git a/src/kim/lib/kim_ui_plugin.c b/src/kim/lib/kim_ui_plugin.c
index 49cceaeb4e..0ac2f14940 100644
--- a/src/kim/lib/kim_ui_plugin.c
+++ b/src/kim/lib/kim_ui_plugin.c
@@ -202,11 +202,13 @@ kim_error kim_ui_plugin_select_identity (kim_ui_context *in_context,
kim_error kim_ui_plugin_auth_prompt (kim_ui_context *in_context,
kim_identity in_identity,
kim_prompt_type in_type,
+ kim_boolean in_allow_save_reply,
kim_boolean in_hide_reply,
kim_string in_title,
kim_string in_message,
kim_string in_description,
- char **out_reply)
+ char **out_reply,
+ kim_boolean *out_save_reply)
{
kim_error err = KIM_NO_ERROR;
@@ -221,11 +223,13 @@ kim_error kim_ui_plugin_auth_prompt (kim_ui_context *in_context,
err = context->ftable->auth_prompt (context->plugin_context,
in_identity,
in_type,
+ in_allow_save_reply,
in_hide_reply,
in_title,
in_message,
in_description,
- out_reply);
+ out_reply,
+ out_save_reply);
}
return check_error (err);
diff --git a/src/kim/lib/kim_ui_plugin_private.h b/src/kim/lib/kim_ui_plugin_private.h
index e4d3547642..58eb60f408 100644
--- a/src/kim/lib/kim_ui_plugin_private.h
+++ b/src/kim/lib/kim_ui_plugin_private.h
@@ -45,11 +45,13 @@ kim_error kim_ui_plugin_select_identity (kim_ui_context *in_context,
kim_error kim_ui_plugin_auth_prompt (kim_ui_context *in_context,
kim_identity in_identity,
kim_prompt_type in_type,
+ kim_boolean in_allow_save_reply,
kim_boolean in_hide_reply,
kim_string in_title,
kim_string in_message,
kim_string in_description,
- char **out_reply);
+ char **out_reply,
+ kim_boolean *out_save_reply);
kim_error kim_ui_plugin_change_password (kim_ui_context *in_context,
kim_identity in_identity,
diff --git a/src/kim/lib/kim_ui_private.h b/src/kim/lib/kim_ui_private.h
index d280f59974..f4d1b10d9b 100644
--- a/src/kim/lib/kim_ui_private.h
+++ b/src/kim/lib/kim_ui_private.h
@@ -50,6 +50,7 @@ typedef struct kim_ui_context {
void *tcontext;
kim_identity identity;
kim_count prompt_count;
+ kim_string password_to_save;
} kim_ui_context;
diff --git a/src/kim/lib/mac/kim_os_identity.c b/src/kim/lib/mac/kim_os_identity.c
index 690a2f252c..fba941820a 100644
--- a/src/kim/lib/mac/kim_os_identity.c
+++ b/src/kim/lib/mac/kim_os_identity.c
@@ -32,6 +32,33 @@
/* ------------------------------------------------------------------------ */
+kim_boolean kim_os_identity_allow_save_password (void)
+{
+ kim_boolean disabled = 0;
+ CFPropertyListRef disable_pref = NULL;
+
+ disable_pref = CFPreferencesCopyValue (CFSTR ("SavePasswordDisabled"),
+ CFSTR ("edu.mit.Kerberos.KerberosAgent"),
+ kCFPreferencesAnyUser,
+ kCFPreferencesAnyHost);
+ if (!disable_pref) {
+ disable_pref = CFPreferencesCopyValue (CFSTR ("SavePasswordDisabled"),
+ CFSTR ("edu.mit.Kerberos.KerberosAgent"),
+ kCFPreferencesAnyUser,
+ kCFPreferencesCurrentHost);
+ }
+
+ disabled = (disable_pref &&
+ CFGetTypeID (disable_pref) == CFBooleanGetTypeID () &&
+ CFBooleanGetValue (disable_pref));
+
+ if (disable_pref) { CFRelease (disable_pref); }
+
+ return !disabled;
+}
+
+/* ------------------------------------------------------------------------ */
+
kim_error kim_os_identity_get_saved_password (kim_identity in_identity,
kim_string *out_password)
{
@@ -44,6 +71,11 @@ kim_error kim_os_identity_get_saved_password (kim_identity in_identity,
if (!err && !in_identity ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
if (!err && !out_password) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+ /* Short circuit if password saving is disabled */
+ if (!err && !kim_os_identity_allow_save_password ()) {
+ return kim_os_identity_remove_saved_password (in_identity);
+ }
+
if (!err) {
err = kim_identity_get_components_string (in_identity, &name);
}
@@ -85,6 +117,11 @@ kim_error kim_os_identity_set_saved_password (kim_identity in_identity,
if (!err && !in_identity) { err = check_error (KIM_NULL_PARAMETER_ERR); }
if (!err && !in_password) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+ /* Short circuit if password saving is disabled */
+ if (!err && !kim_os_identity_allow_save_password ()) {
+ return kim_os_identity_remove_saved_password (in_identity);
+ }
+
if (!err) {
err = kim_identity_get_components_string (in_identity, &name);
}
diff --git a/src/kim/lib/mac/kim_os_ui_gui.c b/src/kim/lib/mac/kim_os_ui_gui.c
index 1ada9e2130..d87efb0679 100644
--- a/src/kim/lib/mac/kim_os_ui_gui.c
+++ b/src/kim/lib/mac/kim_os_ui_gui.c
@@ -220,14 +220,16 @@ kim_error kim_os_ui_gui_select_identity (kim_ui_context *in_context,
/* ------------------------------------------------------------------------ */
-kim_error kim_os_ui_gui_auth_prompt (kim_ui_context *in_context,
- kim_identity in_identity,
- kim_prompt_type in_type,
- kim_boolean in_hide_reply,
- kim_string in_title,
- kim_string in_message,
- kim_string in_description,
- char **out_reply)
+kim_error kim_os_ui_gui_auth_prompt (kim_ui_context *in_context,
+ kim_identity in_identity,
+ kim_prompt_type in_type,
+ kim_boolean in_allow_save_reply,
+ kim_boolean in_hide_reply,
+ kim_string in_title,
+ kim_string in_message,
+ kim_string in_description,
+ char **out_reply,
+ kim_boolean *out_save_reply)
{
kim_error err = KIM_NO_ERROR;
k5_ipc_stream request = NULL;
@@ -259,6 +261,10 @@ kim_error kim_os_ui_gui_auth_prompt (kim_ui_context *in_context,
}
if (!err) {
+ err = k5_ipc_stream_write_int32 (request, in_allow_save_reply);
+ }
+
+ if (!err) {
err = k5_ipc_stream_write_int32 (request, in_hide_reply);
}
@@ -295,6 +301,10 @@ kim_error kim_os_ui_gui_auth_prompt (kim_ui_context *in_context,
err = k5_ipc_stream_read_string (reply, out_reply);
}
+ if (!err) {
+ err = k5_ipc_stream_read_int32 (reply, out_save_reply);
+ }
+
kim_string_free (&identity_string);
k5_ipc_stream_release (request);