]> git.saurik.com Git - apple/security.git/blob - keychain/analytics/SecC2DeviceInfo.m
Security-59306.11.20.tar.gz
[apple/security.git] / keychain / analytics / SecC2DeviceInfo.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 "SecC2DeviceInfo.h"
25
26 #import <os/variant_private.h>
27 #import <CoreFoundation/CFPriv.h>
28 #import <os/log.h>
29 #if TARGET_OS_IPHONE
30 #import <MobileGestalt.h>
31 #else
32 #import <sys/sysctl.h>
33 #endif
34
35 static NSString* C2MetricBuildVersion(void);
36 static NSString* C2MetricProductName(void);
37 static NSString* C2MetricProductType(void);
38 static NSString* C2MetricProductVersion(void);
39 static NSString* C2MetricProcessName(void);
40 static NSString* C2MetricProcessVersion(void);
41 static NSString* C2MetricProcessUUID(void);
42
43 @implementation SecC2DeviceInfo
44
45 + (BOOL) isAppleInternal {
46 return os_variant_has_internal_content("com.apple.security.analytics");
47 }
48
49 + (NSString*) buildVersion {
50 return C2MetricBuildVersion();
51 }
52
53 + (NSString*) productName {
54 return C2MetricProductName();
55 }
56
57 + (NSString*) productType {
58 return C2MetricProductType();
59 }
60
61 + (NSString*) productVersion {
62 return C2MetricProductVersion();
63 }
64
65 + (NSString*) processName {
66 return C2MetricProcessName();
67 }
68
69 + (NSString*) processVersion {
70 return C2MetricProcessVersion();
71 }
72
73 + (NSString*) processUUID {
74 return C2MetricProcessUUID();
75 }
76
77 @end
78
79 /* Stolen without remorse from CloudKit. */
80
81 #pragma mark - NSBundleInfoDictionary Constants
82
83 static NSDictionary *processInfoDict() {
84 static NSDictionary *processInfoDict = nil;
85 static dispatch_once_t onceToken;
86 dispatch_once(&onceToken, ^{
87 NSBundle *processBundle = [NSBundle mainBundle];
88 processInfoDict = [processBundle infoDictionary];
89 });
90 return processInfoDict;
91 }
92
93 static NSString* C2MetricProcessName() {
94 return processInfoDict()[(NSString *)kCFBundleIdentifierKey];
95 }
96
97 static NSString* C2MetricProcessVersion() {
98 return processInfoDict()[(NSString *)_kCFBundleShortVersionStringKey];
99 }
100
101 static NSString* C2MetricProcessUUID() {
102 static NSString* processUUIDString;
103 static dispatch_once_t onceToken;
104 dispatch_once(&onceToken, ^{
105 processUUIDString = [[NSUUID UUID] UUIDString];
106 });
107 return processUUIDString;
108 }
109
110 #pragma mark - MobileGestalt Constants
111
112 #if TARGET_OS_IPHONE
113
114 static NSMutableDictionary* _CKCachedGestaltValues = nil;
115
116 static NSArray* _CKCachedLockdownKeys() {
117 return @[(NSString *)kMGQUniqueDeviceID,
118 (NSString *)kMGQBuildVersion,
119 (NSString *)kMGQProductName,
120 (NSString *)kMGQProductType,
121 (NSString *)kMGQProductVersion];
122 }
123
124 static NSDictionary* _CKGetCachedGestaltValues() {
125 static dispatch_once_t pred;
126 dispatch_once(&pred, ^{
127 _CKCachedGestaltValues = [[NSMutableDictionary alloc] initWithCapacity:0];
128
129 for (NSString *key in _CKCachedLockdownKeys()) {
130 NSString *value = CFBridgingRelease(MGCopyAnswer((__bridge CFStringRef)key, NULL));
131 if (value) {
132 _CKCachedGestaltValues[key] = value;
133 } else {
134 os_log(OS_LOG_DEFAULT, "Error getting %@ from MobileGestalt", key);
135 }
136 }
137 });
138 return _CKCachedGestaltValues;
139 }
140
141 static NSString* _CKGetCachedGestaltValue(NSString *key) {
142 return _CKGetCachedGestaltValues()[key];
143 }
144
145 static NSString* C2MetricBuildVersion() {
146 return _CKGetCachedGestaltValue((NSString *)kMGQBuildVersion);
147 }
148
149 static NSString* C2MetricProductName() {
150 return _CKGetCachedGestaltValue((NSString *)kMGQProductName);
151 }
152
153 static NSString* C2MetricProductType() {
154 return _CKGetCachedGestaltValue((NSString *)kMGQProductType);
155 }
156
157 static NSString* C2MetricProductVersion() {
158 return _CKGetCachedGestaltValue((NSString *)kMGQProductVersion);
159 }
160
161 #else
162
163 static CFStringRef CKCopySysctl(int mib[2]) {
164 char sysctlString[128];
165 size_t len = sizeof(sysctlString);
166
167 // add the system product
168 if (sysctl(mib, 2, sysctlString, &len, 0, 0) >= 0) {
169 return CFStringCreateWithCString(kCFAllocatorDefault, sysctlString, kCFStringEncodingUTF8);
170 }
171
172 return NULL;
173 }
174
175 static NSDictionary* systemVersionDict() {
176 static NSDictionary *sysVers = nil;
177 static dispatch_once_t onceToken;
178 dispatch_once(&onceToken, ^{
179 sysVers = (__bridge NSDictionary *)_CFCopySystemVersionDictionary();
180 });
181 return sysVers;
182 }
183
184 static NSString* C2MetricBuildVersion() {
185 return systemVersionDict()[(NSString *)_kCFSystemVersionBuildVersionKey];
186 }
187
188 static NSString* C2MetricProductName() {
189 return systemVersionDict()[(NSString *)_kCFSystemVersionProductNameKey];
190 }
191
192 static NSString* C2MetricProductType() {
193 static dispatch_once_t onceToken;
194 static NSString *productType = nil;
195 dispatch_once(&onceToken, ^{
196 productType = (__bridge NSString *)CKCopySysctl((int[2]) { CTL_HW, HW_MODEL });
197 });
198 return productType;
199 }
200
201 static NSString* C2MetricProductVersion() {
202 return systemVersionDict()[(NSString *)_kCFSystemVersionProductVersionKey];
203 }
204
205 #endif