basic ipc framework
This commit is contained in:
		
							
								
								
									
										31
									
								
								lib/ipc/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								lib/ipc/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| # $Id: Makefile.am,v 1.1 2004/12/20 08:31:45 assar Exp $ | ||||
|  | ||||
| include $(top_srcdir)/Makefile.am.common | ||||
|  | ||||
| noinst_LTLIBRARIES = libheim-ipcc.la libheim-ipcs.la | ||||
|  | ||||
| libheim_ipcc_la_SOURCES = client.c common.c | ||||
| libheim_ipcs_la_SOURCES = server.c common.c | ||||
|  | ||||
| include_HEADERS = heim-ipc.h | ||||
|  | ||||
| libheim_ipsc_la_LDFLAGS = -version-info 0:0:0 | ||||
| libheim_ipss_la_LDFLAGS = -version-info 0:0:0 | ||||
|  | ||||
| libheim_ipsc_la_LIBADD = \ | ||||
| 	$(LIB_roken) | ||||
|  | ||||
| libheim_ipss_la_LIBADD = $(libheim_ipsc_la_LIBADD) | ||||
|  | ||||
| if versionscript | ||||
| libheim_ipsc_la_LDFLAGS += $(LDFLAGS_VERSION_SCRIPT)$(srcdir)/version-scriptc.map | ||||
| libheim_ipss_la_LDFLAGS += $(LDFLAGS_VERSION_SCRIPT)$(srcdir)/version-scripts.map | ||||
| endif | ||||
|  | ||||
| TESTS =	$(check_PROGRAMS) | ||||
|  | ||||
| noinst_PROGRAMS = tc ts | ||||
|  | ||||
| ts_LDADD = libheim-ipcs.la | ||||
| tc_LDADD = libheim-ipcc.la | ||||
|  | ||||
							
								
								
									
										541
									
								
								lib/ipc/client.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										541
									
								
								lib/ipc/client.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,541 @@ | ||||
