--- /dev/null
+/*
+ * $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 */
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
kim_prompt_type_password = 0,
kim_prompt_type_preauth = 1
};
-
+
/*
* Plugins for Controlling Identity Selection and Credential Acquisition
*
--- /dev/null
+/*
+ * 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);
* 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) {
}
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 ();
+}
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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
-
#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;
}
#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);
}
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);
}
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);
}
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);
}
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); }
}
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);
}
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);
}
+++ /dev/null
-/*
- * $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);
-
-
--- /dev/null
+/* $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;
--- /dev/null
+/*
+ * $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;
+}
/*
* $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
* 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 */
--- /dev/null
+/* $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);
--- /dev/null
+/* $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);
--- /dev/null
+/*
+ * $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;
+}
--- /dev/null
+/*
+ * $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 */
--- /dev/null
+/* $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 */
--- /dev/null
+/*
+ * $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);
+}