]> git.saurik.com Git - apple/securityd.git/blobdiff - src/main.cpp
securityd-55199.3.tar.gz
[apple/securityd.git] / src / main.cpp
index ef34365ee7174ea7cadb8808a2ab681daa98175e..8647e721dd8c636e233d898b093e57a07e01fce3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
 #include "entropy.h"
 #include "authority.h"
 #include "session.h"
+#include "notifications.h"
 #include "pcscmonitor.h"
+#include "auditevents.h"
 #include "self.h"
 
 #include <security_utilities/daemon.h>
 #include <security_utilities/machserver.h>
 #include <security_utilities/logging.h>
-#include <security_utilities/ktracecodes.h>
-#include <security_cdsa_client/osxsigner.h>
+
+#include <Security/SecKeychainPriv.h>
 
 #include <unistd.h>
 #include <sys/types.h>
 #include <signal.h>
 #include <syslog.h>
 
-
-// #define PERFORMANCE_MEASUREMENT 1
-
-#ifdef PERFORMANCE_MEASUREMENT
-#include <mach/mach_time.h>
-#endif
-
 // ACL subject types (their makers are instantiated here)
 #include <security_cdsa_utilities/acl_any.h>
 #include <security_cdsa_utilities/acl_password.h>
@@ -74,6 +69,7 @@ static PCSCMonitor::ServiceLevel scOptions(const char *optionString);
 
 
 static Port gMainServerPort;
+PCSCMonitor *gPCSC;
 
 
 //
