3 SWTPM_EXE=${SWTPM_EXE:-${ROOT}/src/swtpm/${SWTPM}}
4 SWTPM_IOCTL=${SWTPM_IOCTL:-${ROOT}/src/swtpm_ioctl/swtpm_ioctl}
5 SWTPM_BIOS=${SWTPM_BIOS:-${ROOT}/src/swtpm_bios/swtpm_bios}
6 SWTPM_SETUP=${SWTPM_SETUP:-${ROOT}/src/swtpm_setup/swtpm_setup}
7 SWTPM_CERT=${SWTPM_CERT:-${ROOT}/src/swtpm_cert/swtpm_cert}
12 CERTTOOL=gnutls-certtool;;
17 # Note: Do not use file descriptors above 127 due to OpenBSD.
19 # Kill a process quietly
27 bash -c "kill $sig $pid &>/dev/null"
31 # Wait for a regular file to appear and for it to have > 0 bytes
34 # @2: timeout in seconds
35 function wait_for_file()
40 local loops=$((timeout * 10)) loop
42 for ((loop=0; loop<loops; loop++)); do
43 [ -f "${filename}" ] && [ $(get_filesize ${filename}) != 0 ] && {
51 # Wait for a regular file to disappear
54 # @2: timeout in seconds
55 function wait_file_gone()
60 local loops=$((timeout * 10)) loop
62 for ((loop=0; loop<loops; loop++)); do
63 [ -f "${filename}" ] || return 1
69 # Wait for a process with given PID to be gone
72 # @2: timeout in seconds
73 function wait_process_gone()
78 local loops=$((timeout * 10)) loop
80 for ((loop=0; loop<loops; loop++)); do
81 kill_quiet -0 ${pid} || return 1
87 # Wait for a chardev to appear
90 # @2: timeout in seconds
91 function wait_for_chardev()
96 local loops=$((timeout * 10)) loop
98 for ((loop=0; loop<loops; loop++)); do
99 [ -c "${filename}" ] && return 1
105 # Wait for a chardev to disappear
108 # @2: timeout in seconds
109 function wait_chardev_gone()
114 local loops=$((timeout * 10)) loop
116 for ((loop=0; loop<loops; loop++)); do
117 [ -c "${filename}" ] || return 1
123 # Wait for a socket file to appear
126 # @2: timeout in seconds
127 function wait_for_socketfile()
132 local loops=$((timeout * 10)) loop
134 for ((loop=0; loop<loops; loop++)); do
135 [ -S "${filename}" ] && return 1
141 # Wait for a socket file to disappear
144 # @2: timeout in seconds
145 function wait_socketfile_gone()
150 local loops=$((timeout * 10)) loop
152 for ((loop=0; loop<loops; loop++)); do
153 [ -S "${filename}" ] || return 1
159 # Wait for a server socket to appear
163 # @3: timeout in seconds
164 function wait_for_serversocket()
170 local loops=$((timeout * 10)) loop
172 for ((loop=0; loop<loops; loop++)); do
173 (exec 127<>/dev/tcp/${host}/${port}) &>/dev/null
174 [ $? -eq 0 ] && return 1
180 # Wait for a server socket to disappear
184 # @3: timeout in seconds
185 function wait_serversocket_gone()
191 local loops=$((timeout * 10)) loop
193 for ((loop=0; loop<loops; loop++)); do
194 (exec 127<>/dev/tcp/${host}/${port}) &>/dev/null
195 [ $? -eq 0 ] || return 1
201 # Wait for a TCP port to open for listening
203 # @2: id of process to open port
204 # @3: timeout in seconds
205 function wait_port_open()
211 local loops=$((timeout * 10)) loop
212 local NETSTAT=$(type -P netstat)
214 for ((loop = 0; loop < loops; loop++)); do
215 if [ -n "$NETSTAT" ]; then
216 if [ -n "$(netstat -naptl 2>/dev/null |
219 grep ":$port ")" ]; then
223 if [ -n "$(ss -nptl |
224 grep ",pid=${pid}," |
225 grep ":$port ")" ]; then
234 # Wait for a TCP listening port to close
236 # @2: id of process to close port
237 # @3: timeout in seconds
238 function wait_port_closed()
244 local loops=$((timeout * 10)) loop
245 local NETSTAT=$(type -P netstat)
247 for ((loop = 0; loop < loops; loop++)); do
248 if [ -n "$NETSTAT" ]; then
249 if [ -z "$(netstat -naptl 2>/dev/null |
252 grep ":$port ")" ]; then
256 if [ -z "$(ss -nptl |
257 grep ",pid=${pid}," |
258 grep ":$port ")" ]; then
267 # Run the swtpm_ioctl command
269 # @param1: type of interface
270 function run_swtpm_ioctl()
272 local iface=$1; shift
276 [ -z "${SWTPM_DEV_NAME}" ] && {
277 echo "SWTPM_DEV_NAME not defined"
280 ${SWTPM_IOCTL} $@ ${SWTPM_DEV_NAME}
283 socket+socket|unix+socket)
284 [ -z "${SWTPM_SERVER_NAME}" ] && {
285 echo "SWTPM_SERVER_NAME not defined"
288 [ -z "${SWTPM_SERVER_PORT}" ] && {
289 echo "SWTPM_SERVER_PORT not defined"
293 --tcp ${SWTPM_SERVER_NAME}:${SWTPM_CTRL_PORT} \
297 socket+unix|unix+unix)
298 [ -z "${SWTPM_CTRL_UNIX_PATH}" ] && {
299 echo "SWTPM_CTRL_UNIX_PATH not defined"
303 --unix ${SWTPM_CTRL_UNIX_PATH} \
310 # Start the swtpm in the background
312 # @param1: type of interface
313 # @param2.. : parameters to pass to 'swtpm'
316 local iface=$1; shift
317 local swtpm_server_disconnect=""
319 echo "==== Starting swtpm with interfaces ${iface} ===="
320 if [ -z "${SWTPM_SERVER_NO_DISCONNECT}" ]; then
321 swtpm_server_disconnect=",disconnect"
326 [ -z "${SWTPM_DEV_NAME}" ] && {
327 echo "SWTPM_DEV_NAME not defined"
331 if wait_chardev_gone ${SWTPM_DEV_NAME} 2; then
332 echo "${SWTPM_DEV_NAME} is still there and may be used."
336 ${SWTPM_EXE} cuse "$@" ${SWTPM_TEST_SECCOMP_OPT} \
337 -n ${SWTPM_DEV_NAME##*/}
339 if [ $rc -ne 0 ]; then
340 echo "Could not run ${SWTPM_EXE} using ${iface}"
343 if wait_for_chardev ${SWTPM_DEV_NAME} 2; then
344 echo "$SWTPM_DEV_NAME did not appear"
350 grep -E " ${SWTPM_DEV_NAME##*/}\$" |
356 [ -z "${SWTPM_SERVER_PORT}" ] && {
357 echo "SWTPM_SERVER_PORT not defined"
360 [ -z "${SWTPM_CTRL_PORT}" ] && {
361 echo "SWTPM_CTRL_PORT not defined"
365 if wait_serversocket_gone "${SWTPM_SERVER_PORT}" 127.0.0.1 2; then
366 echo "Port ${SWTPM_SERVER_PORT} is still used"
369 if wait_serversocket_gone "${SWTPM_CTRL_PORT}" 127.0.0.1 1; then
370 echo "Port ${SWTPM_CTRL_PORT} is still used"
374 ${SWTPM_EXE} socket "$@" \
375 ${SWTPM_TEST_SECCOMP_OPT} \
376 --server type=tcp,port=${SWTPM_SERVER_PORT}${swtpm_server_disconnect} \
377 --ctrl type=tcp,port=${SWTPM_CTRL_PORT} &
379 if [ $rc -ne 0 ]; then
380 echo "Could not run ${SWTPM_EXE} using ${iface}"
384 if wait_for_serversocket "${SWTPM_SERVER_PORT}" 127.0.0.1 2; then
385 echo "Server did not open port ${SWTPM_SERVER_PORT}"
389 if wait_for_serversocket "${SWTPM_CTRL_PORT}" 127.0.0.1 1; then
390 echo "Server did not open port ${SWTPM_CTRL_PORT}"
397 [ -z "${SWTPM_SERVER_PORT}" ] && {
398 echo "SWTPM_SERVER_PORT not defined"
401 [ -z "${SWTPM_CTRL_UNIX_PATH}" ] && {
402 echo "SWTPM_CTRL_UNIX_PATH not defined"
406 if wait_serversocket_gone "${SWTPM_SERVER_PORT}" 127.0.0.1 2; then
407 echo "Port ${SWTPM_SERVER_PORT} is still used"
410 if wait_socketfile_gone "${SWTPM_CTRL_UNIX_PATH}" 2; then
411 echo "Unix socket ${SWTPM_CTRL_UNIX_PATH} is still there"
415 ${SWTPM_EXE} socket "$@" \
416 ${SWTPM_TEST_SECCOMP_OPT} \
417 --server type=tcp,port=${SWTPM_SERVER_PORT}${swtpm_server_disconnect} \
418 --ctrl type=unixio,path=${SWTPM_CTRL_UNIX_PATH} &
420 if [ $rc -ne 0 ]; then
421 echo "Could not run ${SWTPM_EXE} using ${iface}"
424 [ $rc -ne 0 ] && return $rc
426 if wait_for_serversocket "${SWTPM_SERVER_PORT}" 127.0.0.1 2; then
427 echo "Server did not open port ${SWTPM_SERVER_PORT}"
431 if wait_for_socketfile ${SWTPM_CTRL_UNIX_PATH} 1; then
432 echo "Server did not create UnixIO socket ${SWTPM_CTRL_UNIX_PATH}"
439 [ -z "${SWTPM_CMD_UNIX_PATH}" ] && {
440 echo "SWTPM_CMD_UNIX_PATH not defined"
443 [ -z "${SWTPM_CTRL_PORT}" ] && {
444 echo "SWTPM_CTRL_PORT not defined"
448 if wait_socketfile_gone "${SWTPM_CMD_UNIX_PATH}" 2; then
449 echo "Unix socket ${SWTPM_CMD_UNIX_PATH} is still there"
452 if wait_serversocket_gone "${SWTPM_CTRL_PORT}" 127.0.0.1 1; then
453 echo "Port ${SWTPM_CTRL_PORT} is still used"
457 ${SWTPM_EXE} socket "$@" \
458 ${SWTPM_TEST_SECCOMP_OPT} \
459 --server type=unixio,path=${SWTPM_CMD_UNIX_PATH} \
460 --ctrl type=tcp,port=${SWTPM_CTRL_PORT} &
462 if [ $rc -ne 0 ]; then
463 echo "Could not run ${SWTPM_EXE} using ${iface}"
467 if wait_for_socketfile ${SWTPM_CMD_UNIX_PATH} 2; then
468 echo "Server did not create UnixIO socket ${SWTPM_CMD_UNIX_PATH}"
472 if wait_for_serversocket "${SWTPM_CTRL_PORT}" 127.0.0.1 1; then
473 echo "Server did not open port ${SWTPM_CTRL_PORT}"
480 [ -z "${SWTPM_CMD_UNIX_PATH}" ] && {
481 echo "SWTPM_CMD_UNIX_PATH not defined"
484 [ -z "${SWTPM_CTRL_UNIX_PATH}" ] && {
485 echo "SWTPM_CTRL_UNIX_PATH not defined"
489 if wait_socketfile_gone "${SWTPM_CMD_UNIX_PATH}" 2; then
490 echo "Unix socket ${SWTPM_CMD_UNIX_PATH} is still there"
493 if wait_socketfile_gone "${SWTPM_CTRL_UNIX_PATH}" 2; then
494 echo "Unix socket ${SWTPM_CTRL_UNIX_PATH} is still there"
498 ${SWTPM_EXE} socket "$@" \
499 ${SWTPM_TEST_SECCOMP_OPT} \
500 --server type=unixio,path=${SWTPM_CMD_UNIX_PATH} \
501 --ctrl type=unixio,path=${SWTPM_CTRL_UNIX_PATH} &
503 if [ $rc -ne 0 ]; then
504 echo "Could not run ${SWTPM_EXE} using ${iface}"
508 if wait_for_socketfile ${SWTPM_CMD_UNIX_PATH} 2; then
509 echo "Server did not create UnixIO socket ${SWTPM_CMD_UNIX_PATH}"
513 if wait_for_socketfile ${SWTPM_CTRL_UNIX_PATH} 1; then
514 echo "Server did not create UnixIO socket ${SWTPM_CTRL_UNIX_PATH}"
523 # Open the command channel/device on fd 100
525 # @param1: type of interface
526 # @param2: must be '100'
527 function swtpm_open_cmddev()
529 local iface=$1; shift
531 [ "$1" != "100" ] && {
532 echo "swtpm_opendev: Filedescriptor must be 100"
538 [ -z "${SWTPM_DEV_NAME}" ] && {
539 echo "SWTPM_DEV_NAME not defined"
543 exec 100<>${SWTPM_DEV_NAME}
546 socket+socket|socket+unix)
547 [ -z "${SWTPM_SERVER_NAME}" ] && {
548 echo "SWTPM_SERVER_NAME not defined"
551 [ -z "${SWTPM_SERVER_PORT}" ] && {
552 echo "SWTPM_SERVER_PORT not defined"
555 # Must first close on OS/X
557 exec 100<>/dev/tcp/${SWTPM_SERVER_NAME}/${SWTPM_SERVER_PORT}
560 unix+socket|unix+unix)
563 echo "swtpm_opendev: unsupported interface $iface"
568 # Transmit a command on fd 100
570 # @param1: type of interface
571 function swtpm_cmd_tx()
574 local cmd_path resp_path
578 swtpm_open_cmddev "${iface}" 100
582 echo -en "$2" > ${cmd_path}
583 cat ${cmd_path} >&100
590 socket+socket|socket+unix)
591 echo -en "$2" > ${cmd_path}
592 cat ${cmd_path} >&100
593 cat <&100 | od -t x1 -A n | \
598 unix+socket|unix+unix)
599 echo -en "$2" > ${cmd_path}
601 FILE:${cmd_path},rdonly \
602 UNIX-CLIENT:${SWTPM_CMD_UNIX_PATH} 2>&1 | \
607 echo "swtpm_opendev: unsupported interface $iface"
615 # Transmit a control command on fd 101
617 # @param1: type of interface
618 function swtpm_ctrl_tx()
621 local ctrl_path resp_path
624 socket+socket|unix+socket)
626 cat <&101 | od -t x1 -A n -w128
628 socket+unix|unix+unix)
630 echo -en "$2" > ${ctrl_path}
632 FILE:${ctrl_path},rdonly \
633 UNIX-CLIENT:${SWTPM_CTRL_UNIX_PATH} 2>&1 | \
639 echo "swtpm_opendev: unsupported interface $iface"
647 # @param1: type of interface
648 # @param2 ...: parameters to pass to swtpm_bios
649 function run_swtpm_bios()
657 [ -z "${SWTPM_DEV_NAME}" ] && {
658 echo "SWTPM_DEV_NAME not defined"
661 ${SWTPM_BIOS} --tpm-device ${SWTPM_DEV_NAME} $@
664 unix+unix|unix+socket)
665 [ -z "${SWTPM_CMD_UNIX_PATH}" ] && {
666 echo "SWTPM_CMD_UNIX_PATH not defined"
669 ${SWTPM_BIOS} --unix ${SWTPM_CMD_UNIX_PATH} $@
672 socket+unix|socket+socket)
673 [ -z "${SWTPM_SERVER_PORT}" ] && {
674 echo "SWTPM_SERVER_PORT not defined"
677 ${SWTPM_BIOS} --tcp ${SWTPM_SERVER_NAME}:${SWTPM_SERVER_PORT} $@
681 echo "run_swtpm_bios: unsupported interface $iface"
686 # Get the size of a file in bytes
689 function get_filesize()
691 if [[ "$(uname -s)" =~ (Linux|CYGWIN_NT-) ]]; then
699 # Get the file mode bits in octal format
702 function get_filemode()
704 if [[ "$(uname -s)" =~ (Linux|CYGWIN_NT-) ]]; then
712 # Get the file owner uid and gid
715 function get_fileowner()
717 if [[ "$(uname -s)" =~ (Linux|CYGWIN_NT-) ]]; then
725 # Get the file owner user name and group name
728 function get_fileowner_names()
730 if [[ "$(uname -s)" =~ (Linux|CYGWIN_NT-) ]]; then
734 stat -f"%Su %Sg" "$1"
738 # Get the SHA1 of a file
741 function get_sha1_file()
743 if ! [ -r "$1" ]; then
744 echo "[file $1 does not exist]"
747 case "$(uname -s)" in
749 sha1sum "$1" | cut -f1 -d" "
752 shasum "$1" | cut -f1 -d" "
756 sha1 "$1" | cut -d "=" -f2 | tr -d " "
760 # Display process that have the same name
762 # @1: process name to match
763 function display_processes_by_name()
768 ps aux | grep "${name}" | grep -v grep
772 # Check whether seccomp support is compiled in
776 # Returns 0 if seccomp is supported, 1 otherwise
777 function has_seccomp_support()
781 local tmp=$(${swtpm_exe} socket --help | grep -E "\-\-seccomp")
783 [ -n "${tmp}" ] && return 0
787 # Check whether the given process runs with the given seccomp
788 # profile type IF the given swtpm executable has seccomp support
790 # @1: Path to swtpm executable from which process was started
792 # @3: The expected seccomp profile type
793 function check_seccomp_profile()
801 if ! has_seccomp_support "${swtpm_exe}"; then
804 if [ -n "${SWTPM_TEST_SECCOMP_OPT}" ]; then
808 tmp=$(grep -E "^Seccomp" /proc/self/status |
811 if [ "${tmp}" != "0" ]; then
812 echo "check_seccomp_profile: skipping check since test env." \
813 "runs with in a seccomp profile overriding --seccomp"
817 tmp=$(grep -E "^Seccomp" /proc/${swtpm_pid}/status |
820 if [ "${tmp}" != ${profile} ]; then
821 echo "Process ${swtpm_pid} has wrong seccomp profile type"
822 echo "Expected: ${profile}"
823 echo "Actual : ${tmp}"
829 # Validate the content of the pid file
831 # @2: pid file filename
832 function validate_pidfile()
836 local rpid="$(cat $pidfile)"
838 if [ -z "$rpid" ]; then
840 rpid="$(cat $pidfile)"
843 if [ "$pid" != "$rpid" ]; then
844 echo "Error: pid file contains unexpected PID value."
845 echo "expected: $pid"
846 echo "actual : $(cat $pidfile)"
851 # Check whether swtpm can use a TPM 1.2
852 function skip_test_no_tpm12()
856 local res=$(${swtpm_exe} socket --print-capabilities | grep '"tpm-1.2"')
857 if [ -z "${res}" ]; then
858 echo "${swtpm_exe} does not provide a TPM 1.2"
863 # Check whether swtpm can use a TPM 2.0
864 function skip_test_no_tpm20()
868 local res=$(${swtpm_exe} socket --print-capabilities | grep '"tpm-2.0"')
869 if [ -z "${res}" ]; then
870 echo "${swtpm_exe} does not provide a TPM 2.0"
875 # Test whether swtpm has a chardev interface; Returns 0 if true, 1 otherwise
876 function test_swtpm_has_chardev()
880 local res=$(${swtpm_exe} chardev --help 2>&1 |
881 grep "Unsupported TPM interface")
882 if [ -z "${res}" ]; then
888 # Skip test if swtpm does not support chardev interface
889 function skip_test_no_chardev()
893 if ! test_swtpm_has_chardev "${swtpm_exe}"; then
894 echo "${swtpm_exe} does not support chardev interface"
899 # Check whether swtpm links with ASAN
900 function skip_test_linked_with_asan()
906 if [[ "$(uname -s)" =~ Linux ]]; then
907 if [ -z "$(file "${swtpm_exe}" | grep ELF)" ]; then
908 act_exe="$(dirname "${swtpm_exe}")"/.libs/"$(basename "${swtpm_exe}")"
910 act_exe="${swtpm_exe}"
912 if [ -n "$(nm "${act_exe}" | grep __asan_)" ]; then
913 echo "${act_exe} is built with ASAN"
919 # Have swtpm lock or re-lock the storage. Neither locking nor re-locking
920 # may produce an error
922 # @param1: reason like 'lock' or 're-lock'
923 function swtpm_lock_storage()
927 if ! run_swtpm_ioctl "${SWTPM_INTERFACE}" --lock-storage 0; then
928 echo "Error: 'swtpm_ioctl --lock-storage' to ${reason} storage failed"
933 # Check that swtpm has no lock on the directory backend storage
934 function check_swtpm_no_storage_lock()
938 if [ -d "/proc/${pid}/fd" ]; then
939 if [ -n "$(ls -l "/proc/${pid}/fd" | grep -E "\.lock\$")" ]; then
940 echo "Error: swtpm must not have storage locked"
944 elif [ -n "$(type -P lsof)" ]; then
945 if [ -n "$(lsof -p "${pid}" | grep -e "\.lock\$")" ]; then
946 echo "Error: swtpm must not have storage locked"
951 echo "Missing procfs directory and lsof tool to determine open files."
956 # Check that swtpm has a lock on the directory backend storage
957 function check_swtpm_storage_locked()
961 if [ -d "/proc/${pid}/fd" ]; then
962 if [ -z "$(ls -l "/proc/${pid}/fd" | grep -E "\.lock\$")" ]; then
963 echo "Error: swtpm must have storage locked"
967 elif [ -n "$(type -P lsof)" ]; then
968 if [ -z "$(lsof -p "${pid}" | grep -e "\.lock\$")" ]; then
969 echo "Error: swtpm must have storage locked"
974 echo "Missing procfs directory and lsof tool to determine open files."