]> git.saurik.com Git - apple/security.git/blob - SecurityServer/main.cpp
Security-163.tar.gz
[apple/security.git] / SecurityServer / main.cpp
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
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
8 * using this file.
9 *
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.
16 */
17
18
19 //
20 // SecurityServer - Apple security services daemon.
21 //
22 #include "securityserver.h"
23 #include "server.h"
24 #include "entropy.h"
25
26 #include <Security/daemon.h>
27 #include <Security/osxsigner.h>
28 #include "authority.h"
29 #include "session.h"
30
31 #include <unistd.h>
32 #include <Security/machserver.h>
33
34 #include <sys/types.h>
35 #include <sys/wait.h>
36 #include <signal.h>
37
38 #include "ktracecodes.h"
39
40 // ACL subject types (their makers are instantiated here)
41 #include <Security/acl_any.h>
42 #include <Security/acl_password.h>
43 #include <Security/acl_protectedpw.h>
44 #include <Security/acl_threshold.h>
45 #include <Security/acl_codesigning.h>
46 #include <Security/acl_process.h>
47 #include <Security/acl_comment.h>
48 #include "acl_keychain.h"
49
50
51 namespace Security
52 {
53
54 //
55 // Program options (set by argument scan and environment)
56 //
57 uint32 debugMode = 0;
58 const char *bootstrapName = NULL;
59
60 } // end namespace Security
61
62
63 //
64 // Local functions of the main program driver
65 //
66 static void usage(const char *me);
67 static void handleSIGCHLD(int);
68 static void handleSIGOther(int);
69
70
71 //
72 // Main driver
73 //
74 int main(int argc, char *argv[])
75 {
76 Debug::trace (kSecTraceSecurityServerStart);
77
78 // program arguments (preset to defaults)
79 bool forceCssmInit = false;
80 bool reExecute = false;
81 int workerTimeout = 0;
82 int maxThreads = 0;
83 const char *authorizationConfig = "/etc/authorization";
84 const char *entropyFile = "/var/db/SystemEntropyCache";
85 const char *equivDbFile = EQUIVALENCEDBPATH;
86
87 // parse command line arguments
88 extern char *optarg;
89 extern int optind;
90 int arg;
91 while ((arg = getopt(argc, argv, "a:de:E:fN:t:T:X")) != -1) {
92 switch (arg) {
93 case 'a':
94 authorizationConfig = optarg;
95 break;
96 case 'd':
97 debugMode++;
98 break;
99 case 'e':
100 equivDbFile = optarg;
101 break;
102 case 'E':
103 entropyFile = optarg;
104 break;
105 case 'f':
106 forceCssmInit = true;
107 break;
108 case 'N':
109 bootstrapName = optarg;
110 break;
111 case 't':
112 if ((maxThreads = atoi(optarg)) < 0)
113 maxThreads = 0;
114 break;
115 case 'T':
116 if ((workerTimeout = atoi(optarg)) < 0)
117 workerTimeout = 0;
118 break;
119 case 'X':
120 reExecute = true;
121 break;
122 default:
123 usage(argv[0]);
124 }
125 }
126
127 // take no non-option arguments
128 if (optind < argc)
129 usage(argv[0]);
130
131 // figure out the bootstrap name
132 IFDEBUG(if (!bootstrapName) bootstrapName = getenv(SECURITYSERVER_BOOTSTRAP_ENV));
133
134 if (!bootstrapName) {
135 bootstrapName = SECURITYSERVER_BOOTSTRAP_NAME;
136 }
137
138 // configure logging first
139 if (debugMode) {
140 Syslog::open(bootstrapName, LOG_AUTHPRIV, LOG_PERROR);
141 Syslog::notice("SecurityServer started in debug mode");
142 } else {
143 Syslog::open(bootstrapName, LOG_AUTHPRIV, LOG_CONS);
144 }
145
146 // if we're not running as root in production mode, fail
147 // in debug mode, issue a warning
148 if (uid_t uid = getuid()) {
149 #if defined(NDEBUG)
150 Syslog::alert("Tried to run SecurityServer as user %d: aborted", uid);
151 fprintf(stderr, "You are not allowed to run SecurityServer\n");
152 exit(1);
153 #else
154 fprintf(stderr, "SecurityServer is unprivileged; some features may not work.\n");
155 secdebug("SS", "Running as user %d (you have been warned)", uid);
156 #endif //NDEBUG
157 }
158
159 // turn into a properly diabolical daemon unless debugMode is on
160 if (!debugMode) {
161 if (!Daemon::incarnate())
162 exit(1); // can't daemonize
163
164 if (reExecute && !Daemon::executeSelf(argv))
165 exit(1); // can't self-execute
166 }
167
168 // create a code signing engine
169 CodeSigning::OSXSigner signer;
170
171 // create an Authorization engine
172 Authority authority(authorizationConfig);
173
174 // establish the ACL machinery
175 new AnyAclSubject::Maker();
176 new PasswordAclSubject::Maker();
177 new ProtectedPasswordAclSubject::Maker();
178 new ThresholdAclSubject::Maker();
179 new CommentAclSubject::Maker();
180 new ProcessAclSubject::Maker();
181 new CodeSignatureAclSubject::Maker(signer);
182 new KeychainPromptAclSubject::Maker();
183
184 // add a temporary registration for a subject type that went out in 10.2 seed 1
185 // this should probably be removed for the next major release >10.2
186 new KeychainPromptAclSubject::Maker(CSSM_WORDID__RESERVED_1);
187
188 // establish the code equivalents database
189 CodeSignatures codeSignatures(equivDbFile);
190
191 // create the main server object and register it
192 Server server(authority, codeSignatures, bootstrapName);
193
194 // set server configuration from arguments, if specified
195 if (workerTimeout)
196 server.timeout(workerTimeout);
197 if (maxThreads)
198 server.maxThreads(maxThreads);
199
200 // add the RNG seed timer to it
201 # if defined(NDEBUG)
202 EntropyManager entropy(server, entropyFile);
203 # else
204 if (!getuid()) new EntropyManager(server, entropyFile);
205 # endif
206
207 // create the RootSession object (if -d, give it graphics and tty attributes)
208 RootSession rootSession(server.primaryServicePort(),
209 debugMode ? (sessionHasGraphicAccess | sessionHasTTY) : 0);
210
211 // set up signal handlers
212 if (signal(SIGCHLD, handleSIGCHLD) == SIG_ERR)
213 secdebug("SS", "Cannot ignore SIGCHLD: errno=%d", errno);
214 if (signal(SIGINT, handleSIGOther) == SIG_ERR)
215 secdebug("SS", "Cannot handle SIGINT: errno=%d", errno);
216 if (signal(SIGTERM, handleSIGOther) == SIG_ERR)
217 secdebug("SS", "Cannot handle SIGTERM: errno=%d", errno);
218
219 // initialize CSSM now if requested
220 if (forceCssmInit)
221 server.loadCssm();
222
223 Syslog::notice("Entering service");
224 secdebug("SS", "%s initialized", bootstrapName);
225
226 Debug::trace (kSecTraceSecurityServerStart);
227
228 server.run();
229
230 // fell out of runloop (should not happen)
231 Syslog::alert("Aborting");
232 return 1;
233 }
234
235
236 //
237 // Issue usage message and die
238 //
239 static void usage(const char *me)
240 {
241 fprintf(stderr, "Usage: %s [-df] [-t maxthreads] [-T threadTimeout]"
242 "\t[-N bootstrapName] [-a authConfigFile]\n", me);
243 exit(2);
244 }
245
246
247 //
248 // Handle SIGCHLD signals to reap our children (zombie cleanup)
249 //
250 static void handleSIGCHLD(int)
251 {
252 int status;
253 pid_t pid = waitpid(-1, &status, WNOHANG);
254 switch (pid) {
255 case 0:
256 //secdebug("SS", "Spurious SIGCHLD ignored");
257 return;
258 case -1:
259 //secdebug("SS", "waitpid after SIGCHLD failed: errno=%d", errno);
260 return;
261 default:
262 //secdebug("SS", "Reaping child pid=%d", pid);
263 return;
264 }
265 }
266
267
268 //
269 // Handle some other signals to shut down cleanly (and with logging)
270 //
271 static void handleSIGOther(int sig)
272 {
273 switch (sig) {
274 case SIGINT:
275 //secdebug("SS", "Interrupt signal; terminating");
276 Syslog::notice("received interrupt signal; terminating");
277 exit(0);
278 case SIGTERM:
279 //secdebug("SS", "Termination signal; terminating");
280 Syslog::notice("received termination signal; terminating");
281 exit(0);
282 }
283 }