]> git.proxmox.com Git - swtpm.git/blob - tests/common
packaging: track dbgsym package for swtpm-libs and swtpm-tools
[swtpm.git] / tests / common
1
2 SWTPM=swtpm
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}
8 ECHO=$(type -P echo)
9
10 case "$(uname -s)" in
11 Darwin)
12 CERTTOOL=gnutls-certtool;;
13 *)
14 CERTTOOL=certtool;;
15 esac
16
17 # Note: Do not use file descriptors above 127 due to OpenBSD.
18
19 # Kill a process quietly
20 # @1: signal, e.g. -9
21 # @2: pid
22 function kill_quiet()
23 {
24 local sig="$1"
25 local pid="$2"
26
27 bash -c "kill $sig $pid &>/dev/null"
28 return $?
29 }
30
31 # Wait for a regular file to appear and for it to have > 0 bytes
32 #
33 # @1: filename
34 # @2: timeout in seconds
35 function wait_for_file()
36 {
37 local filename="$1"
38 local timeout="$2"
39
40 local loops=$((timeout * 10)) loop
41
42 for ((loop=0; loop<loops; loop++)); do
43 [ -f "${filename}" ] && [ $(get_filesize ${filename}) != 0 ] && {
44 return 1
45 }
46 sleep 0.1
47 done
48 return 0
49 }
50
51 # Wait for a regular file to disappear
52 #
53 # @1: filename
54 # @2: timeout in seconds
55 function wait_file_gone()
56 {
57 local filename="$1"
58 local timeout="$2"
59
60 local loops=$((timeout * 10)) loop
61
62 for ((loop=0; loop<loops; loop++)); do
63 [ -f "${filename}" ] || return 1
64 sleep 0.1
65 done
66 return 0
67 }
68
69 # Wait for a process with given PID to be gone
70 #
71 # @1: pid
72 # @2: timeout in seconds
73 function wait_process_gone()
74 {
75 local pid="$1"
76 local timeout="$2"
77
78 local loops=$((timeout * 10)) loop
79
80 for ((loop=0; loop<loops; loop++)); do
81 kill_quiet -0 ${pid} || return 1
82 sleep 0.1
83 done
84 return 0
85 }
86
87 # Wait for a chardev to appear
88 #
89 # @1: filename
90 # @2: timeout in seconds
91 function wait_for_chardev()
92 {
93 local filename="$1"
94 local timeout="$2"
95
96 local loops=$((timeout * 10)) loop
97
98 for ((loop=0; loop<loops; loop++)); do
99 [ -c "${filename}" ] && return 1
100 sleep 0.1
101 done
102 return 0
103 }
104
105 # Wait for a chardev to disappear
106 #
107 # @1: filename
108 # @2: timeout in seconds
109 function wait_chardev_gone()
110 {
111 local filename="$1"
112 local timeout="$2"
113
114 local loops=$((timeout * 10)) loop
115
116 for ((loop=0; loop<loops; loop++)); do
117 [ -c "${filename}" ] || return 1
118 sleep 0.1
119 done
120 return 0
121 }
122
123 # Wait for a socket file to appear
124 #
125 # @1: filename
126 # @2: timeout in seconds
127 function wait_for_socketfile()
128 {
129 local filename="$1"
130 local timeout="$2"
131
132 local loops=$((timeout * 10)) loop
133
134 for ((loop=0; loop<loops; loop++)); do
135 [ -S "${filename}" ] && return 1
136 sleep 0.1
137 done
138 return 0
139 }
140
141 # Wait for a socket file to disappear
142 #
143 # @1: filename
144 # @2: timeout in seconds
145 function wait_socketfile_gone()
146 {
147 local filename="$1"
148 local timeout="$2"
149
150 local loops=$((timeout * 10)) loop
151
152 for ((loop=0; loop<loops; loop++)); do
153 [ -S "${filename}" ] || return 1
154 sleep 0.1
155 done
156 return 0
157 }
158
159 # Wait for a server socket to appear
160 #
161 # @1: port
162 # @2: host
163 # @3: timeout in seconds
164 function wait_for_serversocket()
165 {
166 local port="$1"
167 local host="$2"
168 local timeout="$3"
169
170 local loops=$((timeout * 10)) loop
171
172 for ((loop=0; loop<loops; loop++)); do
173 (exec 127<>/dev/tcp/${host}/${port}) &>/dev/null
174 [ $? -eq 0 ] && return 1
175 sleep 0.1
176 done
177 return 0
178 }
179
180 # Wait for a server socket to disappear
181 #
182 # @1: port
183 # @2: host
184 # @3: timeout in seconds
185 function wait_serversocket_gone()
186 {
187 local port="$1"
188 local host="$2"
189 local timeout="$3"
190
191 local loops=$((timeout * 10)) loop
192
193 for ((loop=0; loop<loops; loop++)); do
194 (exec 127<>/dev/tcp/${host}/${port}) &>/dev/null
195 [ $? -eq 0 ] || return 1
196 sleep 0.1
197 done
198 return 0
199 }
200
201 # Wait for a TCP port to open for listening
202 # @1: port
203 # @2: id of process to open port
204 # @3: timeout in seconds
205 function wait_port_open()
206 {
207 local port=$1
208 local pid=$2
209 local timeout=$3
210
211 local loops=$((timeout * 10)) loop
212 local NETSTAT=$(type -P netstat)
213
214 for ((loop = 0; loop < loops; loop++)); do
215 if [ -n "$NETSTAT" ]; then
216 if [ -n "$(netstat -naptl 2>/dev/null |
217 grep "LISTEN" |
218 grep " $pid/" |
219 grep ":$port ")" ]; then
220 return 1
221 fi
222 else
223 if [ -n "$(ss -nptl |
224 grep ",pid=${pid}," |
225 grep ":$port ")" ]; then
226 return 1
227 fi
228 fi
229 sleep 0.1
230 done
231 return 0
232 }
233
234 # Wait for a TCP listening port to close
235 # @1: port
236 # @2: id of process to close port
237 # @3: timeout in seconds
238 function wait_port_closed()
239 {
240 local port=$1
241 local pid=$2
242 local timeout=$3
243
244 local loops=$((timeout * 10)) loop
245 local NETSTAT=$(type -P netstat)
246
247 for ((loop = 0; loop < loops; loop++)); do
248 if [ -n "$NETSTAT" ]; then
249 if [ -z "$(netstat -naptl 2>/dev/null |
250 grep "LISTEN" |
251 grep " $pid/" |
252 grep ":$port ")" ]; then
253 return 1
254 fi
255 else
256 if [ -z "$(ss -nptl |
257 grep ",pid=${pid}," |
258 grep ":$port ")" ]; then
259 return 1
260 fi
261 fi
262 sleep 0.1
263 done
264 return 0
265 }
266
267 # Run the swtpm_ioctl command
268 #
269 # @param1: type of interface
270 function run_swtpm_ioctl()
271 {
272 local iface=$1; shift
273
274 case "${iface}" in
275 cuse)
276 [ -z "${SWTPM_DEV_NAME}" ] && {
277 echo "SWTPM_DEV_NAME not defined"
278 exit 1
279 }
280 ${SWTPM_IOCTL} $@ ${SWTPM_DEV_NAME}
281 return $?
282 ;;
283 socket+socket|unix+socket)
284 [ -z "${SWTPM_SERVER_NAME}" ] && {
285 echo "SWTPM_SERVER_NAME not defined"
286 exit 1
287 }
288 [ -z "${SWTPM_SERVER_PORT}" ] && {
289 echo "SWTPM_SERVER_PORT not defined"
290 exit 1
291 }
292 ${SWTPM_IOCTL} \
293 --tcp ${SWTPM_SERVER_NAME}:${SWTPM_CTRL_PORT} \
294 $@
295 return $?
296 ;;
297 socket+unix|unix+unix)
298 [ -z "${SWTPM_CTRL_UNIX_PATH}" ] && {
299 echo "SWTPM_CTRL_UNIX_PATH not defined"
300 exit 1
301 }
302 ${SWTPM_IOCTL} \
303 --unix ${SWTPM_CTRL_UNIX_PATH} \
304 $@
305 return $?
306 ;;
307 esac
308 }
309
310 # Start the swtpm in the background
311 #
312 # @param1: type of interface
313 # @param2.. : parameters to pass to 'swtpm'
314 function run_swtpm()
315 {
316 local iface=$1; shift
317 local swtpm_server_disconnect=""
318
319 echo "==== Starting swtpm with interfaces ${iface} ===="
320 if [ -z "${SWTPM_SERVER_NO_DISCONNECT}" ]; then
321 swtpm_server_disconnect=",disconnect"
322 fi
323
324 case "${iface}" in
325 cuse)
326 [ -z "${SWTPM_DEV_NAME}" ] && {
327 echo "SWTPM_DEV_NAME not defined"
328 exit 1
329 }
330
331 if wait_chardev_gone ${SWTPM_DEV_NAME} 2; then
332 echo "${SWTPM_DEV_NAME} is still there and may be used."
333 exit 1
334 fi
335
336 ${SWTPM_EXE} cuse "$@" ${SWTPM_TEST_SECCOMP_OPT} \
337 -n ${SWTPM_DEV_NAME##*/}
338 rc=$?
339 if [ $rc -ne 0 ]; then
340 echo "Could not run ${SWTPM_EXE} using ${iface}"
341 exit 1
342 fi
343 if wait_for_chardev ${SWTPM_DEV_NAME} 2; then
344 echo "$SWTPM_DEV_NAME did not appear"
345 exit 1
346 fi
347
348 SWTPM_PID=$(ps aux |
349 grep "cuse" |
350 grep -E " ${SWTPM_DEV_NAME##*/}\$" |
351 grep -v grep |
352 gawk '{print $2}')
353 return $?
354 ;;
355 socket+socket)
356 [ -z "${SWTPM_SERVER_PORT}" ] && {
357 echo "SWTPM_SERVER_PORT not defined"
358 exit 1
359 }
360 [ -z "${SWTPM_CTRL_PORT}" ] && {
361 echo "SWTPM_CTRL_PORT not defined"
362 exit 1
363 }
364
365 if wait_serversocket_gone "${SWTPM_SERVER_PORT}" 127.0.0.1 2; then
366 echo "Port ${SWTPM_SERVER_PORT} is still used"
367 exit 1
368 fi
369 if wait_serversocket_gone "${SWTPM_CTRL_PORT}" 127.0.0.1 1; then
370 echo "Port ${SWTPM_CTRL_PORT} is still used"
371 exit 1
372 fi
373
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} &
378 rc=$?
379 if [ $rc -ne 0 ]; then
380 echo "Could not run ${SWTPM_EXE} using ${iface}"
381 exit 1
382 fi
383 SWTPM_PID=$!
384 if wait_for_serversocket "${SWTPM_SERVER_PORT}" 127.0.0.1 2; then
385 echo "Server did not open port ${SWTPM_SERVER_PORT}"
386 kill -9 ${SWTPM_PID}
387 exit 1
388 fi
389 if wait_for_serversocket "${SWTPM_CTRL_PORT}" 127.0.0.1 1; then
390 echo "Server did not open port ${SWTPM_CTRL_PORT}"
391 kill -9 ${SWTPM_PID}
392 exit 1
393 fi
394 return 0
395 ;;
396 socket+unix)
397 [ -z "${SWTPM_SERVER_PORT}" ] && {
398 echo "SWTPM_SERVER_PORT not defined"
399 exit 1
400 }
401 [ -z "${SWTPM_CTRL_UNIX_PATH}" ] && {
402 echo "SWTPM_CTRL_UNIX_PATH not defined"
403 exit 1
404 }
405
406 if wait_serversocket_gone "${SWTPM_SERVER_PORT}" 127.0.0.1 2; then
407 echo "Port ${SWTPM_SERVER_PORT} is still used"
408 exit 1
409 fi
410 if wait_socketfile_gone "${SWTPM_CTRL_UNIX_PATH}" 2; then
411 echo "Unix socket ${SWTPM_CTRL_UNIX_PATH} is still there"
412 exit 1
413 fi
414
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} &
419 rc=$?
420 if [ $rc -ne 0 ]; then
421 echo "Could not run ${SWTPM_EXE} using ${iface}"
422 exit 1
423 fi
424 [ $rc -ne 0 ] && return $rc
425 SWTPM_PID=$!
426 if wait_for_serversocket "${SWTPM_SERVER_PORT}" 127.0.0.1 2; then
427 echo "Server did not open port ${SWTPM_SERVER_PORT}"
428 kill -9 ${SWTPM_PID}
429 exit 1
430 fi
431 if wait_for_socketfile ${SWTPM_CTRL_UNIX_PATH} 1; then
432 echo "Server did not create UnixIO socket ${SWTPM_CTRL_UNIX_PATH}"
433 kill -9 ${SWTPM_PID}
434 exit 1
435 fi
436 return 0
437 ;;
438 unix+socket)
439 [ -z "${SWTPM_CMD_UNIX_PATH}" ] && {
440 echo "SWTPM_CMD_UNIX_PATH not defined"
441 exit 1
442 }
443 [ -z "${SWTPM_CTRL_PORT}" ] && {
444 echo "SWTPM_CTRL_PORT not defined"
445 exit 1
446 }
447
448 if wait_socketfile_gone "${SWTPM_CMD_UNIX_PATH}" 2; then
449 echo "Unix socket ${SWTPM_CMD_UNIX_PATH} is still there"
450 exit 1
451 fi
452 if wait_serversocket_gone "${SWTPM_CTRL_PORT}" 127.0.0.1 1; then
453 echo "Port ${SWTPM_CTRL_PORT} is still used"
454 exit 1
455 fi
456
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} &
461 rc=$?
462 if [ $rc -ne 0 ]; then
463 echo "Could not run ${SWTPM_EXE} using ${iface}"
464 exit 1
465 fi
466 SWTPM_PID=$!
467 if wait_for_socketfile ${SWTPM_CMD_UNIX_PATH} 2; then
468 echo "Server did not create UnixIO socket ${SWTPM_CMD_UNIX_PATH}"
469 kill -9 ${SWTPM_PID}
470 exit 1
471 fi
472 if wait_for_serversocket "${SWTPM_CTRL_PORT}" 127.0.0.1 1; then
473 echo "Server did not open port ${SWTPM_CTRL_PORT}"
474 kill -9 ${SWTPM_PID}
475 exit 1
476 fi
477 return 0
478 ;;
479 unix+unix)
480 [ -z "${SWTPM_CMD_UNIX_PATH}" ] && {
481 echo "SWTPM_CMD_UNIX_PATH not defined"
482 exit 1
483 }
484 [ -z "${SWTPM_CTRL_UNIX_PATH}" ] && {
485 echo "SWTPM_CTRL_UNIX_PATH not defined"
486 exit 1
487 }
488
489 if wait_socketfile_gone "${SWTPM_CMD_UNIX_PATH}" 2; then
490 echo "Unix socket ${SWTPM_CMD_UNIX_PATH} is still there"
491 exit 1
492 fi
493 if wait_socketfile_gone "${SWTPM_CTRL_UNIX_PATH}" 2; then
494 echo "Unix socket ${SWTPM_CTRL_UNIX_PATH} is still there"
495 exit 1
496 fi
497
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} &
502 rc=$?
503 if [ $rc -ne 0 ]; then
504 echo "Could not run ${SWTPM_EXE} using ${iface}"
505 exit 1
506 fi
507 SWTPM_PID=$!
508 if wait_for_socketfile ${SWTPM_CMD_UNIX_PATH} 2; then
509 echo "Server did not create UnixIO socket ${SWTPM_CMD_UNIX_PATH}"
510 kill -9 ${SWTPM_PID}
511 exit 1
512 fi
513 if wait_for_socketfile ${SWTPM_CTRL_UNIX_PATH} 1; then
514 echo "Server did not create UnixIO socket ${SWTPM_CTRL_UNIX_PATH}"
515 kill -9 ${SWTPM_PID}
516 exit 1
517 fi
518 return 0
519 ;;
520 esac
521 }
522
523 # Open the command channel/device on fd 100
524 #
525 # @param1: type of interface
526 # @param2: must be '100'
527 function swtpm_open_cmddev()
528 {
529 local iface=$1; shift
530
531 [ "$1" != "100" ] && {
532 echo "swtpm_opendev: Filedescriptor must be 100"
533 exit 1
534 }
535
536 case "${iface}" in
537 cuse)
538 [ -z "${SWTPM_DEV_NAME}" ] && {
539 echo "SWTPM_DEV_NAME not defined"
540 exit 1
541 }
542 exec 100>&-
543 exec 100<>${SWTPM_DEV_NAME}
544 return $?
545 ;;
546 socket+socket|socket+unix)
547 [ -z "${SWTPM_SERVER_NAME}" ] && {
548 echo "SWTPM_SERVER_NAME not defined"
549 exit 1
550 }
551 [ -z "${SWTPM_SERVER_PORT}" ] && {
552 echo "SWTPM_SERVER_PORT not defined"
553 exit 1
554 }
555 # Must first close on OS/X
556 exec 100>&-
557 exec 100<>/dev/tcp/${SWTPM_SERVER_NAME}/${SWTPM_SERVER_PORT}
558 return $?
559 ;;
560 unix+socket|unix+unix)
561 ;;
562 *)
563 echo "swtpm_opendev: unsupported interface $iface"
564 exit 1
565 esac
566 }
567
568 # Transmit a command on fd 100
569 #
570 # @param1: type of interface
571 function swtpm_cmd_tx()
572 {
573 local iface=$1
574 local cmd_path resp_path
575
576 cmd_path=$(mktemp)
577
578 swtpm_open_cmddev "${iface}" 100
579
580 case "${iface}" in
581 cuse)
582 echo -en "$2" > ${cmd_path}
583 cat ${cmd_path} >&100
584 cat <&100 | \
585 od -t x1 -A n | \
586 tr -s ' ' | \
587 tr -d '\n' | \
588 sed 's/ $//g'
589 ;;
590 socket+socket|socket+unix)
591 echo -en "$2" > ${cmd_path}
592 cat ${cmd_path} >&100
593 cat <&100 | od -t x1 -A n | \
594 tr -s ' ' | \
595 tr -d '\n' | \
596 sed 's/ $//g'
597 ;;
598 unix+socket|unix+unix)
599 echo -en "$2" > ${cmd_path}
600 socat -x -t50 \
601 FILE:${cmd_path},rdonly \
602 UNIX-CLIENT:${SWTPM_CMD_UNIX_PATH} 2>&1 | \
603 sed -n '/^ /p' | \
604 tail -n1
605 ;;
606 *)
607 echo "swtpm_opendev: unsupported interface $iface"
608 rm -f ${cmd_path}
609 exit 1
610 esac
611
612 rm -f ${cmd_path}
613 }
614
615 # Transmit a control command on fd 101
616 #
617 # @param1: type of interface
618 function swtpm_ctrl_tx()
619 {
620 local iface=$1
621 local ctrl_path resp_path
622
623 case "${iface}" in
624 socket+socket|unix+socket)
625 $ECHO -en "$2" >&101
626 cat <&101 | od -t x1 -A n -w128
627 ;;
628 socket+unix|unix+unix)
629 ctrl_path=$(mktemp)
630 echo -en "$2" > ${ctrl_path}
631 socat -x -t50 \
632 FILE:${ctrl_path},rdonly \
633 UNIX-CLIENT:${SWTPM_CTRL_UNIX_PATH} 2>&1 | \
634 sed -n '/^ /p' | \
635 tail -n1
636 rm -f ${ctrl_path}
637 ;;
638 *)
639 echo "swtpm_opendev: unsupported interface $iface"
640 exit 1
641 esac
642 }
643
644
645 # Run swtpm_bios
646 #
647 # @param1: type of interface
648 # @param2 ...: parameters to pass to swtpm_bios
649 function run_swtpm_bios()
650 {
651 local iface=$1
652
653 shift
654
655 case "${iface}" in
656 cuse)
657 [ -z "${SWTPM_DEV_NAME}" ] && {
658 echo "SWTPM_DEV_NAME not defined"
659 exit 1
660 }
661 ${SWTPM_BIOS} --tpm-device ${SWTPM_DEV_NAME} $@
662 return $?
663 ;;
664 unix+unix|unix+socket)
665 [ -z "${SWTPM_CMD_UNIX_PATH}" ] && {
666 echo "SWTPM_CMD_UNIX_PATH not defined"
667 exit 1
668 }
669 ${SWTPM_BIOS} --unix ${SWTPM_CMD_UNIX_PATH} $@
670 return $?
671 ;;
672 socket+unix|socket+socket)
673 [ -z "${SWTPM_SERVER_PORT}" ] && {
674 echo "SWTPM_SERVER_PORT not defined"
675 exit 1
676 }
677 ${SWTPM_BIOS} --tcp ${SWTPM_SERVER_NAME}:${SWTPM_SERVER_PORT} $@
678 return $?
679 ;;
680 *)
681 echo "run_swtpm_bios: unsupported interface $iface"
682 exit 1
683 esac
684 }
685
686 # Get the size of a file in bytes
687 #
688 # @1: filename
689 function get_filesize()
690 {
691 if [[ "$(uname -s)" =~ (Linux|CYGWIN_NT-) ]]; then
692 stat -c%s "$1"
693 else
694 # OpenBSD
695 stat -f%z "$1"
696 fi
697 }
698
699 # Get the file mode bits in octal format
700 #
701 # @1: filename
702 function get_filemode()
703 {
704 if [[ "$(uname -s)" =~ (Linux|CYGWIN_NT-) ]]; then
705 stat -c%a "$1"
706 else
707 # BSDs
708 stat -f%Lp "$1"
709 fi
710 }
711
712 # Get the file owner uid and gid
713 #
714 # @1: filename
715 function get_fileowner()
716 {
717 if [[ "$(uname -s)" =~ (Linux|CYGWIN_NT-) ]]; then
718 stat -c"%u %g" "$1"
719 else
720 # BSDs
721 stat -f"%u %g" "$1"
722 fi
723 }
724
725 # Get the file owner user name and group name
726 #
727 # @1: filename
728 function get_fileowner_names()
729 {
730 if [[ "$(uname -s)" =~ (Linux|CYGWIN_NT-) ]]; then
731 stat -c"%U %G" "$1"
732 else
733 # BSDs
734 stat -f"%Su %Sg" "$1"
735 fi
736 }
737
738 # Get the SHA1 of a file
739 #
740 # @1: filename
741 function get_sha1_file()
742 {
743 if ! [ -r "$1" ]; then
744 echo "[file $1 does not exist]"
745 return
746 fi
747 case "$(uname -s)" in
748 Linux|CYGWIN*)
749 sha1sum "$1" | cut -f1 -d" "
750 ;;
751 Darwin)
752 shasum "$1" | cut -f1 -d" "
753 ;;
754 *)
755 # OpenBSD
756 sha1 "$1" | cut -d "=" -f2 | tr -d " "
757 esac
758 }
759
760 # Display process that have the same name
761 #
762 # @1: process name to match
763 function display_processes_by_name()
764 {
765 local name="$1"
766
767 if [ 1 -eq 0 ]; then
768 ps aux | grep "${name}" | grep -v grep
769 fi
770 }
771
772 # Check whether seccomp support is compiled in
773 #
774 # @1: path to swtpm
775 #
776 # Returns 0 if seccomp is supported, 1 otherwise
777 function has_seccomp_support()
778 {
779 local swtpm_exe="$1"
780
781 local tmp=$(${swtpm_exe} socket --help | grep -E "\-\-seccomp")
782
783 [ -n "${tmp}" ] && return 0
784 return 1
785 }
786
787 # Check whether the given process runs with the given seccomp
788 # profile type IF the given swtpm executable has seccomp support
789 #
790 # @1: Path to swtpm executable from which process was started
791 # @2: The process ID
792 # @3: The expected seccomp profile type
793 function check_seccomp_profile()
794 {
795 local swtpm_exe="$1"
796 local swtpm_pid="$2"
797 local profile="$3"
798
799 local tmp
800
801 if ! has_seccomp_support "${swtpm_exe}"; then
802 return 0
803 fi
804 if [ -n "${SWTPM_TEST_SECCOMP_OPT}" ]; then
805 return 0
806 fi
807
808 tmp=$(grep -E "^Seccomp" /proc/self/status |
809 cut -d":" -f2 |
810 tr -d '\t')
811 if [ "${tmp}" != "0" ]; then
812 echo "check_seccomp_profile: skipping check since test env." \
813 "runs with in a seccomp profile overriding --seccomp"
814 return 0
815 fi
816
817 tmp=$(grep -E "^Seccomp" /proc/${swtpm_pid}/status |
818 cut -d":" -f2 |
819 tr -d '\t')
820 if [ "${tmp}" != ${profile} ]; then
821 echo "Process ${swtpm_pid} has wrong seccomp profile type"
822 echo "Expected: ${profile}"
823 echo "Actual : ${tmp}"
824 return 1
825 fi
826 return 0
827 }
828
829 # Validate the content of the pid file
830 # @1: Expected PID
831 # @2: pid file filename
832 function validate_pidfile()
833 {
834 local pid="$1"
835 local pidfile="$2"
836 local rpid="$(cat $pidfile)"
837
838 if [ -z "$rpid" ]; then
839 sleep 0.1
840 rpid="$(cat $pidfile)"
841 fi
842
843 if [ "$pid" != "$rpid" ]; then
844 echo "Error: pid file contains unexpected PID value."
845 echo "expected: $pid"
846 echo "actual : $(cat $pidfile)"
847 exit 1
848 fi
849 }
850
851 # Check whether swtpm can use a TPM 1.2
852 function skip_test_no_tpm12()
853 {
854 local swtpm_exe="$1"
855
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"
859 exit 77
860 fi
861 }
862
863 # Check whether swtpm can use a TPM 2.0
864 function skip_test_no_tpm20()
865 {
866 local swtpm_exe="$1"
867
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"
871 exit 77
872 fi
873 }
874
875 # Test whether swtpm has a chardev interface; Returns 0 if true, 1 otherwise
876 function test_swtpm_has_chardev()
877 {
878 local swtpm_exe="$1"
879
880 local res=$(${swtpm_exe} chardev --help 2>&1 |
881 grep "Unsupported TPM interface")
882 if [ -z "${res}" ]; then
883 return 0
884 fi
885 return 1
886 }
887
888 # Skip test if swtpm does not support chardev interface
889 function skip_test_no_chardev()
890 {
891 local swtpm_exe="$1"
892
893 if ! test_swtpm_has_chardev "${swtpm_exe}"; then
894 echo "${swtpm_exe} does not support chardev interface"
895 exit 77
896 fi
897 }
898
899 # Check whether swtpm links with ASAN
900 function skip_test_linked_with_asan()
901 {
902 local swtpm_exe="$1"
903
904 local act_exe
905
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}")"
909 else
910 act_exe="${swtpm_exe}"
911 fi
912 if [ -n "$(nm "${act_exe}" | grep __asan_)" ]; then
913 echo "${act_exe} is built with ASAN"
914 exit 77
915 fi
916 fi
917 }
918
919 # Have swtpm lock or re-lock the storage. Neither locking nor re-locking
920 # may produce an error
921 #
922 # @param1: reason like 'lock' or 're-lock'
923 function swtpm_lock_storage()
924 {
925 local reason="$1"
926
927 if ! run_swtpm_ioctl "${SWTPM_INTERFACE}" --lock-storage 0; then
928 echo "Error: 'swtpm_ioctl --lock-storage' to ${reason} storage failed"
929 exit 1
930 fi
931 }
932
933 # Check that swtpm has no lock on the directory backend storage
934 function check_swtpm_no_storage_lock()
935 {
936 local pid="$1"
937
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"
941 ls -l /proc/${1}/fd
942 exit 1
943 fi
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"
947 lsof -p "${pid}"
948 exit 1
949 fi
950 else
951 echo "Missing procfs directory and lsof tool to determine open files."
952 exit 1
953 fi
954 }
955
956 # Check that swtpm has a lock on the directory backend storage
957 function check_swtpm_storage_locked()
958 {
959 local pid="$1"
960
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"
964 ls -l /proc/${1}/fd
965 exit 1
966 fi
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"
970 ls -l /proc/${1}/fd
971 exit 1
972 fi
973 else
974 echo "Missing procfs directory and lsof tool to determine open files."
975 exit 1
976 fi
977 }