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#import <CoreFoundation/CoreFoundation.h> 31#import <CoreFoundation/CFRuntime.h> 32#import <CoreFoundation/CFXPCBridge.h> 33#import <xpc/xpc.h> 34 35#import "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 74CFDictionaryRef 75HeimCredMessageCopyAttributes(xpc_object_t object, const char *key) 76{ 77 xpc_object_t xpcattrs = xpc_dictionary_get_value(object, key); 78 if (xpcattrs == NULL) 79 return NULL; 80 return _CFXPCCreateCFObjectFromXPCObject(xpcattrs); 81} 82 83void 84HeimCredMessageSetAttributes(xpc_object_t object, const char *key, CFTypeRef attrs) 85{ 86 xpc_object_t xpcattrs = _CFXPCCreateXPCObjectFromCFObject(attrs); 87 if (xpcattrs == NULL) 88 return; 89 xpc_dictionary_set_value(object, key, xpcattrs); 90 xpc_release(xpcattrs); 91} 92 93 94void 95HeimCredSetUUID(xpc_object_t object, const char *key, CFUUIDRef uuid) 96{ 97 CFUUIDBytes bytes = CFUUIDGetUUIDBytes(uuid); 98 uuid_t u; 99 memcpy(&u, &bytes, sizeof(u)); 100 xpc_dictionary_set_uuid(object, key, u); 101} 102 103static CFStringRef 104HeimCredCopyFormatString(CFTypeRef cf, CFDictionaryRef formatOptions) 105{ 106 return CFSTR("format"); 107} 108 109static CFStringRef 110HeimCredCopyDebugName(CFTypeRef cf) 111{ 112 HeimCredRef cred = (HeimCredRef)cf; 113 CFTypeRef client = CFDictionaryGetValue(cred->attributes, kHEIMAttrClientName); 114 CFTypeRef server = CFDictionaryGetValue(cred->attributes, kHEIMAttrServerName); 115 CFTypeRef group = CFDictionaryGetValue(cred->attributes, kHEIMAttrCredentialGroup); 116 CFTypeRef parent = CFDictionaryGetValue(cred->attributes, kHEIMAttrParentCredential); 117 CFTypeRef lead = CFDictionaryGetValue(cred->attributes, kHEIMAttrCredentialGroupLead); 118 CFTypeRef acl = CFDictionaryGetValue(cred->attributes, kHEIMAttrBundleIdentifierACL); 119 return CFStringCreateWithFormat(NULL, NULL, CFSTR("HeimCred<%@ group: %@ parent: %@ client: %@ server: %@ lead: %s ACL: %@>"), 120 cred->uuid, group, parent, client, server, lead ? "yes" : "no", acl ? acl : CFSTR("")); 121} 122 123static void 124HeimCredReleaseItem(CFTypeRef item) 125{ 126 HeimCredRef cred = (HeimCredRef)item; 127 CFRELEASE_NULL(cred->uuid); 128 CFRELEASE_NULL(cred->attributes); 129} 130 131void 132_HeimCredInitCommon(void) 133{ 134 static dispatch_once_t once; 135 136 dispatch_once(&once, ^{ 137 static const CFRuntimeClass HeimCredClass = { 138 0, 139 "HeimCredential", 140 NULL, 141 NULL, 142 HeimCredReleaseItem, 143 NULL, 144 NULL, 145 HeimCredCopyFormatString, 146 HeimCredCopyDebugName 147 }; 148 HeimCredCTX.haid = _CFRuntimeRegisterClass(&HeimCredClass); 149 150 HeimCredCTX.queue = dispatch_queue_create("HeimCred", NULL); 151 HeimCredCTX.items = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 152 }); 153} 154 155 156HeimCredRef 157HeimCredCreateItem(CFUUIDRef uuid) 158{ 159 HeimCredRef cred = (HeimCredRef)_CFRuntimeCreateInstance(NULL, HeimCredCTX.haid, sizeof(struct HeimCred_s) - sizeof(CFRuntimeBase), NULL); 160 if (cred == NULL) 161 return NULL; 162 163 CFRetain(uuid); 164 cred->uuid = uuid; 165 return cred; 166} 167 168