#include "MDSAttrUtils.h"
#include <strings.h>
namespace Security
{
void MDSRawValueToDbAttr(
const void *value,
size_t len,
CSSM_DB_ATTRIBUTE_FORMAT attrFormat, const char *attrName,
CSSM_DB_ATTRIBUTE_DATA &attr,
uint32 numValues)
{
CSSM_DB_ATTRIBUTE_INFO_PTR attrInfo = &attr.Info;
attrInfo->AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING;
attrInfo->Label.AttributeName = const_cast<char *>(attrName);
attrInfo->AttributeFormat = attrFormat;
attr.NumberOfValues = numValues;
attr.Value = new CSSM_DATA[1];
attr.Value->Data = new uint8[len];
attr.Value->Length = len;
memcpy(attr.Value->Data, value, len);
}
void MDSFreeDbRecordAttrs(
CSSM_DB_ATTRIBUTE_DATA *attrs,
unsigned numAttrs)
{
uint32 i;
for(i=0; i<numAttrs; i++) {
assert(attrs->Value != NULL);
delete [] attrs->Value->Data;
attrs->Value->Data = NULL;
attrs->Value->Length = 0;
delete [] attrs->Value;
attrs->Value = NULL;
attrs++;
}
}
char *MDSCFStringToCString(
CFStringRef cfStr)
{
char *rtn = NULL;
CFIndex len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfStr), kCFStringEncodingUTF8) + 1;
rtn = new char[len];
if(rtn) {
CFStringGetCString(cfStr, rtn, len, kCFStringEncodingUTF8);
}
return rtn;
}
char *MDSCopyCstring(
const char *inStr)
{
char *outStr = new char[::strlen(inStr) + 1];
strcpy(outStr, inStr);
return outStr;
}
bool MDSCfTypeToUInt32(
CFTypeRef cfValue,
const MDSNameValuePair *nameValues, const char *key, uint32 &iValue, size_t &iValueLen) {
assert(cfValue != NULL);
CFTypeID valueType = CFGetTypeID(cfValue);
if(valueType == CFStringGetTypeID()) {
uint32 tmpValue = 0;
CSSM_RETURN crtn = MDSStringToUint32((CFStringRef)cfValue,
nameValues, tmpValue);
if(crtn) {
MPDebug("cfTypeToInt: key %s uint32 form, string data (%s), "
"bad conv", key,
CFStringGetCStringPtr((CFStringRef)cfValue,
kCFStringEncodingUTF8));
return false;
}
iValue = tmpValue;
iValueLen = sizeof(tmpValue);
return true;
}
else if(valueType == CFNumberGetTypeID()) {
int64_t tmpValue = 0;
CFNumberRef cfNum = (CFNumberRef)cfValue;
CFNumberType numType = CFNumberGetType(cfNum);
switch(numType) {
case kCFNumberSInt8Type:
iValueLen = 1; break;
case kCFNumberSInt16Type:
iValueLen = 2; break;
case kCFNumberSInt32Type:
iValueLen = 4; break;
case kCFNumberSInt64Type: iValueLen = 4; break;
case kCFNumberCharType:
iValueLen = sizeof(char); break;
case kCFNumberShortType:
iValueLen = sizeof(short); break;
case kCFNumberIntType:
iValueLen = sizeof(int); break;
case kCFNumberLongType:
MPDebug("Warning: MDS key %s encoded kCFNumberLongType", key);
iValueLen = sizeof(long); break;
default:
MPDebug("MDS cfTypeToInt: Bad CFNumber type (%ld) key %s", numType, key);
return false;
}
Boolean brtn = CFNumberGetValue(cfNum, numType, &tmpValue);
if(!brtn) {
MPDebug("MDS cfTypeToInt: Bad CFNumber conversion");
return false;
}
iValue = uint32(tmpValue);
return true;
}
else if(valueType == CFBooleanGetTypeID()) {
Boolean b = CFBooleanGetValue((CFBooleanRef)cfValue);
iValue = b ? 1 : 0;
iValueLen = sizeof(iValue);
return true;
}
else {
MPDebug("MDS cfTypeToInt: key %s, uint64 form, bad CF type (%d)",
key, (int)valueType);
return false;
}
}
bool MDSInsertRecord(
const CSSM_DB_ATTRIBUTE_DATA *inAttr,
unsigned numAttrs,
CSSM_DB_RECORDTYPE recordType,
MDSSession &dl,
CSSM_DB_HANDLE dbHand)
{
CSSM_DB_RECORD_ATTRIBUTE_DATA recordAttrData;
CSSM_DB_UNIQUE_RECORD_PTR uid = NULL;
bool ourRtn = true;
recordAttrData.DataRecordType = recordType;
recordAttrData.SemanticInformation = 0;
recordAttrData.NumberOfAttributes = numAttrs;
recordAttrData.AttributeData =
const_cast<CSSM_DB_ATTRIBUTE_DATA_PTR>(inAttr);
try {
dl.DataInsert(dbHand,
recordType,
&recordAttrData,
NULL,
uid);
}
catch (const CssmError &cerr) {
MPDebug("MDSInsertRecord: DataInsert: %d", cerr.error);
ourRtn = false;
}
catch(...) {
MPDebug("MDSInsertRecord: DataInsert: unknown exception");
ourRtn = false;
}
if(uid != NULL) {
dl.FreeUniqueRecord(dbHand, *uid);
}
return ourRtn;
}
CSSM_RETURN MDSStringToUint32(
CFStringRef str,
const MDSNameValuePair *table, uint32 &value)
{
char *cstr = MDSCFStringToCString(str);
if(cstr == NULL) {
MPDebug("MDSStringToUint32: CFString conversion error");
return CSSMERR_CSSM_MDS_ERROR;
}
char tokenStr[200];
char *src = cstr;
char *dst = tokenStr;
char c;
CSSM_RETURN crtn = CSSM_OK;
value = 0;
while(*src != '\0') {
for( ; *src != '\0'; src++) {
c = *src;
if(!isspace(c) && (c != '|')) {
*dst++ = c;
src++;
break;
}
}
if((*src == '\0') && (dst == tokenStr)) {
break;
}
for( ; *src != '\0'; src++) {
c = *src;
if(isspace(c) || (c == '|')) {
break;
}
else {
*dst++ = c;
}
}
*dst = '\0';
uint32 tokenVal = 0;
CSSM_RETURN crtn = MDSAttrNameToValue(tokenStr, table, tokenVal);
if(crtn) {
break;
}
value |= tokenVal;
dst = tokenStr;
}
delete [] cstr;
return crtn;
}
}