Added support for disabling password saving, both globally
authorAlexandra Ellwood <lxs@mit.edu>
Mon, 29 Sep 2008 20:48:43 +0000 (20:48 +0000)
committerAlexandra Ellwood <lxs@mit.edu>
Mon, 29 Sep 2008 20:48:43 +0000 (20:48 +0000)
and also per prompt via the UI.

ticket: 6055

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@20781 dc483132-0cff-0310-8789-dd5450dbe970

15 files changed:
src/include/kim/kim_ui_plugin.h
src/kim/agent/mac/ServerDemux.h
src/kim/agent/mac/ServerDemux.m
src/kim/lib/kim_credential.c
src/kim/lib/kim_identity.c
src/kim/lib/kim_identity_private.h
src/kim/lib/kim_ui.c
src/kim/lib/kim_ui_cli.c
src/kim/lib/kim_ui_cli_private.h
src/kim/lib/kim_ui_gui_private.h
src/kim/lib/kim_ui_plugin.c
src/kim/lib/kim_ui_plugin_private.h
src/kim/lib/kim_ui_private.h
src/kim/lib/mac/kim_os_identity.c
src/kim/lib/mac/kim_os_ui_gui.c

index 0f6895ffc606abd4d5f8f5fe1b19d14a1cd30989..99923e51037fc123fbc8a40994802680e8c3201f 100644 (file)
@@ -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,
index 12afa36c2ce4d2de1c43e345e2a0e5b76d0b6def..1f1de5964cc56a7de05e9e995c933f9adb575212 100644 (file)
@@ -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, 
index bc8525b0d6c624dfa86160a4f7cd32fc31f040e1..a70a668c438d8d236eacc247acf8ccfc28791cb1 100644 (file)
@@ -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;
@@ -280,6 +281,10 @@ static int32_t kim_handle_request_auth_prompt (mach_port_t   in_client_port,
         err = k5_ipc_stream_read_int32 (in_request_stream, &type);
     }    
     
+    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);
     }
index ee2ec0448e06754f049cb471f967d05912d713ee..64561896d5cc527eb9d24c776a759046c8d7b8b3 100644 (file)
@@ -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) {
index b431ae8b8dbd93bc6eacb063068c5396d30e15bd..10604e6d072af89dd5ab15237a4c1bc966d400da 100644 (file)
@@ -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) {
index f8ef4d629980d86913b7389a148169ec8f752c2b..2a212aa1cc07b05cb7bfc7331c6405092fe1287d 100644 (file)
@@ -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 */
index 3abc3f95cec8b9709dddb74434f259e870f1e096..b585ff7a010f18100b89d4a8886881f07657a61f 100644 (file)
@@ -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);
index f26e328822380446571559b794f6740149875449..cd7cea601f2f49d36bb96e07b9d346150ed54d39 100644 (file)
@@ -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); }
index 872fb4b226ef9b9cf121a3fce76890f3d0304ac9..5059196003a1e426c72bfafc30549c0a819e9d59 100644 (file)
@@ -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,
index b89cf348fad681aae5c089d754a38de53c7c67c5..dd2f2a9e5c02174041bc9a6d3891c4979c3c3dee 100644 (file)
@@ -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,
index 49cceaeb4edb63e2e038452d11187cafedc3870a..0ac2f149408218ddb65a6b1c540304b145a4b47a 100644 (file)
@@ -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);
index e4d3547642a8da45be630291c71ec449556bddd7..58eb60f4083cc3d8c89573a791b5bd662023d1bc 100644 (file)
@@ -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,
index d280f5997489575ade6426825e5c3d8a8e90bf82..f4d1b10d9ba26555bd2062bae244190fcf4cb22b 100644 (file)
@@ -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;
 
 
index 690a2f252cdde627105b28c6dc9954c058556c49..fba941820a16963976f34fe34dac56730391a775 100644 (file)
 
 /* ------------------------------------------------------------------------ */
 
+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);
     }
index 1ada9e21306e1cb9c832f33690986603d719b27c..d87efb0679a4740f0f02ff40642e457a14483761 100644 (file)
@@ -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;
@@ -258,6 +260,10 @@ kim_error kim_os_ui_gui_auth_prompt (kim_ui_context     *in_context,
         err = k5_ipc_stream_write_int32 (request, in_type);
     }
     
+    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);