X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/libsecurity_mds/lib/MDSDictionary.cpp diff --git a/libsecurity_mds/lib/MDSDictionary.cpp b/libsecurity_mds/lib/MDSDictionary.cpp deleted file mode 100644 index 426f7a6c..00000000 --- a/libsecurity_mds/lib/MDSDictionary.cpp +++ /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 -#include - -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( - 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; dexAttributeInfo; - const MDSNameValuePair **nameValues = relInfo->nameValues; - - assert(relInfo != NULL); - numAttrs = 0; - for(dex=0; dexNumberOfAttributes; 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