/ securityd / src / notifications.h
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