summaryrefslogtreecommitdiffstats
path: root/src/kim/agent/mac/ServerDemux.m
diff options
context:
space:
mode:
authorAlexandra Ellwood <lxs@mit.edu>2008-09-27 00:46:39 +0000
committerAlexandra Ellwood <lxs@mit.edu>2008-09-27 00:46:39 +0000
commit06847c646f5630878d6f28025993cee57f2839a8 (patch)
treec853a823d1cdc5b7bd7cf0bacac3e2aaff3d275d /src/kim/agent/mac/ServerDemux.m
parentf0098982775d44d490bae733f386a5432e712a8e (diff)
downloadkrb5-06847c646f5630878d6f28025993cee57f2839a8.tar.gz
krb5-06847c646f5630878d6f28025993cee57f2839a8.tar.xz
krb5-06847c646f5630878d6f28025993cee57f2839a8.zip
KerberosAgent MachIPC support
ticket: 6055 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@20763 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/kim/agent/mac/ServerDemux.m')
-rw-r--r--src/kim/agent/mac/ServerDemux.m618
1 files changed, 618 insertions, 0 deletions
diff --git a/src/kim/agent/mac/ServerDemux.m b/src/kim/agent/mac/ServerDemux.m
new file mode 100644
index 000000000..b7f208417
--- /dev/null
+++ b/src/kim/agent/mac/ServerDemux.m
@@ -0,0 +1,618 @@
+/*
+ * Copyright 2008 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#import "kim_migServer.h"
+#import "ServerThread.h"
+
+// ---------------------------------------------------------------------------
+
+static kim_boolean caller_is_front_process (task_t in_task,
+ NSString *in_path)
+{
+ kim_error err = KIM_NO_ERROR;
+ Boolean is_front_process;
+ pid_t task_pid;
+ ProcessSerialNumber task_psn, front_psn;
+
+ NSBundle *bundle = [NSBundle bundleWithPath: in_path];
+ if (bundle) {
+ NSString *identifier = [bundle bundleIdentifier];
+ if (identifier &&
+ ([identifier compare: @"edu.mit.Kerberos.KerberosMenu"] == NSOrderedSame ||
+ [identifier compare: @"com.apple.systemuiserver"] == NSOrderedSame)) {
+ return TRUE;
+ }
+ }
+
+ if (!err) {
+ err = pid_for_task (in_task, &task_pid);
+ }
+
+ if (!err) {
+ err = GetProcessForPID (task_pid, &task_psn);
+ }
+
+ if (!err) {
+ err = GetFrontProcess (&front_psn);
+ }
+
+ if (!err) {
+ err = SameProcess (&task_psn, &front_psn, &is_front_process);
+ }
+
+ return !err ? is_front_process : FALSE;
+}
+
+#pragma mark -
+
+/* ------------------------------------------------------------------------ */
+
+kern_return_t kim_mipc_srv_init (mach_port_t in_server_port,
+ task_t in_application_task,
+ kim_mipc_in_string in_application_name,
+ mach_msg_type_number_t in_application_nameCnt,
+ kim_mipc_in_string in_application_path,
+ mach_msg_type_number_t in_application_pathCnt,
+ kim_mipc_error *out_error)
+{
+ kern_return_t err = 0;
+ ServerThread *sthread = NULL;
+
+ if (!err) {
+ sthread = [ServerThread sharedServerThread];
+ if (!sthread) { err = KIM_OUT_OF_MEMORY_ERR; }
+ }
+
+ if (!err) {
+ kim_mipc_error result = KIM_NO_ERROR;
+ NSString *name = NULL;
+ NSString *path = NULL;
+
+ if (in_application_name) {
+ name = [NSString stringWithUTF8String: in_application_name];
+ }
+
+ if (in_application_path) {
+ path = [NSString stringWithUTF8String: in_application_path];
+ }
+
+ [sthread addConnectionWithPort: in_server_port
+ name: name
+ path: path
+ frontProcess: caller_is_front_process (in_application_task,
+ path)];
+ *out_error = result;
+ }
+
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+kern_return_t kim_mipc_srv_enter_identity (mach_port_t in_server_port,
+ kim_mipc_out_string *out_identity,
+ mach_msg_type_number_t *out_identityCnt,
+ kim_mipc_error *out_error)
+{
+ kern_return_t err = 0;
+ kim_error result = KIM_NO_ERROR;
+ ClientConnection *client = NULL;
+ kim_identity identity = NULL;
+ kim_string identity_string = NULL;
+ mach_msg_type_number_t identity_len = 0;
+ kim_mipc_out_string identity_buf = NULL;
+
+ if (!err) {
+ ServerThread *sthread = [ServerThread sharedServerThread];
+ if (!sthread) { err = KIM_OUT_OF_MEMORY_ERR; }
+
+ if (!err) {
+ client = [sthread connectionForPort: in_server_port];
+ if (!client) { err = KIM_OUT_OF_MEMORY_ERR; }
+ }
+ }
+
+ if (!err) {
+ identity = [client enterIdentityWithError: &result];
+ }
+
+ if (!err && !result) {
+ err = kim_identity_get_string (identity, &identity_string);
+ }
+
+ if (!err && !result && identity_string) {
+ identity_len = strlen (identity_string) + 1;
+ err = vm_allocate (mach_task_self (),
+ (vm_address_t *) &identity_buf, identity_len, TRUE);
+
+ }
+
+ if (!err && !result) {
+ memmove (identity_buf, identity_string, identity_len);
+ *out_identity = identity_buf;
+ *out_identityCnt = identity_len;
+ identity_buf = NULL;
+ }
+
+ if (!err) {
+ *out_error = result;
+ }
+
+ if (identity_buf) { vm_deallocate (mach_task_self (), (vm_address_t) identity_buf, identity_len); }
+ kim_string_free (&identity_string);
+ kim_identity_free (&identity);
+
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+kern_return_t kim_mipc_srv_select_identity (mach_port_t in_server_port,
+ kim_mipc_in_string in_application_id,
+ mach_msg_type_number_t in_application_idCnt,
+ kim_mipc_in_string in_explanation,
+ mach_msg_type_number_t in_explanationCnt,
+ kim_mipc_time in_start_time,
+ kim_mipc_lifetime in_lifetime,
+ kim_mipc_boolean in_renewable,
+ kim_mipc_lifetime in_renewal_lifetime,
+ kim_mipc_boolean in_forwardable,
+ kim_mipc_boolean in_proxiable,
+ kim_mipc_boolean in_addressless,
+ kim_mipc_in_string in_service_name,
+ mach_msg_type_number_t in_service_nameCnt,
+ kim_mipc_in_string in_service_identity_hint,
+ mach_msg_type_number_t in_service_identity_hintCnt,
+ kim_mipc_in_string in_client_realm_hint,
+ mach_msg_type_number_t in_client_realm_hintCnt,
+ kim_mipc_in_string in_user_hint,
+ mach_msg_type_number_t in_user_hintCnt,
+ kim_mipc_in_string in_service_realm_hint,
+ mach_msg_type_number_t in_service_realm_hintCnt,
+ kim_mipc_in_string in_service_hint,
+ mach_msg_type_number_t in_service_hintCnt,
+ kim_mipc_in_string in_server_hint,
+ mach_msg_type_number_t in_server_hintCnt,
+ kim_mipc_out_string *out_identity,
+ mach_msg_type_number_t *out_identityCnt,
+ kim_mipc_error *out_error)
+{
+ kern_return_t err = 0;
+ kim_error result = KIM_NO_ERROR;
+ ClientConnection *client = NULL;
+ kim_selection_hints hints = NULL;
+ kim_identity identity = NULL;
+ kim_string identity_string = NULL;
+ mach_msg_type_number_t identity_len = 0;
+ kim_mipc_out_string identity_buf = NULL;
+
+ if (!err) {
+ err = kim_selection_hints_create (&hints, in_application_id);
+ }
+
+ if (!err) {
+ kim_options options = NULL;
+
+ err = kim_options_create (&options);
+
+ if (!err) {
+ err = kim_options_set_start_time (options, in_start_time);
+ }
+
+ if (!err) {
+ err = kim_options_set_lifetime (options, in_lifetime);
+ }
+
+ if (!err) {
+ err = kim_options_set_renewable (options, in_renewable);
+ }
+
+ if (!err) {
+ err = kim_options_set_renewal_lifetime (options, in_renewal_lifetime);
+ }
+
+ if (!err) {
+ err = kim_options_set_forwardable (options, in_forwardable);
+ }
+
+ if (!err) {
+ err = kim_options_set_proxiable (options, in_proxiable);
+ }
+
+ if (!err) {
+ err = kim_options_set_addressless (options, in_addressless);
+ }
+
+ if (!err) {
+ err = kim_options_set_service_name (options, in_service_name);
+ }
+
+ if (!err) {
+ err = kim_selection_hints_set_options (hints, options);
+ }
+
+ kim_options_free (&options);
+ }
+
+ if (!err) {
+ err = kim_selection_hints_set_explanation (hints, in_explanation);
+ }
+
+ if (!err && in_service_identity_hint) {
+ err = kim_selection_hints_set_hint (hints,
+ kim_hint_key_service_identity,
+ in_service_identity_hint);
+ }
+
+ if (!err && in_client_realm_hint) {
+ err = kim_selection_hints_set_hint (hints,
+ kim_hint_key_client_realm,
+ in_client_realm_hint);
+ }
+
+ if (!err && in_user_hint) {
+ err = kim_selection_hints_set_hint (hints,
+ kim_hint_key_user,
+ in_user_hint);
+ }
+
+ if (!err && in_service_realm_hint) {
+ err = kim_selection_hints_set_hint (hints,
+ kim_hint_key_service_realm,
+ in_service_realm_hint);
+ }
+
+ if (!err && in_service_hint) {
+ err = kim_selection_hints_set_hint (hints,
+ kim_hint_key_service,
+ in_service_hint);
+ }
+
+ if (!err && in_server_hint) {
+ err = kim_selection_hints_set_hint (hints,
+ kim_hint_key_server,
+ in_server_hint);
+ }
+
+ if (!err) {
+ ServerThread *sthread = [ServerThread sharedServerThread];
+ if (!sthread) { err = KIM_OUT_OF_MEMORY_ERR; }
+
+ if (!err) {
+ client = [sthread connectionForPort: in_server_port];
+ if (!client) { err = KIM_OUT_OF_MEMORY_ERR; }
+ }
+ }
+
+ if (!err) {
+ identity = [client selectIdentityWithHints: hints
+ error: &result];
+ }
+
+ if (!err && !result) {
+ err = kim_identity_get_string (identity, &identity_string);
+ }
+
+ if (!err && !result && identity_string) {
+ identity_len = strlen (identity_string) + 1;
+ err = vm_allocate (mach_task_self (),
+ (vm_address_t *) &identity_buf, identity_len, TRUE);
+ }
+
+ if (!err && !result) {
+ memmove (identity_buf, identity_string, identity_len);
+ *out_identity = identity_buf;
+ *out_identityCnt = identity_len;
+ identity_buf = NULL;
+ }
+
+ if (!err) {
+ *out_error = result;
+ }
+
+ if (identity_buf) { vm_deallocate (mach_task_self (),
+ (vm_address_t) identity_buf,
+ identity_len); }
+ kim_string_free (&identity_string);
+ kim_identity_free (&identity);
+ kim_selection_hints_free (&hints);
+
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+kern_return_t kim_mipc_srv_auth_prompt (mach_port_t in_server_port,
+ kim_mipc_in_string in_identity,
+ mach_msg_type_number_t in_identityCnt,
+ kim_mipc_prompt_type in_prompt_type,
+ kim_mipc_boolean in_hide_reply,
+ kim_mipc_in_string in_title,
+ mach_msg_type_number_t in_titleCnt,
+ kim_mipc_in_string in_message,
+ mach_msg_type_number_t in_messageCnt,
+ kim_mipc_in_string in_description,
+ mach_msg_type_number_t in_descriptionCnt,
+ kim_mipc_out_string *out_response,
+ mach_msg_type_number_t *out_responseCnt,
+ kim_mipc_error *out_error)
+{
+ kern_return_t err = 0;
+ kim_error result = KIM_NO_ERROR;
+ ClientConnection *client = NULL;
+ kim_identity identity = NULL;
+ const char *response_string = NULL;
+ mach_msg_type_number_t response_len = 0;
+ kim_mipc_out_string response_buf = NULL;
+
+ if (!err) {
+ ServerThread *sthread = [ServerThread sharedServerThread];
+ if (!sthread) { err = KIM_OUT_OF_MEMORY_ERR; }
+
+ if (!err) {
+ client = [sthread connectionForPort: in_server_port];
+ if (!client) { err = KIM_OUT_OF_MEMORY_ERR; }
+ }
+ }
+
+ if (!err) {
+ err = kim_identity_create_from_string (&identity, in_identity);
+ }
+
+ if (!err) {
+ NSString *title = NULL;
+ NSString *message = NULL;
+ NSString *description = NULL;
+
+ if (in_title) {
+ title = [NSString stringWithUTF8String: in_title];
+ }
+
+ if (in_message) {
+ message = [NSString stringWithUTF8String: in_message];
+ }
+
+ if (in_description) {
+ description = [NSString stringWithUTF8String: in_description];
+ }
+
+ response_string = [[client authPromptWithIdentity: identity
+ type: in_prompt_type
+ hideReply: in_hide_reply
+ title: title
+ message: message
+ description: description
+ error: &result] UTF8String];
+ }
+
+ if (!err && !result && response_string) {
+ response_len = strlen (response_string) + 1;
+ err = vm_allocate (mach_task_self (),
+ (vm_address_t *) &response_buf, response_len, TRUE);
+
+ }
+
+ if (!err && !result) {
+ memmove (response_buf, response_string, response_len);
+ *out_response = response_buf;
+ *out_responseCnt = response_len;
+ response_buf = NULL;
+ }
+
+ if (!err) {
+ *out_error = result;
+ }
+
+ if (response_buf) { vm_deallocate (mach_task_self (),
+ (vm_address_t) response_buf,
+ response_len); }
+ kim_identity_free (&identity);
+
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+kern_return_t kim_mipc_srv_change_password (mach_port_t in_server_port,
+ kim_mipc_in_string in_identity,
+ mach_msg_type_number_t in_identityCnt,
+ kim_mipc_boolean in_old_password_expired,
+ kim_mipc_out_string *out_old_password,
+ mach_msg_type_number_t *out_old_passwordCnt,
+ kim_mipc_out_string *out_new_password,
+ mach_msg_type_number_t *out_new_passwordCnt,
+ kim_mipc_out_string *out_vfy_password,
+ mach_msg_type_number_t *out_vfy_passwordCnt,
+ kim_mipc_error *out_error)
+{
+ kern_return_t err = 0;
+ kim_error result = KIM_NO_ERROR;
+ ClientConnection *client = NULL;
+ kim_identity identity = NULL;
+ NSArray *passwords = NULL;
+ const char *old_password_string = NULL;
+ const char *new_password_string = NULL;
+ const char *vfy_password_string = NULL;
+ mach_msg_type_number_t old_password_len = 0;
+ mach_msg_type_number_t new_password_len = 0;
+ mach_msg_type_number_t vfy_password_len = 0;
+ kim_mipc_out_string old_password_buf = NULL;
+ kim_mipc_out_string new_password_buf = NULL;
+ kim_mipc_out_string vfy_password_buf = NULL;
+
+ if (!err) {
+ ServerThread *sthread = [ServerThread sharedServerThread];
+ if (!sthread) { err = KIM_OUT_OF_MEMORY_ERR; }
+
+ if (!err) {
+ client = [sthread connectionForPort: in_server_port];
+ if (!client) { err = KIM_OUT_OF_MEMORY_ERR; }
+ }
+ }
+
+ if (!err) {
+ err = kim_identity_create_from_string (&identity, in_identity);
+ }
+
+ if (!err) {
+ passwords = [client changePasswordWithIdentity: identity
+ oldPasswordIsExpired: in_old_password_expired
+ error: &result];
+ }
+
+ if (!err && !result) {
+ if (passwords && [passwords count] == 3) {
+ old_password_string = [[passwords objectAtIndex: 1] UTF8String];
+ new_password_string = [[passwords objectAtIndex: 2] UTF8String];
+ vfy_password_string = [[passwords objectAtIndex: 3] UTF8String];
+ } else {
+ err = KIM_OUT_OF_MEMORY_ERR;
+ }
+ }
+
+ if (!err && !result && old_password_string) {
+ old_password_len = strlen (old_password_string) + 1;
+ err = vm_allocate (mach_task_self (), (vm_address_t *) &old_password_buf, old_password_len, TRUE);
+
+ }
+
+ if (!err && !result && new_password_string) {
+ new_password_len = strlen (new_password_string) + 1;
+ err = vm_allocate (mach_task_self (), (vm_address_t *) &new_password_buf, new_password_len, TRUE);
+
+ }
+
+ if (!err && !result && vfy_password_string) {
+ vfy_password_len = strlen (vfy_password_string) + 1;
+ err = vm_allocate (mach_task_self (), (vm_address_t *) &vfy_password_buf, vfy_password_len, TRUE);
+ }
+
+ if (!err && !result) {
+ memmove (old_password_buf, old_password_string, old_password_len);
+ memmove (new_password_buf, new_password_string, new_password_len);
+ memmove (vfy_password_buf, vfy_password_string, vfy_password_len);
+ *out_old_password = old_password_buf;
+ *out_new_password = new_password_buf;
+ *out_vfy_password = vfy_password_buf;
+ *out_old_passwordCnt = old_password_len;
+ *out_new_passwordCnt = new_password_len;
+ *out_vfy_passwordCnt = vfy_password_len;
+ old_password_buf = NULL;
+ new_password_buf = NULL;
+ vfy_password_buf = NULL;
+ }
+
+ if (!err) {
+ *out_error = result;
+ }
+
+ if (old_password_buf) { vm_deallocate (mach_task_self (), (vm_address_t) old_password_buf, old_password_len); }
+ if (new_password_buf) { vm_deallocate (mach_task_self (), (vm_address_t) new_password_buf, new_password_len); }
+ if (vfy_password_buf) { vm_deallocate (mach_task_self (), (vm_address_t) vfy_password_buf, vfy_password_len); }
+ kim_identity_free (&identity);
+
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+kern_return_t kim_mipc_srv_handle_error (mach_port_t in_server_port,
+ kim_mipc_in_string in_identity,
+ mach_msg_type_number_t in_identityCnt,
+ kim_mipc_error in_error,
+ kim_mipc_in_string in_message,
+ mach_msg_type_number_t in_messageCnt,
+ kim_mipc_in_string in_description,
+ mach_msg_type_number_t in_descriptionCnt,
+ kim_mipc_error *out_error)
+{
+ kern_return_t err = 0;
+ kim_error result = KIM_NO_ERROR;
+ ClientConnection *client = NULL;
+ kim_identity identity = NULL;
+
+ if (!err) {
+ ServerThread *sthread = [ServerThread sharedServerThread];
+ if (!sthread) { err = KIM_OUT_OF_MEMORY_ERR; }
+
+ if (!err) {
+ client = [sthread connectionForPort: in_server_port];
+ if (!client) { err = KIM_OUT_OF_MEMORY_ERR; }
+ }
+ }
+
+ if (!err) {
+ err = kim_identity_create_from_string (&identity, in_identity);
+ }
+
+ if (!err) {
+ NSString *message = NULL;
+ NSString *description = NULL;
+
+ if (in_message) {
+ message = [NSString stringWithUTF8String: in_message];
+ }
+
+ if (in_description) {
+ description = [NSString stringWithUTF8String: in_description];
+ }
+
+ result = [client handleError: in_error
+ identity: identity
+ message: message
+ description: description];
+ }
+
+ if (!err) {
+ *out_error = result;
+ }
+
+ kim_identity_free (&identity);
+
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+kern_return_t kim_mipc_srv_fini (mach_port_t in_server_port,
+ kim_mipc_error *out_error)
+{
+ kern_return_t err = 0;
+ ServerThread *sthread = NULL;
+
+ if (!err) {
+ sthread = [ServerThread sharedServerThread];
+ if (!sthread) { err = KIM_OUT_OF_MEMORY_ERR; }
+ }
+
+ if (!err) {
+ [sthread removeConnectionWithPort: in_server_port];
+ }
+
+ if (!err) {
+ *out_error = KIM_NO_ERROR;
+ }
+
+ return err;
+}