2 * Copyright (c) 2000-2004,2006-2007,2011-2012 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
26 // cssmaclpod - enhanced PodWrappers for ACL-related CSSM data structures
28 #include <security_cdsa_utilities/cssmaclpod.h>
29 #include <security_cdsa_utilities/cssmwalkers.h>
37 // AclAuthorizationSets
39 AclAuthorizationSet::AclAuthorizationSet(AclAuthorization auth0
, AclAuthorization auth
, ...)
47 auth
= va_arg(args
, AclAuthorization
);
54 // AclAuthorizationGroups
56 AuthorizationGroup::AuthorizationGroup(const AclAuthorizationSet
&auths
, Allocator
&alloc
)
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
63 AuthorizationGroup::AuthorizationGroup(CSSM_ACL_AUTHORIZATION_TAG tag
, Allocator
&alloc
)
65 AuthTags
= alloc
.alloc
<CSSM_ACL_AUTHORIZATION_TAG
>(1);
70 void AuthorizationGroup::destroy(Allocator
&alloc
)
75 bool AuthorizationGroup::contains(CSSM_ACL_AUTHORIZATION_TAG tag
) const
77 return find(AuthTags
, &AuthTags
[NumberOfAuthTags
], tag
) != &AuthTags
[NumberOfAuthTags
];
80 bool AuthorizationGroup::containsOnly(CSSM_ACL_AUTHORIZATION_TAG tag
) const
82 return count() == 1 && (*this)[0] == tag
;
86 AuthorizationGroup::operator AclAuthorizationSet() const
88 return AclAuthorizationSet(AuthTags
, &AuthTags
[NumberOfAuthTags
]);
91 AclEntryPrototype::AclEntryPrototype(const AclOwnerPrototype
&proto
)
93 memset(this, 0, sizeof(*this));
94 TypedSubject
= proto
.subject(); Delegate
= proto
.delegate();
95 //@@@ set authorization to "is owner" pseudo-auth? See cssmacl.h
98 void AclEntryPrototype::tag(const char *tagString
)
100 if (tagString
== NULL
)
102 else if (strlen(tagString
) > CSSM_MODULE_STRING_SIZE
)
103 CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_ENTRY_TAG
);
105 strcpy(EntryTag
, tagString
);
108 void AclEntryPrototype::tag(const string
&tagString
)
110 if (tagString
.length() > CSSM_MODULE_STRING_SIZE
)
111 CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_ENTRY_TAG
);
113 memcpy(EntryTag
, tagString
.c_str(), tagString
.length() + 1);
117 AclOwnerPrototype
*AutoAclOwnerPrototype::make()
119 if (!mAclOwnerPrototype
) {
120 mAclOwnerPrototype
= (AclOwnerPrototype
*) mAllocator
->malloc(sizeof(AclOwnerPrototype
));
121 new (mAclOwnerPrototype
) AclOwnerPrototype
;
122 mAclOwnerPrototype
->clearPod();
124 return mAclOwnerPrototype
;
127 AutoAclOwnerPrototype::~AutoAclOwnerPrototype()
130 DataWalkers::chunkFree(mAclOwnerPrototype
, *mAllocator
);
134 AutoAclOwnerPrototype::allocator(Allocator
&allocator
)
136 mAllocator
= &allocator
;
140 void AutoAclEntryInfoList::size(uint32 newSize
)
143 mEntries
= mAllocator
->alloc
<AclEntryInfo
>(mEntries
, newSize
);
144 for (uint32 n
= mCount
; n
< newSize
; n
++)
145 mEntries
[n
].clearPod();
150 AclEntryInfo
&AutoAclEntryInfoList::at(uint32 ix
)
153 size(ix
+ 1); // expand vector
158 void AutoAclEntryInfoList::clear()
162 DataWalkers::ChunkFreeWalker
w(*mAllocator
);
163 for (uint32 ix
= 0; ix
< mCount
; ix
++)
164 walk(w
, mEntries
[ix
]);
165 mAllocator
->free(mEntries
);
171 void AutoAclEntryInfoList::allocator(Allocator
&allocator
)
173 mAllocator
= &allocator
;
177 void AutoAclEntryInfoList::add(const TypedList
&subj
, const AclAuthorizationSet
&auths
, const char *tag
/* = NULL */)
179 AclEntryInfo
&info
= at(size());
180 info
.proto() = AclEntryPrototype(subj
);
181 info
.proto().authorization() = AuthorizationGroup(auths
, allocator());
182 info
.proto().tag(tag
);
186 void AutoAclEntryInfoList::addPin(const TypedList
&subj
, uint32 slot
)
189 snprintf(tag
, sizeof(tag
), "PIN%d", slot
);
190 add(subj
, CSSM_ACL_AUTHORIZATION_PREAUTH(slot
), tag
);
193 void AutoAclEntryInfoList::addPinState(uint32 slot
, uint32 status
)
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
);
203 void AutoAclEntryInfoList::addPinState(uint32 slot
, uint32 status
, uint32 count
)
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
);
214 uint32
pinFromAclTag(const char *tag
, const char *suffix
/* = NULL */)
218 snprintf(format
, sizeof(format
), "PIN%%d%s%%n", suffix
? suffix
: "");
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
229 } // namespace Security