SecTranslocateServer.cpp [plain text]
#include <string>
#include <vector>
#include <exception>
#include <dispatch/dispatch.h>
#include "SecTranslocateShared.hpp"
#include "SecTranslocateServer.hpp"
#include "SecTranslocateUtilities.hpp"
#include "SecTranslocateDANotification.hpp"
#include "SecTranslocateXPCServer.hpp"
#include "SecTranslocateLSNotification.hpp"
#undef check //The CoreServices code pulls in a check macro that we don't want
#include <security_utilities/unix++.h>
#include <security_utilities/logging.h>
namespace Security {
using namespace Security::UnixPlusPlus;
namespace SecTranslocate {
using namespace std;
#define TRANSLOCATION_CLEANUP_INTERVAL 12ULL * 60ULL * 60ULL * NSEC_PER_SEC
#define TRANSLOCATION_CLEANUP_LEEWAY TRANSLOCATION_CLEANUP_INTERVAL/2ULL
TranslocatorServer::TranslocatorServer(dispatch_queue_t q):syncQ(q), da(q), ls(q),xpc(q)
{
if (!q)
{
Syslog::critical("SecTranslocate: TranslocatorServer failed to create the dispatch queue");
UnixError::throwMe(ENOMEM);
}
dispatch_retain(syncQ);
setupPeriodicCleanup();
Syslog::warning("SecTranslocate: Server started");
}
TranslocatorServer::~TranslocatorServer()
{
if( syncQ )
{
dispatch_release(syncQ);
}
if(cleanupTimer)
{
dispatch_source_cancel(cleanupTimer);
cleanupTimer = NULL;
}
}
string TranslocatorServer::translocatePathForUser(const TranslocationPath &originalPath, const string &destPath)
{
__block string newPath;
__block exception_ptr exception(0);
dispatch_sync(syncQ, ^{
try
{
newPath = Security::SecTranslocate::translocatePathForUser(originalPath,destPath);
}
catch (...)
{
exception = current_exception();
}
});
if (exception)
{
rethrow_exception(exception);
}
return newPath;
}
bool TranslocatorServer::destroyTranslocatedPathForUser(const string &translocatedPath)
{
__block bool result = false;
__block exception_ptr exception(0);
dispatch_sync(syncQ, ^{
try
{
result = Security::SecTranslocate::destroyTranslocatedPathForUser(translocatedPath);
}
catch (...)
{
exception = current_exception();
}
});
if (exception)
{
rethrow_exception(exception);
}
return result;
}
void TranslocatorServer::appLaunchCheckin(pid_t pid)
{
ls.checkIn(pid);
}
void TranslocatorServer::setupPeriodicCleanup()
{
cleanupTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, syncQ);
dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, TRANSLOCATION_CLEANUP_INTERVAL);
dispatch_source_set_timer(cleanupTimer, when, TRANSLOCATION_CLEANUP_INTERVAL, TRANSLOCATION_CLEANUP_LEEWAY);
dispatch_source_set_cancel_handler(cleanupTimer, ^{
dispatch_release(cleanupTimer);
});
dispatch_source_set_event_handler(cleanupTimer, ^{
try
{
Syslog::notice("SecTranslocate: attempting to cleanup unused translocation points");
tryToDestroyUnusedTranslocationMounts();
}
catch (Security::UnixError err)
{
int error = err.unixError();
Syslog::error("SecTranslocate: got unix error[ %d : %s ] while trying to cleanup translocation points.",error, strerror(error));
}
catch (...)
{
Syslog::error("SecTranslocate: unknown error while trying to cleanup translocation points.");
}
});
dispatch_resume(cleanupTimer);
}
} }