]> git.saurik.com Git - apple/security.git/blob - libsecurity_cdsa_utilities/lib/cssmaclpod.cpp
Security-55163.44.tar.gz
[apple/security.git] / libsecurity_cdsa_utilities / lib / cssmaclpod.cpp
1 /*
2 * Copyright (c) 2000-2004,2006-2007 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 = 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 = new AclOwnerPrototype;
116 mAclOwnerPrototype->clearPod();
117 }
118 return mAclOwnerPrototype;
119 }
120
121 AutoAclOwnerPrototype::~AutoAclOwnerPrototype()
122 {
123 if (mAllocator)
124 DataWalkers::chunkFree(mAclOwnerPrototype, *mAllocator);
125 }
126
127 void
128 AutoAclOwnerPrototype::allocator(Allocator &allocator)
129 {
130 mAllocator = &allocator;
131 }
132
133
134 void AutoAclEntryInfoList::size(uint32 newSize)
135 {
136 assert(mAllocator);
137 mEntries = mAllocator->alloc<AclEntryInfo>(mEntries, newSize);
138 for (uint32 n = mCount; n < newSize; n++)
139 mEntries[n].clearPod();
140 mCount = newSize;
141 }
142
143
144 AclEntryInfo &AutoAclEntryInfoList::at(uint32 ix)
145 {
146 if (ix >= mCount)
147 size(ix + 1); // expand vector
148 return mEntries[ix];
149 }
150
151
152 void AutoAclEntryInfoList::clear()
153 {
154 if (mAllocator)
155 {
156 DataWalkers::ChunkFreeWalker w(*mAllocator);
157 for (uint32 ix = 0; ix < mCount; ix++)
158 walk(w, mEntries[ix]);
159 mAllocator->free(mEntries);
160 mEntries = NULL;
161 mCount = 0;
162 }
163 }
164
165 void AutoAclEntryInfoList::allocator(Allocator &allocator)
166 {
167 mAllocator = &allocator;
168 }
169
170
171 void AutoAclEntryInfoList::add(const TypedList &subj, const AclAuthorizationSet &auths, const char *tag /* = NULL */)
172 {
173 AclEntryInfo &info = at(size());
174 info.proto() = AclEntryPrototype(subj);
175 info.proto().authorization() = AuthorizationGroup(auths, allocator());
176 info.proto().tag(tag);
177 info.handle(size());
178 }
179
180 void AutoAclEntryInfoList::addPin(const TypedList &subj, uint32 slot)
181 {
182 char tag[20];
183 snprintf(tag, sizeof(tag), "PIN%d", slot);
184 add(subj, CSSM_ACL_AUTHORIZATION_PREAUTH(slot), tag);
185 }
186
187 void AutoAclEntryInfoList::addPinState(uint32 slot, uint32 status)
188 {
189 char tag[20];
190 snprintf(tag, sizeof(tag), "PIN%d?", slot);
191 TypedList subj(allocator(), CSSM_WORDID_PIN,
192 new(allocator()) ListElement(slot),
193 new(allocator()) ListElement(status));
194 add(subj, CSSM_WORDID_PIN, tag);
195 }
196
197 void AutoAclEntryInfoList::addPinState(uint32 slot, uint32 status, uint32 count)
198 {
199 char tag[20];
200 snprintf(tag, sizeof(tag), "PIN%d?", slot);
201 TypedList subj(allocator(), CSSM_WORDID_PIN,
202 new(allocator()) ListElement(slot),
203 new(allocator()) ListElement(status),
204 new(allocator()) ListElement(count));
205 add(subj, CSSM_WORDID_PIN, tag);
206 }
207
208 uint32 pinFromAclTag(const char *tag, const char *suffix /* = NULL */)
209 {
210 if (tag) {
211 char format[20];
212 snprintf(format, sizeof(format), "PIN%%d%s%%n", suffix ? suffix : "");
213 uint32 pin;
214 unsigned consumed;
215 sscanf(tag, format, &pin, &consumed);
216 if (consumed == strlen(tag)) // complete and sufficient
217 return pin;
218 }
219 return 0;
220 }
221
222 } // namespace Security