#ifndef _H_NOTIFICATIONS
#define _H_NOTIFICATIONS
#include <security_utilities/mach++.h>
#include <security_utilities/machserver.h>
#include <security_utilities/globalizer.h>
#include <securityd_client/ssclient.h>
#include "SharedMemoryCommon.h"
#include <map>
#include <queue>
#include "SharedMemoryServer.h"
using MachPlusPlus::Port;
using MachPlusPlus::MachServer;
using SecurityServer::NotificationDomain;
using SecurityServer::NotificationEvent;
using SecurityServer::NotificationMask;
class SharedMemoryListener;
class Listener: public RefCount {
public:
Listener(NotificationDomain domain, NotificationMask events,
mach_port_t port = MACH_PORT_NULL);
virtual ~Listener();
static void notify(NotificationDomain domain,
NotificationEvent event, const CssmData &data);
static void notify(NotificationDomain domain,
NotificationEvent event, uint32 sequence, const CssmData &data, audit_token_t auditToken);
static bool remove(Port port);
const NotificationDomain domain;
const NotificationMask events;
bool wants(NotificationEvent event)
{ return (1 << event) & events; }
protected:
class Notification : public RefCount {
public:
Notification(NotificationDomain domain, NotificationEvent event,
uint32 seq, const CssmData &data);
virtual ~Notification();
const NotificationDomain domain;
const NotificationEvent event;
const uint32 sequence;
const CssmAutoData data;
std::string description() const;
size_t size() const
{ return data.length(); } };
virtual void notifyMe(Notification *message) = 0;
static bool testPredicate(const std::function<bool(const Listener& listener)> test);
public:
class JitterBuffer {
public:
JitterBuffer() : mNotifyLast(0) { }
bool inSequence(Notification *message);
RefPointer<Notification> popNotification();
private:
uint32 mNotifyLast; typedef std::map<uint32, RefPointer<Notification> > JBuffer;
JBuffer mBuffer; };
private:
static void sendNotification(Notification *message);
private:
typedef multimap<mach_port_t, RefPointer<Listener> > ListenerMap;
static ListenerMap& listeners;
static Mutex setLock;
};
class SharedMemoryListener : public Listener, public SharedMemoryServer, public Security::MachPlusPlus::MachServer::Timer
{
protected:
virtual void action ();
virtual void notifyMe(Notification *message);
static bool findUID(uid_t uid);
static int get_process_euid(pid_t pid, uid_t& out_euid);
bool needsPrivacyFilter(Notification *notification);
bool isTrustEvent(Notification *notification);
uint32 getRecordType(const CssmData& val) const;
bool mActive;
public:
SharedMemoryListener (const char* serverName, u_int32_t serverSize, uid_t uid = 0, gid_t gid = 0);
virtual ~SharedMemoryListener ();
static void createDefaultSharedMemoryListener(uid_t uid, gid_t gid);
};
#endif