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