/ OSX / libsecurity_cdsa_utilities / lib / cssmcred.cpp
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