2 * acltool.cpp - display and manipluate ACLs on SecKeychainItems
9 #include <Security/Security.h>
12 static void usage(char **argv
)
14 printf("usage: %s op [options]\n", argv
[0]);
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");
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");
33 /* print an item's label and (optionally) its data */
34 static OSStatus
printItemLabelAndData(
35 SecKeychainItemRef itemRef
,
36 SecItemAttr labelAttr
,
39 SecKeychainAttributeList attrList
;
40 SecKeychainAttribute attr
;
48 attrList
.attr
= &attr
;
50 OSStatus ortn
= SecKeychainItemCopyContent(itemRef
,
51 NULL
, // itemClass - we know
52 &attrList
, // for label
53 dumpData
? &length
: 0,
54 dumpData
? &outData
: NULL
);
56 cssmPerror("SecKeychainItemCopyContent", ortn
);
57 printf("***Error fetching label %s\n", dumpData
? "and data" : "");
61 if(attr
.data
== NULL
) {
62 printf("**No label attribute found\n");
66 print_buffer(stdout
, attr
.length
, attr
.data
);
71 printf("***Asked for data but none found\n");
75 print_buffer(stdout
, length
, outData
);
79 SecKeychainItemFreeContent(&attrList
, outData
);
84 * Lookup by itemClass and optional label. Then do one or more of:
86 * -- dump label (always done)
90 * -- set (modify) data
92 static OSStatus
dumpAcls(
95 /* item specification */
96 SecItemClass itemClass
,
97 SecItemAttr labelAttr
, // to look up by label if specified
100 /* what we do with the item(s) found */
104 bool simulateStickyRecord
,
105 const unsigned char *newData
, // if non-NULL, set/modify new data
109 SecKeychainSearchRef srchRef
;
110 SecKeychainAttributeList attrList
;
111 SecKeychainAttributeList
*attrListP
= NULL
;
112 SecKeychainAttribute attr
;
113 unsigned numFound
= 0;
115 /* searching by label, or blindly? */
117 attr
.tag
= labelAttr
;
118 attr
.length
= strlen(label
);
119 attr
.data
= (void *)label
;
121 attrList
.attr
= &attr
;
122 attrListP
= &attrList
;
124 ortn
= SecKeychainSearchCreateFromAttributes(kcRef
,
129 cssmPerror("SecKeychainSearchCreateFromAttributes", ortn
);
133 SecKeychainItemRef itemRef
;
134 ortn
= SecKeychainSearchCopyNext(srchRef
, &itemRef
);
136 if(ortn
== errSecItemNotFound
) {
137 /* normal search end */
141 cssmPerror("SecKeychainSearchCopyNext", ortn
);
146 printf("Item %u:\n", numFound
++);
147 printItemLabelAndData(itemRef
, labelAttr
, dumpData
);
150 ortn
= SecKeychainItemModifyAttributesAndData(itemRef
,
151 NULL
, // attrList - we don't change any attrs
155 cssmPerror("SecKeychainItemModifyAttributesAndData", ortn
);
156 printf("***Cannot modify data of this item***\n");
161 SecAccessRef accessRef
= nil
;
162 ortn
= SecKeychainItemCopyAccess(itemRef
, &accessRef
);
164 cssmPerror("SecKeychainItemCopyAccess", ortn
);
165 printf("***No SecAccessRef found***\n");
168 print_access(stdout
, accessRef
, editAcl
);
169 if(simulateStickyRecord
) {
170 ortn
= stickyRecordUpdateAcl(accessRef
);
175 if(editAcl
|| simulateStickyRecord
) {
176 ortn
= SecKeychainItemSetAccess(itemRef
, accessRef
);
178 cssmPerror("SecKeychainItemSetAccess", ortn
);
189 printf("...%u items found\n", numFound
);
200 int main(int argc
, char **argv
)
202 /* user spec'd variables */
203 const char *kcName
= NULL
;
204 const char *labelOrName
= NULL
; // attribute type varies per
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;
212 bool simulateStickyRecord
= false;
213 const char *newPassword
= NULL
;
214 unsigned newPasswordLen
= 0;
216 SecKeychainRef kcRef
= nil
;
234 op
= AO_ModifyPassword
;
245 while ((arg
= getopt(argc
, argv
, "k:t:l:dep:sh")) != -1) {
253 itemClass
= CSSM_DL_DB_RECORD_PRIVATE_KEY
;
256 itemClass
= CSSM_DL_DB_RECORD_SYMMETRIC_KEY
;
259 itemClass
= CSSM_DL_DB_RECORD_PUBLIC_KEY
;
262 itemClass
= kSecGenericPasswordItemClass
;
263 labelAttr
= kSecLabelItemAttr
;
270 labelOrName
= optarg
;
279 newPassword
= optarg
;
280 newPasswordLen
= strlen(newPassword
);
283 simulateStickyRecord
= true;
292 if(op
== AO_ModifyPassword
) {
293 if(itemClass
!= kSecGenericPasswordItemClass
) {
294 printf("***You can only modify data on a password item.\n");
297 if(newPassword
== NULL
) {
298 printf("***You must supply new password data for this operation.\n");
303 ortn
= SecKeychainOpen(kcName
, &kcRef
);
305 cssmPerror("SecKeychainOpen", ortn
);
306 printf("***Error opening keychain %s. Aborting.\n", kcName
);
314 case AO_ModifyPassword
:
315 ortn
= dumpAcls(kcRef
, itemClass
, labelAttr
, labelOrName
, dumpData
, dumpAcl
, editAcl
,
316 simulateStickyRecord
, (unsigned char *)newPassword
, newPasswordLen
);
319 printf("Add ACL op to be implemented real soon now\n");