]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_cdsa_utilities/lib/cssmaclpod.cpp
Security-59306.11.20.tar.gz
[apple/security.git] / OSX / libsecurity_cdsa_utilities / lib / cssmaclpod.cpp
1 /*
2 * Copyright (c) 2000-2004,2006-2007,2011-2012 Apple Inc. All Rights Reserved.
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 #include <security_cdsa_utilities/cssmaclpod.h>
29 #include <security_cdsa_utilities/cssmwalkers.h>
30 #include <cstdarg>
31
32
33 namespace Security {
34
35
36 //
37 // AclAuthorizationSets
38 //
39 AclAuthorizationSet::AclAuthorizationSet(AclAuthorization auth0, AclAuthorization auth, ...)
40 {
41 insert(auth0);
42
43 va_list args;
44 va_start(args, auth);
45 while (auth) {
46 insert(auth);
47 auth = va_arg(args, AclAuthorization);
48 }
49 va_end(args);
50 }
51
52
53 //
54 // AclAuthorizationGroups
55 //
56 AuthorizationGroup::AuthorizationGroup(const AclAuthorizationSet &auths, Allocator &alloc)
57 {
58 NumberOfAuthTags = (uint32)auths.size();
59 AuthTags = alloc.alloc<CSSM_ACL_AUTHORIZATION_TAG>(NumberOfAuthTags);
60 copy(auths.begin(), auths.end(), AuthTags); // happens to be sorted
61 }
62
63 AuthorizationGroup::AuthorizationGroup(CSSM_ACL_AUTHORIZATION_TAG tag, Allocator &alloc)
64 {
65 AuthTags = alloc.alloc<CSSM_ACL_AUTHORIZATION_TAG>(1);
66 AuthTags[0] = tag;
67 NumberOfAuthTags = 1;
68 }
69
70 void AuthorizationGroup::destroy(Allocator &alloc)
71 {
72 alloc.free(AuthTags);
73 }
74
75 bool AuthorizationGroup::contains(CSSM_ACL_AUTHORIZATION_TAG tag) const
76 {
77 return find(AuthTags, &AuthTags[NumberOfAuthTags], tag) != &AuthTags[NumberOfAuthTags];
78 }
79
80 bool AuthorizationGroup::containsOnly(CSSM_ACL_AUTHORIZATION_TAG tag) const
81 {
82 return count() == 1 && (*this)[0] == tag;
83 }
84
85
86 AuthorizationGroup::operator AclAuthorizationSet() const
87 {
88 return AclAuthorizationSet(AuthTags, &AuthTags[NumberOfAuthTags]);
89 }
90
91 AclEntryPrototype::AclEntryPrototype(const AclOwnerPrototype &proto)
92 {
93 memset(this, 0, sizeof(*this));
94 TypedSubject = proto.subject(); Delegate = proto.delegate();
95 //@@@ set authorization to "is owner" pseudo-auth? See cssmacl.h
96 }
97
98 void AclEntryPrototype::tag(const char *tagString)
99 {
100 if (tagString == NULL)
101 EntryTag[0] = '\0';
102 else if (strlen(tagString) > CSSM_MODULE_STRING_SIZE)
103 CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_ENTRY_TAG);
104 else
105 strcpy(EntryTag, tagString);
106 }
107
108 void AclEntryPrototype::tag(const string &tagString)
109 {
110 if (tagString.length() > CSSM_MODULE_STRING_SIZE)
111 CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_ENTRY_TAG);
112 else
113 memcpy(EntryTag, tagString.c_str(), tagString.length() + 1);
114 }
115
116
117 AclOwnerPrototype *AutoAclOwnerPrototype::make()
118 {
119 if (!mAclOwnerPrototype) {
120 mAclOwnerPrototype = (AclOwnerPrototype*) mAllocator->malloc(sizeof(AclOwnerPrototype));
121 new (mAclOwnerPrototype) AclOwnerPrototype;
122 mAclOwnerPrototype->clearPod();
123 }
124 return mAclOwnerPrototype;
125 }
126
127 AutoAclOwnerPrototype::~AutoAclOwnerPrototype()
128 {
129 if (mAllocator)
130 DataWalkers::chunkFree(mAclOwnerPrototype, *mAllocator);
131 }
132
133 void
134 AutoAclOwnerPrototype::allocator(Allocator &allocator)
135 {
136 mAllocator = &allocator;
137 }
138
139
140 void AutoAclEntryInfoList::size(uint32 newSize)
141 {
142 assert(mAllocator);
143 mEntries = mAllocator->alloc<AclEntryInfo>(mEntries, newSize);
144 for (uint32 n = mCount; n < newSize; n++)
145 mEntries[n].clearPod();
146 mCount = newSize;
147 }
148
149
150 AclEntryInfo &AutoAclEntryInfoList::at(uint32 ix)
151 {
152 if (ix >= mCount)
153 size(ix + 1); // expand vector
154 return mEntries[ix];
155 }
156
157
158 void AutoAclEntryInfoList::clear()
159 {
160 if (mAllocator)
161 {
162 DataWalkers::ChunkFreeWalker w(*mAllocator);
163 for (uint32 ix = 0; ix < mCount; ix++)
164 walk(w, mEntries[ix]);
165 mAllocator->free(mEntries);
166 mEntries = NULL;
167 mCount = 0;
168 }
169 }
170
171 void AutoAclEntryInfoList::allocator(Allocator &allocator)
172 {
173 mAllocator = &allocator;
174 }
175
176
177 void AutoAclEntryInfoList::add(const TypedList &subj, const AclAuthorizationSet &auths, const char *tag /* = NULL */)
178 {
179 AclEntryInfo &info = at(size());
180 info.proto() = AclEntryPrototype(subj);
181 info.proto().authorization() = AuthorizationGroup(auths, allocator());
182 info.proto().tag(tag);
183 info.handle(size());
184 }
185
186 void AutoAclEntryInfoList::addPin(const TypedList &subj, uint32 slot)
187 {
188 char tag[20];
189 snprintf(tag, sizeof(tag), "PIN%d", slot);
190 add(subj, CSSM_ACL_AUTHORIZATION_PREAUTH(slot), tag);
191 }
192
193 void AutoAclEntryInfoList::addPinState(uint32 slot, uint32 status)
194 {
195 char tag[20];
196 snprintf(tag, sizeof(tag), "PIN%d?", slot);
197 TypedList subj(allocator(), CSSM_WORDID_PIN,
198 new(allocator()) ListElement(slot),
199 new(allocator()) ListElement(status));
200 add(subj, CSSM_WORDID_PIN, tag);
201 }
202
203 void AutoAclEntryInfoList::addPinState(uint32 slot, uint32 status, uint32 count)
204 {
205 char tag[20];
206 snprintf(tag, sizeof(tag), "PIN%d?", slot);
207 TypedList subj(allocator(), CSSM_WORDID_PIN,
208 new(allocator()) ListElement(slot),
209 new(allocator()) ListElement(status),
210 new(allocator()) ListElement(count));
211 add(subj, CSSM_WORDID_PIN, tag);
212 }
213
214 uint32 pinFromAclTag(const char *tag, const char *suffix /* = NULL */)
215 {
216 if (tag) {
217 char format[20];
218 snprintf(format, sizeof(format), "PIN%%d%s%%n", suffix ? suffix : "");
219 uint32 pin = 0;
220 unsigned consumed = 0;
221 // sscanf does not count %n as a filled value so number of read variables should be just 1
222 if (sscanf(tag, format, &pin, &consumed) == 1 && consumed == strlen(tag)) { // complete and sufficient
223 return pin;
224 }
225 }
226 return 0;
227 }
228
229 } // namespace Security