]> git.saurik.com Git - apple/security.git/blame - OSX/libsecurity_cdsa_utilities/lib/cssmaclpod.cpp
Security-57740.1.18.tar.gz
[apple/security.git] / OSX / libsecurity_cdsa_utilities / lib / cssmaclpod.cpp
CommitLineData
b1ab9ed8 1/*
d8f41ccd 2 * Copyright (c) 2000-2004,2006-2007,2011-2012 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#include <security_cdsa_utilities/cssmaclpod.h>
29#include <security_cdsa_utilities/cssmwalkers.h>
30#include <cstdarg>
31
32
33namespace Security {
34
35
36//
37// AclAuthorizationSets
38//
39AclAuthorizationSet::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//
56AuthorizationGroup::AuthorizationGroup(const AclAuthorizationSet &auths, Allocator &alloc)
57{
427c49bc 58 NumberOfAuthTags = (uint32)auths.size();
b1ab9ed8
A
59 AuthTags = alloc.alloc<CSSM_ACL_AUTHORIZATION_TAG>(NumberOfAuthTags);
60 copy(auths.begin(), auths.end(), AuthTags); // happens to be sorted
61}
62
63AuthorizationGroup::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
70void AuthorizationGroup::destroy(Allocator &alloc)
71{
72 alloc.free(AuthTags);
73}
e3d460c9 74
b1ab9ed8
A
75bool AuthorizationGroup::contains(CSSM_ACL_AUTHORIZATION_TAG tag) const
76{
77 return find(AuthTags, &AuthTags[NumberOfAuthTags], tag) != &AuthTags[NumberOfAuthTags];
78}
79
e3d460c9
A
80bool AuthorizationGroup::containsOnly(CSSM_ACL_AUTHORIZATION_TAG tag) const
81{
82 return count() == 1 && (*this)[0] == tag;
83}
84
b1ab9ed8
A
85
86AuthorizationGroup::operator AclAuthorizationSet() const
87{
88 return AclAuthorizationSet(AuthTags, &AuthTags[NumberOfAuthTags]);
89}
90
91AclEntryPrototype::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
98void 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
108void 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
117AclOwnerPrototype *AutoAclOwnerPrototype::make()
118{
119 if (!mAclOwnerPrototype) {
427c49bc
A
120 mAclOwnerPrototype = (AclOwnerPrototype*) mAllocator->malloc(sizeof(AclOwnerPrototype));
121 new (mAclOwnerPrototype) AclOwnerPrototype;
b1ab9ed8
A
122 mAclOwnerPrototype->clearPod();
123 }
124 return mAclOwnerPrototype;
125}
126
127AutoAclOwnerPrototype::~AutoAclOwnerPrototype()
128{
129 if (mAllocator)
130 DataWalkers::chunkFree(mAclOwnerPrototype, *mAllocator);
131}
132
133void
134AutoAclOwnerPrototype::allocator(Allocator &allocator)
135{
136 mAllocator = &allocator;
137}
138
139
140void 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
150AclEntryInfo &AutoAclEntryInfoList::at(uint32 ix)
151{
152 if (ix >= mCount)
153 size(ix + 1); // expand vector
154 return mEntries[ix];
155}
156
157
158void 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
171void AutoAclEntryInfoList::allocator(Allocator &allocator)
172{
173 mAllocator = &allocator;
174}
175
176
177void 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
186void 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
193void 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
203void 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
214uint32 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;
220 unsigned consumed;
221 sscanf(tag, format, &pin, &consumed);
222 if (consumed == strlen(tag)) // complete and sufficient
223 return pin;
224 }
225 return 0;
226}
227
228} // namespace Security