]> git.saurik.com Git - apple/security.git/blobdiff - libsecurity_mds/lib/MDSDictionary.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / libsecurity_mds / lib / MDSDictionary.cpp
diff --git a/libsecurity_mds/lib/MDSDictionary.cpp b/libsecurity_mds/lib/MDSDictionary.cpp
deleted file mode 100644 (file)
index 426f7a6..0000000
+++ /dev/null
@@ -1,597 +0,0 @@
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- * 
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- * 
- * This Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
- * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
- * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
- * specific language governing rights and limitations under the License.
- */
-
-
-/*
-   File:      MDSDictionary.cpp
-
-   Contains:  Internal representation of one MDS info file in the form of 
-              a CFDictionary. 
-
-   Copyright: (c) 2001 Apple Computer, Inc., all rights reserved.
-*/
-
-#include "MDSDictionary.h"
-#include "MDSAttrParser.h"
-#include "MDSAttrUtils.h"
-#include <security_utilities/logging.h>
-#include <security_utilities/cfutilities.h>
-
-namespace Security
-{
-
-/* heavyweight constructor from file */
-MDSDictionary::MDSDictionary(
-       CFURLRef fileUrl,
-       CFStringRef subdir,
-       const char *fullPath)           // could get from fileUrl, but very messy!
-       : mDict(NULL),
-         mWeOwnDict(false),
-         mUrlPath(NULL),
-         mFileDesc(NULL),
-         mSubdir(subdir),
-         mDefaults(NULL)
-{
-       CFDataRef dictData = NULL;
-       CFStringRef cfErr = NULL;
-       
-       assert(fileUrl != NULL);
-       mUrlPath = MDSCopyCstring(fullPath);
-       MPDebug("Creating MDSDictionary from %s", mUrlPath);
-       
-       /* Load data from URL */
-       SInt32 uerr;
-       Boolean brtn = CFURLCreateDataAndPropertiesFromResource(
-               NULL,
-               fileUrl,
-               &dictData,
-               NULL,           // properties
-               NULL,           // desiredProperties
-               &uerr);
-       if(!brtn) {
-               Syslog::alert("Error reading MDS file %s: %d", mUrlPath, (int)uerr);
-               CssmError::throwMe(CSSMERR_CSSM_MDS_ERROR);
-       }
-       
-       /* if it's not a dictionary, we don't want it */
-       mDict = reinterpret_cast<CFDictionaryRef>(
-               CFPropertyListCreateFromXMLData(NULL,
-                       dictData,
-                       kCFPropertyListImmutable,
-                       &cfErr));
-       CFRelease(dictData);
-       if(mDict == NULL) {
-               Syslog::alert("Malformed MDS file %s (1)", mUrlPath);
-               CssmError::throwMe(CSSMERR_CSSM_MDS_ERROR);
-       }
-       
-       /* henceforth we must release this dictionary */
-       mWeOwnDict = true;
-       if(CFGetTypeID(mDict) != CFDictionaryGetTypeID()) {
-               Syslog::alert("Malformed MDS file %s (2)", mUrlPath);
-               CssmError::throwMe(CSSMERR_CSSM_MDS_ERROR);
-       }
-       CF_RELEASE(cfErr);
-       
-       /* get file description for error logging and debugging */
-       CFStringRef cfStr = (CFStringRef)lookup(CFSTR(MDS_INFO_FILE_DESC), 
-               true, CFStringGetTypeID());
-       if(cfStr) {
-               CFIndex len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfStr), kCFStringEncodingUTF8) + 1/*nul terminator*/;
-               mFileDesc = new char[len];
-               if(mFileDesc) {
-                       CFStringGetCString(cfStr, mFileDesc, len, 
-                               kCFStringEncodingUTF8);
-               }
-       }
-}
-
-/* lightweight constructor from existing CFDictionary */
-MDSDictionary::MDSDictionary(CFDictionaryRef theDict)
-       : mDict(theDict),
-         mWeOwnDict(false),
-         mUrlPath(NULL),
-         mFileDesc(NULL),
-         mDefaults(NULL)
-{
-       /* note caller owns and releases the dictionary */ 
-       if(mDict == NULL) {
-               MPDebug("Malformed MDS file (3)");
-               CssmError::throwMe(CSSMERR_CSSM_MDS_ERROR);
-       }
-       if(CFGetTypeID(mDict) != CFDictionaryGetTypeID()) {
-               MPDebug("Malformed MDS file (4)");
-               CssmError::throwMe(CSSMERR_CSSM_MDS_ERROR);
-       }
-}
-
-MDSDictionary::~MDSDictionary()
-{
-       if(mWeOwnDict) {
-               CF_RELEASE(mDict);
-       }
-       mDict = NULL;
-       delete [] mUrlPath;
-       delete [] mFileDesc;
-}
-
-/* lookup by either C string or CFStringRef - returns NULL on error */
-const void *MDSDictionary::lookup(
-       const char *key,
-       bool checkType,
-       CFTypeID type)
-{
-       CFStringRef cfKey = CFStringCreateWithCString(NULL,
-               key,
-               kCFStringEncodingUTF8);
-       if(cfKey == NULL) {
-               MPDebug("MDSDictionary::lookup: error creating CFString for key");
-               return NULL;
-       }
-       const void *rtn = lookup(cfKey, checkType, type);
-       CFRelease(cfKey);
-       return rtn;
-
-}
-
-const void *MDSDictionary::lookup(
-       CFStringRef key,
-       bool checkType,
-       CFTypeID type)
-{
-       assert(mDict != NULL);
-       const void *rtn = CFDictionaryGetValue(mDict, key);
-       if(rtn && checkType) {
-               if(CFGetTypeID((CFTypeRef)rtn) != type) {
-                       return NULL;
-               }
-       }
-       return rtn;
-}
-
-/*
- * Common means to perform a lookup in a dictionary given a C-string key and
- * placing the value - if present - in a CSSM_DB_ATTRIBUTE_DATA. Any errors
- * are only logged via MPDebug. Returns true if the value was found and 
- * successfully placed in supplied CSSM_DB_ATTRIBUTE_DATA.
- *
- * For now we assume that the key in the dictionary is the same as the key
- * in the DB to which we're writing. 
- *
- * We're also assuming that all DB keys are of format CSSM_DB_ATTRIBUTE_NAME_AS_STRING.
- */
-bool MDSDictionary::lookupToDbAttr(
-       const char *key,
-       CSSM_DB_ATTRIBUTE_DATA &attr,
-       CSSM_DB_ATTRIBUTE_FORMAT attrFormat,
-       const MDSNameValuePair *nameValues)     // optional for converting strings to numbers
-{
-       assert(mDict != NULL);
-       assert(&attr != NULL);
-       
-       CFTypeRef       value;                          // polymorphic dictionary value
-       bool            ourRtn = false;
-       const void      *srcPtr = NULL;         // polymorphic raw source bytes
-       size_t          srcLen = 0;
-       uint32          ival = 0;
-       uint32          *ivalArray = NULL;
-       uint32          numValues = 1;          // the default for MDSRawValueToDbAttr
-       string          stringVal;
-
-       value = (CFTypeRef)lookup(key);
-       if(value == NULL) {
-               return false;
-       }
-       CFTypeID valueType = CFGetTypeID(value);
-       
-       /* 
-        * We have the value; could be any type. Handle it based on caller's 
-        * CSSM_DB_ATTRIBUTE_FORMAT.
-        */
-       switch(attrFormat) {
-               case CSSM_DB_ATTRIBUTE_FORMAT_STRING:
-               {
-                       if(valueType != CFStringGetTypeID()) {
-                               MPDebug("lookupToDbAttr: string format mismatch");
-                               break;
-                       }
-                       stringVal = cfString((CFStringRef)value, false);
-                       srcPtr = stringVal.c_str();
-                       srcLen = stringVal.size();
-                       if(srcLen) {
-                               ourRtn = true;
-                       }
-                       break;
-               }
-               case CSSM_DB_ATTRIBUTE_FORMAT_UINT32:
-               {
-                       bool brtn = MDSCfTypeToUInt32(value, nameValues, key, ival, srcLen);
-                       if(!brtn) {
-                               MPDebug("MDS lookupToDbAttr: Bad number conversion");
-                               return false;
-                       }
-                       srcPtr = &ival;
-                       ourRtn = true;
-                       break;
-               }        
-               case CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32:     
-               {
-                       /* 
-                        * This is expressed in the dictionary as an array of numbers. 
-                        * as in CSSM_DB_ATTRIBUTE_FORMAT_UINT32, each number can be
-                        * expressed as either a string or a number.
-                        */
-                       if(valueType != CFArrayGetTypeID()) {
-                               /*
-                                * Let's be extremely slick and allow one number here, either 
-                                * in string or number form....
-                                */
-                               bool brtn = MDSCfTypeToUInt32(value, nameValues, key, ival, srcLen);
-                               if(!brtn) {
-                                       MPDebug("MDS lookupToDbAttr: Bad array element");
-                                       return false;
-                               }
-                               srcPtr = &ival;
-                               ourRtn = true;
-                               break;
-                       }
-                       CFArrayRef cfArray = (CFArrayRef)value;
-                       numValues = (uint32)CFArrayGetCount(cfArray);
-                       if(numValues == 0) {
-                               /* degenerate case, legal - right? Can AppleDatabase do this? */
-                               srcPtr = NULL;
-                               srcLen = 0;
-                               ourRtn = true;
-                               break;
-                       }
-                       
-                       /* 
-                        * malloc an array of uint32s
-                        * convert each element in cfArray to a uint32
-                        * store as CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32
-                        *
-                        * Note this does not have to be endian independent; the MDS DBs
-                        * are not portable across machines let alone platforms. 
-                        */
-                       ivalArray = new uint32[numValues];
-                       unsigned dex;
-                       bool brtn;
-                       for(dex=0; dex<numValues; dex++) {
-                               CFTypeRef elmt = (CFTypeRef)CFArrayGetValueAtIndex(cfArray, dex);
-                               if(elmt == NULL) {
-                                       MPDebug("MDS lookupToDbAttr: key %s: Bad array element (1)", key);
-                                       delete [] ivalArray;
-                                       return false;
-                               }
-                size_t itemLen = 0;
-                               brtn =  MDSCfTypeToUInt32(elmt, nameValues, key, ivalArray[dex], itemLen);
-                               if(!brtn) {
-                                       MPDebug("MDS lookupToDbAttr: key %s Bad element at index %d",
-                                               key, dex);
-                                       delete [] ivalArray;
-                                       return false;
-                               }
-                srcLen += itemLen;
-                       }
-                       srcPtr = ivalArray;
-                       ourRtn = true;
-                       /*
-                        * FIXME - numValues as used by MDSRawValueToDbAttr and placed in 
-                        * CSSM_DB_ATTRIBUTE_DATA.NumberOfValues, appears to need to be
-                        * one even for MULTI_UINT32 format; the number of ints in inferred
-                        * from Value.Length....
-                        */
-                       numValues = 1;
-                       break;
-               }
-               case CSSM_DB_ATTRIBUTE_FORMAT_BLOB:                     // CFData
-               {
-                       if(valueType != CFDataGetTypeID()) {
-                               MPDebug("lookupToDbAttr: blob/CFData format mismatch");
-                               break;
-                       }
-                       CFDataRef cfData = (CFDataRef)value;
-                       srcLen = CFDataGetLength(cfData);
-                       srcPtr = CFDataGetBytePtr(cfData);
-                       ourRtn = true;
-                       break;
-               }
-               case CSSM_DB_ATTRIBUTE_FORMAT_SINT32:           // I don't think we support this
-               default:
-                       MPDebug("lookupToDbAttr: bad attrForm(%d)", (int)attrFormat);
-                       return false;
-       }
-       if(ourRtn) {
-               MDSRawValueToDbAttr(srcPtr, srcLen, attrFormat, key, attr, numValues);
-       }
-       if(ivalArray) {
-               delete [] ivalArray;
-       }
-       return ourRtn;
-}
-
-/*
- * Given a RelationInfo and an array of CSSM_DB_ATTRIBUTE_DATAs, fill in 
- * the CSSM_DB_ATTRIBUTE_DATA array with as many fields as we can find in 
- * the dictionary. All fields are treated as optional. 
- */
-void MDSDictionary::lookupAttributes(
-       const RelationInfo                      *relInfo,
-       CSSM_DB_ATTRIBUTE_DATA_PTR      outAttrs,               // filled in on return
-       uint32                                          &numAttrs)              // RETURNED
-{
-       unsigned                                                dex;
-       const CSSM_DB_ATTRIBUTE_INFO    *inAttr = relInfo->AttributeInfo;
-       const MDSNameValuePair                  **nameValues    = relInfo->nameValues;
-
-       assert(relInfo != NULL);
-       numAttrs = 0;
-       for(dex=0; dex<relInfo->NumberOfAttributes; dex++) {
-               bool brtn;
-               const MDSNameValuePair *nvp;
-               
-               /* the array itself, or any element in it, can be NULL */
-               if(nameValues != NULL) {
-                       nvp = nameValues[dex];
-               }
-               else {
-                       nvp = NULL;
-               }
-               brtn = lookupToDbAttr(inAttr->Label.AttributeName,
-                       *outAttrs, 
-                       inAttr->AttributeFormat,
-                       nvp);
-               if(brtn) {
-                       /* successfully added to dbAttrs */
-                       outAttrs++;
-                       numAttrs++;
-               }
-               inAttr++;               // regardless
-       }
-}
-
-/*
- * Lookup with file-based indirection. Allows multiple mdsinfo files to share commmon
- * info from a separate plist file.
- *
- * Do a lookup for specified key. If not found, return NULL. If found:
- * {
- *             if type of value matches desiredType {
- *                     return the value;
- *             }
- *             else if type of value is string {
- *                     if string starts with "file:" {
- *                             attempt to read property list with that filename relative to 
- *                                     specified bundle;
- *                             if CFType of that propList matches desiredType {
- *                                     return newly read propList;
- *                             }
- *                     }
- *             }
- *             ...else return error;
- */
-const CFPropertyListRef MDSDictionary::lookupWithIndirect(
-       const char *key,
-       CFBundleRef bundle,
-       CFTypeID        desiredType,
-       bool            &fetchedFromDisk)       // true --> caller must CFRelease the returned
-                                                                       //     value
-                                                                       // false -> it's part of this dictionary
-{
-       CFPropertyListRef ourRtn = NULL;
-       CFDataRef dictData = NULL;
-       CFStringRef cfErr = NULL;
-       SInt32 uerr;
-       Boolean brtn;
-       
-       
-       assert(key != NULL);
-       assert(bundle != NULL);
-       
-       fetchedFromDisk = false;
-       
-       /* basic local lookup */
-       CFStringRef cfKey = CFStringCreateWithCString(NULL,
-               key,
-               kCFStringEncodingUTF8);
-       if(cfKey == NULL) {
-               MPDebug("CFStringCreateWithCString error");
-               return NULL;
-       }
-       const void *rtn = CFDictionaryGetValue(mDict, cfKey);
-       CFRelease(cfKey);
-       if(rtn == NULL) {
-               return NULL;
-       }
-       CFTypeID foundType = CFGetTypeID((CFTypeRef)rtn);
-       if(foundType == desiredType) {
-               /* found what we're looking for; done */
-               return (CFPropertyListRef)rtn;
-       }
-       
-       /* is it a string which starts with "file:"? */
-       if(foundType != CFStringGetTypeID()) {
-               return NULL;
-       }
-       const char *cVal = MDSCFStringToCString((CFStringRef)rtn);
-       if(cVal == NULL) {
-               MPDebug("MDSCFStringToCString error in lookupWithIndirect");
-               return NULL;
-       }
-       if(strstr(cVal, "file:") != cVal) {
-               delete [] cVal;
-               return NULL;
-       }
-       /* delete [] cval on return */
-       
-       /* OK, this specifies a resource file in the bundle. Fetch it. */
-       CFURLRef fileUrl = NULL;
-       CFStringRef cfFileName = CFStringCreateWithCString(NULL,
-               cVal + 5,
-               kCFStringEncodingUTF8);
-       if(cfFileName == NULL) {
-               MPDebug("lookupWithIndirect: bad file name spec");
-               goto abort;
-       }
-       fileUrl = CFBundleCopyResourceURL(bundle, 
-                cfFileName, 
-                NULL, 
-                mSubdir);
-       if(fileUrl == NULL) {
-               MPDebug("lookupWithIndirect: file %s not found", cVal);
-               goto abort;
-       }
-
-       MPDebug("Fetching indirect resource %s", cVal);
-       
-       /* Load data from URL */
-       brtn = CFURLCreateDataAndPropertiesFromResource(
-               NULL,
-               fileUrl,
-               &dictData,
-               NULL,           // properties
-               NULL,           // desiredProperties
-               &uerr);
-       if(!brtn) {
-               MPDebug("lookupWithIndirect: error %d reading %s", (int)uerr, cVal);
-               goto abort;
-       }
-       
-       /* if it's not a property list, we don't want it */
-       ourRtn = CFPropertyListCreateFromXMLData(NULL,
-                       dictData,
-                       kCFPropertyListImmutable,
-                       &cfErr);
-       if(ourRtn == NULL) {
-               MPDebug("lookupWithIndirect: %s malformed (not a prop list)", cVal);
-               goto abort;
-       }
-       
-       /* if it doesn't match the caller's spec, we don't want it */
-       if(CFGetTypeID(ourRtn) != desiredType) {
-               MPDebug("lookupWithIndirect: %s malformed (mismatch)", cVal);
-               CF_RELEASE(ourRtn);
-               ourRtn = NULL;
-               goto abort;
-       }
-
-       MPDebug("lookupWithIndirect: resource %s FOUND", cVal);
-       fetchedFromDisk = true;
-       
-abort:
-       delete [] cVal;
-       CF_RELEASE(cfFileName);
-       CF_RELEASE(fileUrl);
-       CF_RELEASE(dictData);
-       CF_RELEASE(cfErr);
-       return ourRtn;
-}
-
-void MDSDictionary::setDefaults(const MDS_InstallDefaults *defaults) 
-{ 
-       mDefaults = defaults;
-
-       /*
-        * Save the values into (a new) mDict.  
-        */
-       assert(mDict != NULL);
-       CFMutableDictionaryRef tmpDict = CFDictionaryCreateMutableCopy(NULL, 0, mDict);
-       if(tmpDict == NULL) {
-               MPDebug("setDefaults: error copying old dictionary");
-               CssmError::throwMe(CSSMERR_CSSM_MDS_ERROR);
-       }
-
-       CFStringRef tmpStr = NULL;
-
-       /*
-        * CFDictionaryAddValue() does nothing if the requested key is already 
-        * present.  If you need to call setDefaults() more than once, you'll 
-        * have to add the code to remove the old key/value pairs first.  
-        */
-       if(defaults) {
-               if(defaults->guid) {
-                       tmpStr = CFStringCreateWithCString(NULL, defaults->guid, kCFStringEncodingUTF8);
-                       if(tmpStr) {
-                               CFDictionaryAddValue(tmpDict, CFSTR("ModuleID"), tmpStr);
-                               CFRelease(tmpStr);
-                       }
-                       else {
-                               MPDebug("setDefaults: error creating CFString for GUID");
-                               CssmError::throwMe(CSSMERR_CSSM_MDS_ERROR);
-                       }
-               }
-
-               CFNumberRef tmpNum = CFNumberCreate(NULL, kCFNumberIntType, &defaults->ssid);
-               if(tmpNum) {
-                       CFDictionaryAddValue(tmpDict, CFSTR("SSID"), tmpNum);
-                       CFRelease(tmpNum);
-               }
-               else {
-                       MPDebug("setDefaults: error creating CFString for SSID");
-                       CssmError::throwMe(CSSMERR_CSSM_MDS_ERROR);
-               }
-
-               if(defaults->serial) {
-                       tmpStr = CFStringCreateWithCString(NULL, defaults->serial, kCFStringEncodingUTF8);
-                       if(tmpStr) {
-                               CFDictionaryAddValue(tmpDict, CFSTR("ScSerialNumber"), tmpStr);
-                               CFRelease(tmpStr);
-                       }
-                       else {
-                               MPDebug("setDefaults: error creating CFString for serial number");
-                               CssmError::throwMe(CSSMERR_CSSM_MDS_ERROR);
-                       }
-               }
-
-               if(defaults->printName) {
-                       tmpStr = CFStringCreateWithCString(NULL, defaults->printName, kCFStringEncodingUTF8);
-                       if(tmpStr) {
-                               CFDictionaryAddValue(tmpDict, CFSTR("ScDesc"), tmpStr);
-                               CFRelease(tmpStr);
-                       }
-                       else {
-                               MPDebug("setDefaults: error creating CFString for description");
-                               CssmError::throwMe(CSSMERR_CSSM_MDS_ERROR);
-                       }
-               }
-       }
-
-       if(mUrlPath) {
-               tmpStr = CFStringCreateWithCString(NULL, mUrlPath, kCFStringEncodingUTF8);
-               if(tmpStr) {
-                       CFDictionaryAddValue(tmpDict, CFSTR("Path"), tmpStr);
-                       CFRelease(tmpStr);
-               }
-               else {
-                       MPDebug("setDefaults: error creating CFString for path");
-                       CssmError::throwMe(CSSMERR_CSSM_MDS_ERROR);
-               }
-       }
-       CFDictionaryRef oldDict = mDict;
-       mDict = CFDictionaryCreateCopy(NULL, tmpDict);
-       if(mDict == NULL) {
-               mDict = oldDict;        // first do no harm
-               CFRelease(tmpDict);
-               MPDebug("setDefaults: error creating new dictionary");
-               CssmError::throwMe(CSSMERR_CSSM_MDS_ERROR);
-       }
-       CFRelease(oldDict);
-       CFRelease(tmpDict);
-}
-
-
-} // end namespace Security