]> git.saurik.com Git - apple/security.git/blob - OSX/sec/SOSCircle/IDSKeychainSyncingProxy/IDSPersistentState.m
Security-57337.50.23.tar.gz
[apple/security.git] / OSX / sec / SOSCircle / IDSKeychainSyncingProxy / IDSPersistentState.m
1 /*
2 * Copyright (c) 2012-2014 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 // IDSPersistentState.m
26 // idskeychainsyncingproxy
27 //
28
29 #import <Security/Security.h>
30 #import <Foundation/NSPropertyList.h>
31 #import <Foundation/NSArray.h>
32 #import <Foundation/NSPropertyList.h>
33 #import <Foundation/NSData.h>
34 #import <Foundation/NSDictionary.h>
35 #import <utilities/debugging.h>
36 #import <utilities/SecFileLocations.h>
37
38 #import "IDSPersistentState.h"
39
40 #if ! __has_feature(objc_arc)
41 #error This file must be compiled with ARC. Either turn on ARC for the project or use -fobjc-arc flag
42 #endif
43
44 static CFStringRef kRegistrationFileName = CFSTR("com.apple.security.idskeychainsyncingproxy.unhandledMessages.plist");
45
46 @implementation IDSKeychainSyncingProxyPersistentState
47
48 + (BOOL)write:(NSURL *)path data:(id)plist error:(NSError **)error
49 {
50 if (![NSPropertyListSerialization propertyList: plist isValidForFormat: NSPropertyListXMLFormat_v1_0])
51 {
52 secerror("can't save PersistentState as XML");
53 return false;
54 }
55
56 NSData *data = [NSPropertyListSerialization dataWithPropertyList: plist
57 format: NSPropertyListXMLFormat_v1_0 options: 0 error: error];
58 if (data == nil)
59 {
60 secerror("error serializing PersistentState to xml: %@", *error);
61 return false;
62 }
63
64 BOOL writeStatus = [data writeToURL: path options: NSDataWritingAtomic error: error];
65 if (!writeStatus)
66 secerror("error writing PersistentState to file: %@", *error);
67
68 return writeStatus;
69 }
70
71 + (id)read: (NSURL *)path error:(NSError **)error
72 {
73 NSData *data = [NSData dataWithContentsOfURL: path options: 0 error: error];
74 if (data == nil)
75 {
76 secdebug("unhandledmessages", "error reading PersistentState from %@: %@", path, *error);
77 return nil;
78 }
79
80 // Now the deserializing:
81
82 NSPropertyListFormat format;
83 id plist = [NSPropertyListSerialization propertyListWithData: data
84 options: NSPropertyListMutableContainersAndLeaves format: &format error: error];
85
86 if (plist == nil)
87 secerror("could not deserialize PersistentState from %@: %@", path, *error);
88
89 return plist;
90 }
91
92 + (NSURL *)registrationFileURL
93 {
94 return (NSURL *)CFBridgingRelease(SecCopyURLForFileInPreferencesDirectory(kRegistrationFileName));
95 }
96
97 + (NSString *)dictionaryDescription: (NSDictionary *)state
98 {
99 NSMutableArray *elements = [NSMutableArray array];
100 [state enumerateKeysAndObjectsUsingBlock: ^(NSString *key, id obj, BOOL *stop) {
101 [elements addObject: [key stringByAppendingString: @":"]];
102 if ([obj isKindOfClass:[NSArray class]]) {
103 [elements addObject: [(NSArray *)obj componentsJoinedByString: @" "]];
104 } else {
105 [elements addObject: [NSString stringWithFormat:@"%@", obj]];
106 }
107 }];
108 return [elements componentsJoinedByString: @" "];
109 }
110
111 + (NSMutableDictionary *)unhandledMessages
112 {
113 NSError *error = NULL;
114 id stateDictionary = [IDSKeychainSyncingProxyPersistentState read:[[self class] registrationFileURL] error:&error];
115 secdebug("keyregister", "Read registeredKeys: <%@>", [self dictionaryDescription: stateDictionary]);
116 // Ignore older states with an NSArray
117 if (![stateDictionary isKindOfClass:[NSDictionary class]])
118 return NULL;
119 return [NSMutableDictionary dictionaryWithDictionary:stateDictionary];
120 }
121
122 + (void)setUnhandledMessages: (NSDictionary *)unhandledMessages
123 {
124 NSError *error = NULL;
125 secdebug("keyregister", "Write registeredKeys: <%@>", [self dictionaryDescription: unhandledMessages]);
126 [IDSKeychainSyncingProxyPersistentState write:[[self class] registrationFileURL] data:unhandledMessages error:&error];
127 }
128
129 @end