]>
Commit | Line | Data |
---|---|---|
b1ab9ed8 | 1 | /* |
d8f41ccd | 2 | * Copyright (c) 2000-2007,2011 Apple Inc. All Rights Reserved. |
b1ab9ed8 A |
3 | * |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * This file contains Original Code and/or Modifications of Original Code | |
7 | * as defined in and that are subject to the Apple Public Source License | |
8 | * Version 2.0 (the 'License'). You may not use this file except in | |
9 | * compliance with the License. Please obtain a copy of the License at | |
10 | * http://www.opensource.apple.com/apsl/ and read it before using this | |
11 | * file. | |
12 | * | |
13 | * The Original Code and all software distributed under the License are | |
14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. | |
18 | * Please see the License for the specific language governing rights and | |
19 | * limitations under the License. | |
20 | * | |
21 | * @APPLE_LICENSE_HEADER_END@ | |
22 | */ | |
23 | ||
24 | ||
25 | // | |
26 | // cssmaclpod - enhanced PodWrappers for ACL-related CSSM data structures | |
27 | // | |
28 | #ifndef _CSSMACLPOD | |
29 | #define _CSSMACLPOD | |
30 | ||
31 | #include <security_utilities/utilities.h> | |
32 | #include <security_cdsa_utilities/cssmlist.h> | |
33 | #include <security_cdsa_utilities/cssmalloc.h> | |
34 | ||
35 | namespace Security { | |
36 | ||
37 | // a nicer name for an authorization tag | |
38 | typedef CSSM_ACL_AUTHORIZATION_TAG AclAuthorization; | |
39 | ||
40 | ||
41 | // | |
42 | // An STL set of authorization tags, with some convenience features | |
43 | // | |
44 | class AclAuthorizationSet : public std::set<AclAuthorization> { | |
45 | public: | |
46 | AclAuthorizationSet() { } | |
47 | AclAuthorizationSet(AclAuthorization auth) { insert(auth); } | |
48 | AclAuthorizationSet(AclAuthorization *authBegin, AclAuthorization *authEnd) | |
49 | : set<AclAuthorization>(authBegin, authEnd) { } | |
50 | AclAuthorizationSet(AclAuthorization a1, AclAuthorization a2, ...); // list of auths, end with zero | |
51 | }; | |
52 | ||
53 | ||
54 | // | |
55 | // Enhanced POD Wrappers for the public ACL-related CSSM structures | |
56 | // | |
57 | class AuthorizationGroup : public PodWrapper<AuthorizationGroup, CSSM_AUTHORIZATIONGROUP> { | |
58 | public: | |
59 | AuthorizationGroup() { NumberOfAuthTags = 0; } | |
60 | AuthorizationGroup(const AclAuthorizationSet &, Allocator &alloc); | |
61 | AuthorizationGroup(AclAuthorization tag, Allocator &alloc); | |
62 | void destroy(Allocator &alloc); | |
63 | ||
64 | bool empty() const { return NumberOfAuthTags == 0; } | |
65 | unsigned int size() const { return NumberOfAuthTags; } | |
66 | unsigned int count() const { return NumberOfAuthTags; } | |
67 | CSSM_ACL_AUTHORIZATION_TAG operator [] (unsigned ix) const | |
68 | { assert(ix < size()); return AuthTags[ix]; } | |
69 | ||
70 | bool contains(CSSM_ACL_AUTHORIZATION_TAG tag) const; | |
e3d460c9 | 71 | bool containsOnly(CSSM_ACL_AUTHORIZATION_TAG tag) const; |
b1ab9ed8 A |
72 | operator AclAuthorizationSet () const; |
73 | }; | |
74 | ||
75 | class AclOwnerPrototype; | |
76 | ||
77 | class AclEntryPrototype : public PodWrapper<AclEntryPrototype, CSSM_ACL_ENTRY_PROTOTYPE> { | |
78 | public: | |
79 | AclEntryPrototype() { clearPod(); } | |
80 | explicit AclEntryPrototype(const AclOwnerPrototype &proto); | |
81 | AclEntryPrototype(const CSSM_LIST &subj, bool delegate = false) | |
82 | { clearPod(); TypedSubject = subj; Delegate = delegate; } | |
83 | ||
84 | TypedList &subject() { return TypedList::overlay(TypedSubject); } | |
85 | const TypedList &subject() const { return TypedList::overlay(TypedSubject); } | |
86 | ||
87 | bool delegate() const { return Delegate; } | |
88 | void delegate(bool d) { Delegate = d; } | |
89 | ||
90 | char *tag() { return EntryTag[0] ? EntryTag : NULL; } | |
91 | void tag(const char *tagString); | |
92 | void tag(const std::string &tagString); | |
93 | const char *tag() const { return EntryTag[0] ? EntryTag : NULL; } | |
94 | std::string s_tag() const { return EntryTag; } | |
95 | ||
96 | AuthorizationGroup &authorization() { return AuthorizationGroup::overlay(Authorization); } | |
97 | const AuthorizationGroup &authorization() const | |
98 | { return AuthorizationGroup::overlay(Authorization); } | |
99 | }; | |
100 | ||
101 | class AclOwnerPrototype : public PodWrapper<AclOwnerPrototype, CSSM_ACL_OWNER_PROTOTYPE> { | |
102 | public: | |
103 | AclOwnerPrototype() { clearPod(); } | |
104 | explicit AclOwnerPrototype(const AclEntryPrototype &proto) | |
105 | { TypedSubject = proto.subject(); delegate(proto.delegate()); } | |
106 | AclOwnerPrototype(const CSSM_LIST &subj, bool del = false) | |
107 | { TypedSubject = subj; delegate(del); } | |
108 | ||
109 | TypedList &subject() { return TypedList::overlay(TypedSubject); } | |
110 | const TypedList &subject() const { return TypedList::overlay(TypedSubject); } | |
111 | bool delegate() const { return Delegate; } | |
112 | void delegate(bool d) { Delegate = d; } | |
113 | }; | |
114 | ||
115 | class AclEntryInfo : public PodWrapper<AclEntryInfo, CSSM_ACL_ENTRY_INFO> { | |
116 | public: | |
117 | AclEntryInfo() { clearPod(); } | |
118 | AclEntryInfo(const AclEntryPrototype &prot, CSSM_ACL_HANDLE h = 0) | |
119 | { proto() = prot; handle() = h; } | |
120 | ||
121 | AclEntryPrototype &proto() { return AclEntryPrototype::overlay(EntryPublicInfo); } | |
122 | const AclEntryPrototype &proto() const | |
123 | { return AclEntryPrototype::overlay(EntryPublicInfo); } | |
124 | ||
125 | operator AclEntryPrototype &() { return proto(); } | |
126 | operator const AclEntryPrototype &() const { return proto(); } | |
127 | ||
128 | CSSM_ACL_HANDLE &handle() { return EntryHandle; } | |
129 | const CSSM_ACL_HANDLE &handle() const { return EntryHandle; } | |
130 | void handle(CSSM_ACL_HANDLE h) { EntryHandle = h; } | |
131 | }; | |
132 | ||
133 | class AclEntryInput : public PodWrapper<AclEntryInput, CSSM_ACL_ENTRY_INPUT> { | |
134 | public: | |
135 | AclEntryInput() { clearPod(); } | |
136 | AclEntryInput(const CSSM_ACL_ENTRY_PROTOTYPE &prot) | |
137 | { Prototype = prot; Callback = NULL; CallerContext = NULL; } | |
138 | ||
139 | AclEntryInput &operator = (const CSSM_ACL_ENTRY_PROTOTYPE &prot) | |
140 | { Prototype = prot; Callback = NULL; CallerContext = NULL; return *this; } | |
141 | ||
142 | AclEntryPrototype &proto() { return AclEntryPrototype::overlay(Prototype); } | |
143 | const AclEntryPrototype &proto() const { return AclEntryPrototype::overlay(Prototype); } | |
144 | //@@@ not supporting callback features (yet) | |
145 | }; | |
146 | ||
147 | class AclEdit : public PodWrapper<AclEdit, CSSM_ACL_EDIT> { | |
148 | public: | |
149 | AclEdit(CSSM_ACL_EDIT_MODE m, CSSM_ACL_HANDLE h, const AclEntryInput *data) | |
150 | { EditMode = m; OldEntryHandle = h; NewEntry = data; } | |
151 | AclEdit(const AclEntryInput &add) | |
152 | { EditMode = CSSM_ACL_EDIT_MODE_ADD; OldEntryHandle = CSSM_INVALID_HANDLE; NewEntry = &add; } | |
153 | AclEdit(CSSM_ACL_HANDLE h, const AclEntryInput &modify) | |
154 | { EditMode = CSSM_ACL_EDIT_MODE_REPLACE; OldEntryHandle = h; NewEntry = &modify; } | |
155 | AclEdit(CSSM_ACL_HANDLE h) | |
156 | { EditMode = CSSM_ACL_EDIT_MODE_DELETE; OldEntryHandle = h; NewEntry = NULL; } | |
157 | ||
158 | CSSM_ACL_EDIT_MODE mode() const { return EditMode; } | |
159 | CSSM_ACL_HANDLE handle() const { return OldEntryHandle; } | |
160 | const AclEntryInput *newEntry() const { return AclEntryInput::overlay(NewEntry); } | |
161 | }; | |
162 | ||
163 | ||
164 | // | |
165 | // Allocating versions of Acl structures | |
166 | // | |
167 | class AutoAclOwnerPrototype { | |
168 | NOCOPY(AutoAclOwnerPrototype) | |
169 | public: | |
170 | // allocator can be set after construction | |
171 | AutoAclOwnerPrototype(Allocator *allocator = NULL) | |
172 | : mAclOwnerPrototype(NULL), mAllocator(allocator) { } | |
173 | ~AutoAclOwnerPrototype(); | |
174 | ||
175 | operator bool () const { return mAllocator; } | |
176 | bool operator ! () const { return !mAllocator; } | |
177 | ||
178 | operator AclOwnerPrototype * () { return make(); } | |
179 | operator AclOwnerPrototype & () { return *make(); } | |
180 | AclOwnerPrototype &operator * () { return *make(); } | |
181 | ||
182 | TypedList &subject() { return make()->subject(); } | |
183 | TypedList &subject() const | |
184 | { assert(mAclOwnerPrototype); return mAclOwnerPrototype->subject(); } | |
185 | bool delegate() const | |
186 | { assert(mAclOwnerPrototype); return mAclOwnerPrototype->delegate(); } | |
187 | void delegate(bool d) { make()->delegate(d); } | |
188 | ||
189 | void allocator(Allocator &allocator); | |
190 | Allocator &allocator() const { assert(mAllocator); return *mAllocator; } | |
191 | ||
192 | AclOwnerPrototype &operator = (const TypedList &subj) | |
193 | { make()->subject() = subj; make()->delegate(false); return *mAclOwnerPrototype; } | |
194 | ||
195 | const AclOwnerPrototype *release() | |
196 | { AclOwnerPrototype *r = mAclOwnerPrototype; mAclOwnerPrototype = NULL; return r; } | |
197 | ||
198 | private: | |
199 | AclOwnerPrototype *mAclOwnerPrototype; | |
200 | Allocator *mAllocator; | |
201 | ||
202 | AclOwnerPrototype *make(); | |
203 | }; | |
204 | ||
205 | ||
206 | class AutoAclEntryInfoList { | |
207 | NOCOPY(AutoAclEntryInfoList) | |
208 | public: | |
209 | // allocator can be set after construction | |
210 | AutoAclEntryInfoList(Allocator *allocator = NULL) | |
211 | : mEntries(NULL), mCount(0), mAllocator(allocator) { } | |
212 | ~AutoAclEntryInfoList() { clear(); } | |
213 | ||
214 | operator bool () const { return mAllocator; } | |
215 | bool operator ! () const { return !mAllocator; } | |
216 | operator uint32 *() { return &mCount; } | |
217 | operator CSSM_ACL_ENTRY_INFO ** () { return reinterpret_cast<CSSM_ACL_ENTRY_INFO **>(&mEntries); } | |
218 | ||
219 | void allocator(Allocator &allocator); | |
220 | Allocator &allocator() const { assert(mAllocator); return *mAllocator; } | |
221 | ||
222 | const AclEntryInfo &at(uint32 ix) const | |
223 | { assert(ix < mCount); return mEntries[ix]; } | |
224 | const AclEntryInfo &operator [] (uint32 ix) const { return at(ix); } | |
225 | AclEntryInfo &at(uint32 ix); | |
226 | AclEntryInfo &operator[] (uint32 ix) { return at(ix); } | |
227 | ||
228 | uint32 size() const { return mCount; } | |
229 | uint32 count() const { return mCount; } | |
230 | AclEntryInfo *entries() const { return mEntries; } | |
231 | ||
232 | void clear(); | |
233 | void size(uint32 newSize); | |
234 | ||
235 | // structured adders. Inputs must be chunk-allocated with our Allocator | |
236 | void add(const TypedList &subj, const AclAuthorizationSet &auths, const char *tag = NULL); | |
237 | void addPin(const TypedList &subj, uint32 slot); | |
238 | void addPinState(uint32 slot, uint32 state); | |
239 | void addPinState(uint32 slot, uint32 state, uint32 count); | |
240 | ||
241 | void release() { mAllocator = NULL; } | |
242 | ||
243 | private: | |
244 | AclEntryInfo *mEntries; | |
245 | uint32 mCount; | |
246 | Allocator *mAllocator; | |
247 | }; | |
248 | ||
249 | // | |
250 | // Extract the pin number from a "PIN%d?" tag. | |
251 | // Returns 0 if the tag isn't of that form. | |
252 | // | |
253 | uint32 pinFromAclTag(const char *tag, const char *suffix = NULL); | |
254 | ||
255 | ||
256 | class AutoAuthorizationGroup : public AuthorizationGroup { | |
257 | public: | |
258 | AutoAuthorizationGroup(Allocator &alloc) : allocator(alloc) { } | |
259 | explicit AutoAuthorizationGroup(const AclAuthorizationSet &set, | |
260 | Allocator &alloc) : AuthorizationGroup(set, alloc), allocator(alloc) { } | |
261 | ~AutoAuthorizationGroup() { destroy(allocator); } | |
262 | ||
263 | Allocator &allocator; | |
264 | }; | |
265 | ||
266 | ||
267 | // | |
268 | // Walkers for the CSSM API structure types | |
269 | // | |
270 | namespace DataWalkers { | |
271 | ||
272 | // AclEntryInput | |
273 | template <class Action> | |
274 | AclEntryInput *walk(Action &operate, AclEntryInput * &input) | |
275 | { | |
276 | operate(input); | |
277 | walk(operate, input->proto()); | |
278 | return input; | |
279 | } | |
280 | ||
281 | template <class Action> | |
282 | void walk(Action &operate, AclEntryInput &input) | |
283 | { | |
284 | operate(input); | |
285 | walk(operate, input.proto()); | |
286 | } | |
287 | ||
288 | // AclEntryInfo | |
289 | template <class Action> | |
290 | void walk(Action &operate, AclEntryInfo &info) | |
291 | { | |
292 | operate(info); | |
293 | walk(operate, info.proto()); | |
294 | } | |
295 | ||
296 | // AuthorizationGroup | |
297 | template <class Action> | |
298 | void walk(Action &operate, AuthorizationGroup &auth) | |
299 | { | |
300 | operate(auth); | |
301 | uint32 count = auth.count(); | |
302 | operate.blob(auth.AuthTags, count * sizeof(auth.AuthTags[0])); | |
303 | for (uint32 n = 0; n < count; n++) | |
304 | operate(auth.AuthTags[n]); | |
305 | } | |
306 | ||
307 | template <class Action> | |
308 | void walk(Action &operate, CSSM_AUTHORIZATIONGROUP &auth) | |
309 | { walk(operate, static_cast<CSSM_AUTHORIZATIONGROUP &>(auth)); } | |
310 | ||
311 | // AclEntryPrototype | |
312 | template <class Action> | |
313 | void enumerate(Action &operate, AclEntryPrototype &proto) | |
314 | { | |
315 | walk(operate, proto.subject()); | |
316 | walk(operate, proto.authorization()); | |
317 | //@@@ ignoring validity period | |
318 | } | |
319 | ||
320 | template <class Action> | |
321 | void walk(Action &operate, AclEntryPrototype &proto) | |
322 | { | |
323 | operate(proto); | |
324 | enumerate(operate, proto); | |
325 | } | |
326 | ||
327 | template <class Action> | |
328 | AclEntryPrototype *walk(Action &operate, AclEntryPrototype * &proto) | |
329 | { | |
330 | operate(proto); | |
331 | enumerate(operate, *proto); | |
332 | return proto; | |
333 | } | |
334 | ||
335 | // AclOwnerPrototype | |
336 | template <class Action> | |
337 | void walk(Action &operate, AclOwnerPrototype &proto) | |
338 | { | |
339 | operate(proto); | |
340 | walk(operate, proto.subject()); | |
341 | } | |
342 | ||
343 | template <class Action> | |
344 | AclOwnerPrototype *walk(Action &operate, AclOwnerPrototype * &proto) | |
345 | { | |
346 | operate(proto); | |
347 | walk(operate, proto->subject()); | |
348 | return proto; | |
349 | } | |
350 | ||
351 | ||
352 | } // end namespace DataWalkers | |
353 | ||
354 | } // end namespace Security | |
355 | ||
356 | ||
357 | #endif //_CSSMACLPOD |