cssmcred.cpp
1 /* 2 * Copyright (c) 2000-2001,2003-2004,2006,2011,2014 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 // cssmcred - enhanced PodWrappers and construction aids for ACL credentials 27 // 28 #include <security_cdsa_utilities/cssmcred.h> 29 30 31 namespace Security { 32 33 // 34 // Scan a SampleGroup for samples with a given CSSM_SAMPLE_TYPE. 35 // Collect all matching samples into a list (which is cleared to begin with). 36 // Return true if any were found, false if none. 37 // Throw if any of the samples are obviously malformed. 38 // 39 bool SampleGroup::collect(CSSM_SAMPLE_TYPE sampleType, list<CssmSample> &matches) const 40 { 41 for (uint32 n = 0; n < length(); n++) { 42 TypedList sample = (*this)[n]; 43 sample.checkProper(); 44 if (sample.type() == sampleType) { 45 sample.snip(); // skip sample type 46 matches.push_back(sample); 47 } 48 } 49 return !matches.empty(); 50 } 51 52 53 // 54 // AccessCredentials 55 // 56 const AccessCredentials& AccessCredentials::null_credential() 57 { 58 static const CSSM_ACCESS_CREDENTIALS null_credentials = { "" }; // and more nulls 59 return AccessCredentials::overlay(null_credentials); 60 } 61 62 void AccessCredentials::tag(const char *tagString) 63 { 64 if (tagString == NULL) 65 EntryTag[0] = '\0'; 66 else if (strlen(tagString) > CSSM_MODULE_STRING_SIZE) 67 CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_ENTRY_TAG); 68 else 69 strcpy(EntryTag, tagString); 70 } 71 72 bool AccessCredentials::authorizesUI() const { 73 list<CssmSample> uisamples; 74 75 if(samples().collect(CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT, uisamples)) { 76 // The existence of a lone keychain prompt gives UI access 77 return true; 78 } 79 80 samples().collect(CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK, uisamples); 81 samples().collect(CSSM_SAMPLE_TYPE_THRESHOLD, uisamples); 82 83 for (list<CssmSample>::iterator it = uisamples.begin(); it != uisamples.end(); it++) { 84 TypedList &sample = *it; 85 86 if(!sample.isProper()) { 87 secnotice("integrity", "found a non-proper sample, skipping..."); 88 continue; 89 } 90 91 switch (sample.type()) { 92 case CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT: 93 // these credentials allow UI 94 return true; 95 } 96 } 97 98 // no interesting credential found; no UI for you 99 return false; 100 } 101 102 // 103 // AutoCredentials self-constructing credentials structure 104 // 105 AutoCredentials::AutoCredentials(Allocator &alloc) : allocator(alloc) 106 { 107 init(); 108 } 109 110 AutoCredentials::AutoCredentials(Allocator &alloc, uint32 nSamples) : allocator(alloc) 111 { 112 init(); 113 getSample(nSamples - 1); // extend array to nSamples elements 114 } 115 116 void AutoCredentials::init() 117 { 118 sampleArray = NULL; 119 nSamples = 0; 120 } 121 122 123 CssmSample &AutoCredentials::getSample(uint32 n) 124 { 125 if (n >= nSamples) { 126 sampleArray = allocator.alloc<CssmSample>(sampleArray, nSamples = n + 1); 127 Samples.Samples = sampleArray; 128 Samples.NumberOfSamples = nSamples; 129 } 130 return sampleArray[n]; 131 } 132 133 } // end namespace Security