/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
);
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";
//
// 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
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<Mutex, Mutex> 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:
}
// attempt interactive unlock
+ StSyncLock<Mutex, Mutex> uisync(common().uiLock(), common());
QueryUnlock query(*this);
query.inferHints(Server::process());
if (query() == SecurityAgent::noReason)
case CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT:
{
secdebug("KCdb", "%p specified interactive passphrase", this);
+ StSyncLock<Mutex, Mutex> uisync(common().uiLock(), common());
QueryNewPassphrase query(*this, reason);
query.inferHints(Server::process());
CssmAutoData passphrase(Allocator::standard(Allocator::sensitive));
}
} else {
// default action -- interactive (only)
+ StSyncLock<Mutex, Mutex> uisync(common().uiLock(), common());
QueryNewPassphrase query(*this, reason);
query.inferHints(Server::process());
CssmAutoData passphrase(Allocator::standard(Allocator::sensitive));
// 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
//
// KeychainDatabase DbCommons
//
-class KeychainDbCommon : public DbCommon,
+class KeychainDbCommon : public LocalDbCommon,
public DatabaseCryptoCore, public MachServer::Timer {
public:
KeychainDbCommon(Session &ssn, const DbIdentifier &id);
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.
Child::fork();
// if pcscd doesn't report a reader found soon, we'll kill it off
- server.setTimer(this, PCSCD_IDLE_SHUTDOWN);
+ scheduleTimer(true);
}
//
// 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()
{
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
{
try {
secdebug("scsel", "%s", dev.path().c_str());
- CFRef<CFNumberRef> cfClass(dev.property<CFNumberRef>("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<CFNumberRef> cfInterface = dev.property<CFNumberRef>("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<CFNumberRef> cfDevice = dev.property<CFNumberRef>("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;
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);