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