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 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{ 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 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} 74 75bool AuthorizationGroup::contains(CSSM_ACL_AUTHORIZATION_TAG tag) const 76{ 77 return find(AuthTags, &AuthTags[NumberOfAuthTags], tag) != &AuthTags[NumberOfAuthTags]; 78} 79 80 81AuthorizationGroup::operator AclAuthorizationSet() const 82{ 83 return AclAuthorizationSet(AuthTags, &AuthTags[NumberOfAuthTags]); 84} 85 86AclEntryPrototype::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 93void 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 103void 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 112AclOwnerPrototype *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 122AutoAclOwnerPrototype::~AutoAclOwnerPrototype() 123{ 124 if (mAllocator) 125 DataWalkers::chunkFree(mAclOwnerPrototype, *mAllocator); 126} 127 128void 129AutoAclOwnerPrototype::allocator(Allocator &allocator) 130{ 131 mAllocator = &allocator; 132} 133 134 135void 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 145AclEntryInfo &AutoAclEntryInfoList::at(uint32 ix) 146{ 147 if (ix >= mCount) 148 size(ix + 1); // expand vector 149 return mEntries[ix]; 150} 151 152 153void 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 166void AutoAclEntryInfoList::allocator(Allocator &allocator) 167{ 168 mAllocator = &allocator; 169} 170 171 172void 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 181void 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 188void 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 198void 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 209uint32 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 224