X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/libsecurityd/lib/eventlistener.cpp diff --git a/libsecurityd/lib/eventlistener.cpp b/libsecurityd/lib/eventlistener.cpp deleted file mode 100644 index f3f47d45..00000000 --- a/libsecurityd/lib/eventlistener.cpp +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright (c) 2003-2004,2006 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@ - */ - -#include -#include -#include -#include "eventlistener.h" -#include "SharedMemoryClient.h" -#include -#include "sscommon.h" -#include - -using namespace MachPlusPlus; - - -namespace Security { -namespace SecurityServer { - -typedef RefPointer EventPointer; -typedef std::list EventListenerList; - -static const char* GetNotificationName () -{ - // the name we give the client depends on the value of the environment variable "SECURITYSERVER" - const char* name = getenv (SECURITYSERVER_BOOTSTRAP_ENV); - if (name == NULL) - { - name = SECURITY_MESSAGES_NAME; - } - - return name; -} - - - -class SharedMemoryClientMaker -{ -private: - SharedMemoryClient mClient; - -public: - SharedMemoryClientMaker (); - SharedMemoryClient* Client (); -}; - - - -SharedMemoryClientMaker::SharedMemoryClientMaker () : mClient (GetNotificationName (), kSharedMemoryPoolSize) -{ -} - - - -SharedMemoryClient* SharedMemoryClientMaker::Client () -{ - return &mClient; -} - - - -ModuleNexus gEventListeners; -ModuleNexus gNotificationLock; -ModuleNexus gMemoryClient; - -class NotificationPort : public MachPlusPlus::CFAutoPort -{ -protected: - SharedMemoryClient *mClient; - - void ReceiveImplementation(u_int8_t* buffer, SegmentOffsetType length, UnavailableReason ur); - static void HandleRunLoopTimer(CFRunLoopTimerRef timer, void* info); - -public: - NotificationPort (mach_port_t port); - virtual ~NotificationPort (); - virtual void receive(const MachPlusPlus::Message &msg); -}; - -NotificationPort::NotificationPort (mach_port_t mp) : CFAutoPort (mp) -{ - mClient = gMemoryClient ().Client (); -} - - - -NotificationPort::~NotificationPort () -{ -} - - - -void NotificationPort::ReceiveImplementation(u_int8_t* buffer, SegmentOffsetType length, UnavailableReason ur) -{ - EventListenerList& eventList = gEventListeners(); - - // route the message to its destination - u_int32_t* ptr = (u_int32_t*) buffer; - - // we have a message, do the semantics... - SecurityServer::NotificationDomain domain = (SecurityServer::NotificationDomain) OSSwapBigToHostInt32 (*ptr++); - SecurityServer::NotificationEvent event = (SecurityServer::NotificationEvent) OSSwapBigToHostInt32 (*ptr++); - CssmData data ((u_int8_t*) ptr, buffer + length - (u_int8_t*) ptr); - - EventListenerList::iterator it = eventList.begin (); - while (it != eventList.end ()) - { - try - { - EventPointer ep = *it++; - if (ep->GetDomain () == domain && - (ep->GetMask () & (1 << event)) != 0) - { - ep->consume (domain, event, data); - } - } - catch (CssmError &e) - { - if (e.error != CSSM_ERRCODE_INTERNAL_ERROR) - { - throw; - } - } - } -} - - - -typedef void (^NotificationBlock)(); - - - -void NotificationPort::HandleRunLoopTimer(CFRunLoopTimerRef timer, void* info) -{ - // reconstruct our context and call it - NotificationBlock nb = (NotificationBlock) info; - nb(); - - // clean up - Block_release(nb); - CFRunLoopTimerInvalidate(timer); - CFRelease(timer); -} - - - -void NotificationPort::receive (const MachPlusPlus::Message &msg) -{ - /* - Read each notification received and post a timer for each with an expiration of - zero. I'd prefer to use a notification here, but I can't because, according to - the documentation, each application may only have one notification center and - the main application should have the right to pick the one it needs. - */ - - SegmentOffsetType length; - UnavailableReason ur; - - bool result; - - while (true) - { - u_int8_t *buffer = new u_int8_t[kSharedMemoryPoolSize]; - - { - StLock lock (gNotificationLock ()); - result = mClient->ReadMessage(buffer, length, ur); - if (!result) - { - delete [] buffer; - return; - } - } - - // make a block that contains our data - NotificationBlock nb = - ^{ - ReceiveImplementation(buffer, length, ur); - delete [] buffer; - }; - - // keep it in scope - nb = Block_copy(nb); - - // set up to run the next time the run loop fires - CFRunLoopTimerContext ctx; - memset(&ctx, 0, sizeof(ctx)); - ctx.info = nb; - - // make a run loop timer - CFRunLoopTimerRef timerRef = - CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent(), 0, - 0, 0, NotificationPort::HandleRunLoopTimer, &ctx); - - // install it to be run. - CFRunLoopAddTimer(CFRunLoopGetCurrent(), timerRef, kCFRunLoopDefaultMode); - } -} - - - -class ThreadNotifier -{ -protected: - NotificationPort *mNotificationPort; - int mNotifyToken; - -public: - ThreadNotifier(); - ~ThreadNotifier(); -}; - - - -ThreadNotifier::ThreadNotifier() - : mNotificationPort(NULL) -{ - mach_port_t mp; - if (notify_register_mach_port (GetNotificationName (), &mp, 0, &mNotifyToken) == NOTIFY_STATUS_OK) { - mNotificationPort = new NotificationPort (mp); - mNotificationPort->enable (); - } -} - - - -ThreadNotifier::~ThreadNotifier() -{ - if (mNotificationPort) { - notify_cancel (mNotifyToken); - delete mNotificationPort; - } -} - - - -ModuleNexus > threadInfo; - - - -static void InitializeNotifications () -{ - threadInfo()(); // cause the notifier for this thread to initialize -} - - - -EventListener::EventListener (NotificationDomain domain, NotificationMask eventMask) - : mDomain (domain), mMask (eventMask) -{ - // make sure that notifications are turned on. - InitializeNotifications (); -} - - -// -// StopNotification() is needed on destruction; everyone else cleans up after themselves. -// -EventListener::~EventListener () -{ - StLock lock (gNotificationLock ()); - - // find the listener in the list and remove it - EventListenerList::iterator it = std::find (gEventListeners ().begin (), - gEventListeners ().end (), - this); - if (it != gEventListeners ().end ()) - { - gEventListeners ().erase (it); - } -} - - - -// get rid of the pure virtual -void EventListener::consume(NotificationDomain, NotificationEvent, const Security::CssmData&) -{ -} - - - -void EventListener::FinishedInitialization(EventListener *eventListener) -{ - StLock lock (gNotificationLock ()); - gEventListeners().push_back (eventListener); -} - - - -} // end namespace SecurityServer -} // end namespace Security