]> git.saurik.com Git - apple/security.git/blob - Keychain/SecACL.cpp
Security-176.tar.gz
[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 #include <Security/ACL.h>
20 #include <Security/Access.h>
21
22 #include "SecBridge.h"
23
24
25 //
26 // Local functions
27 //
28 static void setApplications(ACL *acl, CFArrayRef applicationList);
29
30
31 CFTypeID
32 SecACLGetTypeID(void)
33 {
34 BEGIN_SECAPI
35
36 return gTypes().ACL.typeID;
37
38 END_SECAPI1(_kCFRuntimeNotATypeID)
39 }
40
41
42 /*!
43 */
44 OSStatus SecACLCreateFromSimpleContents(SecAccessRef accessRef,
45 CFArrayRef applicationList,
46 CFStringRef description, const CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR *promptSelector,
47 SecACLRef *newAcl)
48 {
49 BEGIN_SECAPI
50 SecPointer<Access> access = Access::required(accessRef);
51 SecPointer<ACL> acl = new ACL(*access, cfString(description), *promptSelector);
52 if (applicationList) {
53 // application-list + prompt
54 acl->form(ACL::appListForm);
55 setApplications(acl, applicationList);
56 } else {
57 // allow-any
58 acl->form(ACL::allowAllForm);
59 }
60 access->add(acl.get());
61 Required(newAcl) = acl->handle();
62 END_SECAPI
63 }
64
65
66 /*!
67 */
68 OSStatus SecACLRemove(SecACLRef aclRef)
69 {
70 BEGIN_SECAPI
71 ACL::required(aclRef)->remove();
72 END_SECAPI
73 }
74
75
76 static SecTrustedApplicationRef
77 convert(const SecPointer<TrustedApplication> &trustedApplication)
78 {
79 return *trustedApplication;
80 }
81
82 /*!
83 */
84 OSStatus SecACLCopySimpleContents(SecACLRef aclRef,
85 CFArrayRef *applicationList,
86 CFStringRef *promptDescription, CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR *promptSelector)
87 {
88 BEGIN_SECAPI
89 SecPointer<ACL> acl = ACL::required(aclRef);
90 switch (acl->form()) {
91 case ACL::allowAllForm:
92 Required(applicationList) = NULL;
93 Required(promptDescription) =
94 acl->promptDescription().empty() ? NULL
95 : makeCFString(acl->promptDescription());
96 Required(promptSelector) = acl->promptSelector();
97 break;
98 case ACL::appListForm:
99 Required(applicationList) =
100 makeCFArray(convert, acl->applications());
101 Required(promptDescription) = makeCFString(acl->promptDescription());
102 Required(promptSelector) = acl->promptSelector();
103 break;
104 default:
105 return errSecACLNotSimple; // custom or unknown
106 }
107 END_SECAPI
108 }
109
110 OSStatus SecACLSetSimpleContents(SecACLRef aclRef,
111 CFArrayRef applicationList,
112 CFStringRef description, const CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR *promptSelector)
113 {
114 BEGIN_SECAPI
115 SecPointer<ACL> acl = ACL::required(aclRef);
116 acl->promptDescription() = description ? cfString(description) : "";
117 acl->promptSelector() = promptSelector ? *promptSelector : ACL::defaultSelector;
118 if (applicationList) {
119 // application-list + prompt
120 acl->form(ACL::appListForm);
121 setApplications(acl, applicationList);
122 } else {
123 // allow-any
124 acl->form(ACL::allowAllForm);
125 }
126 acl->modify();
127 END_SECAPI
128 }
129
130
131 //
132 // Stuff a CFArray-of-SecTrustedApplications into an ACL object
133 //
134 static void setApplications(ACL *acl, CFArrayRef applicationList)
135 {
136 ACL::ApplicationList &appList = acl->applications();
137 appList.clear();
138 //@@@ should really use STL iterator overlay on CFArray. By hand...
139 CFIndex count = CFArrayGetCount(applicationList);
140 for (CFIndex n = 0; n < count; n++)
141 appList.push_back(TrustedApplication::required(
142 SecTrustedApplicationRef(CFArrayGetValueAtIndex(applicationList, n))));
143 }
144
145
146 //
147 // Set and get the authorization tags of an ACL entry
148 //
149 OSStatus SecACLGetAuthorizations(SecACLRef acl,
150 CSSM_ACL_AUTHORIZATION_TAG *tags, uint32 *tagCount)
151 {
152 BEGIN_SECAPI
153 AclAuthorizationSet auths = ACL::required(acl)->authorizations();
154 if (Required(tagCount) < auths.size()) { // overflow
155 *tagCount = auths.size(); // report size required
156 CssmError::throwMe(paramErr);
157 }
158 *tagCount = auths.size();
159 copy(auths.begin(), auths.end(), tags);
160 END_SECAPI
161 }
162
163 OSStatus SecACLSetAuthorizations(SecACLRef aclRef,
164 CSSM_ACL_AUTHORIZATION_TAG *tags, uint32 tagCount)
165 {
166 BEGIN_SECAPI
167 SecPointer<ACL> acl = ACL::required(aclRef);
168 if (acl->isOwner()) // can't change rights of the owner ACL
169 MacOSError::throwMe(errSecInvalidOwnerEdit);
170 AclAuthorizationSet &auths = acl->authorizations();
171 auths.clear();
172 copy(tags, tags + tagCount, insert_iterator<AclAuthorizationSet>(auths, auths.begin()));
173 acl->modify();
174 END_SECAPI
175 }