]> git.saurik.com Git - apple/security.git/blob - Security/libsecurity_cdsa_utilities/lib/cssmaclpod.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / Security / 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
81 AuthorizationGroup::operator AclAuthorizationSet() const
82 {
83 return AclAuthorizationSet(AuthTags, &AuthTags[NumberOfAuthTags]);
84 }
85
86 AclEntryPrototype::AclEntryPrototype(const AclOwnerPrototype &proto)
87 {
88 memset(this, 0, sizeof(*this));
89 TypedSubject = proto.subject(); Delegate = proto.delegate();
90 //@@@ set authorization to "is owner" pseudo-auth? See cssmacl.h
91 }
92
93 void AclEntryPrototype::tag(const char *tagString)
94 {
95 if (tagString == NULL)
96 EntryTag[0] = '\0';
97 else if (strlen(tagString) > CSSM_MODULE_STRING_SIZE)
98 CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_ENTRY_TAG);
99 else
100 strcpy(EntryTag, tagString);
101 }
102
103 void AclEntryPrototype::tag(const string &tagString)
104 {
105 if (tagString.length() > CSSM_MODULE_STRING_SIZE)
106 CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_ENTRY_TAG);
107 else
108 memcpy(EntryTag, tagString.c_str(), tagString.length() + 1);
109 }
110
111
112 AclOwnerPrototype *AutoAclOwnerPrototype::make()
113 {
114 if (!mAclOwnerPrototype) {
115 mAclOwnerPrototype = (AclOwnerPrototype*) mAllocator->malloc(sizeof(AclOwnerPrototype));
116 new (mAclOwnerPrototype) AclOwnerPrototype;
117 mAclOwnerPrototype->clearPod();
118 }
119 return mAclOwnerPrototype;
120 }
121
122 AutoAclOwnerPrototype::~AutoAclOwnerPrototype()
123 {
124 if (mAllocator)
125 DataWalkers::chunkFree(mAclOwnerPrototype, *mAllocator);
126 }
127
128 void
129 AutoAclOwnerPrototype::allocator(Allocator &allocator)
130 {
131 mAllocator = &allocator;
132 }
133
134
135 void AutoAclEntryInfoList::size(uint32 newSize)
136 {
137 assert(mAllocator);
138 mEntries = mAllocator->alloc<AclEntryInfo>(mEntries, newSize);
139 for (uint32 n = mCount; n < newSize; n++)
140 mEntries[n].clearPod();
141 mCount = newSize;
142 }
143
144
145 AclEntryInfo &AutoAclEntryInfoList::at(uint32 ix)
146 {
147 if (ix >= mCount)
148 size(ix + 1); // expand vector
149 return mEntries[ix];
150 }
151
152
153 void AutoAclEntryInfoList::clear()
154 {
155 if (mAllocator)
156 {
157 DataWalkers::ChunkFreeWalker w(*mAllocator);
158 for (uint32 ix = 0; ix < mCount; ix++)
159 walk(w, mEntries[ix]);
160 mAllocator->free(mEntries);
161 mEntries = NULL;
162 mCount = 0;
163 }
164 }
165
166 void AutoAclEntryInfoList::allocator(Allocator &allocator)
167 {
168 mAllocator = &allocator;
169 }
170
171
172 void AutoAclEntryInfoList::add(const TypedList &subj, const AclAuthorizationSet &auths, const char *tag /* = NULL */)
173 {
174 AclEntryInfo &info = at(size());
175 info.proto() = AclEntryPrototype(subj);
176 info.proto().authorization() = AuthorizationGroup(auths, allocator());
177 info.proto().tag(tag);
178 info.handle(size());
179 }
180
181 void AutoAclEntryInfoList::addPin(const TypedList &subj, uint32 slot)
182 {
183 char tag[20];
184 snprintf(tag, sizeof(tag), "PIN%d", slot);
185 add(subj, CSSM_ACL_AUTHORIZATION_PREAUTH(slot), tag);
186 }
187
188 void AutoAclEntryInfoList::addPinState(uint32 slot, uint32 status)
189 {
190 char tag[20];
191 snprintf(tag, sizeof(tag), "PIN%d?", slot);
192 TypedList subj(allocator(), CSSM_WORDID_PIN,
193 new(allocator()) ListElement(slot),
194 new(allocator()) ListElement(status));
195 add(subj, CSSM_WORDID_PIN, tag);
196 }
197
198 void AutoAclEntryInfoList::addPinState(uint32 slot, uint32 status, uint32 count)
199 {
200 char tag[20];
201 snprintf(tag, sizeof(tag), "PIN%d?", slot);
202 TypedList subj(allocator(), CSSM_WORDID_PIN,
203 new(allocator()) ListElement(slot),
204 new(allocator()) ListElement(status),
205 new(allocator()) ListElement(count));
206 add(subj, CSSM_WORDID_PIN, tag);
207 }
208
209 uint32 pinFromAclTag(const char *tag, const char *suffix /* = NULL */)
210 {
211 if (tag) {
212 char format[20];
213 snprintf(format, sizeof(format), "PIN%%d%s%%n", suffix ? suffix : "");
214 uint32 pin;
215 unsigned consumed;
216 sscanf(tag, format, &pin, &consumed);
217 if (consumed == strlen(tag)) // complete and sufficient
218 return pin;
219 }
220 return 0;
221 }
222
223 } // namespace Security