+++ /dev/null
-#include "dltests.h"
-#include "csptests.h"
-#include "attributes.h"
-#include <security_cdsa_client/multidldb.h>
-#include <vector>
-#include <security_cdsa_client/securestorage.h> // For CSPDL.
-#include <security_cdsa_client/genkey.h>
-#include <security_utilities/trackingallocator.h>
-
-using namespace CssmClient;
-
-// Configuration.
-#define HEX_DIGITS_PER_LINE 20
-#define INDENT_SIZE 2
-
-
-const CSSM_GUID* gSelectedFileGuid = &gGuidAppleFileDL;
-
-
-
-static void testDLCreate(const Guid &dlGuid);
-static void testDLDelete(const Guid &dlGuid, bool throwOnError);
-static void testGen(const Guid &cspDlGuid);
-static void testDLCrypt(const Guid &cspDlGuid);
-static void testMultiDLDb(const Guid &dlGuid);
-static void dumpRelation(uint32 indent, Db &db, uint32 relationID, const char *relationName, bool printSchema);
-static void dumpRecord(uint32 indent, const DbAttributes &record, const CssmData &data, const DbUniqueRecord &uniqueId);
-
-#define CSSM_DB_RELATION(RELATIONID) RecordAttrInfo ## RELATIONID
-
-#define CSSM_DB_DEFINE_RELATION_BEGIN(RELATIONID) \
-static const CSSM_DB_ATTRIBUTE_INFO AttrInfo ## RELATIONID[] =
-
-#define CSSM_DB_DEFINE_RELATION_END(RELATIONID) \
-; \
-static const CSSM_DB_RECORD_ATTRIBUTE_INFO CSSM_DB_RELATION(RELATIONID) = \
-{ \
- RELATIONID, \
- sizeof(AttrInfo ## RELATIONID) / sizeof(CSSM_DB_ATTRIBUTE_INFO), \
- const_cast<CSSM_DB_ATTRIBUTE_INFO_PTR>(AttrInfo ## RELATIONID) \
-}
-
-// GENERIC PASSWORDS
-CSSM_DB_DEFINE_RELATION_BEGIN(CSSM_DL_DB_RECORD_GENERIC_PASSWORD)
-{
- CSSM_DB_ATTR(Attributes::Class),
- CSSM_DB_ATTR(Attributes::CreationDate),
- CSSM_DB_ATTR(Attributes::ModDate),
- CSSM_DB_ATTR(Attributes::Description),
- CSSM_DB_ATTR(Attributes::Comment),
- CSSM_DB_ATTR(Attributes::Creator),
- CSSM_DB_ATTR(Attributes::Type),
- CSSM_DB_ATTR(Attributes::ScrCode),
- CSSM_DB_ATTR(Attributes::Label),
- CSSM_DB_ATTR(Attributes::Invisible),
- CSSM_DB_ATTR(Attributes::Negative),
- CSSM_DB_ATTR(Attributes::Custom),
- //CSSM_DB_ATTR(Attributes::Protected),
- CSSM_DB_ATTR(Attributes::Account),
- CSSM_DB_ATTR(Attributes::Service),
- CSSM_DB_ATTR(Attributes::Generic)
-}
-CSSM_DB_DEFINE_RELATION_END(CSSM_DL_DB_RECORD_GENERIC_PASSWORD);
-
-
-// APPLESHARE PASSWORDS
-CSSM_DB_DEFINE_RELATION_BEGIN(CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD)
-{
- CSSM_DB_ATTR(Attributes::Class),
- CSSM_DB_ATTR(Attributes::CreationDate),
- CSSM_DB_ATTR(Attributes::ModDate),
- CSSM_DB_ATTR(Attributes::Description),
- CSSM_DB_ATTR(Attributes::Comment),
- CSSM_DB_ATTR(Attributes::Creator),
- CSSM_DB_ATTR(Attributes::Type),
- CSSM_DB_ATTR(Attributes::ScrCode),
- CSSM_DB_ATTR(Attributes::Label),
- CSSM_DB_ATTR(Attributes::Invisible),
- CSSM_DB_ATTR(Attributes::Negative),
- CSSM_DB_ATTR(Attributes::Custom),
- //CSSM_DB_ATTR(Attributes::Protected),
- CSSM_DB_ATTR(Attributes::Volume),
- CSSM_DB_ATTR(Attributes::Addr),
- CSSM_DB_ATTR(Attributes::Signature),
- CSSM_DB_ATTR(Attributes::ProtocolType)
-}
-CSSM_DB_DEFINE_RELATION_END(CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD);
-
-// INTERNET PASSWORDS
-CSSM_DB_DEFINE_RELATION_BEGIN(CSSM_DL_DB_RECORD_INTERNET_PASSWORD)
-{
- CSSM_DB_ATTR(Attributes::Class),
- CSSM_DB_ATTR(Attributes::CreationDate),
- CSSM_DB_ATTR(Attributes::ModDate),
- CSSM_DB_ATTR(Attributes::Description),
- CSSM_DB_ATTR(Attributes::Comment),
- CSSM_DB_ATTR(Attributes::Creator),
- CSSM_DB_ATTR(Attributes::Type),
- CSSM_DB_ATTR(Attributes::ScrCode),
- CSSM_DB_ATTR(Attributes::Label),
- CSSM_DB_ATTR(Attributes::Invisible),
- CSSM_DB_ATTR(Attributes::Negative),
- CSSM_DB_ATTR(Attributes::Custom),
- //CSSM_DB_ATTR(Attributes::Protected),
- CSSM_DB_ATTR(Attributes::Account),
- CSSM_DB_ATTR(Attributes::SecDomain),
- CSSM_DB_ATTR(Attributes::Server),
- CSSM_DB_ATTR(Attributes::AuthType),
- CSSM_DB_ATTR(Attributes::Port),
- CSSM_DB_ATTR(Attributes::Path),
- CSSM_DB_ATTR(Attributes::ProtocolType)
-}
-CSSM_DB_DEFINE_RELATION_END(CSSM_DL_DB_RECORD_INTERNET_PASSWORD);
-
-// INTERNET PASSWORDS
-CSSM_DB_DEFINE_RELATION_BEGIN(CSSM_DL_DB_RECORD_SYMMETRIC_KEY)
-{
- CSSM_DB_ATTR(Attributes::KeyClass),
- CSSM_DB_ATTR(Attributes::PrintName),
- CSSM_DB_ATTR(Attributes::Alias),
- CSSM_DB_ATTR(Attributes::Permanent),
- CSSM_DB_ATTR(Attributes::Private),
- CSSM_DB_ATTR(Attributes::Modifiable),
- CSSM_DB_ATTR(Attributes::Label),
- CSSM_DB_ATTR(Attributes::ApplicationTag),
- CSSM_DB_ATTR(Attributes::KeyCreator),
- CSSM_DB_ATTR(Attributes::KeyType),
- CSSM_DB_ATTR(Attributes::KeySizeInBits),
- CSSM_DB_ATTR(Attributes::EffectiveKeySize),
- CSSM_DB_ATTR(Attributes::StartDate),
- CSSM_DB_ATTR(Attributes::EndDate),
- CSSM_DB_ATTR(Attributes::Sensitive),
- CSSM_DB_ATTR(Attributes::AlwaysSensitive),
- CSSM_DB_ATTR(Attributes::Extractable),
- CSSM_DB_ATTR(Attributes::NeverExtractable),
- CSSM_DB_ATTR(Attributes::Encrypt),
- CSSM_DB_ATTR(Attributes::Decrypt),
- CSSM_DB_ATTR(Attributes::Derive),
- CSSM_DB_ATTR(Attributes::Sign),
- CSSM_DB_ATTR(Attributes::Verify),
- CSSM_DB_ATTR(Attributes::SignRecover),
- CSSM_DB_ATTR(Attributes::VerifyRecover),
- CSSM_DB_ATTR(Attributes::Wrap),
- CSSM_DB_ATTR(Attributes::UnWrap)
-}
-CSSM_DB_DEFINE_RELATION_END(CSSM_DL_DB_RECORD_SYMMETRIC_KEY);
-
-
-static const CSSM_DB_RECORD_ATTRIBUTE_INFO KCAttrs[] =
-{
- CSSM_DB_RELATION(CSSM_DL_DB_RECORD_GENERIC_PASSWORD),
- CSSM_DB_RELATION(CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD),
- CSSM_DB_RELATION(CSSM_DL_DB_RECORD_INTERNET_PASSWORD)
- //CSSM_DB_RELATION(CSSM_DL_DB_RECORD_SYMMETRIC_KEY)
-};
-
-static const CSSM_DB_RECORD_INDEX_INFO recordIndex =
-{
- CSSM_DB_RECORDTYPE_APP_DEFINED_START, // CSSM_DB_RECORDTYPE
- 0, //%%% for now
- NULL //%%% for now
-};
-static const CSSM_DB_RECORD_INDEX_INFO recordIndexes[] = {recordIndex, recordIndex, recordIndex};
-
-// parse info (to improve later)
-static const CSSM_DB_PARSING_MODULE_INFO parseInfo =
-{
- CSSM_DB_RECORDTYPE_APP_DEFINED_START,
- {
- {0,0,0,{0}},
- {0,0},
- 0,
- 0
- }
-};
-static const CSSM_DB_PARSING_MODULE_INFO parseInfos[] = {parseInfo, parseInfo, parseInfo};
-
-static const CSSM_DBINFO KCDBInfo =
-{
- sizeof(KCAttrs) / sizeof(CSSM_DB_RECORD_ATTRIBUTE_INFO),
- const_cast<CSSM_DB_PARSING_MODULE_INFO_PTR>(parseInfos),
- const_cast<CSSM_DB_RECORD_ATTRIBUTE_INFO_PTR>(KCAttrs),
- const_cast<CSSM_DB_RECORD_INDEX_INFO_PTR>(recordIndexes),
- CSSM_TRUE,
- NULL,
- NULL
-};
-
-
-
-void dltests(bool autoCommit)
-{
- testDLDelete(gGuidAppleFileDL, false);
- testDLCreate(gGuidAppleFileDL);
- testMultiDLDb(gGuidAppleFileDL);
-
- testDLDelete(gGuidAppleCSPDL, false);
- testDLCreate(gGuidAppleCSPDL);
- testGen(gGuidAppleCSPDL);
- testDLCrypt(gGuidAppleCSPDL);
- testMultiDLDb(gGuidAppleCSPDL);
- //testDLDelete(gGuidAppleCSPDL, true);
-}
-
-static void testDLCreate(const Guid &dlGuid)
-{
- DL appledl(dlGuid);
- Db testDb(appledl, DBNAME1);
- testDb->dbInfo(&KCDBInfo);
- testDb->create();
-}
-
-static void testDLDelete(const Guid &dlGuid, bool throwOnError)
-{
- DL appledl(dlGuid);
- Db testDb(appledl, DBNAME1);
- try
- {
- testDb->deleteDb();
- }
- catch(CssmError e)
- {
- if (throwOnError || e.osStatus() != CSSMERR_DL_DATASTORE_DOESNOT_EXIST)
- throw;
- }
-}
-
-static void testGen(const Guid &cspDlGuid)
-{
- printf("\n* performing CSP/DL keygen test...\n");
- CSPDL cspdl(cspDlGuid);
- Db db(cspdl, DBNAME1);
-
- printf("Generating permanent key\n");
- GenerateKey genKey(cspdl, CSSM_ALGID_DES, 64);
- genKey.database(db);
- CssmPolyData label("First Key!");
- Key key = genKey(KeySpec(CSSM_KEYUSE_ANY,
- CSSM_KEYATTR_PERMANENT | CSSM_KEYATTR_SENSITIVE,
- label));
- printf("done\n");
-}
-
-static void testDLCrypt(const Guid &cspDlGuid)
-{
- printf("\n* performing encrypt/decrypt test...\n");
- CSPDL cspdl(cspDlGuid);
- Db db(cspdl, DBNAME1);
-
- printf("Finding key\n");
- DbCursor cursor(db);
- cursor->recordType(CSSM_DL_DB_RECORD_SYMMETRIC_KEY);
- DbUniqueRecord keyId;
- CssmDataContainer keyData;
- if (!cursor->next(NULL, &keyData, keyId))
- CssmError::throwMe(CSSMERR_DL_ENDOFDATA);
-
- Key key(cspdl, *reinterpret_cast<CSSM_KEY *>(keyData.Data));
-
- printf("done\n");
-
- // Gnerate IV
- printf("Generating iv\n");
- //CssmData iv = Random(csp, CSSM_ALGID_SHARandom)(8);
- CssmPolyData iv("12345678");
-
- CssmPolyData in("Om mani padme hum");
- printf("input=");
- dump(in);
-
- // Encrypt
- printf("Encrypting\n");
-
- Encrypt encrypt(cspdl, CSSM_ALGID_DES);
- encrypt.mode(CSSM_ALGMODE_CBCPadIV8);
- encrypt.padding(CSSM_PADDING_PKCS1);
- encrypt.initVector(iv);
- encrypt.key(key);
- CssmData cipher;
- CssmData remcipher;
- encrypt.encrypt(&in, 1, &cipher, 1);
- encrypt.final(remcipher);
- printf("ciphertext=");
- dump(cipher);
- printf("remainder=");
- dump(remcipher);
-
- // Decrypt
- printf("Decrypting\n");
-
- Decrypt decrypt(cspdl, CSSM_ALGID_DES);
- decrypt.key(key);
- decrypt.mode(CSSM_ALGMODE_CBCPadIV8);
- decrypt.padding(CSSM_PADDING_PKCS1);
- decrypt.initVector(iv);
- CssmData plain;
- CssmData remplain;
- CssmData inp[] = { cipher, remcipher };
- decrypt.decrypt(inp, 2, &plain, 1);
- decrypt.final(remplain);
- printf("plaintext=");
- dump(plain);
- printf("remainder=");
- dump(remplain);
-
- printf("end encrypt/decrypt test\n");
-}
-
-static void print(sint32 value)
-{
- printf("%ld", value);
-}
-
-static void print(double value)
-{
- printf("%g", value);
-}
-
-static void print(uint32 value)
-{
- uint8 *bytes = reinterpret_cast<uint8 *>(&value);
- bool ascii = true;
- for (uint32 ix = 0; ix < sizeof(uint32); ++ix)
- if (bytes[ix] < 0x20 || bytes[ix] > 0x7f)
- {
- ascii = false;
- break;
- }
-
- if (ascii)
- {
- putchar('\'');
- for (uint32 ix = 0; ix < sizeof(uint32); ++ix)
- putchar(bytes[ix]);
-
- printf("' (0x%08lx)", value);
- }
- else
- printf("0x%08lx", value);
-}
-
-static void printAsString(uint32 indent, const CSSM_DATA &value)
-{
- printf("%.*s", static_cast<int>(value.Length), value.Data);
-}
-
-static void print(uint32 indent, const char *value)
-{
- printf("%s", value);
-}
-
-static void printIndent(uint32 indent)
-{
- //if (indent == 0)
- // return;
-
- putchar('\n');
- for (uint32 ix = 0; ix < indent; ++ix)
- putchar(' ');
-}
-
-static void printRange(uint32 length, const uint8 *data)
-{
- for (uint32 ix = 0; ix < HEX_DIGITS_PER_LINE; ++ix)
- {
- if (ix && ix % 4 == 0)
- putchar(' ');
-
- if (ix < length)
- printf("%02x", static_cast<unsigned int>(data[ix]));
- else
- printf(" ");
- }
-
- printf(" ");
- for (uint32 ix = 0; ix < length; ++ix)
- {
- if (data[ix] < 0x20 || data[ix] > 0x7f)
- putchar('.');
- else
- putchar(data[ix]);
- }
-}
-
-static void print(uint32 indent, const CSSM_DATA &value)
-{
- if (value.Length == 0)
- return;
-
- if (value.Length > HEX_DIGITS_PER_LINE)
- {
- uint32 ix;
- for (ix = 0; ix < value.Length - HEX_DIGITS_PER_LINE; ix += HEX_DIGITS_PER_LINE)
- {
- printIndent(indent);
- printRange(HEX_DIGITS_PER_LINE, &value.Data[ix]);
- }
- printIndent(indent);
- printRange(value.Length - ix, &value.Data[ix]);
- printIndent(indent - INDENT_SIZE);
- }
- else
- printRange(value.Length, value.Data);
-}
-
-static void printOID(uint32 indent, const CSSM_OID &value)
-{
- print(indent, value);
-}
-
-static const char *format(CSSM_DB_ATTRIBUTE_FORMAT format)
-{
- switch(format)
- {
- case CSSM_DB_ATTRIBUTE_FORMAT_STRING: return "string";
- case CSSM_DB_ATTRIBUTE_FORMAT_SINT32: return "sint32";
- case CSSM_DB_ATTRIBUTE_FORMAT_UINT32: return "uint32";
- case CSSM_DB_ATTRIBUTE_FORMAT_BIG_NUM: return "big_num";
- case CSSM_DB_ATTRIBUTE_FORMAT_REAL: return "real";
- case CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE: return "time_date";
- case CSSM_DB_ATTRIBUTE_FORMAT_BLOB: return "blob";
- case CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32: return "multi_uint32";
- case CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX: return "complex";
- default: abort();
- }
-}
-
-static void print(uint32 indent, const CssmDbAttributeData &attr)
-{
- bool multiValues = false;
- if (attr.size() == 0)
- {
- printf("<array/>");
- return;
- }
-
- if (attr.size() != 1)
- {
- printIndent(indent);
- printf("<array>");
- indent += INDENT_SIZE;
- multiValues = true;
- }
-
- for (uint32 ix = 0; ix < attr.size(); ++ix)
- {
- if (multiValues)
- printIndent(indent);
-
- printf("<%s>", format(attr.format()));
- switch (attr.format())
- {
- case CSSM_DB_ATTRIBUTE_FORMAT_STRING:
- printAsString(indent + INDENT_SIZE, attr.at(ix));
- break;
- case CSSM_DB_ATTRIBUTE_FORMAT_UINT32:
- print(attr.at<uint32>(ix));
- break;
- case CSSM_DB_ATTRIBUTE_FORMAT_SINT32:
- print(attr.at<sint32>(ix));
- break;
- case CSSM_DB_ATTRIBUTE_FORMAT_REAL:
- print(attr.at<double>(ix));
- break;
- case CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE:
- printf("%*s", 15, attr.at<const char *>(ix));
- break;
- case CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32:
- case CSSM_DB_ATTRIBUTE_FORMAT_BIG_NUM:
- case CSSM_DB_ATTRIBUTE_FORMAT_BLOB:
- case CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX:
- default:
- print(indent + INDENT_SIZE, attr.at<const CssmData &>(ix));
- break;
- }
- printf("</%s>", format(attr.format()));
- }
-
- if (multiValues)
- {
- indent -= INDENT_SIZE;
- printIndent(indent);
- printf("</array>");
- }
-}
-
-static void print(uint32 indent, const CssmDbAttributeInfo &info)
-{
- switch (info.nameFormat())
- {
- case CSSM_DB_ATTRIBUTE_NAME_AS_STRING:
- {
- printf("<string>");
- print(indent + INDENT_SIZE, info.Label.AttributeName);
- printf("</string>");
- break;
- }
- case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER:
- {
- printf("<integer>");
- print(info.Label.AttributeID);
- printf("</integer>");
- break;
- }
- case CSSM_DB_ATTRIBUTE_NAME_AS_OID:
- {
- printf("<oid>");
- printOID(indent + INDENT_SIZE, info.Label.AttributeOID);
- printf("</oid>");
- break;
- }
- default:
- throw Error(CSSMERR_DL_DATABASE_CORRUPT);
- }
-}
-
-void dumpDb(char *dbName, bool printSchema)
-{
- DL appledl(*gSelectedFileGuid);
- Db db(appledl, dbName);
- DbCursor relations(db);
- relations->recordType(CSSM_DL_DB_SCHEMA_INFO);
- DbAttributes schemaRecord(db, 2);
- schemaRecord.add(Attributes::RelationID);
- schemaRecord.add(Attributes::RelationName);
- CssmDataContainer data;
- DbUniqueRecord uniqueId(db);
-
- uint32 indent = 0;
- printf("<database>");
- indent += INDENT_SIZE;
- printIndent(indent);
- printf("<name>%s</name>", dbName);
- while (relations->next(&schemaRecord, &data, uniqueId))
- {
- uint32 relationID = schemaRecord.at(0);
- if (!printSchema && CSSM_DB_RECORDTYPE_SCHEMA_START <= relationID
- && relationID < CSSM_DB_RECORDTYPE_SCHEMA_END)
- continue;
-
- printIndent(indent);
- printf("<relation>");
- string relationName = schemaRecord.at(1);
- dumpRelation(indent + INDENT_SIZE, db, relationID, relationName.c_str(), printSchema);
- printIndent(indent);
- printf("</relation>");
- }
-
- indent -= INDENT_SIZE;
- printIndent(indent);
- printf("</database>\n");
-}
-
-static void dumpRelation(uint32 indent, Db &db, uint32 relationID, const char *relationName, bool printSchema)
-{
- TrackingAllocator anAllocator(Allocator::standard());
-
- printIndent(indent);
- printf("<name>");
- print(indent + INDENT_SIZE, relationName);
- printf("</name>");
- printIndent(indent);
- printf("<id>");
- print(relationID);
- printf("</id>");
-
- // Create a cursor on the SCHEMA_ATTRIBUTES table for records with RelationID == relationID
- DbCursor attributes(db);
- attributes->recordType(CSSM_DL_DB_SCHEMA_ATTRIBUTES);
- attributes->add(CSSM_DB_EQUAL, Attributes::RelationID, relationID);
-
- // Set up a record for retriving the SCHEMA_ATTRIBUTES
- DbAttributes schemaRecord(db, 5);
- schemaRecord.add(Attributes::AttributeNameFormat);
- schemaRecord.add(Attributes::AttributeFormat);
- schemaRecord.add(Attributes::AttributeName);
- schemaRecord.add(Attributes::AttributeID);
- schemaRecord.add(Attributes::AttributeNameID);
-
- DbAttributes record(db);
- CssmDataContainer data;
- DbUniqueRecord uniqueId(db);
-
- if (printSchema)
- {
- printIndent(indent);
- printf("<schema>");
- indent += INDENT_SIZE;
- }
-
- while (attributes->next(&schemaRecord, &data, uniqueId))
- {
- CssmDbAttributeInfo &anInfo = record.add().info();
- anInfo.AttributeNameFormat = schemaRecord.at(0);
- anInfo.AttributeFormat = schemaRecord.at(1);
- switch (anInfo.AttributeNameFormat)
- {
- case CSSM_DB_ATTRIBUTE_NAME_AS_STRING:
- {
- CssmDbAttributeData &anAttributeName = schemaRecord.at(2);
-
- string name = static_cast<string>(anAttributeName);
- anInfo.Label.AttributeName = reinterpret_cast<char *>(anAllocator.malloc(name.size() + 1));
- strcpy(anInfo.Label.AttributeName, name.c_str());
-
- // XXX Need to copy the memory. For now avoid it being freed.
- anAttributeName.Value[0].Data = NULL;
- anAttributeName.Value[0].Length = 0;
- break;
- }
- case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER:
- {
- CssmDbAttributeData &anAttributeID = schemaRecord.at(3);
- anInfo.Label.AttributeID = anAttributeID;
- break;
- }
- case CSSM_DB_ATTRIBUTE_NAME_AS_OID:
- {
- CssmDbAttributeData &anAttributeOID = schemaRecord.at(4);
- anInfo.Label.AttributeOID = anAttributeOID;
-
- // XXX Need to copy the memory. For now avoid it being freed.
- anAttributeOID.Value[0].Data = NULL;
- anAttributeOID.Value[0].Length = 0;
- break;
- }
- default:
- throw Error(CSSMERR_DL_DATABASE_CORRUPT);
- }
-
- if (printSchema)
- {
- printIndent(indent);
- print(indent, anInfo);
- printf("<format>%s</format>", format(anInfo.format()));
- }
- }
-
- if (printSchema)
- {
- indent -= INDENT_SIZE;
- printIndent(indent);
- printf("</schema>");
- }
-
- DbCursor records(db);
- records->recordType(relationID);
- printIndent(indent);
- printf("<records>");
- indent += INDENT_SIZE;
- while (records->next(&record, &data, uniqueId))
- dumpRecord(indent, record, data, uniqueId);
-
- indent -= INDENT_SIZE;
- printIndent(indent);
- printf("</records>");
-}
-
-static void
-dumpRecord(uint32 indent, const DbAttributes &record, const CssmData &data, const DbUniqueRecord &uniqueId)
-{
- const CSSM_DB_UNIQUE_RECORD *recId = static_cast<const DbUniqueRecord &>(uniqueId);
- uint32 recCount = recId->RecordIdentifier.Length;
- const uint32 *recArray = reinterpret_cast<const uint32 *>(recId->RecordIdentifier.Data);
- printIndent(indent);
- printf("<recid>");
- for (uint32 ix = 0; ix < recCount / 4; ++ix)
- {
- if (ix != 0)
- putchar(' ');
- printf("0x%08lx", recArray[ix]);
- }
- printf("</recid>");
-
- // Print the attributes
- printIndent(indent);
- if (record.size() == 0)
- {
- printf("<attributes/>");
- }
- else
- {
- printf("<attributes>");
- indent += INDENT_SIZE;
- for (uint32 ix = 0; ix < record.size(); ix++)
- {
- const CssmDbAttributeData &anAttr = record.at(ix);
- if (anAttr.size()) // Skip zero valued attributes.
- {
- printIndent(indent);
- print(indent + INDENT_SIZE, anAttr.info());
- print(indent + INDENT_SIZE, anAttr);
- }
- }
-
- indent -= INDENT_SIZE;
- printIndent(indent);
- printf("</attributes>");
- }
-
- // Print the data
- printIndent(indent);
- if (data.length())
- {
- printf("<data>");
- print(indent + INDENT_SIZE, data);
- printf("</data>");
- }
- else
- printf("<data/>");
-}
-
-static void testMultiDLDb(const Guid &dlGuid)
-{
- // Setup a list of DLDbIdentifier object to hand off the MultiDLDb.
- vector<DLDbIdentifier> list;
- list.push_back(DLDbIdentifier(CssmSubserviceUid(dlGuid), "multidb1.db", NULL));
- list.push_back(DLDbIdentifier(CssmSubserviceUid(dlGuid), "multidb2.db", NULL));
-
- // Create MultiDLDb instance.
- MultiDLDb multiDLDb(list, false);
-
- // Get a handle for the first and second Db.
- Db db1(multiDLDb->database(list[0]));
- Db db2(multiDLDb->database(list[1]));
-
- // Until this point no CSSM API's have been called!
-
- // Delete both databases if they exist.
- try
- { db1->deleteDb(); }
- catch(CssmError e)
- { if (e.osStatus() != CSSMERR_DL_DATASTORE_DOESNOT_EXIST) throw; }
-
- try
- { db2->deleteDb(); }
- catch(CssmError e)
- { if (e.osStatus() != CSSMERR_DL_DATASTORE_DOESNOT_EXIST) throw; }
-
- // XXX Note to self if you set the schema but do not call create()
- // explicitly maybe the db should only be created if it did not yet exist...
-
- // Set the schema of both databases so they get created on activate.
- db1->dbInfo(&KCDBInfo);
- db2->dbInfo(&KCDBInfo);
-
- // Insert a record into each database.
- DbAttributes attrs(db1);
- attrs.add(Attributes::Comment, "This is the first comment").add("This is the second comment", attrs);
- attrs.add(Attributes::Label, "Item1");
- CssmPolyData testdata1("testdata1");
- db1->insert(CSSM_DL_DB_RECORD_GENERIC_PASSWORD, &attrs, &testdata1);
-
- attrs.clear();
- attrs.add(Attributes::Comment, "This is the second comment");
- attrs.add(Attributes::Label, "Item (in database2).");
- CssmPolyData testdata2("testdata2");
- db2->insert(CSSM_DL_DB_RECORD_GENERIC_PASSWORD, &attrs, &testdata2);
-
- // Create a cursor on the multiDLDb.
- DbCursor cursor(multiDLDb);
- // Set the type of records we wish to query.
- cursor->recordType(CSSM_DL_DB_RECORD_GENERIC_PASSWORD);
- cursor->add(CSSM_DB_EQUAL, Attributes::Comment, "This is the second comment");
-
- DbUniqueRecord uniqueId; // Empty uniqueId calling cursor.next will initialize.
- CssmDataContainer data; // XXX Think about data's allocator.
-
- // Iterate over the records in all the db's in the multiDLDb.
- while (cursor->next(&attrs, &data, uniqueId))
- {
- // Print the record data.
- dumpRecord(0, attrs, data, uniqueId);
- }
-}
-
-#if 0
- CssmDb::Impl *CssmDL::Impl::newDb(args) { new CssmDbImpl(args); }
-
- SecureStorage ss(Guid);
- CssmDb db(ss, DBNAME);
- CssmUniqueId unique;
- db.insert(attr, data, unique);
-
- Cursor cursor(db);
- CssmKey key;
- cursor.next(key);
-
- Cssm cssm;
- Module module(cssm);
- CSPDL cspdl(module);
-
-
- SecureStorage ss(Guid);
- CssmDb db = ss->db(DBNAME);
- CssmUniqueId unique;
- db->insert(attr, data, unique);
-
- Cursor cursor(db);
- CssmKey key;
- cursor->next(key);
-
-
-#endif