@@ -81,35 +77,42 @@ static Port gMainServerPort;
 //
 int main(int argc, char *argv[])
 {
-       #ifdef PERFORMANCE_MEASUREMENT
-       // needed for automated timing of securityd startup
-       uint64_t startTime = mach_absolute_time ();
-       #endif
-       
-    Debug::trace (kSecTraceSecurityServerStart);
-       
        // clear the umask - we know what we're doing
        secdebug("SS", "starting umask was 0%o", ::umask(0));
        ::umask(0);
-    
+
+       // tell the keychain (client) layer to turn off the server interface
+       SecKeychainSetServerMode();
+       
        // program arguments (preset to defaults)
        bool debugMode = false;
        const char *bootstrapName = NULL;
+       const char* messagingName = SECURITY_MESSAGES_NAME;
        bool doFork = false;
        bool reExecute = false;
        int workerTimeout = 0;
        int maxThreads = 0;
+       bool waitForClients = true;
+    bool mdsIsInstalled = false;
        const char *authorizationConfig = "/etc/authorization";
        const char *tokenCacheDir = "/var/db/TokenCache";
     const char *entropyFile = "/var/db/SystemEntropyCache";
        const char *equivDbFile = EQUIVALENCEDBPATH;
        const char *smartCardOptions = getenv("SMARTCARDS");
+       uint32_t keychainAclDefault = CSSM_ACL_KEYCHAIN_PROMPT_INVALID | CSSM_ACL_KEYCHAIN_PROMPT_UNSIGNED;
+       unsigned int verbose = 0;
+       
+       // check for the Installation-DVD environment and modify some default arguments if found
+       if (access("/etc/rc.cdrom", F_OK) == 0) {       // /etc/rc.cdrom exists
+               SECURITYD_INSTALLMODE();
+               smartCardOptions = "off";       // needs writable directories that aren't
+       }
 
        // parse command line arguments
        extern char *optarg;
        extern int optind;
        int arg;
-       while ((arg = getopt(argc, argv, "a:c:de:E:fN:s:t:T:X")) != -1) {
+       while ((arg = getopt(argc, argv, "a:c:de:E:imN:s:t:T:uvWX")) != -1) {
                switch (arg) {
                case 'a':
                        authorizationConfig = optarg;
@@ -126,8 +129,11 @@ int main(int argc, char *argv[])
         case 'E':
             entropyFile = optarg;
             break;
-        case 'f':
-            fprintf(stderr, "%s: the -f option is obsolete\n", argv[0]);
+               case 'i':
+                       keychainAclDefault &= ~CSSM_ACL_KEYCHAIN_PROMPT_INVALID;
+                       break;
+        case 'm':
+            mdsIsInstalled = true;
             break;
                case 'N':
                        bootstrapName = optarg;
@@ -143,6 +149,15 @@ int main(int argc, char *argv[])
                        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;
                case 'X':
                        doFork = true;
                        reExecute = true;
@@ -160,9 +175,19 @@ int main(int argc, char *argv[])
     if (!bootstrapName) {
                bootstrapName = getenv(SECURITYSERVER_BOOTSTRAP_ENV);
                if (!bootstrapName)
+               {
                        bootstrapName = SECURITYSERVER_BOOTSTRAP_NAME;
+               }
+               else
+               {
+                       messagingName = bootstrapName;
+               }
        }
-
+       else
+       {
+               messagingName = bootstrapName;
+       }
+       
        // configure logging first
        if (debugMode) {
                Syslog::open(bootstrapName, LOG_AUTHPRIV, LOG_PERROR);
@@ -179,8 +204,7 @@ int main(int argc, char *argv[])
         fprintf(stderr, "You are not allowed to run securityd\n");
         exit(1);
 #else
-        fprintf(stderr, "securityd is unprivileged; some features may not work.\n");
-        secdebug("SS", "Running as user %d (you have been warned)", uid);
+        fprintf(stderr, "securityd is unprivileged (uid=%d); some features may not work.\n", uid);
 #endif //NDEBUG
     }
     
@@ -194,24 +218,22 @@ int main(int argc, char *argv[])
        }
         
     // arm signal handlers; code below may generate signals we want to see
-    if (signal(SIGCHLD, handleSignals) == SIG_ERR)
-        secdebug("SS", "Cannot handle SIGCHLD: errno=%d", errno);
-    if (signal(SIGINT, handleSignals) == SIG_ERR)
-        secdebug("SS", "Cannot handle SIGINT: errno=%d", errno);
-    if (signal(SIGTERM, handleSignals) == SIG_ERR)
-        secdebug("SS", "Cannot handle SIGTERM: errno=%d", errno);
+    if (signal(SIGCHLD, handleSignals) == SIG_ERR
+               || signal(SIGINT, handleSignals) == SIG_ERR
+               || signal(SIGTERM, handleSignals) == SIG_ERR
+               || signal(SIGPIPE, handleSignals) == SIG_ERR
 #if !defined(NDEBUG)
-    if (signal(SIGUSR1, handleSignals) == SIG_ERR)
-        secdebug("SS", "Cannot handle SIGHUP: errno=%d", errno);
+               || signal(SIGUSR1, handleSignals) == SIG_ERR
 #endif //NDEBUG
-       
-       // create a code signing engine
-       CodeSigning::OSXSigner signer;
-       
+               || signal(SIGUSR2, handleSignals) == SIG_ERR) {
+               perror("signal");
+               exit(1);
+       }
+
        // create an Authorization engine
        Authority authority(authorizationConfig);
        
-       // establish the ACL machinery
+       // introduce all supported ACL subject types
        new AnyAclSubject::Maker();
        new PasswordAclSubject::Maker();
     new ProtectedPasswordAclSubject::Maker();
@@ -219,8 +241,8 @@ int main(int argc, char *argv[])
        new ThresholdAclSubject::Maker();
     new CommentAclSubject::Maker();
        new ProcessAclSubject::Maker();
-       new CodeSignatureAclSubject::Maker(signer);
-    new KeychainPromptAclSubject::Maker();
+       new CodeSignatureAclSubject::Maker();
+    new KeychainPromptAclSubject::Maker(keychainAclDefault);
     new PreAuthorizationAcls::OriginMaker();
     new PreAuthorizationAcls::SourceMaker();
        
@@ -238,6 +260,9 @@ int main(int argc, char *argv[])
                server.timeout(workerTimeout);
        if (maxThreads)
                server.maxThreads(maxThreads);
+       server.floatingThread(true);
+       server.waitForClients(waitForClients);
+       server.verbosity(verbose);
     
        // add the RNG seed timer
 # if defined(NDEBUG)
@@ -245,51 +270,27 @@ int main(int argc, char *argv[])
 # else
     if (getuid() == 0) new EntropyManager(server, entropyFile);
 # endif
-       
-       // create a token-cache interface
-#if !defined(NDEBUG)
-       if (const char *s = getenv("TOKENCACHE"))
-               tokenCacheDir = s;
-#endif //NDEBUG
-       TokenCache tokenCache(tokenCacheDir);
 
        // create a smartcard monitor to manage external token devices
-       PCSCMonitor secureCards(server, tokenCache, scOptions(smartCardOptions));
+       gPCSC = new PCSCMonitor(server, tokenCacheDir, scOptions(smartCardOptions));
     
     // create the RootSession object (if -d, give it graphics and tty attributes)
-    RootSession rootSession(server,
-               debugMode ? (sessionHasGraphicAccess | sessionHasTTY) : 0);
+    RootSession rootSession(debugMode ? (sessionHasGraphicAccess | sessionHasTTY) : 0, server);
+       
+       // create a monitor thread to watch for audit session events
+       AuditMonitor audits(gMainServerPort);
+       audits.run();
     
-    // install MDS and initialize the local CSSM
-    server.loadCssm();
+    // install MDS (if needed) and initialize the local CSSM
+    server.loadCssm(mdsIsInstalled);
     
+       // create the shared memory notification hub
+       new SharedMemoryListener(messagingName, kSharedMemoryPoolSize);
+       
        // okay, we're ready to roll
+       SECURITYD_INITIALIZED((char*)bootstrapName);
        Syslog::notice("Entering service");
-       secdebug("SS", "%s initialized", bootstrapName);
-    Debug::trace (kSecTraceSecurityServerInitialized);
     
-       #ifdef PERFORMANCE_MEASUREMENT
-       // needed for automated timing of securityd startup
-       uint64_t endTime = mach_absolute_time ();
-       
-       // compute how long it took to initialize
-       uint64_t elapsedTime = endTime - startTime;
-       mach_timebase_info_data_t multiplier;
-       mach_timebase_info (&multiplier);
-       
-       elapsedTime = elapsedTime * multiplier.numer / multiplier.denom;
-       
-       FILE* f = fopen ("/var/log/startuptime.txt", "a");
-       if (f == NULL)
-       {
-               // probably not running as root.
-               f = fopen ("/tmp/startuptime.txt", "a");
-       }
-       
-       fprintf (f, "%lld\n", elapsedTime);
-       fclose (f);
-       #endif
-
        // go
        server.run();
        
@@ -304,7 +305,7 @@ int main(int argc, char *argv[])
 //
 static void usage(const char *me)
 {
-       fprintf(stderr, "Usage: %s [-dX]"
+       fprintf(stderr, "Usage: %s [-dwX]"
                "\n\t[-a authConfigFile]                    Authorization configuration file"
                "\n\t[-c tokencache]                        smartcard token cache directory"
                "\n\t[-e equivDatabase]                                         path to code equivalence database"
@@ -347,6 +348,7 @@ static PCSCMonitor::ServiceLevel scOptions(const char *optionString)
 //
 static void handleSignals(int sig)
 {
+       SECURITYD_SIGNAL_RECEIVED(sig);
        if (kern_return_t rc = self_client_handleSignal(gMainServerPort, mach_task_self(), sig))
                Syslog::error("self-send failed (mach error %d)", rc);
 }