diff options
author | Alexandra Ellwood <lxs@mit.edu> | 2006-06-09 22:01:11 +0000 |
---|---|---|
committer | Alexandra Ellwood <lxs@mit.edu> | 2006-06-09 22:01:11 +0000 |
commit | 6f294bfe674c557255eca075d2fa2f3064ce4ff5 (patch) | |
tree | 8781c38f0e73aa27716706f0b7f4ee0c90f5f372 | |
parent | 3b5e562ae1fca86bb7396ecb0eaf5a7d3a40acfd (diff) | |
download | krb5-6f294bfe674c557255eca075d2fa2f3064ce4ff5.zip krb5-6f294bfe674c557255eca075d2fa2f3064ce4ff5.tar.gz krb5-6f294bfe674c557255eca075d2fa2f3064ce4ff5.tar.bz2 |
Temporarily copied KerberosIPC libary from the KfM repository for
testing purposes. Note that this will be removed when the CCAPI
branch is merged onto the trunk.
git-svn-id: svn://anonsvn.mit.edu/krb5/branches/ccapi@18100 dc483132-0cff-0310-8789-dd5450dbe970
10 files changed, 908 insertions, 0 deletions
diff --git a/src/lib/ccapi/common/mac/KerberosIPC/Kerberos/kipc_client.h b/src/lib/ccapi/common/mac/KerberosIPC/Kerberos/kipc_client.h new file mode 100644 index 0000000..89923eb --- /dev/null +++ b/src/lib/ccapi/common/mac/KerberosIPC/Kerberos/kipc_client.h @@ -0,0 +1,47 @@ +/* + * kipc_client.h + * + * $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 KIPC_CLIENT_H +#define KIPC_CLIENT_H + +#include <Kerberos/kipc_common.h> + +#if __cplusplus +extern "C" { +#endif + +kipc_err_t +kipc_client_lookup_server (const char *in_service_id, + boolean_t in_launch_if_necessary, + mach_port_t *out_service_port); + +#if __cplusplus +} +#endif + +#endif /* KIPC_CLIENT_H */ diff --git a/src/lib/ccapi/common/mac/KerberosIPC/Kerberos/kipc_common.h b/src/lib/ccapi/common/mac/KerberosIPC/Kerberos/kipc_common.h new file mode 100644 index 0000000..361f7f5 --- /dev/null +++ b/src/lib/ccapi/common/mac/KerberosIPC/Kerberos/kipc_common.h @@ -0,0 +1,76 @@ +/* + * KerberosIPCCommon.h + * + * $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 KIPC_COMMON_H +#define KIPC_COMMON_H + +//#include <Kerberos/KerberosDebug.h> +#include <CoreFoundation/CoreFoundation.h> +#include <mach/mach.h> +#include <mach/boolean.h> +#include <mach/mach_error.h> +#include <mach/notify.h> +#include <servers/bootstrap.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/resource.h> +#include <sys/wait.h> +#include <sys/param.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> + + +#if __cplusplus +extern "C" { +#endif + +typedef kern_return_t kipc_err_t; +typedef boolean_t kipc_boolean_t; +typedef char *kipc_string; + +#define kkipc_max_message_size 2048 + MAX_TRAILER_SIZE +#define kkipc_timeout 200 + +// Debugging API used by library +kipc_err_t __kipc_err (kipc_err_t inError, const char *function, const char *file, int line); +#define kipc_err(err) __kipc_err(err, __FUNCTION__, __FILE__, __LINE__) + +const char *kipc_error_string (kipc_err_t in_error); + +kipc_err_t kipc_get_lookup_name (char **out_lookup_name, const char *in_service_id); +kipc_err_t kipc_get_service_name (char **out_service_name, const char *in_service_id); + +void kipc_free_string (char *io_string); + +#if __cplusplus +} +#endif + +#endif /* KIPC_COMMON_H */ diff --git a/src/lib/ccapi/common/mac/KerberosIPC/Kerberos/kipc_server.h b/src/lib/ccapi/common/mac/KerberosIPC/Kerberos/kipc_server.h new file mode 100644 index 0000000..5d97547 --- /dev/null +++ b/src/lib/ccapi/common/mac/KerberosIPC/Kerberos/kipc_server.h @@ -0,0 +1,54 @@ +/* + * kipc_server.h + * + * $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 KIPC_SERVER_H +#define KIPC_SERVER_H + +#include <Kerberos/kipc_common.h> + +#define kKerberosIPCMaxMsgSize 2048 + MAX_TRAILER_SIZE +#define kKerberosIPCTimeout 200 + +#if __cplusplus +extern "C" { +#endif + +typedef kipc_boolean_t (*kipc_demux_proc) (mach_msg_header_t *, mach_msg_header_t *); + + +kipc_err_t kipc_server_run_server (kipc_demux_proc in_demux_proc); + +mach_port_t kipc_server_get_service_port (); + +kipc_boolean_t kipc_server_quit (void); + +#if __cplusplus +} +#endif + +#endif /* KIPC_SERVER_H */ diff --git a/src/lib/ccapi/common/mac/KerberosIPC/Kerberos/kipc_session.h b/src/lib/ccapi/common/mac/KerberosIPC/Kerberos/kipc_session.h new file mode 100644 index 0000000..3f25956 --- /dev/null +++ b/src/lib/ccapi/common/mac/KerberosIPC/Kerberos/kipc_session.h @@ -0,0 +1,59 @@ +/* + * kipc_session.h + * + * $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 KIPC_SESSION_H +#define KIPC_SESSION_H + +#include <Kerberos/kipc_common.h> + +#if __cplusplus +extern "C" { +#endif + +#define kkipc_session_has_gui_access 0x00000001 +#define kkipc_session_caller_uses_gui 0x00000002 +#define kkipc_session_has_cli_access 0x00000004 + +typedef u_int32_t kipc_session_attributes_t; + + +kipc_boolean_t kipc_session_is_root_session (void); + +kipc_session_attributes_t kipc_session_get_attributes (void); + +kipc_string kipc_get_session_id_string (void); + +uid_t kipc_session_get_session_uid (void); + +uid_t kipc_session_get_server_uid (void); + +#if __cplusplus +} +#endif + +#endif /* KIPC_SESSION_H */ diff --git a/src/lib/ccapi/common/mac/KerberosIPC/README b/src/lib/ccapi/common/mac/KerberosIPC/README new file mode 100644 index 0000000..2e2d70d --- /dev/null +++ b/src/lib/ccapi/common/mac/KerberosIPC/README @@ -0,0 +1,3 @@ +This is a temporary copy of the KfM KerberosIPC library sources. +Once this gets merged onto the trunk the KfM build will use the +KerberosIPC library instead. diff --git a/src/lib/ccapi/common/mac/KerberosIPC/kipc_client.c b/src/lib/ccapi/common/mac/KerberosIPC/kipc_client.c new file mode 100644 index 0000000..2e48c42 --- /dev/null +++ b/src/lib/ccapi/common/mac/KerberosIPC/kipc_client.c @@ -0,0 +1,86 @@ +/* + * kipc_client.c + * + * $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 <Kerberos/kipc_client.h> + +// --------------------------------------------------------------------------- + +kipc_err_t +kipc_client_lookup_server (const char *in_service_id, + boolean_t in_launch_if_necessary, + mach_port_t *out_service_port) +{ + kipc_err_t err = 0; + mach_port_t boot_port = MACH_PORT_NULL; + char *service_name = NULL; + + if (in_service_id == NULL) { err = kipc_err (EINVAL); } + if (out_service_port == NULL) { err = kipc_err (EINVAL); } + + if (!err) { + // Get our bootstrap port + err = task_get_bootstrap_port (mach_task_self (), &boot_port); + } + + if (!err && !in_launch_if_necessary) { + char *lookup_name = NULL; + mach_port_t lookup_port = MACH_PORT_NULL; + + err = kipc_get_lookup_name (&lookup_name, in_service_id); + + if (!err) { + // Use the lookup name because the service name will return + // a valid port even if the server isn't running + err = bootstrap_look_up (boot_port, lookup_name, &lookup_port); + //dprintf ("%s(): bootstrap_look_up('%s'): port is %x (err = %d '%s')", + // __FUNCTION__, lookup_name, lookup_port, err, mach_error_string (err)); + } + + if (lookup_name != NULL ) { kipc_free_string (lookup_name); } + if (lookup_port != MACH_PORT_NULL) { mach_port_deallocate (mach_task_self (), lookup_port); } + } + + if (!err) { + err = kipc_get_service_name (&service_name, in_service_id); + } + + if (!err) { + err = bootstrap_look_up (boot_port, service_name, out_service_port); + //dprintf ("%s(): bootstrap_look_up('%s'): port is %x (err = %d '%s')", + // __FUNCTION__, service_name, *out_service_port, err, mach_error_string (err)); + } + + if (service_name != NULL ) { kipc_free_string (service_name); } + if (boot_port != MACH_PORT_NULL) { mach_port_deallocate (mach_task_self (), boot_port); } + + if (err == BOOTSTRAP_UNKNOWN_SERVICE) { + return err; // Avoid spewing to the log file + } else { + return kipc_err (err); + } +} diff --git a/src/lib/ccapi/common/mac/KerberosIPC/kipc_common.c b/src/lib/ccapi/common/mac/KerberosIPC/kipc_common.c new file mode 100644 index 0000000..438650f --- /dev/null +++ b/src/lib/ccapi/common/mac/KerberosIPC/kipc_common.c @@ -0,0 +1,93 @@ +/* + * kipc_common.c + * + * $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 <Kerberos/kipc_common.h> +#include <Kerberos/kipc_session.h> + + +// --------------------------------------------------------------------------- + +kipc_err_t __kipc_err (kipc_err_t in_error, const char *in_function, const char *in_file, int in_line) +{ + if (in_error && (ddebuglevel () > 0)) { + dprintf ("%s() got %d ('%s') at %s: %d", + in_function, in_error, mach_error_string (in_error), in_file, in_line); + dprintsession (); + //dprintbootstrap (mach_task_self ()); + } + return in_error; +} +// --------------------------------------------------------------------------- + + +const char *kipc_error_string (kipc_err_t in_error) +{ + return mach_error_string (in_error); +} + +// --------------------------------------------------------------------------- + +kipc_err_t kipc_get_service_name (char **out_service_name, const char *in_service_id) +{ + kipc_err_t err = 0; + + if (out_service_name == NULL) { err = EINVAL; } + if (in_service_id == NULL) { err = EINVAL; } + + if (!err) { + int wrote = asprintf (out_service_name, "%s%s", in_service_id, ".ipcService"); + if (wrote < 0) { err = ENOMEM; } + } + + return kipc_err (err); +} + +// --------------------------------------------------------------------------- + +kipc_err_t kipc_get_lookup_name (char **out_lookup_name, const char *in_service_id) +{ + kipc_err_t err = 0; + + if (out_lookup_name == NULL) { err = EINVAL; } + if (in_service_id == NULL) { err = EINVAL; } + + if (!err) { + int wrote = asprintf (out_lookup_name, "%s%s", in_service_id, ".ipcLookup"); + if (wrote < 0) { err = ENOMEM; } + } + + return kipc_err (err); +} + +// --------------------------------------------------------------------------- + +void kipc_free_string (char *io_string) +{ + free (io_string); +} + diff --git a/src/lib/ccapi/common/mac/KerberosIPC/kipc_server.c b/src/lib/ccapi/common/mac/KerberosIPC/kipc_server.c new file mode 100644 index 0000000..c7c973b --- /dev/null +++ b/src/lib/ccapi/common/mac/KerberosIPC/kipc_server.c @@ -0,0 +1,313 @@ +/* + * kipc_server.c + * + * $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 <Kerberos/kipc_server.h> +#include <Kerberos/kipc_session.h> +#include "notifyServer.h" + +// Global variables for servers (used by demux) +static mach_port_t g_service_port = MACH_PORT_NULL; +static kipc_boolean_t g_ready_to_quit = FALSE; +static kipc_demux_proc g_demux_proc = NULL; + +#pragma mark - + +// --------------------------------------------------------------------------- + +mach_port_t +kipc_server_get_service_port () +{ + return g_service_port; +} + +#pragma mark - + +// --------------------------------------------------------------------------- + +kipc_boolean_t +kipc_server_quit (void) +{ + // Do not unregister our port because then we won't get automatically launched again. + dprintf ("mach_server_quit_self(): quitting..."); + g_ready_to_quit = true; + return g_ready_to_quit; +} + +#pragma mark - + +// --------------------------------------------------------------------------- + +static kipc_boolean_t +kipc_server_demux (mach_msg_header_t *request, mach_msg_header_t *reply) +{ + if (mach_notify_server (request, reply) != false) { + return true; + } else { + return g_demux_proc (request, reply); + } + return false; +} + +#pragma mark - + +// --------------------------------------------------------------------------- + +static kipc_err_t +kipc_get_server_id (char **out_server_id) +{ + kern_return_t err = KERN_SUCCESS; + CFBundleRef bundle = NULL; + CFStringRef id_string = NULL; + CFIndex id_length = 0; + char *server_id = NULL; + + if (out_server_id == NULL) { err = kipc_err (EINVAL); } + + if (!err) { + bundle = CFBundleGetMainBundle (); + if (bundle == NULL) { err = ENOENT; } + } + + if (!err) { + id_string = CFBundleGetIdentifier (bundle); + if (id_string == NULL) { err = ENOMEM; } + } + + if (!err) { + id_length = CFStringGetMaximumSizeForEncoding (CFStringGetLength (id_string), + CFStringGetSystemEncoding ()) + 1; + server_id = calloc (id_length, sizeof (char)); + if (server_id == NULL) { err = errno; } + } + + if (!err) { + if (!CFStringGetCString (id_string, server_id, id_length, CFStringGetSystemEncoding ())) { + err = ENOMEM; + } + } + + if (!err) { + *out_server_id = server_id; + server_id = NULL; + } + + if (server_id != NULL) { kipc_free_string (server_id); } + + return kipc_err (err); +} + +// --------------------------------------------------------------------------- + +kipc_err_t +kipc_server_run_server (kipc_demux_proc in_demux_proc) +{ + kern_return_t err = KERN_SUCCESS; + char *server_id = NULL; + char *service_name = NULL; + char *lookup_name = NULL; + mach_port_t boot_port = MACH_PORT_NULL; + mach_port_t lookup_port = MACH_PORT_NULL; + mach_port_t notify_port = MACH_PORT_NULL; + mach_port_t previous_notify_port = MACH_PORT_NULL; + mach_port_t listen_port_set = MACH_PORT_NULL; + + if (in_demux_proc == NULL) { err = kipc_err (EINVAL); } + + // Shed root privileges if any + if (!err && (geteuid () == 0)) { + uid_t new_uid = kipc_session_get_server_uid (); + if (setuid (new_uid) < 0) { + dprintf ("%s(): setuid(%d) failed (euid is %d)", __FUNCTION__, new_uid, geteuid ()); + } + } + + if (!err) { + // Set up the globals so the demux can find them + g_demux_proc = in_demux_proc; + } + + if (!err) { + err = kipc_get_server_id (&server_id); + } + + if (!err) { + err = kipc_get_service_name (&service_name, server_id); + } + + if (!err) { + err = kipc_get_lookup_name (&lookup_name, server_id); + } + + if (!err) { + // Get the bootstrap port + err = task_get_bootstrap_port (mach_task_self (), &boot_port); + dprintf ("%s(): task_get_bootstrap_port(): port is %x (err = %d '%s')", + __FUNCTION__, boot_port, err, mach_error_string (err)); + } + + if (!err) { + // Create the lookup port: + err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &lookup_port); + } + + if (!err) { + err = mach_port_insert_right (mach_task_self (), lookup_port, lookup_port, MACH_MSG_TYPE_MAKE_SEND); + } + + if (!err) { + // Register the lookup port so others can tell whether or not we are running + err = bootstrap_register (boot_port, lookup_name, lookup_port); + dprintf ("%s(): bootstrap_register('%s', %x): (err = %d '%s')", + __FUNCTION__, lookup_name, lookup_port, err, mach_error_string (err)); + } + + if (!err) { + // We are an on-demand server so our port already exists. Just ask for it. + err = bootstrap_check_in (boot_port, (char *) service_name, &g_service_port); + dprintf ("%s(): bootstrap_check_in('%s'): port is %d (err = %d '%s')", + __FUNCTION__, service_name, g_service_port, err, mach_error_string (err)); + } + + if (!err) { + // Create the notification port: + err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, ¬ify_port); + } + + if (!err) { + // Ask for notification when the server port has no more senders + // A send-once right != a send right so our send-once right will not interfere with the notification + err = mach_port_request_notification (mach_task_self (), g_service_port, MACH_NOTIFY_NO_SENDERS, true, + notify_port, MACH_MSG_TYPE_MAKE_SEND_ONCE, &previous_notify_port); + dprintf ("%s(): requesting notification for no senders of %x returned '%s', err = %d\n", + __FUNCTION__, g_service_port, mach_error_string (err), err); + } + + if (!err) { + // Create the port set that the server will listen on + err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_PORT_SET, &listen_port_set); + } + + if (!err) { + // Add the service port to the port set + err = mach_port_move_member (mach_task_self (), g_service_port, listen_port_set); + } + + if (!err) { + // Add the notify port to the port set + err = mach_port_move_member (mach_task_self (), notify_port, listen_port_set); + } + + if (!err) { + dprintf ("%s(): \"%s\": starting up. service port = %x, bootstrap port = %x\n", + __FUNCTION__, service_name, g_service_port, boot_port); + } + + while (!err && !g_ready_to_quit) { + // Handle one message at a time so we can check to see if the server wants to quit + err = mach_msg_server_once (kipc_server_demux, kkipc_max_message_size, listen_port_set, MACH_MSG_OPTION_NONE); + } + + // Regardless of whether there was an error, unregister ourselves from no senders notifications + // so we don't get launched again by the notification message when we quit + // A send-once right != a send right so our send-once right will not interfere with the notification + if (g_service_port != MACH_PORT_NULL) { + err = mach_port_request_notification (mach_task_self (), g_service_port, MACH_NOTIFY_NO_SENDERS, + true, MACH_PORT_NULL, MACH_MSG_TYPE_MAKE_SEND_ONCE, + &previous_notify_port); + dprintf ("%s(): removing notification for no senders of %x returned '%s', err = %d\n", + __FUNCTION__, previous_notify_port, mach_error_string (err), err); + } + + // Clean up the ports and strings + if (lookup_port != MACH_PORT_NULL) { + kipc_err_t terr = bootstrap_register (boot_port, lookup_name, MACH_PORT_NULL); + dprintf ("%s(): bootstrap_register('%s', MACH_PORT_NULL): (err = %d '%s')", + __FUNCTION__, lookup_name, terr, mach_error_string (terr)); + mach_port_deallocate (mach_task_self (), lookup_port); + } + if (notify_port != MACH_PORT_NULL) { mach_port_deallocate (mach_task_self (), notify_port); } + if (listen_port_set != MACH_PORT_NULL) { mach_port_deallocate (mach_task_self (), listen_port_set); } + if (boot_port != MACH_PORT_NULL) { mach_port_deallocate (mach_task_self (), boot_port); } + if (lookup_name != NULL ) { kipc_free_string (lookup_name); } + if (service_name != NULL ) { kipc_free_string (service_name); } + if (server_id != NULL ) { kipc_free_string (server_id); } + + return kipc_err (err); +} + +#pragma mark - + +// --------------------------------------------------------------------------- + +kern_return_t +do_mach_notify_port_deleted (mach_port_t notify, mach_port_name_t name) +{ + dprintf ("Received MACH_NOTIFY_PORT_DELETED... quitting self"); + kipc_server_quit (); + return KERN_SUCCESS; +} + +// --------------------------------------------------------------------------- + +kern_return_t +do_mach_notify_port_destroyed (mach_port_t notify, mach_port_t rights) +{ + dprintf ("Received MACH_NOTIFY_PORT_DESTROYED... quitting self"); + kipc_server_quit (); + return KERN_SUCCESS; +} + +// --------------------------------------------------------------------------- + +kern_return_t +do_mach_notify_no_senders (mach_port_t notify, mach_port_mscount_t mscount) +{ + dprintf ("Received MACH_NOTIFY_NO_SENDERS... quitting self"); + kipc_server_quit (); + return KERN_SUCCESS; +} + +// --------------------------------------------------------------------------- + +kern_return_t +do_mach_notify_send_once (mach_port_t notify) +{ + dprintf ("Received MACH_NOTIFY_SEND_ONCE"); + return KERN_SUCCESS; +} + +// --------------------------------------------------------------------------- + +kern_return_t +do_mach_notify_dead_name (mach_port_t notify, mach_port_name_t name) +{ + dprintf ("Received MACH_NOTIFY_DEAD_NAME... quitting self"); + kipc_server_quit (); + return KERN_SUCCESS; +} + diff --git a/src/lib/ccapi/common/mac/KerberosIPC/kipc_session.c b/src/lib/ccapi/common/mac/KerberosIPC/kipc_session.c new file mode 100644 index 0000000..c08e1bc --- /dev/null +++ b/src/lib/ccapi/common/mac/KerberosIPC/kipc_session.c @@ -0,0 +1,141 @@ +/* + * kipc_session.c + * + * $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 <Security/AuthSession.h> +#include <pwd.h> +#include <Kerberos/kipc_session.h> + +// --------------------------------------------------------------------------- + +kipc_boolean_t kipc_session_is_root_session (void) +{ + kipc_err_t err = 0; + kipc_boolean_t is_root_session = TRUE; // safer to assume root session + SessionAttributeBits sattrs = 0L; + + err = SessionGetInfo (callerSecuritySession, NULL, &sattrs); + + if (!err) { + is_root_session = (sattrs & sessionIsRoot); + dprintf ("%s(): running in %s session", + __FUNCTION__, is_root_session ? "the root" : "a user"); + } else { + dprintf ("%s(): SessionGetInfo() failed with %d", __FUNCTION__, err); + } + + return is_root_session; +} + +// --------------------------------------------------------------------------- + +kipc_session_attributes_t kipc_session_get_attributes (void) +{ + kipc_session_attributes_t attributes = 0L; + SessionAttributeBits sattrs = 0L; + int fd_stdin = fileno (stdin); + int fd_stdout = fileno (stdout); + char *fd_stdin_name = ttyname (fd_stdin); + + if ((SessionGetInfo (callerSecuritySession, NULL, &sattrs) == noErr) && (sattrs & sessionHasGraphicAccess)) { + dprintf ("%s(): Session has graphic access.", __FUNCTION__); + attributes |= kkipc_session_has_gui_access; + + // Check for the HIToolbox (Carbon) or AppKit (Cocoa). If either is loaded, we are a GUI app! + CFBundleRef hiToolBoxBundle = CFBundleGetBundleWithIdentifier (CFSTR ("com.apple.HIToolbox")); + if (hiToolBoxBundle != NULL && CFBundleIsExecutableLoaded (hiToolBoxBundle)) { + dprintf ("%s(): Carbon Toolbox is loaded.", __FUNCTION__); + attributes |= kkipc_session_caller_uses_gui; + } + + CFBundleRef appKitBundle = CFBundleGetBundleWithIdentifier (CFSTR ("com.apple.AppKit")); + if (appKitBundle != NULL && CFBundleIsExecutableLoaded (appKitBundle)) { + dprintf ("%s(): AppKit is loaded.", __FUNCTION__); + attributes |= kkipc_session_caller_uses_gui; + } + } + + // Session info isn't reliable for remote sessions. + // Check manually for terminal access with file descriptors + if (isatty (fd_stdin) && isatty (fd_stdout) && (fd_stdin_name != NULL)) { + dprintf ("%s(): Terminal '%s' of type '%s' exists.", + __FUNCTION__, fd_stdin_name, getenv ("TERM")); + attributes |= kkipc_session_has_cli_access; + } + + dprintf ("%s(): Attributes are %x", __FUNCTION__, attributes); + return attributes; +} + +// --------------------------------------------------------------------------- + +kipc_string kipc_get_session_id_string (void) +{ + // Session ID is a 32 bit quanitity, so the longest string is 0xFFFFFFFF + static char s_session_name[16]; + SecuritySessionId id; + + s_session_name[0] = '\0'; + + if (SessionGetInfo (callerSecuritySession, &id, NULL) == noErr) { + snprintf (s_session_name, sizeof (s_session_name), "0x%lx", id); + } + + return s_session_name; +} + +// --------------------------------------------------------------------------- + +uid_t kipc_session_get_session_uid (void) +{ + // Get the uid of the user that the server will be run and named for. + uid_t uid = geteuid (); + + // Avoid root because the client can later go back to the real uid + if (uid == 0 /* root */) { + dprintf ("%s(): geteuid returned UID %d, trying getuid...\n", __FUNCTION__, uid); + uid = getuid (); + } + + return uid; +} + +// --------------------------------------------------------------------------- + +uid_t kipc_session_get_server_uid (void) +{ + uid_t server_uid = 92; + + struct passwd *pw = getpwnam ("securityagent"); + if (pw != NULL) { + server_uid = pw->pw_uid; + } else { + dprintf ("%s: getpwnam(securityagent) failed, using hardcoded value.", __FUNCTION__); + } + + return server_uid; +} diff --git a/src/lib/ccapi/common/mac/KerberosIPC/notify.defs b/src/lib/ccapi/common/mac/KerberosIPC/notify.defs new file mode 100644 index 0000000..fea03c9 --- /dev/null +++ b/src/lib/ccapi/common/mac/KerberosIPC/notify.defs @@ -0,0 +1,36 @@ +/* + * mach_notify.defs + * + * $Header$ + * + * Copyright 2003 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. + */ + +/* + * This is totally disgusting. + * Rename the demux function so we don't collide with other libraries using this. + */ + +#define notify_server mach_notify_server + +#include <mach/notify.defs> |