1/*- 2 * Copyright (c) 2013 Kungliga Tekniska Högskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Portions Copyright (c) 2013 Apple Inc. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#include <CoreFoundation/CoreFoundation.h> 31#include <CoreFoundation/CFRuntime.h> 32#include <CoreFoundation/CFXPCBridge.h> 33#include <xpc/xpc.h> 34 35#include "common.h" 36 37 38 39#define HEIMCRED_CONST(_t,_c) \ 40 const _t _c = (_t)CFSTR(#_c); \ 41 const char *_c##xpc = #_c 42 43#include "heimcred-const.h" 44 45/* 46 * auth 47 */ 48 49HEIMCRED_CONST(CFTypeRef, kHEIMTargetName); 50 51#undef HEIMCRED_CONST 52 53/* 54 * 55 */ 56 57HeimCredContext HeimCredCTX; 58 59/* 60 * 61 */ 62 63CFUUIDRef 64HeimCredCopyUUID(xpc_object_t object, const char *key) 65{ 66 CFUUIDBytes bytes; 67 const void *data = xpc_dictionary_get_uuid(object, key); 68 if (data == NULL) 69 return NULL; 70 memcpy(&bytes, data, sizeof(bytes)); 71 return CFUUIDCreateFromUUIDBytes(NULL, bytes); 72} 73 74CFTypeRef 75HeimCredMessageCopyAttributes(xpc_object_t object, const char *key, CFTypeID type) 76{ 77 xpc_object_t xpcattrs = xpc_dictionary_get_value(object, key); 78 CFTypeRef item; 79 if (xpcattrs == NULL) 80 return NULL; 81 item = _CFXPCCreateCFObjectFromXPCObject(xpcattrs); 82 if (item && CFGetTypeID(item) != type) { 83 CFRelease(item); 84 item = NULL; 85 } 86 return item; 87} 88 89void 90HeimCredMessageSetAttributes(xpc_object_t object, const char *key, CFTypeRef attrs) 91{ 92 xpc_object_t xpcattrs = _CFXPCCreateXPCObjectFromCFObject(attrs); 93 if (xpcattrs == NULL) 94 return; 95 xpc_dictionary_set_value(object, key, xpcattrs); 96 xpc_release(xpcattrs); 97} 98 99 100void 101HeimCredSetUUID(xpc_object_t object, const char *key, CFUUIDRef uuid) 102{ 103 CFUUIDBytes bytes = CFUUIDGetUUIDBytes(uuid); 104 uuid_t u; 105 memcpy(&u, &bytes, sizeof(u)); 106 xpc_dictionary_set_uuid(object, key, u); 107} 108 109static CFStringRef 110HeimCredCopyFormatString(CFTypeRef cf, CFDictionaryRef formatOptions) 111{ 112 return CFSTR("format"); 113} 114 115static CFStringRef 116HeimCredCopyDebugName(CFTypeRef cf) 117{ 118 HeimCredRef cred = (HeimCredRef)cf; 119 if (cred->attributes) { 120 CFTypeRef client = CFDictionaryGetValue(cred->attributes, kHEIMAttrClientName); 121 CFTypeRef server = CFDictionaryGetValue(cred->attributes, kHEIMAttrServerName); 122 CFTypeRef parent = CFDictionaryGetValue(cred->attributes, kHEIMAttrParentCredential); 123 CFTypeRef group = CFDictionaryGetValue(cred->attributes, kHEIMAttrLeadCredential); 124 125 int lead = group ? CFBooleanGetValue(group) : false; 126 CFTypeRef acl = CFDictionaryGetValue(cred->attributes, kHEIMAttrBundleIdentifierACL); 127 return CFStringCreateWithFormat(NULL, NULL, CFSTR("HeimCred<%@ group: %@ parent: %@ client: %@ server: %@ lead: %s ACL: %@>"), 128 cred->uuid, group, parent, client, server, lead ? "yes" : "no", acl ? acl : CFSTR("")); 129 } else { 130 return CFStringCreateWithFormat(NULL, NULL, CFSTR("HeimCred<%@>"), cred->uuid); 131 } 132} 133 134static void 135HeimCredReleaseItem(CFTypeRef item) 136{ 137 HeimCredRef cred = (HeimCredRef)item; 138 CFRELEASE_NULL(cred->uuid); 139 CFRELEASE_NULL(cred->attributes); 140} 141 142void 143_HeimCredInitCommon(void) 144{ 145 static dispatch_once_t once; 146 147 dispatch_once(&once, ^{ 148 static const CFRuntimeClass HeimCredClass = { 149 0, 150 "HeimCredential", 151 NULL, 152 NULL, 153 HeimCredReleaseItem, 154 NULL, 155 NULL, 156 HeimCredCopyFormatString, 157 HeimCredCopyDebugName 158 }; 159 HeimCredCTX.haid = _CFRuntimeRegisterClass(&HeimCredClass); 160 161 HeimCredCTX.queue = dispatch_queue_create("HeimCred", NULL); 162 163#if HEIMCRED_SERVER 164 HeimCredCTX.sessions = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 165#else 166 HeimCredCTX.items = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 167#endif 168 }); 169} 170 171CFTypeID 172HeimCredGetTypeID(void) 173{ 174 _HeimCredInitCommon(); 175 return HeimCredCTX.haid; 176} 177 178 179HeimCredRef 180HeimCredCreateItem(CFUUIDRef uuid) 181{ 182 HeimCredRef cred = (HeimCredRef)_CFRuntimeCreateInstance(NULL, HeimCredCTX.haid, sizeof(struct HeimCred_s) - sizeof(CFRuntimeBase), NULL); 183 if (cred == NULL) 184 return NULL; 185 186 CFRetain(uuid); 187 cred->uuid = uuid; 188 return cred; 189} 190 191