| /* | ||||
|  * Copyright (c) 2009 Kungliga Tekniska H<>gskolan | ||||
|  * (Royal Institute of Technology, Stockholm, Sweden). | ||||
|  * All rights reserved. | ||||
|  * | ||||
|  * Portions Copyright (c) 2009 Apple Inc. All rights reserved. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions | ||||
|  * are met: | ||||
|  * | ||||
|  * 1. Redistributions of source code must retain the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer. | ||||
|  * | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer in the | ||||
|  *    documentation and/or other materials provided with the distribution. | ||||
|  * | ||||
|  * 3. Neither the name of the Institute nor the names of its contributors | ||||
|  *    may be used to endorse or promote products derived from this software | ||||
|  *    without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND | ||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE | ||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
|  * SUCH DAMAGE. | ||||
|  */ | ||||
|  | ||||
| #include "hi_locl.h" | ||||
|  | ||||
| #ifdef __APPLE__ | ||||
|  | ||||
| #include "heim_ipc.h" | ||||
| #include "heim_ipc_asyncServer.h" | ||||
|  | ||||
| #include <dispatch/dispatch.h> | ||||
| #include <mach/mach.h> | ||||
|  | ||||
| static dispatch_once_t jobqinited = 0; | ||||
| static dispatch_queue_t jobq = NULL; | ||||
| static dispatch_queue_t syncq; | ||||
|  | ||||
| struct mach_ctx { | ||||
|     mach_port_t server; | ||||
|     char *name; | ||||
| }; | ||||
|  | ||||
| static int | ||||
| mach_release(void *ctx); | ||||
|  | ||||
| static int | ||||
| mach_init(const char *service, void **ctx) | ||||
| { | ||||
|     struct mach_ctx *ipc; | ||||
|     mach_port_t sport; | ||||
|     int ret; | ||||
|  | ||||
|     dispatch_once(&jobqinited, ^{ | ||||
| 	    jobq = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); | ||||
| 	    syncq = dispatch_queue_create("heim-ipc-syncq", NULL); | ||||
| 	}); | ||||
|  | ||||
|     ret = bootstrap_look_up(bootstrap_port, service, &sport); | ||||
|     if (ret) | ||||
| 	return ret; | ||||
|  | ||||
|     ipc = malloc(sizeof(*ipc)); | ||||
|     if (ipc == NULL) { | ||||
| 	mach_port_destroy(mach_task_self(), sport); | ||||
| 	return ENOMEM; | ||||
|     } | ||||
|  | ||||
|     ipc->server = sport; | ||||
|     ipc->name = strdup(service); | ||||
|     if (ipc->name == NULL) { | ||||
| 	mach_release(ipc); | ||||
| 	return ENOMEM; | ||||
|     } | ||||
|  | ||||
|     *ctx = ipc; | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static int | ||||
| mach_ipc(void *ctx,  | ||||
| 	 const heim_idata *request, heim_idata *response, | ||||
| 	 heim_icred *cred) | ||||
| { | ||||
|     struct mach_ctx *ipc = ctx; | ||||
|     heim_ipc_message_inband_t requestin; | ||||
|     mach_msg_type_number_t requestin_length = 0; | ||||
|     heim_ipc_message_outband_t requestout = NULL; | ||||
|     mach_msg_type_number_t requestout_length = 0; | ||||
|     heim_ipc_message_inband_t replyin; | ||||
|     mach_msg_type_number_t replyin_length; | ||||
|     heim_ipc_message_outband_t replyout; | ||||
|     mach_msg_type_number_t replyout_length; | ||||
|     int ret, errorcode, retries = 0; | ||||
|  | ||||
|     memcpy(requestin, request->data, request->length); | ||||
|     requestin_length = request->length; | ||||
|  | ||||
|     while (retries < 2) { | ||||
| 	__block mach_port_t sport; | ||||
|  | ||||
| 	dispatch_sync(syncq, ^{ sport = ipc->server; }); | ||||
|  | ||||
| 	ret = mheim_ipc_call(sport, | ||||
| 			     requestin, requestin_length, | ||||
| 			     requestout, requestout_length, | ||||
| 			     &errorcode, | ||||
| 			     replyin, &replyin_length, | ||||
| 			     &replyout, &replyout_length); | ||||
| 	if (ret == MACH_SEND_INVALID_DEST) { | ||||
| 	    mach_port_t nport; | ||||
| 	    /* race other threads to get a new port */ | ||||
| 	    ret = bootstrap_look_up(bootstrap_port, ipc->name, &nport); | ||||
| 	    if (ret) | ||||
| 		return ret; | ||||
| 	    dispatch_sync(syncq, ^{ | ||||
| 		    /* check if we lost the race to lookup the port */ | ||||
| 		    if (sport != ipc->server) { | ||||
| 			mach_port_deallocate(mach_task_self(), nport); | ||||
| 		    } else { | ||||
| 			mach_port_deallocate(mach_task_self(), ipc->server); | ||||
| 			ipc->server = nport; | ||||
| 		    } | ||||
| 		}); | ||||
| 	    retries++; | ||||
| 	} else if (ret) { | ||||
| 	    return ret; | ||||
| 	} else | ||||
| 	    break; | ||||
|     } | ||||
|     if (retries >= 2) | ||||
| 	return EINVAL; | ||||
|  | ||||
|     if (errorcode) { | ||||
| 	if (replyout_length) | ||||
| 	    vm_deallocate (mach_task_self (), (vm_address_t) replyout, | ||||
| 			   replyout_length);  | ||||
| 	return errorcode; | ||||
|     } | ||||
|      | ||||
|     if (replyout_length) { | ||||
| 	response->data = malloc(replyout_length); | ||||
| 	if (response->data == NULL) { | ||||
| 	    vm_deallocate (mach_task_self (), (vm_address_t) replyout, | ||||
| 			   replyout_length);  | ||||
| 	    return ENOMEM; | ||||
| 	} | ||||
| 	memcpy(response->data, replyout, replyout_length); | ||||
| 	response->length = replyout_length; | ||||
| 	vm_deallocate (mach_task_self (), (vm_address_t) replyout, | ||||
| 		       replyout_length);  | ||||
|     } else { | ||||
| 	response->data = malloc(replyin_length); | ||||
| 	if (response->data == NULL) | ||||
| 	    return ENOMEM; | ||||
| 	memcpy(response->data, replyin, replyin_length); | ||||
| 	response->length = replyin_length; | ||||
|     } | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| struct async_client { | ||||
|     mach_port_t mp; | ||||
|     dispatch_source_t source; | ||||
|     dispatch_queue_t queue; | ||||
|     void (*func)(void *, int, heim_idata *, heim_icred); | ||||
|     void *userctx; | ||||
| }; | ||||
|  | ||||
| kern_return_t | ||||
| mheim_ado_acall_reply(mach_port_t server_port, | ||||
| 		      audit_token_t client_creds, | ||||
| 		      int returnvalue, | ||||
| 		      heim_ipc_message_inband_t replyin, | ||||
| 		      mach_msg_type_number_t replyinCnt, | ||||
| 		      heim_ipc_message_outband_t replyout, | ||||
| 		      mach_msg_type_number_t replyoutCnt) | ||||
| { | ||||
|     struct async_client *c = dispatch_get_context(dispatch_get_current_queue()); | ||||
|     heim_idata response; | ||||
|  | ||||
|     if (returnvalue) { | ||||
| 	response.data = NULL; | ||||
| 	response.length = 0; | ||||
|     } else if (replyoutCnt) { | ||||
| 	response.data = replyout; | ||||
| 	response.length = replyoutCnt; | ||||
|     } else { | ||||
| 	response.data = replyin; | ||||
| 	response.length = replyinCnt; | ||||
|     } | ||||
|  | ||||
|     (*c->func)(c->userctx, returnvalue, &response, NULL); | ||||
|  | ||||
|     if (replyoutCnt) | ||||
| 	vm_deallocate (mach_task_self (), (vm_address_t) replyout, replyoutCnt);  | ||||
|  | ||||
|     dispatch_source_cancel(c->source); | ||||
|  | ||||
|     return 0; | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| static int | ||||
| mach_async(void *ctx, const heim_idata *request, void *userctx,  | ||||
| 	   void (*func)(void *, int, heim_idata *, heim_icred)) | ||||
| { | ||||
|     struct mach_ctx *ipc = ctx; | ||||
|     heim_ipc_message_inband_t requestin; | ||||
|     mach_msg_type_number_t requestin_length = 0; | ||||
|     heim_ipc_message_outband_t requestout = NULL; | ||||
|     mach_msg_type_number_t requestout_length = 0; | ||||
|     int ret, retries = 0; | ||||
|     kern_return_t kr; | ||||
|     struct async_client *c; | ||||
|  | ||||
|     /* first create the service that will catch the reply from the server */ | ||||
|     /* XXX these object should be cached and reused */ | ||||
|  | ||||
|     c = malloc(sizeof(*c)); | ||||
|     if (c == NULL) | ||||
| 	return ENOMEM; | ||||
|  | ||||
|     kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &c->mp); | ||||
|     if (kr != KERN_SUCCESS) | ||||
| 	return EINVAL; | ||||
|  | ||||
|     c->queue = dispatch_queue_create("heim-ipc-async-client", NULL); | ||||
|     c->source = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, c->mp, 0, c->queue); | ||||
|     dispatch_set_context(c->queue, c); | ||||
|  | ||||
|     dispatch_source_set_event_handler(c->source, ^{ | ||||
| 	    dispatch_mig_server(c->source, | ||||
| 				sizeof(union __RequestUnion__mheim_ado_mheim_aipc_subsystem),  | ||||
| 				mheim_aipc_server); | ||||
| 	}); | ||||
|  | ||||
|     dispatch_source_set_cancel_handler(c->source, ^{ | ||||
| 	    struct async_client *s = dispatch_get_context(dispatch_get_current_queue()); | ||||
| 	    mach_port_mod_refs(mach_task_self(), c->mp,  | ||||
| 			       MACH_PORT_RIGHT_RECEIVE, -1); | ||||
| 	    dispatch_release(c->queue); | ||||
| 	    dispatch_release(c->source); | ||||
| 	    free(c); | ||||
| 	}); | ||||
|  | ||||
|     c->func = func; | ||||
|     c->userctx = userctx; | ||||
|  | ||||
|     dispatch_resume(c->source); | ||||
|  | ||||
|     /* ok, send the message */ | ||||
|  | ||||
|     memcpy(requestin, request->data, request->length); | ||||
|     requestin_length = request->length; | ||||
|  | ||||
|     while (retries < 2) { | ||||
| 	__block mach_port_t sport; | ||||
|  | ||||
| 	dispatch_sync(syncq, ^{ sport = ipc->server; }); | ||||
|  | ||||
| 	ret = mheim_ipc_call_request(sport, c->mp, | ||||
| 				     requestin, requestin_length, | ||||
| 				     requestout, requestout_length); | ||||
| 	if (ret == MACH_SEND_INVALID_DEST) { | ||||
| 	    ret = bootstrap_look_up(bootstrap_port, ipc->name, &sport); | ||||
| 	    if (ret) { | ||||
| 		dispatch_source_cancel(c->source); | ||||
| 		return ret; | ||||
| 	    } | ||||
| 	    mach_port_deallocate(mach_task_self(), ipc->server); | ||||
| 	    ipc->server = sport; | ||||
| 	    retries++; | ||||
| 	} else if (ret) { | ||||
| 	    dispatch_source_cancel(c->source); | ||||
| 	    return ret; | ||||
| 	} else | ||||
| 	    break; | ||||
|     } | ||||
|     if (retries >= 2) { | ||||
| 	dispatch_source_cancel(c->source); | ||||
| 	return EINVAL; | ||||
|     } | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static int | ||||
| mach_release(void *ctx) | ||||
| { | ||||
|     struct mach_ctx *ipc = ctx; | ||||
|     if (ipc->server != MACH_PORT_NULL) | ||||
| 	mach_port_deallocate(mach_task_self(), ipc->server); | ||||
|     free(ipc->name); | ||||
|     free(ipc); | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| struct path_ctx { | ||||
|     char *path; | ||||
|     int fd; | ||||
| }; | ||||
|  | ||||
| static int common_release(void *); | ||||
|  | ||||
| static int | ||||
| connect_unix(struct path_ctx *s) | ||||
| { | ||||
|     struct sockaddr_un addr; | ||||
|  | ||||
|     addr.sun_family = AF_UNIX; | ||||
|     strlcpy(addr.sun_path, s->path, sizeof(addr.sun_path)); | ||||
|  | ||||
|     s->fd = socket(AF_UNIX, SOCK_STREAM, 0); | ||||
|     if (s->fd < 0) | ||||
| 	return errno; | ||||
|     rk_cloexec(s->fd); | ||||
|  | ||||
|     if (connect(s->fd, (struct sockaddr *)&addr, sizeof(addr)) != 0) { | ||||
| 	close(s->fd); | ||||
| 	return errno; | ||||
|     } | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static int | ||||
| common_path_init(const char *service, | ||||
| 		 const char *file, | ||||
| 		 void **ctx) | ||||
| { | ||||
|     struct path_ctx *s; | ||||
|     const char *path; | ||||
|     char *apath = NULL; | ||||
|     int ret; | ||||
|     int *fd; | ||||
|  | ||||
|     s = malloc(sizeof(*s)); | ||||
|     if (s == NULL) | ||||
| 	return ENOMEM; | ||||
|     s->fd = -1; | ||||
|  | ||||
|     if (service[0] == '\0') | ||||
| 	asprintf(&s->path, "/var/run/.heim_%s", file); | ||||
|     else | ||||
| 	s->path = strdup(service); | ||||
| 	 | ||||
|     *ctx = s; | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static int | ||||
| unix_socket_init(const char *service, | ||||
| 		 void **ctx) | ||||
| { | ||||
|     int ret; | ||||
|  | ||||
|     ret = common_path_init(service, "socket", ctx); | ||||
|     if (ret) | ||||
| 	return ret; | ||||
|     ret = connect_unix(*ctx); | ||||
|     if (ret) | ||||
| 	common_release(*ctx); | ||||
|  | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
|  | ||||
| static int | ||||
| unix_socket_ipc(void *ctx, | ||||
| 		const heim_idata *request, heim_idata *response, | ||||
| 		heim_icred *cred) | ||||
| { | ||||
|     return EINVAL; | ||||
| } | ||||
|  | ||||
| int | ||||
| common_release(void *ctx) | ||||
| { | ||||
|     struct path_ctx *s = ctx; | ||||
|     if (s->fd >= 0) | ||||
| 	close(s->fd); | ||||
|     free(s->path); | ||||
|     free(s); | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| #ifdef HAVE_DOOR | ||||
|  | ||||
| static int | ||||
| door_init(const char *service, | ||||
| 	  void **ctx) | ||||
| { | ||||
|     ret = common_path_init(context, service, name, "door", ctx); | ||||
|     if (ret) | ||||
| 	return ret; | ||||
|     ret = connect_door(*ctx); | ||||
|     if (ret) | ||||
| 	common_release(*ctx); | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| static int | ||||
| door_ipc(void *ctx,  | ||||
| 	 const heim_idata *request, heim_idata *response, | ||||
| 	 heim_icred *cred) | ||||
| { | ||||
|     door_arg_t arg; | ||||
|     int ret; | ||||
|  | ||||
|     arg.data_ptr = request->data; | ||||
|     arg.data_size = request->length; | ||||
|     arg.desc_ptr = NULL; | ||||
|     arg.desc_num = 0; | ||||
|     arg.rbuf = NULL; | ||||
|     arg.rsize = 0; | ||||
|  | ||||
|     ret = door_call(fd, &arg); | ||||
|     close(fd); | ||||
|     if (ret != 0) | ||||
| 	return errno; | ||||
| 	 | ||||
|     response->data = malloc(arg.rsize); | ||||
|     if (response->data == NULL) { | ||||
| 	munmap(arg.rbuf, arg.rsize); | ||||
| 	return ENOMEM; | ||||
|     } | ||||
|     memcpy(response->data, arg.rbuf, arg.rsize); | ||||
|     response->length = arg.rsize; | ||||
|     munmap(arg.rbuf, arg.rsize); | ||||
|  | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| struct hipc_ops { | ||||
|     const char *prefix; | ||||
|     int (*init)(const char *, void **); | ||||
|     int (*release)(void *); | ||||
|     int (*ipc)(void *,const heim_idata *, heim_idata *, heim_icred *); | ||||
|     int (*async)(void *, const heim_idata *, void *,  | ||||
| 		 void (*)(void *, int, heim_idata *, heim_icred)); | ||||
| }; | ||||
|  | ||||
| struct hipc_ops ipcs[] = { | ||||
| #ifdef __APPLE__ | ||||
|     { "MACH", mach_init, mach_release, mach_ipc, mach_async }, | ||||
| #endif | ||||
| #ifdef HAVE_DOOR | ||||
|     { "DOOR", door_init, common_release, door_ipc } | ||||
| #endif | ||||
|     { "UNIX", unix_socket_init, common_release, unix_socket_ipc } | ||||
| }; | ||||
|  | ||||
| struct heim_ipc { | ||||
|     struct hipc_ops *ops; | ||||
|     void *ctx; | ||||
| }; | ||||
|  | ||||
|  | ||||
| int | ||||
| heim_ipc_init_context(const char *name, heim_ipc *ctx) | ||||
| { | ||||
|     unsigned int i; | ||||
|     int ret, any = 0; | ||||
|  | ||||
|     for(i = 0; i < sizeof(ipcs)/sizeof(ipcs[0]); i++) { | ||||
| 	size_t prefix_len = strlen(ipcs[i].prefix); | ||||
| 	heim_ipc c; | ||||
| 	if(strncmp(ipcs[i].prefix, name, prefix_len) == 0  | ||||
| 	   && name[prefix_len] == ':')  { | ||||
| 	} else if (strncmp("ANY:", name, 4) == 0) { | ||||
| 	    prefix_len = 3; | ||||
| 	    any = 1; | ||||
| 	} else | ||||
| 	    continue; | ||||
| 	     | ||||
| 	c = calloc(1, sizeof(*c)); | ||||
| 	if (c == NULL) | ||||
| 	    return ENOMEM; | ||||
| 	 | ||||
| 	c->ops = &ipcs[i]; | ||||
| 	 | ||||
| 	ret = (c->ops->init)(name + prefix_len + 1, &c->ctx); | ||||
| 	if (ret) { | ||||
| 	    free(c); | ||||
| 	    if (any) | ||||
| 		continue; | ||||
| 	    return ret; | ||||
| 	} | ||||
| 	 | ||||
| 	*ctx = c; | ||||
| 	return 0; | ||||
|     } | ||||
|  | ||||
|     return ENOENT; | ||||
| } | ||||
|  | ||||
| void | ||||
| heim_ipc_free_context(heim_ipc ctx) | ||||
| { | ||||
|     (ctx->ops->release)(ctx->ctx); | ||||
|     free(ctx); | ||||
| } | ||||
|  | ||||
| int | ||||
| heim_ipc_call(heim_ipc ctx, const heim_idata *send, heim_idata *recv, | ||||
| 	      heim_icred *cred) | ||||
| { | ||||
|     if (cred) | ||||
| 	*cred = NULL; | ||||
|     return (ctx->ops->ipc)(ctx->ctx, send, recv, cred); | ||||
| } | ||||
|  | ||||
| int | ||||
| heim_ipc_async(heim_ipc ctx, const heim_idata *send, void *userctx, | ||||
| 	       void (*func)(void *, int, heim_idata *, heim_icred)) | ||||
| { | ||||
|     if (ctx->ops->async == NULL) | ||||
| 	return EAGAIN; /* XXX */ | ||||
|     return (ctx->ops->async)(ctx->ctx, send, userctx, func); | ||||
| } | ||||
							
								
								
									
										155
									
								
								lib/ipc/common.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								lib/ipc/common.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,155 @@ | ||||
| /* | ||||
|  * Copyright (c) 2009 Kungliga Tekniska H<>gskolan | ||||
|  * (Royal Institute of Technology, Stockholm, Sweden). | ||||
|  * All rights reserved. | ||||
|  * | ||||
|  * Portions Copyright (c) 2009 Apple Inc. All rights reserved. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions | ||||
|  * are met: | ||||
|  * | ||||
|  * 1. Redistributions of source code must retain the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer. | ||||
|  * | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer in the | ||||
|  *    documentation and/or other materials provided with the distribution. | ||||
|  * | ||||
|  * 3. Neither the name of the Institute nor the names of its contributors | ||||
|  *    may be used to endorse or promote products derived from this software | ||||
|  *    without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND | ||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE | ||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
|  * SUCH DAMAGE. | ||||
|  */ | ||||
|  | ||||
| #include "hi_locl.h" | ||||
| #ifdef __APPLE__ | ||||
| #include <dispatch/dispatch.h> | ||||
| #endif | ||||
|  | ||||
| struct heim_icred { | ||||
|     uid_t uid; | ||||
|     gid_t gid; | ||||
|     pid_t pid; | ||||
|     pid_t session; | ||||
| }; | ||||
|  | ||||
| void | ||||
| heim_ipc_free_cred(heim_icred cred) | ||||
| { | ||||
|     free(cred); | ||||
| } | ||||
|  | ||||
| uid_t | ||||
| heim_ipc_cred_get_uid(heim_icred cred) | ||||
| { | ||||
|     return cred->uid; | ||||
| } | ||||
|  | ||||
| gid_t | ||||
| heim_ipc_cred_get_gid(heim_icred cred) | ||||
| { | ||||
|     return cred->gid; | ||||
| } | ||||
|  | ||||
| pid_t | ||||
| heim_ipc_cred_get_pid(heim_icred cred) | ||||
| { | ||||
|     return cred->pid; | ||||
| } | ||||
|  | ||||
| pid_t | ||||
| heim_ipc_cred_get_session(heim_icred cred) | ||||
| { | ||||
|     return cred->session; | ||||
| } | ||||
|  | ||||
|  | ||||
| int | ||||
| _heim_ipc_create_cred(uid_t uid, gid_t gid, pid_t pid, pid_t session, heim_icred *cred) | ||||
| { | ||||
|     *cred = calloc(1, sizeof(**cred)); | ||||
|     if (*cred == NULL) | ||||
| 	return ENOMEM; | ||||
|     (*cred)->uid = uid; | ||||
|     (*cred)->gid = gid; | ||||
|     (*cred)->pid = pid; | ||||
|     (*cred)->session = session; | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| void | ||||
| heim_ipc_main(void) | ||||
| { | ||||
| #if __APPLE__ | ||||
|     dispatch_main(); | ||||
| #else | ||||
|     abort(); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| heim_isemaphore | ||||
| heim_ipc_semaphore_create(long value) | ||||
| { | ||||
| #ifdef __APPLE__ | ||||
|     return (heim_isemaphore)dispatch_semaphore_create(value); | ||||
| #else | ||||
|     abort(); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| long | ||||
| heim_ipc_semaphore_wait(heim_isemaphore s, time_t t) | ||||
| { | ||||
| #ifdef __APPLE__ | ||||
|     uint64_t timeout; | ||||
|     if (t == HEIM_IPC_WAIT_FOREVER) | ||||
| 	timeout = DISPATCH_TIME_FOREVER; | ||||
|     else | ||||
| 	timeout = (uint64_t)t * NSEC_PER_SEC; | ||||
|  | ||||
|     return dispatch_semaphore_wait((dispatch_semaphore_t)s, timeout); | ||||
| #else | ||||
|     abort(); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| long | ||||
| heim_ipc_semaphore_signal(heim_isemaphore s) | ||||
| { | ||||
| #ifdef __APPLE__ | ||||
|     return dispatch_semaphore_signal((dispatch_semaphore_t)s); | ||||
| #else | ||||
|     abort(); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void | ||||
| heim_ipc_semaphore_release(heim_isemaphore s) | ||||
| { | ||||
| #ifdef __APPLE__ | ||||
|     return dispatch_release((dispatch_semaphore_t)s); | ||||
| #else | ||||
|     abort(); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void | ||||
| heim_ipc_free_data(heim_idata *data) | ||||
| { | ||||
|     if (data->data) | ||||
| 	free(data->data); | ||||
|     data->data = NULL; | ||||
|     data->length = 0; | ||||
| } | ||||
							
								
								
									
										117
									
								
								lib/ipc/heim-ipc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								lib/ipc/heim-ipc.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,117 @@ | ||||
| /* | ||||
|  * Copyright (c) 2009 Kungliga Tekniska H<>gskolan | ||||
|  * (Royal Institute of Technology, Stockholm, Sweden). | ||||
|  * All rights reserved. | ||||
|  * | ||||
|  * Portions Copyright (c) 2009 Apple Inc. All rights reserved. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions | ||||
|  * are met: | ||||
|  * | ||||
|  * 1. Redistributions of source code must retain the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer. | ||||
|  * | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer in the | ||||
|  *    documentation and/or other materials provided with the distribution. | ||||
|  * | ||||
|  * 3. Neither the name of the Institute nor the names of its contributors | ||||
|  *    may be used to endorse or promote products derived from this software | ||||
|  *    without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND | ||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE | ||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
|  * SUCH DAMAGE. | ||||
|  */ | ||||
|  | ||||
| #include <asn1-common.h> | ||||
|  | ||||
| typedef struct heim_ipc *heim_ipc; | ||||
| typedef struct heim_sipc *heim_sipc; | ||||
| typedef struct heim_icred *heim_icred; | ||||
| typedef struct heim_isemaphore *heim_isemaphore; | ||||
| typedef struct heim_octet_string heim_idata; | ||||
| typedef struct heim_sipc_call *heim_sipc_call; | ||||
|  | ||||
| /* common */ | ||||
|  | ||||
| void | ||||
| heim_ipc_free_cred(heim_icred); | ||||
|  | ||||
| uid_t | ||||
| heim_ipc_cred_get_uid(heim_icred); | ||||
|  | ||||
| gid_t | ||||
| heim_ipc_cred_get_gid(heim_icred); | ||||
|  | ||||
| pid_t | ||||
| heim_ipc_cred_get_pid(heim_icred); | ||||
|  | ||||
| pid_t | ||||
| heim_ipc_cred_get_session(heim_icred); | ||||
|  | ||||
| void | ||||
| heim_ipc_main(void); | ||||
|  | ||||
| heim_isemaphore | ||||
| heim_ipc_semaphore_create(long); | ||||
|  | ||||
| long | ||||
| heim_ipc_semaphore_wait(heim_isemaphore, time_t); | ||||
|  | ||||
| long | ||||
| heim_ipc_semaphore_signal(heim_isemaphore); | ||||
|  | ||||
| void | ||||
| heim_ipc_semaphore_release(heim_isemaphore); | ||||
|  | ||||
| #define HEIM_IPC_WAIT_FOREVER ((time_t)-1) | ||||
|  | ||||
| void | ||||
| heim_ipc_free_data(heim_idata *); | ||||
|  | ||||
| /* client */ | ||||
|  | ||||
| int | ||||
| heim_ipc_init_context(const char *, heim_ipc *); | ||||
|  | ||||
| void | ||||
| heim_ipc_free_context(heim_ipc); | ||||
|  | ||||
| int | ||||
| heim_ipc_call(heim_ipc, const heim_idata *, heim_idata *, heim_icred *); | ||||
|  | ||||
| int | ||||
| heim_ipc_async(heim_ipc, const heim_idata *, void *, void (*func)(void *, int, heim_idata *, heim_icred)); | ||||
|  | ||||
| /* server */ | ||||
|  | ||||
| typedef void | ||||
| (*heim_ipc_complete)(heim_sipc_call, int, heim_idata *); | ||||
|  | ||||
| typedef void | ||||
| (*heim_ipc_callback)(void *, const heim_idata *, | ||||
| 		     const heim_icred, heim_ipc_complete, heim_sipc_call); | ||||
|  | ||||
|  | ||||
| int | ||||
| heim_sipc_launchd_mach_init(const char *, heim_ipc_callback, | ||||
| 			    void *, heim_sipc *); | ||||
|  | ||||
| void | ||||
| heim_sipc_timeout(time_t); | ||||
|  | ||||
| void | ||||
| heim_sipc_set_timeout_handler(void (*)(void)); | ||||
|  | ||||
| void | ||||
| heim_sipc_free_context(heim_sipc); | ||||
							
								
								
									
										66
									
								
								lib/ipc/heim_ipc.defs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								lib/ipc/heim_ipc.defs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| /* | ||||
|  * Copyright (c) 2009 Kungliga Tekniska H<>gskolan | ||||
|  * (Royal Institute of Technology, Stockholm, Sweden). | ||||
|  * All rights reserved. | ||||
|  * | ||||
|  * Portions Copyright (c) 2009 Apple Inc. All rights reserved. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions | ||||
|  * are met: | ||||
|  * | ||||
|  * 1. Redistributions of source code must retain the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer. | ||||
|  * | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer in the | ||||
|  *    documentation and/or other materials provided with the distribution. | ||||
|  * | ||||
|  * 3. Neither the name of the Institute nor the names of its contributors | ||||
|  *    may be used to endorse or promote products derived from this software | ||||
|  *    without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND | ||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE | ||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
|  * SUCH DAMAGE. | ||||
|  */ | ||||
|  | ||||
| #include <mach/std_types.defs> | ||||
| #include <mach/mach_types.defs> | ||||
|  | ||||
| type heim_ipc_message_inband_t = array [ * : 2048 ] of char; | ||||
| type heim_ipc_message_outband_t = array [] of char; | ||||
|  | ||||
| import "heim_ipc_types.h"; | ||||
|  | ||||
| subsystem mheim_ipc 1; | ||||
| userprefix mheim_ipc_; | ||||
| serverprefix mheim_do_; | ||||
|  | ||||
| routine call( | ||||
| 				server_port	: mach_port_t; | ||||
| 		ServerAuditToken client_creds	: audit_token_t; | ||||
| 		sreplyport	reply_port	: mach_port_make_send_once_t; | ||||
| 		in		requestin	: heim_ipc_message_inband_t; | ||||
| 		in		requestout	: heim_ipc_message_outband_t; | ||||
| 		out		returnvalue	: int; | ||||
| 		out		replyin		: heim_ipc_message_inband_t; | ||||
| 		out		replyout	: heim_ipc_message_outband_t, dealloc); | ||||
|  | ||||
| simpleroutine call_request( | ||||
| 				server_port	: mach_port_t; | ||||
| 		ServerAuditToken client_creds	: audit_token_t; | ||||
| 		in		reply_to	: mach_port_make_send_once_t; | ||||
| 		in		requestin	: heim_ipc_message_inband_t; | ||||
| 		in		requestout	: heim_ipc_message_outband_t); | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										56
									
								
								lib/ipc/heim_ipc_async.defs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								lib/ipc/heim_ipc_async.defs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| /* | ||||
|  * Copyright (c) 2009 Kungliga Tekniska H<>gskolan | ||||
|  * (Royal Institute of Technology, Stockholm, Sweden). | ||||
|  * All rights reserved. | ||||
|  * | ||||
|  * Portions Copyright (c) 2009 Apple Inc. All rights reserved. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions | ||||
|  * are met: | ||||
|  * | ||||
|  * 1. Redistributions of source code must retain the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer. | ||||
|  * | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer in the | ||||
|  *    documentation and/or other materials provided with the distribution. | ||||
|  * | ||||
|  * 3. Neither the name of the Institute nor the names of its contributors | ||||
|  *    may be used to endorse or promote products derived from this software | ||||
|  *    without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND | ||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE | ||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
|  * SUCH DAMAGE. | ||||
|  */ | ||||
|  | ||||
| #include <mach/std_types.defs> | ||||
| #include <mach/mach_types.defs> | ||||
|  | ||||
| type heim_ipc_message_inband_t = array [ * : 2048 ] of char; | ||||
| type heim_ipc_message_outband_t = array [] of char; | ||||
|  | ||||
| import "heim_ipc_types.h"; | ||||
|  | ||||
| subsystem mheim_aipc 201; | ||||
| userprefix mheim_aipc_; | ||||
| serverprefix mheim_ado_; | ||||
|  | ||||
| simpleroutine acall_reply( | ||||
| 				server_port	: mach_port_move_send_once_t; | ||||
| 		ServerAuditToken client_creds	: audit_token_t; | ||||
| 		in		returnvalue	: int; | ||||
| 		in		requestin	: heim_ipc_message_inband_t; | ||||
| 		in		requestout	: heim_ipc_message_outband_t); | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										51
									
								
								lib/ipc/heim_ipc_reply.defs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								lib/ipc/heim_ipc_reply.defs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| /* | ||||
|  * Copyright (c) 2009 Kungliga Tekniska H<>gskolan | ||||
|  * (Royal Institute of Technology, Stockholm, Sweden). | ||||
|  * All rights reserved. | ||||
|  * | ||||
|  * Portions Copyright (c) 2009 Apple Inc. All rights reserved. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions | ||||
|  * are met: | ||||
|  * | ||||
|  * 1. Redistributions of source code must retain the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer. | ||||
|  * | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer in the | ||||
|  *    documentation and/or other materials provided with the distribution. | ||||
|  * | ||||
|  * 3. Neither the name of the Institute nor the names of its contributors | ||||
|  *    may be used to endorse or promote products derived from this software | ||||
|  *    without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND | ||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE | ||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
|  * SUCH DAMAGE. | ||||
|  */ | ||||
|  | ||||
| #include <mach/std_types.defs> | ||||
| #include <mach/mach_types.defs> | ||||
|  | ||||
| type heim_ipc_message_inband_t = array [ * : 2048 ] of char; | ||||
| type heim_ipc_message_outband_t = array [] of char; | ||||
|  | ||||
| import "heim_ipc_types.h"; | ||||
|  | ||||
| subsystem heim_ipc 101; | ||||
| userprefix mheim_ripc_; | ||||
|  | ||||
| simpleroutine call_reply( | ||||
| 				reply_port	: mach_port_move_send_once_t; | ||||
| 				returnvalue	: int; | ||||
| 				replyin		: heim_ipc_message_inband_t; | ||||
| 				replyout	: heim_ipc_message_outband_t, dealloc); | ||||
							
								
								
									
										44
									
								
								lib/ipc/heim_ipc_types.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								lib/ipc/heim_ipc_types.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| /* | ||||
|  * Copyright (c) 2009 Kungliga Tekniska H<>gskolan | ||||
|  * (Royal Institute of Technology, Stockholm, Sweden). | ||||
|  * All rights reserved. | ||||
|  * | ||||
|  * Portions Copyright (c) 2009 Apple Inc. All rights reserved. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions | ||||
|  * are met: | ||||
|  * | ||||
|  * 1. Redistributions of source code must retain the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer. | ||||
|  * | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer in the | ||||
|  *    documentation and/or other materials provided with the distribution. | ||||
|  * | ||||
|  * 3. Neither the name of the Institute nor the names of its contributors | ||||
|  *    may be used to endorse or promote products derived from this software | ||||
|  *    without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND | ||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE | ||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
|  * SUCH DAMAGE. | ||||
|  */ | ||||
|  | ||||
| #ifndef _HEIM_IPC_TYPES_H_ | ||||
| #define _HEIM_IPC_TYPES_H_ | ||||
|  | ||||
| #define HEIM_KCM_BOOTSTRAP_NAME "org.h5l.Kerberos.kcm" | ||||
|  | ||||
| typedef char  heim_ipc_message_inband_t[2048]; | ||||
| typedef char *heim_ipc_message_outband_t; | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										54
									
								
								lib/ipc/hi_locl.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								lib/ipc/hi_locl.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | ||||
| /* | ||||
|  * Copyright (c) 2009 Kungliga Tekniska H<>gskolan | ||||
|  * (Royal Institute of Technology, Stockholm, Sweden). | ||||
|  * All rights reserved. | ||||
|  * | ||||
|  * Portions Copyright (c) 2009 Apple Inc. All rights reserved. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions | ||||
|  * are met: | ||||
|  * | ||||
|  * 1. Redistributions of source code must retain the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer. | ||||
|  * | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer in the | ||||
|  *    documentation and/or other materials provided with the distribution. | ||||
|  * | ||||
|  * 3. Neither the name of the Institute nor the names of its contributors | ||||
|  *    may be used to endorse or promote products derived from this software | ||||
|  *    without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND | ||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE | ||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
|  * SUCH DAMAGE. | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include <sys/types.h> | ||||
| #include <sys/un.h> | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <errno.h> | ||||
|  | ||||
| #include <krb5-types.h> | ||||
| #include <asn1-common.h> | ||||
|  | ||||
| #include <heim-ipc.h> | ||||
|  | ||||
| #include <roken.h> | ||||
|  | ||||
| int | ||||
| _heim_ipc_create_cred(uid_t, gid_t, pid_t, pid_t, heim_icred *); | ||||
							
								
								
									
										492
									
								
								lib/ipc/server.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										492
									
								
								lib/ipc/server.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,492 @@ | ||||
| /* | ||||
|  * Copyright (c) 2009 Kungliga Tekniska H<>gskolan | ||||
|  * (Royal Institute of Technology, Stockholm, Sweden). | ||||
|  * All rights reserved. | ||||
|  * | ||||
|  * Portions Copyright (c) 2009 Apple Inc. All rights reserved. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions | ||||
|  * are met: | ||||
|  * | ||||
|  * 1. Redistributions of source code must retain the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer. | ||||
|  * | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer in the | ||||
|  *    documentation and/or other materials provided with the distribution. | ||||
|  * | ||||
|  * 3. Neither the name of the Institute nor the names of its contributors | ||||
|  *    may be used to endorse or promote products derived from this software | ||||
|  *    without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND | ||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE | ||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
|  * SUCH DAMAGE. | ||||
|  */ | ||||
|  | ||||
| #include "hi_locl.h" | ||||
|  | ||||
| struct heim_sipc { | ||||
|     int (*release)(heim_sipc ctx); | ||||
|     heim_ipc_callback callback; | ||||
|     void *userctx; | ||||
|     void *mech; | ||||
| }; | ||||
|  | ||||
| #ifdef __APPLE__ | ||||
|  | ||||
| #include <mach/mach.h> | ||||
| #include <dispatch/dispatch.h> | ||||
| #include <bsm/libbsm.h> | ||||
| #include "heim_ipcServer.h" | ||||
| #include "heim_ipc_reply.h" | ||||
|  | ||||
| static dispatch_source_t timer; | ||||
| static dispatch_queue_t timerq; | ||||
| static uint64_t timeoutvalue; | ||||
|  | ||||
| static dispatch_queue_t workq; | ||||
|  | ||||
| static void | ||||
| default_timer_ev(void) | ||||
| { | ||||
|     exit(0); | ||||
| } | ||||
|  | ||||
| static void (*timer_ev)(void) = default_timer_ev; | ||||
|  | ||||
| static void | ||||
| set_timer(void) | ||||
| { | ||||
|     dispatch_source_set_timer(timer, | ||||
| 			      dispatch_time(DISPATCH_TIME_NOW, | ||||
| 					    timeoutvalue * NSEC_PER_SEC), | ||||
| 			      timeoutvalue * NSEC_PER_SEC, 1000000);  | ||||
| } | ||||
|  | ||||
| static void | ||||
| init_globals(void) | ||||
| { | ||||
|     static dispatch_once_t once; | ||||
|     dispatch_once(&once, ^{  | ||||
| 	timerq = dispatch_queue_create("hiem-sipc-timer-q", NULL); | ||||
|         timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, timerq); | ||||
| 	dispatch_source_set_event_handler(timer, ^{ timer_ev(); } ); | ||||
|  | ||||
| 	workq = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); | ||||
|     }); | ||||
| } | ||||
|  | ||||
| static void | ||||
| suspend_timer(void) | ||||
| { | ||||
|     dispatch_suspend(timer); | ||||
| } | ||||
|  | ||||
| static void | ||||
| restart_timer(void) | ||||
| { | ||||
|     dispatch_sync(timerq, ^{ set_timer(); }); | ||||
|     dispatch_resume(timer); | ||||
| } | ||||
|  | ||||
| struct mach_service { | ||||
|     mach_port_t sport; | ||||
|     dispatch_source_t source; | ||||
|     dispatch_queue_t queue; | ||||
| }; | ||||
|  | ||||
| struct mach_call_ctx { | ||||
|     mach_port_t reply_port; | ||||
|     heim_icred cred; | ||||
|     heim_idata req; | ||||
| }; | ||||
|  | ||||
|  | ||||
| static void | ||||
| mach_complete_sync(heim_sipc_call ctx, int returnvalue, heim_idata *reply) | ||||
| { | ||||
|     struct mach_call_ctx *s = (struct mach_call_ctx *)ctx; | ||||
|     heim_ipc_message_inband_t replyin; | ||||
|     mach_msg_type_number_t replyinCnt; | ||||
|     heim_ipc_message_outband_t replyout; | ||||
|     mach_msg_type_number_t replyoutCnt; | ||||
|     kern_return_t kr; | ||||
|  | ||||
|     if (returnvalue) { | ||||
| 	/* on error, no reply */ | ||||
| 	replyinCnt = 0; | ||||
| 	replyout = 0; replyoutCnt = 0; | ||||
| 	kr = KERN_SUCCESS; | ||||
|     } else if (reply->length < 2048) { | ||||
| 	replyinCnt = reply->length; | ||||
| 	memcpy(replyin, reply->data, replyinCnt); | ||||
| 	replyout = 0; replyoutCnt = 0; | ||||
| 	kr = KERN_SUCCESS; | ||||
|     } else { | ||||
| 	replyinCnt = 0; | ||||
| 	kr = vm_read(mach_task_self(),  | ||||
| 		     (vm_address_t)reply->data, reply->length, | ||||
| 		     (vm_address_t *)&replyout, &replyoutCnt); | ||||
|     } | ||||
|  | ||||
|     mheim_ripc_call_reply(s->reply_port, returnvalue, | ||||
| 			  replyin, replyinCnt, | ||||
| 			  replyout, replyoutCnt); | ||||
|  | ||||
|     heim_ipc_free_cred(s->cred); | ||||
|     free(s->req.data); | ||||
|     free(s); | ||||
|     restart_timer(); | ||||
| } | ||||
|  | ||||
| static void | ||||
| mach_complete_async(heim_sipc_call ctx, int returnvalue, heim_idata *reply) | ||||
| { | ||||
|     struct mach_call_ctx *s = (struct mach_call_ctx *)ctx; | ||||
|     heim_ipc_message_inband_t replyin; | ||||
|     mach_msg_type_number_t replyinCnt; | ||||
|     heim_ipc_message_outband_t replyout; | ||||
|     mach_msg_type_number_t replyoutCnt; | ||||
|     kern_return_t kr; | ||||
|  | ||||
|     if (returnvalue) { | ||||
| 	/* on error, no reply */ | ||||
| 	replyinCnt = 0; | ||||
| 	replyout = 0; replyoutCnt = 0; | ||||
| 	kr = KERN_SUCCESS; | ||||
|     } else if (reply->length < 2048) { | ||||
| 	replyinCnt = reply->length; | ||||
| 	memcpy(replyin, reply->data, replyinCnt); | ||||
| 	replyout = 0; replyoutCnt = 0; | ||||
| 	kr = KERN_SUCCESS; | ||||
|     } else { | ||||
| 	replyinCnt = 0; | ||||
| 	kr = vm_read(mach_task_self(),  | ||||
| 		     (vm_address_t)reply->data, reply->length, | ||||
| 		     (vm_address_t *)&replyout, &replyoutCnt); | ||||
|     } | ||||
|  | ||||
|     kr = mheim_aipc_acall_reply(s->reply_port, returnvalue, | ||||
| 				replyin, replyinCnt, | ||||
| 				replyout, replyoutCnt); | ||||
|     heim_ipc_free_cred(s->cred); | ||||
|     free(s->req.data); | ||||
|     free(s); | ||||
|     restart_timer(); | ||||
| } | ||||
|  | ||||
|  | ||||
| kern_return_t | ||||
| mheim_do_call(mach_port_t server_port, | ||||
| 	      audit_token_t client_creds, | ||||
| 	      mach_port_t reply_port, | ||||
| 	      heim_ipc_message_inband_t requestin, | ||||
| 	      mach_msg_type_number_t requestinCnt, | ||||
| 	      heim_ipc_message_outband_t requestout, | ||||
| 	      mach_msg_type_number_t requestoutCnt, | ||||
| 	      int *returnvalue, | ||||
| 	      heim_ipc_message_inband_t replyin, | ||||
| 	      mach_msg_type_number_t *replyinCnt, | ||||
| 	      heim_ipc_message_outband_t *replyout, | ||||
| 	      mach_msg_type_number_t *replyoutCnt) | ||||
| { | ||||
|     heim_sipc ctx = dispatch_get_context(dispatch_get_current_queue()); | ||||
|     struct mach_service *st = ctx->mech; | ||||
|     struct mach_call_ctx *s; | ||||
|     kern_return_t kr; | ||||
|     heim_icred cred; | ||||
|     uid_t uid; | ||||
|     gid_t gid; | ||||
|     pid_t pid; | ||||
|     au_asid_t session; | ||||
|  | ||||
|     *replyout = NULL; | ||||
|     *replyoutCnt = 0; | ||||
|     *replyinCnt = 0; | ||||
|  | ||||
|     s = malloc(sizeof(*s)); | ||||
|     if (s == NULL) | ||||
| 	return KERN_MEMORY_FAILURE; /* XXX */ | ||||
|      | ||||
|     s->reply_port = reply_port; | ||||
|      | ||||
|     audit_token_to_au32(client_creds, NULL, &uid, &gid, NULL, NULL, &pid, &session, NULL); | ||||
|      | ||||
|     kr = _heim_ipc_create_cred(uid, gid, pid, session, &s->cred); | ||||
|     if (kr) { | ||||
| 	free(s); | ||||
| 	return kr; | ||||
|     } | ||||
|      | ||||
|     suspend_timer(); | ||||
|      | ||||
|     if (requestinCnt) { | ||||
| 	s->req.data = malloc(requestinCnt); | ||||
| 	memcpy(s->req.data, requestin, requestinCnt); | ||||
| 	s->req.length = requestinCnt; | ||||
|     } else { | ||||
| 	s->req.data = malloc(requestoutCnt); | ||||
| 	memcpy(s->req.data, requestout, requestoutCnt); | ||||
| 	s->req.length = requestoutCnt; | ||||
|     } | ||||
|      | ||||
|     dispatch_async(workq, ^{ | ||||
| 	(ctx->callback)(ctx->userctx, &s->req, s->cred, | ||||
| 			mach_complete_sync, (heim_sipc_call)s); | ||||
|     }); | ||||
|  | ||||
|     return MIG_NO_REPLY; | ||||
| } | ||||
|  | ||||
| kern_return_t | ||||
| mheim_do_call_request(mach_port_t server_port, | ||||
| 		      audit_token_t client_creds, | ||||
| 		      mach_port_t reply_port, | ||||
| 		      heim_ipc_message_inband_t requestin, | ||||
| 		      mach_msg_type_number_t requestinCnt, | ||||
| 		      heim_ipc_message_outband_t requestout, | ||||
| 		      mach_msg_type_number_t requestoutCnt) | ||||
| { | ||||
|     heim_sipc ctx = dispatch_get_context(dispatch_get_current_queue()); | ||||
|     struct mach_service *st = ctx->mech; | ||||
|     struct mach_call_ctx *s; | ||||
|     kern_return_t kr; | ||||
|     heim_icred cred; | ||||
|     uid_t uid; | ||||
|     gid_t gid; | ||||
|     pid_t pid; | ||||
|     au_asid_t session; | ||||
|      | ||||
|     s = malloc(sizeof(*s)); | ||||
|     if (s == NULL) | ||||
| 	return KERN_MEMORY_FAILURE; /* XXX */ | ||||
|      | ||||
|     s->reply_port = reply_port; | ||||
|      | ||||
|     audit_token_to_au32(client_creds, NULL, &uid, &gid, NULL, NULL, &pid, &session, NULL); | ||||
|      | ||||
|     kr = _heim_ipc_create_cred(uid, gid, pid, session, &s->cred); | ||||
|     if (kr) { | ||||
| 	free(s); | ||||
| 	return kr; | ||||
|     } | ||||
|      | ||||
|     suspend_timer(); | ||||
|      | ||||
|     if (requestinCnt) { | ||||
| 	s->req.data = malloc(requestinCnt); | ||||
| 	memcpy(s->req.data, requestin, requestinCnt); | ||||
| 	s->req.length = requestinCnt; | ||||
|     } else { | ||||
| 	s->req.data = malloc(requestoutCnt); | ||||
| 	memcpy(s->req.data, requestout, requestoutCnt); | ||||
| 	s->req.length = requestoutCnt; | ||||
|     } | ||||
|      | ||||
|     dispatch_async(workq, ^{ | ||||
| 	(ctx->callback)(ctx->userctx, &s->req, s->cred, | ||||
| 			mach_complete_async, (heim_sipc_call)s); | ||||
|     }); | ||||
|      | ||||
|     return KERN_SUCCESS; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| static int | ||||
| mach_init(const char *service, mach_port_t sport, heim_sipc ctx) | ||||
| { | ||||
|     struct mach_service *s; | ||||
|     kern_return_t kr; | ||||
|     char *name; | ||||
|  | ||||
|     init_globals(); | ||||
|  | ||||
|     s = calloc(1, sizeof(*s)); | ||||
|     if (s == NULL) | ||||
| 	return ENOMEM; | ||||
|  | ||||
|     asprintf(&name, "heim-ipc-mach-%s", service); | ||||
|  | ||||
|     s->queue = dispatch_queue_create(name, NULL); | ||||
|     free(name); | ||||
|     s->sport = sport; | ||||
|  | ||||
|     s->source = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV,  | ||||
| 				       s->sport, 0, s->queue); | ||||
|     if (s->source == NULL) { | ||||
| 	dispatch_release(s->queue); | ||||
| 	free(s); | ||||
| 	return ENOMEM; | ||||
|     } | ||||
|     ctx->mech = s; | ||||
|  | ||||
|     dispatch_set_context(s->queue, ctx); | ||||
|     dispatch_set_context(s->source, s); | ||||
|  | ||||
|     dispatch_source_set_event_handler(s->source, ^{ | ||||
| 	    dispatch_mig_server(s->source, sizeof(union __RequestUnion__mheim_do_mheim_ipc_subsystem), mheim_ipc_server); | ||||
| 	}); | ||||
|  | ||||
|     dispatch_source_set_cancel_handler(s->source, ^{ | ||||
| 	    heim_sipc ctx = dispatch_get_context(dispatch_get_current_queue()); | ||||
| 	    struct mach_service *st = ctx->mech; | ||||
| 	    mach_port_mod_refs(mach_task_self(), st->sport,  | ||||
| 			       MACH_PORT_RIGHT_RECEIVE, -1); | ||||
| 	    dispatch_release(st->queue); | ||||
| 	    dispatch_release(st->source); | ||||
| 	    free(st); | ||||
| 	    free(ctx); | ||||
| 	}); | ||||
|  | ||||
|     dispatch_resume(s->source); | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static int | ||||
| mach_release(heim_sipc ctx) | ||||
| { | ||||
|     struct mach_service *s = ctx->mech; | ||||
|     dispatch_source_cancel(s->source); | ||||
|     dispatch_release(s->source); | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static mach_port_t | ||||
| mach_checkin_or_register(const char *service) | ||||
| { | ||||
|     mach_port_t mp; | ||||
|     kern_return_t kr; | ||||
|  | ||||
|     kr = bootstrap_check_in(bootstrap_port, service, &mp); | ||||
|     if (kr == KERN_SUCCESS) | ||||
| 	return mp; | ||||
|  | ||||
|     kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &mp); | ||||
|     if (kr != KERN_SUCCESS) | ||||
| 	return MACH_PORT_NULL; | ||||
|  | ||||
|     kr = mach_port_insert_right(mach_task_self(), mp, mp,  | ||||
| 				MACH_MSG_TYPE_MAKE_SEND); | ||||
|     if (kr != KERN_SUCCESS) { | ||||
| 	mach_port_destroy(mach_task_self(), mp); | ||||
| 	return MACH_PORT_NULL; | ||||
|     } | ||||
|  | ||||
|     kr = bootstrap_register(bootstrap_port, service, mp); | ||||
|     if (kr != KERN_SUCCESS) { | ||||
| 	mach_port_destroy(mach_task_self(), mp); | ||||
| 	return MACH_PORT_NULL; | ||||
|     } | ||||
|  | ||||
|     return mp; | ||||
| } | ||||
|  | ||||
|  | ||||
| #endif /* __APPLE__ */ | ||||
|  | ||||
| int | ||||
| heim_sipc_launchd_mach_init(const char *service, | ||||
| 			    heim_ipc_callback callback, | ||||
| 			    void *user, heim_sipc *ctx) | ||||
| { | ||||
| #ifdef __APPLE__ | ||||
|     mach_port_t sport = MACH_PORT_NULL; | ||||
|     heim_sipc c; | ||||
|     int ret; | ||||
|  | ||||
|     *ctx = NULL; | ||||
|  | ||||
|     sport = mach_checkin_or_register(service); | ||||
|     if (sport == MACH_PORT_NULL) { | ||||
| 	ret = ENOENT; | ||||
| 	goto error; | ||||
|     } | ||||
|  | ||||
|     c = calloc(1, sizeof(*c)); | ||||
|     if (c == NULL) { | ||||
| 	ret = ENOMEM; | ||||
| 	goto error; | ||||
|     } | ||||
|     c->release = mach_release; | ||||
|     c->userctx = user; | ||||
|     c->callback = callback; | ||||
| 		  | ||||
|     ret = mach_init(service, sport, c); | ||||
|     if (ret) | ||||
| 	goto error; | ||||
|  | ||||
|     *ctx = c; | ||||
|     return 0; | ||||
|  error: | ||||
|     if (c) | ||||
| 	free(c); | ||||
|     if (sport != MACH_PORT_NULL) | ||||
| 	mach_port_mod_refs(mach_task_self(), sport,  | ||||
| 			   MACH_PORT_RIGHT_RECEIVE, -1); | ||||
|     return ret; | ||||
| #else | ||||
|     *ctx = NULL; | ||||
|     return EINVAL; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Set the idle timeout value | ||||
|  | ||||
|  * The timeout event handler is triggered recurrently every idle | ||||
|  * period `t'. The default action is rather draconian and just calls | ||||
|  * exit(0), so you might want to change this to something more | ||||
|  * graceful using heim_sipc_set_timeout_handler(). | ||||
|  */ | ||||
|  | ||||
| void | ||||
| heim_sipc_timeout(time_t t) | ||||
| { | ||||
| #if __APPLE__ | ||||
|     static dispatch_once_t timeoutonce; | ||||
|     init_globals(); | ||||
|     dispatch_sync(timerq, ^{ | ||||
| 	    timeoutvalue = t; | ||||
| 	    set_timer(); | ||||
| 	}); | ||||
|     dispatch_once(&timeoutonce, ^{  dispatch_resume(timer); }); | ||||
| #else | ||||
|     abort(); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Set the timeout event handler | ||||
|  * | ||||
|  * Replaces the default idle timeout action. | ||||
|  */ | ||||
|  | ||||
| void | ||||
| heim_sipc_set_timeout_handler(void (*func)(void)) | ||||
| { | ||||
| #ifdef __APPLE__ | ||||
|     init_globals(); | ||||
|     dispatch_sync(timerq, ^{ timer_ev = func; }); | ||||
| #else | ||||
|     abort(); | ||||
| #endif | ||||
| } | ||||
|  | ||||
|  | ||||
| void | ||||
| heim_sipc_free_context(heim_sipc ctx) | ||||
| { | ||||
|     (ctx->release)(ctx); | ||||
| } | ||||
							
								
								
									
										82
									
								
								lib/ipc/tc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								lib/ipc/tc.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | ||||
| /* | ||||
|  * Copyright (c) 2009 Kungliga Tekniska H<>gskolan | ||||
|  * (Royal Institute of Technology, Stockholm, Sweden). | ||||
|  * All rights reserved. | ||||
|  * | ||||
|  * Portions Copyright (c) 2009 Apple Inc. All rights reserved. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions | ||||
|  * are met: | ||||
|  * | ||||
|  * 1. Redistributions of source code must retain the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer. | ||||
|  * | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer in the | ||||
|  *    documentation and/or other materials provided with the distribution. | ||||
|  * | ||||
|  * 3. Neither the name of the Institute nor the names of its contributors | ||||
|  *    may be used to endorse or promote products derived from this software | ||||
|  *    without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND | ||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE | ||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
|  * SUCH DAMAGE. | ||||
|  */ | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <krb5-types.h> | ||||
| #include <asn1-common.h> | ||||
| #include <heim-ipc.h> | ||||
| #include <err.h> | ||||
|  | ||||
|  | ||||
| static void | ||||
| reply(void *ctx, int errorcode, heim_idata *reply, heim_icred cred) | ||||
| { | ||||
|     printf("got reply\n"); | ||||
|     heim_ipc_semaphore_signal((heim_isemaphore)ctx); /* tell caller we are done */ | ||||
| } | ||||
|  | ||||
| int | ||||
| main(int argc, char **argv) | ||||
| { | ||||
|     heim_isemaphore s; | ||||
|     heim_idata req, rep; | ||||
|     heim_ipc ipc; | ||||
|     int ret; | ||||
|  | ||||
|     ret = heim_ipc_init_context("ANY:org.h5l.test-ipc", &ipc); | ||||
|     if (ret) | ||||
| 	errx(1, "heim_ipc_init_context: %d", ret); | ||||
|  | ||||
|     req.length = 0; | ||||
|     req.data = NULL; | ||||
|      | ||||
|     ret = heim_ipc_call(ipc, &req, &rep, NULL); | ||||
|     if (ret) | ||||
| 	errx(1, "heim_ipc_call: %d", ret); | ||||
|      | ||||
|     s = heim_ipc_semaphore_create(0); | ||||
|     if (s == NULL) | ||||
| 	errx(1, "heim_ipc_semaphore_create"); | ||||
|  | ||||
|     ret = heim_ipc_async(ipc, &req, s, reply); | ||||
|     if (ret) | ||||
| 	errx(1, "heim_ipc_async: %d", ret); | ||||
|  | ||||
|     heim_ipc_semaphore_wait(s, HEIM_IPC_WAIT_FOREVER); /* wait for reply to complete the work */ | ||||
|  | ||||
|     heim_ipc_free_context(ipc); | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										67
									
								
								lib/ipc/ts.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								lib/ipc/ts.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
| /* | ||||
|  * Copyright (c) 2009 Kungliga Tekniska H<>gskolan | ||||
|  * (Royal Institute of Technology, Stockholm, Sweden). | ||||
|  * All rights reserved. | ||||
|  * | ||||
|  * Portions Copyright (c) 2009 Apple Inc. All rights reserved. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions | ||||
|  * are met: | ||||
|  * | ||||
|  * 1. Redistributions of source code must retain the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer. | ||||
|  * | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer in the | ||||
|  *    documentation and/or other materials provided with the distribution. | ||||
|  * | ||||
|  * 3. Neither the name of the Institute nor the names of its contributors | ||||
|  *    may be used to endorse or promote products derived from this software | ||||
|  *    without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND | ||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE | ||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
|  * SUCH DAMAGE. | ||||
|  */ | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <krb5-types.h> | ||||
| #include <heim-ipc.h> | ||||
|  | ||||
| static void | ||||
| test_service(void *ctx, const heim_idata *req, | ||||
| 	     const heim_icred cred, | ||||
| 	     heim_ipc_complete complete, | ||||
| 	     heim_sipc_call cctx) | ||||
| { | ||||
|     heim_idata rep; | ||||
|     printf("got request\n"); | ||||
|     rep.length = 0; | ||||
|     rep.data = NULL; | ||||
|     (*complete)(cctx, 0, &rep); | ||||
| } | ||||
|  | ||||
|  | ||||
| int | ||||
| main(int argc, char **argv) | ||||
| { | ||||
| #if __APPLE__ | ||||
|     { | ||||
| 	heim_sipc mach; | ||||
| 	heim_sipc_launchd_mach_init("org.h5l.test-ipc", | ||||
| 				    test_service, NULL, &mach); | ||||
|     } | ||||
| #endif | ||||
|     heim_ipc_main(); | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Love Hornquist Astrand
					Love Hornquist Astrand