]>
git.saurik.com Git - apple/security.git/blob - SecurityServer/main.cpp
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
20 // SecurityServer - Apple security services daemon.
22 #include "securityserver.h"
26 #include <Security/daemon.h>
27 #include <Security/osxsigner.h>
28 #include "authority.h"
32 #include <Security/machserver.h>
34 #include <sys/types.h>
38 // ACL subject types (their makers are instantiated here)
39 #include <Security/acl_any.h>
40 #include <Security/acl_password.h>
41 #include <Security/acl_protectedpw.h>
42 #include <Security/acl_threshold.h>
43 #include <Security/acl_codesigning.h>
44 #include <Security/acl_comment.h>
45 #include "acl_keychain.h"
52 // Program options (set by argument scan and environment)
56 } // end namespace Security
60 // Local functions of the main program driver
62 static void usage(const char *me
);
63 static void handleSIGCHLD(int);
64 static void handleSIGOther(int);
70 int main(int argc
, char *argv
[])
72 // program arguments (preset to defaults)
73 bool forceCssmInit
= false;
74 bool reExecute
= false;
75 int workerTimeout
= 0;
77 const char *authorizationConfig
= "/etc/authorization";
78 const char *bootstrapName
= "SecurityServer";
79 const char *entropyFile
= "/var/db/SystemEntropyCache";
81 // parse command line arguments
85 while ((arg
= getopt(argc
, argv
, "a:dEfN:t:T:X")) != -1) {
88 authorizationConfig
= optarg
;
100 bootstrapName
= optarg
;
103 if ((maxThreads
= atoi(optarg
)) < 0)
107 if ((workerTimeout
= atoi(optarg
)) < 0)
118 // take no non-option arguments
122 // configure logging first
124 Syslog::open(argv
[0], LOG_AUTHPRIV
, LOG_PERROR
);
125 Syslog::notice("SecurityServer started in debug mode");
127 Syslog::open(argv
[0], LOG_AUTHPRIV
, LOG_CONS
);
130 // if we're not running as root in production mode, fail
131 // in debug mode, issue a warning
132 if (uid_t uid
= getuid()) {
134 Syslog::alert("Tried to run SecurityServer as user %d: aborted", uid
);
135 fprintf(stderr
, "You are not allowed to run SecurityServer\n");
138 fprintf(stderr
, "SecurityServer is unprivileged; some features may not work.\n");
139 debug("SS", "Running as user %d (you have been warned)", uid
);
143 // turn into a properly diabolical daemon unless debugMode is on
145 if (!Daemon::incarnate())
146 exit(1); // can't daemonize
148 if (reExecute
&& !Daemon::executeSelf(argv
))
149 exit(1); // can't self-execute
152 // create a code signing engine
153 CodeSigning::OSXSigner signer
;
155 // create an Authorization engine
156 Authority
authority(authorizationConfig
);
158 // establish the ACL machinery
159 new AnyAclSubject::Maker();
160 new PasswordAclSubject::Maker();
161 new ProtectedPasswordAclSubject::Maker();
162 new ThresholdAclSubject::Maker();
163 new CommentAclSubject::Maker();
164 new CodeSignatureAclSubject::Maker(signer
);
165 new KeychainPromptAclSubject::Maker();
167 // add a temporary registration for a subject type that went out in 10.2 seed 1
168 // this should probably be removed for the next major release >10.2
169 new KeychainPromptAclSubject::Maker(CSSM_WORDID__RESERVED_1
);
171 // create the main server object and register it
172 Server
server(authority
, bootstrapName
);
174 // create the RootSession object (if -d, give it graphics and tty attributes)
175 RootSession
rootSession(server
.primaryServicePort(),
176 debugMode
? (sessionHasGraphicAccess
| sessionHasTTY
) : 0);
178 // set server configuration from arguments, if specified
180 server
.timeout(workerTimeout
);
182 server
.maxThreads(maxThreads
);
184 // add the RNG seed timer to it
186 EntropyManager
entropy(server
, entropyFile
);
188 if (!getuid()) new EntropyManager(server
, entropyFile
);
191 // set up signal handlers
192 if (signal(SIGCHLD
, handleSIGCHLD
) == SIG_ERR
)
193 debug("SS", "Cannot ignore SIGCHLD: errno=%d", errno
);
194 if (signal(SIGINT
, handleSIGOther
) == SIG_ERR
)
195 debug("SS", "Cannot handle SIGINT: errno=%d", errno
);
196 if (signal(SIGTERM
, handleSIGOther
) == SIG_ERR
)
197 debug("SS", "Cannot handle SIGTERM: errno=%d", errno
);
199 // initialize CSSM now if requested
203 Syslog::notice("Entering service");
204 debug("SS", "Entering service run loop");
207 // fell out of runloop (should not happen)
208 Syslog::alert("Aborting");
214 // Issue usage message and die
216 static void usage(const char *me
)
218 fprintf(stderr
, "Usage: %s [-df] [-t maxthreads] [-T threadTimeout]"
219 "\t[-N bootstrapName] [-a authConfigFile]\n", me
);
225 // Handle SIGCHLD signals to reap our children (zombie cleanup)
227 static void handleSIGCHLD(int)
230 switch (pid_t pid
= waitpid(-1, &status
, WNOHANG
)) {
232 debug("SS", "Spurious SIGCHLD ignored");
235 debug("SS", "waitpid after SIGCHLD failed: errno=%d", errno
);
238 debug("SS", "Reaping child pid=%d", pid
);
245 // Handle some other signals to shut down cleanly (and with logging)
247 static void handleSIGOther(int sig
)
251 debug("SS", "Interrupt signal; terminating");
252 Syslog::notice("received interrupt signal; terminating");
255 debug("SS", "Termination signal; terminating");
256 Syslog::notice("received termination signal; terminating");