]> git.saurik.com Git - apple/security.git/blob - keychain/ot/OTFollowup.m
Security-59306.11.20.tar.gz
[apple/security.git] / keychain / ot / OTFollowup.m
1 /*
2 * Copyright (c) 2019 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 #if OCTAGON
25
26 #import "OTFollowup.h"
27
28 #if __has_include(<CoreFollowUp/CoreFollowUp.h>) && !TARGET_OS_SIMULATOR
29 #import <CoreFollowUp/CoreFollowUp.h>
30 #define HAVE_COREFOLLOW_UP 1
31 #endif
32
33 #undef HAVE_COREFOLLOW_UP // XXX
34
35 #import <CoreCDP/CDPFollowUpController.h>
36 #import <CoreCDP/CDPFollowUpContext.h>
37
38 #include "utilities/debugging.h"
39
40 static NSString * const kOTFollowupEventCompleteKey = @"OTFollowupContextType";
41
42 @interface OTFollowup()
43 @property id<OctagonFollowUpControllerProtocol> cdpd;
44 @property NSTimeInterval previousFollowupEnd;
45 @property NSTimeInterval followupStart;
46 @property NSTimeInterval followupEnd;
47 @end
48
49 @implementation OTFollowup : NSObject
50
51 - (id)initWithFollowupController:(id<OctagonFollowUpControllerProtocol>)cdpFollowupController
52 {
53 if (self = [super init]) {
54 self.cdpd = cdpFollowupController;
55 }
56 return self;
57 }
58
59 - (CDPFollowUpContext *)createCDPFollowupContext:(OTFollowupContextType)contextType
60 {
61 switch (contextType) {
62 case OTFollowupContextTypeStateRepair: {
63 return [CDPFollowUpContext contextForStateRepair];
64 }
65 case OTFollowupContextTypeRecoveryKeyRepair: {
66 return [CDPFollowUpContext contextForRecoveryKeyRepair];
67 }
68 case OTFollowupContextTypeOfflinePasscodeChange: {
69 return [CDPFollowUpContext contextForOfflinePasscodeChange];
70 }
71 default: {
72 return nil;
73 }
74 }
75 }
76
77 - (BOOL)postFollowUp:(OTFollowupContextType)contextType
78 error:(NSError **)error
79 {
80 CDPFollowUpContext *context = [self createCDPFollowupContext:contextType];
81 if (!context) {
82 return NO;
83 }
84
85 NSError *followupError = nil;
86 BOOL result = [self.cdpd postFollowUpWithContext:context error:&followupError];
87 if (error) {
88 *error = followupError;
89 }
90
91 return result;
92 }
93
94 - (BOOL)clearFollowUp:(OTFollowupContextType)contextType
95 error:(NSError **)error
96 {
97 // Note(caw): we don't track metrics for clearing CFU prompts.
98 CDPFollowUpContext *context = [self createCDPFollowupContext:contextType];
99 if (!context) {
100 return NO;
101 }
102
103 return [self.cdpd clearFollowUpWithContext:context error:error];
104 }
105
106
107 - (NSDictionary *)sysdiagnoseStatus
108 {
109 NSMutableDictionary *pendingCFUs = nil;
110
111 #if HAVE_COREFOLLOW_UP
112 if ([FLFollowUpController class]) {
113 NSError *error = nil;
114 pendingCFUs = [NSMutableDictionary dictionary];
115
116 FLFollowUpController *followUpController = [[FLFollowUpController alloc] initWithClientIdentifier:@"com.apple.corecdp"];
117 NSArray <FLFollowUpItem*>* followUps = [followUpController pendingFollowUpItems:&error];
118 if (error) {
119 secnotice("octagon", "Fetching pending follow ups failed with: %@", error);
120 pendingCFUs[@"error"] = [error description];
121 }
122 for (FLFollowUpItem *followUp in followUps) {
123 NSDate *creationDate = followUp.notification.creationDate;
124 pendingCFUs[followUp.uniqueIdentifier] = creationDate;
125 }
126 }
127 #endif
128 return pendingCFUs;
129 }
130
131 - (NSDictionary<NSString*,NSNumber *> *)sfaStatus {
132 NSMutableDictionary<NSString*, NSNumber*>* values = [NSMutableDictionary dictionary];
133 #if HAVE_COREFOLLOW_UP
134 if ([FLFollowUpController class]) {
135 NSError *error = nil;
136
137 //pretend to be CDP
138 FLFollowUpController *followUpController = [[FLFollowUpController alloc] initWithClientIdentifier:@"com.apple.corecdp"];
139
140 NSArray <FLFollowUpItem*>* followUps = [followUpController pendingFollowUpItems:&error];
141 if (error) {
142 secnotice("octagon", "Fetching pending follow ups failed with: %@", error);
143 }
144 for (FLFollowUpItem *followUp in followUps) {
145 NSInteger created = 10000;
146
147 NSDate *creationDate = followUp.notification.creationDate;
148 if (creationDate) {
149 created = [CKKSAnalytics fuzzyDaysSinceDate:creationDate];
150 }
151 NSString *key = [NSString stringWithFormat:@"OACFU-%@", followUp.uniqueIdentifier];
152 values[key] = @(created);
153 }
154 }
155 #endif
156 return values;
157 }
158
159
160 @end
161
162 #endif // OCTAGON