]> git.saurik.com Git - apple/security.git/blob - Keychain/SecACL.cpp
1a79e249a66ae6b47de8e7802dcc85de6a320585
[apple/security.git] / Keychain / SecACL.cpp
1 /*
2 * Copyright (c) 2002 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18 #include <Security/SecACL.h>
19
20 #include "SecBridge.h"
21
22
23 //
24 // Local functions
25 //
26 static void setApplications(ACL *acl, CFArrayRef applicationList);
27
28
29 CFTypeID
30 SecACLGetTypeID(void)
31 {
32 BEGIN_SECAPI
33
34 return gTypes().acl.typeId;
35
36 END_SECAPI1(_kCFRuntimeNotATypeID)
37 }
38
39
40 /*!
41 */
42 OSStatus SecACLCreateFromSimpleContents(SecAccessRef accessRef,
43 CFArrayRef applicationList,
44 CFStringRef description, const CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR *promptSelector,
45 SecACLRef *newAcl)
46 {
47 BEGIN_SECAPI
48 RefPointer<Access> access = gTypes().access.required(accessRef);
49 RefPointer<ACL> acl = new ACL(*access, cfString(description), *promptSelector);
50 setApplications(acl, applicationList);
51 access->add(acl.get());
52 Required(newAcl) = gTypes().acl.handle(*acl);
53 END_SECAPI
54 }
55
56
57 /*!
58 */
59 OSStatus SecACLRemove(SecACLRef aclRef)
60 {
61 BEGIN_SECAPI
62 gTypes().acl.required(aclRef)->remove();
63 END_SECAPI
64 }
65
66
67 /*!
68 */
69 OSStatus SecACLCopySimpleContents(SecACLRef aclRef,
70 CFArrayRef *applicationList,
71 CFStringRef *promptDescription, CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR *promptSelector)
72 {
73 BEGIN_SECAPI
74 RefPointer<ACL> acl = gTypes().acl.required(aclRef);
75 switch (acl->form()) {
76 case ACL::allowAllForm:
77 Required(applicationList) = NULL;
78 Required(promptDescription) =
79 acl->promptDescription().empty() ? NULL
80 : makeCFString(acl->promptDescription());
81 Required(promptSelector) = acl->promptSelector();
82 break;
83 case ACL::appListForm:
84 Required(applicationList) =
85 makeCFArray(gTypes().trustedApplication, acl->applications());
86 Required(promptDescription) = makeCFString(acl->promptDescription());
87 Required(promptSelector) = acl->promptSelector();
88 break;
89 default:
90 return errSecACLNotSimple; // custom or unknown
91 }
92 END_SECAPI
93 }
94
95 OSStatus SecACLSetSimpleContents(SecACLRef aclRef,
96 CFArrayRef applicationList,
97 CFStringRef description, const CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR *promptSelector)
98 {
99 BEGIN_SECAPI
100 RefPointer<ACL> acl = gTypes().acl.required(aclRef);
101 acl->promptDescription() = description ? cfString(description) : "";
102 acl->promptSelector() = promptSelector ? *promptSelector : ACL::defaultSelector;
103 if (applicationList) {
104 // application-list + prompt
105 acl->form(ACL::appListForm);
106 setApplications(acl, applicationList);
107 } else {
108 // allow-any
109 acl->form(ACL::allowAllForm);
110 }
111 acl->modify();
112 END_SECAPI
113 }
114
115
116 //
117 // Stuff a CFArray-of-SecTrustedApplications into an ACL object
118 //
119 static void setApplications(ACL *acl, CFArrayRef applicationList)
120 {
121 ACL::ApplicationList &appList = acl->applications();
122 appList.clear();
123 //@@@ should really use STL iterator overlay on CFArray. By hand...
124 CFIndex count = CFArrayGetCount(applicationList);
125 for (CFIndex n = 0; n < count; n++)
126 appList.push_back(gTypes().trustedApplication.required(
127 SecTrustedApplicationRef(CFArrayGetValueAtIndex(applicationList, n))));
128 }
129
130
131 //
132 // Set and get the authorization tags of an ACL entry
133 //
134 OSStatus SecACLGetAuthorizations(SecACLRef acl,
135 CSSM_ACL_AUTHORIZATION_TAG *tags, uint32 *tagCount)
136 {
137 BEGIN_SECAPI
138 AclAuthorizationSet auths = gTypes().acl.required(acl)->authorizations();
139 if (Required(tagCount) < auths.size()) { // overflow
140 *tagCount = auths.size(); // report size required
141 CssmError::throwMe(paramErr);
142 }
143 *tagCount = auths.size();
144 copy(auths.begin(), auths.end(), tags);
145 END_SECAPI
146 }
147
148 OSStatus SecACLSetAuthorizations(SecACLRef aclRef,
149 CSSM_ACL_AUTHORIZATION_TAG *tags, uint32 tagCount)
150 {
151 BEGIN_SECAPI
152 RefPointer<ACL> acl = gTypes().acl.required(aclRef);
153 if (acl->isOwner()) // can't change rights of the owner ACL
154 MacOSError::throwMe(errSecInvalidOwnerEdit);
155 AclAuthorizationSet &auths = acl->authorizations();
156 auths.clear();
157 copy(tags, tags + tagCount, insert_iterator<AclAuthorizationSet>(auths, auths.begin()));
158 acl->modify();
159 END_SECAPI
160 }