Add support for the --tpmstate dir=<dir> command line parameter.
It will be used instead of the TPM_PATH, unless it is not set.
Adapt two test cases for the new parameter.
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
.\" ========================================================================
.\"
.IX Title "swtpm 8"
-.TH swtpm 8 "2015-10-26" "swtpm" ""
+.TH swtpm 8 "2015-10-27" "swtpm" ""
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
be set to the \s-1TCP/IP\s0 port the process is supposed to listen on for \s-1TPM\s0
request messages.
.PP
-The environment variable \fI\s-1TPM_PATH\s0\fR must be set and
+Similarly, the environment variable \fI\s-1TPM_PATH\s0\fR can be set and
contain the name of a directory where the \s-1TPM\s0 can store its persistent
-data into.
+state into.
.PP
The \fBswtpm\fR process can be terminated by sending a
\&\fI\s-1SIGTERM\s0\fR signal to it.
.IP "\fB\-p|\-\-port <port\fR>" 4
.IX Item "-p|--port <port>"
Use the given port rather than using the environment variable \s-1TPM_PORT.\s0
-.IP "\fB\-i|\-\-dir <dir\fR>" 4
-.IX Item "-i|--dir <dir>"
+.IP "\fB\-\-tpmstate dir=<dir>\fR" 4
+.IX Item "--tpmstate dir=<dir>"
Use the given path rather than using the environment variable \s-1TPM_PATH.\s0
.IP "\fB\-f|\-\-fd <fd\fR>" 4
.IX Item "-f|--fd <fd>"
be set to the TCP/IP port the process is supposed to listen on for TPM
request messages.
-The environment variable I<TPM_PATH> must be set and
+Similarly, the environment variable I<TPM_PATH> can be set and
contain the name of a directory where the TPM can store its persistent
-data into.
+state into.
The B<swtpm> process can be terminated by sending a
I<SIGTERM> signal to it.
Use the given port rather than using the environment variable TPM_PORT.
-=item B<-i|--dir <dir>>
+=item B<--tpmstate dir=E<lt>dirE<gt>>
Use the given path rather than using the environment variable TPM_PATH.
.\" ========================================================================
.\"
.IX Title "swtpm_cuse 8"
-.TH swtpm_cuse 8 "2015-10-26" "swtpm" ""
+.TH swtpm_cuse 8 "2015-10-27" "swtpm" ""
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
\&\fBswtpm_cuse\fR implements a \s-1TPM\s0 software emulator built on libtpms.
-It provides access to \s-1TPM\s0 functionality over a Linux \s-1CUSE
+It provides access to \s-1TPM\s0 functionality over a Linux \s-1CUSE
\&\s0(character device in user space) interface.
.PP
-The environment variable \fI\s-1TPM_PATH\s0\fR must be set and
-contain the name of a directory where the \s-1TPM\s0 can store its persistent
-data into.
-.PP
The \fBswtpm_ioctl\fR command should be used for a graceful shutdown
of the \s-1CUSE TPM.\s0
.PP
.IP "\fB\-h | \-\-help\fR" 4
.IX Item "-h | --help"
Display help screen.
+.IP "\fB\-\-tpmstate dir=<dir>\fR" 4
+.IX Item "--tpmstate dir=<dir>"
+This parameter allows to set the directory where the \s-1TPM\s0 will
+store its persistent state to. If this parameter is not set,
+the environment variable \fI\s-1TPM_PATH\s0\fR can be set instead.
.IP "\fB\-n <device name> | \-\-name=<device name> (mandatory)\fR" 4
.IX Item "-n <device name> | --name=<device name> (mandatory)"
The name of the character device to create. To create /dev/vtpm\-200, the
=head1 DESCRIPTION
B<swtpm_cuse> implements a TPM software emulator built on libtpms.
-It provides access to TPM functionality over a Linux CUSE
+It provides access to TPM functionality over a Linux CUSE
(character device in user space) interface.
-The environment variable I<TPM_PATH> must be set and
-contain the name of a directory where the TPM can store its persistent
-data into.
-
The B<swtpm_ioctl> command should be used for a graceful shutdown
of the CUSE TPM.
Display help screen.
+=item B<--tpmstate dir=E<lt>dirE<gt>>
+
+This parameter allows to set the directory where the TPM will
+store its persistent state to. If this parameter is not set,
+the environment variable I<TPM_PATH> can be set instead.
+
=item B<-n E<lt>device nameE<gt> | --name=E<lt>device nameE<gt> (mandatory)>
The name of the character device to create. To create /dev/vtpm-200, the
swtpm_aes.h \
swtpm_debug.h \
swtpm_io.h \
- swtpm_nvfile.h
+ swtpm_nvfile.h \
+ tpmstate.h
lib_LTLIBRARIES = libswtpm_libtpms.la
swtpm_aes.c \
swtpm_debug.c \
swtpm_io.c \
- swtpm_nvfile.c
+ swtpm_nvfile.c \
+ tpmstate.c
libswtpm_libtpms_la_CFLAGS = \
$(HARDENING_CFLAGS)
#include "logging.h"
#include "swtpm_nvfile.h"
#include "pidfile.h"
+#include "tpmstate.h"
/* --log %s */
static const OptionDesc logging_opt_desc[] = {
END_OPTION_DESC
};
+/* --state %s */
+static const OptionDesc tpmstate_opt_desc[] = {
+ {
+ .name = "dir",
+ .type = OPT_TYPE_STRING,
+ },
+ END_OPTION_DESC
+};
+
/*
* handle_log_options:
* Parse and act upon the parsed log options. Initialize the logging.
/*
* handle_pidfile_options:
- * Parse and act upon the parse pidfile options. Set global value
- * related to the options found.
+ * Parse and act upon the parse pidfile options.
+ *
* @options: the pidfile options to parse
*
* Returns 0 on success, -1 on failure.
if (parse_pid_options(options, &pidfile) < 0)
return -1;
- pidfile_set(pidfile);
+ if (pidfile_set(pidfile) < 0)
+ return -1;
free(pidfile);
return 0;
}
+
+/*
+ * parse_tpmstate_options:
+ * Parse and act upon the parsed 'tpmstate' options.
+ *
+ * @options: the 'pid' options to parse
+ * @tpmstatedir: Point to pointer for tpmstatedir
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+static int
+parse_tpmstate_options(char *options, char **tpmstatedir)
+{
+ OptionValues *ovs = NULL;
+ char *error = NULL;
+ const char *directory = NULL;
+
+ ovs = options_parse(options, tpmstate_opt_desc, &error);
+
+ if (!ovs) {
+ fprintf(stderr, "Error parsing pid options: %s\n",
+ error);
+ goto error;
+ }
+
+ directory = option_get_string(ovs, "dir", NULL);
+ if (!directory) {
+ fprintf(stderr, "The file parameter is required for the tpmstate option.\n");
+ goto error;
+ }
+
+ *tpmstatedir = strdup(directory);
+ if (!*tpmstatedir) {
+ fprintf(stderr, "Out of memory.");
+ goto error;
+ }
+
+ option_values_free(ovs);
+
+ return 0;
+
+error:
+ option_values_free(ovs);
+
+ return -1;
+}
+
+/*
+ * handle_tpmstate_options:
+ * Parse and act upon the parsed 'tpmstate' options.
+ *
+ * @options: the tpmstate options to parse
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+int
+handle_tpmstate_options(char *options)
+{
+ char *tpmstatedir = NULL;
+
+ if (!options)
+ return 0;
+
+ if (parse_tpmstate_options(options, &tpmstatedir) < 0)
+ return -1;
+
+ if (tpmstate_set_dir(tpmstatedir) < 0)
+ return -1;
+
+ free(tpmstatedir);
+
+ return 0;
+}
int handle_key_options(char *options);
int handle_migration_key_options(char *options);
int handle_pid_options(char *options);
+int handle_tpmstate_options(char *options);
#endif /* _SWTPM_COMMON_H_ */
#include "main.h"
#include "common.h"
#include "pidfile.h"
+#include "tpmstate.h"
#include <glib.h>
char *keydata;
char *migkeydata;
char *piddata;
+ char *tpmstatedata;
};
"--log file=<path>|fd=<filedescriptor>\n"
" : write the TPM's log into the given file rather than\n"
" to the console; provide '-' for path to avoid logging\n"
+"--pid file=<path> : write the process ID into the given file\n"
+"--tpmstate dir=<dir>\n"
+" : set the directory where the TPM's state will be written\n"
+" into; the TPM_PATH environment variable can be used\n"
+" instead\n"
+""
"-h|--help : display this help screen and terminate\n"
-"\n"
-"Make sure that TPM_PATH environment variable points to directory\n"
-"where TPM's NV storage file is kept\n"
"\n";
const static unsigned char TPM_Resp_FatalError[] = {
static int tpm_start(uint32_t flags)
{
DIR *dir;
- char * tpmdir = NULL;
+ const char *tpmdir = tpmstate_get_dir();
- /* temporary - the backend script lacks the perms to do this */
if (tpmdir == NULL) {
- tpmdir = getenv("TPM_PATH");
- if (!tpmdir) {
- logprintf(STDOUT_FILENO,
- "Error: TPM_PATH is not set\n");
- return -1;
- }
+ logprintf(STDOUT_FILENO,
+ "Error: TPM_PATH is not set\n");
+ return -1;
}
+
dir = opendir(tpmdir);
if (dir) {
closedir(dir);
} else {
if (mkdir(tpmdir, 0775)) {
logprintf(STDERR_FILENO,
- "Error: Could not open TPM_PATH dir\n");
+ "Error: Could not open tpmstate dir %s\n",
+ tpmdir);
return -1;
}
}
PTM_OPT("--key %s", keydata),
PTM_OPT("--migration-key %s", migkeydata),
PTM_OPT("--pid %s", piddata),
+ PTM_OPT("--tpmstate %s", tpmstatedata),
FUSE_OPT_KEY("-h", 0),
FUSE_OPT_KEY("--help", 0),
FUSE_OPT_KEY("-v", 1),
.logging = NULL,
.keydata = NULL,
.migkeydata = NULL,
+ .piddata = NULL,
+ .tpmstatedata = NULL,
};
char dev_name[128] = "DEVNAME=";
const char *dev_info_argv[] = { dev_name };
if (handle_log_options(param.logging) < 0 ||
handle_key_options(param.keydata) < 0 ||
handle_migration_key_options(param.migkeydata) < 0 ||
- handle_pid_options(param.piddata) < 0)
+ handle_pid_options(param.piddata) < 0 ||
+ handle_tpmstate_options(param.tpmstatedata) < 0)
return -3;
if (setuid(0)) {
int pidfile_set(const char *pidfile)
{
g_pidfile = strdup(pidfile);
- if (!g_pidfile)
+ if (!g_pidfile) {
+ logprintf(STDERR_FILENO, "Out of memory.\n");
return -1;
+ }
return 0;
}
"The following options are supported:\n"
"\n"
"-p|--port <port> : use the given port\n"
- "-i|--dir <dir> : use the given directory\n"
"-f|--fd <fd> : use the given socket file descriptor\n"
"-t|--terminate : terminate the TPM once a connection has been lost\n"
"-d|--daemon : daemonize the TPM\n"
"--log file=<path>|fd=<filedescriptor>\n"
- " : write the TPM's log into the given file rather than\n"
- " to the console; provide '-' for path to avoid logging\n"
+ " : write the TPM's log into the given file rather than\n"
+ " to the console; provide '-' for path to avoid logging\n"
"--key file=<path>[,mode=aes-cbc][,format=hex|binary][,remove=[true|false]]\n"
" : use an AES key for the encryption of the TPM's state\n"
" files; use the given mode for the block encryption;\n"
" format; the keyfile can be automatically removed using\n"
" the remove parameter\n"
"--key pwdfile=<path>[,mode=aes-cbc][,remove=[true|false]]\n"
- " : provide a passphrase in a file; the AES key will be\n"
- " derived from this passphrase\n"
+ " : provide a passphrase in a file; the AES key will be\n"
+ " derived from this passphrase\n"
+ "--pid file=<path>\n"
+ " : write the process ID into the given file\n"
+ "--tpmstate dir=<dir>\n"
+ " : set the directory where the TPM's state will be written\n"
+ " into; the TPM_PATH environment variable can be used\n"
+ " instead\n"
"-h|--help : display this help screen and terminate\n"
"\n",
prgname, iface);
char *keydata = NULL;
char *logdata = NULL;
char *piddata = NULL;
+ char *tpmstatedata = NULL;
#ifdef DEBUG
time_t start_time;
#endif
{"daemon" , no_argument, 0, 'd'},
{"help" , no_argument, 0, 'h'},
{"port" , required_argument, 0, 'p'},
- {"dir" , required_argument, 0, 'i'},
{"fd" , required_argument, 0, 'f'},
{"terminate" , no_argument, 0, 't'},
{"log" , required_argument, 0, 'l'},
{"key" , required_argument, 0, 'k'},
{"pid" , required_argument, 0, 'P'},
+ {"tpmstate" , required_argument, 0, 's'},
{NULL , 0 , 0, 0 },
};
while (TRUE) {
- opt = getopt_long(argc, argv, "dhp:i:f:tk:", longopts, &longindex);
+ opt = getopt_long(argc, argv, "dhp:f:tk:P:s:", longopts, &longindex);
if (opt == -1)
break;
}
break;
- case 'i':
- if (setenv("TPM_PATH", optarg, 1) != 0) {
- fprintf(stderr, "Could not set path: %s\n", strerror(errno));
- exit(1);
- }
- break;
-
case 'f':
val = strtoul(optarg, &end_ptr, 10);
if (val != (unsigned int)val || errno || end_ptr[0] != '\0') {
piddata = optarg;
break;
+ case 's':
+ tpmstatedata = optarg;
+ break;
+
case 'h':
usage(stdout, prgname, iface);
exit(EXIT_SUCCESS);
if (handle_log_options(logdata) < 0 ||
handle_key_options(keydata) < 0 ||
- handle_pid_options(piddata) < 0)
+ handle_pid_options(piddata) < 0 ||
+ handle_tpmstate_options(tpmstatedata) < 0)
return EXIT_FAILURE;
if (daemonize) {
#include "swtpm_nvfile.h"
#include "key.h"
#include "logging.h"
+#include "tpmstate.h"
/* local structures */
typedef struct {
TPM_RESULT SWTPM_NVRAM_Init(void)
{
TPM_RESULT rc = 0;
- char *tpm_state_path;
+ const char *tpm_state_path;
size_t length;
TPM_DEBUG(" SWTPM_NVRAM_Init:\n");
/* TPM_NV_DISK TPM emulation stores in local directory determined by environment variable. */
if (rc == 0) {
- tpm_state_path = getenv("TPM_PATH");
+ tpm_state_path = tpmstate_get_dir();
if (tpm_state_path == NULL) {
fprintf(stderr,
"SWTPM_NVRAM_Init: Error (fatal), TPM_PATH environment "
--- /dev/null
+/*
+ * tpmstate.c -- tpmstate parameter handling
+ *
+ * (c) Copyright IBM Corporation 2015.
+ *
+ * Author: Stefan Berger <stefanb@us.ibm.com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the names of the IBM Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "tpmstate.h"
+#include "logging.h"
+
+static char *g_tpmstatedir;
+
+int tpmstate_set_dir(char *tpmstatedir)
+{
+ g_tpmstatedir = strdup(tpmstatedir);
+ if (!g_tpmstatedir) {
+ logprintf(STDERR_FILENO, "Out of memory.\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+const char *tpmstate_get_dir(void)
+{
+ if (g_tpmstatedir)
+ return g_tpmstatedir;
+ return getenv("TPM_PATH");
+}
--- /dev/null
+/*
+ * tpmstate.h -- tpmstate parameter handling
+ *
+ * (c) Copyright IBM Corporation 2015.
+ *
+ * Author: Stefan Berger <stefanb@us.ibm.com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the names of the IBM Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SWTPM_TPMSTATE_H_
+#define _SWTPM_TPMSTATE_H_
+
+int tpmstate_set_dir(char *tpmstatdir);
+const char *tpmstate_get_dir(void);
+
+#endif /* _SWTPM_TPMSTATE_H_ */
# Test 1: test port and directory command line parameters
-$SWTPM_EXE socket -p $PORT -i $TPMDIR --pid file=$PID_FILE &>/dev/null &
+$SWTPM_EXE socket -p $PORT --tpmstate dir=$TPMDIR --pid file=$PID_FILE &>/dev/null &
PID=$!
wait_port_open $PORT $PID
# that causes the swtpm process to exit upon connection close
TPMDIR=`mktemp -d`
-$SWTPM_EXE socket -p $PORT -i $TPMDIR -t &>/dev/null &
+$SWTPM_EXE socket -p $PORT --tpmstate dir=$TPMDIR -t &>/dev/null &
PID=$!
wait_port_open $PORT $PID
SWTPM_EXE=$ROOT/src/swtpm/$SWTPM
CUSE_TPM_IOCTL=$ROOT/src/swtpm_ioctl/swtpm_ioctl
VTPM_NAME="vtpm-test-init"
-export TPM_PATH=$(mktemp -d)
+TPM_PATH=$(mktemp -d)
STATE_FILE=$TPM_PATH/tpm-00.permall
VOLATILE_STATE_FILE=$TPM_PATH/tpm-00.volatilestate
PID_FILE=$TPM_PATH/${SWTPM}.pid
rm -f $STATE_FILE $VOLATILE_STATE_FILE 2>/dev/null
-$SWTPM_EXE --pid file=$PID_FILE -n $VTPM_NAME
+$SWTPM_EXE --tpmstate dir=$TPM_PATH --pid file=$PID_FILE -n $VTPM_NAME
sleep 0.5
PID=$(ps aux | grep $SWTPM | grep -E "$VTPM_NAME\$" | gawk '{print $2}')