/ OSX / libsecurity_mds / lib / MDSPrefs.cpp
MDSPrefs.cpp
  1  /*
  2   * Copyright (c) 2000-2001,2011,2014 Apple Inc. All Rights Reserved.
  3   * 
  4   * The contents of this file constitute Original Code as defined in and are
  5   * subject to the Apple Public Source License Version 1.2 (the 'License').
  6   * You may not use this file except in compliance with the License. Please obtain
  7   * a copy of the License at http://www.apple.com/publicsource and read it before
  8   * using this file.
  9   * 
 10   * This Original Code and all software distributed under the License are
 11   * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
 12   * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
 13   * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 14   * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
 15   * specific language governing rights and limitations under the License.
 16   */
 17  
 18  
 19  //
 20  // MDSPrefs.cpp
 21  //
 22  
 23  #include "MDSPrefs.h"
 24  #include <CoreFoundation/CFPreferences.h>
 25  #include <stdlib.h>
 26  
 27  // Construct the preferences object and read the current preference settings.
 28  
 29  MDSPrefs::MDSPrefs()
 30      :	mPluginFolders(NULL)
 31  {
 32      if (!readPathFromPrefs() && !readPathFromEnv())
 33          useDefaultPath();
 34  }
 35  
 36  // Destroy the preferences object.
 37  
 38  MDSPrefs::~MDSPrefs()
 39  {
 40      if (mPluginFolders)
 41          CFRelease(mPluginFolders);
 42  }
 43  
 44  // Obtain the plugin path from a preferences file. Returns true on success of false
 45  // if no prefs could be found.
 46  
 47  bool
 48  MDSPrefs::readPathFromPrefs()
 49  {
 50      static const CFStringRef kPrefsSuite = CFSTR("com.apple.mds");
 51      static const CFStringRef kPluginPathKey = CFSTR("securityPluginPath");
 52  
 53      bool result = true;
 54  
 55      CFPreferencesAddSuitePreferencesToApp(kCFPreferencesCurrentApplication, kPrefsSuite);
 56      
 57      CFPropertyListRef value;
 58      value = CFPreferencesCopyAppValue(kPluginPathKey, kCFPreferencesCurrentApplication);
 59      
 60      if (CFGetTypeID(value) != CFArrayGetTypeID())
 61  		// the prefs object is not an array, so fail
 62  		result = false;
 63  		
 64  	else {
 65          // make sure that all array elements are strings
 66  
 67  		CFArrayRef array = (CFArrayRef) value;
 68  		int numItems = CFArrayGetCount(array);
 69  		for (int i = 0; i < numItems; i++)
 70  			if (CFGetTypeID(CFArrayGetValueAtIndex(array, i)) != CFStringGetTypeID()) {
 71  				result = false;
 72  				break;
 73  			}
 74  	}
 75  	
 76  	if (result)
 77          mPluginFolders = (CFArrayRef) value;
 78  	else
 79          CFRelease(value);
 80  
 81      return result;
 82  }
 83  
 84  bool
 85  MDSPrefs::readPathFromEnv()
 86  {
 87      static const char *kPluginPathEnv = "MDSPATH";
 88      static const CFStringRef kSeparator = CFSTR(":");
 89  
 90      char *envValue = getenv(kPluginPathEnv);
 91      if (envValue) {
 92          CFStringRef path = CFStringCreateWithCString(NULL, envValue, kCFStringEncodingUTF8);
 93  
 94          mPluginFolders = CFStringCreateArrayBySeparatingStrings(NULL, path, kSeparator);
 95          
 96          CFRelease(path);
 97          return true;
 98      }
 99      
100      return false;
101  }
102  
103  void
104  MDSPrefs::useDefaultPath()
105  {
106      static const CFStringRef kDefaultPluginPath = CFSTR("/System/Library/Security");
107  
108      mPluginFolders = CFArrayCreate(NULL, (const void **) &kDefaultPluginPath, 1, &kCFTypeArrayCallBacks);
109  }
110  
111  // Retrieve the elements of the plugin path.
112  
113  int
114  MDSPrefs::getNumberOfPluginFolders() const
115  {
116      if (mPluginFolders)
117          return CFArrayGetCount(mPluginFolders);
118          
119      return 0;
120  }
121  
122  const char *
123  MDSPrefs::getPluginFolder(int index)
124  {
125      if (mPluginFolders) {
126          int numValues = CFArrayGetCount(mPluginFolders);
127          if (index >= 0 && index < numValues) {
128              CFStringRef value = (CFStringRef) CFArrayGetValueAtIndex(mPluginFolders, index);
129              if (value) {
130                  // we have to copy the string since it may be using a different native
131                  // encoding than the one we want. the copy is put in a temporary buffer,
132                  // so its lifetime is limited to the next call to getPluginFolder() or to
133                  // the destruction of the MDSPrefs object. Very long paths will silently fail.
134                  
135                  if (CFStringGetCString(value, mTempBuffer, kTempBufferSize, kCFStringEncodingUTF8))
136                      return mTempBuffer;
137              }
138          }
139      }
140      
141      return NULL;
142  }
143