Daemonize the process.
-=item B<--ctrl type=[unixio|tcp][,path=E<lt>pathE<gt>] [,port=E<lt>portE<gt>[,bindaddr=E<lt>addressE<gt>[,ifname=E<lt>ifnameE<gt>]]] [,fd=E<lt>filedescriptorE<gt>|clientfd=E<lt>filedescriptorE<gt>] [,mode=E<lt>0...E<gt>][,uid=E<lt>uidE<gt>][,gid=E<lt>gidE<gt>] >
+=item B<--ctrl type=[unixio|tcp][,path=E<lt>pathE<gt>] [,port=E<lt>portE<gt>[,bindaddr=E<lt>addressE<gt>[,ifname=E<lt>ifnameE<gt>]]] [,fd=E<lt>filedescriptorE<gt>|clientfd=E<lt>filedescriptorE<gt>] [,mode=E<lt>0...E<gt>][,uid=E<lt>uidE<gt>][,gid=E<lt>gidE<gt>][,terminate] >
This option adds a control channel to the TPM. The control channel can either use a UnixIO socket with
a given I<path> or I<filedescriptor> or it can use a TCP socket on the given I<port> or I<filedescriptor>.
local IPv6 address is provided, the name of the interface to bind to must be
provided with I<ifname>.
-The mode parameter allows a user to set the file mode bits of the UnixIO path.
+The I<mode> parameter allows a user to set the file mode bits of the UnixIO path.
The mode bits value must be given as an octal number starting with a '0'.
-The default value is 0770. uid and gid set the ownership of the UnixIO socket's path.
+The default value is 0770. I<uid> and I<gid> set the ownership of the UnixIO socket's path.
This operation requires root privileges.
+The I<terminate> parameter enables the automatic termination of swtpm when the
+control channel connection has been lost. This is useful in scenarios where
+the control channel connection is held permanently, such as by QEMU, and
+swtpm should terminate upon abnormal termination of the client that could
+not send a CMD_SHUTDOWN via the control channel anymore.
+
The control channel enables out-of-band control of the TPM, such as resetting the TPM.
=back
#include "server.h"
#include "seccomp_profile.h"
#include "tpmlib.h"
+#include "mainloop.h"
/* --log %s */
static const OptionDesc logging_opt_desc[] = {
}, {
.name = "gid",
.type = OPT_TYPE_GID_T,
+ }, {
+ .name = "terminate",
+ .type = OPT_TYPE_BOOLEAN,
},
END_OPTION_DESC
};
* Parse the 'ctrl' (control channel) options.
*
* @options: the control channel options to parse
+ * @cc: pointer for pointer to allocated ctrlchannel struct
+ * @mainloop_flags: pointer to mainloop flags to add a flag to
*
* Returns 0 on success, -1 on failure.
*/
-static int parse_ctrlchannel_options(char *options, struct ctrlchannel **cc)
+static int parse_ctrlchannel_options(char *options, struct ctrlchannel **cc,
+ uint32_t *mainloop_flags)
{
OptionValues *ovs = NULL;
char *error = NULL;
if (*cc == NULL)
goto error;
+ if (option_get_bool(ovs, "terminate", false))
+ *mainloop_flags |= MAIN_LOOP_FLAG_CTRL_END_ON_HUP;
+
option_values_free(ovs);
return 0;
* Parse and act upon the parsed 'ctrl' (control channel) options.
*
* @options: the control channel options to parse
+ * @cc: pointer for pointer to allocated ctrlchannel struct
+ * @mainloop_flags: pointer to mainloop flags to add a flag to
*
* Returns 0 on success, -1 on failure.
*/
-int handle_ctrlchannel_options(char *options, struct ctrlchannel **cc)
+int handle_ctrlchannel_options(char *options, struct ctrlchannel **cc,
+ uint32_t *mainloop_flag)
{
if (!options)
return 0;
- if (parse_ctrlchannel_options(options, cc) < 0)
+ if (parse_ctrlchannel_options(options, cc, mainloop_flag) < 0)
return -1;
return 0;
int handle_pid_options(char *options);
int handle_tpmstate_options(char *options);
struct ctrlchannel;
-int handle_ctrlchannel_options(char *options, struct ctrlchannel **cc);
+int handle_ctrlchannel_options(char *options, struct ctrlchannel **cc,
+ uint32_t *mainloop_flag);
struct server;
int handle_server_options(char *options, struct server **s);
int handle_locality_options(char *options, uint32_t *flags);
&mainloop_terminate,
&locality, &tpm_running,
mlp);
+ if (ctrlclntfd < 0 &&
+ mlp->flags & MAIN_LOOP_FLAG_CTRL_END_ON_HUP)
+ mainloop_terminate = true;
+
if (mainloop_terminate)
break;
}
if (ctrlclntfd >= 0)
close(ctrlclntfd);
ctrlclntfd = -1;
+ /* unixio gets this signal, not tcp */
+ if (mlp->flags & MAIN_LOOP_FLAG_CTRL_END_ON_HUP) {
+ mainloop_terminate = true;
+ break;
+ }
}
if (!(pollfds[DATA_CLIENT_FD].revents & POLLIN))
struct mainLoopParams {
uint32_t flags;
-#define MAIN_LOOP_FLAG_TERMINATE (1 << 0)
-#define MAIN_LOOP_FLAG_USE_FD (1 << 1)
-#define MAIN_LOOP_FLAG_KEEP_CONNECTION (1 << 2)
-#define MAIN_LOOP_FLAG_END_ON_HUP (1 << 3)
+#define MAIN_LOOP_FLAG_TERMINATE (1 << 0)
+#define MAIN_LOOP_FLAG_USE_FD (1 << 1)
+#define MAIN_LOOP_FLAG_KEEP_CONNECTION (1 << 2)
+#define MAIN_LOOP_FLAG_END_ON_HUP (1 << 3)
+#define MAIN_LOOP_FLAG_CTRL_END_ON_HUP (1 << 4) /* terminate on ctrl ch. client loss (QEMU) */
int fd;
struct ctrlchannel *cc;
"-t|--terminate : terminate the TPM once the data channel connection (TCP)\n"
" has been lost\n"
"-d|--daemon : daemonize the TPM\n"
- "--ctrl type=[unixio|tcp][,path=<path>][,port=<port>[,bindaddr=address[,ifname=ifname]]][,fd=<filedescriptor>|clientfd=<filedescriptor>][,mode=0...][,uid=uid][,gid=gid]\n"
+ "--ctrl type=[unixio|tcp][,path=<path>][,port=<port>[,bindaddr=address[,ifname=ifname]]][,fd=<filedescriptor>|clientfd=<filedescriptor>][,mode=0...][,uid=uid][,gid=gid][,terminate]\n"
" : TPM control channel using either UnixIO or TCP sockets;\n"
" the path is only valid for Unixio channels; the port must\n"
" be given in case the type is TCP; the TCP socket is bound\n"
" mode allows a user to set the file mode bits of a Unixio socket;\n"
" the value must be given in octal number format\n"
" uid and gid set the ownership of the Unixio socket's file;\n"
+ " terminate terminates on ctrl channel connection loss;\n"
"--migration-key file=<path>|fd=<fd>[,mode=aes-cbc|aes-256-cbc][,format=hex|binary][,remove=[true|false]]\n"
" : use an AES key for the encryption of the TPM's state\n"
" when it is retrieved from the TPM via ioctls;\n"
if (tpmlib_choose_tpm_version(mlp.tpmversion) != TPM_SUCCESS)
exit(EXIT_FAILURE);
- if (handle_ctrlchannel_options(ctrlchdata, &mlp.cc) < 0 ||
+ if (handle_ctrlchannel_options(ctrlchdata, &mlp.cc, &mlp.flags) < 0 ||
handle_server_options(serverdata, &server) < 0) {
goto exit_failure;
}
" : use the given character device\n"
"-f|--fd <fd> : use the given character device file descriptor\n"
"-d|--daemon : daemonize the TPM\n"
- "--ctrl type=[unixio|tcp][,path=<path>][,port=<port>[,bindaddr=address[,ifname=ifname]]][,fd=<filedescriptor|clientfd=<filedescriptor>][,mode=0...][,uid=uid][,gid=gid]\n"
+ "--ctrl type=[unixio|tcp][,path=<path>][,port=<port>[,bindaddr=address[,ifname=ifname]]][,fd=<filedescriptor|clientfd=<filedescriptor>][,mode=0...][,uid=uid][,gid=gid][,terminate]\n"
" : TPM control channel using either UnixIO or TCP sockets;\n"
" the path is only valid for Unixio channels; the port must\n"
" be given in case the type is TCP; the TCP socket is bound\n"
" mode allows a user to set the file mode bits of a Unixio socket;\n"
" the value must be given in octal number format\n"
" uid and gid set the ownership of the Unixio socket's file;\n"
+ " terminate terminates on ctrl channel connection loss;\n"
"--migration-key file=<path>|fd=<fd>[,mode=aes-cbc|aes-256-cbc][,format=hex|binary][,remove=[true|false]]\n"
" : use an AES key for the encryption of the TPM's state\n"
" when it is retrieved from the TPM via ioctls;\n"
exit(EXIT_FAILURE);
}
- if (handle_ctrlchannel_options(ctrlchdata, &mlp.cc) < 0) {
+ if (handle_ctrlchannel_options(ctrlchdata, &mlp.cc, &mlp.flags) < 0) {
goto exit_failure;
}