]> git.saurik.com Git - apple/security.git/blob - sec/securityd/Regressions/secd-05-corrupted-items.c
Security-55471.tar.gz
[apple/security.git] / sec / securityd / Regressions / secd-05-corrupted-items.c
1 //
2 // secd-05-corrupted-item.c
3 // sec
4 //
5 // Created by Fabrice Gautier on 06/26/13.
6 //
7 //
8
9 #include "secd_regressions.h"
10
11 #include <securityd/SecDbItem.h>
12 #include <utilities/array_size.h>
13 #include <utilities/SecCFWrappers.h>
14 #include <utilities/SecFileLocations.h>
15 #include <utilities/fileIo.h>
16
17 #include <securityd/SOSCloudCircleServer.h>
18 #include <securityd/SecItemServer.h>
19
20 #include <Security/SecBasePriv.h>
21
22 #include <AssertMacros.h>
23
24 #include <stdio.h>
25 #include <unistd.h>
26 #include <sys/stat.h>
27 #include <pthread.h>
28
29 #include "SecdTestKeychainUtilities.h"
30
31 #define N_ITEMS (100)
32 #define N_THREADS (10)
33 #define N_ADDS (20)
34
35 static void *do_add(void *arg)
36 {
37 int tid=(int)(arg);
38
39 for(int i=0;i<N_ADDS;i++) {
40 /* Creating a password */
41 SInt32 v_eighty = (tid+1)*1000+i;
42 CFNumberRef eighty = CFNumberCreate(NULL, kCFNumberSInt32Type, &v_eighty);
43 const char *v_data = "test";
44 CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data));
45 const void *keys[] = {
46 kSecClass,
47 kSecAttrServer,
48 kSecAttrAccount,
49 kSecAttrPort,
50 kSecAttrProtocol,
51 kSecAttrAuthenticationType,
52 kSecValueData
53 };
54 const void *values[] = {
55 kSecClassInternetPassword,
56 CFSTR("members.spamcop.net"),
57 CFSTR("smith"),
58 eighty,
59 CFSTR("http"),
60 CFSTR("dflt"),
61 pwdata
62 };
63
64 CFDictionaryRef item = CFDictionaryCreate(NULL, keys, values,
65 array_size(keys), NULL, NULL);
66
67 ok_status(SecItemAdd(item, NULL), "add internet password");
68 }
69
70 return NULL;
71 }
72
73
74 int secd_05_corrupted_items(int argc, char *const *argv)
75 {
76 plan_tests(1 + N_THREADS*(N_ADDS+1) + N_ITEMS*4 + kSecdTestSetupTestCount);
77
78 /* custom keychain dir */
79 secd_test_setup_temp_keychain("secd_05_corrupted_items", NULL);
80
81 /* add a password */
82 const char *v_data = "test";
83 CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data));
84 CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
85 CFDictionaryAddValue(query, kSecClass, kSecClassInternetPassword);
86 CFDictionaryAddValue(query, kSecAttrServer, CFSTR("corrupt.spamcop.net"));
87 CFDictionaryAddValue(query, kSecAttrAccount, CFSTR("smith"));
88 CFDictionaryAddValue(query, kSecAttrProtocol, kSecAttrProtocolHTTP);
89 CFDictionaryAddValue(query, kSecAttrAuthenticationType, kSecAttrAuthenticationTypeDefault);
90 CFDictionaryAddValue(query, kSecValueData, pwdata);
91
92 SInt32 i;
93 for(i=1; i<=N_ITEMS; i++) {
94 CFNumberRef port = CFNumberCreate(NULL, kCFNumberSInt32Type, &i);
95 CFDictionarySetValue(query, kSecAttrPort, port);
96 ok_status(SecItemAdd(query, NULL), "add internet password");
97 CFReleaseNull(port);
98 }
99
100 /* corrupt all the password */
101 CFStringRef keychain_path_cf = __SecKeychainCopyPath();
102
103 CFStringPerformWithCString(keychain_path_cf, ^(const char *keychain_path) {
104 /* Create a new keychain sqlite db */
105 sqlite3 *db;
106
107 is(sqlite3_open(keychain_path, &db), SQLITE_OK, "open keychain");
108
109 char corrupt_item_sql[80];
110 for(int i=1;i<=N_ITEMS;i++) {
111 ok_unix(snprintf(corrupt_item_sql, sizeof(corrupt_item_sql), "UPDATE inet SET data=X'12345678' WHERE rowid=%d", i));
112 is(sqlite3_exec(db, corrupt_item_sql, NULL, NULL, NULL), SQLITE_OK, "corrupting keychain item");
113 }
114 });
115
116 /* start the adder threads */
117 pthread_t add_thread[N_THREADS];
118 void *add_err[N_THREADS] = {NULL,};
119
120 for(int i=0; i<N_THREADS; i++)
121 pthread_create(&add_thread[i], NULL, do_add, (void*)(intptr_t)i);
122
123 /* query the corrupted items */
124 CFDictionaryAddValue(query, kSecReturnPersistentRef, kCFBooleanTrue);
125 for(int i=1;i<=N_ITEMS;i++) {
126 CFTypeRef ref = NULL;
127 CFNumberRef port = CFNumberCreate(NULL, kCFNumberSInt32Type, &i);
128 CFDictionarySetValue(query, kSecAttrPort, port);
129 is_status(SecItemCopyMatching(query, &ref), errSecItemNotFound, "Item not found");
130 CFReleaseNull(port);
131 CFReleaseNull(ref);
132 }
133
134 /* collect the adder threads */
135 for(int i=0; i<N_THREADS; i++)
136 pthread_join(add_thread[i], &add_err[i]);
137
138 for(int i=0; i<N_THREADS; i++)
139 ok(add_err[i]==NULL, "add thread");
140
141
142 CFReleaseNull(query);
143
144 return 0;
145 }