KerberosAgent MachIPC support
authorAlexandra Ellwood <lxs@mit.edu>
Sat, 27 Sep 2008 00:46:39 +0000 (00:46 +0000)
committerAlexandra Ellwood <lxs@mit.edu>
Sat, 27 Sep 2008 00:46:39 +0000 (00:46 +0000)
ticket: 6055

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

15 files changed:
src/include/kim/kim_identity.h
src/kim/agent/mac/ServerDemux.m [new file with mode: 0644]
src/kim/agent/mac/ServerThread.h [new file with mode: 0644]
src/kim/agent/mac/ServerThread.m [new file with mode: 0644]
src/kim/lib/kim-lite.exports
src/kim/lib/kim.exports
src/kim/lib/kim_identity.c
src/kim/lib/kim_identity_private.h
src/kim/lib/kim_selection_hints.c
src/kim/lib/kim_selection_hints_private.h
src/kim/lib/kim_string_private.h
src/kim/lib/kim_ui.c
src/kim/lib/kim_ui_cli.c
src/kim/lib/mac/kim_os_ui_gui.c
src/kim/mac/kim_mig.defs

index f09c24aa7a7feb30e4b0c82c90d91cf8518e145b..c627758d1ca9281a21b3be5650bd24f8168e0197 100644 (file)
@@ -241,6 +241,16 @@ kim_error kim_identity_get_component_at_index (kim_identity  in_identity,
                                                  kim_count     in_index,
                                                  kim_string   *out_component_string);
 
