]> git.saurik.com Git - apple/security.git/blob - OSX/sec/SOSCircle/SecureObjectSync/SOSAccountGetSet.c
397b5051cdcc90fd359ecb65c7bdcf8baed9a782
[apple/security.git] / OSX / sec / SOSCircle / SecureObjectSync / SOSAccountGetSet.c
1 //
2 // SOSAccountGetSet.c
3 // Security
4 //
5 //
6
7 #include "SOSAccountPriv.h"
8
9 #include <utilities/SecCFWrappers.h>
10
11 //
12 // MARK: Generic Value manipulation
13 //
14
15 static inline bool SOSAccountEnsureExpansion(SOSAccountRef account, CFErrorRef *error) {
16 if (!account->expansion) {
17 account->expansion = CFDictionaryCreateMutableForCFTypes(NULL);
18 }
19
20 return SecAllocationError(account->expansion, error, CFSTR("Can't Alloc Account Expansion dictionary"));
21 }
22
23 bool SOSAccountClearValue(SOSAccountRef account, CFStringRef key, CFErrorRef *error) {
24 bool success = SOSAccountEnsureExpansion(account, error);
25 require_quiet(success, errOut);
26
27 CFDictionaryRemoveValue(account->expansion, key);
28 errOut:
29 return success;
30 }
31
32 bool SOSAccountSetValue(SOSAccountRef account, CFStringRef key, CFTypeRef value, CFErrorRef *error) {
33 if (value == NULL) return SOSAccountClearValue(account, key, error);
34
35 bool success = SOSAccountEnsureExpansion(account, error);
36 require_quiet(success, errOut);
37
38 CFDictionarySetValue(account->expansion, key, value);
39 errOut:
40 return success;
41 }
42
43 CFTypeRef SOSAccountGetValue(SOSAccountRef account, CFStringRef key, CFErrorRef *error) {
44 if (!account->expansion) {
45 return NULL;
46 }
47 return CFDictionaryGetValue(account->expansion, key);
48 }
49
50
51 //
52 // MARK: Value as Set manipulation
53 //
54 bool SOSAccountValueSetContainsValue(SOSAccountRef account, CFStringRef key, CFTypeRef value);
55 void SOSAccountValueUnionWith(SOSAccountRef account, CFStringRef key, CFSetRef valuesToUnion);
56 void SOSAccountValueSubtractFrom(SOSAccountRef account, CFStringRef key, CFSetRef valuesToSubtract);
57
58 bool SOSAccountValueSetContainsValue(SOSAccountRef account, CFStringRef key, CFTypeRef value) {
59 CFSetRef foundSet = asSet(SOSAccountGetValue(account, key, NULL), NULL);
60 return foundSet && CFSetContainsValue(foundSet, value);
61 }
62
63 void SOSAccountValueUnionWith(SOSAccountRef account, CFStringRef key, CFSetRef valuesToUnion) {
64 CFMutableSetRef unionedSet = CFSetCreateMutableCopy(kCFAllocatorDefault, 0, valuesToUnion);
65 CFSetRef foundSet = asSet(SOSAccountGetValue(account, key, NULL), NULL);
66 if (foundSet) {
67 CFSetUnion(unionedSet, foundSet);
68 }
69 SOSAccountSetValue(account, key, unionedSet, NULL);
70 CFReleaseNull(unionedSet);
71 }
72
73 void SOSAccountValueSubtractFrom(SOSAccountRef account, CFStringRef key, CFSetRef valuesToSubtract) {
74 CFSetRef foundSet = asSet(SOSAccountGetValue(account, key, NULL), NULL);
75 if (foundSet) {
76 CFMutableSetRef subtractedSet = CFSetCreateMutableCopy(kCFAllocatorDefault, 0, foundSet);
77 CFSetSubtract(subtractedSet, valuesToSubtract);
78 SOSAccountSetValue(account, key, subtractedSet, NULL);
79 CFReleaseNull(subtractedSet);
80 }
81 }
82
83 //
84 // MARK: UUID
85 CFStringRef SOSAccountCopyUUID(SOSAccountRef account) {
86 CFStringRef uuid = CFRetainSafe(asString(SOSAccountGetValue(account, kSOSAccountUUID, NULL), NULL));
87 if (uuid == NULL) {
88 CFUUIDRef newID = CFUUIDCreate(kCFAllocatorDefault);
89 uuid = CFUUIDCreateString(kCFAllocatorDefault, newID);
90
91 CFErrorRef setError = NULL;
92 if (!SOSAccountSetValue(account, kSOSAccountUUID, uuid, &setError)) {
93 secerror("Failed to set UUID: %@ (%@)", uuid, setError);
94 }
95 CFReleaseNull(setError);
96 CFReleaseNull(newID);
97 }
98 return uuid;
99 }
100
101 void SOSAccountEnsureUUID(SOSAccountRef account) {
102 CFStringRef uuid = SOSAccountCopyUUID(account);
103 CFReleaseNull(uuid);
104 }
105