2 // secd-04-corrupted-item.c
5 // Created by Fabrice Gautier on 06/19/13.
9 #include "secd_regressions.h"
11 #include <securityd/SecDbItem.h>
12 #include <utilities/SecCFWrappers.h>
13 #include <utilities/SecFileLocations.h>
14 #include <utilities/fileIo.h>
16 #include <securityd/SOSCloudCircleServer.h>
17 #include <securityd/SecItemServer.h>
19 #include <Security/SecBasePriv.h>
21 #include <AssertMacros.h>
28 #include "SecdTestKeychainUtilities.h"
30 /* Corrupt 1st and 3rd item */
31 static const char *corrupt_item_sql
= "UPDATE inet SET data=X'12345678' WHERE rowid=1 OR rowid=3";
33 int secd_04_corrupted_items(int argc
, char *const *argv
)
35 plan_tests(11 + kSecdTestSetupTestCount
);
37 /* custom keychain dir */
38 secd_test_setup_temp_keychain("secd_04_corrupted_items", NULL
);
41 CFTypeRef ref1
= NULL
;
43 CFNumberRef eighty
= CFNumberCreate(NULL
, kCFNumberSInt32Type
, &v_eighty
);
44 const char *v_data
= "test";
45 CFDataRef pwdata
= CFDataCreate(NULL
, (UInt8
*)v_data
, strlen(v_data
));
46 CFMutableDictionaryRef query
= CFDictionaryCreateMutable(NULL
, 0, NULL
, NULL
);
47 CFDictionaryAddValue(query
, kSecClass
, kSecClassInternetPassword
);
48 CFDictionaryAddValue(query
, kSecAttrServer
, CFSTR("corrupt.spamcop.net"));
49 CFDictionaryAddValue(query
, kSecAttrAccount
, CFSTR("smith"));
50 CFDictionaryAddValue(query
, kSecAttrPort
, eighty
);
51 CFDictionaryAddValue(query
, kSecAttrProtocol
, kSecAttrProtocolHTTP
);
52 CFDictionaryAddValue(query
, kSecAttrAuthenticationType
, kSecAttrAuthenticationTypeDefault
);
53 CFDictionaryAddValue(query
, kSecValueData
, pwdata
);
54 CFDictionaryAddValue(query
, kSecReturnPersistentRef
, kCFBooleanTrue
);
55 ok_status(SecItemAdd(query
, &ref1
), "add internet password port 80");
58 CFTypeRef ref2
= NULL
;
59 int v_eighty_one
= 81;
60 CFNumberRef eighty_one
= CFNumberCreate(NULL
, kCFNumberSInt32Type
, &v_eighty_one
);
61 CFDictionarySetValue(query
, kSecAttrPort
, eighty_one
);
62 ok_status(SecItemAdd(query
, &ref2
), "add internet password port 81");
65 CFTypeRef ref3
= NULL
;
66 int v_eighty_two
= 82;
67 CFNumberRef eighty_two
= CFNumberCreate(NULL
, kCFNumberSInt32Type
, &v_eighty_two
);
68 CFDictionarySetValue(query
, kSecAttrPort
, eighty_two
);
69 ok_status(SecItemAdd(query
, &ref3
), "add internet password port 82");
71 /* remove the data, and return key from the query */
72 CFDictionaryRemoveValue(query
, kSecValueData
);
73 CFDictionaryRemoveValue(query
, kSecReturnPersistentRef
);
75 /* update second password to conflict with first one */
76 CFDictionarySetValue(query
, kSecAttrPort
, eighty_one
);
77 CFMutableDictionaryRef attributes
= CFDictionaryCreateMutable(NULL
, 0, NULL
, NULL
);
78 CFDictionaryAddValue(attributes
, kSecAttrPort
, eighty
);
79 is_status(SecItemUpdate(query
, attributes
), errSecDuplicateItem
, "update internet password port 80 to 81");
81 /* corrupt the first and 3rd password */
82 CFStringRef keychain_path_cf
= __SecKeychainCopyPath();
84 CFStringPerformWithCString(keychain_path_cf
, ^(const char *keychain_path
) {
85 /* Create a new keychain sqlite db */
88 is(sqlite3_open(keychain_path
, &db
), SQLITE_OK
, "open keychain");
89 is(sqlite3_exec(db
, corrupt_item_sql
, NULL
, NULL
, NULL
), SQLITE_OK
,
90 "corrupting keychain items");
94 /* Try the update again */
95 ok_status(SecItemUpdate(query
, attributes
), "update internet password port 80 to 81 (after corrupting item)");
97 /* query the persistent ref */
99 CFDictionarySetValue(query
, kSecAttrPort
, eighty
);
100 CFDictionaryAddValue(query
, kSecReturnPersistentRef
, kCFBooleanTrue
);
101 ok_status(SecItemCopyMatching(query
, &ref
), "Item 80 found");
103 CFDictionaryRemoveValue(query
, kSecReturnPersistentRef
);
104 ok(CFEqual(ref
, ref2
), "persistent ref of item 2");
106 CFReleaseNull(attributes
);
108 /* Update the 3rd item (82) */
109 CFDictionarySetValue(query
, kSecAttrPort
, eighty_two
);
111 attributes
= CFDictionaryCreateMutable(NULL
, 0, NULL
, NULL
);
112 CFDictionaryAddValue(attributes
, kSecAttrLabel
, CFSTR("This is the 3rd password"));
113 is_status(SecItemUpdate(query
, attributes
), errSecItemNotFound
, "update internet password port 82 (after corrupting item)");
115 CFDictionarySetValue(query
, kSecValueData
, pwdata
);
116 ok_status(SecItemAdd(query
, NULL
), "re-adding internet password port 82 (after corrupting item)");
117 CFReleaseNull(pwdata
);
118 CFReleaseNull(attributes
);
119 CFReleaseNull(query
);
120 CFReleaseNull(eighty
);
121 CFReleaseNull(eighty_one
);
122 CFReleaseNull(eighty_two
);