#include <securityd_client/ucsp.h>
#include "server.h"
#include "session.h"
#include "notifications.h"
#include "auditevents.h"
#include "self.h"
#include "util.h"
#include <security_utilities/daemon.h>
#include <security_utilities/machserver.h>
#include <security_utilities/logging.h>
#include <Security/SecKeychainPriv.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <syslog.h>
#include <security_cdsa_utilities/acl_any.h>
#include <security_cdsa_utilities/acl_password.h>
#include <security_cdsa_utilities/acl_prompted.h>
#include <security_cdsa_utilities/acl_protectedpw.h>
#include <security_cdsa_utilities/acl_threshold.h>
#include <security_cdsa_utilities/acl_codesigning.h>
#include <security_cdsa_utilities/acl_process.h>
#include <security_cdsa_utilities/acl_comment.h>
#include <security_cdsa_utilities/acl_preauth.h>
#include "acl_keychain.h"
#include "acl_partition.h"
#include <sandbox.h>
static void usage(const char *me) __attribute__((noreturn));
static void handleSignals(int sig);
static Port gMainServerPort;
int main(int argc, char *argv[])
{
DisableLocalization();
secnotice("SecServer", "starting umask was 0%o", ::umask(0));
::umask(0);
SecKeychainSetServerMode();
const char *params[] = {"LEGACY_TOKENS_ENABLED", "NO", NULL};
char* errorbuf = NULL;
if (sandbox_init_with_parameters("com.apple.securityd", SANDBOX_NAMED, params, &errorbuf)) {
seccritical("SecServer: unable to enter sandbox: %{public}s", errorbuf);
if (errorbuf) {
sandbox_free_error(errorbuf);
}
exit(1);
} else {
secnotice("SecServer", "entered sandbox");
}
bool debugMode = false;
int workerTimeout = 0;
int maxThreads = 0;
bool waitForClients = true;
bool mdsIsInstalled = false;
uint32_t keychainAclDefault = CSSM_ACL_KEYCHAIN_PROMPT_INVALID | CSSM_ACL_KEYCHAIN_PROMPT_UNSIGNED;
unsigned int verbose = 0;
if (access("/etc/rc.cdrom", F_OK) == 0) { secnotice("SecServer", "starting in installmode");
}
extern char *optarg;
extern int optind;
int arg;
while ((arg = getopt(argc, argv, ":dE:im:t:T:uvW")) != -1) {
switch (arg) {
case 'd':
debugMode = true;
break;
case 'E':
break;
case 'i':
keychainAclDefault &= ~CSSM_ACL_KEYCHAIN_PROMPT_INVALID;
break;
case 'm':
mdsIsInstalled = true;
break;
case 't':
if ((maxThreads = atoi(optarg)) < 0)
maxThreads = 0;
break;
case 'T':
if ((workerTimeout = atoi(optarg)) < 0)
workerTimeout = 0;
break;
case 'W':
waitForClients = false;
break;
case 'u':
keychainAclDefault &= ~CSSM_ACL_KEYCHAIN_PROMPT_UNSIGNED;
break;
case 'v':
verbose++;
break;
default:
usage(argv[0]);
}
}
if (optind < argc) {
usage(argv[0]);
}
const char *bootstrapName = SECURITYSERVER_BOOTSTRAP_NAME;
const char* messagingName = SharedMemoryCommon::kDefaultSecurityMessagesName;
if (debugMode) {
Syslog::open(bootstrapName, LOG_AUTHPRIV, LOG_PERROR);
Syslog::notice("%s started in debug mode", argv[0]);
} else {
Syslog::open(bootstrapName, LOG_AUTHPRIV, LOG_CONS);
}
if (uid_t uid = getuid()) {
#if defined(NDEBUG)
Syslog::alert("Tried to run securityd as user %d: aborted", uid);
fprintf(stderr, "You are not allowed to run securityd\n");
exit(1);
#else
fprintf(stderr, "securityd is unprivileged (uid=%d); some features may not work.\n", uid);
#endif //NDEBUG
}
if (!debugMode && getppid() != 1 && !Daemon::incarnate(false)) {
exit(1); }
if (signal(SIGCHLD, handleSignals) == SIG_ERR
|| signal(SIGINT, handleSignals) == SIG_ERR
|| signal(SIGTERM, handleSignals) == SIG_ERR
|| signal(SIGPIPE, handleSignals) == SIG_ERR
#if !defined(NDEBUG)
|| signal(SIGUSR1, handleSignals) == SIG_ERR
#endif //NDEBUG
|| signal(SIGUSR2, handleSignals) == SIG_ERR) {
perror("signal");
exit(1);
}
#ifndef __clang_analyzer__
new AnyAclSubject::Maker();
new PasswordAclSubject::Maker();
new ProtectedPasswordAclSubject::Maker();
new PromptedAclSubject::Maker();
new ThresholdAclSubject::Maker();
new CommentAclSubject::Maker();
new ProcessAclSubject::Maker();
new CodeSignatureAclSubject::Maker();
new KeychainPromptAclSubject::Maker(keychainAclDefault);
new PartitionAclSubject::Maker();
new PreAuthorizationAcls::OriginMaker();
new PreAuthorizationAcls::SourceMaker();
#endif
CodeSignatures codeSignatures;
Server server(codeSignatures, bootstrapName);
gMainServerPort = server.primaryServicePort();
if (workerTimeout)
server.timeout(workerTimeout);
if (maxThreads)
server.maxThreads(maxThreads);
server.floatingThread(true);
server.waitForClients(waitForClients);
server.verbosity(verbose);
RootSession rootSession(debugMode ? (sessionHasGraphicAccess | sessionHasTTY) : 0, server);
AuditMonitor audits(gMainServerPort);
audits.run();
server.loadCssm(mdsIsInstalled);
#ifndef __clang_analyzer__
new SharedMemoryListener(messagingName, kSharedMemoryPoolSize);
#endif
secnotice("SecServer", "Entering service as %s", (char*)bootstrapName);
Syslog::notice("Entering service");
server.run();
Syslog::alert("Aborting");
return 1;
}
static void usage(const char *me)
{
fprintf(stderr, "Usage: %s [-dwX]"
"\n\t[-e equivDatabase] path to code equivalence database"
"\n\t[-t maxthreads] [-T threadTimeout] server thread control"
"\n", me);
exit(2);
}
const CFStringRef kTKSmartCardPreferencesDomain = CFSTR("com.apple.security.smartcard");
const CFStringRef kTKLegacyTokendPreferencesKey = CFSTR("Legacy");
static void handleSignals(int sig)
{
(void)self_client_handleSignal(gMainServerPort, mach_task_self(), sig);
}