]> git.saurik.com Git - apple/security.git/blob - SecurityTests/cspxutils/acltool/acltool.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / cspxutils / acltool / acltool.cpp
1 /*
2 * acltool.cpp - display and manipluate ACLs on SecKeychainItems
3 */
4
5 #include <stdlib.h>
6 #include <strings.h>
7 #include <stdio.h>
8 #include <unistd.h>
9 #include <Security/Security.h>
10 #include "aclUtils.h"
11
12 static void usage(char **argv)
13 {
14 printf("usage: %s op [options]\n", argv[0]);
15 printf("op:\n");
16 printf(" d -- display ACL\n");
17 printf(" a -- add ACL\n");
18 printf(" l -- lookup, dump label; no ACL operation\n");
19 printf(" m -- modify data (only allowed for password items; must specify -p)\n");
20 printf("Options:\n");
21 printf(" -k keychain\n");
22 printf(" -t itemType : k=privateKey, b=publicKey s=sessionKey, p=password; default is sessionKey\n");
23 printf(" -l label_or_printName\n");
24 printf(" -p new_password_data\n");
25 printf(" -d -- dump data\n");
26 printf(" -e -- edit ACL entries\n");
27 printf(" -s -- simulate StickyRecord ACL\n");
28 /* etc. */
29 exit(1);
30 }
31
32
33 /* print an item's label and (optionally) its data */
34 static OSStatus printItemLabelAndData(
35 SecKeychainItemRef itemRef,
36 SecItemAttr labelAttr,
37 bool dumpData)
38 {
39 SecKeychainAttributeList attrList;
40 SecKeychainAttribute attr;
41 UInt32 length = 0;
42 void *outData = NULL;
43
44 attr.tag = labelAttr;
45 attr.length = 0;
46 attr.data = NULL;
47 attrList.count = 1;
48 attrList.attr = &attr;
49
50 OSStatus ortn = SecKeychainItemCopyContent(itemRef,
51 NULL, // itemClass - we know
52 &attrList, // for label
53 dumpData ? &length : 0,
54 dumpData ? &outData : NULL);
55 if(ortn) {
56 cssmPerror("SecKeychainItemCopyContent", ortn);
57 printf("***Error fetching label %s\n", dumpData ? "and data" : "");
58 return ortn;
59 }
60
61 if(attr.data == NULL) {
62 printf("**No label attribute found\n");
63 }
64 else {
65 printf("Label: ");
66 print_buffer(stdout, attr.length, attr.data);
67 printf("\n");
68 }
69 if(dumpData) {
70 if(outData == NULL) {
71 printf("***Asked for data but none found\n");
72 }
73 else {
74 printf("Data : ");
75 print_buffer(stdout, length, outData);
76 printf("\n");
77 }
78 }
79 SecKeychainItemFreeContent(&attrList, outData);
80 return noErr;
81 }
82
83 /*
84 * Lookup by itemClass and optional label. Then do one or more of:
85 *
86 * -- dump label (always done)
87 * -- dump ACLs
88 * -- edit acl
89 * -- dump data
90 * -- set (modify) data
91 */
92 static OSStatus dumpAcls(
93 SecKeychainRef kcRef,
94
95 /* item specification */
96 SecItemClass itemClass,
97 SecItemAttr labelAttr, // to look up by label if specified
98 const char *label,
99
100 /* what we do with the item(s) found */
101 bool dumpData,
102 bool dumpAcl,
103 bool editAcl,
104 bool simulateStickyRecord,
105 const unsigned char *newData, // if non-NULL, set/modify new data
106 unsigned newDataLen)
107 {
108 OSStatus ortn;
109 SecKeychainSearchRef srchRef;
110 SecKeychainAttributeList attrList;
111 SecKeychainAttributeList *attrListP = NULL;
112 SecKeychainAttribute attr;
113 unsigned numFound = 0;
114
115 /* searching by label, or blindly? */
116 if(label) {
117 attr.tag = labelAttr;
118 attr.length = strlen(label);
119 attr.data = (void *)label;
120 attrList.count = 1;
121 attrList.attr = &attr;
122 attrListP = &attrList;
123 }
124 ortn = SecKeychainSearchCreateFromAttributes(kcRef,
125 itemClass,
126 attrListP,
127 &srchRef);
128 if(ortn) {
129 cssmPerror("SecKeychainSearchCreateFromAttributes", ortn);
130 return ortn;
131 }
132 for(;;) {
133 SecKeychainItemRef itemRef;
134 ortn = SecKeychainSearchCopyNext(srchRef, &itemRef);
135 if(ortn) {
136 if(ortn == errSecItemNotFound) {
137 /* normal search end */
138 ortn = noErr;
139 }
140 else {
141 cssmPerror("SecKeychainSearchCopyNext", ortn);
142 }
143 break;
144 }
145
146 printf("Item %u:\n", numFound++);
147 printItemLabelAndData(itemRef, labelAttr, dumpData);
148
149 if(newData) {
150 ortn = SecKeychainItemModifyAttributesAndData(itemRef,
151 NULL, // attrList - we don't change any attrs
152 newDataLen,
153 newData);
154 if(ortn) {
155 cssmPerror("SecKeychainItemModifyAttributesAndData", ortn);
156 printf("***Cannot modify data of this item***\n");
157 goto endOfLoop;
158 }
159 }
160 if(dumpAcl) {
161 SecAccessRef accessRef = nil;
162 ortn = SecKeychainItemCopyAccess(itemRef, &accessRef);
163 if(ortn) {
164 cssmPerror("SecKeychainItemCopyAccess", ortn);
165 printf("***No SecAccessRef found***\n");
166 goto endOfLoop;
167 }
168 print_access(stdout, accessRef, editAcl);
169 if(simulateStickyRecord) {
170 ortn = stickyRecordUpdateAcl(accessRef);
171 if(ortn) {
172 goto endOfLoop;
173 }
174 }
175 if(editAcl || simulateStickyRecord) {
176 ortn = SecKeychainItemSetAccess(itemRef, accessRef);
177 if(ortn) {
178 cssmPerror("SecKeychainItemSetAccess", ortn);
179 }
180 }
181 }
182 endOfLoop:
183 CFRelease(itemRef);
184 if(ortn) {
185 break;
186 }
187 }
188 CFRelease(srchRef);
189 printf("...%u items found\n", numFound);
190 return ortn;
191 }
192
193 typedef enum {
194 AO_Dump,
195 AO_Add,
196 AO_Lookup,
197 AO_ModifyPassword
198 } AclOp;
199
200 int main(int argc, char **argv)
201 {
202 /* user spec'd variables */
203 const char *kcName = NULL;
204 const char *labelOrName = NULL; // attribute type varies per
205 AclOp op = AO_Dump;
206 SecItemClass itemClass = CSSM_DL_DB_RECORD_SYMMETRIC_KEY;
207 /* FIXME why does this work like this for keys? doc says kSecKeyPrintName but that doesn't work */
208 SecItemAttr labelAttr = kSecLabelItemAttr;
209 bool dumpData = false;
210 bool editAcl = false;
211 bool dumpAcl = true;
212 bool simulateStickyRecord = false;
213 const char *newPassword = NULL;
214 unsigned newPasswordLen = 0;
215
216 SecKeychainRef kcRef = nil;
217 OSStatus ortn;
218
219 if(argc < 2) {
220 usage(argv);
221 }
222 switch(argv[1][0]) {
223 case 'd':
224 op = AO_Dump;
225 break;
226 case 'a':
227 op = AO_Add;
228 break;
229 case 'l':
230 op = AO_Lookup;
231 dumpAcl = false;
232 break;
233 case 'm':
234 op = AO_ModifyPassword;
235 dumpAcl = false;
236 break;
237 default:
238 usage(argv);
239 }
240
241 extern char *optarg;
242 int arg;
243 extern int optind;
244 optind = 2;
245 while ((arg = getopt(argc, argv, "k:t:l:dep:sh")) != -1) {
246 switch (arg) {
247 case 'k':
248 kcName = optarg;
249 break;
250 case 't':
251 switch(optarg[0]) {
252 case 'k':
253 itemClass = CSSM_DL_DB_RECORD_PRIVATE_KEY;
254 break;
255 case 's':
256 itemClass = CSSM_DL_DB_RECORD_SYMMETRIC_KEY;
257 break;
258 case 'b':
259 itemClass = CSSM_DL_DB_RECORD_PUBLIC_KEY;
260 break;
261 case 'p':
262 itemClass = kSecGenericPasswordItemClass;
263 labelAttr = kSecLabelItemAttr;
264 break;
265 default:
266 usage(argv);
267 }
268 break;
269 case 'l':
270 labelOrName = optarg;
271 break;
272 case 'd':
273 dumpData = true;
274 break;
275 case 'e':
276 editAcl = true;
277 break;
278 case 'p':
279 newPassword = optarg;
280 newPasswordLen = strlen(newPassword);
281 break;
282 case 's':
283 simulateStickyRecord = true;
284 break;
285 case 'h':
286 usage(argv);
287 }
288 }
289 if(optind != argc) {
290 usage(argv);
291 }
292 if(op == AO_ModifyPassword) {
293 if(itemClass != kSecGenericPasswordItemClass) {
294 printf("***You can only modify data on a password item.\n");
295 exit(1);
296 }
297 if(newPassword == NULL) {
298 printf("***You must supply new password data for this operation.\n");
299 exit(1);
300 }
301 }
302 if(kcName) {
303 ortn = SecKeychainOpen(kcName, &kcRef);
304 if(ortn) {
305 cssmPerror("SecKeychainOpen", ortn);
306 printf("***Error opening keychain %s. Aborting.\n", kcName);
307 exit(1);
308 }
309 }
310
311 switch(op) {
312 case AO_Dump:
313 case AO_Lookup:
314 case AO_ModifyPassword:
315 ortn = dumpAcls(kcRef, itemClass, labelAttr, labelOrName, dumpData, dumpAcl, editAcl,
316 simulateStickyRecord, (unsigned char *)newPassword, newPasswordLen);
317 break;
318 case AO_Add:
319 printf("Add ACL op to be implemented real soon now\n");
320 ortn = -1;
321 break;
322 }
323 if(kcRef) {
324 CFRelease(kcRef);
325 }
326 return (int)ortn;
327 }