diff options
| author | Alexandra Ellwood <lxs@mit.edu> | 2008-09-28 19:43:47 +0000 |
|---|---|---|
| committer | Alexandra Ellwood <lxs@mit.edu> | 2008-09-28 19:43:47 +0000 |
| commit | b5dce4285a9330d25542528030ce93da78e36375 (patch) | |
| tree | c8cbd6a729cddb99bda84991e1c7c231449434f2 /src | |
| parent | 01a5986cbf7afdba2b805bdd16893b6b52c87f42 (diff) | |
| download | krb5-b5dce4285a9330d25542528030ce93da78e36375.tar.gz krb5-b5dce4285a9330d25542528030ce93da78e36375.tar.xz krb5-b5dce4285a9330d25542528030ce93da78e36375.zip | |
Create common stream and ipc layer for CCAPI and KIM.
Will switch CCAPI to this new code later though, so as
not to destabilize KfM and the Windows builds.
ticket: 6055
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@20769 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src')
| -rw-r--r-- | src/include/k5-ipc_stream.h | 82 | ||||
| -rw-r--r-- | src/include/k5-thread.h | 3 | ||||
| -rw-r--r-- | src/include/kim/kim_ui_plugin.h | 2 | ||||
| -rw-r--r-- | src/kim/agent/mac/ServerDemux.h | 58 | ||||
| -rw-r--r-- | src/kim/agent/mac/ServerDemux.m | 810 | ||||
| -rw-r--r-- | src/kim/agent/mac/ServerThread.h | 92 | ||||
| -rw-r--r-- | src/kim/agent/mac/ServerThread.m | 221 | ||||
| -rw-r--r-- | src/kim/agent/mac/main.m | 17 | ||||
| -rw-r--r-- | src/kim/lib/mac/kim_os_ui_gui.c | 543 | ||||
| -rw-r--r-- | src/kim/mac/kim_mig.defs | 107 | ||||
| -rw-r--r-- | src/util/mac/k5_mig.defs | 54 | ||||
| -rw-r--r-- | src/util/mac/k5_mig_client.c | 292 | ||||
| -rw-r--r-- | src/util/mac/k5_mig_client.h (renamed from src/kim/mac/kim_mig_types.h) | 22 | ||||
| -rw-r--r-- | src/util/mac/k5_mig_reply.defs | 58 | ||||
| -rw-r--r-- | src/util/mac/k5_mig_request.defs | 62 | ||||
| -rw-r--r-- | src/util/mac/k5_mig_server.c | 233 | ||||
| -rw-r--r-- | src/util/mac/k5_mig_server.h | 53 | ||||
| -rw-r--r-- | src/util/mac/k5_mig_types.h | 55 | ||||
| -rw-r--r-- | src/util/support/ipc_stream.c | 507 |
19 files changed, 2110 insertions, 1161 deletions
diff --git a/src/include/k5-ipc_stream.h b/src/include/k5-ipc_stream.h new file mode 100644 index 0000000000..55397ef908 --- /dev/null +++ b/src/include/k5-ipc_stream.h @@ -0,0 +1,82 @@ +/* + * $Header$ + * + * Copyright 2006 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. + */ + +#ifndef K5_IPC_STREAM_H +#define K5_IPC_STREAM_H + +#include "k5-platform.h" + +struct k5_ipc_stream; +typedef struct k5_ipc_stream *k5_ipc_stream; + + +int32_t k5_ipc_stream_new (k5_ipc_stream *out_stream); + +uint32_t k5_ipc_stream_release (k5_ipc_stream io_stream); + +uint64_t k5_ipc_stream_size (k5_ipc_stream in_stream); + +const char *k5_ipc_stream_data (k5_ipc_stream in_stream); + +uint32_t k5_ipc_stream_read (k5_ipc_stream in_stream, + void *io_data, + uint64_t in_size); +uint32_t k5_ipc_stream_write (k5_ipc_stream in_stream, + const void *in_data, + uint64_t in_size); + +uint32_t k5_ipc_stream_read_string (k5_ipc_stream io_stream, + char **out_string); +uint32_t k5_ipc_stream_write_string (k5_ipc_stream io_stream, + const char *in_string); +void k5_ipc_stream_free_string (char *in_string); + +uint32_t k5_ipc_stream_read_int32 (k5_ipc_stream io_stream, + int32_t *out_int32); +uint32_t k5_ipc_stream_write_int32 (k5_ipc_stream io_stream, + int32_t in_int32); + +uint32_t k5_ipc_stream_read_uint32 (k5_ipc_stream io_stream, + uint32_t *out_uint32); +uint32_t k5_ipc_stream_write_uint32 (k5_ipc_stream io_stream, + uint32_t in_uint32); + +uint32_t k5_ipc_stream_read_int64 (k5_ipc_stream io_stream, + int64_t *out_int64); +uint32_t k5_ipc_stream_write_int64 (k5_ipc_stream io_stream, + int64_t in_int64); + +uint32_t k5_ipc_stream_read_uint64 (k5_ipc_stream io_stream, + uint64_t *out_uint64); +uint32_t k5_ipc_stream_write_uint64 (k5_ipc_stream io_stream, + uint64_t in_uint64); + +uint32_t k5_ipc_stream_read_time (k5_ipc_stream io_stream, + time_t *out_time); +uint32_t k5_ipc_stream_write_time (k5_ipc_stream io_stream, + time_t in_time); + +#endif /* K5_IPC_STREAM_H */ diff --git a/src/include/k5-thread.h b/src/include/k5-thread.h index c2d4f4bf28..57aa78f4b9 100644 --- a/src/include/k5-thread.h +++ b/src/include/k5-thread.h @@ -414,6 +414,9 @@ typedef enum { K5_KEY_CCAPI_REQUEST_PORT, K5_KEY_CCAPI_REPLY_STREAM, K5_KEY_CCAPI_SERVER_DIED, + K5_KEY_IPC_REQUEST_PORT, + K5_KEY_IPC_REPLY_STREAM, + K5_KEY_IPC_SERVER_DIED, K5_KEY_COM_ERR_REENTER, #endif K5_KEY_MAX diff --git a/src/include/kim/kim_ui_plugin.h b/src/include/kim/kim_ui_plugin.h index b7d48ad89a..0f6895ffc6 100644 --- a/src/include/kim/kim_ui_plugin.h +++ b/src/include/kim/kim_ui_plugin.h @@ -40,7 +40,7 @@ enum kim_prompt_type_enum { kim_prompt_type_password = 0, kim_prompt_type_preauth = 1 }; - + /* * Plugins for Controlling Identity Selection and Credential Acquisition * diff --git a/src/kim/agent/mac/ServerDemux.h b/src/kim/agent/mac/ServerDemux.h new file mode 100644 index 0000000000..12afa36c2c --- /dev/null +++ b/src/kim/agent/mac/ServerDemux.h @@ -0,0 +1,58 @@ +/* + * 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 "k5_mig_requestServer.h" +#import "k5_mig_reply.h" +#import "k5-ipc_stream.h" +#import "k5_mig_server.h" + + +int32_t kim_agent_listen_loop (void); + +int32_t kim_handle_reply_init (mach_port_t in_reply_port, + int32_t in_error); + +int32_t kim_handle_reply_enter_identity (mach_port_t in_reply_port, + kim_identity in_identity, + int32_t in_error); + +int32_t kim_handle_reply_select_identity (mach_port_t in_reply_port, + kim_identity in_identity, + int32_t in_error); + +int32_t kim_handle_reply_auth_prompt (mach_port_t in_reply_port, + kim_string in_prompt_response, + int32_t in_error); + +int32_t kim_handle_reply_change_password (mach_port_t in_reply_port, + kim_string in_old_password, + kim_string in_new_password, + kim_string in_vfy_password, + int32_t in_error); + +int32_t kim_handle_reply_handle_error (mach_port_t in_reply_port, + int32_t in_error); + +int32_t kim_handle_reply_fini (mach_port_t in_reply_port, + int32_t in_error); diff --git a/src/kim/agent/mac/ServerDemux.m b/src/kim/agent/mac/ServerDemux.m index b7f2084177..7c2e4f0842 100644 --- a/src/kim/agent/mac/ServerDemux.m +++ b/src/kim/agent/mac/ServerDemux.m @@ -22,18 +22,16 @@ * or implied warranty. */ -#import "kim_migServer.h" -#import "ServerThread.h" +#import "ServerDemux.h" // --------------------------------------------------------------------------- -static kim_boolean caller_is_front_process (task_t in_task, +static kim_boolean caller_is_front_process (pid_t in_pid, NSString *in_path) { kim_error err = KIM_NO_ERROR; - Boolean is_front_process; - pid_t task_pid; - ProcessSerialNumber task_psn, front_psn; + kim_boolean is_front_process = FALSE; + NSNumber *active_pid = NULL; NSBundle *bundle = [NSBundle bundleWithPath: in_path]; if (bundle) { @@ -46,573 +44,553 @@ static kim_boolean caller_is_front_process (task_t in_task, } if (!err) { - err = pid_for_task (in_task, &task_pid); + NSDictionary *activeApplication = [[NSWorkspace sharedWorkspace] activeApplication]; + if (activeApplication) { + active_pid = [activeApplication objectForKey: @"NSApplicationProcessIdentifier"]; + } + } + + if (!err && active_pid) { + is_front_process = ([active_pid intValue] == in_pid); } + return is_front_process; +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +static int32_t kim_handle_request_init (mach_port_t in_client_port, + mach_port_t in_reply_port, + k5_ipc_stream in_request_stream) +{ + int32_t err = 0; + int32_t pid = 0; + char *name = NULL; + char *path = NULL; + bool isFrontProcess = 0; + if (!err) { - err = GetProcessForPID (task_pid, &task_psn); + err = k5_ipc_stream_read_int32 (in_request_stream, &pid); } if (!err) { - err = GetFrontProcess (&front_psn); + err = k5_ipc_stream_read_string (in_request_stream, &name); + } + + if (!err) { + err = k5_ipc_stream_read_string (in_request_stream, &path); + } + + + if (!err) { + isFrontProcess = caller_is_front_process (pid, + [NSString stringWithUTF8String: path]); } if (!err) { - err = SameProcess (&task_psn, &front_psn, &is_front_process); +#warning Send init message to main thread with 2 ports, name and path } - return !err ? is_front_process : FALSE; -} + k5_ipc_stream_free_string (name); + k5_ipc_stream_free_string (path); -#pragma mark - + return err; +} /* ------------------------------------------------------------------------ */ -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) +int32_t kim_handle_reply_init (mach_port_t in_reply_port, + int32_t in_error) { - kern_return_t err = 0; - ServerThread *sthread = NULL; + int32_t err = 0; + k5_ipc_stream reply = NULL; if (!err) { - sthread = [ServerThread sharedServerThread]; - if (!sthread) { err = KIM_OUT_OF_MEMORY_ERR; } + err = k5_ipc_stream_new (&reply); } if (!err) { - kim_mipc_error result = KIM_NO_ERROR; - NSString *name = NULL; - NSString *path = NULL; + err = k5_ipc_stream_write_int32 (reply, in_error); + } + + if (!err) { + err = k5_ipc_server_send_reply (in_reply_port, reply); + } + + k5_ipc_stream_release (reply); + + return err; +} - if (in_application_name) { - name = [NSString stringWithUTF8String: in_application_name]; - } +#pragma mark - - 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; +/* ------------------------------------------------------------------------ */ + +static int32_t kim_handle_request_enter_identity (mach_port_t in_client_port, + mach_port_t in_reply_port, + k5_ipc_stream in_request_stream) +{ + int32_t err = 0; + + if (!err) { +#warning Send enter identity message to main thread with 2 ports } - return err; + 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) +int32_t kim_handle_reply_enter_identity (mach_port_t in_reply_port, + kim_identity in_identity, + int32_t in_error) { - kern_return_t err = 0; - kim_error result = KIM_NO_ERROR; - ClientConnection *client = NULL; - kim_identity identity = NULL; + int32_t err = 0; + k5_ipc_stream reply = 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; } - } + err = kim_identity_get_string (in_identity, &identity_string); } if (!err) { - identity = [client enterIdentityWithError: &result]; + err = k5_ipc_stream_new (&reply); } - 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) { + err = k5_ipc_stream_write_int32 (reply, in_error); } - if (!err && !result) { - memmove (identity_buf, identity_string, identity_len); - *out_identity = identity_buf; - *out_identityCnt = identity_len; - identity_buf = NULL; + if (!err && !in_error) { + err = k5_ipc_stream_write_string (reply, identity_string); } if (!err) { - *out_error = result; + err = k5_ipc_server_send_reply (in_reply_port, reply); } - if (identity_buf) { vm_deallocate (mach_task_self (), (vm_address_t) identity_buf, identity_len); } kim_string_free (&identity_string); - kim_identity_free (&identity); + k5_ipc_stream_release (reply); - return err; + return err; } +#pragma mark - + /* ------------------------------------------------------------------------ */ -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) +static int32_t kim_handle_request_select_identity (mach_port_t in_client_port, + mach_port_t in_reply_port, + k5_ipc_stream in_request_stream) { - kern_return_t err = 0; - kim_error result = KIM_NO_ERROR; - ClientConnection *client = NULL; + int32_t err = 0; 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); - } + //err = kim_os_selection_hints_read (out_hints, in_request_stream); + } 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); +#warning Send select identity message to main thread with 2 ports } + kim_selection_hints_free (&hints); + + return err; +} + +/* ------------------------------------------------------------------------ */ + +int32_t kim_handle_reply_select_identity (mach_port_t in_reply_port, + kim_identity in_identity, + int32_t in_error) +{ + int32_t err = 0; + k5_ipc_stream reply = NULL; + kim_string identity_string = NULL; + if (!err) { - err = kim_selection_hints_set_explanation (hints, in_explanation); + err = kim_identity_get_string (in_identity, &identity_string); } - if (!err && in_service_identity_hint) { - err = kim_selection_hints_set_hint (hints, - kim_hint_key_service_identity, - in_service_identity_hint); + if (!err) { + err = k5_ipc_stream_new (&reply); } - if (!err && in_client_realm_hint) { - err = kim_selection_hints_set_hint (hints, - kim_hint_key_client_realm, - in_client_realm_hint); + if (!err) { + err = k5_ipc_stream_write_int32 (reply, in_error); } - if (!err && in_user_hint) { - err = kim_selection_hints_set_hint (hints, - kim_hint_key_user, - in_user_hint); + if (!err && !in_error) { + err = k5_ipc_stream_write_string (reply, identity_string); } - if (!err && in_service_realm_hint) { - err = kim_selection_hints_set_hint (hints, - kim_hint_key_service_realm, - in_service_realm_hint); + if (!err) { + err = k5_ipc_server_send_reply (in_reply_port, reply); } - if (!err && in_service_hint) { - err = kim_selection_hints_set_hint (hints, - kim_hint_key_service, - in_service_hint); - } + kim_string_free (&identity_string); + k5_ipc_stream_release (reply); - if (!err && in_server_hint) { - err = kim_selection_hints_set_hint (hints, - kim_hint_key_server, - in_server_hint); - } + return err; +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +static int32_t kim_handle_request_auth_prompt (mach_port_t in_client_port, + mach_port_t in_reply_port, + k5_ipc_stream in_request_stream) +{ + int32_t err = 0; + char *identity_string = NULL; + int32_t type = 0; + int32_t hide_reply = 0; + char *title = NULL; + char *message = NULL; + char *description = 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; } - } - } + err = k5_ipc_stream_read_string (in_request_stream, &identity_string); + } if (!err) { - identity = [client selectIdentityWithHints: hints - error: &result]; - } + err = k5_ipc_stream_read_int32 (in_request_stream, &type); + } + + if (!err) { + err = k5_ipc_stream_read_int32 (in_request_stream, &hide_reply); + } + + if (!err) { + err = k5_ipc_stream_read_string (in_request_stream, &title); + } + + if (!err) { + err = k5_ipc_stream_read_string (in_request_stream, &message); + } - if (!err && !result) { - err = kim_identity_get_string (identity, &identity_string); + if (!err) { + err = k5_ipc_stream_read_string (in_request_stream, &description); + } + + if (!err) { +#warning Send auth prompt message to main thread with 2 ports and arguments } + + k5_ipc_stream_free_string (identity_string); + k5_ipc_stream_free_string (title); + k5_ipc_stream_free_string (message); + k5_ipc_stream_free_string (description); + + return err; +} - 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); +/* ------------------------------------------------------------------------ */ + +int32_t kim_handle_reply_auth_prompt (mach_port_t in_reply_port, + kim_string in_prompt_response, + int32_t in_error) +{ + int32_t err = 0; + k5_ipc_stream reply = NULL; + + if (!err) { + err = k5_ipc_stream_new (&reply); + } + + if (!err) { + err = k5_ipc_stream_write_int32 (reply, in_error); } - if (!err && !result) { - memmove (identity_buf, identity_string, identity_len); - *out_identity = identity_buf; - *out_identityCnt = identity_len; - identity_buf = NULL; + if (!err && !in_error) { + err = k5_ipc_stream_write_string (reply, in_prompt_response); } - + if (!err) { - *out_error = result; + err = k5_ipc_server_send_reply (in_reply_port, reply); } - 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; + k5_ipc_stream_release (reply); + + return err; } +#pragma mark - + /* ------------------------------------------------------------------------ */ -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) +static int32_t kim_handle_request_change_password (mach_port_t in_client_port, + mach_port_t in_reply_port, + k5_ipc_stream in_request_stream) { - 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; } - } + int32_t err = 0; + char *identity_string = NULL; + int32_t old_password_expired = 0; + + if (!err) { + err = k5_ipc_stream_read_string (in_request_stream, &identity_string); + } + + if (!err) { + err = k5_ipc_stream_read_int32 (in_request_stream, + &old_password_expired); + } + + if (!err) { +#warning Send change password message to main thread with 2 ports and arguments } + k5_ipc_stream_free_string (identity_string); + + return err; +} + +/* ------------------------------------------------------------------------ */ + +int32_t kim_handle_reply_change_password (mach_port_t in_reply_port, + kim_string in_old_password, + kim_string in_new_password, + kim_string in_vfy_password, + int32_t in_error) +{ + int32_t err = 0; + k5_ipc_stream reply = NULL; + if (!err) { - err = kim_identity_create_from_string (&identity, in_identity); + err = k5_ipc_stream_new (&reply); } 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]; + err = k5_ipc_stream_write_int32 (reply, in_error); + } + + if (!err && !in_error) { + err = k5_ipc_stream_write_string (reply, in_old_password); } - 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 && !in_error) { + err = k5_ipc_stream_write_string (reply, in_new_password); } - if (!err && !result) { - memmove (response_buf, response_string, response_len); - *out_response = response_buf; - *out_responseCnt = response_len; - response_buf = NULL; + if (!err && !in_error) { + err = k5_ipc_stream_write_string (reply, in_vfy_password); } if (!err) { - *out_error = result; + err = k5_ipc_server_send_reply (in_reply_port, reply); } - if (response_buf) { vm_deallocate (mach_task_self (), - (vm_address_t) response_buf, - response_len); } - kim_identity_free (&identity); + k5_ipc_stream_release (reply); - return err; + return err; } +#pragma mark - + /* ------------------------------------------------------------------------ */ -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) +static int32_t kim_handle_request_handle_error (mach_port_t in_client_port, + mach_port_t in_reply_port, + k5_ipc_stream in_request_stream) { - 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; } - } - } + int32_t err = 0; + char *identity_string = NULL; + int32_t error = 0; + char *message = NULL; + char *description = NULL; if (!err) { - err = kim_identity_create_from_string (&identity, in_identity); - } + err = k5_ipc_stream_read_string (in_request_stream, &identity_string); + } if (!err) { - passwords = [client changePasswordWithIdentity: identity - oldPasswordIsExpired: in_old_password_expired - error: &result]; - } + err = k5_ipc_stream_read_int32 (in_request_stream, &error); + } - 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) { + err = k5_ipc_stream_read_string (in_request_stream, &message); + } + + if (!err) { + err = k5_ipc_stream_read_string (in_request_stream, &description); + } + + if (!err) { +#warning Send handle error message to main thread with 2 ports and arguments } + + k5_ipc_stream_free_string (identity_string); + k5_ipc_stream_free_string (message); + k5_ipc_stream_free_string (description); + + return err; +} - 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); - - } +/* ------------------------------------------------------------------------ */ + +int32_t kim_handle_reply_handle_error (mach_port_t in_reply_port, + int32_t in_error) +{ + int32_t err = 0; + k5_ipc_stream reply = NULL; - 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) { + err = k5_ipc_stream_new (&reply); } - 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) { + err = k5_ipc_stream_write_int32 (reply, in_error); } - + if (!err) { - *out_error = result; + err = k5_ipc_server_send_reply (in_reply_port, reply); } - 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); + k5_ipc_stream_release (reply); - return err; + return err; } +#pragma mark - + /* ------------------------------------------------------------------------ */ -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) +static int32_t kim_handle_request_fini (mach_port_t in_client_port, + mach_port_t in_reply_port, + k5_ipc_stream in_request_stream) { - 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; } - } + int32_t err = 0; + + if (!err) { +#warning Send fini message to main thread with 2 ports } + return err; +} + +/* ------------------------------------------------------------------------ */ + +int32_t kim_handle_reply_fini (mach_port_t in_reply_port, + int32_t in_error) +{ + int32_t err = 0; + k5_ipc_stream reply = NULL; + if (!err) { - err = kim_identity_create_from_string (&identity, in_identity); + err = k5_ipc_stream_new (&reply); } 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]; + err = k5_ipc_stream_write_int32 (reply, in_error); } if (!err) { - *out_error = result; + err = k5_ipc_server_send_reply (in_reply_port, reply); } - kim_identity_free (&identity); + k5_ipc_stream_release (reply); + + return err; +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +int32_t k5_ipc_server_add_client (mach_port_t in_client_port) +{ + int32_t err = 0; + + if (!err) { + /* Don't need to do anything here since we have an init message */ + } return err; } /* ------------------------------------------------------------------------ */ -kern_return_t kim_mipc_srv_fini (mach_port_t in_server_port, - kim_mipc_error *out_error) +int32_t k5_ipc_server_remove_client (mach_port_t in_client_port) { - kern_return_t err = 0; - ServerThread *sthread = NULL; + int32_t err = 0; if (!err) { - sthread = [ServerThread sharedServerThread]; - if (!sthread) { err = KIM_OUT_OF_MEMORY_ERR; } + /* Client exited. Main thread should check for windows belonging to + * in_client_port and close any it finds. */ +#warning Insert code to handle client death here } + + return err; +} + +/* ------------------------------------------------------------------------ */ +int32_t k5_ipc_server_handle_request (mach_port_t in_client_port, + mach_port_t in_reply_port, + k5_ipc_stream in_request_stream) +{ + int32_t err = 0; + char *message_type = NULL; + if (!err) { - [sthread removeConnectionWithPort: in_server_port]; + err = k5_ipc_stream_read_string (in_request_stream, &message_type); } if (!err) { - *out_error = KIM_NO_ERROR; + if (!strcmp (message_type, "init")) { + err = kim_handle_request_init (in_client_port, + in_reply_port, + in_request_stream); + + } else if (!strcmp (message_type, "enter_identity")) { + err = kim_handle_request_enter_identity (in_client_port, + in_reply_port, + in_request_stream); + + } else if (!strcmp (message_type, "select_identity")) { + err = kim_handle_request_select_identity (in_client_port, + in_reply_port, + in_request_stream); + + } else if (!strcmp (message_type, "auth_prompt")) { + err = kim_handle_request_auth_prompt (in_client_port, + in_reply_port, + in_request_stream); + + } else if (!strcmp (message_type, "change_password")) { + err = kim_handle_request_change_password (in_client_port, + in_reply_port, + in_request_stream); + + } else if (!strcmp (message_type, "handle_error")) { + err = kim_handle_request_handle_error (in_client_port, + in_reply_port, + in_request_stream); + + } else if (!strcmp (message_type, "fini")) { + err = kim_handle_request_fini (in_client_port, + in_reply_port, + in_request_stream); + + } else { + err = EINVAL; + } } + k5_ipc_stream_free_string (message_type); + return err; } + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +int32_t kim_agent_listen_loop (void) +{ + return k5_ipc_server_listen_loop (); +} diff --git a/src/kim/agent/mac/ServerThread.h b/src/kim/agent/mac/ServerThread.h deleted file mode 100644 index 4457f2a629..0000000000 --- a/src/kim/agent/mac/ServerThread.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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 deleted file mode 100644 index 6d5ba5ed5c..0000000000 --- a/src/kim/agent/mac/ServerThread.m +++ /dev/null @@ -1,221 +0,0 @@ -/* - * 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 - diff --git a/src/kim/agent/mac/main.m b/src/kim/agent/mac/main.m index fb0b9dfd37..a6ffad1d0e 100644 --- a/src/kim/agent/mac/main.m +++ b/src/kim/agent/mac/main.m @@ -1,6 +1,19 @@ #import <Cocoa/Cocoa.h> +#import "k5_mig_server.h" -int main(int argc, char *argv[]) +int main(int argc, const char *argv[]) { - return NSApplicationMain(argc, (const char **) argv); + int err = 0; + + err = k5_ipc_server_initialize (argc, argv); + + if (!err) { + err = NSApplicationMain(argc, argv); + } + + if (!err) { + err = k5_ipc_server_cleanup (argc, argv); + } + + return err; } diff --git a/src/kim/lib/mac/kim_os_ui_gui.c b/src/kim/lib/mac/kim_os_ui_gui.c index 4f629105d9..7559dbed94 100644 --- a/src/kim/lib/mac/kim_os_ui_gui.c +++ b/src/kim/lib/mac/kim_os_ui_gui.c @@ -27,107 +27,74 @@ #ifndef LEAN_CLIENT #include "kim_os_private.h" -#include "kim_mig_types.h" -#include "kim_mig.h" -#define kKerberosAgentBundleID "edu.mit.Kerberos.KerberosAgent" -#define kKerberosAgentPath "/System/Library/CoreServices/KerberosAgent.app/Contents/MacOS/KerberosAgent" +#include "k5_mig_client.h" #include <Kerberos/kipc_client.h> #include <mach/mach.h> #include <mach/mach_error.h> +#include <unistd.h> -struct kim_ui_gui_context { - mach_port_t port; -}; /* ------------------------------------------------------------------------ */ -static void kim_os_ui_gui_context_free (kim_ui_gui_context *io_context) -{ - if (io_context && *io_context) { - free (*io_context); - *io_context = NULL; - } -} - -/* ------------------------------------------------------------------------ */ - -static kim_error kim_os_ui_gui_context_allocate (kim_ui_gui_context *out_context) +kim_error kim_os_ui_gui_init (kim_ui_context *io_context) { kim_error err = KIM_NO_ERROR; - kim_ui_gui_context context = NULL; - - if (!err && !out_context) { err = check_error (KIM_NULL_PARAMETER_ERR); } + kim_string name = NULL; + kim_string path = NULL; + k5_ipc_stream request = NULL; + k5_ipc_stream reply = NULL; if (!err) { - context = malloc (sizeof (*context)); - if (!context) { err = KIM_OUT_OF_MEMORY_ERR; } + err = kim_library_get_application_name (&name); } if (!err) { - context->port = MACH_PORT_NULL; - - *out_context = context; - context = NULL; + err = kim_os_library_get_application_path (&path); } - kim_os_ui_gui_context_free (&context); - - return check_error (err); -} - -#pragma mark - - -/* ------------------------------------------------------------------------ */ - -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) { + err = k5_ipc_stream_new (&request); + } - if (!err && !io_context) { err = check_error (KIM_NULL_PARAMETER_ERR); } + if (!err) { + err = k5_ipc_stream_write_string (request, "init"); + } if (!err) { - err = kim_os_ui_gui_context_allocate (&context); + err = k5_ipc_stream_write_int32 (request, getpid()); } if (!err) { - err = kim_library_get_application_name (&name); + err = k5_ipc_stream_write_string (request, name); } if (!err) { - err = kim_os_library_get_application_path (&path); + err = k5_ipc_stream_write_string (request, path); } - + if (!err) { - err = kipc_client_lookup_server (kim_os_agent_bundle_id, - 1 /* launch */, - 0 /* don't use cached port */, - &context->port); + err = k5_ipc_send_request (1 /* launch server */, + request, + &reply); } if (!err) { - kim_mipc_error result = 0; - - err = kim_mipc_cli_init (context->port, - mach_task_self (), - name, kim_string_buflen (name), - path, kim_string_buflen (path), - &result); + int32_t result = 0; + + err = k5_ipc_stream_read_int32 (reply, &result); if (!err) { err = check_error (result); } } if (!err) { - io_context->tcontext = context; - context = NULL; + io_context->tcontext = NULL; } + k5_ipc_stream_release (request); + k5_ipc_stream_release (reply); kim_string_free (&name); kim_string_free (&path); - kim_os_ui_gui_context_free (&context); return check_error (err); } @@ -138,29 +105,46 @@ 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; + k5_ipc_stream request = NULL; + k5_ipc_stream reply = NULL; + char *identity_string = NULL; - 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 = k5_ipc_stream_new (&request); + } + + if (!err) { + err = k5_ipc_stream_write_string (request, "enter_identity"); + } - err = kim_mipc_cli_enter_identity (context->port, - &identity, - &identity_len, - &result); + + if (!err) { + err = k5_ipc_send_request (0 /* don't launch server */, + request, + &reply); + if (!reply) { err = check_error (KIM_NO_SERVER_ERR); } + } + + if (!err) { + int32_t result = 0; + + err = k5_ipc_stream_read_int32 (reply, &result); if (!err) { err = check_error (result); } } if (!err) { - err = kim_identity_create_from_string (out_identity, identity); + err = k5_ipc_stream_read_string (reply, &identity_string); + } + + if (!err) { + err = kim_identity_create_from_string (out_identity, identity_string); } - if (identity) { vm_deallocate (mach_task_self (), - (vm_address_t) identity, identity_len); } + k5_ipc_stream_free_string (identity_string); + k5_ipc_stream_release (request); + k5_ipc_stream_release (reply); return check_error (err); } @@ -172,232 +156,136 @@ 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); } + k5_ipc_stream request = NULL; + k5_ipc_stream reply = NULL; + char *identity_string = NULL; + 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); - } + err = k5_ipc_stream_new (&request); } if (!err) { - err = kim_options_get_start_time (options, &start_time); + err = k5_ipc_stream_write_string (request, "select_identity"); } if (!err) { - err = kim_options_get_lifetime (options, &lifetime); + //err = kim_os_selection_hints_write (in_hints, request); } if (!err) { - err = kim_options_get_renewable (options, &renewable); + err = k5_ipc_send_request (0 /* don't launch server */, + request, + &reply); + if (!reply) { err = check_error (KIM_NO_SERVER_ERR); } } if (!err) { - err = kim_options_get_renewal_lifetime (options, &renewal_lifetime); - } - - if (!err) { - err = kim_options_get_forwardable (options, &forwardable); + int32_t result = 0; + + err = k5_ipc_stream_read_int32 (reply, &result); + if (!err) { err = check_error (result); } } if (!err) { - err = kim_options_get_proxiable (options, &proxiable); + err = k5_ipc_stream_read_string (reply, &identity_string); } if (!err) { - err = kim_options_get_addressless (options, &addressless); + err = kim_identity_create_from_string (out_identity, identity_string); } - if (!err) { - err = kim_options_get_service_name (options, &service_name); - } + k5_ipc_stream_free_string (identity_string); + k5_ipc_stream_release (request); + k5_ipc_stream_release (reply); - if (!err) { - err = kim_selection_hints_get_explanation (in_hints, &explanation); - } + return check_error (err); +} +/* ------------------------------------------------------------------------ */ + +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 err = KIM_NO_ERROR; + k5_ipc_stream request = NULL; + k5_ipc_stream reply = NULL; + kim_string identity_string = NULL; + + 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_selection_hints_get_application_id (in_hints, &application_id); + err = kim_identity_get_string (in_identity, &identity_string); } if (!err) { - err = kim_selection_hints_get_hint (in_hints, - kim_hint_key_service_identity, - &service_identity_hint); + err = k5_ipc_stream_new (&request); } if (!err) { - err = kim_selection_hints_get_hint (in_hints, - kim_hint_key_client_realm, - &client_realm_hint); + err = k5_ipc_stream_write_string (request, "auth_prompt"); } if (!err) { - err = kim_selection_hints_get_hint (in_hints, - kim_hint_key_user, - &user_hint); + err = k5_ipc_stream_write_string (request, identity_string); } if (!err) { - err = kim_selection_hints_get_hint (in_hints, - kim_hint_key_service_realm, - &service_realm_hint); + err = k5_ipc_stream_write_int32 (request, in_type); } if (!err) { - err = kim_selection_hints_get_hint (in_hints, - kim_hint_key_service, - &service_hint); + err = k5_ipc_stream_write_int32 (request, in_hide_reply); } if (!err) { - err = kim_selection_hints_get_hint (in_hints, - kim_hint_key_server, - &server_hint); + err = k5_ipc_stream_write_string (request, + in_title ? in_title : ""); } 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); } + err = k5_ipc_stream_write_string (request, + in_message ? in_message : ""); } if (!err) { - err = kim_identity_create_from_string (out_identity, identity); + err = k5_ipc_stream_write_string (request, + in_description ? in_description : ""); } - 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); -} - -/* ------------------------------------------------------------------------ */ - -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 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); + err = k5_ipc_send_request (0 /* don't launch server */, + request, + &reply); + if (!reply) { err = check_error (KIM_NO_SERVER_ERR); } } 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); + int32_t result = 0; + + err = k5_ipc_stream_read_int32 (reply, &result); if (!err) { err = check_error (result); } } if (!err) { - err = kim_string_copy ((kim_string *) out_reply, reply); - } + err = k5_ipc_stream_read_string (reply, out_reply); + } - if (reply) { vm_deallocate (mach_task_self (), (vm_address_t) reply, reply_len); } kim_string_free (&identity_string); - + + k5_ipc_stream_release (request); + k5_ipc_stream_release (reply); + return check_error (err); } @@ -408,85 +296,85 @@ kim_error kim_os_ui_gui_change_password (kim_ui_context *in_context, kim_boolean in_old_password_expired, char **out_old_password, char **out_new_password, - char **out_verify_password) + char **out_vfy_password) { kim_error err = KIM_NO_ERROR; + k5_ipc_stream request = NULL; + k5_ipc_stream reply = NULL; 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; + char *old_password = NULL; + char *new_password = NULL; + char *vfy_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 && !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_vfy_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); } + err = k5_ipc_stream_new (&request); } if (!err) { - err = kim_string_copy (&old_password, old_password_buf); + err = k5_ipc_stream_write_string (request, "change_password"); } if (!err) { - err = kim_string_copy (&new_password, new_password_buf); + err = k5_ipc_stream_write_string (request, identity_string); } if (!err) { - err = kim_string_copy (&verify_password, verify_password_buf); + err = k5_ipc_stream_write_int32 (request, in_old_password_expired); } if (!err) { + err = k5_ipc_send_request (0 /* don't launch server */, + request, + &reply); + if (!reply) { err = check_error (KIM_NO_SERVER_ERR); } + } + + if (!err) { + int32_t result = 0; + + err = k5_ipc_stream_read_int32 (reply, &result); + if (!err) { err = check_error (result); } + } + + if (!err) { + err = k5_ipc_stream_read_string (reply, &old_password); + } + + if (!err) { + err = k5_ipc_stream_read_string (reply, &new_password); + } + + if (!err) { + err = k5_ipc_stream_read_string (reply, &vfy_password); + } + + 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); } + *out_vfy_password = (char *) vfy_password; + vfy_password = NULL; + } + kim_string_free (&identity_string); - kim_string_free (&old_password); - kim_string_free (&new_password); - kim_string_free (&verify_password); + k5_ipc_stream_free_string (old_password); + k5_ipc_stream_free_string (new_password); + k5_ipc_stream_free_string (vfy_password); + k5_ipc_stream_release (request); + k5_ipc_stream_release (reply); + return check_error (err); } @@ -499,9 +387,10 @@ kim_error kim_os_ui_gui_handle_error (kim_ui_context *in_context, kim_string in_error_description) { kim_error err = KIM_NO_ERROR; + k5_ipc_stream request = NULL; + k5_ipc_stream reply = NULL; 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); } @@ -510,23 +399,48 @@ kim_error kim_os_ui_gui_handle_error (kim_ui_context *in_context, } if (!err) { - kim_ui_gui_context context = (kim_ui_gui_context) in_context->tcontext; - kim_mipc_error result = 0; + err = k5_ipc_stream_new (&request); + } + + if (!err) { + err = k5_ipc_stream_write_string (request, "handle_error"); + } + + if (!err) { + err = k5_ipc_stream_write_string (request, identity_string); + } + + if (!err) { + err = k5_ipc_stream_write_int32 (request, in_error); + } + + if (!err) { + err = k5_ipc_stream_write_string (request, in_error_message); + } + + if (!err) { + err = k5_ipc_stream_write_string (request, in_error_description); + } + + if (!err) { + err = k5_ipc_send_request (0 /* don't launch server */, + request, + &reply); + if (!reply) { err = check_error (KIM_NO_SERVER_ERR); } + } + + if (!err) { + int32_t 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); } + err = k5_ipc_stream_read_int32 (reply, &result); + if (!err) { err = check_error (result); } } kim_string_free (&identity_string); + k5_ipc_stream_release (request); + k5_ipc_stream_release (reply); + return check_error (err); } @@ -543,23 +457,34 @@ void kim_os_ui_gui_free_string (kim_ui_context *in_context, kim_error kim_os_ui_gui_fini (kim_ui_context *io_context) { kim_error err = KIM_NO_ERROR; + k5_ipc_stream request = NULL; + k5_ipc_stream reply = NULL; + + if (!err) { + err = k5_ipc_stream_new (&request); + } + + if (!err) { + err = k5_ipc_stream_write_string (request, "fini"); + } - if (!err && !io_context) { err = check_error (KIM_NULL_PARAMETER_ERR); } + if (!err) { + err = k5_ipc_send_request (0 /* don't launch server */, + request, + &reply); + if (!reply) { err = check_error (KIM_NO_SERVER_ERR); } + } if (!err) { - kim_ui_gui_context context = (kim_ui_gui_context) io_context->tcontext; - kim_mipc_error result = 0; + int32_t result = 0; - err = kim_mipc_cli_fini (context->port, &result); + err = k5_ipc_stream_read_int32 (reply, &result); if (!err) { err = check_error (result); } - - - if (!err) { - kim_os_ui_gui_context_free (&context); - io_context->tcontext = NULL; - } } + k5_ipc_stream_release (request); + k5_ipc_stream_release (reply); + return check_error (err); } diff --git a/src/kim/mac/kim_mig.defs b/src/kim/mac/kim_mig.defs deleted file mode 100644 index 8d041cf40f..0000000000 --- a/src/kim/mac/kim_mig.defs +++ /dev/null @@ -1,107 +0,0 @@ -/* - * $Header$ - * - * Copyright 2006-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 <mach/std_types.defs> -#include <mach/mach_types.defs> - -import "kim_mig_types.h"; - -subsystem kim 100; - -serverprefix kim_mipc_srv_; -userprefix kim_mipc_cli_; - -type kim_mipc_in_string = array [] of char; -type kim_mipc_out_string = array [] of char; -type kim_mipc_error = int32_t; -type kim_mipc_boolean = boolean_t; -type kim_mipc_time = uint32_t; -type kim_mipc_lifetime = uint32_t; -type kim_mipc_prompt_type = uint32_t; - -routine init (in_server_port : mach_port_t; - in_application_task : task_t; - in_application_name : kim_mipc_in_string; - in_application_path : kim_mipc_in_string; - out out_error : kim_mipc_error); - -routine fini (in_server_port : mach_port_t; - out out_error : kim_mipc_error); - - -routine enter_identity (in_server_port : mach_port_t; - out out_identity : kim_mipc_out_string; - 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; - in_lifetime : kim_mipc_lifetime; - in_renewable : kim_mipc_boolean; - in_renewal_lifetime : kim_mipc_lifetime; - in_forwardable : kim_mipc_boolean; - in_proxiable : kim_mipc_boolean; - in_addressless : kim_mipc_boolean; - in_service_name : kim_mipc_in_string; - - in_service_identity_hint : kim_mipc_in_string; - in_client_realm_hint : kim_mipc_in_string; - in_user_hint : kim_mipc_in_string; - in_service_realm_hint : kim_mipc_in_string; - in_service_hint : kim_mipc_in_string; - in_server_hint : kim_mipc_in_string; - - out out_identity : kim_mipc_out_string; - out out_error : kim_mipc_error); - -routine auth_prompt (in_server_port : mach_port_t; - in_identity : kim_mipc_in_string; - in_prompt_type : kim_mipc_prompt_type; - in_hide_reply : kim_mipc_boolean; - in_title : kim_mipc_in_string; - in_message : kim_mipc_in_string; - in_description : kim_mipc_in_string; - out out_response : kim_mipc_out_string; - out out_error : kim_mipc_error); - -routine change_password (in_server_port : mach_port_t; - in_identity : kim_mipc_in_string; - in_old_password_expired : kim_mipc_boolean; - out out_old_password : kim_mipc_out_string; - out out_new_password : kim_mipc_out_string; - out out_verify_password : kim_mipc_out_string; - out out_error : kim_mipc_error); - - routine handle_error (in_server_port : mach_port_t; - in_identity : kim_mipc_in_string; - in_error : kim_mipc_error; - in_message : kim_mipc_in_string; - in_description : kim_mipc_in_string; - out out_error : kim_mipc_error); - - diff --git a/src/util/mac/k5_mig.defs b/src/util/mac/k5_mig.defs new file mode 100644 index 0000000000..6349eb877f --- /dev/null +++ b/src/util/mac/k5_mig.defs @@ -0,0 +1,54 @@ +/* $Copyright: + * + * Copyright 2004-2006 by the 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 MIT 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Individual source code files are copyright MIT, Cygnus Support, + * OpenVision, Oracle, Sun Soft, FundsXpress, and others. + * + * Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira, + * and Zephyr are trademarks of the Massachusetts Institute of Technology + * (MIT). No commercial use of these trademarks may be made without prior + * written permission of MIT. + * + * "Commercial use" means use of a name in a product or other for-profit + * manner. It does NOT prevent a commercial firm from referring to the MIT + * trademarks in order to convey information (although in doing so, + * recognition of their trademark status should be given). + * $ + */ + +#include <mach/std_types.defs> +#include <mach/mach_types.defs> + +import "k5_mig_types.h"; + +/* Note the 1024 must be the same as K5_IPC_MAX_MSG_SIZE */ +type k5_ipc_inl_request_t = array [ * : 1024 ] of char; +type k5_ipc_ool_request_t = array [] of char; + +type k5_ipc_inl_reply_t = array [ * : 1024 ] of char; +type k5_ipc_ool_reply_t = array [] of char; diff --git a/src/util/mac/k5_mig_client.c b/src/util/mac/k5_mig_client.c new file mode 100644 index 0000000000..5ffe7deb8d --- /dev/null +++ b/src/util/mac/k5_mig_client.c @@ -0,0 +1,292 @@ +/* + * $Header$ + * + * Copyright 2006 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 "k5_mig_client.h" + +#include <Kerberos/kipc_client.h> +#include "k5_mig_request.h" +#include "k5_mig_replyServer.h" +#include "k5-thread.h" + +MAKE_INIT_FUNCTION(k5_cli_ipc_thread_init); +MAKE_FINI_FUNCTION(k5_cli_ipc_thread_fini); + +/* ------------------------------------------------------------------------ */ + +static int k5_cli_ipc_thread_init (void) +{ + int err = 0; + + err = k5_key_register (K5_KEY_IPC_REQUEST_PORT, free); + + if (!err) { + err = k5_key_register (K5_KEY_IPC_REPLY_STREAM, NULL); + } + + if (!err) { + err = k5_key_register (K5_KEY_IPC_SERVER_DIED, NULL); + } + + return err; +} + +/* ------------------------------------------------------------------------ */ + +static void k5_cli_ipc_thread_fini (void) +{ + k5_key_delete (K5_KEY_IPC_REQUEST_PORT); + k5_key_delete (K5_KEY_IPC_REPLY_STREAM); + k5_key_delete (K5_KEY_IPC_SERVER_DIED); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +static boolean_t k5_ipc_reply_demux (mach_msg_header_t *request, + mach_msg_header_t *reply) +{ + boolean_t handled = 0; + + if (CALL_INIT_FUNCTION (k5_cli_ipc_thread_init) != 0) { + return 0; + } + + if (!handled && request->msgh_id == MACH_NOTIFY_NO_SENDERS) { + int32_t *server_died = k5_getspecific (K5_KEY_IPC_SERVER_DIED); + if (!server_died) { + *server_died = 1; + } + + handled = 1; /* server died */ + } + + if (!handled) { + handled = k5_ipc_reply_server (request, reply); + } + + return handled; +} + +/* ------------------------------------------------------------------------ */ + +kern_return_t k5_ipc_client_reply (mach_port_t in_reply_port, + k5_ipc_inl_reply_t in_inl_reply, + mach_msg_type_number_t in_inl_replyCnt, + k5_ipc_ool_reply_t in_ool_reply, + mach_msg_type_number_t in_ool_replyCnt) +{ + kern_return_t err = KERN_SUCCESS; + k5_ipc_stream reply_stream = NULL; + + if (!err) { + err = CALL_INIT_FUNCTION (k5_cli_ipc_thread_init); + } + + if (!err) { + reply_stream = k5_getspecific (K5_KEY_IPC_REPLY_STREAM); + if (!reply_stream) { err = EINVAL; } + } + + if (!err) { + if (in_inl_replyCnt) { + err = k5_ipc_stream_write (reply_stream, in_inl_reply, in_inl_replyCnt); + + } else if (in_ool_replyCnt) { + err = k5_ipc_stream_write (reply_stream, in_ool_reply, in_ool_replyCnt); + + } else { + err = EINVAL; + } + } + + if (in_ool_replyCnt) { vm_deallocate (mach_task_self (), (vm_address_t) in_ool_reply, in_ool_replyCnt); } + + return err; +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +int32_t k5_ipc_send_request (int32_t in_launch_server, + k5_ipc_stream in_request_stream, + k5_ipc_stream *out_reply_stream) +{ + int err = 0; + int32_t done = 0; + int32_t try_count = 0; + int32_t server_died = 0; + mach_port_t server_port = MACH_PORT_NULL; + mach_port_t *request_port = NULL; + mach_port_t reply_port = MACH_PORT_NULL; + const char *inl_request = NULL; /* char * so we can pass the buffer in directly */ + mach_msg_type_number_t inl_request_length = 0; + k5_ipc_ool_request_t ool_request = NULL; + mach_msg_type_number_t ool_request_length = 0; + k5_ipc_stream reply_stream = NULL; + + if (!in_request_stream) { err = EINVAL; } + if (!out_reply_stream ) { err = EINVAL; } + + if (!err) { + err = CALL_INIT_FUNCTION (k5_cli_ipc_thread_init); + } + + if (!err) { + /* depending on how big the message is, use the fast inline buffer or + * the slow dynamically allocated buffer */ + mach_msg_type_number_t request_length = k5_ipc_stream_size (in_request_stream); + + if (request_length > K5_IPC_MAX_MSG_SIZE) { + //dprintf ("%s choosing out of line buffer (size is %d)", + // __FUNCTION__, request_length); + + err = vm_read (mach_task_self (), + (vm_address_t) k5_ipc_stream_data (in_request_stream), request_length, + (vm_address_t *) &ool_request, &ool_request_length); + } else { + //dprintf ("%s choosing in line buffer (size is %d)", + // __FUNCTION__, request_length); + + inl_request_length = request_length; + inl_request = k5_ipc_stream_data (in_request_stream); + } + } + + if (!err) { + request_port = k5_getspecific (K5_KEY_IPC_REQUEST_PORT); + + if (!request_port) { + request_port = malloc (sizeof (mach_port_t)); + if (!request_port) { err = ENOMEM; } + + if (!err) { + *request_port = MACH_PORT_NULL; + err = k5_setspecific (K5_KEY_IPC_REQUEST_PORT, request_port); + } + } + } + + if (!err) { + err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &reply_port); + } + + if (!err) { + err = kipc_client_lookup_server (K5_IPC_SERVER_ID, + in_launch_server, TRUE, &server_port); + } + + while (!err && !done) { + if (!err && !MACH_PORT_VALID (*request_port)) { + err = k5_ipc_client_create_client_connection (server_port, request_port); + } + + if (!err) { + err = k5_ipc_client_request (*request_port, reply_port, + inl_request, inl_request_length, + ool_request, ool_request_length); + + } + + if (err == MACH_SEND_INVALID_DEST) { + if (try_count < 2) { + try_count++; + err = 0; + } + + if (request_port && MACH_PORT_VALID (*request_port)) { + mach_port_mod_refs (mach_task_self(), *request_port, MACH_PORT_RIGHT_SEND, -1 ); + *request_port = MACH_PORT_NULL; + } + + /* Look up server name again without using the cached copy */ + err = kipc_client_lookup_server (K5_IPC_SERVER_ID, + in_launch_server, FALSE, &server_port); + + } else { + /* Talked to server, though we may have gotten an error */ + done = 1; + + /* Because we use ",dealloc" ool_request will be freed by mach. + * Don't double free it. */ + ool_request = NULL; + ool_request_length = 0; + } + } + + if (!err) { + err = k5_ipc_stream_new (&reply_stream); + } + + if (!err) { + err = k5_setspecific (K5_KEY_IPC_REPLY_STREAM, reply_stream); + } + + if (!err) { + err = k5_setspecific (K5_KEY_IPC_SERVER_DIED, &server_died); + } + + if (!err) { + mach_port_t old_notification_target = MACH_PORT_NULL; + + /* request no-senders notification so we can get a message when server dies */ + err = mach_port_request_notification (mach_task_self (), reply_port, + MACH_NOTIFY_NO_SENDERS, 1, reply_port, + MACH_MSG_TYPE_MAKE_SEND_ONCE, + &old_notification_target); + + if (!err && old_notification_target != MACH_PORT_NULL) { + mach_port_deallocate (mach_task_self (), old_notification_target); + } + } + + if (!err) { + err = mach_msg_server_once (k5_ipc_reply_demux, kkipc_max_message_size, + reply_port, MACH_MSG_TIMEOUT_NONE); + } + + if (!err && server_died) { + err = ENOTCONN; + } + + if (err == BOOTSTRAP_UNKNOWN_SERVICE && !in_launch_server) { + err = 0; /* If the server is not running just return an empty stream. */ + } + + if (!err) { + *out_reply_stream = reply_stream; + reply_stream = NULL; + } + + k5_setspecific (K5_KEY_IPC_REPLY_STREAM, NULL); + k5_setspecific (K5_KEY_IPC_SERVER_DIED, NULL); + if (reply_port != MACH_PORT_NULL) { mach_port_destroy (mach_task_self (), reply_port); } + if (ool_request_length ) { vm_deallocate (mach_task_self (), (vm_address_t) ool_request, ool_request_length); } + if (reply_stream ) { k5_ipc_stream_release (reply_stream); } + + return err; +} diff --git a/src/kim/mac/kim_mig_types.h b/src/util/mac/k5_mig_client.h index 189fe06ebf..b5eefdc3af 100644 --- a/src/kim/mac/kim_mig_types.h +++ b/src/util/mac/k5_mig_client.h @@ -1,14 +1,14 @@ /* * $Header$ * - * Copyright 2006-2008 Massachusetts Institute of Technology. + * Copyright 2006 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 @@ -24,17 +24,13 @@ * or implied warranty. */ -#ifndef KIM_MIG_H -#define KIM_MIG_H +#ifndef K5_MIG_CLIENT_H +#define K5_MIG_CLIENT_H -#include <kim/kim.h> +#include "k5-ipc_stream.h" -typedef const char *kim_mipc_in_string; -typedef char *kim_mipc_out_string; -typedef int32_t kim_mipc_error; -typedef boolean_t kim_mipc_boolean; -typedef uint32_t kim_mipc_lifetime; -typedef uint32_t kim_mipc_time; -typedef uint32_t kim_mipc_prompt_type; +int32_t k5_ipc_send_request (int32_t in_launch_server, + k5_ipc_stream in_request_stream, + k5_ipc_stream *out_reply_stream); -#endif /* KIM_MIG_H */ +#endif /* K5_MIG_CLIENT_H */ diff --git a/src/util/mac/k5_mig_reply.defs b/src/util/mac/k5_mig_reply.defs new file mode 100644 index 0000000000..301778e15a --- /dev/null +++ b/src/util/mac/k5_mig_reply.defs @@ -0,0 +1,58 @@ +/* $Copyright: + * + * Copyright 2004-2006 by the 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 MIT 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Individual source code files are copyright MIT, Cygnus Support, + * OpenVision, Oracle, Sun Soft, FundsXpress, and others. + * + * Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira, + * and Zephyr are trademarks of the Massachusetts Institute of Technology + * (MIT). No commercial use of these trademarks may be made without prior + * written permission of MIT. + * + * "Commercial use" means use of a name in a product or other for-profit + * manner. It does NOT prevent a commercial firm from referring to the MIT + * trademarks in order to convey information (although in doing so, + * recognition of their trademark status should be given). + * $ + */ + +#include "k5_mig.defs" + +subsystem k5_ipc_reply 200; + +serverprefix k5_ipc_client_; +userprefix k5_ipc_server_; + +/* ",dealloc" means that the vm_read() memory will be moved to + * the other process rather than copied. This is necessary on the + * client side because we can't know when server has copied our + * buffers so we can't vm_deallocate() them ourselves. */ + +simpleroutine reply (in_reply_port : mach_port_move_send_once_t; + in_inl_reply : k5_ipc_inl_reply_t; + in_ool_reply : k5_ipc_ool_reply_t, dealloc); diff --git a/src/util/mac/k5_mig_request.defs b/src/util/mac/k5_mig_request.defs new file mode 100644 index 0000000000..bbb23f0e3e --- /dev/null +++ b/src/util/mac/k5_mig_request.defs @@ -0,0 +1,62 @@ +/* $Copyright: + * + * Copyright 2004-2006 by the 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 MIT 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Individual source code files are copyright MIT, Cygnus Support, + * OpenVision, Oracle, Sun Soft, FundsXpress, and others. + * + * Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira, + * and Zephyr are trademarks of the Massachusetts Institute of Technology + * (MIT). No commercial use of these trademarks may be made without prior + * written permission of MIT. + * + * "Commercial use" means use of a name in a product or other for-profit + * manner. It does NOT prevent a commercial firm from referring to the MIT + * trademarks in order to convey information (although in doing so, + * recognition of their trademark status should be given). + * $ + */ + +#include "k5_mig.defs" + +subsystem k5_ipc_request 100; + +serverprefix k5_ipc_server_; +userprefix k5_ipc_client_; + +routine create_client_connection (in_server_port : mach_port_t; + out out_connection_port : mach_port_t = MACH_MSG_TYPE_MAKE_SEND); + +/* ",dealloc" means that the vm_read() memory will be moved to + * the other process rather than copied. This is necessary on the + * server side because we can't know when client has copied our + * buffers so we can't vm_deallocate() them ourselves. */ + +simpleroutine request (in_connection_port : mach_port_t; + in_reply_port : mach_port_make_send_once_t; + in_inl_request : k5_ipc_inl_request_t; + in_ool_request : k5_ipc_ool_request_t, dealloc); diff --git a/src/util/mac/k5_mig_server.c b/src/util/mac/k5_mig_server.c new file mode 100644 index 0000000000..ddf81ce0b6 --- /dev/null +++ b/src/util/mac/k5_mig_server.c @@ -0,0 +1,233 @@ +/* + * $Header$ + * + * Copyright 2006 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 "k5_mig_server.h" + +#include <syslog.h> +#include <Kerberos/kipc_server.h> +#include "k5_mig_requestServer.h" +#include "k5_mig_reply.h" + + +/* ------------------------------------------------------------------------ */ + +static boolean_t k5_ipc_request_demux (mach_msg_header_t *request, + mach_msg_header_t *reply) +{ + boolean_t handled = false; + + if (!handled) { + handled = k5_ipc_request_server (request, reply); + } + + if (!handled && request->msgh_id == MACH_NOTIFY_NO_SENDERS) { + kern_return_t err = KERN_SUCCESS; + + err = k5_ipc_server_remove_client (request->msgh_local_port); + + if (!err) { + /* Check here for a client in our table and free rights associated with it */ + err = mach_port_mod_refs (mach_task_self (), request->msgh_local_port, + MACH_PORT_RIGHT_RECEIVE, -1); + } + + if (!err) { + handled = 1; /* was a port we are tracking */ + } + } + + return handled; +} + +/* ------------------------------------------------------------------------ */ + +kern_return_t k5_ipc_server_create_client_connection (mach_port_t in_server_port, + mach_port_t *out_connection_port) +{ + kern_return_t err = KERN_SUCCESS; + mach_port_t connection_port = MACH_PORT_NULL; + mach_port_t old_notification_target = MACH_PORT_NULL; + + if (!err) { + err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &connection_port); + } + + if (!err) { + err = mach_port_move_member (mach_task_self (), connection_port, kipc_server_get_listen_portset ()); + } + + if (!err) { + /* request no-senders notification so we can tell when client quits/crashes */ + err = mach_port_request_notification (mach_task_self (), connection_port, + MACH_NOTIFY_NO_SENDERS, 1, connection_port, + MACH_MSG_TYPE_MAKE_SEND_ONCE, &old_notification_target ); + } + + if (!err) { + err = k5_ipc_server_add_client (connection_port); + } + + if (!err) { + *out_connection_port = connection_port; + connection_port = MACH_PORT_NULL; + } + + if (MACH_PORT_VALID (connection_port)) { mach_port_deallocate (mach_task_self (), connection_port); } + + return err; +} + +/* ------------------------------------------------------------------------ */ + +kern_return_t k5_ipc_server_request (mach_port_t in_connection_port, + mach_port_t in_reply_port, + k5_ipc_inl_request_t in_inl_request, + mach_msg_type_number_t in_inl_requestCnt, + k5_ipc_ool_request_t in_ool_request, + mach_msg_type_number_t in_ool_requestCnt) +{ + kern_return_t err = KERN_SUCCESS; + k5_ipc_stream request_stream = NULL; + + if (!err) { + err = k5_ipc_stream_new (&request_stream); + } + + if (!err) { + if (in_inl_requestCnt) { + err = k5_ipc_stream_write (request_stream, in_inl_request, in_inl_requestCnt); + + } else if (in_ool_requestCnt) { + err = k5_ipc_stream_write (request_stream, in_ool_request, in_ool_requestCnt); + + } else { + err = EINVAL; + } + } + + if (!err) { + err = k5_ipc_server_handle_request (in_connection_port, in_reply_port, request_stream); + } + + k5_ipc_stream_release (request_stream); + if (in_ool_requestCnt) { vm_deallocate (mach_task_self (), (vm_address_t) in_ool_request, in_ool_requestCnt); } + + return err; +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +int32_t k5_ipc_server_initialize (int argc, const char *argv[]) +{ + int32_t err = 0; + + openlog (argv[0], LOG_CONS | LOG_PID, LOG_AUTH); + syslog (LOG_INFO, "Starting up."); + + syslog (LOG_NOTICE, "Exiting: %s (%d)", kipc_error_string (err), err); + + return err; +} + +/* ------------------------------------------------------------------------ */ + +int32_t k5_ipc_server_cleanup (int argc, const char *argv[]) +{ + int32_t err = 0; + + openlog (argv[0], LOG_CONS | LOG_PID, LOG_AUTH); + syslog (LOG_INFO, "Starting up."); + + syslog (LOG_NOTICE, "Exiting: %s (%d)", kipc_error_string (err), err); + + return err; +} + +/* ------------------------------------------------------------------------ */ + +int32_t k5_ipc_server_listen_loop (void) +{ + /* Run the Mach IPC listen loop. + * This will call k5_ipc_server_create_client_connection for new clients + * and k5_ipc_server_request for existing clients */ + + return kipc_server_run_server (k5_ipc_request_demux); +} + +/* ------------------------------------------------------------------------ */ + +int32_t k5_ipc_server_send_reply (mach_port_t in_reply_port, + k5_ipc_stream in_reply_stream) +{ + kern_return_t err = KERN_SUCCESS; + k5_ipc_inl_reply_t inl_reply; + mach_msg_type_number_t inl_reply_length = 0; + k5_ipc_ool_reply_t ool_reply = NULL; + mach_msg_type_number_t ool_reply_length = 0; + + if (!MACH_PORT_VALID (in_reply_port)) { err = EINVAL; } + if (!in_reply_stream ) { err = EINVAL; } + + if (!err) { + /* depending on how big the message is, use the fast inline buffer or + * the slow dynamically allocated buffer */ + mach_msg_type_number_t reply_length = k5_ipc_stream_size (in_reply_stream); + + if (reply_length > K5_IPC_MAX_MSG_SIZE) { + //dprintf ("%s choosing out of line buffer (size is %d)", + // __FUNCTION__, reply_length); + + err = vm_read (mach_task_self (), + (vm_address_t) k5_ipc_stream_data (in_reply_stream), reply_length, + (vm_address_t *) &ool_reply, &ool_reply_length); + + } else { + //cci_debug_printf ("%s choosing in line buffer (size is %d)", + // __FUNCTION__, reply_length); + + inl_reply_length = reply_length; + memcpy (inl_reply, k5_ipc_stream_data (in_reply_stream), reply_length); + } + } + + if (!err) { + err = k5_ipc_server_reply (in_reply_port, + inl_reply, inl_reply_length, + ool_reply, ool_reply_length); + } + + if (!err) { + /* Because we use ",dealloc" ool_reply will be freed by mach. Don't double free it. */ + ool_reply = NULL; + ool_reply_length = 0; + } + + if (ool_reply_length) { vm_deallocate (mach_task_self (), (vm_address_t) ool_reply, ool_reply_length); } + + return err; +} diff --git a/src/util/mac/k5_mig_server.h b/src/util/mac/k5_mig_server.h new file mode 100644 index 0000000000..c98d1dc4b0 --- /dev/null +++ b/src/util/mac/k5_mig_server.h @@ -0,0 +1,53 @@ +/* + * $Header$ + * + * Copyright 2006 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. + */ + +#ifndef K5_MIG_SERVER +#define K5_MIG_SERVER + +#include "k5-ipc_stream.h" + +/* Defined by caller */ + +int32_t k5_ipc_server_add_client (mach_port_t in_client_port); + +int32_t k5_ipc_server_remove_client (mach_port_t in_client_port); + +int32_t k5_ipc_server_handle_request (mach_port_t in_connection_port, + mach_port_t in_reply_port, + k5_ipc_stream in_request_stream); + +/* Server control functions */ + +int32_t k5_ipc_server_initialize (int argc, const char *argv[]); + +int32_t k5_ipc_server_cleanup (int argc, const char *argv[]); + +int32_t k5_ipc_server_listen_loop (void); + +int32_t k5_ipc_server_send_reply (mach_port_t in_reply_pipe, + k5_ipc_stream in_reply_stream); + +#endif /* K5_MIG_SERVER */ diff --git a/src/util/mac/k5_mig_types.h b/src/util/mac/k5_mig_types.h new file mode 100644 index 0000000000..4c8ddb73b1 --- /dev/null +++ b/src/util/mac/k5_mig_types.h @@ -0,0 +1,55 @@ +/* $Copyright: +* +* Copyright 2004-2006 by the 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 MIT 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. +* +* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED +* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +* MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. +* +* Individual source code files are copyright MIT, Cygnus Support, +* OpenVision, Oracle, Sun Soft, FundsXpress, and others. +* +* Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira, +* and Zephyr are trademarks of the Massachusetts Institute of Technology +* (MIT). No commercial use of these trademarks may be made without prior +* written permission of MIT. +* +* "Commercial use" means use of a name in a product or other for-profit +* manner. It does NOT prevent a commercial firm from referring to the MIT +* trademarks in order to convey information (although in doing so, +* recognition of their trademark status should be given). +* $ +*/ + +#ifndef K5_MIG_TYPES_H +#define K5_MIG_TYPES_H + + +#define K5_IPC_MAX_MSG_SIZE 1024 + +typedef const char k5_ipc_inl_request_t[K5_IPC_MAX_MSG_SIZE]; +typedef const char *k5_ipc_ool_request_t; +typedef char k5_ipc_inl_reply_t[K5_IPC_MAX_MSG_SIZE]; +typedef char *k5_ipc_ool_reply_t; + +#endif /* K5_MIG_TYPES_H */ diff --git a/src/util/support/ipc_stream.c b/src/util/support/ipc_stream.c new file mode 100644 index 0000000000..608e0fb37a --- /dev/null +++ b/src/util/support/ipc_stream.c @@ -0,0 +1,507 @@ +/* + * $Header$ + * + * Copyright 2006, 2007 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 "k5-ipc_stream.h" + +#if !defined(htonll) +#define htonll(x) k5_htonll(x) +#endif + +#if !defined(ntohll) +#define ntohll(x) k5_ntohll(x) +#endif + +/* Add debugging later */ +#define k5_check_error(x) (x) + +struct k5_ipc_stream { + char *data; + uint64_t size; + uint64_t max_size; +}; + +const struct k5_ipc_stream k5_ipc_stream_initializer = { NULL, 0, 0 }; + +#define K5_IPC_STREAM_SIZE_INCREMENT 128 + +/* ------------------------------------------------------------------------ */ + +static uint32_t k5_ipc_stream_reallocate (k5_ipc_stream io_stream, + uint64_t in_new_size) +{ + int32_t err = 0; + uint64_t new_max_size = 0; + + if (!io_stream) { err = k5_check_error (EINVAL); } + + if (!err) { + uint64_t old_max_size = io_stream->max_size; + new_max_size = io_stream->max_size; + + if (in_new_size > old_max_size) { + /* Expand the stream */ + while (in_new_size > new_max_size) { + new_max_size += K5_IPC_STREAM_SIZE_INCREMENT; + } + + + } else if ((in_new_size + K5_IPC_STREAM_SIZE_INCREMENT) < old_max_size) { + /* Shrink the array, but never drop below K5_IPC_STREAM_SIZE_INCREMENT */ + while ((in_new_size + K5_IPC_STREAM_SIZE_INCREMENT) < new_max_size && + (new_max_size > K5_IPC_STREAM_SIZE_INCREMENT)) { + new_max_size -= K5_IPC_STREAM_SIZE_INCREMENT; + } + } + } + + if (!err && new_max_size != io_stream->max_size) { + char *data = io_stream->data; + + if (!data) { + data = malloc (new_max_size * sizeof (*data)); + } else { + data = realloc (data, new_max_size * sizeof (*data)); + } + + if (data) { + io_stream->data = data; + io_stream->max_size = new_max_size; + } else { + err = k5_check_error (ENOMEM); + } + } + + return k5_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +int32_t k5_ipc_stream_new (k5_ipc_stream *out_stream) +{ + int32_t err = 0; + k5_ipc_stream stream = NULL; + + if (!out_stream) { err = k5_check_error (EINVAL); } + + if (!err) { + stream = malloc (sizeof (*stream)); + if (stream) { + *stream = k5_ipc_stream_initializer; + } else { + err = k5_check_error (ENOMEM); + } + } + + if (!err) { + *out_stream = stream; + stream = NULL; + } + + k5_ipc_stream_release (stream); + + return k5_check_error (err); +} + + +/* ------------------------------------------------------------------------ */ + +uint32_t k5_ipc_stream_release (k5_ipc_stream io_stream) +{ + int32_t err = 0; + + if (!err && io_stream) { + free (io_stream->data); + free (io_stream); + } + + return err; +} + +/* ------------------------------------------------------------------------ */ + +uint64_t k5_ipc_stream_size (k5_ipc_stream in_stream) +{ + return in_stream ? in_stream->size : 0; +} + + +/* ------------------------------------------------------------------------ */ + +const char *k5_ipc_stream_data (k5_ipc_stream in_stream) +{ + return in_stream ? in_stream->data : NULL; +} + +#ifdef TARGET_OS_MAC +#pragma mark - +#endif + +/* ------------------------------------------------------------------------ */ + +uint32_t k5_ipc_stream_read (k5_ipc_stream io_stream, + void *io_data, + uint64_t in_size) +{ + int32_t err = 0; + + if (!io_stream) { err = k5_check_error (EINVAL); } + if (!io_data ) { err = k5_check_error (EINVAL); } + + if (!err) { + if (in_size > io_stream->size) { + err = k5_check_error (EINVAL); + } + } + + if (!err) { + memcpy (io_data, io_stream->data, in_size); + memmove (io_stream->data, &io_stream->data[in_size], + io_stream->size - in_size); + + err = k5_ipc_stream_reallocate (io_stream, io_stream->size - in_size); + + if (!err) { + io_stream->size -= in_size; + } + } + + return k5_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +uint32_t k5_ipc_stream_write (k5_ipc_stream io_stream, + const void *in_data, + uint64_t in_size) +{ + int32_t err = 0; + + if (!io_stream) { err = k5_check_error (EINVAL); } + if (!in_data ) { err = k5_check_error (EINVAL); } + + if (!err) { + /* Security check: Do not let the caller overflow the length */ + if (in_size > (UINT64_MAX - io_stream->size)) { + err = k5_check_error (EINVAL); + } + } + + if (!err) { + err = k5_ipc_stream_reallocate (io_stream, io_stream->size + in_size); + } + + if (!err) { + memcpy (&io_stream->data[io_stream->size], in_data, in_size); + io_stream->size += in_size; + } + + return k5_check_error (err); +} + +#ifdef TARGET_OS_MAC +#pragma mark - +#endif + +/* ------------------------------------------------------------------------ */ + +void k5_ipc_stream_free_string (char *in_string) +{ + free (in_string); +} + +/* ------------------------------------------------------------------------ */ + +uint32_t k5_ipc_stream_read_string (k5_ipc_stream io_stream, + char **out_string) +{ + int32_t err = 0; + uint32_t length = 0; + char *string = NULL; + + if (!io_stream ) { err = k5_check_error (EINVAL); } + if (!out_string) { err = k5_check_error (EINVAL); } + + if (!err) { + err = k5_ipc_stream_read_uint32 (io_stream, &length); + } + + if (!err) { + string = malloc (length); + if (!string) { err = k5_check_error (ENOMEM); } + } + + if (!err) { + err = k5_ipc_stream_read (io_stream, string, length); + } + + if (!err) { + *out_string = string; + string = NULL; + } + + free (string); + + return k5_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +uint32_t k5_ipc_stream_write_string (k5_ipc_stream io_stream, + const char *in_string) +{ + int32_t err = 0; + uint32_t length = 0; + + if (!io_stream) { err = k5_check_error (EINVAL); } + if (!in_string) { err = k5_check_error (EINVAL); } + + if (!err) { + length = strlen (in_string) + 1; + + err = k5_ipc_stream_write_uint32 (io_stream, length); + } + + if (!err) { + err = k5_ipc_stream_write (io_stream, in_string, length); + } + + return k5_check_error (err); +} + +#ifdef TARGET_OS_MAC +#pragma mark - +#endif + +/* ------------------------------------------------------------------------ */ + +uint32_t k5_ipc_stream_read_int32 (k5_ipc_stream io_stream, + int32_t *out_int32) +{ + int32_t err = 0; + int32_t int32 = 0; + + if (!io_stream) { err = k5_check_error (EINVAL); } + if (!out_int32) { err = k5_check_error (EINVAL); } + + if (!err) { + err = k5_ipc_stream_read (io_stream, &int32, sizeof (int32)); + } + + if (!err) { + *out_int32 = ntohl (int32); + } + + return k5_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +uint32_t k5_ipc_stream_write_int32 (k5_ipc_stream io_stream, + int32_t in_int32) +{ + int32_t err = 0; + int32_t int32 = htonl (in_int32); + + if (!io_stream) { err = k5_check_error (EINVAL); } + + if (!err) { + err = k5_ipc_stream_write (io_stream, &int32, sizeof (int32)); + } + + return k5_check_error (err); +} + +#ifdef TARGET_OS_MAC +#pragma mark - +#endif + +/* ------------------------------------------------------------------------ */ + +uint32_t k5_ipc_stream_read_uint32 (k5_ipc_stream io_stream, + uint32_t *out_uint32) +{ + int32_t err = 0; + uint32_t uint32 = 0; + + if (!io_stream) { err = k5_check_error (EINVAL); } + if (!out_uint32) { err = k5_check_error (EINVAL); } + + if (!err) { + err = k5_ipc_stream_read (io_stream, &uint32, sizeof (uint32)); + } + + if (!err) { + *out_uint32 = ntohl (uint32); + } + + return k5_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +uint32_t k5_ipc_stream_write_uint32 (k5_ipc_stream io_stream, + uint32_t in_uint32) +{ + int32_t err = 0; + int32_t uint32 = htonl (in_uint32); + + if (!io_stream) { err = k5_check_error (EINVAL); } + + if (!err) { + err = k5_ipc_stream_write (io_stream, &uint32, sizeof (uint32)); + } + + return k5_check_error (err); +} + +#ifdef TARGET_OS_MAC +#pragma mark - +#endif + +/* ------------------------------------------------------------------------ */ + +uint32_t k5_ipc_stream_read_int64 (k5_ipc_stream io_stream, + int64_t *out_int64) +{ + int32_t err = 0; + uint64_t int64 = 0; + + if (!io_stream) { err = k5_check_error (EINVAL); } + if (!out_int64) { err = k5_check_error (EINVAL); } + + if (!err) { + err = k5_ipc_stream_read (io_stream, &int64, sizeof (int64)); + } + + if (!err) { + *out_int64 = ntohll (int64); + } + + return k5_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +uint32_t k5_ipc_stream_write_int64 (k5_ipc_stream io_stream, + int64_t in_int64) +{ + int32_t err = 0; + int64_t int64 = htonll (in_int64); + + if (!io_stream) { err = k5_check_error (EINVAL); } + + if (!err) { + err = k5_ipc_stream_write (io_stream, &int64, sizeof (int64)); + } + + return k5_check_error (err); +} + + +#ifdef TARGET_OS_MAC +#pragma mark - +#endif + +/* ------------------------------------------------------------------------ */ + +uint32_t k5_ipc_stream_read_uint64 (k5_ipc_stream io_stream, + uint64_t *out_uint64) +{ + int32_t err = 0; + uint64_t uint64 = 0; + + if (!io_stream) { err = k5_check_error (EINVAL); } + if (!out_uint64) { err = k5_check_error (EINVAL); } + + if (!err) { + err = k5_ipc_stream_read (io_stream, &uint64, sizeof (uint64)); + } + + if (!err) { + *out_uint64 = ntohll (uint64); + } + + return k5_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +uint32_t k5_ipc_stream_write_uint64 (k5_ipc_stream io_stream, + uint64_t in_uint64) +{ + int32_t err = 0; + int64_t uint64 = htonll (in_uint64); + + if (!io_stream) { err = k5_check_error (EINVAL); } + + if (!err) { + err = k5_ipc_stream_write (io_stream, &uint64, sizeof (uint64)); + } + + return k5_check_error (err); +} + +#ifdef TARGET_OS_MAC +#pragma mark - +#endif + +/* ------------------------------------------------------------------------ */ + +uint32_t k5_ipc_stream_read_time (k5_ipc_stream io_stream, + time_t *out_time) +{ + int32_t err = 0; + int64_t t = 0; + + if (!io_stream) { err = k5_check_error (EINVAL); } + if (!out_time ) { err = k5_check_error (EINVAL); } + + if (!err) { + err = k5_ipc_stream_read_int64 (io_stream, &t); + } + + if (!err) { + *out_time = t; + } + + return k5_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +uint32_t k5_ipc_stream_write_time (k5_ipc_stream io_stream, + time_t in_time) +{ + int32_t err = 0; + + if (!io_stream) { err = k5_check_error (EINVAL); } + + if (!err) { + err = k5_ipc_stream_write_int64 (io_stream, in_time); + } + + return k5_check_error (err); +} |
