]> git.saurik.com Git - apple/security.git/blob - keychain/behavior/SFBehavior.m
Security-59306.140.5.tar.gz
[apple/security.git] / keychain / behavior / SFBehavior.m
1 /*
2 * Copyright (c) 2017 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 #import "SFBehavior.h"
25 #import <dispatch/dispatch.h>
26
27 #if __OBJC2__
28
29 @interface SFBehavior ()
30 @property NSString *family;
31 @property NSXPCConnection *connection;
32 - (instancetype)initBehaviorFamily:(NSString *)family connection:(NSXPCConnection *)connection;
33 @end
34
35 @protocol SFBehaviorProtocol <NSObject>
36 - (void)ramping:(NSString *)feature family:(NSString*)family complete:(void (^)(SFBehaviorRamping))complete;
37 - (void)feature:(NSString *)feature family:(NSString*)family defaultValue:(bool)defaultValue complete:(void (^)(bool))complete;
38
39 - (void)configNumber:(NSString *)configuration family:(NSString*)family complete:(void (^)(NSNumber *))complete;
40 - (void)configString:(NSString *)configuration family:(NSString*)family complete:(void (^)(NSString *))complete;
41 @end
42
43
44 @implementation SFBehavior
45
46 + (SFBehavior *)behaviorFamily:(NSString *)family
47 {
48 static dispatch_once_t onceToken = 0;
49 static NSMutableDictionary<NSString *, SFBehavior *> *behaviors;
50 static NSXPCConnection *connection = NULL;
51 dispatch_once(&onceToken, ^{
52 behaviors = [NSMutableDictionary dictionary];
53 connection = [[NSXPCConnection alloc] initWithMachServiceName:@"com.apple.security.behavior" options:NSXPCConnectionPrivileged];
54
55 connection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(SFBehaviorProtocol)];
56 [connection resume];
57 });
58
59 SFBehavior *behavior = nil;
60 @synchronized (behaviors) {
61 behavior = behaviors[family];
62 if (behavior == NULL) {
63 behavior = [[SFBehavior alloc] initBehaviorFamily:family connection:connection];
64 behaviors[family] = behavior;
65 }
66 }
67
68 return behavior;
69 }
70
71 - (instancetype)initBehaviorFamily:(NSString *)family connection:(NSXPCConnection *)connection
72 {
73 self = [super init];
74 if (self) {
75 _family = family;
76 _connection = connection;
77 }
78 return self;
79 }
80
81 - (SFBehaviorRamping)ramping:(NSString *)feature force:(bool)force
82 {
83 __block SFBehaviorRamping _ramping = SFBehaviorRampingDisabled;
84 [[_connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) {
85 }] ramping:feature family:_family complete:^(SFBehaviorRamping ramping) {
86 _ramping = ramping;
87 }];
88 return _ramping;
89 }
90
91 - (bool)feature:(NSString *)feature defaultValue:(bool)defaultValue
92 {
93 __block bool enabled = defaultValue;
94
95 [[_connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) {
96 }] feature:feature family:_family defaultValue:defaultValue complete:^(bool returnFeature) {
97 enabled = returnFeature;
98 }];
99 return enabled;
100
101 }
102
103 - (bool)featureEnabled:(NSString *)feature
104 {
105 return [self feature:feature defaultValue:true];
106 }
107
108 - (bool)featureDisabled:(NSString *)feature
109 {
110 return ![self feature:feature defaultValue:false];
111 }
112
113 - (NSNumber *)configurationNumber:(NSString *)configuration defaultValue:(NSNumber *)defaultValue
114 {
115 __block NSNumber *_number = defaultValue;
116
117 [[_connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) {
118 }] configNumber:configuration family:_family complete:^(NSNumber *number) {
119 if (number)
120 _number = number;
121 }];
122 return _number;
123 }
124
125 - (NSString *)configurationString:(NSString *)configuration defaultValue:(NSString *)defaultValue
126 {
127 __block NSString *_string = defaultValue;
128
129 [[_connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) {
130 }] configString:configuration family:_family complete:^(NSString *string) {
131 if (string)
132 _string = string;
133 }];
134 return _string;
135 }
136
137 @end
138
139 #endif /* __OBJC2__ */
140