notifications.h
1 /* 2 * Copyright (c) 2000-2004,2006-2008 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 25 // 26 // notifications - handling of securityd-gated notification messages 27 // 28 #ifndef _H_NOTIFICATIONS 29 #define _H_NOTIFICATIONS 30 31 #include <security_utilities/mach++.h> 32 #include <security_utilities/machserver.h> 33 #include <security_utilities/globalizer.h> 34 #include <securityd_client/ssclient.h> 35 #include "SharedMemoryCommon.h" 36 #include <map> 37 #include <queue> 38 39 #include "SharedMemoryServer.h" 40 41 using MachPlusPlus::Port; 42 using MachPlusPlus::MachServer; 43 using SecurityServer::NotificationDomain; 44 using SecurityServer::NotificationEvent; 45 using SecurityServer::NotificationMask; 46 47 class SharedMemoryListener; 48 49 // 50 // A registered receiver of notifications. 51 // This is an abstract class; you must subclass to define notifyMe(). 52 // 53 // All Listeners in existence are collected in an internal map of ports to 54 // Listener*s, which makes them eligible to have events delivered to them via 55 // their notifyMe() method. There are (only) two viable lifetime management 56 // strategies for your Listener subclass: 57 // (1) Eternal: don't ever destroy your Listener. All is well. By convention, 58 // such Listeners use the null port. 59 // (2) Port-based: To get rid of your Listeners, call Listener::remove(port), 60 // which will delete(!) all Listeners constructed with that port. 61 // Except for the remove() functionality, Listener does not interpret the port. 62 // 63 // If you need another Listener lifetime management strategy, you will probably 64 // have to change things around here. 65 // 66 class Listener: public RefCount { 67 public: 68 Listener(NotificationDomain domain, NotificationMask events, 69 mach_port_t port = MACH_PORT_NULL); 70 virtual ~Listener(); 71 72 // inject an event into the notification system 73 static void notify(NotificationDomain domain, 74 NotificationEvent event, const CssmData &data); 75 static void notify(NotificationDomain domain, 76 NotificationEvent event, uint32 sequence, const CssmData &data, audit_token_t auditToken); 77 78 const NotificationDomain domain; 79 const NotificationMask events; 80 81 bool wants(NotificationEvent event) 82 { return (1 << event) & events; } 83 84 protected: 85 class Notification : public RefCount { 86 public: 87 Notification(NotificationDomain domain, NotificationEvent event, 88 uint32 seq, const CssmData &data); 89 virtual ~Notification(); 90 91 const NotificationDomain domain; 92 const NotificationEvent event; 93 const uint32 sequence; 94 const CssmAutoData data; 95 96 std::string description() const; 97 size_t size() const 98 { return data.length(); } //@@@ add "slop" here for heuristic? 99 }; 100 101 virtual void notifyMe(Notification *message) = 0; 102 103 static bool testPredicate(const std::function<bool(const Listener& listener)> test); 104 105 public: 106 class JitterBuffer { 107 public: 108 JitterBuffer() : mNotifyLast(0) { } 109 110 bool inSequence(Notification *message); 111 RefPointer<Notification> popNotification(); 112 113 private: 114 uint32 mNotifyLast; // last notification seq processed 115 typedef std::map<uint32, RefPointer<Notification> > JBuffer; 116 JBuffer mBuffer; // early messages buffer 117 }; 118 119 private: 120 static void sendNotification(Notification *message); 121 122 private: 123 typedef multimap<mach_port_t, RefPointer<Listener> > ListenerMap; 124 static ListenerMap& listeners; 125 static Mutex setLock; 126 }; 127 128 129 130 class SharedMemoryListener : public Listener, public SharedMemoryServer, public Security::MachPlusPlus::MachServer::Timer 131 { 132 protected: 133 virtual void action (); 134 virtual void notifyMe(Notification *message); 135 136 static bool findUID(uid_t uid); 137 static int get_process_euid(pid_t pid, uid_t& out_euid); 138 139 bool needsPrivacyFilter(Notification *notification); 140 bool isTrustEvent(Notification *notification); 141 uint32 getRecordType(const CssmData& val) const; 142 143 bool mActive; 144 145 Mutex mMutex; 146 147 public: 148 SharedMemoryListener (const char* serverName, u_int32_t serverSize, uid_t uid = 0, gid_t gid = 0); 149 virtual ~SharedMemoryListener (); 150 151 static void createDefaultSharedMemoryListener(uid_t uid, gid_t gid); 152 }; 153 154 #endif