#include <stdlib.h>
#include "ocspdServer.h"
#include <security_ocspd/ocspdTypes.h>
#include <security_ocspd/ocspdDebug.h>
#include <security_utilities/daemon.h>
#include <security_utilities/logging.h>
#include <CoreFoundation/CoreFoundation.h>
using namespace Security;
Mutex gTimeMutex;
const CFAbsoluteTime kTimeoutInterval = 300;
const int kTimeoutCheckTime = 60;
static void usage(char **argv)
{
printf("Usage: %s [option...]\n", argv[0]);
printf("Options:\n");
printf(" -d -- Debug mode, do not run as forked daemon\n");
printf(" -n bootstrapName -- specify alternate bootstrap name\n");
exit(1);
}
void HandleSigTerm (int sig)
{
exit (1);
}
CFAbsoluteTime gLastActivity;
void ServerActivity()
{
StLock<Mutex> _mutexLock(gTimeMutex);
gLastActivity = CFAbsoluteTimeGetCurrent();
}
class TimeoutTimer : public MachPlusPlus::MachServer::Timer
{
protected:
OcspdServer &mServer;
public:
TimeoutTimer(OcspdServer &server) : mServer(server) {}
void action();
};
void TimeoutTimer::action()
{
bool doExit = false;
{
StLock<Mutex> _mutexLock(gTimeMutex);
CFAbsoluteTime thisTime = CFAbsoluteTimeGetCurrent();
if (thisTime - gLastActivity > kTimeoutInterval)
{
doExit = true;
}
if (!doExit)
{
mServer.setTimer(this, Time::Interval(kTimeoutCheckTime));
}
}
if (doExit)
{
exit(0);
}
}
int main(int argc, char **argv)
{
signal (SIGTERM, HandleSigTerm);
const char *bootStrapName = NULL;
bool debugMode = false;
extern char *optarg;
int arg;
while ((arg = getopt(argc, argv, "dn:h")) != -1) {
switch(arg) {
case 'd':
debugMode = true;
break;
case 'n':
bootStrapName = optarg;
break;
case 'h':
default:
usage(argv);
}
}
if (optind < argc) {
usage(argv);
}
#ifndef NDEBUG
if(bootStrapName == NULL) {
bootStrapName = getenv(OCSPD_BOOTSTRAP_ENV);
}
#endif
if(bootStrapName == NULL) {
bootStrapName = OCSPD_BOOTSTRAP_NAME;
}
#if defined(NDEBUG)
if (uid_t uid = getuid()) {
Syslog::alert("Tried to run ocspd as user %d: aborted", uid);
fprintf(stderr, "You are not allowed to run securityd\n");
exit(1);
}
#endif
if (!debugMode) {
if (!Daemon::incarnate(false))
exit(1); }
OcspdServer server(bootStrapName);
try {
ocspdDebug("ocspd: starting main run loop");
ServerActivity();
TimeoutTimer tt(server);
server.setTimer(&tt, Time::Interval(kTimeoutCheckTime));
server.run(4096, MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0) |
MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT));
}
catch(...) {}
#ifndef NDEBUG
Syslog::alert("Aborting");
#endif
return 1;
}