From 24a291535d44686bc7959c7e398fab040e3e08a7 Mon Sep 17 00:00:00 2001 From: Apple Date: Mon, 15 May 2006 23:06:28 +0000 Subject: [PATCH] securityd-27896.tar.gz --- securityd.xcode/project.pbxproj | 14 +++--- src/acls.cpp | 3 ++ src/acls.h | 1 + src/agentquery.cpp | 18 ++++---- src/codesigdb.cpp | 47 +++++++++++++------- src/dbcrypto.cpp | 12 ++--- src/dbcrypto.h | 2 +- src/flippers.cpp | 44 ++++++++++++++++--- src/flippers.h | 5 ++- src/generate.cf | 4 +- src/kcdatabase.cpp | 4 +- src/kckey.cpp | 4 +- src/main.cpp | 3 +- src/notifications.cpp | 3 +- src/server.h | 8 ++-- src/session.cpp | 4 +- src/session.h | 2 +- src/structure.h | 16 +++---- src/token.cpp | 8 ++-- src/tokend.cpp | 7 +++ src/tokend.h | 1 + src/transition.cpp | 7 +-- src/transwalkers.cpp | 77 +++++++++++++++++++++++++++++++++ src/transwalkers.h | 21 ++++++++- 24 files changed, 236 insertions(+), 79 deletions(-) diff --git a/securityd.xcode/project.pbxproj b/securityd.xcode/project.pbxproj index 6b77cb6..2cbf2f2 100644 --- a/securityd.xcode/project.pbxproj +++ b/securityd.xcode/project.pbxproj @@ -836,21 +836,21 @@ ); buildSettings = { BUILD_VARIANTS = "normal debug"; - CURRENT_PROJECT_VERSION = 27887; + CURRENT_PROJECT_VERSION = 27896; FRAMEWORK_SEARCH_PATHS = "/usr/local/SecurityPieces/Frameworks /usr/local/SecurityPieces/Components/securityd $(SYSTEM_LIBRARY_DIR)/PrivateFrameworks"; INSTALL_PATH = /usr/sbin; - OPT_CPPXFLAGS = "$(OPT_CXFLAGS) -fno-enforce-eh-specs -fno-implement-inlines -fcoalesce-templates"; + OPT_CPPXFLAGS = "$(OPT_CXFLAGS)"; OPT_CXFLAGS = "-DNDEBUG $(OPT_INLINEXFLAGS)"; - OPT_INLINEXFLAGS = " -finline-functions --param max-inline-insns-single=150 --param max-inline-insns-auto=150 --param max-inline-insns=300 --param min-inline-insns=90"; + OPT_INLINEXFLAGS = "-finline-functions"; OPT_LDXFLAGS = "-dead_strip"; OPT_LDXNOPIC = ",_nopic"; OTHER_ASFLAGS_debug = "$(OTHER_CFLAGS)"; OTHER_ASFLAGS_normal = "-DNDEBUG $(OTHER_CFLAGS)"; OTHER_ASFLAGS_profile = "-DNDEBUG $(OTHER_CFLAGS) -pg"; - OTHER_CFLAGS_debug = "$(OTHER_CFLAGS) -O0 -fno-inline"; + OTHER_CFLAGS_debug = "$(OTHER_CFLAGS) -O1 -fno-inline"; OTHER_CFLAGS_normal = "$(OPT_CXFLAGS) $(OTHER_CFLAGS)"; OTHER_CFLAGS_profile = "$(OPT_CXFLAGS) $(OTHER_CFLAGS) -pg"; - OTHER_CPLUSPLUSFLAGS_debug = "$(OTHER_CPLUSPLUSFLAGS) -O0 -fno-inline"; + OTHER_CPLUSPLUSFLAGS_debug = "$(OTHER_CPLUSPLUSFLAGS) -O1 -fno-inline"; OTHER_CPLUSPLUSFLAGS_normal = "$(OPT_CPPXFLAGS) $(OTHER_CPLUSPLUSFLAGS)"; OTHER_CPLUSPLUSFLAGS_profile = "$(OPT_CPPXFLAGS) $(OTHER_CPLUSPLUSFLAGS) -pg"; OTHER_LDFLAGS = "-lbsm"; @@ -1378,8 +1378,8 @@ OPT_LDFLAGS = ""; OPT_LDXFLAGS = ""; OPT_LDXNOPIC = ""; - OTHER_CFLAGS_normal = "$(OTHER_CFLAGS) -O0 -fno-inline"; - OTHER_CPLUSPLUSFLAGS_normal = "$(OTHER_CPLUSPLUSFLAGS) -O0 -fno-inline"; + OTHER_CFLAGS_normal = "$(OTHER_CFLAGS) -O1 -fno-inline"; + OTHER_CPLUSPLUSFLAGS_normal = "$(OTHER_CPLUSPLUSFLAGS) -O1 -fno-inline"; }; isa = PBXBuildStyle; name = "normal with debug"; diff --git a/src/acls.cpp b/src/acls.cpp index f820d00..aa2524a 100644 --- a/src/acls.cpp +++ b/src/acls.cpp @@ -187,6 +187,9 @@ ObjectAcl *SecurityServerEnvironment::preAuthSource() // // The default AclSource denies having an ACL at all // +AclSource::~AclSource() +{ /* virtual */ } + SecurityServerAcl &AclSource::acl() { CssmError::throwMe(CSSM_ERRCODE_OBJECT_ACL_NOT_SUPPORTED); diff --git a/src/acls.h b/src/acls.h index 0aad47f..ed8338b 100644 --- a/src/acls.h +++ b/src/acls.h @@ -118,6 +118,7 @@ public: class AclSource { protected: AclSource() { } + virtual ~AclSource(); public: virtual SecurityServerAcl &acl(); // defaults to "no ACL; throw exception" diff --git a/src/agentquery.cpp b/src/agentquery.cpp index 1876642..9878249 100644 --- a/src/agentquery.cpp +++ b/src/agentquery.cpp @@ -242,7 +242,7 @@ Reason QueryKeychainUse::queryUser (const char *database, const char *descriptio if (mPassphraseCheck) { - create("builtin", "confirm-access-password", NULL); + create("builtin", "confirm-access-password", noSecuritySession); CssmAutoData data(Allocator::standard(Allocator::sensitive)); @@ -280,7 +280,7 @@ Reason QueryKeychainUse::queryUser (const char *database, const char *descriptio } else { - create("builtin", "confirm-access", NULL); + create("builtin", "confirm-access", noSecuritySession); setInput(hints, context); invoke(); } @@ -322,7 +322,7 @@ bool QueryCodeCheck::operator () (const char *aclPath) hints.insert(AuthItemRef(AGENT_HINT_APPLICATION_PATH, AuthValueOverlay(strlen(aclPath), const_cast(aclPath)))); - create("builtin", "code-identity", NULL); + create("builtin", "code-identity", noSecuritySession); setInput(hints, context); status = invoke(); @@ -366,7 +366,7 @@ Reason QueryOld::query() hints.insert(mClientHints.begin(), mClientHints.end()); - create("builtin", "unlock-keychain", NULL); + create("builtin", "unlock-keychain", noSecuritySession); do { @@ -478,10 +478,10 @@ Reason QueryNewPassphrase::query() switch (initialReason) { case SecurityAgent::newDatabase: - create("builtin", "new-passphrase", NULL); + create("builtin", "new-passphrase", noSecuritySession); break; case SecurityAgent::changePassphrase: - create("builtin", "change-passphrase", NULL); + create("builtin", "change-passphrase", noSecuritySession); break; default: assert(false); @@ -597,11 +597,11 @@ Reason QueryGenericPassphrase::query(const char *prompt, bool verify, // CSSM_ATTRIBUTE_ALERT_TITLE (optional alert panel title) if (false == verify) { // import - create("builtin", "generic-unlock", NULL); + create("builtin", "generic-unlock", noSecuritySession); } else { // verify passphrase (export) // new-passphrase-generic works with the pre-4 June 2004 agent; // generic-new-passphrase is required for the new agent - create("builtin", "generic-new-passphrase", NULL); + create("builtin", "generic-new-passphrase", noSecuritySession); } AuthItem *passwordItem; @@ -652,7 +652,7 @@ Reason QueryDBBlobSecret::query(DatabaseCryptoCore &dbCore, const DbBlob *secret hints.insert(mClientHints.begin(), mClientHints.end()); - create("builtin", "generic-unlock-kcblob", NULL); + create("builtin", "generic-unlock-kcblob", noSecuritySession); AuthItem *secretItem; diff --git a/src/codesigdb.cpp b/src/codesigdb.cpp index d8094fa..4ff3d64 100644 --- a/src/codesigdb.cpp +++ b/src/codesigdb.cpp @@ -116,7 +116,8 @@ CodeSignatures::~CodeSignatures() void CodeSignatures::open(const char *path) { mDb.open(path, O_RDWR | O_CREAT, 0644); - mDb.flush(); + if (mDb) + mDb.flush(); IFDUMPING("equiv", debugDump("reopen")); } @@ -144,6 +145,8 @@ string CodeSignatures::Identity::canonicalName(const string &path) // bool CodeSignatures::find(Identity &id, uid_t user) { + if (!mDb) + return false; if (id.mState != Identity::untried) return id.mState == Identity::valid; try { @@ -171,6 +174,8 @@ bool CodeSignatures::find(Identity &id, uid_t user) void CodeSignatures::makeLink(Identity &id, const string &ident, bool forUser, uid_t user) { + if (!mDb) + UnixError::throwMe(ENOENT); DbKey key('H', id.getHash(mSigner), forUser, user); if (!mDb.put(key, StringData(ident))) UnixError::throwMe(); @@ -214,6 +219,8 @@ void CodeSignatures::addLink(const CssmData &oldHash, const CssmData &newHash, void CodeSignatures::removeLink(const CssmData &hash, const char *name, bool forSystem) { + if (!mDb) + UnixError::throwMe(ENOENT); AclIdentity code(hash, name); uid_t user = Server::process().uid(); if (forSystem && user) // only root user can remove forSystem links @@ -252,6 +259,12 @@ bool CodeSignatures::verify(Process &process, return false; } + // don't bother the user if the db is MIA + if (!mDb) { + secdebug("codesign", "database not open; cannot verify"); + return false; + } + // ah well. Establish mediator objects for database signature links AclIdentity aclIdentity(trustedSignature, comment ? comment->interpretedAs() : NULL); @@ -302,7 +315,7 @@ bool CodeSignatures::verify(Process &process, return false; } } - + // ask the user QueryCodeCheck query; query.inferHints(process); @@ -357,20 +370,24 @@ void CodeSignatures::debugDump(const char *how) const if (!how) how = "dump"; CssmData key, value; - if (!mDb.first(key, value)) { - dump("CODE EQUIVALENTS DATABASE IS EMPTY (%s)\n", how); + if (!mDb) { + dump("CODE EQUIVALENTS DATABASE IS NOT OPEN (%s)", how); } else { - dump("CODE EQUIVALENTS DATABASE DUMP (%s)\n", how); - do { - const char *header = key.interpretedAs(); - size_t headerLength = strlen(header) + 1; - dump("%s:", header); - dumpData(key.at(headerLength), key.length() - headerLength); - dump(" => "); - dumpData(value); - dump("\n"); - } while (mDb.next(key, value)); - dump("END DUMP\n"); + if (!mDb.first(key, value)) { + dump("CODE EQUIVALENTS DATABASE IS EMPTY (%s)\n", how); + } else { + dump("CODE EQUIVALENTS DATABASE DUMP (%s)\n", how); + do { + const char *header = key.interpretedAs(); + size_t headerLength = strlen(header) + 1; + dump("%s:", header); + dumpData(key.at(headerLength), key.length() - headerLength); + dump(" => "); + dumpData(value); + dump("\n"); + } while (mDb.next(key, value)); + dump("END DUMP\n"); + } } } diff --git a/src/dbcrypto.cpp b/src/dbcrypto.cpp index b850653..5054f85 100644 --- a/src/dbcrypto.cpp +++ b/src/dbcrypto.cpp @@ -238,7 +238,7 @@ DbBlob *DatabaseCryptoCore::encodeCore(const DbBlob &blobTemplate, // Throws exceptions if decoding fails. // Memory returned in privateAclBlob is allocated and becomes owned by caller. // -void DatabaseCryptoCore::decodeCore(DbBlob *blob, void **privateAclBlob) +void DatabaseCryptoCore::decodeCore(const DbBlob *blob, void **privateAclBlob) { assert(mHaveMaster); // must have master key installed @@ -247,8 +247,8 @@ void DatabaseCryptoCore::decodeCore(DbBlob *blob, void **privateAclBlob) decryptor.mode(CSSM_ALGMODE_CBCPadIV8); decryptor.padding(CSSM_PADDING_PKCS1); decryptor.key(mMasterKey); - CssmData ivd(blob->iv, sizeof(blob->iv)); decryptor.initVector(ivd); - CssmData cryptoBlob(blob->cryptoBlob(), blob->cryptoBlobLength()); + CssmData ivd = CssmData::wrap(blob->iv); decryptor.initVector(ivd); + CssmData cryptoBlob = CssmData::wrap(blob->cryptoBlob(), blob->cryptoBlobLength()); CssmData decryptedBlob, remData; decryptor.decrypt(cryptoBlob, decryptedBlob, remData); DbBlob::PrivateBlob *privateBlob = decryptedBlob.interpretedAs(); @@ -263,8 +263,8 @@ void DatabaseCryptoCore::decodeCore(DbBlob *blob, void **privateAclBlob) // verify signature on the whole blob CssmData signChunk[] = { - CssmData(blob->data(), fieldOffsetOf(&DbBlob::blobSignature)), - CssmData(blob->publicAclBlob(), blob->publicAclBlobLength() + blob->cryptoBlobLength()) + CssmData::wrap(blob->data(), fieldOffsetOf(&DbBlob::blobSignature)), + CssmData::wrap(blob->publicAclBlob(), blob->publicAclBlobLength() + blob->cryptoBlobLength()) }; CSSM_ALGORITHMS verifyAlgorithm = CSSM_ALGID_SHA1HMAC; #if defined(COMPAT_OSX_10_0) @@ -273,7 +273,7 @@ void DatabaseCryptoCore::decodeCore(DbBlob *blob, void **privateAclBlob) #endif VerifyMac verifier(Server::csp(), verifyAlgorithm); verifier.key(mSigningKey); - verifier.verify(signChunk, 2, CssmData(blob->blobSignature, sizeof(blob->blobSignature))); + verifier.verify(signChunk, 2, CssmData::wrap(blob->blobSignature)); // all checks out; start extracting fields if (privateAclBlob) { diff --git a/src/dbcrypto.h b/src/dbcrypto.h index 3067b70..16d42e3 100644 --- a/src/dbcrypto.h +++ b/src/dbcrypto.h @@ -55,7 +55,7 @@ public: void setup(const DbBlob *blob, const CssmData &passphrase); void setup(const DbBlob *blob, CssmClient::Key master); - void decodeCore(DbBlob *blob, void **privateAclBlob = NULL); + void decodeCore(const DbBlob *blob, void **privateAclBlob = NULL); DbBlob *encodeCore(const DbBlob &blobTemplate, const CssmData &publicAcl, const CssmData &privateAcl) const; void importSecrets(const DatabaseCryptoCore &src); diff --git a/src/flippers.cpp b/src/flippers.cpp index 6f67415..4f8fa31 100644 --- a/src/flippers.cpp +++ b/src/flippers.cpp @@ -33,13 +33,6 @@ using namespace LowLevelMemoryUtilities; namespace Flippers { - -// -// Automatically generated flippers -// -#include "flip_gen.cpp" - - // // The raw byte reversal flipper // @@ -82,4 +75,41 @@ void flip(CSSM_CONTEXT_ATTRIBUTE &obj) } +// +// Flip a CSSM_DB_ATTRIBUTE_INFO, also very polymorphic +// +void flip(CSSM_DB_ATTRIBUTE_INFO &obj) +{ + bool flippedAttributeNameFormat = false; + // check and see if obj is in host byte order. If not, flip it now + if (obj.AttributeNameFormat > CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER) + { + flip(obj.AttributeNameFormat); + flippedAttributeNameFormat = true; + } + + switch (obj.AttributeNameFormat) + { + case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER: + { + flip(obj.Label.AttributeID); + } + break; + } + + flip (obj.AttributeFormat); + + if (!flippedAttributeNameFormat) + { + flip(obj.AttributeNameFormat); + } + +} + +// +// Automatically generated flippers +// +#include "flip_gen.cpp" + + } // end namespace Flippers diff --git a/src/flippers.h b/src/flippers.h index 6e437c0..9d2fb8c 100644 --- a/src/flippers.h +++ b/src/flippers.h @@ -56,8 +56,7 @@ inline void flip(T &obj) // It's a bad idea to try to flip a const, so flag that // template -inline void flip(const T &) -{ tryingToFlipAConstWontWork(); } +inline void flip(const T &); // @@ -77,6 +76,8 @@ inline void flip(Base * &obj) { flip(&obj, sizeof(obj)); } // void flip(void *addr, size_t size); +void flip(CSSM_DB_ATTRIBUTE_INFO &obj); +inline void flip(CssmDbAttributeInfo &obj) { flip(static_cast(obj)); } // // Include automatically generated flipper declarations diff --git a/src/generate.cf b/src/generate.cf index 8557c3e..fa387c5 100644 --- a/src/generate.cf +++ b/src/generate.cf @@ -33,7 +33,9 @@ CSSM_RANGE * CSSM_KEY_SIZE/CssmKeySize * CSSM_KEYHEADER/CssmKey::Header * CSSM_KEY/CssmKey KeyHeader - +CSSM_QUERY/CssmQuery RecordType Conjunctive NumSelectionPredicates QueryLimits QueryFlags +CSSM_DB_ATTRIBUTE_DATA/CssmDbAttributeData NumberOfValues +CSSM_DB_RECORD_ATTRIBUTE_DATA/CssmDbRecordAttributeData DataRecordType SemanticInformation NumberOfAttributes # # Authorization structures diff --git a/src/kcdatabase.cpp b/src/kcdatabase.cpp index 8f723c5..32160b5 100644 --- a/src/kcdatabase.cpp +++ b/src/kcdatabase.cpp @@ -878,10 +878,10 @@ void KeychainDatabase::validateBlob(const DbBlob *blob) blob->validate(CSSMERR_APPLEDL_INVALID_DATABASE_BLOB); switch (blob->version()) { #if defined(COMPAT_OSX_10_0) - case blob->version_MacOS_10_0: + case DbBlob::version_MacOS_10_0: break; #endif - case blob->version_MacOS_10_1: + case DbBlob::version_MacOS_10_1: break; default: CssmError::throwMe(CSSMERR_APPLEDL_INCOMPATIBLE_DATABASE_BLOB); diff --git a/src/kckey.cpp b/src/kckey.cpp index c5c825e..f6ed602 100644 --- a/src/kckey.cpp +++ b/src/kckey.cpp @@ -43,10 +43,10 @@ KeychainKey::KeychainKey(Database &db, const KeyBlob *blob) blob->validate(CSSMERR_APPLEDL_INVALID_KEY_BLOB); switch (blob->version()) { #if defined(COMPAT_OSX_10_0) - case blob->version_MacOS_10_0: + case KeyBlob::version_MacOS_10_0: break; #endif - case blob->version_MacOS_10_1: + case KeyBlob::version_MacOS_10_1: break; default: CssmError::throwMe(CSSMERR_APPLEDL_INCOMPATIBLE_KEY_BLOB); diff --git a/src/main.cpp b/src/main.cpp index 2208882..5b47f5e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -64,7 +64,6 @@ #include #include "acl_keychain.h" - // // Local functions of the main program driver // @@ -261,7 +260,7 @@ int main(int argc, char *argv[]) // install MDS and initialize the local CSSM server.loadCssm(); - + // okay, we're ready to roll Syslog::notice("Entering service"); secdebug("SS", "%s initialized", bootstrapName); diff --git a/src/notifications.cpp b/src/notifications.cpp index 0ac6a36..ebee947 100644 --- a/src/notifications.cpp +++ b/src/notifications.cpp @@ -29,7 +29,6 @@ #include "server.h" #include - Listener::ListenerMap Listener::listeners; Mutex Listener::setLock; @@ -116,7 +115,7 @@ void ProcessListener::notifyMe(NotificationDomain domain, { secdebug("notify", "%p sending domain %ld event 0x%lx to port %d process %d", this, domain, event, mPort.port(), process.pid()); - + // send mach message (via MIG simpleroutine) if (IFDEBUG(kern_return_t rc =) ucsp_notify_sender_notify(mPort, domain, event, data.data(), data.length(), diff --git a/src/server.h b/src/server.h index 80c0992..011a649 100644 --- a/src/server.h +++ b/src/server.h @@ -114,11 +114,11 @@ public: static AclSource &aclBearer(AclKind kind, CSSM_HANDLE handle); // Generic version of handle lookup - template - static RefPointer find(CSSM_HANDLE handle, CSSM_RETURN notFoundError) + template + static RefPointer find(CSSM_HANDLE handle, CSSM_RETURN notFoundError) { - RefPointer object = - HandleObject::findRef(handle, notFoundError); + RefPointer object = + HandleObject::findRef(handle, notFoundError); if (object->process() != Server::process()) CssmError::throwMe(notFoundError); return object; diff --git a/src/session.cpp b/src/session.cpp index 9f4854f..7cabc91 100644 --- a/src/session.cpp +++ b/src/session.cpp @@ -485,7 +485,7 @@ OSStatus Session::authorizationdbRemove(const AuthorizationBlob &authBlob, Autho void Session::mergeCredentials(CredentialSet &creds) { secdebug("SSsession", "%p merge creds @%p", this, &creds); - CredentialSet updatedCredentials = creds; + CredentialSet updatedCredentials = creds; for (CredentialSet::const_iterator it = creds.begin(); it != creds.end(); it++) if (((*it)->isShared() && (*it)->isValid())) { CredentialSet::iterator old = mSessionCreds.find(*it); @@ -498,7 +498,7 @@ void Session::mergeCredentials(CredentialSet &creds) updatedCredentials.insert(*old); } } - creds.swap(updatedCredentials); + creds.swap(updatedCredentials); } diff --git a/src/session.h b/src/session.h index b252964..7799cc4 100644 --- a/src/session.h +++ b/src/session.h @@ -139,7 +139,7 @@ protected: void kill(); -private: +protected: static PortMap mSessions; }; diff --git a/src/structure.h b/src/structure.h index 2be7527..66f0d92 100644 --- a/src/structure.h +++ b/src/structure.h @@ -222,24 +222,24 @@ template class PortMap : public Mutex, public std::map > { typedef std::map > _Map; public: - bool contains(mach_port_t port) const { return find(port) != end(); } + bool contains(mach_port_t port) const { return this->find(port) != this->end(); } Node *getOpt(mach_port_t port) const { - typename _Map::const_iterator it = find(port); - return (it == end()) ? NULL : it->second; + typename _Map::const_iterator it = this->find(port); + return (it == this->end()) ? NULL : it->second; } Node *get(mach_port_t port) const { - typename _Map::const_iterator it = find(port); - assert(it != end()); + typename _Map::const_iterator it = this->find(port); + assert(it != this->end()); return it->second; } Node *get(mach_port_t port, OSStatus error) const { - typename _Map::const_iterator it = find(port); - if (it == end()) + typename _Map::const_iterator it = this->find(port); + if (it == this->end()) MacOSError::throwMe(error); return it->second; } @@ -250,7 +250,7 @@ public: template void PortMap::dump() { - for (typename _Map::const_iterator it = begin(); it != end(); it++) + for (typename _Map::const_iterator it = this->begin(); it != this->end(); it++) it->second->dump(); } diff --git a/src/token.cpp b/src/token.cpp index faf7172..17e405d 100644 --- a/src/token.cpp +++ b/src/token.cpp @@ -149,8 +149,8 @@ void Token::resetAcls() mResetLevel++; secdebug("token", "%p reset (level=%d, propagating to %ld common(s)", this, mResetLevel, mCommons.size()); - for (CommonSet::const_iterator it = mCommons.begin(); it != mCommons.end(); it++) - RefPointer(*it)->resetAcls(); + for (CommonSet::const_iterator it = mCommons.begin(); it != mCommons.end(); ) + RefPointer(*it++)->resetAcls(); } void Token::addCommon(TokenDbCommon &dbc) @@ -382,8 +382,8 @@ void Token::kill() void Token::notify(NotificationEvent event) { NameValueDictionary nvd; - CssmSubserviceUid ssuid(mGuid, NULL, mSubservice, - CSSM_SERVICE_DL | CSSM_SERVICE_CSP); + CssmSubserviceUid ssuid(mGuid, NULL, h2n (mSubservice), + h2n(CSSM_SERVICE_DL | CSSM_SERVICE_CSP)); nvd.Insert(new NameValuePair(SSUID_KEY, CssmData::wrap(ssuid))); CssmData data; nvd.Export(data); diff --git a/src/tokend.cpp b/src/tokend.cpp index 1707618..350752f 100644 --- a/src/tokend.cpp +++ b/src/tokend.cpp @@ -177,6 +177,13 @@ bool TokenDaemon::probe() } +// +// FaultRelay +// +FaultRelay::~FaultRelay() +{ /* virtual */ } + + // // Debug dump support // diff --git a/src/tokend.h b/src/tokend.h index 6e407ab..e4b808a 100644 --- a/src/tokend.h +++ b/src/tokend.h @@ -41,6 +41,7 @@ // class FaultRelay { public: + virtual ~FaultRelay(); virtual void relayFault(bool async) = 0; }; diff --git a/src/transition.cpp b/src/transition.cpp index 63d12eb..79f708e 100644 --- a/src/transition.cpp +++ b/src/transition.cpp @@ -189,8 +189,8 @@ kern_return_t ucsp_server_findFirst(UCSP_ARGS, DbHandle db, DATA_OUT(data), KeyHandle *hKey, SearchHandle *hSearch, RecordHandle *hRecord) { BEGIN_IPC - relocate(query, queryBase, queryLength); - relocate(inAttributes, inAttributesBase, inAttributesLength); + relocate (query, queryBase, queryLength); + relocate (inAttributes, inAttributesBase, inAttributesLength); RefPointer search; RefPointer record; @@ -212,7 +212,8 @@ kern_return_t ucsp_server_findFirst(UCSP_ARGS, DbHandle db, *hKey = key ? key->handle() : noKey; // return attributes (assumes relocated flat blob) - flips(outAttrs, outAttributes, outAttributesBase); + flips(outAttrs, outAttributes, outAttributesBase); + // flipCssmDbAttributeData(outAttrs, outAttributes, outAttributesBase); *outAttributesLength = outAttrsLength; // return data (temporary fix) diff --git a/src/transwalkers.cpp b/src/transwalkers.cpp index 0d8fa4a..2a3055a 100644 --- a/src/transwalkers.cpp +++ b/src/transwalkers.cpp @@ -111,3 +111,80 @@ Database *pickDb(Database *db1, Database *db2) // none at all. use the canonical transient store return Server::optionalDatabase(noDb); } + + + +void fixDbAttributes (CssmDbAttributeData &data) +{ + /* + NOTE TO FUTURE MAINTAINERS OF THIS CODE: + + This code is called by two different routines; the relocation walker on the input attributes, and flips + on the output attributtes. This is bad, because the relocation walker flips the Info data structure, + and flips does not. We could fix this in flips, but flips is a template and does different things + depending on what its parameters are. As a result, the best place to do this is here. + */ + + // pull this data out first, so that it is unperverted once the flip occurs + unsigned limit = data.size (); + unsigned format = data.format (); + CssmData* values = data.values (); + + // flip if it is safe to do so + if (format > CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX) // is the format screwed up? + { + flip (data.info ()); + limit = data.size (); + format = data.format (); + values = data.values (); + } + + unsigned i; + + for (i = 0; i < limit; ++i) + { + switch (format) + { + case CSSM_DB_ATTRIBUTE_FORMAT_UINT32: + Flippers::flip(*(uint32*) values[i].data ()); + break; + + case CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32: + { + CssmData& d = values[i]; + int numValues = d.length() / sizeof (UInt32); + int j; + UInt32* v = (UInt32*) d.data(); + for (j = 0; j < numValues; ++j) + { + Flippers::flip (v[j]); + } + } + break; + } + } +} + + + +void fixDbAttributes (CssmQuery &query) +{ + unsigned i; + unsigned numItems = query.size (); + for (i = 0; i < numItems; ++i) + { + fixDbAttributes(query.predicates()[i].attribute()); + } +} + + + +void fixDbAttributes (CssmDbRecordAttributeData &data) +{ + unsigned i; + unsigned numItems = data.size (); + for (i = 0; i < numItems; ++i) + { + fixDbAttributes(data.attributes()[i]); + } +} diff --git a/src/transwalkers.h b/src/transwalkers.h index 148ed22..e9476a7 100644 --- a/src/transwalkers.h +++ b/src/transwalkers.h @@ -121,6 +121,17 @@ private: }; +// +// Fix DBAttributes, which have to be processed specially +// +void fixDbAttributes (CssmDbAttributeData &data); +void fixDbAttributes (CssmQuery &query); +void fixDbAttributes (CssmDbRecordAttributeData &data); + +template +void fixDbAttributes(T &n) {} // handle the default case + + // // Process an incoming (IPC) data blob of type T. // This relocates pointers to fit in the local address space, @@ -135,6 +146,10 @@ void relocate(T *obj, T *base, size_t size) CheckingReconstituteWalker relocator(obj, base, size, Server::process().byteFlipped()); walk(relocator, base); + + // resolve weird type interdependency in DB_ATTRIBUTE_DATA + if (Server::process().byteFlipped()) + fixDbAttributes(*obj); } } @@ -222,6 +237,8 @@ void flip(T &addr) } +void flipCssmDbAttributeData (CssmDbRecordAttributeData *value, CssmDbRecordAttributeData **&addr, CssmDbRecordAttributeData **&base); + // // Take an object at value, flip it, and return appropriately flipped // addr/base pointers ready to be returned through IPC. @@ -232,6 +249,9 @@ void flips(T *value, T ** &addr, T ** &base) { *addr = *base = value; if (flipClient()) { + // resolve weird type inter-dependency in DB_ATTRIBUTE_DATA + if (value) + fixDbAttributes(*value); FlipWalker w; // collector walk(w, value); // collect all flippings needed w.doFlips(); // execute flips (flips value but leaves addr alone) @@ -239,7 +259,6 @@ void flips(T *value, T ** &addr, T ** &base) } } - // // Take a DATA type RPC argument purportedly representing a Blob of some kind, // turn it into a Blob, and fail properly if it's not kosher. -- 2.45.2