]>
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" |
e6bc4bdf | 171 | "--flags [not-need-init][,startup-clear|startup-state|startup-deactivated|startup-none]\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" |
bb420d74 | 175 | "-r|--runas <user>: change to the given user\n" |
fbc596ab | 176 | "--tpm2 : choose TPM2 functionality\n" |
07dfd958 SB |
177 | #ifdef WITH_SECCOMP |
178 | # ifndef SCMP_ACT_LOG | |
179 | "--seccomp action=none|kill\n" | |
180 | # else | |
181 | "--seccomp action=none|kill|log\n" | |
182 | # endif | |
183 | " : Choose the action of the seccomp profile when a\n" | |
184 | " blacklisted syscall is executed; default is kill\n" | |
185 | #endif | |
11114ba7 SB |
186 | "--print-capabilites\n" |
187 | " : print capabilities and terminate\n" | |
5bc59a74 ET |
188 | "--print-states\n" |
189 | " : print existing TPM states and terminate\n" | |
f163b202 SB |
190 | "-h|--help : display this help screen and terminate\n" |
191 | "\n", | |
192 | prgname, iface); | |
193 | } | |
194 | ||
321a22cc SB |
195 | static void swtpm_cleanup(struct ctrlchannel *cc, struct server *server) |
196 | { | |
197 | pidfile_remove(); | |
198 | ctrlchannel_free(cc); | |
199 | server_free(server); | |
200 | log_global_free(); | |
fc36ef35 | 201 | tpmstate_global_free(); |
8f57999d | 202 | SWTPM_NVRAM_Shutdown(); |
321a22cc SB |
203 | } |
204 | ||
f163b202 SB |
205 | int swtpm_main(int argc, char **argv, const char *prgname, const char *iface) |
206 | { | |
207 | TPM_RESULT rc = 0; | |
208 | int daemonize = FALSE; | |
11114ba7 | 209 | int opt, longindex, ret; |
f163b202 SB |
210 | struct stat statbuf; |
211 | struct mainLoopParams mlp = { | |
510f1848 | 212 | .cc = NULL, |
f163b202 | 213 | .flags = 0, |
7c0a033f | 214 | .fd = -1, |
4a565414 | 215 | .locality_flags = 0, |
32694853 | 216 | .tpmversion = TPMLIB_TPM_VERSION_1_2, |
e6bc4bdf | 217 | .startupType = _TPM_ST_NONE, |
f163b202 | 218 | }; |
4716d35a | 219 | struct server *server = NULL; |
f163b202 SB |
220 | unsigned long val; |
221 | char *end_ptr; | |
222 | char buf[20]; | |
223 | char *keydata = NULL; | |
84259c17 | 224 | char *migkeydata = NULL; |
f163b202 | 225 | char *logdata = NULL; |
b2151737 | 226 | char *piddata = NULL; |
4a565414 | 227 | char *localitydata = NULL; |
bc525ccd | 228 | char *tpmstatedata = NULL; |
9ddc6998 | 229 | char *ctrlchdata = NULL; |
4716d35a | 230 | char *serverdata = NULL; |
63ab6c3c | 231 | char *flagsdata = NULL; |
07dfd958 | 232 | char *seccompdata = NULL; |
bb420d74 | 233 | char *runas = NULL; |
63ab6c3c | 234 | bool need_init_cmd = true; |
f163b202 SB |
235 | #ifdef DEBUG |
236 | time_t start_time; | |
237 | #endif | |
07dfd958 | 238 | unsigned int seccomp_action; |
3a3a9f5b | 239 | bool printcapabilities = false; |
5bc59a74 | 240 | bool printstates = false; |
f163b202 SB |
241 | static struct option longopts[] = { |
242 | {"daemon" , no_argument, 0, 'd'}, | |
243 | {"help" , no_argument, 0, 'h'}, | |
244 | {"port" , required_argument, 0, 'p'}, | |
f163b202 | 245 | {"fd" , required_argument, 0, 'f'}, |
93edca48 | 246 | {"server" , required_argument, 0, 'c'}, |
bb420d74 | 247 | {"runas" , required_argument, 0, 'r'}, |
f163b202 | 248 | {"terminate" , no_argument, 0, 't'}, |
4a565414 | 249 | {"locality" , required_argument, 0, 'L'}, |
f163b202 SB |
250 | {"log" , required_argument, 0, 'l'}, |
251 | {"key" , required_argument, 0, 'k'}, | |
84259c17 | 252 | {"migration-key", required_argument, 0, 'K'}, |
b2151737 | 253 | {"pid" , required_argument, 0, 'P'}, |
bc525ccd | 254 | {"tpmstate" , required_argument, 0, 's'}, |
9ddc6998 | 255 | {"ctrl" , required_argument, 0, 'C'}, |
63ab6c3c | 256 | {"flags" , required_argument, 0, 'F'}, |
fbc596ab | 257 | {"tpm2" , no_argument, 0, '2'}, |
07dfd958 SB |
258 | #ifdef WITH_SECCOMP |
259 | {"seccomp" , required_argument, 0, 'S'}, | |
260 | #endif | |
11114ba7 SB |
261 | {"print-capabilities" |
262 | , no_argument, 0, 'a'}, | |
5bc59a74 | 263 | {"print-states", no_argument, 0, 'e'}, |
f163b202 SB |
264 | {NULL , 0 , 0, 0 }, |
265 | }; | |
266 | ||
cba81569 SB |
267 | log_set_prefix("swtpm: "); |
268 | ||
f163b202 | 269 | while (TRUE) { |
bb420d74 | 270 | opt = getopt_long(argc, argv, "dhp:f:tr:", longopts, &longindex); |
f163b202 SB |
271 | |
272 | if (opt == -1) | |
273 | break; | |
274 | ||
275 | switch (opt) { | |
276 | case 'd': | |
277 | daemonize = TRUE; | |
98d1d126 NW |
278 | if (daemonize_prep() == -1) { |
279 | logprintf(STDERR_FILENO, | |
280 | "Could not prepare to daemonize: %s\n", strerror(errno)); | |
281 | exit(EXIT_FAILURE); | |
282 | } | |
f163b202 SB |
283 | break; |
284 | ||
285 | case 'p': | |
6fc8fb9f | 286 | errno = 0; |
f163b202 SB |
287 | val = strtoul(optarg, &end_ptr, 0); |
288 | if (val != (unsigned int)val || errno || end_ptr[0] != '\0') { | |
cba81569 SB |
289 | logprintf(STDERR_FILENO, |
290 | "Cannot parse socket port number '%s'.\n", | |
291 | optarg); | |
4fd2d23b | 292 | exit(EXIT_FAILURE); |
f163b202 SB |
293 | } |
294 | if (val >= 0x10000) { | |
cba81569 | 295 | logprintf(STDERR_FILENO, "Port is outside valid range.\n"); |
4fd2d23b | 296 | exit(EXIT_FAILURE); |
f163b202 SB |
297 | } |
298 | snprintf(buf, sizeof(buf), "%lu", val); | |
299 | if (setenv("TPM_PORT", buf, 1) != 0) { | |
cba81569 SB |
300 | logprintf(STDERR_FILENO, |
301 | "Could not set port: %s\n", strerror(errno)); | |
4fd2d23b | 302 | exit(EXIT_FAILURE); |
f163b202 | 303 | } |
c310f1d7 | 304 | serverdata = "type=tcp,disconnect"; |
f163b202 SB |
305 | break; |
306 | ||
f163b202 | 307 | case 'f': |
3f37cc3e | 308 | errno = 0; |
f163b202 SB |
309 | val = strtoul(optarg, &end_ptr, 10); |
310 | if (val != (unsigned int)val || errno || end_ptr[0] != '\0') { | |
cba81569 SB |
311 | logprintf(STDERR_FILENO, |
312 | "Cannot parse socket file descriptor.\n"); | |
4fd2d23b | 313 | exit(EXIT_FAILURE); |
f163b202 SB |
314 | } |
315 | mlp.fd = val; | |
316 | if (fstat(mlp.fd, &statbuf) != 0) { | |
cba81569 SB |
317 | logprintf(STDERR_FILENO, "Cannot stat file descriptor: %s\n", |
318 | strerror(errno)); | |
4fd2d23b | 319 | exit(EXIT_FAILURE); |
f163b202 | 320 | } |
1e029685 SB |
321 | /* |
322 | * test for wrong file types; anonymous fd's do not seem to be any of the wrong | |
323 | * ones but are also not character devices | |
324 | */ | |
b20eafa7 SB |
325 | if (S_ISREG(statbuf.st_mode) || S_ISDIR(statbuf.st_mode) || |
326 | S_ISBLK(statbuf.st_mode) || S_ISLNK(statbuf.st_mode)) { | |
cba81569 SB |
327 | logprintf(STDERR_FILENO, |
328 | "Given file descriptor type is not supported.\n"); | |
4fd2d23b | 329 | exit(EXIT_FAILURE); |
f163b202 | 330 | } |
0a0885cf AV |
331 | mlp.flags |= MAIN_LOOP_FLAG_TERMINATE | MAIN_LOOP_FLAG_USE_FD | |
332 | MAIN_LOOP_FLAG_KEEP_CONNECTION; | |
87d56f93 | 333 | |
f163b202 SB |
334 | SWTPM_IO_SetSocketFD(mlp.fd); |
335 | ||
336 | break; | |
337 | ||
7c0a033f | 338 | case 'c': |
4716d35a | 339 | serverdata = optarg; |
7c0a033f SB |
340 | break; |
341 | ||
f163b202 SB |
342 | case 't': |
343 | mlp.flags |= MAIN_LOOP_FLAG_TERMINATE; | |
344 | break; | |
345 | ||
346 | case 'k': | |
347 | keydata = optarg; | |
348 | break; | |
349 | ||
84259c17 SB |
350 | case 'K': |
351 | migkeydata = optarg; | |
352 | break; | |
353 | ||
f163b202 SB |
354 | case 'l': |
355 | logdata = optarg; | |
356 | break; | |
357 | ||
b2151737 SB |
358 | case 'P': |
359 | piddata = optarg; | |
360 | break; | |
361 | ||
bc525ccd SB |
362 | case 's': |
363 | tpmstatedata = optarg; | |
364 | break; | |
365 | ||
9ddc6998 SB |
366 | case 'C': |
367 | ctrlchdata = optarg; | |
368 | break; | |
369 | ||
4a565414 SB |
370 | case 'L': |
371 | localitydata = optarg; | |
372 | break; | |
373 | ||
63ab6c3c SB |
374 | case 'F': |
375 | flagsdata = optarg; | |
376 | break; | |
377 | ||
fbc596ab | 378 | case '2': |
32694853 | 379 | mlp.tpmversion = TPMLIB_TPM_VERSION_2; |
fbc596ab SB |
380 | break; |
381 | ||
f163b202 SB |
382 | case 'h': |
383 | usage(stdout, prgname, iface); | |
384 | exit(EXIT_SUCCESS); | |
385 | ||
11114ba7 | 386 | case 'a': |
3a3a9f5b SB |
387 | printcapabilities = true; |
388 | break; | |
11114ba7 | 389 | |
5bc59a74 ET |
390 | case 'e': |
391 | printstates = true; | |
392 | break; | |
393 | ||
bb420d74 SB |
394 | case 'r': |
395 | runas = optarg; | |
396 | break; | |
397 | ||
07dfd958 SB |
398 | case 'S': |
399 | seccompdata = optarg; | |
400 | break; | |
401 | ||
f163b202 SB |
402 | default: |
403 | usage(stderr, prgname, iface); | |
404 | exit(EXIT_FAILURE); | |
405 | } | |
406 | } | |
407 | ||
f1766b31 SB |
408 | if (optind < argc) { |
409 | logprintf(STDERR_FILENO, | |
410 | "Unknown parameter '%s'\n", argv[optind]); | |
4fd2d23b | 411 | exit(EXIT_FAILURE); |
f1766b31 SB |
412 | } |
413 | ||
15ff0d96 ET |
414 | /* change process ownership before accessing files */ |
415 | if (runas) { | |
416 | if (change_process_owner(runas) < 0) | |
417 | exit(EXIT_FAILURE); | |
418 | } | |
419 | ||
420 | if (handle_log_options(logdata) < 0) | |
421 | exit(EXIT_FAILURE); | |
422 | ||
83764896 SB |
423 | if (mlp.fd >= 0 && mlp.fd < 3) { |
424 | /* no std{in,out,err} */ | |
425 | logprintf(STDERR_FILENO, | |
426 | "Error: Cannot accept file descriptors with values 0, 1, or 2\n"); | |
4fd2d23b | 427 | exit(EXIT_FAILURE); |
83764896 SB |
428 | } |
429 | ||
ccaf99f1 MAL |
430 | if (printcapabilities) { |
431 | /* | |
432 | * Choose the TPM version so that getting/setting buffer size works. | |
433 | * Ignore failure, for backward compatibility when TPM 1.2 is disabled. | |
434 | */ | |
435 | TPMLIB_ChooseTPMVersion(mlp.tpmversion); | |
436 | ret = capabilities_print_json(false); | |
437 | exit(ret ? EXIT_FAILURE : EXIT_SUCCESS); | |
438 | } | |
439 | ||
fbc596ab SB |
440 | if (TPMLIB_ChooseTPMVersion(mlp.tpmversion) != TPM_SUCCESS) { |
441 | logprintf(STDERR_FILENO, | |
442 | "Error: Could not choose TPM version.\n"); | |
4fd2d23b | 443 | exit(EXIT_FAILURE); |
fbc596ab SB |
444 | } |
445 | ||
f34e01a5 SB |
446 | if (handle_ctrlchannel_options(ctrlchdata, &mlp.cc) < 0 || |
447 | handle_server_options(serverdata, &server) < 0) { | |
448 | goto exit_failure; | |
449 | } | |
450 | ||
2d3deaef | 451 | tpmstate_set_version(mlp.tpmversion); |
fbc596ab | 452 | |
5bc59a74 ET |
453 | if (printstates) { |
454 | if (handle_tpmstate_options(tpmstatedata) < 0) | |
455 | goto exit_failure; | |
456 | if (tpmstatedata == NULL) { | |
457 | logprintf(STDERR_FILENO, | |
458 | "Error: --tpmstate option is required for --print-states\n"); | |
459 | goto exit_failure; | |
460 | } | |
89f25f91 | 461 | ret = SWTPM_NVRAM_PrintJson(); |
5bc59a74 ET |
462 | if (ret == 0) |
463 | goto exit_success; | |
464 | else | |
465 | goto exit_failure; | |
466 | } | |
467 | ||
15ff0d96 | 468 | if (handle_key_options(keydata) < 0 || |
84259c17 | 469 | handle_migration_key_options(migkeydata) < 0 || |
bc525ccd | 470 | handle_pid_options(piddata) < 0 || |
4a565414 | 471 | handle_locality_options(localitydata, &mlp.locality_flags) < 0 || |
7c0a033f | 472 | handle_tpmstate_options(tpmstatedata) < 0 || |
07dfd958 | 473 | handle_seccomp_options(seccompdata, &seccomp_action) < 0 || |
e6bc4bdf SB |
474 | handle_flags_options(flagsdata, &need_init_cmd, |
475 | &mlp.startupType) < 0) { | |
510f1848 SB |
476 | goto exit_failure; |
477 | } | |
f163b202 | 478 | |
4716d35a SB |
479 | if (server) { |
480 | if (server_get_fd(server) >= 0) { | |
75f9f0d3 | 481 | mlp.fd = server_set_fd(server, -1); |
7c0a033f SB |
482 | SWTPM_IO_SetSocketFD(mlp.fd); |
483 | } | |
484 | ||
485 | mlp.flags |= MAIN_LOOP_FLAG_KEEP_CONNECTION; | |
4716d35a | 486 | if ((server_get_flags(server) & SERVER_FLAG_DISCONNECT)) |
c2d04f53 | 487 | mlp.flags &= ~MAIN_LOOP_FLAG_KEEP_CONNECTION; |
7c0a033f | 488 | |
4716d35a | 489 | if ((server_get_flags(server) & SERVER_FLAG_FD_GIVEN)) |
7c0a033f SB |
490 | mlp.flags |= MAIN_LOOP_FLAG_TERMINATE | MAIN_LOOP_FLAG_USE_FD; |
491 | } | |
492 | ||
b2151737 | 493 | if (pidfile_write(getpid()) < 0) { |
510f1848 | 494 | goto exit_failure; |
b2151737 SB |
495 | } |
496 | ||
f163b202 SB |
497 | setvbuf(stdout, 0, _IONBF, 0); /* output may be going through pipe */ |
498 | ||
499 | #ifdef DEBUG | |
500 | /* initialization */ | |
501 | start_time = time(NULL); | |
502 | #endif | |
503 | ||
504 | TPM_DEBUG("main: Initializing TPM at %s", ctime(&start_time)); | |
505 | ||
fbc596ab | 506 | tpmlib_debug_libtpms_parameters(mlp.tpmversion); |
f163b202 | 507 | |
7f46fa86 SB |
508 | if ((rc = tpmlib_register_callbacks(&callbacks))) |
509 | goto error_no_tpm; | |
510 | ||
63ab6c3c | 511 | if (!need_init_cmd) { |
32694853 | 512 | if ((rc = tpmlib_start(0, mlp.tpmversion))) |
63ab6c3c SB |
513 | goto error_no_tpm; |
514 | tpm_running = true; | |
515 | } | |
1bebb6be SB |
516 | |
517 | if (install_sighandlers(notify_fd, sigterm_handler) < 0) | |
518 | goto error_no_sighandlers; | |
519 | ||
07dfd958 SB |
520 | if (create_seccomp_profile(false, seccomp_action) < 0) |
521 | goto error_seccomp_profile; | |
522 | ||
98d1d126 NW |
523 | if (daemonize) { |
524 | daemonize_finish(); | |
525 | } | |
526 | ||
7f46fa86 | 527 | rc = mainLoop(&mlp, notify_fd[0]); |
1bebb6be | 528 | |
07dfd958 | 529 | error_seccomp_profile: |
869df69f | 530 | uninstall_sighandlers(); |
bd247379 | 531 | |
1bebb6be SB |
532 | error_no_sighandlers: |
533 | TPMLIB_Terminate(); | |
f163b202 | 534 | |
1bebb6be | 535 | error_no_tpm: |
f163b202 SB |
536 | close(notify_fd[0]); |
537 | notify_fd[0] = -1; | |
538 | close(notify_fd[1]); | |
539 | notify_fd[1] = -1; | |
540 | ||
321a22cc | 541 | swtpm_cleanup(mlp.cc, server); |
510f1848 | 542 | |
f163b202 SB |
543 | /* Fatal initialization errors cause the program to abort */ |
544 | if (rc == 0) { | |
4fd2d23b | 545 | exit(EXIT_SUCCESS); |
f163b202 SB |
546 | } |
547 | else { | |
548 | TPM_DEBUG("main: TPM initialization failure %08x, exiting\n", rc); | |
4fd2d23b | 549 | exit(EXIT_FAILURE); |
f163b202 | 550 | } |
510f1848 SB |
551 | |
552 | exit_failure: | |
321a22cc | 553 | swtpm_cleanup(mlp.cc, server); |
510f1848 | 554 | |
4fd2d23b | 555 | exit(EXIT_FAILURE); |
5bc59a74 ET |
556 | |
557 | exit_success: | |
558 | swtpm_cleanup(mlp.cc, server); | |
559 | ||
560 | exit(EXIT_SUCCESS); | |
f163b202 | 561 | } |