+/*!
+ * \param in_identity      an identity object.
+ * \param out_components   on exit, a string of the non-realm components of \a in_identity 
+ *                         separated by '/' characters.  Must be freed with kim_string_free().
+ * \return On success, #KIM_NO_ERROR.  On failure, an error code representing the failure.
+ * \brief Get a display string of the non-realm components of an identity.
+ */
+kim_error kim_identity_get_components (kim_identity  in_identity,
+                                       kim_string   *out_components);
+    
 /*!
  * \param in_identity        an identity object.
  * \param in_krb5_context    a krb5 context object.  
diff --git a/src/kim/agent/mac/ServerDemux.m b/src/kim/agent/mac/ServerDemux.m
new file mode 100644 (file)
index 0000000..b7f2084
--- /dev/null
@@ -0,0 +1,618 @@
+/*
+ * Copyright 2008 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#import "kim_migServer.h"
+#import "ServerThread.h"
+
+// ---------------------------------------------------------------------------
+
+static kim_boolean caller_is_front_process (task_t    in_task, 
+                                            NSString *in_path)
+{
+    kim_error err = KIM_NO_ERROR;
+    Boolean is_front_process;
+    pid_t task_pid;
+    ProcessSerialNumber task_psn, front_psn;
+    
+    NSBundle *bundle = [NSBundle bundleWithPath: in_path];
+    if (bundle) {
+        NSString *identifier = [bundle bundleIdentifier];
+        if (identifier && 
+            ([identifier compare: @"edu.mit.Kerberos.KerberosMenu"] == NSOrderedSame ||
+             [identifier compare: @"com.apple.systemuiserver"]      == NSOrderedSame)) {
+            return TRUE;
+        }
+    }
+    
+    if (!err) {
+        err = pid_for_task (in_task, &task_pid);
+    }
+    
+    if (!err) {
+        err = GetProcessForPID (task_pid, &task_psn);
+    }
+    
+    if (!err) {
+        err = GetFrontProcess (&front_psn);
+    }
+    
+    if (!err) {
+        err = SameProcess (&task_psn, &front_psn, &is_front_process);
+    }
+    
+    return !err ? is_front_process : FALSE;
+}
+
+#pragma mark -
+
+/* ------------------------------------------------------------------------ */
+
+kern_return_t kim_mipc_srv_init (mach_port_t             in_server_port,
+                                 task_t                  in_application_task,
+                                 kim_mipc_in_string      in_application_name,
+                                 mach_msg_type_number_t  in_application_nameCnt,
+                                 kim_mipc_in_string      in_application_path,
+                                 mach_msg_type_number_t  in_application_pathCnt,
+                                 kim_mipc_error         *out_error)
+{
+    kern_return_t err = 0;
+    ServerThread *sthread = NULL;
+    
+    if (!err) {
+        sthread = [ServerThread sharedServerThread];
+        if (!sthread) { err = KIM_OUT_OF_MEMORY_ERR; }
+    }
+    
+    if (!err) {
+        kim_mipc_error result = KIM_NO_ERROR;
+        NSString *name = NULL;
+        NSString *path = NULL;
+
+        if (in_application_name) {
+            name = [NSString stringWithUTF8String: in_application_name];
+        }
+
+        if (in_application_path) {
+            path = [NSString stringWithUTF8String: in_application_path];
+        }
+        
+        [sthread addConnectionWithPort: in_server_port
+                                  name: name
+                                  path: path
+                          frontProcess: caller_is_front_process (in_application_task, 
+                                                                 path)];
+        *out_error = result;
+    }
+    
+    return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+kern_return_t kim_mipc_srv_enter_identity (mach_port_t             in_server_port,
+                                           kim_mipc_out_string    *out_identity,
+                                           mach_msg_type_number_t *out_identityCnt,
+                                           kim_mipc_error         *out_error)
+{
+    kern_return_t err = 0;
+    kim_error result = KIM_NO_ERROR;
+    ClientConnection *client = NULL;
+    kim_identity identity = NULL;
+    kim_string identity_string = NULL;
+    mach_msg_type_number_t identity_len = 0;
+    kim_mipc_out_string identity_buf = NULL;
+    
+    if (!err) {
+        ServerThread *sthread = [ServerThread sharedServerThread];
+        if (!sthread) { err = KIM_OUT_OF_MEMORY_ERR; }
+
+        if (!err) {
+            client = [sthread connectionForPort: in_server_port];
+            if (!client) { err = KIM_OUT_OF_MEMORY_ERR; }
+        }
+    }
+    
+    if (!err) {
+        identity = [client enterIdentityWithError: &result];
+    }
+    
+    if (!err && !result) {
+        err = kim_identity_get_string (identity, &identity_string);
+    }
+    
+    if (!err && !result && identity_string) {
+        identity_len = strlen (identity_string) + 1;
+        err = vm_allocate (mach_task_self (), 
+                           (vm_address_t *) &identity_buf, identity_len, TRUE);
+        
+    }
+    
+    if (!err && !result) {
+        memmove (identity_buf, identity_string, identity_len);
+        *out_identity = identity_buf;
+        *out_identityCnt = identity_len;
+        identity_buf = NULL;
+    }
+    
+    if (!err) {
+        *out_error = result;
+    }
+    
+    if (identity_buf) { vm_deallocate (mach_task_self (), (vm_address_t) identity_buf, identity_len); }
+    kim_string_free (&identity_string);
+    kim_identity_free (&identity);
+    
+    return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+kern_return_t kim_mipc_srv_select_identity (mach_port_t             in_server_port,
+                                            kim_mipc_in_string      in_application_id,
+                                            mach_msg_type_number_t  in_application_idCnt,
+                                            kim_mipc_in_string      in_explanation,
+                                            mach_msg_type_number_t  in_explanationCnt,
+                                            kim_mipc_time           in_start_time,
+                                            kim_mipc_lifetime       in_lifetime,
+                                            kim_mipc_boolean        in_renewable,
+                                            kim_mipc_lifetime       in_renewal_lifetime,
+                                            kim_mipc_boolean        in_forwardable,
+                                            kim_mipc_boolean        in_proxiable,
+                                            kim_mipc_boolean        in_addressless,
+                                            kim_mipc_in_string      in_service_name,
+                                            mach_msg_type_number_t  in_service_nameCnt,
+                                            kim_mipc_in_string      in_service_identity_hint,
+                                            mach_msg_type_number_t  in_service_identity_hintCnt,
+                                            kim_mipc_in_string      in_client_realm_hint,
+                                            mach_msg_type_number_t  in_client_realm_hintCnt,
+                                            kim_mipc_in_string      in_user_hint,
+                                            mach_msg_type_number_t  in_user_hintCnt,
+                                            kim_mipc_in_string      in_service_realm_hint,
+                                            mach_msg_type_number_t  in_service_realm_hintCnt,
+                                            kim_mipc_in_string      in_service_hint,
+                                            mach_msg_type_number_t  in_service_hintCnt,
+                                            kim_mipc_in_string      in_server_hint,
+                                            mach_msg_type_number_t  in_server_hintCnt,
+                                            kim_mipc_out_string    *out_identity,
+                                            mach_msg_type_number_t *out_identityCnt,
+                                            kim_mipc_error         *out_error)
+{
+    kern_return_t err = 0;
+    kim_error result = KIM_NO_ERROR;
+    ClientConnection *client = NULL;
+    kim_selection_hints hints = NULL;
+    kim_identity identity = NULL;
+    kim_string identity_string = NULL;
+    mach_msg_type_number_t identity_len = 0;
+    kim_mipc_out_string identity_buf = NULL;
+    
+    if (!err) {
+        err = kim_selection_hints_create (&hints, in_application_id);
+    }
+    
+    if (!err) {
+        kim_options options = NULL;
+        
+        err = kim_options_create (&options);
+        
+        if (!err) {
+            err = kim_options_set_start_time (options, in_start_time);
+        }
+        
+        if (!err) {
+            err = kim_options_set_lifetime (options, in_lifetime);
+        }
+        
+        if (!err) {
+            err = kim_options_set_renewable (options, in_renewable);
+        }
+        
+        if (!err) {
+            err = kim_options_set_renewal_lifetime (options, in_renewal_lifetime);
+        }
+        
+        if (!err) {
+            err = kim_options_set_forwardable (options, in_forwardable);
+        }
+        
+        if (!err) {
+            err = kim_options_set_proxiable (options, in_proxiable);
+        }
+        
+        if (!err) {
+            err = kim_options_set_addressless (options, in_addressless);
+        }
+        
+        if (!err) {
+            err = kim_options_set_service_name (options, in_service_name);
+        }
+        
+        if (!err) {
+            err = kim_selection_hints_set_options (hints, options);
+        }
+        
+        kim_options_free (&options);
+    }
+    
+    if (!err) {
+        err = kim_selection_hints_set_explanation (hints, in_explanation);
+    }
+    
+    if (!err && in_service_identity_hint) {
+        err = kim_selection_hints_set_hint (hints, 
+                                            kim_hint_key_service_identity,
+                                            in_service_identity_hint);
+    }
+    
+    if (!err && in_client_realm_hint) {
+        err = kim_selection_hints_set_hint (hints, 
+                                            kim_hint_key_client_realm,
+                                            in_client_realm_hint);
+    }
+    
+    if (!err && in_user_hint) {
+        err = kim_selection_hints_set_hint (hints, 
+                                            kim_hint_key_user,
+                                            in_user_hint);
+    }
+    
+    if (!err && in_service_realm_hint) {
+        err = kim_selection_hints_set_hint (hints, 
+                                            kim_hint_key_service_realm,
+                                            in_service_realm_hint);
+    }
+    
+    if (!err && in_service_hint) {
+        err = kim_selection_hints_set_hint (hints, 
+                                            kim_hint_key_service,
+                                            in_service_hint);
+    }
+    
+    if (!err && in_server_hint) {
+        err = kim_selection_hints_set_hint (hints, 
+                                            kim_hint_key_server,
+                                            in_server_hint);
+    }
+    
+    if (!err) {
+        ServerThread *sthread = [ServerThread sharedServerThread];
+        if (!sthread) { err = KIM_OUT_OF_MEMORY_ERR; }
+        
+        if (!err) {
+            client = [sthread connectionForPort: in_server_port];
+            if (!client) { err = KIM_OUT_OF_MEMORY_ERR; }
+        }
+    }
+    
+    if (!err) {
+        identity = [client selectIdentityWithHints: hints
+                                             error: &result];
+    }
+    
+    if (!err && !result) {
+        err = kim_identity_get_string (identity, &identity_string);
+    }
+
+    if (!err && !result && identity_string) {
+        identity_len = strlen (identity_string) + 1;
+        err = vm_allocate (mach_task_self (), 
+                           (vm_address_t *) &identity_buf, identity_len, TRUE);
+    }
+    
+    if (!err && !result) {
+        memmove (identity_buf, identity_string, identity_len);
+        *out_identity = identity_buf;
+        *out_identityCnt = identity_len;
+        identity_buf = NULL;
+    }
+        
+    if (!err) {
+        *out_error = result;
+    }
+    
+    if (identity_buf) { vm_deallocate (mach_task_self (), 
+                                       (vm_address_t) identity_buf, 
+                                       identity_len); }
+    kim_string_free (&identity_string);
+    kim_identity_free (&identity);
+    kim_selection_hints_free (&hints);
+
+    return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+kern_return_t kim_mipc_srv_auth_prompt (mach_port_t             in_server_port,
+                                        kim_mipc_in_string      in_identity,
+                                        mach_msg_type_number_t  in_identityCnt,
+                                        kim_mipc_prompt_type    in_prompt_type,
+                                        kim_mipc_boolean        in_hide_reply,
+                                        kim_mipc_in_string      in_title,
+                                        mach_msg_type_number_t  in_titleCnt,
+                                        kim_mipc_in_string      in_message,
+                                        mach_msg_type_number_t  in_messageCnt,
+                                        kim_mipc_in_string      in_description,
+                                        mach_msg_type_number_t  in_descriptionCnt,
+                                        kim_mipc_out_string    *out_response,
+                                        mach_msg_type_number_t *out_responseCnt,
+                                        kim_mipc_error         *out_error)
+{
+    kern_return_t err = 0;
+    kim_error result = KIM_NO_ERROR;
+    ClientConnection *client = NULL;
+    kim_identity identity = NULL;
+    const char *response_string = NULL;
+    mach_msg_type_number_t response_len = 0;
+    kim_mipc_out_string response_buf = NULL;
+    
+    if (!err) {
+        ServerThread *sthread = [ServerThread sharedServerThread];
+        if (!sthread) { err = KIM_OUT_OF_MEMORY_ERR; }
+        
+        if (!err) {
+            client = [sthread connectionForPort: in_server_port];
+            if (!client) { err = KIM_OUT_OF_MEMORY_ERR; }
+        }
+    }
+    
+    if (!err) {
+        err = kim_identity_create_from_string (&identity, in_identity);
+    }
+    
+    if (!err) {
+        NSString *title = NULL;
+        NSString *message = NULL;
+        NSString *description = NULL;
+        
+        if (in_title) {
+            title = [NSString stringWithUTF8String: in_title];
+        }
+        
+        if (in_message) {
+            message = [NSString stringWithUTF8String: in_message];
+        }
+        
+        if (in_description) {
+            description = [NSString stringWithUTF8String: in_description];
+        }
+        
+        response_string = [[client authPromptWithIdentity: identity
+                                                     type: in_prompt_type
+                                                hideReply: in_hide_reply
+                                                    title: title
+                                                  message: message
+                                              description: description
+                                                    error: &result] UTF8String];
+    }
+    
+    if (!err && !result && response_string) {
+        response_len = strlen (response_string) + 1;
+        err = vm_allocate (mach_task_self (), 
+                           (vm_address_t *) &response_buf, response_len, TRUE);
+        
+    }
+    
+    if (!err && !result) {
+        memmove (response_buf, response_string, response_len);
+        *out_response = response_buf;
+        *out_responseCnt = response_len;
+        response_buf = NULL;
+    }
+    
+    if (!err) {
+        *out_error = result;
+    }
+    
+    if (response_buf) { vm_deallocate (mach_task_self (), 
+                                       (vm_address_t) response_buf, 
+                                       response_len); }
+    kim_identity_free (&identity);
+    
+    return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+kern_return_t kim_mipc_srv_change_password (mach_port_t             in_server_port,
+                                            kim_mipc_in_string      in_identity,
+                                            mach_msg_type_number_t  in_identityCnt,
+                                            kim_mipc_boolean        in_old_password_expired,
+                                            kim_mipc_out_string    *out_old_password,
+                                            mach_msg_type_number_t *out_old_passwordCnt,
+                                            kim_mipc_out_string    *out_new_password,
+                                            mach_msg_type_number_t *out_new_passwordCnt,
+                                            kim_mipc_out_string    *out_vfy_password,
+                                            mach_msg_type_number_t *out_vfy_passwordCnt,
+                                            kim_mipc_error         *out_error)
+{
+    kern_return_t err = 0;
+    kim_error result = KIM_NO_ERROR;
+    ClientConnection *client = NULL;
+    kim_identity identity = NULL;
+    NSArray *passwords = NULL;
+    const char *old_password_string = NULL;
+    const char *new_password_string = NULL;
+    const char *vfy_password_string = NULL;
+    mach_msg_type_number_t old_password_len = 0;
+    mach_msg_type_number_t new_password_len = 0;
+    mach_msg_type_number_t vfy_password_len = 0;
+    kim_mipc_out_string old_password_buf = NULL;
+    kim_mipc_out_string new_password_buf = NULL;
+    kim_mipc_out_string vfy_password_buf = NULL;
+    
+    if (!err) {
+        ServerThread *sthread = [ServerThread sharedServerThread];
+        if (!sthread) { err = KIM_OUT_OF_MEMORY_ERR; }
+        
+        if (!err) {
+            client = [sthread connectionForPort: in_server_port];
+            if (!client) { err = KIM_OUT_OF_MEMORY_ERR; }
+        }
+    }
+    
+    if (!err) {
+        err = kim_identity_create_from_string (&identity, in_identity);
+    }
+    
+    if (!err) {
+        passwords = [client changePasswordWithIdentity: identity
+                                   oldPasswordIsExpired: in_old_password_expired
+                                                  error: &result];
+    }
+    
+    if (!err && !result) {
+        if (passwords && [passwords count] == 3) {
+            old_password_string = [[passwords objectAtIndex: 1] UTF8String];
+            new_password_string = [[passwords objectAtIndex: 2] UTF8String];
+            vfy_password_string = [[passwords objectAtIndex: 3] UTF8String];
+        } else {
+            err = KIM_OUT_OF_MEMORY_ERR;
+        }
+    }
+        
+    if (!err && !result && old_password_string) {
+        old_password_len = strlen (old_password_string) + 1;
+        err = vm_allocate (mach_task_self (), (vm_address_t *) &old_password_buf, old_password_len, TRUE);
+        
+    }
+
+    if (!err && !result && new_password_string) {
+        new_password_len = strlen (new_password_string) + 1;
+        err = vm_allocate (mach_task_self (), (vm_address_t *) &new_password_buf, new_password_len, TRUE);
+        
+    }
+    
+    if (!err && !result && vfy_password_string) {
+        vfy_password_len = strlen (vfy_password_string) + 1;
+        err = vm_allocate (mach_task_self (), (vm_address_t *) &vfy_password_buf, vfy_password_len, TRUE);
+    }
+    
+    if (!err && !result) {
+        memmove (old_password_buf, old_password_string, old_password_len);
+        memmove (new_password_buf, new_password_string, new_password_len);
+        memmove (vfy_password_buf, vfy_password_string, vfy_password_len);
+        *out_old_password = old_password_buf;
+        *out_new_password = new_password_buf;
+        *out_vfy_password = vfy_password_buf;
+        *out_old_passwordCnt = old_password_len;
+        *out_new_passwordCnt = new_password_len;
+        *out_vfy_passwordCnt = vfy_password_len;
+        old_password_buf = NULL;
+        new_password_buf = NULL;
+        vfy_password_buf = NULL;
+    }
+    
+    if (!err) {
+        *out_error = result;
+    }
+    
+    if (old_password_buf) { vm_deallocate (mach_task_self (), (vm_address_t) old_password_buf, old_password_len); }
+    if (new_password_buf) { vm_deallocate (mach_task_self (), (vm_address_t) new_password_buf, new_password_len); }
+    if (vfy_password_buf) { vm_deallocate (mach_task_self (), (vm_address_t) vfy_password_buf, vfy_password_len); }
+    kim_identity_free (&identity);
+    
+    return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+kern_return_t kim_mipc_srv_handle_error (mach_port_t             in_server_port,
+                                         kim_mipc_in_string      in_identity,
+                                         mach_msg_type_number_t  in_identityCnt,
+                                         kim_mipc_error          in_error,
+                                         kim_mipc_in_string      in_message,
+                                         mach_msg_type_number_t  in_messageCnt,
+                                         kim_mipc_in_string      in_description,
+                                         mach_msg_type_number_t  in_descriptionCnt,
+                                         kim_mipc_error         *out_error)
+{
+    kern_return_t err = 0;
+    kim_error result = KIM_NO_ERROR;
+    ClientConnection *client = NULL;
+    kim_identity identity = NULL;
+    
+    if (!err) {
+        ServerThread *sthread = [ServerThread sharedServerThread];
+        if (!sthread) { err = KIM_OUT_OF_MEMORY_ERR; }
+        
+        if (!err) {
+            client = [sthread connectionForPort: in_server_port];
+            if (!client) { err = KIM_OUT_OF_MEMORY_ERR; }
+        }
+    }
+    
+    if (!err) {
+        err = kim_identity_create_from_string (&identity, in_identity);
+    }
+    
+    if (!err) {
+        NSString *message = NULL;
+        NSString *description = NULL;
+        
+        if (in_message) {
+            message = [NSString stringWithUTF8String: in_message];
+        }
+        
+        if (in_description) {
+            description = [NSString stringWithUTF8String: in_description];
+        }
+        
+        result = [client handleError: in_error
+                            identity: identity
+                             message: message
+                         description: description];
+    }
+    
+    if (!err) {
+        *out_error = result;
+    }
+    
+    kim_identity_free (&identity);
+    
+    return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+kern_return_t kim_mipc_srv_fini (mach_port_t     in_server_port,
+                                 kim_mipc_error *out_error)
+{
+    kern_return_t err = 0;
+    ServerThread *sthread = NULL;
+    
+    if (!err) {
+        sthread = [ServerThread sharedServerThread];
+        if (!sthread) { err = KIM_OUT_OF_MEMORY_ERR; }
+    }
+
+    if (!err) {
+        [sthread removeConnectionWithPort: in_server_port];
+    }
+    
+    if (!err) {
+        *out_error = KIM_NO_ERROR;
+    }
+    
+    return err;
+}
diff --git a/src/kim/agent/mac/ServerThread.h b/src/kim/agent/mac/ServerThread.h
new file mode 100644 (file)
index 0000000..4457f2a
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2008 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include <Kerberos/kim.h>
+#include <Kerberos/kim_ui_plugin.h>
+
+@interface ClientConnection : NSObject {
+    mach_port_t port;
+    bool callerIsFrontProcess;
+    NSString *applicationName;
+    NSString *applicationPath;
+}
+
+@property(readonly) mach_port_t port;
+
+- (id) initWithPort: (mach_port_t) port
+               name: (NSString *) name
+               path: (NSString *) path
+      front_process: (bool) frontProcess;
+
+- (kim_identity) enterIdentityWithError: (kim_error *) outError;
+
+- (kim_identity) selectIdentityWithHints: (kim_selection_hints) hints
+                                   error: (kim_error *) outError;
+
+- (NSString *) authPromptWithIdentity: (kim_identity) identity
+                                 type: (kim_prompt_type) type
+                            hideReply: (bool) hideReply
+                                title: (NSString *) title
+                              message: (NSString *) message
+                          description: (NSString *) description
+                                error: (kim_error *) outError;
+
+- (NSArray *) changePasswordWithIdentity: (kim_identity) identity
+                    oldPasswordIsExpired: (bool) oldPasswordIsExpired
+                                   error: (kim_error *) outError;
+
+- (kim_error) handleError: (kim_error) error
+                 identity: (kim_identity) identity
+                  message: (NSString *) message
+              description: (NSString *) description;
+
+- (void) dealloc;
+
+@end
+
+/* ------------------------------------------------------------------------ */
+
+@interface ServerThread : NSObject {
+    NSMutableArray *connections;
+}
+
++ (ServerThread *) sharedServerThread;
+   
+- (id) init;
+
+- (void) dealloc;
+
+- (kern_return_t) listen;
+
+- (void) addConnectionWithPort: (mach_port_t) port
+                          name: (NSString *) name
+                          path: (NSString *) path
+                  frontProcess: (bool) frontProcess;
+
+- (void) removeConnectionWithPort: (mach_port_t) port;
+
+
+- (ClientConnection *) connectionForPort: (mach_port_t) port;
+
+@end
diff --git a/src/kim/agent/mac/ServerThread.m b/src/kim/agent/mac/ServerThread.m
new file mode 100644 (file)
index 0000000..6d5ba5e
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ * Copyright 2008 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
+#import "ServerThread.h"
+#import <Kerberos/kim.h>
+#import <Kerberos/kipc_server.h>
+#import "kim_migServer.h"
+
+
+@implementation ClientConnection
+
+@synthesize port;
+
+/* ------------------------------------------------------------------------ */
+
+- (id) initWithPort: (mach_port_t) connectionPort
+               name: (NSString *) name
+               path: (NSString *) path
+      front_process: (bool) frontProcess
+{
+    if ((self = [super init])) {
+        port = connectionPort;
+        callerIsFrontProcess = frontProcess;
+        applicationName = [name retain];
+        applicationPath = [path retain];
+    }
+    
+    return self;
+}
+
+/* ------------------------------------------------------------------------ */
+
+- (kim_identity) enterIdentityWithError: (kim_error *) outError
+{
+    kim_error err = KIM_NO_ERROR;
+    kim_identity identity = NULL;
+    
+    *outError = err;
+    return identity;
+}
+
+/* ------------------------------------------------------------------------ */
+
+- (kim_identity) selectIdentityWithHints: (kim_selection_hints) hints
+                                 error: (kim_error *) outError
+{
+    kim_error err = KIM_NO_ERROR;
+    kim_identity identity = NULL;
+    
+    *outError = err;
+    return identity;
+}
+
+/* ------------------------------------------------------------------------ */
+
+- (NSString *) authPromptWithIdentity: (kim_identity) identity
+                                 type: (kim_prompt_type) type
+                            hideReply: (bool) hideReply
+                                title: (NSString *) title
+                              message: (NSString *) message
+                          description: (NSString *) description
+                                error: (kim_error *) outError
+{
+    kim_error err = KIM_NO_ERROR;
+    NSString *reply = @"A reply";
+    
+    *outError = err;
+    return reply;
+}
+
+/* ------------------------------------------------------------------------ */
+
+- (NSArray *) changePasswordWithIdentity: (kim_identity) identity
+                    oldPasswordIsExpired: (bool) oldPasswordIsExpired
+                                   error: (kim_error *) outError
+{
+    kim_error err = KIM_NO_ERROR;
+    NSString *oldPassword = @"an old password";
+    NSString *newPassword = @"a new password";
+    NSString *verifyPassword = @"a verify password";
+    
+    *outError = err;
+    return !err ? [NSArray arrayWithObjects: oldPassword, newPassword, verifyPassword, NULL] : NULL;    
+}
+
+/* ------------------------------------------------------------------------ */
+
+- (kim_error) handleError: (kim_error) error
+                 identity: (kim_identity) identity
+                  message: (NSString *) message
+              description: (NSString *) description
+{
+    kim_error err = KIM_NO_ERROR;
+    
+    return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+- (void) dealloc
+{
+    [applicationName release];
+    [applicationPath release];
+    [super dealloc];
+}
+
+@end
+
+@implementation ServerThread
+
+/* ------------------------------------------------------------------------ */
+
++ (ServerThread *) sharedServerThread
+{
+    static ServerThread *gServerThread = NULL;
+    
+    if (!gServerThread) {
+        gServerThread = [[ServerThread alloc] init];
+    }
+    
+    return gServerThread;
+}
+
+/* ------------------------------------------------------------------------ */
+
+- (id) init
+{
+    if ((self = [super init])) {
+        connections = [[NSMutableArray alloc] init];
+        if (!connections) {
+            [self release];
+            self = nil;
+        }
+    }
+    
+    return self;
+}
+
+/* ------------------------------------------------------------------------ */
+
+- (void) dealloc
+{
+    [connections release];
+    [super dealloc];
+}
+
+/* ------------------------------------------------------------------------ */
+
+- (kern_return_t) listen
+{
+    return kipc_server_run_server (kim_server);
+}
+
+/* ------------------------------------------------------------------------ */
+
+- (void) addConnectionWithPort: (mach_port_t) port
+                          name: (NSString *) name
+                          path: (NSString *) path
+                  frontProcess: (bool) frontProcess
+{
+    ClientConnection *client = [[ClientConnection alloc] initWithPort: port
+                                                                 name: name
+                                                                 path: path
+                                                        front_process: frontProcess];
+    if (client) {
+        [connections addObject: client];
+    }
+    
+    [client release];
+}
+
+/* ------------------------------------------------------------------------ */
+
+- (void) removeConnectionWithPort: (mach_port_t) port
+{
+    for (ClientConnection *client in connections) {
+        if (client.port == port) {
+            [connections removeObject: client];
+        }
+    }
+    
+    if (![connections count]) {
+        kipc_server_quit ();
+    }
+}
+
+
+/* ------------------------------------------------------------------------ */
+
+- (ClientConnection *) connectionForPort: (mach_port_t) port
+{
+    for (ClientConnection *client in connections) {
+        if (client.port == port) {
+            return client;
+        }
+    }    
+    return NULL;
+}
+
+@end
+
index b548cfc245f09ed06748e6ffaf7fced5ae14d825..27db519267cbc8d8a1db88a51b347305633bb3d6 100644 (file)
@@ -12,6 +12,7 @@ kim_identity_get_string
 kim_identity_get_display_string
 kim_identity_get_realm
 kim_identity_get_number_of_components
+kim_identity_get_components
 kim_identity_get_component_at_index
 kim_identity_get_krb5_principal
 kim_identity_change_password
index a41f48109d88e5f216e66a015eb51b613d9bdfef..126ed9879826d5c52e9287e6bb6f32506e1f0a31 100644 (file)
@@ -13,6 +13,7 @@ kim_identity_get_display_string
 kim_identity_get_realm
 kim_identity_get_number_of_components
 kim_identity_get_component_at_index
+kim_identity_get_components
 kim_identity_get_krb5_principal
 kim_identity_change_password
 kim_identity_free
index 1308c3d7adb583537937b04e8e742a1635362297..333067bc532cb6fb305b7e367e8166c6810759d2 100644 (file)
@@ -598,7 +598,7 @@ static kim_error kim_identity_change_password_with_credential (kim_identity    i
                                                  message_data.length);
         } else {
             err = kim_os_string_create_localized (&rejected_message,
-                                                  "KLStringChangePasswordFailed");
+                                                  "Kerberos Change Password Failed:");
         }
         
         if (!err) {
@@ -608,7 +608,7 @@ static kim_error kim_identity_change_password_with_credential (kim_identity    i
                                                      description_data.length);
             } else {
                 err = kim_os_string_create_localized (&rejected_description,
-                                                      "KLStringPasswordRejected");
+                                                      "New password rejected.");
             }
         }
         
index 44f8c631d5fd0b828a4fe91f505e3bc7577632db..4b1adeb485d7edaa9c5d24857f9bdb948b67f3d5 100644 (file)
@@ -31,9 +31,6 @@
 #include "kim_library_private.h"
 #include "kim_ui_private.h"
 
-kim_error kim_identity_get_components (kim_identity  in_identity,
-                                       kim_string   *out_components);
-
 kim_error kim_identity_is_tgt_service (kim_identity  in_identity,
                                        kim_boolean  *out_is_tgt_service);
 
index a4d7d666aca73d9ef8ea62ed7d73e72a244b077c..6903afb868d7194977eddbcb02b122ac6d7016a1 100644 (file)
@@ -314,6 +314,28 @@ kim_error kim_selection_hints_get_explanation (kim_selection_hints  in_selection
 
 /* ------------------------------------------------------------------------ */
 
+kim_error kim_selection_hints_get_application_id (kim_selection_hints  in_selection_hints,
+                                                  kim_string          *out_application_id)
+{
+    kim_error err = KIM_NO_ERROR;
+    
+    if (!err && !in_selection_hints) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !out_application_id) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    
+    if (!err) {
+        if (in_selection_hints->application_identifier) {
+            err = kim_string_copy (out_application_id, 
+                                   in_selection_hints->application_identifier);
+        } else {
+            *out_application_id = NULL;
+        }
+    }
+    
+    return check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
 kim_error kim_selection_hints_set_options (kim_selection_hints io_selection_hints,
                                            kim_options         in_options)
 {
index 9a59ba4f152577818ea645ed8dae9d4d48840bb2..34694893ef657b0e087057856f60706fd6e8fb5f 100644 (file)
@@ -39,6 +39,8 @@ typedef struct kim_selection_hints_preference_strings {
     kim_string server;
 } kim_selection_hints_preference_strings;
 
+kim_error kim_selection_hints_get_application_id (kim_selection_hints  in_selection_hints,
+                                                  kim_string          *out_application_id);
 
 kim_error kim_selection_hints_get_preference_strings (kim_selection_hints                     in_selection_hints,
                                                       kim_selection_hints_preference_strings *io_preference_strings);
index 4b1cc1839272922c5d10a03e17368a8b33acf05f..9ee4846c27cd2489fe8669b76f9d155670e342b9 100644 (file)
 
 #include <kim/kim.h>
 
+/* ------------------------------------------------------------------------ */
+
+static inline kim_count kim_string_buflen (kim_string in_string)
+{
+    return in_string ? strlen (in_string) + 1 : 0;
+}
+
+/* ------------------------------------------------------------------------ */
 
 kim_error kim_string_create_from_format (kim_string *out_string, 
                                          kim_string  in_format,
index 5060fb0496e1efc7f1a0f3f109426c7f11a328f1..819efbf5ba57f0d48d16a73ae02baea1cd5625c2 100644 (file)
@@ -343,17 +343,17 @@ kim_error kim_ui_handle_kim_error (kim_ui_context         *in_context,
         
         switch (in_type) {
             case kim_ui_error_type_authentication:
-                key = "KLStringLoginFailed";
+                key = "Kerberos Login Failed:";
                 break;
                 
             case kim_ui_error_type_change_password:
-                key = "KLStringChangePasswordFailed";
+                key = "Kerberos Change Password Failed:";
                 break;
                 
             case kim_ui_error_type_selection:
             case kim_ui_error_type_generic:
             default:
-                key = "KLStringKerberosOperationFailed";
+                key = "Kerberos Operation Failed:";
                 break;
         }
         
index 0b0188854329d1334d001e0e15bb319b0ced085d..f26e328822380446571559b794f6740149875449 100644 (file)
@@ -111,7 +111,7 @@ kim_error kim_ui_cli_enter_identity (kim_ui_context *in_context,
     
     if (!err) {
         err = kim_os_string_create_localized (&enter_identity_string, 
-                                              "KLStringEnterPrincipal");
+                                              "Please enter your Kerberos identity");
     }
     
     if (!err) {
@@ -170,7 +170,7 @@ kim_error kim_ui_cli_auth_prompt (kim_ui_context      *in_context,
             kim_string identity_string = NULL;
             
             err = kim_os_string_create_localized (&enter_password_format, 
-                                                  "KLStringEnterPassword");
+                                                  "Please enter the password for %s");
             
             if (!err) {
                 err = kim_identity_get_display_string (in_identity, 
@@ -234,35 +234,26 @@ static kim_error kim_ui_cli_ask_change_password (kim_string in_identity_string)
     
     if (!err) {
         err = kim_os_string_create_localized (&ask_change_password, 
-                                              "KLStringPasswordExpired");        
+                                              "Your password has expired, would you like to change it? (yes/no)");        
     }
     
     if (!err) {
-        err = kim_os_string_create_localized (&answer_options, 
-                                              "KLStringYesOrNoAnswerOptions");        
+        err = kim_os_string_create_localized (&yes, "yes");        
     }
     
     if (!err) {
-        err = kim_os_string_create_localized (&yes, 
-                                              "KLStringYes");        
-    }
-    
-    if (!err) {
-        err = kim_os_string_create_localized (&no, 
-                                              "KLStringNo");        
+        err = kim_os_string_create_localized (&no, "no");        
     }
     
     if (!err) {
         err = kim_os_string_create_localized (&unknown_response, 
-                                              "KLStringUnknownResponse");        
+                                              "%s is not a response I understand.  Please try again.");        
     }
     
     while (!err && !done) {
         kim_string answer = NULL;
         
-        err = kim_ui_cli_read_string (&answer, 
-                                      0, "%s %s", 
-                                      ask_change_password, answer_options);
+        err = kim_ui_cli_read_string (&answer, 0, ask_change_password);
     
         if (!err) {
             err = kim_os_string_compare (answer, no, 
@@ -335,17 +326,17 @@ kim_error kim_ui_cli_change_password (kim_ui_context  *in_context,
     
     if (!err) {
         err = kim_os_string_create_localized (&enter_old_password_format, 
-                                              "KLStringEnterOldPassword");
+                                              "Please enter the old password for %s");
     }
     
     if (!err) {
         err = kim_os_string_create_localized (&enter_new_password_format, 
-                                              "KLStringEnterNewPassword");
+                                              "Please enter the new password for %s");
     }
     
     if (!err) {
         err = kim_os_string_create_localized (&enter_verify_password_format, 
-                                              "KLStringEnterVerifyPassword");
+                                              "Verifying, please re-enter the new password for %s again");
     }
     
     while (!err && !done) {
index 1845584395877814f0900d907c16887025a4576e..4f629105d9d1b3e6c55f24a4477670d5b574f5f3 100644 (file)
@@ -41,7 +41,6 @@ struct kim_ui_gui_context {
     mach_port_t port;
 };
 
-
 /* ------------------------------------------------------------------------ */
 
 static void kim_os_ui_gui_context_free (kim_ui_gui_context *io_context)
@@ -86,6 +85,7 @@ kim_error kim_os_ui_gui_init (kim_ui_context *io_context)
 {
     kim_error err = KIM_NO_ERROR;
     kim_ui_gui_context context = NULL;
+    kim_string name = NULL;
     kim_string path = NULL;
     
     if (!err && !io_context) { err = check_error (KIM_NULL_PARAMETER_ERR); }
@@ -95,29 +95,27 @@ kim_error kim_os_ui_gui_init (kim_ui_context *io_context)
     }
     
     if (!err) {
-        err = kipc_client_lookup_server (kim_os_agent_bundle_id, 
-                                         1 /* launch */, 
-                                         0 /* don't use cached port */, 
-                                         &context->port);
+        err = kim_library_get_application_name (&name);
     }
     
     if (!err) {
         err = kim_os_library_get_application_path (&path);
     }
+
+    if (!err) {
+        err = kipc_client_lookup_server (kim_os_agent_bundle_id, 
+                                         1 /* launch */, 
+                                         0 /* don't use cached port */, 
+                                         &context->port);
+    }
     
     if (!err) {
-        kim_mipc_in_string application_name = NULL;
-        mach_msg_type_number_t application_name_len = 0;
-        kim_mipc_in_string application_path = path;
-        mach_msg_type_number_t application_path_len = strlen (path) + 1;
         kim_mipc_error result = 0;
         
         err = kim_mipc_cli_init (context->port,
                                  mach_task_self (),
-                                 application_name,
-                                 application_name_len,
-                                 application_path,
-                                 application_path_len,
+                                 name, kim_string_buflen (name),
+                                 path, kim_string_buflen (path),
                                  &result);
         if (!err) { err = check_error (result); }
     }
@@ -127,6 +125,7 @@ kim_error kim_os_ui_gui_init (kim_ui_context *io_context)
         context = NULL;
     }
     
+    kim_string_free (&name);
     kim_string_free (&path);
     kim_os_ui_gui_context_free (&context);
     
@@ -139,16 +138,30 @@ kim_error kim_os_ui_gui_enter_identity (kim_ui_context *in_context,
                                         kim_identity   *out_identity)
 {
     kim_error err = KIM_NO_ERROR;
+    kim_mipc_out_string identity = NULL;
+    mach_msg_type_number_t identity_len = 0;
     
     if (!err && !in_context  ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
     if (!err && !out_identity) { err = check_error (KIM_NULL_PARAMETER_ERR); }
     
     if (!err) {
         kim_ui_gui_context context = (kim_ui_gui_context) in_context->tcontext;
-        
-        
+        kim_mipc_error result = 0;
+
+        err = kim_mipc_cli_enter_identity (context->port,
+                                           &identity,
+                                           &identity_len,
+                                           &result);        
+        if (!err) { err = check_error (result); }
+    }
+    
+    if (!err) {
+        err = kim_identity_create_from_string (out_identity, identity);
     }
     
+    if (identity) { vm_deallocate (mach_task_self (), 
+                                   (vm_address_t) identity, identity_len); }
+
     return check_error (err);
 }
 
@@ -159,16 +172,176 @@ kim_error kim_os_ui_gui_select_identity (kim_ui_context      *in_context,
                                          kim_identity        *out_identity)
 {
     kim_error err = KIM_NO_ERROR;
-    
+    kim_options options = NULL;
+    kim_time start_time = 0;
+    kim_lifetime lifetime;
+    kim_boolean renewable;
+    kim_lifetime renewal_lifetime;
+    kim_boolean forwardable;
+    kim_boolean proxiable;
+    kim_boolean addressless;
+    kim_string service_name = NULL;
+    kim_string application_id = NULL;
+    kim_string explanation = NULL;
+    kim_string service_identity_hint = NULL;
+    kim_string client_realm_hint = NULL;
+    kim_string user_hint = NULL;
+    kim_string service_realm_hint = NULL;
+    kim_string service_hint = NULL;
+    kim_string server_hint = NULL;
+    kim_mipc_out_string identity = NULL;
+    mach_msg_type_number_t identity_len = 0;    
+   
     if (!err && !in_context  ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
     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_selection_hints_get_options (in_hints, &options);
+        
+        if (!err && !options) {
+            err = kim_options_create (&options);
+        }
+    }
+    
+    if (!err) {
+        err = kim_options_get_start_time (options, &start_time);
+    }
+    
+    if (!err) {
+        err = kim_options_get_lifetime (options, &lifetime);
+    }
+    
+    if (!err) {
+        err = kim_options_get_renewable (options, &renewable);
+    }
+    
+    if (!err) {
+        err = kim_options_get_renewal_lifetime (options, &renewal_lifetime);
+    }
+    
+    if (!err) {
+        err = kim_options_get_forwardable (options, &forwardable);
+    }
+    
+    if (!err) {
+        err = kim_options_get_proxiable (options, &proxiable);
+    }
+    
+    if (!err) {
+        err = kim_options_get_addressless (options, &addressless);
+    }
+    
+    if (!err) {
+        err = kim_options_get_service_name (options, &service_name);
+    }
+    
+    if (!err) {
+        err = kim_selection_hints_get_explanation (in_hints, &explanation);
+    }
+
+    if (!err) {
+        err = kim_selection_hints_get_application_id (in_hints, &application_id);
+    }
+    
+    if (!err) {
+        err = kim_selection_hints_get_hint (in_hints, 
+                                            kim_hint_key_service_identity,
+                                            &service_identity_hint);
+    }
+    
+    if (!err) {
+        err = kim_selection_hints_get_hint (in_hints, 
+                                            kim_hint_key_client_realm,
+                                            &client_realm_hint);
+    }
+    
+    if (!err) {
+        err = kim_selection_hints_get_hint (in_hints, 
+                                            kim_hint_key_user,
+                                            &user_hint);
+    }
+    
+    if (!err) {
+        err = kim_selection_hints_get_hint (in_hints, 
+                                            kim_hint_key_service_realm,
+                                            &service_realm_hint);
+    }
+    
+    if (!err) {
+        err = kim_selection_hints_get_hint (in_hints, 
+                                            kim_hint_key_service,
+                                            &service_hint);
+    }
+    
+    if (!err) {
+        err = kim_selection_hints_get_hint (in_hints, 
+                                            kim_hint_key_server,
+                                            &server_hint);
+    }
+    
     if (!err) {
         kim_ui_gui_context context = (kim_ui_gui_context) in_context->tcontext;
+        kim_mipc_error result = 0;
         
+        err = kim_mipc_cli_select_identity (context->port,
+                                            application_id,
+                                            kim_string_buflen (application_id),
+                                            explanation,
+                                            kim_string_buflen (explanation),
+                                            
+                                            start_time,
+                                            lifetime,
+                                            renewable,
+                                            renewal_lifetime,
+                                            forwardable,
+                                            proxiable,
+                                            addressless,
+                                            service_name, 
+                                            kim_string_buflen (service_name),
+                                            
+                                            service_identity_hint, 
+                                            kim_string_buflen (service_identity_hint),
+                                            
+                                            client_realm_hint, 
+                                            kim_string_buflen (client_realm_hint),
+                                            
+                                            user_hint, 
+                                            kim_string_buflen (user_hint),
+                                            
+                                            service_realm_hint, 
+                                            kim_string_buflen (service_realm_hint),
+                                           
+                                            service_hint, 
+                                            kim_string_buflen (service_hint),
+                                            
+                                            server_hint, 
+                                            kim_string_buflen (server_hint),
+                                            
+                                            &identity,
+                                            &identity_len,
+                                            &result);        
+        if (!err) { err = check_error (result); }
+    }
+    
+    if (!err) {
+        err = kim_identity_create_from_string (out_identity, identity);
     }
     
+    if (identity) { vm_deallocate (mach_task_self (), 
+                                   (vm_address_t) identity, identity_len); }
+    
+    kim_string_free (&application_id);
+    kim_string_free (&explanation);
+    kim_string_free (&service_name);
+    kim_string_free (&service_identity_hint);
+    kim_string_free (&client_realm_hint);
+    kim_string_free (&user_hint);
+    kim_string_free (&service_realm_hint);
+    kim_string_free (&service_hint);
+    kim_string_free (&server_hint);
+    kim_options_free (&options);
+    
     return check_error (err);
 }
 
@@ -184,17 +357,47 @@ kim_error kim_os_ui_gui_auth_prompt (kim_ui_context     *in_context,
                                      char              **out_reply)
 {
     kim_error err = KIM_NO_ERROR;
+    kim_string identity_string = NULL;
+    kim_mipc_out_string reply = NULL;
+    mach_msg_type_number_t reply_len = 0;    
     
     if (!err && !in_context ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
     if (!err && !in_identity) { err = check_error (KIM_NULL_PARAMETER_ERR); }
     if (!err && !out_reply  ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
     /* in_title, in_message or in_description may be NULL */
     
+    if (!err) {
+        err = kim_identity_get_string (in_identity, &identity_string);
+    }
+    
     if (!err) {
         kim_ui_gui_context context = (kim_ui_gui_context) in_context->tcontext;
-        
+        kim_mipc_error result = 0;
+
+        err = kim_mipc_cli_auth_prompt (context->port,
+                                        identity_string, 
+                                        kim_string_buflen (identity_string),
+                                        in_type,
+                                        in_hide_reply,
+                                        in_title, 
+                                        kim_string_buflen (in_title),
+                                        in_message, 
+                                        kim_string_buflen (in_message),
+                                        in_description, 
+                                        kim_string_buflen (in_description),
+                                        &reply,
+                                        &reply_len,
+                                        &result);
+        if (!err) { err = check_error (result); }
+    }
+    
+    if (!err) {
+        err = kim_string_copy ((kim_string *) out_reply, reply);
     }
     
+    if (reply) { vm_deallocate (mach_task_self (), (vm_address_t) reply, reply_len); }
+    kim_string_free (&identity_string);
+    
     return check_error (err);
 }
 
@@ -208,18 +411,82 @@ kim_error kim_os_ui_gui_change_password (kim_ui_context      *in_context,
                                          char               **out_verify_password)
 {
     kim_error err = KIM_NO_ERROR;
+    kim_string identity_string = NULL;
+    
+    kim_mipc_out_string old_password_buf = NULL;
+    mach_msg_type_number_t old_password_len = 0;    
+    kim_mipc_out_string new_password_buf = NULL;
+    mach_msg_type_number_t new_password_len = 0;    
+    kim_mipc_out_string verify_password_buf = NULL;
+    mach_msg_type_number_t verify_password_len = 0;  
     
+    kim_string old_password = NULL;
+    kim_string new_password = NULL;
+    kim_string verify_password = NULL;
+   
     if (!err && !in_context         ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
     if (!err && !in_identity        ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
     if (!err && !out_old_password   ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
     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_identity_get_string (in_identity, &identity_string);
+    }
+    
     if (!err) {
         kim_ui_gui_context context = (kim_ui_gui_context) in_context->tcontext;
+        kim_mipc_error result = 0;
         
+        err = kim_mipc_cli_change_password (context->port,
+                                            identity_string, 
+                                            kim_string_buflen (identity_string),
+                                            in_old_password_expired,
+                                            &old_password_buf,
+                                            &old_password_len,
+                                            &new_password_buf,
+                                            &new_password_len,
+                                            &verify_password_buf,
+                                            &verify_password_len,
+                                            &result);
+        if (!err) { err = check_error (result); }        
+    }
+    
+    if (!err) {
+        err = kim_string_copy (&old_password, old_password_buf);
+    }
+    
+    if (!err) {
+        err = kim_string_copy (&new_password, new_password_buf);
+    }
+    
+    if (!err) {
+        err = kim_string_copy (&verify_password, verify_password_buf);
+    }
+    
+    if (!err) {
+        *out_old_password = (char *) old_password;
+        old_password = NULL;
+        *out_new_password = (char *) new_password;
+        new_password = NULL;
+        *out_verify_password = (char *) verify_password;
+        verify_password = NULL;
     }
     
+    if (old_password_buf) { vm_deallocate (mach_task_self (), 
+                                           (vm_address_t) old_password_buf, 
+                                           old_password_len); }
+    if (new_password_buf) { vm_deallocate (mach_task_self (), 
+                                           (vm_address_t) new_password_buf, 
+                                           new_password_len); }
+    if (verify_password_buf) { vm_deallocate (mach_task_self (), 
+                                              (vm_address_t) verify_password_buf, 
+                                              verify_password_len); }
+    kim_string_free (&identity_string);    
+    kim_string_free (&old_password);    
+    kim_string_free (&new_password);    
+    kim_string_free (&verify_password);    
+    
     return check_error (err);
 }
 
@@ -232,16 +499,34 @@ kim_error kim_os_ui_gui_handle_error (kim_ui_context    *in_context,
                                       kim_string         in_error_description)
 {
     kim_error err = KIM_NO_ERROR;
+    kim_string identity_string = NULL;
     
     if (!err && !in_context          ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
     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_identity_get_string (in_identity, &identity_string);
+    }
+    
     if (!err) {
         kim_ui_gui_context context = (kim_ui_gui_context) in_context->tcontext;
+        kim_mipc_error result = 0;
         
+        err = kim_mipc_cli_handle_error (context->port,
+                                         identity_string, 
+                                         kim_string_buflen (identity_string),
+                                         in_error,
+                                         in_error_message, 
+                                         kim_string_buflen (in_error_message),
+                                         in_error_description, 
+                                         kim_string_buflen (in_error_description),
+                                         &result);
+        if (!err) { err = check_error (result); }        
     }
     
+    kim_string_free (&identity_string);    
+
     return check_error (err);
 }
 
@@ -263,6 +548,11 @@ kim_error kim_os_ui_gui_fini (kim_ui_context *io_context)
     
     if (!err) {
         kim_ui_gui_context context = (kim_ui_gui_context) io_context->tcontext;
+        kim_mipc_error result = 0;
+        
+        err = kim_mipc_cli_fini (context->port, &result);
+        if (!err) { err = check_error (result); }
+        
         
         if (!err) {
             kim_os_ui_gui_context_free (&context);
index ad10c74183fbc758f4554344891110dd3a3caa37..8d041cf40ff22c4766c12cbf030e63bdfd35e687 100644 (file)
@@ -57,6 +57,7 @@ routine enter_identity (in_server_port : mach_port_t;
                          out out_error : kim_mipc_error);
 
 routine select_identity (in_server_port : mach_port_t;
+                      in_application_id : kim_mipc_in_string;
                          in_explanation : kim_mipc_in_string;
                          
                           in_start_time : kim_mipc_time;
@@ -81,7 +82,7 @@ routine select_identity (in_server_port : mach_port_t;
 routine auth_prompt (in_server_port : mach_port_t;
                         in_identity : kim_mipc_in_string;
                      in_prompt_type : kim_mipc_prompt_type;
-                          in_hidden : kim_mipc_boolean;
+                      in_hide_reply : kim_mipc_boolean;
                            in_title : kim_mipc_in_string;
                          in_message : kim_mipc_in_string;
                      in_description : kim_mipc_in_string;