]>
Commit | Line | Data |
---|---|---|
d8f41ccd A |
1 | /* |
2 | * Copyright (c) 2013-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 | ||
e3d460c9 A |
24 | /* |
25 | * This is to fool os services to not provide the Keychain manager | |
26 | * interface tht doens't work since we don't have unified headers | |
27 | * between iOS and OS X. rdar://23405418/ | |
28 | */ | |
29 | #define __KEYCHAINCORE__ 1 | |
30 | ||
427c49bc | 31 | |
e3d460c9 | 32 | #import "secd_regressions.h" |
427c49bc | 33 | |
e3d460c9 A |
34 | #import <Foundation/Foundation.h> |
35 | #import <securityd/SecDbItem.h> | |
36 | #import <utilities/array_size.h> | |
37 | #import <utilities/SecCFWrappers.h> | |
38 | #import <utilities/SecFileLocations.h> | |
39 | #import <utilities/fileIo.h> | |
427c49bc | 40 | |
e3d460c9 A |
41 | #import <securityd/SOSCloudCircleServer.h> |
42 | #import <securityd/SecItemServer.h> | |
427c49bc | 43 | |
e3d460c9 | 44 | #import <Security/SecBasePriv.h> |
427c49bc | 45 | |
e3d460c9 | 46 | #import <AssertMacros.h> |
427c49bc | 47 | |
e3d460c9 A |
48 | #import <stdio.h> |
49 | #import <unistd.h> | |
50 | #import <sys/stat.h> | |
51 | #import <pthread.h> | |
427c49bc | 52 | |
e3d460c9 | 53 | #import "SecdTestKeychainUtilities.h" |
427c49bc A |
54 | |
55 | #define N_ITEMS (100) | |
56 | #define N_THREADS (10) | |
57 | #define N_ADDS (20) | |
58 | ||
59 | static void *do_add(void *arg) | |
60 | { | |
61 | int tid=(int)(arg); | |
62 | ||
63 | for(int i=0;i<N_ADDS;i++) { | |
64 | /* Creating a password */ | |
65 | SInt32 v_eighty = (tid+1)*1000+i; | |
66 | CFNumberRef eighty = CFNumberCreate(NULL, kCFNumberSInt32Type, &v_eighty); | |
67 | const char *v_data = "test"; | |
68 | CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data)); | |
69 | const void *keys[] = { | |
70 | kSecClass, | |
71 | kSecAttrServer, | |
72 | kSecAttrAccount, | |
73 | kSecAttrPort, | |
74 | kSecAttrProtocol, | |
75 | kSecAttrAuthenticationType, | |
76 | kSecValueData | |
77 | }; | |
78 | const void *values[] = { | |
79 | kSecClassInternetPassword, | |
80 | CFSTR("members.spamcop.net"), | |
81 | CFSTR("smith"), | |
82 | eighty, | |
83 | CFSTR("http"), | |
84 | CFSTR("dflt"), | |
85 | pwdata | |
86 | }; | |
87 | ||
88 | CFDictionaryRef item = CFDictionaryCreate(NULL, keys, values, | |
89 | array_size(keys), NULL, NULL); | |
90 | ||
91 | ok_status(SecItemAdd(item, NULL), "add internet password"); | |
5c19dc3a A |
92 | CFReleaseNull(eighty); |
93 | CFReleaseNull(pwdata); | |
94 | CFReleaseNull(item); | |
427c49bc A |
95 | } |
96 | ||
97 | return NULL; | |
98 | } | |
99 | ||
100 | ||
101 | int secd_05_corrupted_items(int argc, char *const *argv) | |
102 | { | |
103 | plan_tests(1 + N_THREADS*(N_ADDS+1) + N_ITEMS*4 + kSecdTestSetupTestCount); | |
104 | ||
105 | /* custom keychain dir */ | |
106 | secd_test_setup_temp_keychain("secd_05_corrupted_items", NULL); | |
107 | ||
108 | /* add a password */ | |
109 | const char *v_data = "test"; | |
110 | CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data)); | |
111 | CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, NULL, NULL); | |
112 | CFDictionaryAddValue(query, kSecClass, kSecClassInternetPassword); | |
113 | CFDictionaryAddValue(query, kSecAttrServer, CFSTR("corrupt.spamcop.net")); | |
114 | CFDictionaryAddValue(query, kSecAttrAccount, CFSTR("smith")); | |
115 | CFDictionaryAddValue(query, kSecAttrProtocol, kSecAttrProtocolHTTP); | |
116 | CFDictionaryAddValue(query, kSecAttrAuthenticationType, kSecAttrAuthenticationTypeDefault); | |
117 | CFDictionaryAddValue(query, kSecValueData, pwdata); | |
118 | ||
119 | SInt32 i; | |
120 | for(i=1; i<=N_ITEMS; i++) { | |
121 | CFNumberRef port = CFNumberCreate(NULL, kCFNumberSInt32Type, &i); | |
122 | CFDictionarySetValue(query, kSecAttrPort, port); | |
123 | ok_status(SecItemAdd(query, NULL), "add internet password"); | |
124 | CFReleaseNull(port); | |
125 | } | |
126 | ||
427c49bc | 127 | |
e3d460c9 A |
128 | |
129 | SecKeychainDbReset(^{ | |
130 | /* corrupt all the password */ | |
fa7225c8 | 131 | NSString *keychain_path = CFBridgingRelease(__SecKeychainCopyPath()); |
e3d460c9 | 132 | char corrupt_item_sql[80]; |
427c49bc A |
133 | sqlite3 *db; |
134 | ||
e3d460c9 | 135 | is(sqlite3_open([keychain_path UTF8String], &db), SQLITE_OK, "open keychain"); |
427c49bc | 136 | |
427c49bc A |
137 | for(int i=1;i<=N_ITEMS;i++) { |
138 | ok_unix(snprintf(corrupt_item_sql, sizeof(corrupt_item_sql), "UPDATE inet SET data=X'12345678' WHERE rowid=%d", i)); | |
139 | is(sqlite3_exec(db, corrupt_item_sql, NULL, NULL, NULL), SQLITE_OK, "corrupting keychain item"); | |
140 | } | |
141 | }); | |
142 | ||
143 | /* start the adder threads */ | |
144 | pthread_t add_thread[N_THREADS]; | |
145 | void *add_err[N_THREADS] = {NULL,}; | |
146 | ||
147 | for(int i=0; i<N_THREADS; i++) | |
148 | pthread_create(&add_thread[i], NULL, do_add, (void*)(intptr_t)i); | |
149 | ||
150 | /* query the corrupted items */ | |
151 | CFDictionaryAddValue(query, kSecReturnPersistentRef, kCFBooleanTrue); | |
152 | for(int i=1;i<=N_ITEMS;i++) { | |
153 | CFTypeRef ref = NULL; | |
154 | CFNumberRef port = CFNumberCreate(NULL, kCFNumberSInt32Type, &i); | |
155 | CFDictionarySetValue(query, kSecAttrPort, port); | |
156 | is_status(SecItemCopyMatching(query, &ref), errSecItemNotFound, "Item not found"); | |
157 | CFReleaseNull(port); | |
158 | CFReleaseNull(ref); | |
159 | } | |
160 | ||
161 | /* collect the adder threads */ | |
162 | for(int i=0; i<N_THREADS; i++) | |
163 | pthread_join(add_thread[i], &add_err[i]); | |
164 | ||
165 | for(int i=0; i<N_THREADS; i++) | |
166 | ok(add_err[i]==NULL, "add thread"); | |
167 | ||
5c19dc3a | 168 | CFReleaseNull(pwdata); |
427c49bc | 169 | CFReleaseNull(query); |
427c49bc A |
170 | return 0; |
171 | } |