]>
Commit | Line | Data |
---|---|---|
f163b202 SB |
1 | /********************************************************************************/ |
2 | /* */ | |
3 | /* TPM Main Program */ | |
4 | /* Written by Ken Goldman, Stefan Berger */ | |
5 | /* IBM Thomas J. Watson Research Center */ | |
6 | /* */ | |
869df69f | 7 | /* (c) Copyright IBM Corporation 2006, 2010, 2016, 2019. */ |
f163b202 SB |
8 | /* */ |
9 | /* All rights reserved. */ | |
10 | /* */ | |
11 | /* Redistribution and use in source and binary forms, with or without */ | |
12 | /* modification, are permitted provided that the following conditions are */ | |
13 | /* met: */ | |
14 | /* */ | |
15 | /* Redistributions of source code must retain the above copyright notice, */ | |
16 | /* this list of conditions and the following disclaimer. */ | |
17 | /* */ | |
18 | /* Redistributions in binary form must reproduce the above copyright */ | |
19 | /* notice, this list of conditions and the following disclaimer in the */ | |
20 | /* documentation and/or other materials provided with the distribution. */ | |
21 | /* */ | |
22 | /* Neither the names of the IBM Corporation nor the names of its */ | |
23 | /* contributors may be used to endorse or promote products derived from */ | |
24 | /* this software without specific prior written permission. */ | |
25 | /* */ | |
26 | /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ | |
27 | /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ | |
28 | /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ | |
29 | /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ | |
30 | /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ | |
31 | /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ | |
32 | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ | |
33 | /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ | |
34 | /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ | |
35 | /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ | |
36 | /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |
37 | /********************************************************************************/ | |
38 | ||
39 | #include <config.h> | |
40 | ||
41 | #include <stdlib.h> | |
42 | #include <stdio.h> | |
43 | #include <string.h> | |
44 | #include <time.h> | |
f163b202 SB |
45 | #include <getopt.h> |
46 | #include <errno.h> | |
47 | #include <poll.h> | |
48 | #include <sys/stat.h> | |
804e7472 | 49 | #include <stdbool.h> |
87d56f93 AV |
50 | #include <sys/types.h> |
51 | #include <sys/socket.h> | |
f163b202 SB |
52 | |
53 | #include <libtpms/tpm_error.h> | |
54 | #include <libtpms/tpm_library.h> | |
55 | #include <libtpms/tpm_memory.h> | |
56 | ||
57 | #include "main.h" | |
58 | #include "swtpm_debug.h" | |
59 | #include "swtpm_io.h" | |
2d3deaef | 60 | #include "swtpm_nvstore.h" |
4716d35a | 61 | #include "server.h" |
f163b202 SB |
62 | #include "common.h" |
63 | #include "logging.h" | |
b2151737 | 64 | #include "pidfile.h" |
1bebb6be SB |
65 | #include "tpmlib.h" |
66 | #include "utils.h" | |
b959335e | 67 | #include "mainloop.h" |
298d1782 | 68 | #include "ctrlchannel.h" |
fc36ef35 | 69 | #include "tpmstate.h" |
af23737e | 70 | #include "sys_dependencies.h" |
98d1d126 | 71 | #include "daemonize.h" |
07dfd958 | 72 | #include "seccomp_profile.h" |
11114ba7 SB |
73 | #include "options.h" |
74 | #include "capabilities.h" | |
f163b202 SB |
75 | |
76 | /* local variables */ | |
27a3c239 | 77 | static int notify_fd[2] = {-1, -1}; |
f163b202 | 78 | |
27a3c239 | 79 | static struct libtpms_callbacks callbacks = { |
f163b202 SB |
80 | .sizeOfStruct = sizeof(struct libtpms_callbacks), |
81 | .tpm_nvram_init = SWTPM_NVRAM_Init, | |
82 | .tpm_nvram_loaddata = SWTPM_NVRAM_LoadData, | |
83 | .tpm_nvram_storedata = SWTPM_NVRAM_StoreData, | |
84 | .tpm_nvram_deletename = SWTPM_NVRAM_DeleteName, | |
85 | .tpm_io_init = SWTPM_IO_Init, | |
f56a0cd2 | 86 | .tpm_io_getlocality = mainloop_cb_get_locality, |
f163b202 SB |
87 | }; |
88 | ||
1bebb6be SB |
89 | static void sigterm_handler(int sig __attribute__((unused))) |
90 | { | |
91 | TPM_DEBUG("Terminating...\n"); | |
92 | if (write(notify_fd[1], "T", 1) < 0) { | |
93 | logprintf(STDERR_FILENO, "Error: sigterm notification failed: %s\n", | |
94 | strerror(errno)); | |
95 | } | |
b959335e | 96 | mainloop_terminate = true; |
f163b202 SB |
97 | } |
98 | ||
f163b202 SB |
99 | static void usage(FILE *file, const char *prgname, const char *iface) |
100 | { | |
101 | fprintf(file, | |
102 | "Usage: %s %s [options]\n" | |
103 | "\n" | |
104 | "The following options are supported:\n" | |
105 | "\n" | |
106 | "-p|--port <port> : use the given port\n" | |
f163b202 SB |
107 | "-f|--fd <fd> : use the given socket file descriptor\n" |
108 | "-t|--terminate : terminate the TPM once a connection has been lost\n" | |
109 | "-d|--daemon : daemonize the TPM\n" | |
f34e01a5 | 110 | "--ctrl type=[unixio|tcp][,path=<path>][,port=<port>[,bindaddr=address[,ifname=ifname]]][,fd=<filedescriptor>|clientfd=<filedescriptor>][,mode=0...][,uid=uid][,gid=gid]\n" |
9ddc6998 SB |
111 | " : TPM control channel using either UnixIO or TCP sockets;\n" |
112 | " the path is only valid for Unixio channels; the port must\n" | |
113 | " be given in case the type is TCP; the TCP socket is bound\n" | |
16eb0ff2 | 114 | " to 127.0.0.1 by default and other bind addresses can be\n" |
93edca48 AV |
115 | " given with the bindaddr parameter; if fd is provided,\n" |
116 | " it will be treated as a server socket and used for \n" | |
117 | " accepting client connections; if clientfd is provided,\n" | |
118 | " it will be treaded as client connection;\n" | |
119 | " NOTE: fd and clientfd are mutually exclusive and clientfd\n" | |
120 | " is only valid for UnixIO channels\n" | |
2bc601bb | 121 | " mode allows a user to set the file mode bits of a Unixio socket;\n" |
682fe581 | 122 | " the value must be given in octal number format\n" |
f34e01a5 | 123 | " uid and gid set the ownership of the Unixio socket's file;\n" |
1ed09c03 | 124 | "--migration-key file=<path>|fd=<fd>[,mode=aes-cbc|aes-256-cbc][,format=hex|binary][,remove=[true|false]]\n" |
84259c17 SB |
125 | " : use an AES key for the encryption of the TPM's state\n" |
126 | " when it is retrieved from the TPM via ioctls;\n" | |
127 | " Setting this key ensures that the TPM's state will always\n" | |
128 | " be encrypted when migrated\n" | |
26933af5 | 129 | "--migration-key pwdfile=<path>|pwdfd=<fd>[,mode=aes-cbc|aes-256-cbc][,remove=[true|false]][,kdf=sha512|pbkdf2]\n" |
84259c17 | 130 | " : provide a passphrase in a file; the AES key will be\n" |
bf5220cf | 131 | " derived from this passphrase; default kdf is PBKDF2\n" |
3760c342 | 132 | "--log file=<path>|fd=<filedescriptor>[,level=n][,prefix=<prefix>][,truncate]\n" |
bc525ccd SB |
133 | " : write the TPM's log into the given file rather than\n" |
134 | " to the console; provide '-' for path to avoid logging\n" | |
93f4a389 | 135 | " log level 5 and higher will enable libtpms logging;\n" |
3760c342 SB |
136 | " all logged output will be prefixed with prefix;\n" |
137 | " the log file can be reset (truncate)\n" | |
1ed09c03 | 138 | "--key file=<path>|fd=<fd>[,mode=aes-cbc|aes-256-cbc][,format=hex|binary][,remove=[true|false]]\n" |
f163b202 SB |
139 | " : use an AES key for the encryption of the TPM's state\n" |
140 | " files; use the given mode for the block encryption;\n" | |
141 | " the key is to be provided as a hex string or in binary\n" | |
142 | " format; the keyfile can be automatically removed using\n" | |
143 | " the remove parameter\n" | |
1253088f | 144 | "--key pwdfile=<path>|pwdfd=<fd>[,mode=aes-cbc|aes-256-cbc][,remove=[true|false]][,kdf=sha512|pbkdf2]\n" |
bc525ccd | 145 | " : provide a passphrase in a file; the AES key will be\n" |
bf5220cf | 146 | " derived from this passphrase; default kdf is PBKDF2\n" |
3b563487 | 147 | "--locality [reject-locality-4][,allow-set-locality]\n" |
4a565414 | 148 | " : reject-locality-4: reject any command in locality 4\n" |
3b563487 | 149 | " allow-set-locality: accept SetLocality command\n" |
db608775 | 150 | "--pid file=<path>|fd=<filedescriptor>\n" |
bc525ccd | 151 | " : write the process ID into the given file\n" |
b82eb7e7 ET |
152 | "--tpmstate dir=<dir>[,mode=0...]|backend-uri=<uri>\n" |
153 | " : set the directory or uri where the TPM's state will be written\n" | |
bc525ccd | 154 | " into; the TPM_PATH environment variable can be used\n" |
b82eb7e7 | 155 | " instead dir option;\n" |
2bc601bb | 156 | " mode allows a user to set the file mode bits of the state files;\n" |
640f1fab | 157 | " the default mode is 0640;\n" |
8047b5d6 | 158 | "--server [type=tcp][,port=port[,bindaddr=address[,ifname=ifname]]][,fd=fd][,disconnect]\n" |
7c0a033f SB |
159 | " : Expect TCP connections on the given port;\n" |
160 | " if fd is provided, packets will be read from it directly;\n" | |
161 | " the disconnect parameter closes the connection after\n" | |
16eb0ff2 SB |
162 | " sending a response back to the client; the TCP socket is\n" |
163 | " bound to 127.0.0.1 by default and other bind addresses\n" | |
164 | " can be given with the bindaddr parameter\n" | |
f34e01a5 | 165 | "--server type=unixio[,path=path][,fd=fd][,mode=0...][,uid=uid][,gid=gid]\n" |
73823529 | 166 | " : Expect UnixIO connections on the given path; if fd is\n" |
e6bc4bdf | 167 | " provided, packets will be read from it directly;\n" |
2bc601bb | 168 | " mode allows a user to set the file mode bits of the socket; the\n" |
682fe581 | 169 | " value must be given in octal number format;\n" |
f34e01a5 | 170 | " uid and gid set the ownership of the Unixio socket's file;\n" |
97e910af | 171 | "--flags [not-need-init][,startup-clear|startup-state|startup-deactivated|startup-none][,disable-auto-shutdown]\n" |
63ab6c3c SB |
172 | " : not-need-init: commands can be sent without needing to\n" |
173 | " send an INIT via control channel;\n" | |
e6bc4bdf | 174 | " startup-...: send Startup command with this type;\n" |
97e910af SB |
175 | " disable-auto-shutdown disables automatic sending of\n" |
176 | " TPM2_Shutdown before TPM 2 reset or swtpm termination;\n" | |
bb420d74 | 177 | "-r|--runas <user>: change to the given user\n" |
68e54284 JH |
178 | "-R|--chroot <path>\n" |
179 | " : chroot to the given directory at startup\n" | |
fbc596ab | 180 | "--tpm2 : choose TPM2 functionality\n" |
07dfd958 SB |
181 | #ifdef WITH_SECCOMP |
182 | # ifndef SCMP_ACT_LOG | |
183 | "--seccomp action=none|kill\n" | |
184 | # else | |
185 | "--seccomp action=none|kill|log\n" | |
186 | # endif | |
187 | " : Choose the action of the seccomp profile when a\n" | |
188 | " blacklisted syscall is executed; default is kill\n" | |
189 | #endif | |
11114ba7 SB |
190 | "--print-capabilites\n" |
191 | " : print capabilities and terminate\n" | |
5bc59a74 ET |
192 | "--print-states\n" |
193 | " : print existing TPM states and terminate\n" | |
f163b202 SB |
194 | "-h|--help : display this help screen and terminate\n" |
195 | "\n", | |
196 | prgname, iface); | |
197 | } | |
198 | ||
321a22cc SB |
199 | static void swtpm_cleanup(struct ctrlchannel *cc, struct server *server) |
200 | { | |
201 | pidfile_remove(); | |
202 | ctrlchannel_free(cc); | |
203 | server_free(server); | |
204 | log_global_free(); | |
fc36ef35 | 205 | tpmstate_global_free(); |
8f57999d | 206 | SWTPM_NVRAM_Shutdown(); |
321a22cc SB |
207 | } |
208 | ||
f163b202 SB |
209 | int swtpm_main(int argc, char **argv, const char *prgname, const char *iface) |
210 | { | |
211 | TPM_RESULT rc = 0; | |
212 | int daemonize = FALSE; | |
11114ba7 | 213 | int opt, longindex, ret; |
f163b202 SB |
214 | struct stat statbuf; |
215 | struct mainLoopParams mlp = { | |
510f1848 | 216 | .cc = NULL, |
f163b202 | 217 | .flags = 0, |
7c0a033f | 218 | .fd = -1, |
4a565414 | 219 | .locality_flags = 0, |
32694853 | 220 | .tpmversion = TPMLIB_TPM_VERSION_1_2, |
e6bc4bdf | 221 | .startupType = _TPM_ST_NONE, |
75fbda26 | 222 | .lastCommand = TPM_ORDINAL_NONE, |
97e910af | 223 | .disable_auto_shutdown = false, |
f163b202 | 224 | }; |
4716d35a | 225 | struct server *server = NULL; |
f163b202 SB |
226 | unsigned long val; |
227 | char *end_ptr; | |
228 | char buf[20]; | |
229 | char *keydata = NULL; | |
84259c17 | 230 | char *migkeydata = NULL; |
f163b202 | 231 | char *logdata = NULL; |
b2151737 | 232 | char *piddata = NULL; |
4a565414 | 233 | char *localitydata = NULL; |
bc525ccd | 234 | char *tpmstatedata = NULL; |
9ddc6998 | 235 | char *ctrlchdata = NULL; |
4716d35a | 236 | char *serverdata = NULL; |
63ab6c3c | 237 | char *flagsdata = NULL; |
07dfd958 | 238 | char *seccompdata = NULL; |
bb420d74 | 239 | char *runas = NULL; |
68e54284 | 240 | char *chroot = NULL; |
63ab6c3c | 241 | bool need_init_cmd = true; |
f163b202 SB |
242 | #ifdef DEBUG |
243 | time_t start_time; | |
244 | #endif | |
07dfd958 | 245 | unsigned int seccomp_action; |
3a3a9f5b | 246 | bool printcapabilities = false; |
5bc59a74 | 247 | bool printstates = false; |
f163b202 SB |
248 | static struct option longopts[] = { |
249 | {"daemon" , no_argument, 0, 'd'}, | |
250 | {"help" , no_argument, 0, 'h'}, | |
251 | {"port" , required_argument, 0, 'p'}, | |
f163b202 | 252 | {"fd" , required_argument, 0, 'f'}, |
93edca48 | 253 | {"server" , required_argument, 0, 'c'}, |
bb420d74 | 254 | {"runas" , required_argument, 0, 'r'}, |
68e54284 | 255 | {"chroot" , required_argument, 0, 'R'}, |
f163b202 | 256 | {"terminate" , no_argument, 0, 't'}, |
4a565414 | 257 | {"locality" , required_argument, 0, 'L'}, |
f163b202 SB |
258 | {"log" , required_argument, 0, 'l'}, |
259 | {"key" , required_argument, 0, 'k'}, | |
84259c17 | 260 | {"migration-key", required_argument, 0, 'K'}, |
b2151737 | 261 | {"pid" , required_argument, 0, 'P'}, |
bc525ccd | 262 | {"tpmstate" , required_argument, 0, 's'}, |
9ddc6998 | 263 | {"ctrl" , required_argument, 0, 'C'}, |
63ab6c3c | 264 | {"flags" , required_argument, 0, 'F'}, |
fbc596ab | 265 | {"tpm2" , no_argument, 0, '2'}, |
07dfd958 SB |
266 | #ifdef WITH_SECCOMP |
267 | {"seccomp" , required_argument, 0, 'S'}, | |
268 | #endif | |
11114ba7 SB |
269 | {"print-capabilities" |
270 | , no_argument, 0, 'a'}, | |
5bc59a74 | 271 | {"print-states", no_argument, 0, 'e'}, |
f163b202 SB |
272 | {NULL , 0 , 0, 0 }, |
273 | }; | |
274 | ||
cba81569 SB |
275 | log_set_prefix("swtpm: "); |
276 | ||
f163b202 | 277 | while (TRUE) { |
68e54284 | 278 | opt = getopt_long(argc, argv, "dhp:f:tr:R:", longopts, &longindex); |
f163b202 SB |
279 | |
280 | if (opt == -1) | |
281 | break; | |
282 | ||
283 | switch (opt) { | |
284 | case 'd': | |
285 | daemonize = TRUE; | |
98d1d126 NW |
286 | if (daemonize_prep() == -1) { |
287 | logprintf(STDERR_FILENO, | |
288 | "Could not prepare to daemonize: %s\n", strerror(errno)); | |
289 | exit(EXIT_FAILURE); | |
290 | } | |
f163b202 SB |
291 | break; |
292 | ||
293 | case 'p': | |
6fc8fb9f | 294 | errno = 0; |
f163b202 SB |
295 | val = strtoul(optarg, &end_ptr, 0); |
296 | if (val != (unsigned int)val || errno || end_ptr[0] != '\0') { | |
cba81569 SB |
297 | logprintf(STDERR_FILENO, |
298 | "Cannot parse socket port number '%s'.\n", | |
299 | optarg); | |
4fd2d23b | 300 | exit(EXIT_FAILURE); |
f163b202 SB |
301 | } |
302 | if (val >= 0x10000) { | |
cba81569 | 303 | logprintf(STDERR_FILENO, "Port is outside valid range.\n"); |
4fd2d23b | 304 | exit(EXIT_FAILURE); |
f163b202 SB |
305 | } |
306 | snprintf(buf, sizeof(buf), "%lu", val); | |
307 | if (setenv("TPM_PORT", buf, 1) != 0) { | |
cba81569 SB |
308 | logprintf(STDERR_FILENO, |
309 | "Could not set port: %s\n", strerror(errno)); | |
4fd2d23b | 310 | exit(EXIT_FAILURE); |
f163b202 | 311 | } |
c310f1d7 | 312 | serverdata = "type=tcp,disconnect"; |
f163b202 SB |
313 | break; |
314 | ||
f163b202 | 315 | case 'f': |
3f37cc3e | 316 | errno = 0; |
f163b202 SB |
317 | val = strtoul(optarg, &end_ptr, 10); |
318 | if (val != (unsigned int)val || errno || end_ptr[0] != '\0') { | |
cba81569 SB |
319 | logprintf(STDERR_FILENO, |
320 | "Cannot parse socket file descriptor.\n"); | |
4fd2d23b | 321 | exit(EXIT_FAILURE); |
f163b202 SB |
322 | } |
323 | mlp.fd = val; | |
324 | if (fstat(mlp.fd, &statbuf) != 0) { | |
cba81569 SB |
325 | logprintf(STDERR_FILENO, "Cannot stat file descriptor: %s\n", |
326 | strerror(errno)); | |
4fd2d23b | 327 | exit(EXIT_FAILURE); |
f163b202 | 328 | } |
1e029685 SB |
329 | /* |
330 | * test for wrong file types; anonymous fd's do not seem to be any of the wrong | |
331 | * ones but are also not character devices | |
332 | */ | |
b20eafa7 SB |
333 | if (S_ISREG(statbuf.st_mode) || S_ISDIR(statbuf.st_mode) || |
334 | S_ISBLK(statbuf.st_mode) || S_ISLNK(statbuf.st_mode)) { | |
cba81569 SB |
335 | logprintf(STDERR_FILENO, |
336 | "Given file descriptor type is not supported.\n"); | |
4fd2d23b | 337 | exit(EXIT_FAILURE); |
f163b202 | 338 | } |
0a0885cf AV |
339 | mlp.flags |= MAIN_LOOP_FLAG_TERMINATE | MAIN_LOOP_FLAG_USE_FD | |
340 | MAIN_LOOP_FLAG_KEEP_CONNECTION; | |
87d56f93 | 341 | |
f163b202 SB |
342 | SWTPM_IO_SetSocketFD(mlp.fd); |
343 | ||
344 | break; | |
345 | ||
7c0a033f | 346 | case 'c': |
4716d35a | 347 | serverdata = optarg; |
7c0a033f SB |
348 | break; |
349 | ||
f163b202 SB |
350 | case 't': |
351 | mlp.flags |= MAIN_LOOP_FLAG_TERMINATE; | |
352 | break; | |
353 | ||
354 | case 'k': | |
355 | keydata = optarg; | |
356 | break; | |
357 | ||
84259c17 SB |
358 | case 'K': |
359 | migkeydata = optarg; | |
360 | break; | |
361 | ||
f163b202 SB |
362 | case 'l': |
363 | logdata = optarg; | |
364 | break; | |
365 | ||
b2151737 SB |
366 | case 'P': |
367 | piddata = optarg; | |
368 | break; | |
369 | ||
bc525ccd SB |
370 | case 's': |
371 | tpmstatedata = optarg; | |
372 | break; | |
373 | ||
9ddc6998 SB |
374 | case 'C': |
375 | ctrlchdata = optarg; | |
376 | break; | |
377 | ||
4a565414 SB |
378 | case 'L': |
379 | localitydata = optarg; | |
380 | break; | |
381 | ||
63ab6c3c SB |
382 | case 'F': |
383 | flagsdata = optarg; | |
384 | break; | |
385 | ||
fbc596ab | 386 | case '2': |
32694853 | 387 | mlp.tpmversion = TPMLIB_TPM_VERSION_2; |
fbc596ab SB |
388 | break; |
389 | ||
f163b202 SB |
390 | case 'h': |
391 | usage(stdout, prgname, iface); | |
392 | exit(EXIT_SUCCESS); | |
393 | ||
11114ba7 | 394 | case 'a': |
3a3a9f5b SB |
395 | printcapabilities = true; |
396 | break; | |
11114ba7 | 397 | |
5bc59a74 ET |
398 | case 'e': |
399 | printstates = true; | |
400 | break; | |
401 | ||
bb420d74 SB |
402 | case 'r': |
403 | runas = optarg; | |
404 | break; | |
405 | ||
68e54284 JH |
406 | case 'R': |
407 | chroot = optarg; | |
408 | break; | |
409 | ||
07dfd958 SB |
410 | case 'S': |
411 | seccompdata = optarg; | |
412 | break; | |
413 | ||
f163b202 SB |
414 | default: |
415 | usage(stderr, prgname, iface); | |
416 | exit(EXIT_FAILURE); | |
417 | } | |
418 | } | |
419 | ||
f1766b31 SB |
420 | if (optind < argc) { |
421 | logprintf(STDERR_FILENO, | |
422 | "Unknown parameter '%s'\n", argv[optind]); | |
4fd2d23b | 423 | exit(EXIT_FAILURE); |
f1766b31 SB |
424 | } |
425 | ||
68e54284 JH |
426 | if (chroot) { |
427 | if (do_chroot(chroot) < 0) | |
428 | exit(EXIT_FAILURE); | |
429 | } | |
430 | ||
15ff0d96 ET |
431 | /* change process ownership before accessing files */ |
432 | if (runas) { | |
433 | if (change_process_owner(runas) < 0) | |
434 | exit(EXIT_FAILURE); | |
435 | } | |
436 | ||
437 | if (handle_log_options(logdata) < 0) | |
438 | exit(EXIT_FAILURE); | |
439 | ||
83764896 SB |
440 | if (mlp.fd >= 0 && mlp.fd < 3) { |
441 | /* no std{in,out,err} */ | |
442 | logprintf(STDERR_FILENO, | |
443 | "Error: Cannot accept file descriptors with values 0, 1, or 2\n"); | |
4fd2d23b | 444 | exit(EXIT_FAILURE); |
83764896 SB |
445 | } |
446 | ||
ccaf99f1 MAL |
447 | if (printcapabilities) { |
448 | /* | |
449 | * Choose the TPM version so that getting/setting buffer size works. | |
450 | * Ignore failure, for backward compatibility when TPM 1.2 is disabled. | |
451 | */ | |
bf3f5175 | 452 | ret = capabilities_print_json(false, mlp.tpmversion); |
ccaf99f1 MAL |
453 | exit(ret ? EXIT_FAILURE : EXIT_SUCCESS); |
454 | } | |
455 | ||
6d1a7abb | 456 | if (tpmlib_choose_tpm_version(mlp.tpmversion) != TPM_SUCCESS) |
4fd2d23b | 457 | exit(EXIT_FAILURE); |
fbc596ab | 458 | |
f34e01a5 SB |
459 | if (handle_ctrlchannel_options(ctrlchdata, &mlp.cc) < 0 || |
460 | handle_server_options(serverdata, &server) < 0) { | |
461 | goto exit_failure; | |
462 | } | |
463 | ||
2d3deaef | 464 | tpmstate_set_version(mlp.tpmversion); |
fbc596ab | 465 | |
5bc59a74 ET |
466 | if (printstates) { |
467 | if (handle_tpmstate_options(tpmstatedata) < 0) | |
468 | goto exit_failure; | |
469 | if (tpmstatedata == NULL) { | |
470 | logprintf(STDERR_FILENO, | |
471 | "Error: --tpmstate option is required for --print-states\n"); | |
472 | goto exit_failure; | |
473 | } | |
89f25f91 | 474 | ret = SWTPM_NVRAM_PrintJson(); |
5bc59a74 ET |
475 | if (ret == 0) |
476 | goto exit_success; | |
477 | else | |
478 | goto exit_failure; | |
479 | } | |
480 | ||
15ff0d96 | 481 | if (handle_key_options(keydata) < 0 || |
84259c17 | 482 | handle_migration_key_options(migkeydata) < 0 || |
bc525ccd | 483 | handle_pid_options(piddata) < 0 || |
4a565414 | 484 | handle_locality_options(localitydata, &mlp.locality_flags) < 0 || |
7c0a033f | 485 | handle_tpmstate_options(tpmstatedata) < 0 || |
07dfd958 | 486 | handle_seccomp_options(seccompdata, &seccomp_action) < 0 || |
e6bc4bdf | 487 | handle_flags_options(flagsdata, &need_init_cmd, |
97e910af | 488 | &mlp.startupType, &mlp.disable_auto_shutdown) < 0) { |
510f1848 SB |
489 | goto exit_failure; |
490 | } | |
f163b202 | 491 | |
4716d35a SB |
492 | if (server) { |
493 | if (server_get_fd(server) >= 0) { | |
75f9f0d3 | 494 | mlp.fd = server_set_fd(server, -1); |
7c0a033f SB |
495 | SWTPM_IO_SetSocketFD(mlp.fd); |
496 | } | |
497 | ||
498 | mlp.flags |= MAIN_LOOP_FLAG_KEEP_CONNECTION; | |
4716d35a | 499 | if ((server_get_flags(server) & SERVER_FLAG_DISCONNECT)) |
c2d04f53 | 500 | mlp.flags &= ~MAIN_LOOP_FLAG_KEEP_CONNECTION; |
7c0a033f | 501 | |
4716d35a | 502 | if ((server_get_flags(server) & SERVER_FLAG_FD_GIVEN)) |
7c0a033f SB |
503 | mlp.flags |= MAIN_LOOP_FLAG_TERMINATE | MAIN_LOOP_FLAG_USE_FD; |
504 | } | |
505 | ||
b2151737 | 506 | if (pidfile_write(getpid()) < 0) { |
510f1848 | 507 | goto exit_failure; |
b2151737 SB |
508 | } |
509 | ||
f163b202 SB |
510 | setvbuf(stdout, 0, _IONBF, 0); /* output may be going through pipe */ |
511 | ||
512 | #ifdef DEBUG | |
513 | /* initialization */ | |
514 | start_time = time(NULL); | |
515 | #endif | |
516 | ||
517 | TPM_DEBUG("main: Initializing TPM at %s", ctime(&start_time)); | |
518 | ||
fbc596ab | 519 | tpmlib_debug_libtpms_parameters(mlp.tpmversion); |
f163b202 | 520 | |
7f46fa86 SB |
521 | if ((rc = tpmlib_register_callbacks(&callbacks))) |
522 | goto error_no_tpm; | |
523 | ||
63ab6c3c | 524 | if (!need_init_cmd) { |
32694853 | 525 | if ((rc = tpmlib_start(0, mlp.tpmversion))) |
63ab6c3c SB |
526 | goto error_no_tpm; |
527 | tpm_running = true; | |
528 | } | |
1bebb6be SB |
529 | |
530 | if (install_sighandlers(notify_fd, sigterm_handler) < 0) | |
531 | goto error_no_sighandlers; | |
532 | ||
07dfd958 SB |
533 | if (create_seccomp_profile(false, seccomp_action) < 0) |
534 | goto error_seccomp_profile; | |
535 | ||
98d1d126 NW |
536 | if (daemonize) { |
537 | daemonize_finish(); | |
538 | } | |
539 | ||
7f46fa86 | 540 | rc = mainLoop(&mlp, notify_fd[0]); |
1bebb6be | 541 | |
07dfd958 | 542 | error_seccomp_profile: |
869df69f | 543 | uninstall_sighandlers(); |
bd247379 | 544 | |
1bebb6be SB |
545 | error_no_sighandlers: |
546 | TPMLIB_Terminate(); | |
f163b202 | 547 | |
1bebb6be | 548 | error_no_tpm: |
f163b202 SB |
549 | close(notify_fd[0]); |
550 | notify_fd[0] = -1; | |
551 | close(notify_fd[1]); | |
552 | notify_fd[1] = -1; | |
553 | ||
321a22cc | 554 | swtpm_cleanup(mlp.cc, server); |
510f1848 | 555 | |
f163b202 SB |
556 | /* Fatal initialization errors cause the program to abort */ |
557 | if (rc == 0) { | |
4fd2d23b | 558 | exit(EXIT_SUCCESS); |
f163b202 SB |
559 | } |
560 | else { | |
561 | TPM_DEBUG("main: TPM initialization failure %08x, exiting\n", rc); | |
4fd2d23b | 562 | exit(EXIT_FAILURE); |
f163b202 | 563 | } |
510f1848 SB |
564 | |
565 | exit_failure: | |
321a22cc | 566 | swtpm_cleanup(mlp.cc, server); |
510f1848 | 567 | |
4fd2d23b | 568 | exit(EXIT_FAILURE); |
5bc59a74 ET |
569 | |
570 | exit_success: | |
571 | swtpm_cleanup(mlp.cc, server); | |
572 | ||
573 | exit(EXIT_SUCCESS); | |
f163b202 | 574 | } |