X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/libsecurity_keychain/lib/CCallbackMgr.cp diff --git a/libsecurity_keychain/lib/CCallbackMgr.cp b/libsecurity_keychain/lib/CCallbackMgr.cp deleted file mode 100644 index 6c9320bc..00000000 --- a/libsecurity_keychain/lib/CCallbackMgr.cp +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The 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. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - -/* - File: CCallbackMgr.cp - - Contains: Code that communicates with processes that install a callback - with the Keychain Manager to receive keychain events. - -*/ - -#include "CCallbackMgr.h" - -#include -#include - -#include "Globals.h" -#include -#include -#include -#include - -using namespace KeychainCore; -using namespace CssmClient; -using namespace SecurityServer; - -#pragma mark ÑÑÑÑ CallbackInfo ÑÑÑÑ - -CallbackInfo::CallbackInfo() : mCallback(NULL),mEventMask(0),mContext(NULL) -{ -} - -CallbackInfo::CallbackInfo(SecKeychainCallback inCallbackFunction, - SecKeychainEventMask inEventMask, void *inContext) - : mCallback(inCallbackFunction), mEventMask(inEventMask), mContext(inContext) -{ -} - -CallbackInfo::~CallbackInfo() -{ -} - -bool CallbackInfo::operator==(const CallbackInfo& other) const -{ - return mCallback==other.mCallback; -} - -bool CallbackInfo::operator!=(const CallbackInfo& other) const -{ - return !(*this==other); -} - - -#pragma mark ÑÑÑÑ CCallbackMgr ÑÑÑÑ - - -class CallbackMaker -{ -protected: - RefPointer mCallbackManager; - -public: - CallbackMaker(); - CCallbackMgr& instance() {return *mCallbackManager;} -}; - - -CallbackMaker::CallbackMaker() -{ - CCallbackMgr* manager = new CCallbackMgr(); - mCallbackManager = manager; -} - - - -ModuleNexus gCallbackMaker; - -CCallbackMgr::CCallbackMgr() : EventListener (kNotificationDomainDatabase, kNotificationAllEvents) -{ - EventListener::FinishedInitialization(this); -} - -CCallbackMgr::~CCallbackMgr() -{ -} - -CCallbackMgr& CCallbackMgr::Instance() -{ - return gCallbackMaker().instance(); -} - -void CCallbackMgr::AddCallback( SecKeychainCallback inCallbackFunction, - SecKeychainEventMask inEventMask, - void* inContext) - -{ - CallbackInfo info( inCallbackFunction, inEventMask, inContext ); - CallbackInfo existingInfo; - - - CallbackInfoListIterator ix = find( CCallbackMgr::Instance().mEventCallbacks.begin(), - CCallbackMgr::Instance().mEventCallbacks.end(), info ); - - // make sure it is not already there - if ( ix!=CCallbackMgr::Instance().mEventCallbacks.end() ) - { - // It's already there. This could mean that the old process died unexpectedly, - // so we need to validate the process ID of the existing callback. - // On Mac OS X this list is per process so this is always a duplicate - MacOSError::throwMe(errSecDuplicateCallback); - } - - CCallbackMgr::Instance().mEventCallbacks.push_back(info); -} - - -class Predicate -{ - SecKeychainCallback mCallbackFunction; -public: - Predicate(SecKeychainCallback inCallbackFunction) : mCallbackFunction(inCallbackFunction) {} - bool operator()(const CallbackInfo &cbInfo) { return cbInfo.mCallback == mCallbackFunction; } -}; - -void CCallbackMgr::RemoveCallback(SecKeychainCallback inCallbackFunction) -{ - size_t oldSize = CCallbackMgr::Instance().mEventCallbacks.size(); - Predicate predicate(inCallbackFunction); - CCallbackMgr::Instance().mEventCallbacks.remove_if(predicate); - - if (oldSize == CCallbackMgr::Instance().mEventCallbacks.size()) - MacOSError::throwMe(errSecInvalidCallback); -} - -void CCallbackMgr::AlertClients(const list &eventCallbacks, - SecKeychainEvent inEvent, - pid_t inPid, - const Keychain &inKeychain, - const Item &inItem) -{ - secdebug("kcnotify", "dispatch event %ld pid %d keychain %p item %p", - (unsigned long)inEvent, inPid, &inKeychain, !!inItem ? &*inItem : NULL); - - // Iterate through callbacks, looking for those registered for inEvent - const SecKeychainEventMask theMask = 1U << inEvent; - - for (ConstCallbackInfoListIterator ix = eventCallbacks.begin(); ix != eventCallbacks.end(); ++ix) - { - if (!(ix->mEventMask & theMask)) - continue; - - SecKeychainCallbackInfo cbInfo; - cbInfo.version = 0; // @@@ kKeychainAPIVersion; - cbInfo.item = inItem ? inItem->handle() : 0; - cbInfo.keychain = inKeychain ? inKeychain->handle() : 0; - cbInfo.pid = inPid; - - ix->mCallback(inEvent, &cbInfo, ix->mContext); - if (cbInfo.item) CFRelease(cbInfo.item); - if (cbInfo.keychain) CFRelease(cbInfo.keychain); - } -} - - - -void CCallbackMgr::consume (SecurityServer::NotificationDomain domain, SecurityServer::NotificationEvent whichEvent, const CssmData &data) -{ - NameValueDictionary dictionary (data); - - // Decode from userInfo the event type, 'keychain' CFDict, and 'item' CFDict - SecKeychainEvent thisEvent = whichEvent; - - pid_t thisPid; - const NameValuePair* pidRef = dictionary.FindByName(PID_KEY); - if (pidRef == 0) - { - thisPid = 0; - } - else - { - thisPid = n2h(*reinterpret_cast(pidRef->Value().data ())); - } - - Keychain thisKeychain; - Item thisItem; - list eventCallbacks; - { - // Lock the global API lock before doing stuff with StorageManager. - // make sure we have a database identifier - if (dictionary.FindByName (SSUID_KEY) != 0) - { - StLock_(*globals().storageManager.getStorageManagerMutex()); - 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()); - else if (thisEvent == kSecKeychainListChangedEvent) - globals().storageManager.forceUserSearchListReread(); - - 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(eventCallbacks, thisEvent, thisPid, thisKeychain, thisItem); -}