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