]>
Commit | Line | Data |
---|---|---|
427c49bc A |
1 | /* |
2 | * si-43-persistent.c | |
3 | * Security | |
4 | * | |
d8f41ccd | 5 | * Copyright (c) 2008-2010,2012-2013 Apple Inc. All Rights Reserved. |
427c49bc A |
6 | * |
7 | */ | |
8 | ||
9 | #include <CoreFoundation/CoreFoundation.h> | |
10 | #include <Security/SecBase.h> | |
11 | #include <Security/SecItem.h> | |
12 | #include <Security/SecInternal.h> | |
13 | #include <Security/SecItemPriv.h> | |
14 | #include <utilities/array_size.h> | |
15 | #include <stdlib.h> | |
16 | #include <unistd.h> | |
17 | ||
18 | #include "Security_regressions.h" | |
19 | ||
20 | static void tests(void) | |
21 | { | |
22 | int v_eighty = 80; | |
23 | CFNumberRef eighty = CFNumberCreate(NULL, kCFNumberSInt32Type, &v_eighty); | |
24 | const char *v_data = "test"; | |
25 | CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data)); | |
26 | const void *keys[] = { | |
27 | kSecClass, | |
28 | kSecAttrServer, | |
29 | kSecAttrAccount, | |
30 | kSecAttrPort, | |
31 | kSecAttrProtocol, | |
32 | kSecAttrAuthenticationType, | |
33 | kSecReturnPersistentRef, | |
34 | kSecValueData | |
35 | }; | |
36 | const void *values[] = { | |
37 | kSecClassInternetPassword, | |
38 | CFSTR("zuigt.nl"), | |
39 | CFSTR("frtnbf"), | |
40 | eighty, | |
41 | CFSTR("http"), | |
42 | CFSTR("dflt"), | |
43 | kCFBooleanTrue, | |
44 | pwdata | |
45 | }; | |
46 | CFDictionaryRef item = CFDictionaryCreate(NULL, keys, values, | |
47 | array_size(keys), NULL, NULL); | |
48 | ||
49 | CFTypeRef persist = NULL; | |
50 | ok_status(SecItemAdd(item, &persist), "add internet password"); | |
51 | ok(persist, "got back persistent ref"); | |
52 | ||
53 | /* Create a dict with all attrs except the data. */ | |
54 | keys[(array_size(keys)) - 2] = kSecReturnAttributes; | |
55 | CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values, | |
56 | (array_size(keys)) - 1, NULL, NULL); | |
57 | CFTypeRef results = NULL; | |
58 | ok_status(SecItemCopyMatching(query, &results), "find internet password by attr"); | |
59 | ||
60 | const void *keys_persist[] = { | |
61 | kSecReturnAttributes, | |
62 | kSecValuePersistentRef | |
63 | }; | |
64 | const void *values_persist[] = { | |
65 | kCFBooleanTrue, | |
66 | persist | |
67 | }; | |
68 | CFDictionaryRef query2 = CFDictionaryCreate(NULL, keys_persist, values_persist, | |
69 | (array_size(keys_persist)), NULL, NULL); | |
70 | CFTypeRef results2 = NULL; | |
71 | ok_status(SecItemCopyMatching(query2, &results2), "find internet password by persistent ref"); | |
72 | ok(CFEqual(results, results2 ? results2 : CFSTR("")), "same item (attributes)"); | |
73 | ||
74 | CFReleaseNull(results); | |
75 | CFReleaseNull(results2); | |
76 | ||
77 | ok_status(SecItemDelete(query), "delete internet password"); | |
78 | ||
79 | ok_status(!SecItemCopyMatching(query, &results), | |
80 | "don't find internet password by attributes"); | |
81 | ok(!results, "no results"); | |
82 | ||
83 | /* clean up left over from aborted run */ | |
84 | if (results) { | |
5c19dc3a | 85 | CFDictionaryRef cleanup = CFDictionaryCreate(NULL, (const void **)&kSecValuePersistentRef, |
427c49bc A |
86 | &results, 1, NULL, NULL); |
87 | SecItemDelete(cleanup); | |
88 | CFRelease(results); | |
89 | CFRelease(cleanup); | |
90 | } | |
91 | ||
92 | ok_status(!SecItemCopyMatching(query2, &results2), | |
93 | "don't find internet password by persistent ref anymore"); | |
94 | ok(!results2, "no results"); | |
95 | ||
96 | CFReleaseNull(persist); | |
97 | ||
98 | /* Add a new item and get its persistent ref. */ | |
99 | ok_status(SecItemAdd(item, &persist), "add internet password"); | |
100 | CFTypeRef persist2 = NULL; | |
101 | CFMutableDictionaryRef item2 = CFDictionaryCreateMutableCopy(NULL, 0, item); | |
102 | CFDictionarySetValue(item2, kSecAttrAccount, CFSTR("johndoe")); | |
103 | ok_status(SecItemAdd(item2, &persist2), "add second internet password"); | |
104 | is(CFGetTypeID(persist), CFDataGetTypeID(), "result is a CFData"); | |
105 | CFMutableDictionaryRef query3 = CFDictionaryCreateMutable(NULL, 0, NULL, NULL); | |
106 | CFDictionaryAddValue(query3, kSecValuePersistentRef, persist); | |
107 | CFMutableDictionaryRef update = CFDictionaryCreateMutable(NULL, 0, NULL, NULL); | |
108 | CFDictionaryAddValue(update, kSecAttrServer, CFSTR("zuigt.com")); | |
109 | ok_status(SecItemUpdate(query3, update), "update via persitant ref"); | |
110 | ||
111 | /* Verify that the update really worked. */ | |
112 | CFDictionaryAddValue(query3, kSecReturnAttributes, kCFBooleanTrue); | |
113 | ok_status(SecItemCopyMatching(query3, &results2), "find updated internet password by persistent ref"); | |
114 | CFStringRef server = CFDictionaryGetValue(results2, kSecAttrServer); | |
115 | ok(CFEqual(server, CFSTR("zuigt.com")), "verify attribute was modified by update"); | |
116 | CFReleaseNull(results2); | |
117 | CFDictionaryRemoveValue(query3, kSecReturnAttributes); | |
118 | ||
119 | /* Verify that item2 wasn't affected by the update. */ | |
120 | CFMutableDictionaryRef query4 = CFDictionaryCreateMutable(NULL, 0, NULL, NULL); | |
121 | CFDictionaryAddValue(query4, kSecValuePersistentRef, persist2); | |
122 | CFDictionaryAddValue(query4, kSecReturnAttributes, kCFBooleanTrue); | |
123 | ok_status(SecItemCopyMatching(query4, &results2), "find non updated internet password by persistent ref"); | |
124 | server = CFDictionaryGetValue(results2, kSecAttrServer); | |
125 | ok(CFEqual(server, CFSTR("zuigt.nl")), "verify second items attribute was not modified by update"); | |
126 | CFReleaseNull(results2); | |
127 | ||
128 | /* Delete the item via persitant ref. */ | |
129 | ok_status(SecItemDelete(query3), "delete via persitant ref"); | |
130 | is_status(SecItemCopyMatching(query3, &results2), errSecItemNotFound, | |
131 | "don't find deleted internet password by persistent ref"); | |
132 | CFReleaseNull(results2); | |
133 | ok_status(SecItemCopyMatching(query4, &results2), | |
134 | "find non deleted internet password by persistent ref"); | |
135 | CFReleaseNull(results2); | |
136 | ok_status(SecItemDelete(query4), | |
137 | "delete internet password by persistent ref"); | |
138 | ||
139 | CFRelease(query); | |
140 | CFRelease(query2); | |
141 | CFRelease(query3); | |
142 | CFRelease(query4); | |
143 | CFRelease(update); | |
144 | CFReleaseNull(item); | |
145 | CFReleaseNull(item2); | |
146 | CFReleaseNull(eighty); | |
147 | CFReleaseNull(pwdata); | |
148 | CFReleaseNull(persist); | |
149 | CFReleaseNull(persist2); | |
150 | } | |
151 | ||
152 | int si_43_persistent(int argc, char *const *argv) | |
153 | { | |
154 | plan_tests(22); | |
155 | ||
156 | ||
157 | tests(); | |
158 | ||
159 | return 0; | |
160 | } |