]> git.saurik.com Git - apple/security.git/blob - OSX/sec/ProjectHeaders/Security/SecureObjectSync/SOSViewManager.c
Security-57336.1.9.tar.gz
[apple/security.git] / OSX / sec / ProjectHeaders / Security / SecureObjectSync / SOSViewManager.c
1 /*
2 * Copyright (c) 2015 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /*
25 * SOSViewManager.c - Implementation of a view manager
26 */
27
28 #include <Security/SecureObjectSync/SOSViewManager.h>
29 #include <Security/SecureObjectSync/SOSInternal.h>
30
31 #if 0
32 /* SOSViewManager implementation. */
33 struct __OpaqueSOSViewManager {
34 CFRuntimeBase _base;
35 CFMutableDictionaryRef views;
36 };
37
38 const CFStringRef kSOSContextChildInfoKey = CFSTR("cntx");
39 const CFStringRef kSOSFunctionChildInfoKey = CFSTR("fctn");
40 const CFStringRef kSOSViewNamesChildInfoKey = CFSTR("vwns");
41
42
43 static CFStringRef SOSViewManagerCopyFormatDescription(CFTypeRef cf, CFDictionaryRef formatOptions) {
44 SOSViewManagerRef vmgr = (SOSViewManagerRef)cf;
45 CFStringRef desc = CFStringCreateWithFormat(kCFAllocatorDefault, formatOptions, CFSTR("<ViewManager %@ >"), vmgr->views);
46 return desc;
47 }
48
49 static void SOSViewManagerDestroy(CFTypeRef cf) {
50 SOSViewManagerRef vmgr = (SOSViewManagerRef)cf;
51 CFReleaseSafe(vmgr->views);
52 }
53
54 CFGiblisFor(SOSViewManager);
55
56
57 static SOSViewManagerRef SOSViewManagerCreate(CFAllocatorRef allocator, CFErrorRef *error) {
58 SOSViewManagerRef vmgr = NULL;
59 vmgr = CFTypeAllocate(SOSViewManager, struct __OpaqueSOSViewManager, allocator);
60 if (vmgr)
61 vmgr->views = CFDictionaryCreateMutableForCFTypes(allocator);
62 return vmgr;
63 }
64
65 CFGiblisGetSingleton(SOSViewManagerRef, SOSGetViewManager, sSOSViewManager, ^{
66 *sSOSViewManager = SOSViewManagerCreate(kCFAllocatorDefault, NULL);
67 });
68
69
70 static CFStringRef CFStringCreateWithViewNames(CFArrayRef viewNames) {
71 CFIndex count = CFArrayGetCount(viewNames);
72 CFMutableArrayRef mvn = CFArrayCreateMutableCopy(kCFAllocatorDefault, count, viewNames);
73 CFArraySortValues(mvn, CFRangeMake(0, count), (CFComparatorFunction)CFStringCompare, 0);
74 CFStringRef string = CFStringCreateByCombiningStrings(kCFAllocatorDefault, mvn, CFSTR(":"));
75 CFRelease(mvn);
76 return string;
77 }
78
79 static SOSViewRef SOSViewManangerCopyViewWithName(SOSViewManagerRef vmgr, CFMutableDictionaryRef referencedViews, CFStringRef viewName, bool isConcrete, CFErrorRef *error) {
80 SOSViewRef view = (SOSViewRef)CFDictionaryGetValue(vmgr->views, viewName);
81 if (view) {
82 if (isConcrete)
83 SOSViewSetConcrete(view, true);
84 CFRetain(view);
85 } else {
86 view = SOSViewCreate(CFGetAllocator(vmgr), isConcrete, NULL, error);
87 if (view) {
88 CFDictionarySetValue(vmgr->views, viewName, view);
89 }
90 // TODO: Query for the initial manifest.
91 }
92 if (view) {
93 if (isConcrete)
94 CFDictionarySetValue(referencedViews, viewName, kCFBooleanTrue);
95 else if (!CFDictionaryContainsKey(referencedViews, viewName))
96 CFDictionarySetValue(referencedViews, viewName, kCFBooleanFalse);
97 }
98 return view;
99 }
100
101 static SOSViewRef SOSViewManangerCopyCompositeViewWithNames(SOSViewManagerRef vmgr, CFMutableDictionaryRef referencedViews, CFArrayRef viewNames, CFErrorRef *error) {
102 CFStringRef compositeName = CFStringCreateWithViewNames(viewNames);
103 SOSViewRef compositeView = (SOSViewRef)CFDictionaryGetValue(vmgr->views, compositeName);
104 if (compositeView) {
105 CFDictionarySetValue(referencedViews, compositeName, kCFBooleanTrue);
106 CFRetain(compositeView);
107 } else {
108 compositeView = SOSViewCreate(CFGetAllocator(vmgr), true, NULL, error);
109 if (compositeView) {
110 // Find the views for each name, and add the new view as a child to each one.
111 CFStringRef viewName;
112 CFArrayForEachC(viewNames, viewName) {
113 SOSViewRef parent = SOSViewManangerCopyViewWithName(vmgr, referencedViews, viewName, false, error);
114 if (!parent) {
115 CFReleaseNull(compositeView);
116 break;
117 }
118 SOSViewAddChild(parent, compositeView);
119 // Update the composite view's manifest by adding each parents manifest.
120 // TODO: Potentially move this out of the loop and create a single multi way manifest union operation
121 SOSManifestRef pmf = SOSViewCopyManifest(parent, error);
122 SOSViewUpdateManifest(compositeView, kSOSDataSourceSOSTransaction, NULL, pmf, error);
123 CFReleaseSafe(pmf);
124 }
125 CFDictionarySetValue(vmgr->views, viewName, compositeView);
126 }
127 }
128 CFReleaseSafe(compositeName);
129 return compositeView;
130 }
131
132 static bool SOSViewManangerAddChildWithInfo(SOSViewManagerRef vmgr, CFMutableDictionaryRef referencedViews, CFDictionaryRef childInfo, CFErrorRef *error) {
133 CFArrayRef viewNames = (CFArrayRef)CFDictionaryGetValue(childInfo, kSOSViewNamesChildInfoKey);
134 // const void *context = (const void *)CFDictionaryGetValue(childInfo, kSOSContextChildInfoKey);
135 // const void *func = (const void *)CFDictionaryGetValue(childInfo, kSOSFunctionChildInfoKey);
136
137 CFIndex count = CFArrayGetCount(viewNames);
138 if (count == 1) {
139 CFStringRef key = CFArrayGetValueAtIndex(viewNames, 0);
140 SOSViewRef view = SOSViewManangerCopyViewWithName(vmgr, referencedViews, key, true, error);
141 // TODO: Fix this...
142 //SOSViewAddClient(view, context, func);
143 if (view) count++; // TODO: REMOVE MOVE -- HERE ONLY FOR COMPILER WARNING
144 } else if (count > 1) {
145 SOSViewRef view = SOSViewManangerCopyCompositeViewWithNames(vmgr, referencedViews, viewNames, error);
146 // TODO: Fix this...
147 //SOSViewAddClient(view, context, func);
148 if (view) count++; // TODO: REMOVE MOVE -- HERE ONLY FOR COMPILER WARNING
149 }
150
151 return true;
152 }
153
154 struct SOSViewManagerContext {
155 SOSViewManagerRef vmgr;
156 CFDictionaryRef referencedViews;
157 };
158
159 static void SOSViewManagerUpdateView(const void *key, const void *value, void *context) {
160 struct SOSViewManagerContext *vmc = context;
161 CFBooleanRef isConcrete = CFDictionaryGetValue(vmc->referencedViews, key);
162 if (!isConcrete) {
163 CFDictionaryRemoveValue(vmc->vmgr->views, key);
164 } else if (CFBooleanGetValue(isConcrete) == 0) {
165 SOSViewRef view = (SOSViewRef)CFDictionaryGetValue(vmc->vmgr->views, key);
166 SOSViewSetConcrete(view, false);
167 }
168 }
169
170 bool SOSViewManagerSetChildren(SOSViewManagerRef vmgr, CFArrayRef children, CFErrorRef *error) {
171 bool ok = true;
172 CFMutableDictionaryRef referencedViews = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
173 CFDictionaryRef childInfo;
174 CFArrayForEachC(children, childInfo) {
175 ok &= SOSViewManangerAddChildWithInfo(vmgr, referencedViews, childInfo, error);
176 }
177
178 // Potentially populate all views here.
179
180 // Cleanup, remove any views we no longer reference, and set any views which need not be concrete as such.
181 struct SOSViewManagerContext vmc = {
182 .vmgr = vmgr,
183 .referencedViews = referencedViews,
184 };
185 CFDictionaryApplyFunction(vmgr->views, SOSViewManagerUpdateView, &vmc);
186 CFRetainSafe(referencedViews);
187
188 return ok;
189 }
190 #endif