From: Apple Date: Thu, 13 May 2004 21:46:53 +0000 (+0000) Subject: Security-176.tar.gz X-Git-Tag: mac-os-x-1034^0 X-Git-Url: https://git.saurik.com/apple/security.git/commitdiff_plain/2b1671fa2b47dc427293e35029f0c21900e0bd45 Security-176.tar.gz --- diff --git a/AppleCSP/AppleCSP/.cvsignore b/AppleCSP/AppleCSP/.cvsignore deleted file mode 100644 index abaf517e..00000000 --- a/AppleCSP/AppleCSP/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -rotty?Data diff --git a/AppleDL/.cvsignore b/AppleDL/.cvsignore deleted file mode 100644 index 7b6b8240..00000000 --- a/AppleDL/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -AppleCSPDL?Data diff --git a/AppleX509CL/.cvsignore b/AppleX509CL/.cvsignore deleted file mode 100644 index 8be42d6a..00000000 --- a/AppleX509CL/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -PBUserInfo -AppleX509CL?Data diff --git a/Keychain/CCallbackMgr.cp b/Keychain/CCallbackMgr.cp index 5fc770bd..6e549b35 100644 --- a/Keychain/CCallbackMgr.cp +++ b/Keychain/CCallbackMgr.cp @@ -130,7 +130,8 @@ void CCallbackMgr::RemoveCallback(SecKeychainCallback inCallbackFunction) MacOSError::throwMe(errSecInvalidCallback); } -void CCallbackMgr::AlertClients(SecKeychainEvent inEvent, +void CCallbackMgr::AlertClients(const list &eventCallbacks, + SecKeychainEvent inEvent, pid_t inPid, const Keychain &inKeychain, const Item &inItem) @@ -138,15 +139,10 @@ void CCallbackMgr::AlertClients(SecKeychainEvent inEvent, secdebug("kcnotify", "dispatch event %ld pid %d keychain %p item %p", inEvent, inPid, &inKeychain, !!inItem ? &*inItem : NULL); - // Deal with events that we care about ourselves first. - if (inEvent == kSecDeleteEvent && inKeychain.get() && inItem.get()) - inKeychain->didDeleteItem(inItem.get()); - // Iterate through callbacks, looking for those registered for inEvent const SecKeychainEventMask theMask = 1U << inEvent; - for ( CallbackInfoListIterator ix = CCallbackMgr::Instance().mEventCallbacks.begin(); - ix != CCallbackMgr::Instance().mEventCallbacks.end(); ++ix ) + for (ConstCallbackInfoListIterator ix = eventCallbacks.begin(); ix != eventCallbacks.end(); ++ix) { if (!(ix->mEventMask & theMask)) continue; @@ -175,40 +171,54 @@ void CCallbackMgr::AlertClients(SecKeychainEvent inEvent, * If it wasn't 'us', we should remove our cached reference to the item that was deleted. * ***********************************************************************************/ -void CCallbackMgr::Event (Listener::Domain domain, Listener::Event whichEvent, NameValueDictionary &dictionary) +void CCallbackMgr::Event(Listener::Domain domain, Listener::Event whichEvent, NameValueDictionary &dictionary) { // Decode from userInfo the event type, 'keychain' CFDict, and 'item' CFDict SecKeychainEvent thisEvent = whichEvent; pid_t thisPid; - const NameValuePair* pidRef = dictionary.FindByName (PID_KEY); + const NameValuePair* pidRef = dictionary.FindByName(PID_KEY); if (pidRef == 0) { thisPid = 0; } else { - thisPid = *reinterpret_cast(pidRef->Value ().data ()); + thisPid = *reinterpret_cast(pidRef->Value().data()); } Keychain thisKeychain = 0; - - // make sure we have a database identifier - if (dictionary.FindByName (SSUID_KEY) != 0) - { - DLDbIdentifier dbid = NameValueDictionary::MakeDLDbIdentifierFromNameValueDictionary (dictionary); - thisKeychain = globals().storageManager.keychain (dbid); - } - - const NameValuePair* item = dictionary.FindByName (ITEM_KEY); Item thisItem; + list eventCallbacks; - if (item && thisKeychain) - { - PrimaryKey pk(item->Value ()); - thisItem = thisKeychain->item(pk); - } + { + // Lock the global API lock before doing stuff with StorageManager. + StLock _(globals().apiLock); + + // make sure we have a database identifier + if (dictionary.FindByName (SSUID_KEY) != 0) + { + DLDbIdentifier dbid = NameValueDictionary::MakeDLDbIdentifierFromNameValueDictionary (dictionary); + thisKeychain = globals().storageManager.keychain(dbid); + } + + const NameValuePair* item = dictionary.FindByName(ITEM_KEY); + + if (item && thisKeychain) + { + PrimaryKey pk(item->Value()); + thisItem = thisKeychain->item(pk); + } + + // Deal with events that we care about ourselves first. + if (thisEvent == kSecDeleteEvent && thisKeychain.get() && thisItem.get()) + thisKeychain->didDeleteItem(thisItem.get()); + + eventCallbacks = CCallbackMgr::Instance().mEventCallbacks; + // We can safely release the global API lock now since thisKeychain and thisItem + // are CFRetained and will be until they go out of scope. + } // Notify our process of this event. - CCallbackMgr::AlertClients(thisEvent, thisPid, thisKeychain, thisItem); + CCallbackMgr::AlertClients(eventCallbacks, thisEvent, thisPid, thisKeychain, thisItem); } diff --git a/Keychain/CCallbackMgr.h b/Keychain/CCallbackMgr.h index be58f280..972fd955 100644 --- a/Keychain/CCallbackMgr.h +++ b/Keychain/CCallbackMgr.h @@ -81,8 +81,8 @@ private: void Event (Listener::Domain domain, Listener::Event whichEvent, NameValueDictionary &dictionary); - static void AlertClients( SecKeychainEvent inEvent, pid_t inPid, - const Keychain& inKeychain, const Item &inItem); + static void AlertClients(const list &eventCallbacks, SecKeychainEvent inEvent, pid_t inPid, + const Keychain& inKeychain, const Item &inItem); list mEventCallbacks; static CCallbackMgr* mCCallbackMgr; diff --git a/Keychain/SecCFTypes.cpp b/Keychain/SecCFTypes.cpp index a6a0e378..1d1a342d 100644 --- a/Keychain/SecCFTypes.cpp +++ b/Keychain/SecCFTypes.cpp @@ -58,13 +58,27 @@ SecCFTypes::SecCFTypes() : Policy("SecPolicy"), PolicyCursor("SecPolicySearch"), Trust("SecTrust"), - TrustedApplication("SecTrustedApplication") + TrustedApplication("SecTrustedApplication"), + allocator(CFAllocatorCreate(NULL, &CFClass::allocatorContext)) { } // // CFClass // +CFAllocatorContext CFClass::allocatorContext = +{ + 0, + NULL, + NULL, /* retain */ + NULL, /* release */ + NULL, /* copyDescription */ + allocatorAllocate, /* allocate */ + allocatorReallocate, /* reallocate */ + allocatorDeallocate, /* deallocate */ + allocatorPreferredSize /* preferredSize */ +}; + CFClass::CFClass(const char *name) { // initialize the CFRuntimeClass structure @@ -72,7 +86,7 @@ CFClass::CFClass(const char *name) className = name; init = NULL; copy = NULL; - finalize = finalizeType; + finalize = NULL; equal = equalType; hash = hashType; copyFormattingDesc = copyFormattingDescType; @@ -83,21 +97,6 @@ CFClass::CFClass(const char *name) assert(typeID != _kCFRuntimeNotATypeID); } -void -CFClass::finalizeType(CFTypeRef cf) -{ - /* - * Called on a CFRelease of any Sec object: single thread through - * same lock held by public API calls. This is a recursive lock - * so it's safe to do this for CF objects allocated and released - * within the Sec layer. - */ - StLock _(globals().apiLock); - SecCFObject *obj = SecCFObject::optional(cf); - if (!obj->isNew()) - obj->~SecCFObject(); -} - Boolean CFClass::equalType(CFTypeRef cf1, CFTypeRef cf2) { @@ -122,3 +121,56 @@ CFClass::copyDebugDescType(CFTypeRef cf) { return SecCFObject::optional(cf)->copyDebugDesc(); } + +// +// CFAllocatorContext callbacks. +// +void * +CFClass::allocatorAllocate(CFIndex allocSize, CFOptionFlags hint, void *info) +{ + return malloc(allocSize); +} + +void * +CFClass::allocatorReallocate(void *ptr, CFIndex newsize, CFOptionFlags hint, void *info) +{ + return realloc(ptr, newsize); +} + +void +CFClass::allocatorDeallocate(void *ptr, void *info) +{ + /* + * Called on a CFRelease of any Sec object: single thread through + * same lock held by public API calls. This is a recursive lock + * so it's safe to do this for CF objects allocated and released + * within the Sec layer. + */ + StLock _(globals().apiLock); + CFTypeRef cf = reinterpret_cast(reinterpret_cast(ptr) + sizeof(CFAllocatorRef)); + CFIndex rc = CFGetRetainCount(cf); + if (rc == 1) + { + SecCFObject *obj = SecCFObject::optional(cf); + if (!obj->isNew()) + obj->~SecCFObject(); + free(ptr); + } + else if (rc > 1) + { + // Since CFRelease did nothing other than call CFAllocatorDeallocate() followed + // by a CFRelease() of the allocator we need to counter that here. + CFRetain(CFGetAllocator(cf)); + CFRelease(cf); + } + else + { + // Something bad happened we're screwed + } +} + +CFIndex +CFClass::allocatorPreferredSize(CFIndex size, CFOptionFlags hint, void *info) +{ + return size; +} diff --git a/Keychain/SecCFTypes.h b/Keychain/SecCFTypes.h index a9f62e9d..63873e83 100644 --- a/Keychain/SecCFTypes.h +++ b/Keychain/SecCFTypes.h @@ -36,14 +36,20 @@ public: CFClass(const char *name); private: - static void finalizeType(CFTypeRef cf); static Boolean equalType(CFTypeRef cf1, CFTypeRef cf2); static CFHashCode hashType(CFTypeRef cf); static CFStringRef copyFormattingDescType(CFTypeRef cf, CFDictionaryRef dict); static CFStringRef copyDebugDescType(CFTypeRef cf); + // CFAllocatorContext callbacks. + static void *allocatorAllocate(CFIndex allocSize, CFOptionFlags hint, void *info); + static void *allocatorReallocate(void *ptr, CFIndex newsize, CFOptionFlags hint, void *info); + static void allocatorDeallocate(void *ptr, void *info); + static CFIndex allocatorPreferredSize(CFIndex size, CFOptionFlags hint, void *info); + public: CFTypeID typeID; + static CFAllocatorContext allocatorContext; }; /* Singleton that registers all the CFClass instances with the CFRuntime. @@ -102,6 +108,8 @@ public: CFClass PolicyCursor; CFClass Trust; CFClass TrustedApplication; + + CFAllocatorRef allocator; }; extern SecCFTypes &gTypes(); diff --git a/Keychain/SecRuntime.cpp b/Keychain/SecRuntime.cpp index a8c01a92..8033967d 100644 --- a/Keychain/SecRuntime.cpp +++ b/Keychain/SecRuntime.cpp @@ -52,7 +52,7 @@ SecCFObject::required(CFTypeRef cfTypeRef, OSStatus error) void * SecCFObject::allocate(size_t size, CFTypeID typeID) throw(std::bad_alloc) { - void *p = const_cast(_CFRuntimeCreateInstance(NULL, typeID, + void *p = const_cast(_CFRuntimeCreateInstance(gTypes().allocator, typeID, size + kAlignedRuntimeSize - sizeof(CFRuntimeBase), NULL)); if (p == NULL) throw std::bad_alloc(); diff --git a/Keychain/iToolsTrustedApps.plist b/Keychain/iToolsTrustedApps.plist index d3c5c8e3..57d04d6f 100644 --- a/Keychain/iToolsTrustedApps.plist +++ b/Keychain/iToolsTrustedApps.plist @@ -3,10 +3,16 @@ /Applications/Mail.app + /Applications/System Preferences.app + /Applications/iCal.app /Applications/iChat.app + /Applications/iMovie.app + /Applications/iPhoto.app /Applications/iSync.app - /Applications/System Preferences.app - /System/Library/PrivateFrameworks/InstantMessage.framework/iChatAgent.app + /Applications/iTunes.app + /System/Library/CoreServices/Finder.app + /System/Library/CoreServices/MirrorAgent.app /System/Library/CoreServices/SyncServer.app + /System/Library/PrivateFrameworks/InstantMessage.framework/iChatAgent.app diff --git a/SecureTransport/sslTransport.cpp b/SecureTransport/sslTransport.cpp index 91cf61d5..1b352e43 100644 --- a/SecureTransport/sslTransport.cpp +++ b/SecureTransport/sslTransport.cpp @@ -49,7 +49,7 @@ static void inline sslIoTrace( UInt32 moved, OSStatus stat) { - sslLogRecordIo("===%s: req %4lu moved %4lu status %ld\n", + sslLogRecordIo("===%s: req %4lu moved %4lu status %ld", op, req, moved, stat); } #else @@ -72,6 +72,7 @@ SSLWrite( SSLRecord rec; UInt32 dataLen, processed; + sslLogRecordIo("SSLWrite top"); if((ctx == NULL) || (bytesWritten == NULL)) { return paramErr; } @@ -159,12 +160,14 @@ SSLRead ( UInt32 bufSize, remaining, count; SSLRecord rec; + sslLogRecordIo("SSLRead top"); if((ctx == NULL) || (processed == NULL)) { return paramErr; } bufSize = dataLength; *processed = 0; /* Initialize in case we return with errSSLWouldBlock */ +readRetry: /* first handle cases in which we know we're finished */ switch(ctx->state) { case SSL_HdskStateGracefulClose: @@ -276,6 +279,11 @@ SSLRead ( err = noErr; exit: + /* test for renegotiate: loop until something happens */ + if((err == noErr) && (*processed == 0)) { + sslLogNegotiateDebug("SSLRead recursion"); + goto readRetry; + } /* shut down on serious errors */ switch(err) { case noErr: @@ -496,6 +504,7 @@ SSLClose(SSLContext *ctx) { OSStatus err = noErr; + sslHdskStateDebug("SSLClose"); if(ctx == NULL) { return paramErr; } diff --git a/Security.pbproj/.cvsignore b/Security.pbproj/.cvsignore deleted file mode 100644 index ae0520be..00000000 --- a/Security.pbproj/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -michael.pbxuser -perry.pbxuser diff --git a/Security.pbproj/project.pbxproj b/Security.pbproj/project.pbxproj index 3f4a0055..fb48422d 100644 --- a/Security.pbproj/project.pbxproj +++ b/Security.pbproj/project.pbxproj @@ -123,7 +123,7 @@ ); buildSettings = { DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 164.1; + DYLIB_CURRENT_VERSION = 176; FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\""; HEADER_SEARCH_PATHS = "\"$(BUILT_PRODUCTS_DIR)/BSafe.framework/Headers\" \"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks/BSafe.framework/Headers\" \"$(SRCROOT)/AppleCSP\" \"$(SRCROOT)/AppleCSP/open_ssl\""; LIBRARY_STYLE = STATIC; @@ -419,7 +419,7 @@ ); buildSettings = { DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 164.1; + DYLIB_CURRENT_VERSION = 176; LIBRARY_STYLE = STATIC; OPTIMIZATION_CFLAGS = "-Os -DNDEBUG"; OTHER_CFLAGS = "-DVDADER_RULES"; @@ -497,7 +497,7 @@ ); buildSettings = { DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 164.1; + DYLIB_CURRENT_VERSION = 176; LIBRARY_STYLE = STATIC; OPTIMIZATION_CFLAGS = "-Os -DNDEBUG"; OTHER_CFLAGS = ""; @@ -557,7 +557,7 @@ ); buildSettings = { DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 164.1; + DYLIB_CURRENT_VERSION = 176; FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\""; LIBRARY_STYLE = STATIC; OPTIMIZATION_CFLAGS = "-Os -DNDEBUG"; @@ -650,7 +650,7 @@ ); buildSettings = { DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 164.1; + DYLIB_CURRENT_VERSION = 176; FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\""; LIBRARY_STYLE = STATIC; OPTIMIZATION_CFLAGS = "-Os -DNDEBUG"; @@ -2698,6 +2698,7 @@ }; 01FA8039FFF2B54C11CD283A = { children = ( + B6F3F06205E5C8DD003E48D8, 014259A8001645E911CD296C, 01FA804DFFF2B54C11CD283A, 01FA804EFFF2B54C11CD283A, @@ -6428,13 +6429,13 @@ 01FA8900FFF2BC5611CD283A, ); buildSettings = { - CURRENT_PROJECT_VERSION = 164.1; + CURRENT_PROJECT_VERSION = 176; HEADER_SEARCH_PATHS = "\"$(BUILT_PRODUCTS_DIR)/derived_src\""; INSTALL_PATH = "$(SYSTEM_CORE_SERVICES_DIR)"; LIBRARY_SEARCH_PATHS = ""; OPTIMIZATION_CFLAGS = "-Os -DNDEBUG"; OTHER_CFLAGS = "-DDatabase=XDatabase"; - OTHER_LDFLAGS = "-twolevel_namespace -lSecurityAgentClient"; + OTHER_LDFLAGS = "-twolevel_namespace -lSecurityAgentClient -lbsm"; OTHER_REZFLAGS = ""; PRODUCT_NAME = SecurityServer; REZ_EXECUTABLE = YES; @@ -6481,6 +6482,7 @@ 40ACEF4D0462F6EC0035B857, 40ACEF510462F6FF0035B857, C2C11915047187E800CA2E77, + B6F3F06605E5C926003E48D8, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -6513,6 +6515,7 @@ 40ACEF4C0462F6EC0035B857, 40ACEF500462F6FF0035B857, C2C11914047187E800CA2E77, + B6F3F06505E5C926003E48D8, ); isa = PBXSourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -6554,7 +6557,7 @@ 01FA890AFFF2BCA811CD283A, ); buildSettings = { - CURRENT_PROJECT_VERSION = 164.1; + CURRENT_PROJECT_VERSION = 176; INSTALL_PATH = "$(SYSTEM_CORE_SERVICES_DIR)"; LIBRARY_SEARCH_PATHS = ""; OPTIMIZATION_CFLAGS = "-Os -DNDEBUG"; @@ -6927,7 +6930,7 @@ ); buildSettings = { DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 164.1; + DYLIB_CURRENT_VERSION = 176; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = STATIC; OPTIMIZATION_CFLAGS = "-Os -DNDEBUG"; @@ -8856,9 +8859,9 @@ F5DDE3AE00B3358F01CD283A, ); buildSettings = { - CURRENT_PROJECT_VERSION = 164.1; + CURRENT_PROJECT_VERSION = 176; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 164.1; + DYLIB_CURRENT_VERSION = 176; FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\""; FRAMEWORK_VERSION = A; HEADER_SEARCH_PATHS = "\"$(SRCROOT)\" \"$(BUILT_PRODUCTS_DIR)/derived_src\""; @@ -8906,11 +8909,11 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.2 + 2.3 CFBundleSignature ???? CFBundleVersion - 164.1 + 176 "; @@ -9983,7 +9986,7 @@ ); buildSettings = { DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 164.1; + DYLIB_CURRENT_VERSION = 176; HEADER_SEARCH_PATHS = "\"$(BUILT_PRODUCTS_DIR)/include\""; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = STATIC; @@ -11842,7 +11845,7 @@ 325EAA2800D6B08805CD296C, ); buildSettings = { - CURRENT_PROJECT_VERSION = 164.1; + CURRENT_PROJECT_VERSION = 176; LIBRARY_SEARCH_PATHS = ""; OPTIMIZATION_CFLAGS = "-Os -DNDEBUG"; OTHER_CFLAGS = ""; @@ -11882,11 +11885,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 2.2 + 2.3 CFBundleSignature ???? CFBundleVersion - 164.1 + 176 "; @@ -12420,7 +12423,7 @@ 3290382100D6BA5905CD296C, ); buildSettings = { - CURRENT_PROJECT_VERSION = 164.1; + CURRENT_PROJECT_VERSION = 176; LIBRARY_SEARCH_PATHS = ""; OPTIMIZATION_CFLAGS = "-Os -DNDEBUG"; OTHER_CFLAGS = ""; @@ -12461,11 +12464,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 2.2 + 2.3 CFBundleSignature ???? CFBundleVersion - 164.1 + 176 "; @@ -12529,7 +12532,7 @@ 3290382700D6BA5905CD296C, ); buildSettings = { - CURRENT_PROJECT_VERSION = 164.1; + CURRENT_PROJECT_VERSION = 176; LIBRARY_SEARCH_PATHS = ""; OPTIMIZATION_CFLAGS = "-Os -DNDEBUG"; OTHER_CFLAGS = ""; @@ -12570,11 +12573,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 2.2 + 2.3 CFBundleSignature ???? CFBundleVersion - 164.1 + 176 "; @@ -12626,7 +12629,7 @@ 3290382D00D6BA5905CD296C, ); buildSettings = { - CURRENT_PROJECT_VERSION = 164.1; + CURRENT_PROJECT_VERSION = 176; LIBRARY_SEARCH_PATHS = ""; OPTIMIZATION_CFLAGS = "-Os -DNDEBUG"; OTHER_CFLAGS = ""; @@ -12667,11 +12670,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 2.2 + 2.3 CFBundleSignature ???? CFBundleVersion - 164.1 + 176 "; @@ -12723,7 +12726,7 @@ 3290383300D6BA5905CD296C, ); buildSettings = { - CURRENT_PROJECT_VERSION = 164.1; + CURRENT_PROJECT_VERSION = 176; LIBRARY_SEARCH_PATHS = ""; OPTIMIZATION_CFLAGS = "-Os -DNDEBUG"; OTHER_LDFLAGS = "-bundle -undefined error"; @@ -12762,11 +12765,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 2.2 + 2.3 CFBundleSignature ???? CFBundleVersion - 164.1 + 176 "; @@ -14967,7 +14970,7 @@ ); buildSettings = { DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 164.1; + DYLIB_CURRENT_VERSION = 176; INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = STATIC; OTHER_CFLAGS = ""; @@ -16199,6 +16202,49 @@ //9D2 //9D3 //9D4 +//B60 +//B61 +//B62 +//B63 +//B64 + B6F3F06205E5C8DD003E48D8 = { + children = ( + B6F3F06305E5C926003E48D8, + B6F3F06405E5C926003E48D8, + ); + isa = PBXGroup; + name = "Common Criteria"; + refType = 4; + }; + B6F3F06305E5C926003E48D8 = { + fileEncoding = 30; + isa = PBXFileReference; + path = ccaudit.cpp; + refType = 4; + }; + B6F3F06405E5C926003E48D8 = { + fileEncoding = 30; + isa = PBXFileReference; + path = ccaudit.h; + refType = 4; + }; + B6F3F06505E5C926003E48D8 = { + fileRef = B6F3F06305E5C926003E48D8; + isa = PBXBuildFile; + settings = { + }; + }; + B6F3F06605E5C926003E48D8 = { + fileRef = B6F3F06405E5C926003E48D8; + isa = PBXBuildFile; + settings = { + }; + }; +//B60 +//B61 +//B62 +//B63 +//B64 //BD0 //BD1 //BD2 diff --git a/SecurityServer/Authorization/AuthorizationEngine.cpp b/SecurityServer/Authorization/AuthorizationEngine.cpp index 1412ac8b..210a4423 100644 --- a/SecurityServer/Authorization/AuthorizationEngine.cpp +++ b/SecurityServer/Authorization/AuthorizationEngine.cpp @@ -49,7 +49,6 @@ namespace Authorization { - // // Errors to be thrown // diff --git a/SecurityServer/Authorization/AuthorizationEngine.h b/SecurityServer/Authorization/AuthorizationEngine.h index dc81591c..f4ce6a06 100644 --- a/SecurityServer/Authorization/AuthorizationEngine.h +++ b/SecurityServer/Authorization/AuthorizationEngine.h @@ -40,7 +40,6 @@ #include #include - class AuthorizationToken; using Authorization::AuthorizationDBPlist; diff --git a/SecurityServer/Authorization/AuthorizationRule.cpp b/SecurityServer/Authorization/AuthorizationRule.cpp index 6592038a..a8d4b8f8 100644 --- a/SecurityServer/Authorization/AuthorizationRule.cpp +++ b/SecurityServer/Authorization/AuthorizationRule.cpp @@ -20,6 +20,9 @@ #include #include +#include +#include +#include "ccaudit.h" // // Rule class @@ -42,6 +45,7 @@ CFStringRef RuleImpl::kRuleUserID = CFSTR(kAuthorizationRuleClassUser); CFStringRef RuleImpl::kRuleDelegateID = CFSTR(kAuthorizationRightRule); CFStringRef RuleImpl::kRuleMechanismsID = CFSTR(kAuthorizationRuleClassMechanisms); + string RuleImpl::Attribute::getString(CFDictionaryRef config, CFStringRef key, bool required = false, char *defaultValue = NULL) { @@ -434,6 +438,8 @@ RuleImpl::evaluateMechanism(const AuthItemRef &inRight, const AuthItemSet &envir AuthItemSet context = auth.infoSet(); AuthItemSet hints = environment; + CommonCriteria::AuditRecord auditrec(auth.creatorAuditToken()); + AuthorizationResult result = kAuthorizationResultAllow; vector::const_iterator currentMechanism = mEvalDef.begin(); @@ -489,11 +495,18 @@ RuleImpl::evaluateMechanism(const AuthItemRef &inRight, const AuthItemSet &envir Credential newCredential(username, password, true); // create a new shared credential if (newCredential->isValid()) + { Syslog::info("authinternal authenticated user %s (uid %lu) for right %s.", newCredential->username().c_str(), newCredential->uid(), inRight->name()); + auditrec.submit(AUE_ssauthint, CommonCriteria::errNone, inRight->name()); + } else + { // we can't be sure that the user actually exists so inhibit logging of uid Syslog::error("authinternal failed to authenticate user %s for right %s.", newCredential->username().c_str(), inRight->name()); - + + auditrec.submit(AUE_ssauthint, CommonCriteria::errInvalidCredential, inRight->name()); + } + if (newCredential->isValid()) { outCredentials.clear(); // only keep last one @@ -614,17 +627,26 @@ RuleImpl::evaluateAuthorization(const AuthItemRef &inRight, const Rule &inRule, // fetch context and construct a credential to be tested AuthItemSet inContext = auth.infoSet(); CredentialSet newCredentials = makeCredentials(inContext); + // clear context after extracting credentials + auth.clearInfoSet(); for (CredentialSet::const_iterator it = newCredentials.begin(); it != newCredentials.end(); ++it) { const Credential& newCredential = *it; + CommonCriteria::AuditRecord auditrec(auth.creatorAuditToken()); // @@@ we log the uid a process was running under when it created the authref, which is misleading in the case of loginwindow if (newCredential->isValid()) + { Syslog::info("uid %lu succeeded authenticating as user %s (uid %lu) for right %s.", auth.creatorUid(), newCredential->username().c_str(), newCredential->uid(), inRight->name()); + auditrec.submit(AUE_ssauthorize, CommonCriteria::errNone, inRight->name()); + } else + { // we can't be sure that the user actually exists so inhibit logging of uid Syslog::error("uid %lu failed to authenticate as user %s for right %s.", auth.creatorUid(), newCredential->username().c_str(), inRight->name()); + auditrec.submit(AUE_ssauthorize, CommonCriteria::errInvalidCredential, inRight->name()); + } if (!newCredential->isValid()) { @@ -639,12 +661,18 @@ RuleImpl::evaluateAuthorization(const AuthItemRef &inRight, const Rule &inRule, { // whack an equivalent credential, so it gets updated to a later achieved credential which must have been more stringent credentials.erase(newCredential); credentials.insert(newCredential); + // use valid credential to set context info + auth.setCredentialInfo(newCredential); secdebug("SSevalMech", "added valid credential for user %s", newCredential->username().c_str()); status = errAuthorizationSuccess; break; } else + { reason = SecurityAgent::userNotInGroup; //unacceptableUser; // userNotInGroup + // don't audit: we denied on the basis of something + // other than a bad user or password + } } if (status == errAuthorizationSuccess) @@ -653,7 +681,10 @@ RuleImpl::evaluateAuthorization(const AuthItemRef &inRight, const Rule &inRule, else if ((status == errAuthorizationCanceled) || (status == errAuthorizationInternal)) - break; + { + auth.clearInfoSet(); + break; + } } // If we fell out of the loop because of too many tries, notify user @@ -665,6 +696,7 @@ RuleImpl::evaluateAuthorization(const AuthItemRef &inRight, const Rule &inRule, AuthItemRef triesHint(AGENT_HINT_TRIES, AuthValueOverlay(sizeof(tries), &tries)); environmentToClient.erase(triesHint); environmentToClient.insert(triesHint); // replace evaluateMechanism(inRight, environmentToClient, auth, credentials); + auth.clearInfoSet(); } Process &cltProc = Server::active().connection().process; @@ -1089,6 +1121,9 @@ RuleImpl::evaluateAuthorizationOld(const AuthItemRef &inRight, const Rule &inRul Credential newCredential; // @@@ Keep the default reason the same, so the agent only gets userNotInGroup or invalidPassphrase SecurityAgent::Reason reason = SecurityAgent::userNotInGroup; + + CommonCriteria::AuditRecord auditrec(auth.creatorAuditToken()); + // @@@ Hardcoded 3 tries to avoid infinite loops. for (uint32_t tryCount = 0; tryCount < mTries; ++tryCount) { @@ -1099,7 +1134,10 @@ RuleImpl::evaluateAuthorizationOld(const AuthItemRef &inRight, const Rule &inRul // Now we have successfully obtained a credential we need to make sure it authorizes the requested right if (!newCredential->isValid()) + { reason = SecurityAgent::invalidPassphrase; + auditrec.submit(AUE_ssauthorize, CommonCriteria::errInvalidCredential, inRight->name()); + } else { status = evaluateCredentialForRight(inRight, inRule, environmentToClient, now, newCredential, true); if (status == errAuthorizationSuccess) @@ -1112,14 +1150,23 @@ RuleImpl::evaluateAuthorizationOld(const AuthItemRef &inRight, const Rule &inRul // add credential to authinfo auth.setCredentialInfo(newCredential); + auditrec.submit(AUE_ssauthorize, CommonCriteria::errNone, inRight->name()); return errAuthorizationSuccess; } else if (status != errAuthorizationDenied) + { + if (status == errAuthorizationCanceled) + auditrec.submit(AUE_ssauthorize, CommonCriteria::errUserCanceled, inRight->name()); + // else don't audit--error not due to bad + // username or password return status; + } } reason = SecurityAgent::userNotInGroup; } query.cancel(SecurityAgent::tooManyTries); + + auditrec.submit(AUE_ssauthorize, CommonCriteria::errTooManyTries, inRight->name()); return errAuthorizationDenied; } diff --git a/SecurityServer/Authorization/AuthorizationRule.h b/SecurityServer/Authorization/AuthorizationRule.h index 91aefcf1..a567f099 100644 --- a/SecurityServer/Authorization/AuthorizationRule.h +++ b/SecurityServer/Authorization/AuthorizationRule.h @@ -74,7 +74,6 @@ private: map localizedPrompts() const { return mLocalizedPrompts; } - // parsed attributes private: enum Type diff --git a/SecurityServer/Authorization/authorization.plist b/SecurityServer/Authorization/authorization.plist index c7f9188c..5e22b0ba 100644 --- a/SecurityServer/Authorization/authorization.plist +++ b/SecurityServer/Authorization/authorization.plist @@ -366,6 +366,23 @@ If the proccess that created the AuthorizationRef has uid = 0 this right will au rule appserver-admin + com.apple.desktopservices + + class + user + comment + authorize privileged file operations from the finder + group + admin + mechanisms + + builtin:authenticate + + shared + + timeout + 0 + com.apple.appserver.privilege.user class diff --git a/SecurityServer/SettingsDialog/SecuritySettings.pbproj/.cvsignore b/SecurityServer/SettingsDialog/SecuritySettings.pbproj/.cvsignore deleted file mode 100644 index 0857ac37..00000000 --- a/SecurityServer/SettingsDialog/SecuritySettings.pbproj/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -*.pbxuser diff --git a/SecurityServer/authority.cpp b/SecurityServer/authority.cpp index 60cefe45..533dff60 100644 --- a/SecurityServer/authority.cpp +++ b/SecurityServer/authority.cpp @@ -55,11 +55,13 @@ Authority::~Authority() // // Create an authorization token. // -AuthorizationToken::AuthorizationToken(Session &ssn, const CredentialSet &base, const security_token_t &securityToken) +AuthorizationToken::AuthorizationToken(Session &ssn, const CredentialSet &base, const audit_token_t &auditToken) : session(ssn), mBaseCreds(base), mTransferCount(INT_MAX), - mCreatorUid(securityToken.val[0]), + mCreatorUid(auditToken.val[1]), + mCreatorGid(auditToken.val[2]), mCreatorCode(Server::connection().process.clientCode()), - mCreatorPid(Server::connection().process.pid()) + mCreatorPid(Server::connection().process.pid()), + mCreatorAuditToken(auditToken) { // generate our (random) handle Server::active().random(mHandle); @@ -257,3 +259,11 @@ AuthorizationToken::setCredentialInfo(const Credential &inCred) setInfoSet(dstInfoSet); } +void +AuthorizationToken::clearInfoSet() +{ + AuthItemSet dstInfoSet; + secdebug("SSauth", "Authorization %p clearing context", this); + setInfoSet(dstInfoSet); +} + diff --git a/SecurityServer/authority.h b/SecurityServer/authority.h index 6882a47d..80a940e0 100644 --- a/SecurityServer/authority.h +++ b/SecurityServer/authority.h @@ -35,7 +35,7 @@ class Session; class AuthorizationToken { public: - AuthorizationToken(Session &ssn, const CredentialSet &base, const security_token_t &securityToken); + AuthorizationToken(Session &ssn, const CredentialSet &base, const audit_token_t &auditToken); ~AuthorizationToken(); Session &session; @@ -60,12 +60,16 @@ public: bool mayInternalize(Process &proc, bool countIt = true); uid_t creatorUid() const { return mCreatorUid; } + uid_t creatorGid() const { return mCreatorGid; } CodeSigning::OSXCode *creatorCode() const { return mCreatorCode; } pid_t creatorPid() const { return mCreatorPid; } + audit_token_t creatorAuditToken() const {return mCreatorAuditToken; } + AuthItemSet infoSet(AuthorizationString tag = NULL); void setInfoSet(AuthItemSet &newInfoSet); void setCredentialInfo(const Credential &inCred); + void clearInfoSet(); public: static AuthorizationToken &find(const AuthorizationBlob &blob); @@ -93,9 +97,12 @@ private: ProcessSet mUsingProcesses; // set of process objects using this token uid_t mCreatorUid; // Uid of proccess that created this authorization + gid_t mCreatorGid; // Gid of proccess that created this authorization RefPointer mCreatorCode; // code id of creator pid_t mCreatorPid; // Pid of processs that created this authorization + audit_token_t mCreatorAuditToken; // Audit token of the process that created this authorization + AuthItemSet mInfoSet; // Side band info gathered from evaluations in this session private: diff --git a/SecurityServer/server.cpp b/SecurityServer/server.cpp index 35914b5f..a26998bb 100644 --- a/SecurityServer/server.cpp +++ b/SecurityServer/server.cpp @@ -25,10 +25,15 @@ #include "notifications.h" #include "ucsp.h" #include +#include +#include +#include +#include +#include +#include "ccaudit.h" using namespace MachPlusPlus; - // // Construct the server object // @@ -40,6 +45,9 @@ Server::Server(Authority &authority, CodeSignatures &signatures, const char *boo mAuthority(authority), mCodeSignatures(signatures) { + + initAudit(); + // engage the subsidiary port handler for sleep notifications add(sleepWatcher); } @@ -112,7 +120,7 @@ void Server::run() { MachServer::run(0x10000, MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0) | - MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_SENDER)); + MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT)); } @@ -157,8 +165,11 @@ boolean_t Server::handle(mach_msg_header_t *in, mach_msg_header_t *out) // Everything at and below that level is constructed. This is straight-forward except // in the case of session re-initialization (see below). // +// audit_token_t.val[1] is the EUID, audit_token_t.val[2] is the EGID. +// void Server::setupConnection(ConnectLevel type, Port servicePort, Port replyPort, Port taskPort, - const security_token_t &securityToken, const ClientSetupInfo *info, const char *identity) + const audit_token_t &auditToken, + const ClientSetupInfo *info, const char *identity) { // first, make or find the process based on task port StLock _(lock); @@ -180,7 +191,7 @@ void Server::setupConnection(ConnectLevel type, Port servicePort, Port replyPort CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR); assert(info && identity); proc = new Process(servicePort, taskPort, info, identity, - securityToken.val[0], securityToken.val[1]); + auditToken.val[1], auditToken.val[2]); notifyIfDead(taskPort); } @@ -265,6 +276,17 @@ void Server::SleepWatcher::systemWillSleep() Session::lockAllDatabases(true); } +void Server::initAudit(void) +{ + secdebug("SS", "initializing Common Criteria auditing"); + mAudit.auditId(geteuid()); + // Set the class mask so only the audit records we submit are written. + mAudit.eventMask().set(AUE_NULL, AUE_NULL); + mAudit.terminalId().set(); + // XXX If we use SS session IDs instead, get the RootSession ID + mAudit.sessionId(getpid()); + mAudit.registerSession(); +} // // Return the primary Cryptographic Service Provider. diff --git a/SecurityServer/server.h b/SecurityServer/server.h index 3da8b93c..38ff0628 100644 --- a/SecurityServer/server.h +++ b/SecurityServer/server.h @@ -36,6 +36,7 @@ #include "xdatabase.h" #include "authority.h" #include +#include "ccaudit.h" #define EQUIVALENCEDBPATH "/var/db/CodeEquivalenceDatabase" @@ -81,8 +82,8 @@ public: connectNewThread }; void setupConnection(ConnectLevel type, Port servicePort, Port replyPort, Port taskPort, - const security_token_t &securityToken, - const ClientSetupInfo *info = NULL, const char *executablePath = NULL); + const audit_token_t &auditToken, + const ClientSetupInfo *info = NULL, const char *executablePath = NULL); void endConnection(Port replyPort); @@ -103,7 +104,9 @@ private: void systemWillSleep(); }; SleepWatcher sleepWatcher; - + + void initAudit(void); + private: Mutex lock; // master lock @@ -131,6 +134,9 @@ private: Authority &mAuthority; CodeSignatures &mCodeSignatures; + + // Per-process audit initialization. + CommonCriteria::AuditSession mAudit; }; #endif //_H_SERVER diff --git a/SecurityServer/session.cpp b/SecurityServer/session.cpp index 090275ed..5c16649c 100644 --- a/SecurityServer/session.cpp +++ b/SecurityServer/session.cpp @@ -238,13 +238,13 @@ OSStatus Session::authCreate(const AuthItemSet &rights, const AuthItemSet &environment, AuthorizationFlags flags, AuthorizationBlob &newHandle, - const security_token_t &securityToken) + const audit_token_t &auditToken) { // invoke the authorization computation engine CredentialSet resultCreds; // this will acquire mLock, so we delay acquiring it - auto_ptr auth(new AuthorizationToken(*this, resultCreds, securityToken)); + auto_ptr auth(new AuthorizationToken(*this, resultCreds, auditToken)); // Make a copy of the mSessionCreds CredentialSet sessionCreds; diff --git a/SecurityServer/session.h b/SecurityServer/session.h index 3ceb2abb..35c89fca 100644 --- a/SecurityServer/session.h +++ b/SecurityServer/session.h @@ -87,7 +87,7 @@ public: const CredentialSet &authCredentials() const { return mSessionCreds; } OSStatus authCreate(const AuthItemSet &rights, const AuthItemSet &environment, - AuthorizationFlags flags, AuthorizationBlob &newHandle, const security_token_t &securityToken); + AuthorizationFlags flags, AuthorizationBlob &newHandle, const audit_token_t &auditToken); void authFree(const AuthorizationBlob &auth, AuthorizationFlags flags); OSStatus authGetRights(const AuthorizationBlob &auth, const AuthItemSet &requestedRights, const AuthItemSet &environment, diff --git a/SecurityServer/transition.cpp b/SecurityServer/transition.cpp index 86da930d..7f7073cd 100644 --- a/SecurityServer/transition.cpp +++ b/SecurityServer/transition.cpp @@ -32,7 +32,7 @@ // // Bracket Macros // -#define UCSP_ARGS mach_port_t servicePort, mach_port_t replyPort, security_token_t securityToken, \ +#define UCSP_ARGS mach_port_t servicePort, mach_port_t replyPort, audit_token_t auditToken, \ CSSM_RETURN *rcode #define CONTEXT_ARGS Context context, Pointer contextBase, Context::Attr *attributes, mach_msg_type_number_t attrSize @@ -87,7 +87,7 @@ kern_return_t ucsp_server_setup(UCSP_ARGS, mach_port_t taskPort, ClientSetupInfo { BEGIN_IPCN Server::active().setupConnection(Server::connectNewProcess, servicePort, replyPort, - taskPort, securityToken, &info, identity); + taskPort, auditToken, &info, identity); END_IPCN(CSSM) return KERN_SUCCESS; } @@ -100,7 +100,7 @@ kern_return_t ucsp_server_setupNew(UCSP_ARGS, mach_port_t taskPort, try { Session *session = new DynamicSession(TaskPort(taskPort).bootstrap()); Server::active().setupConnection(Server::connectNewSession, session->servicePort(), replyPort, - taskPort, securityToken, &info, identity); + taskPort, auditToken, &info, identity); *newServicePort = session->servicePort(); } catch (const MachPlusPlus::Error &err) { switch (err.error) { @@ -118,7 +118,7 @@ kern_return_t ucsp_server_setupThread(UCSP_ARGS, mach_port_t taskPort) { BEGIN_IPCN Server::active().setupConnection(Server::connectNewThread, servicePort, replyPort, - taskPort, securityToken); + taskPort, auditToken); END_IPCN(CSSM) return KERN_SUCCESS; } @@ -644,7 +644,7 @@ kern_return_t ucsp_server_authorizationCreate(UCSP_ARGS, Authorization::AuthItemSet rights(inRights), environment(inEnvironment); *rcode = connection.process.session.authCreate(rights, environment, - flags, *authorization, securityToken); + flags, *authorization, auditToken); END_IPC(CSSM) } diff --git a/SecurityServer/ucsp.defs b/SecurityServer/ucsp.defs index 9c8370ac..52c92806 100644 --- a/SecurityServer/ucsp.defs +++ b/SecurityServer/ucsp.defs @@ -108,7 +108,7 @@ type ExecutablePath = c_string[*:2048]; // #define UCSP_PORTS requestport sport: mach_port_t; \ replyport rport: mach_port_make_send_t; \ - serversectoken sourceSecurity: security_token_t; \ + serveraudittoken sourceAudit: audit_token_t; \ out rcode: CSSM_RETURN #define IN_CONTEXT in context: Context; in contextBase: BasePointer; in attrs: ContextAttributes #define IN_BLOB(name,type) in name: type##Blob; in name##Base: type##Ptr diff --git a/cdsa/cdsa_pluginlib/.cvsignore b/cdsa/cdsa_pluginlib/.cvsignore deleted file mode 100644 index d2615714..00000000 --- a/cdsa/cdsa_pluginlib/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -cdsa_pluginlib?Data diff --git a/cdsa/cdsa_utilities/.cvsignore b/cdsa/cdsa_utilities/.cvsignore deleted file mode 100644 index 2a8f2f8b..00000000 --- a/cdsa/cdsa_utilities/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -cdsa_utilities?Data diff --git a/cdsa/cdsa_utilities/ccaudit.cpp b/cdsa/cdsa_utilities/ccaudit.cpp new file mode 100644 index 00000000..24caac9a --- /dev/null +++ b/cdsa/cdsa_utilities/ccaudit.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved. + * + * The contents of this file constitute Original Code as defined in and are + * subject to the Apple Public Source License Version 1.2 (the 'License'). + * You may not use this file except in compliance with the License. Please obtain + * a copy of the License at http://www.apple.com/publicsource and read it before + * using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS + * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT + * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the + * specific language governing rights and limitations under the License. + */ + + +#include // bcopy() +#include // gethostname() +#include // gethostbyname() +#include // inet_addr() +#include // inet_addr() +#include // inet_addr() +#include // inet_addr() +#include +#include "utilities.h" +#include +#include +#include "ccaudit.h" + +namespace Security +{ +namespace CommonCriteria +{ + +void TerminalId::set(void) +{ + if (audit_set_terminal_id(&mTid) != kAUNoErr) + { + // If we start seeing the syslog too often, change to secdebug() + Syslog::warning("setting terminal ID info failed; using defaults"); + mTid.port = 0; + mTid.machine = 0; + } +} + +void AuditSession::registerSession(void) +{ + auditinfo_t auinfo; + + auinfo.ai_auid = mAuditId; + auinfo.ai_asid = mSessionId; + bcopy(&mTerminalId.get(), &(auinfo.ai_termid), sizeof(auinfo.ai_termid)); + bcopy(&mEventMask.get(), &(auinfo.ai_mask), sizeof(auinfo.ai_mask)); + + if (setaudit(&auinfo) != 0) + { + if (errno == ENOTSUP) + { + Syslog::notice("Attempted to initialize auditing, but this kernel that does not support auditing"); + return; + } + Syslog::notice("Could not initialize auditing; continuing"); + } +} + +void AuditRecord::submit(const short event_code, const int returnCode, + const char *msg) +{ + // If we're not auditing, do nothing + if (au_get_state() == AUC_NOAUDIT) + return; + + // XXX make this a secdebug, then enable it + // Syslog::notice("Submitting authorization audit record"); + + int ret = kAUNoErr; + + // XXX/gh 3574731: Fix BSM SPI so the const_cast<>s aren't necessary + if (returnCode == 0) + { + token_t *tok = NULL; + + if (msg) + tok = au_to_text(const_cast(msg)); + ret = audit_write_success(event_code, const_cast(tok), + mAuditId, mEUid, mEGid, mRUid, mRGid, + mPid, mSessionId, + const_cast(&(mTerminalId.get()))); + } + else + { + ret = audit_write_failure(event_code, const_cast(msg), + returnCode, mAuditId, mEUid, mEGid, + mRUid, mRGid, mPid, mSessionId, + const_cast(&(mTerminalId.get()))); + } + if (ret != kAUNoErr) + MacOSError::throwMe(ret); +} + + +} // end namespace CommonCriteria +} // end namespace Security diff --git a/cdsa/cdsa_utilities/ccaudit.h b/cdsa/cdsa_utilities/ccaudit.h new file mode 100644 index 00000000..0fc9b2d9 --- /dev/null +++ b/cdsa/cdsa_utilities/ccaudit.h @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved. + * + * The contents of this file constitute Original Code as defined in and are + * subject to the Apple Public Source License Version 1.2 (the 'License'). + * You may not use this file except in compliance with the License. Please obtain + * a copy of the License at http://www.apple.com/publicsource and read it before + * using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS + * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT + * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the + * specific language governing rights and limitations under the License. + */ + + +#ifndef _H_CCAUDIT +#define _H_CCAUDIT + +#include +#include + +namespace Security +{ + +namespace CommonCriteria +{ + +// for Tiger, this should be incorporated into Security's OSStatus range +enum ExternalErrors +{ + errNone = 0, + errInvalidCredential = 1111, // try to make easier to find in log + errUserCanceled, + errTooManyTries, + errEndOfExternalErrors // sentry/placeholder +}; + +class AuditMask +{ + public: + AuditMask() { } + AuditMask(const AuditMask &am) { set(am.get()); } + AuditMask(const au_mask_t &am) { set(am); } + ~AuditMask() { } + + void set(const au_mask_t &am) { set(am.am_success, am.am_failure); } + void set(unsigned int s, unsigned int f) { mMask.am_success = s; mMask.am_failure = f; } + const au_mask_t &get(void) const { return mMask; } + + private: + au_mask_t mMask; +}; + +// For the most part, we won't have a machine ID to initialize the +// au_tid_t's machine field. There's no machine ID in the audit token, +// for example, since MIG is localhost-only. +class TerminalId +{ + public: + TerminalId() { } + TerminalId(const TerminalId &t) { set(t.get()); } + TerminalId(const au_tid_t &tid) { set(tid); } + TerminalId(dev_t p, u_int32_t m) { port(p); machine(m); } + ~TerminalId() { } + + void set(void); // set using localhost + void set(const au_tid_t &tid) { port(tid.port); machine(tid.machine); } + void port(dev_t p) { mTid.port = p; } + void machine(u_int32_t m) { mTid.machine = m; } + const au_tid_t &get(void) const { return mTid; } + + private: + au_tid_t mTid; +}; + +// audit session state for the current process; only used by Server +class AuditSession +{ + public: + AuditSession() { } + AuditSession(au_id_t auid, AuditMask &mask, au_asid_t sid, + TerminalId &tid) + : mAuditId(auid), mEventMask(mask), mTerminalId(tid), + mSessionId(sid) { } + ~AuditSession() { } + + // set audit info for this process in kernel + void registerSession(void); + + void auditId(au_id_t auid) { mAuditId = auid; } + void eventMask(AuditMask &mask) { mEventMask = mask; } + void terminalId(TerminalId &tid) { mTerminalId = tid; } + void sessionId(au_asid_t sid) { mSessionId = sid; } + + au_id_t auditId(void) { return mAuditId; } + AuditMask &eventMask(void) { return mEventMask; } + TerminalId &terminalId(void) { return mTerminalId; } + au_asid_t sessionId(void) { return mSessionId; } + + private: + au_id_t mAuditId; + AuditMask mEventMask; + TerminalId mTerminalId; + au_asid_t mSessionId; +}; + +// +// For submitting audit records. Not general-purpose: no ability to +// submit arbitrary BSM tokens, for example. However, the SecurityServer +// has only limited auditing requirements under Common Criteria. +// +class AuditRecord +{ + public: + AuditRecord(const audit_token_t &auditToken) + : mAuditId(auditToken.val[0]), + mRUid(auditToken.val[3]), + mRGid(auditToken.val[4]), + mEUid(auditToken.val[1]), + mEGid(auditToken.val[2]), + mPid(auditToken.val[5]), + mSessionId(auditToken.val[6]), + mTerminalId(auditToken.val[7], 0) { } + ~AuditRecord() { } + + // returnCode == 0 --> success; nonzero returnCode --> failure + void submit(const short event_code, const int returnCode, + const char *msg = NULL); + + private: + au_id_t mAuditId; + uid_t mRUid; + gid_t mRGid; + uid_t mEUid; + gid_t mEGid; + pid_t mPid; + au_asid_t mSessionId; + TerminalId mTerminalId; +}; + +} // end namespace CommonCriteria + +} // end namespace Security + +#endif // _H_CCAUDIT diff --git a/cdsa/cdsa_utilities/utilities.h b/cdsa/cdsa_utilities/utilities.h index 0d148163..bb451cc4 100644 --- a/cdsa/cdsa_utilities/utilities.h +++ b/cdsa/cdsa_utilities/utilities.h @@ -751,7 +751,6 @@ private: const _Tp *_M_finish; }; - } // end namespace Security diff --git a/cdsa/cssm/.cvsignore b/cdsa/cssm/.cvsignore deleted file mode 100644 index 02a2add0..00000000 --- a/cdsa/cssm/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -cdsa?Data diff --git a/cdsa/mds/.cvsignore b/cdsa/mds/.cvsignore deleted file mode 100644 index 9c0531bf..00000000 --- a/cdsa/mds/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -PBUserInfo -mds?Data diff --git a/checkpw/checkpw.c b/checkpw/checkpw.c index 23c21352..f300addf 100644 --- a/checkpw/checkpw.c +++ b/checkpw/checkpw.c @@ -65,6 +65,7 @@ typedef struct sComData unsigned long fPID; unsigned long fPort; unsigned long fIPAddress; + mach_msg_audit_trailer_t fTail; sObject obj[ 10 ]; char data[ 1 ]; } sComData; @@ -86,7 +87,8 @@ typedef struct sIPCMsg unsigned long fPort; sObject obj[ 10 ]; char fData[ kIPCMsgLen ]; - mach_msg_security_trailer_t fTail; + mach_msg_audit_trailer_t fTail; // this is the largest trailer struct + // we have the bucket large enough to receive it } sIPCMsg; typedef enum { @@ -216,7 +218,7 @@ int checkpw_internal( const struct passwd* pw, const char* password ) msg->obj[0].length = curr; msg->fHeader.msgh_bits = MACH_MSGH_BITS( MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND ); - msg->fHeader.msgh_size = sizeof( sIPCMsg ) - sizeof( mach_msg_security_trailer_t ); + msg->fHeader.msgh_size = sizeof( sIPCMsg ) - sizeof( mach_msg_audit_trailer_t ); msg->fHeader.msgh_id = kCheckUserNameAndPassword; msg->fHeader.msgh_remote_port = serverPort; msg->fHeader.msgh_local_port = replyPort; @@ -238,7 +240,9 @@ int checkpw_internal( const struct passwd* pw, const char* password ) // get reply memset( msg, 0, kIPCMsgLen ); - result = mach_msg( (mach_msg_header_t *)msg, MACH_RCV_MSG | MACH_RCV_TIMEOUT, + result = mach_msg( (mach_msg_header_t *)msg, + MACH_RCV_MSG | MACH_RCV_TIMEOUT | + MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT) | MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0), 0, kIPCMsgSize, replyPort, 300 * 1000, MACH_PORT_NULL ); if ( result != MACH_MSG_SUCCESS ) { diff --git a/keychains/Makefile b/keychains/Makefile index 87d49399..cf7cda47 100644 --- a/keychains/Makefile +++ b/keychains/Makefile @@ -5,7 +5,8 @@ KEYCHAINS_SRC=$(SRCROOT)/keychains SYSTEM_LIBRARY_DIR=$(DSTROOT)/System/Library KEYCHAINS_DIR=$(SYSTEM_LIBRARY_DIR)/Keychains -X509KEYCHAINS=X509Anchors X509Certificates +ANCHORS_DIR=$(KEYCHAINS_DIR)/Anchors +CERTIFICATES_DIR=$(KEYCHAINS_DIR)/Certificates # # world-writable directory we need to create for CRL cache @@ -38,18 +39,21 @@ clean: # Install # install: - if [ ! -d $(KEYCHAINS_DIR) ]; then \ - mkdir -p $(KEYCHAINS_DIR); \ - chown root.admin $(KEYCHAINS_DIR); \ - chmod 755 $(KEYCHAINS_DIR); \ - fi - cd $(KEYCHAINS_SRC); cp $(X509KEYCHAINS) $(KEYCHAINS_DIR) - cd $(KEYCHAINS_DIR); \ - chown root.admin $(X509KEYCHAINS); \ - chmod 664 $(X509KEYCHAINS); \ - ls -l $(X509KEYCHAINS) + for d in "$(KEYCHAINS_DIR)" "$(ANCHORS_DIR)" "$(CERTIFICATES_DIR)"; do \ + if [ ! -d "$${d}" ]; then \ + mkdir -p "$${d}"; \ + chown root:admin "$${d}"; \ + chmod 755 "$${d}"; \ + fi; \ + done; \ + find "$(KEYCHAINS_SRC)/roots" -maxdepth 1 -a -type f -exec cp {} "$(ANCHORS_DIR)" \; ; \ + find "$(KEYCHAINS_SRC)/certs" -maxdepth 1 -a -type f -exec cp {} "$(CERTIFICATES_DIR)" \; ; \ + chown root:admin "$(ANCHORS_DIR)/"*; \ + chmod 664 "$(ANCHORS_DIR)/"*; \ + chown root:admin "$(CERTIFICATES_DIR)/"*; \ + chmod 664 "$(CERTIFICATES_DIR)/"*; \ if [ ! -d $(CRL_CACHE_DIR) ]; then \ mkdir -p $(CRL_CACHE_DIR); \ - chown root.wheel $(CRL_CACHE_DIR); \ + chown root:wheel $(CRL_CACHE_DIR); \ chmod 777 $(CRL_CACHE_DIR); \ fi diff --git a/keychains/X509Anchors b/keychains/X509Anchors deleted file mode 100644 index 167c1318..00000000 Binary files a/keychains/X509Anchors and /dev/null differ diff --git a/keychains/X509Certificates b/keychains/X509Certificates deleted file mode 100644 index 1f2c700f..00000000 Binary files a/keychains/X509Certificates and /dev/null differ diff --git a/keychains/certscript b/keychains/certscript deleted file mode 100755 index 3a9d6cc8..00000000 --- a/keychains/certscript +++ /dev/null @@ -1,24 +0,0 @@ -#! /bin/csh -f -# -# Build a keychain out of roots or certs. -# -set prog=$0 -if ( $#argv != 2 ) then - echo usage: ${prog:t} dbfile certsdir - echo dbfile must NOT exist. - exit(1) -endif -# -# Our job is to cook up a list of files in certsdir, not including -# the CVS directory. -# -set cwd=`pwd` -set dbfile=$cwd/$argv[1] -set certsdir=$argv[2] -if ( -e $dbfile ) then - echo I insist that you delete $argv[1] manually. - exit(1) -endif -# -set cmd="./makecerts $dbfile $certsdir/[a-zABD-Z0-9]* $certsdir/C[a-zA-UW-Z0-9]*" -$cmd || exit(1) diff --git a/keychains/makecerts b/keychains/makecerts deleted file mode 100755 index 157320d6..00000000 --- a/keychains/makecerts +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/perl -# -# Use to gather certificates into specified keychain. -# -$numFiles = $#ARGV; -if($numFiles < 1) { - print "usage: makecerts keychainfile cert...\n"; - die; -} -$dbname = $ARGV[0]; - -my $count = 0; -my $created; -foreach $argnum (1 .. $numFiles) { - $thisCert = $ARGV[$argnum]; - my @cmd = ("certtool", "i", $thisCert, "k=$dbname", "d"); - do { push @cmd, "c"; $created = 1; } unless $created; - print "$thisCert "; - die if system @cmd; - $count++; -} - -print "$count certificates placed into $dbname\n"; -exit 0; diff --git a/keychains/makeroots b/keychains/makeroots deleted file mode 100755 index 7c134b04..00000000 --- a/keychains/makeroots +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/perl -# -# -# -use strict; - -my $dbname = "X509Anchors"; - -my $count = 0; -my $created; -for my $file (@ARGV) { - my @cmd = ("certtool", "i", $file, "k=$dbname", "d"); - do { push @cmd, "c"; $created = 1; } unless $created; - print "$file "; - die if system @cmd; - $count++; -} - -print "$count certificates placed into $dbname\n"; -exit 0; diff --git a/keychains/postinstall.sh b/keychains/postinstall.sh new file mode 100755 index 00000000..9042a2de --- /dev/null +++ b/keychains/postinstall.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +# Create keychains if not there already +if [ ! -f "$targetdisk/System/Library/Keychains/X509Anchors" ]; then + "$targetdisk/usr/bin/security" create-keychain -p X509Anchors "$targetdisk/System/Library/Keychains/X509Anchors" +fi +if [ ! -f "$targetdisk/System/Library/Keychains/X509Certificates" ]; then + "$targetdisk/usr/bin/security" create-keychain -p X509Certificates "$targetdisk/System/Library/Keychains/X509Certificates" +fi + +# Add all anchors +cd "$targetdisk/System/Library/Keychains/Anchors/" +"$targetdisk/usr/bin/security" add-certificate -k "$targetdisk/System/Library/Keychains/X509Anchors" * + +# Add all intermediates +cd "$targetdisk/System/Library/Keychains/Certificates/" +"$targetdisk/usr/bin/security" add-certificate -k "$targetdisk/System/Library/Keychains/X509Certificates" * + +# we might want to delete the raw certificate files, in the interest of cruft cleanup +#rm -rf "$targetdisk/System/Library/Keychains/Anchors" +#rm -rf "$targetdisk/System/Library/Keychains/Certificates" diff --git a/keychains/roots/.cvsignore b/keychains/roots/.cvsignore deleted file mode 100644 index e43b0f98..00000000 --- a/keychains/roots/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.DS_Store diff --git a/keychains/roots/AOLTimeWarner1.der b/keychains/roots/AOLTimeWarner1.der new file mode 100644 index 00000000..49df4b3f Binary files /dev/null and b/keychains/roots/AOLTimeWarner1.der differ diff --git a/keychains/roots/AmericaOnline1.der b/keychains/roots/AmericaOnline1.der new file mode 100644 index 00000000..900dc146 Binary files /dev/null and b/keychains/roots/AmericaOnline1.der differ diff --git a/keychains/roots/TCTrustCenterClass1CA.der b/keychains/roots/TCTrustCenterClass1CA.der new file mode 100644 index 00000000..a45bfe25 Binary files /dev/null and b/keychains/roots/TCTrustCenterClass1CA.der differ diff --git a/keychains/roots/TCTrustCenterClass2CA.der b/keychains/roots/TCTrustCenterClass2CA.der new file mode 100644 index 00000000..3f376a7b Binary files /dev/null and b/keychains/roots/TCTrustCenterClass2CA.der differ diff --git a/keychains/roots/TCTrustCenterClass3CA.der b/keychains/roots/TCTrustCenterClass3CA.der new file mode 100644 index 00000000..bf14ae30 Binary files /dev/null and b/keychains/roots/TCTrustCenterClass3CA.der differ diff --git a/keychains/roots/TCTrustCenterClass4CA.der b/keychains/roots/TCTrustCenterClass4CA.der new file mode 100644 index 00000000..02c5fadf Binary files /dev/null and b/keychains/roots/TCTrustCenterClass4CA.der differ diff --git a/keychains/roots/TCTrustCenterTimeStampingCA.der b/keychains/roots/TCTrustCenterTimeStampingCA.der new file mode 100644 index 00000000..dc6d1f03 Binary files /dev/null and b/keychains/roots/TCTrustCenterTimeStampingCA.der differ diff --git a/keychains/roots/ValiCertAddTrustPublicChainingCA.cer b/keychains/roots/ValiCertAddTrustPublicChainingCA.cer new file mode 100644 index 00000000..66d812dc Binary files /dev/null and b/keychains/roots/ValiCertAddTrustPublicChainingCA.cer differ diff --git a/keychains/roots/ValiCertAddTrustSystemCA.cer b/keychains/roots/ValiCertAddTrustSystemCA.cer new file mode 100644 index 00000000..e98462a0 Binary files /dev/null and b/keychains/roots/ValiCertAddTrustSystemCA.cer differ diff --git a/keychains/roots/ValiCertClass1PVA.cer b/keychains/roots/ValiCertClass1PVA.cer new file mode 100644 index 00000000..02b4f23e Binary files /dev/null and b/keychains/roots/ValiCertClass1PVA.cer differ diff --git a/keychains/roots/ValiCertClass2PVA.cer b/keychains/roots/ValiCertClass2PVA.cer new file mode 100644 index 00000000..90f10c1d Binary files /dev/null and b/keychains/roots/ValiCertClass2PVA.cer differ diff --git a/keychains/roots/ValiCertClass3PVA.cer b/keychains/roots/ValiCertClass3PVA.cer new file mode 100644 index 00000000..56fa8491 Binary files /dev/null and b/keychains/roots/ValiCertClass3PVA.cer differ diff --git a/keychains/roots/beTRUSTedRootCertificate.der b/keychains/roots/beTRUSTedRootCertificate.der new file mode 100644 index 00000000..eec29bee Binary files /dev/null and b/keychains/roots/beTRUSTedRootCertificate.der differ