From 725c39316cb3980a9dce9e188ecacab87dca778c Mon Sep 17 00:00:00 2001 From: Apple Date: Fri, 24 Jun 2005 22:48:33 +0000 Subject: [PATCH] securityd-67.tar.gz --- etc/CodeEquivalenceCandidates | 14 +++++++++-- securityd.xcode/project.pbxproj | 2 +- src/kcdatabase.cpp | 17 ++++++++++--- src/kcdatabase.h | 2 +- src/localdatabase.h | 11 +++++++++ src/pcscmonitor.cpp | 44 +++++++++++++++++++-------------- src/pcscmonitor.h | 4 +-- 7 files changed, 66 insertions(+), 28 deletions(-) diff --git a/etc/CodeEquivalenceCandidates b/etc/CodeEquivalenceCandidates index 5c32ae4..45cc39a 100644 --- a/etc/CodeEquivalenceCandidates +++ b/etc/CodeEquivalenceCandidates @@ -24,16 +24,26 @@ /System/Library/CoreServices/SystemUIServer.app /System/Library/CoreServices/dotmacsyncclient /System/Library/Filesystems/ftp.fs/mount_ftp +/System/Library/Frameworks/ApplicationServices.framework/Frameworks/AE.framework/Versions/A/Support/AEServer /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/AE.framework/Versions/A/Support/AEServer +/System/Library/Frameworks/ApplicationServices.framework/Versions/Current/Frameworks/AE.framework/Versions/A/Support/AEServer +/System/Library/Frameworks/ApplicationServices.framework/Frameworks/AE.framework/Versions/Current/Support/AEServer +/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/AE.framework/Versions/Current/Support/AEServer +/System/Library/Frameworks/ApplicationServices.framework/Versions/Current/Frameworks/AE.framework/Versions/Current/Support/AEServer /System/Library/Frameworks/InstantMessage.framework/iChatAgent.app /System/Library/Frameworks/SecurityFoundation.framework/Resources/kcSync.app /System/Library/PreferencePanes/Mac.prefPane +/System/Library/PrivateFrameworks/Admin.framework/Resources/writeconfig /System/Library/PrivateFrameworks/Admin.framework/Versions/A/Resources/writeconfig -/System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport -/System/Library/PrivateFrameworks/Apple80211.framework/Resources/AirPortNetworkPrefs.bundle/Contents/Resources/AirPortCfgTool +/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport +/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/AirPortNetworkPrefs.bundle/Contents/Resources/AirPortCfgTool /System/Library/PrivateFrameworks/DotmacLegacy.framework/Resources/dotMacTranslator +/System/Library/PrivateFrameworks/DotmacLegacy.framework/Versions/A/Resources/dotMacTranslator +/System/Library/PrivateFrameworks/DotmacLegacy.framework/Versions/Current/Resources/dotMacTranslator /System/Library/PrivateFrameworks/InstantMessage.framework/iChatAgent.app /System/Library/PrivateFrameworks/DMNotification.framework/Resources/dmnotifyd +/System/Library/PrivateFrameworks/DMNotification.framework/Versions/A/Resources/dmnotifyd +/System/Library/PrivateFrameworks/DMNotification.framework/Versions/Current/Resources/dmnotifyd /System/Library/ScriptingAdditions/Keychain Scripting.app /sbin/mount_smbfs /sbin/mount_webdav diff --git a/securityd.xcode/project.pbxproj b/securityd.xcode/project.pbxproj index d5ada2f..d4df89e 100644 --- a/securityd.xcode/project.pbxproj +++ b/securityd.xcode/project.pbxproj @@ -838,7 +838,7 @@ ); buildSettings = { BUILD_VARIANTS = "normal debug"; - CURRENT_PROJECT_VERSION = 61; + CURRENT_PROJECT_VERSION = 67; 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"; diff --git a/src/kcdatabase.cpp b/src/kcdatabase.cpp index e41c3d7..4f1b490 100644 --- a/src/kcdatabase.cpp +++ b/src/kcdatabase.cpp @@ -540,7 +540,11 @@ bool KeychainDatabase::decode() // // Given an AccessCredentials for this database, wring out the existing primary // database secret by whatever means necessary. -// On entry, caller must hold the database common lock. It will be held throughout. +// On entry, caller must hold the database common lock. It will be held +// throughout except when user interaction is required. User interaction +// requires relinquishing the database common lock and taking the UI lock. On +// return from user interaction, the UI lock is relinquished and the database +// common lock must be reacquired. At no time may the caller hold both locks. // On exit, the crypto core has its master secret. If things go wrong, // we will throw a suitable exception. Note that encountering any malformed // credential sample will throw, but this is not guaranteed -- don't assume @@ -564,13 +568,15 @@ void KeychainDatabase::establishOldSecrets(const AccessCredentials *creds) switch (sample.type()) { // interactively prompt the user - no additional data case CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT: - { + { secdebug("KCdb", "%p attempting interactive unlock", this); + // Holding DB common lock during UI will deadlock securityd + StSyncLock uisync(common().uiLock(), common()); QueryUnlock query(*this); query.inferHints(Server::process()); if (query() == SecurityAgent::noReason) return; - } + } break; // try to use an explicitly given passphrase - Data:passphrase case CSSM_SAMPLE_TYPE_PASSWORD: @@ -617,6 +623,7 @@ void KeychainDatabase::establishOldSecrets(const AccessCredentials *creds) } // attempt interactive unlock + StSyncLock uisync(common().uiLock(), common()); QueryUnlock query(*this); query.inferHints(Server::process()); if (query() == SecurityAgent::noReason) @@ -643,6 +650,7 @@ void KeychainDatabase::establishNewSecrets(const AccessCredentials *creds, Secur case CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT: { secdebug("KCdb", "%p specified interactive passphrase", this); + StSyncLock uisync(common().uiLock(), common()); QueryNewPassphrase query(*this, reason); query.inferHints(Server::process()); CssmAutoData passphrase(Allocator::standard(Allocator::sensitive)); @@ -682,6 +690,7 @@ void KeychainDatabase::establishNewSecrets(const AccessCredentials *creds, Secur } } else { // default action -- interactive (only) + StSyncLock uisync(common().uiLock(), common()); QueryNewPassphrase query(*this, reason); query.inferHints(Server::process()); CssmAutoData passphrase(Allocator::standard(Allocator::sensitive)); @@ -920,7 +929,7 @@ void KeychainDatabase::dumpNode() // DbCommon basic features // KeychainDbCommon::KeychainDbCommon(Session &ssn, const DbIdentifier &id) - : DbCommon(ssn), sequence(0), version(1), mIdentifier(id), + : LocalDbCommon(ssn), sequence(0), version(1), mIdentifier(id), mIsLocked(true), mValidParams(false) { // match existing DbGlobal or create a new one diff --git a/src/kcdatabase.h b/src/kcdatabase.h index 61f147b..69714aa 100644 --- a/src/kcdatabase.h +++ b/src/kcdatabase.h @@ -89,7 +89,7 @@ private: // // KeychainDatabase DbCommons // -class KeychainDbCommon : public DbCommon, +class KeychainDbCommon : public LocalDbCommon, public DatabaseCryptoCore, public MachServer::Timer { public: KeychainDbCommon(Session &ssn, const DbIdentifier &id); diff --git a/src/localdatabase.h b/src/localdatabase.h index 7e1f53f..6c604f3 100644 --- a/src/localdatabase.h +++ b/src/localdatabase.h @@ -35,6 +35,17 @@ class LocalKey; +class LocalDbCommon : public DbCommon { +public: + LocalDbCommon(Session &ssn) : DbCommon(ssn) { } + + Mutex &uiLock() { return mUILock; } + +private: + // Contract: callers shall not simultaneously hold mUILock and the + // DbCommon lock. StSyncLock coordinates them to uphold the contract. + Mutex mUILock; // serializes user interaction +}; // // A Database object represents an Apple CSP/DL open database (DL/DB) object. diff --git a/src/pcscmonitor.cpp b/src/pcscmonitor.cpp index 47a0eef..9fe6a13 100644 --- a/src/pcscmonitor.cpp +++ b/src/pcscmonitor.cpp @@ -151,7 +151,7 @@ void PCSCMonitor::launchPcscd() Child::fork(); // if pcscd doesn't report a reader found soon, we'll kill it off - server.setTimer(this, PCSCD_IDLE_SHUTDOWN); + scheduleTimer(true); } @@ -252,7 +252,7 @@ void PCSCMonitor::scheduleTimer(bool enable) // // Perform the initial PCSC subsystem initialization. // This runs (shortly) after securityd is fully functional and the -// server loop as started. +// server loop has started. // void PCSCMonitor::initialSetup() { @@ -285,6 +285,12 @@ void PCSCMonitor::initialSetup() IOKit::DeviceMatch pcCardSelector("IOPCCard16Device"); mIOKitNotifier.add(usbSelector, *this); // this will scan existing USB devices mIOKitNotifier.add(pcCardSelector, *this); // ditto for PC Card devices + if (mServiceLevel == aggressive) { + // catch custom non-composite USB devices - they don't have IOServices attached + IOKit::DeviceMatch customUsbSelector(::IOServiceMatching("IOUSBDevice")); + mIOKitNotifier.add(customUsbSelector, *this); // ditto for custom USB devices + } + break; } // we are NOT scanning for PCSC devices here. Pcscd will send us a notification when it's up @@ -345,22 +351,24 @@ PCSCMonitor::DeviceSupport PCSCMonitor::deviceSupport(const IOKit::Device &dev) { try { secdebug("scsel", "%s", dev.path().c_str()); - CFRef cfClass(dev.property("bInterfaceClass")); - if (!cfClass) { - secdebug("scsel", " device without device class (ignored)"); - return impossible; - } - switch (IFDEBUG(uint32 clas =) cfNumber(cfClass)) { - case kUSBChipSmartCardInterfaceClass: // CCID smartcard reader - go - secdebug("scsel", " CCID smartcard reader recognized"); - return definite; - case kUSBVendorSpecificInterfaceClass: - secdebug("scsel", " Vendor-specific device - possible match"); - return possible; - default: - secdebug("scsel", " class %ld is not a smartcard device", clas); - return impossible; - } + if (CFRef cfInterface = dev.property("bInterfaceClass")) + switch (IFDEBUG(uint32 clas =) cfNumber(cfInterface)) { + case kUSBChipSmartCardInterfaceClass: // CCID smartcard reader - go + secdebug("scsel", " CCID smartcard reader recognized"); + return definite; + case kUSBVendorSpecificInterfaceClass: + secdebug("scsel", " Vendor-specific interface - possible match"); + return possible; + default: + secdebug("scsel", " interface class %ld is not a smartcard device", clas); + return impossible; + } + if (CFRef cfDevice = dev.property("bDeviceClass")) + if (cfNumber(cfDevice) == kUSBVendorSpecificClass) { + secdebug("scsel", " Vendor-specific device - possible match"); + return possible; + } + return impossible; } catch (...) { secdebug("scsel", " exception while examining device - ignoring it"); return impossible; diff --git a/src/pcscmonitor.h b/src/pcscmonitor.h index 6ef6328..4163ceb 100644 --- a/src/pcscmonitor.h +++ b/src/pcscmonitor.h @@ -56,9 +56,9 @@ public: enum ServiceLevel { forcedOff, // no service under any circumstances conservative, // launch pcscd for certain smartcard devices - aggressive, // launch pcscd for possible smartcard devices + aggressive, // launch pcscd for possible (and certain) smartcard devices forcedOn, // keep pcscd running at all times - externalDaemon // use externally launched daemon + externalDaemon // use externally launched daemon if present (do not manage pcscd) }; PCSCMonitor(Server &server, TokenCache &cache, ServiceLevel level = conservative); -- 2.45.2