]>
Commit | Line | Data |
---|---|---|
f3a14917 | 1 | |
f3a14917 | 2 | SWTPM=swtpm |
19e05751 SB |
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} | |
0db8249c | 6 | SWTPM_SETUP=${SWTPM_SETUP:-${ROOT}/src/swtpm_setup/swtpm_setup} |
88c7bdc9 | 7 | SWTPM_CERT=${SWTPM_CERT:-${ROOT}/src/swtpm_cert/swtpm_cert} |
f3a14917 SB |
8 | ECHO=$(type -P echo) |
9 | ||
e5bb6f4e SB |
10 | case "$(uname -s)" in |
11 | Darwin) | |
12 | CERTTOOL=gnutls-certtool;; | |
13 | *) | |
14 | CERTTOOL=certtool;; | |
15 | esac | |
16 | ||
35e571b4 SB |
17 | # Note: Do not use file descriptors above 127 due to OpenBSD. |
18 | ||
47c7ea77 SB |
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 | ||
86e8f605 | 31 | # Wait for a regular file to appear and for it to have > 0 bytes |
35e571b4 SB |
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 | |
86e8f605 | 43 | [ -f "${filename}" ] && [ $(get_filesize ${filename}) != 0 ] && { |
c46d6717 SB |
44 | return 1 |
45 | } | |
35e571b4 SB |
46 | sleep 0.1 |
47 | done | |
48 | return 0 | |
49 | } | |
50 | ||
6098d7ba SB |
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 | ||
142a2974 SB |
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 | |
47c7ea77 | 81 | kill_quiet -0 ${pid} || return 1 |
142a2974 SB |
82 | sleep 0.1 |
83 | done | |
84 | return 0 | |
85 | } | |
86 | ||
35e571b4 SB |
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 | ||
bd8f3581 SB |
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 | ||
35e571b4 SB |
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 | ||
bd8f3581 SB |
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 | ||
35e571b4 SB |
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 | ||
bd8f3581 SB |
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 | ||
c5748a53 SB |
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 | |
d4c60e44 | 212 | local NETSTAT=$(type -P netstat) |
c5748a53 SB |
213 | |
214 | for ((loop = 0; loop < loops; loop++)); do | |
d4c60e44 SB |
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 | |
c5748a53 SB |
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 | |
d4c60e44 | 245 | local NETSTAT=$(type -P netstat) |
c5748a53 SB |
246 | |
247 | for ((loop = 0; loop < loops; loop++)); do | |
d4c60e44 SB |
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 | |
c5748a53 SB |
261 | fi |
262 | sleep 0.1 | |
263 | done | |
264 | return 0 | |
265 | } | |
266 | ||
f3a14917 SB |
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 | |
03c7fe45 | 317 | local swtpm_server_disconnect="" |
f3a14917 SB |
318 | |
319 | echo "==== Starting swtpm with interfaces ${iface} ====" | |
03c7fe45 SB |
320 | if [ -z "${SWTPM_SERVER_NO_DISCONNECT}" ]; then |
321 | swtpm_server_disconnect=",disconnect" | |
322 | fi | |
f3a14917 SB |
323 | |
324 | case "${iface}" in | |
325 | cuse) | |
326 | [ -z "${SWTPM_DEV_NAME}" ] && { | |
327 | echo "SWTPM_DEV_NAME not defined" | |
328 | exit 1 | |
329 | } | |
35e571b4 | 330 | |
bd8f3581 SB |
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 | ||
b291eb83 | 336 | ${SWTPM_EXE} cuse "$@" ${SWTPM_TEST_SECCOMP_OPT} \ |
930c7ba1 | 337 | -n ${SWTPM_DEV_NAME##*/} |
35e571b4 SB |
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 | ||
f3a14917 SB |
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 | } | |
bd8f3581 SB |
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 | ||
b291eb83 | 374 | ${SWTPM_EXE} socket "$@" \ |
930c7ba1 | 375 | ${SWTPM_TEST_SECCOMP_OPT} \ |
03c7fe45 | 376 | --server type=tcp,port=${SWTPM_SERVER_PORT}${swtpm_server_disconnect} \ |
f3a14917 SB |
377 | --ctrl type=tcp,port=${SWTPM_CTRL_PORT} & |
378 | rc=$? | |
35e571b4 SB |
379 | if [ $rc -ne 0 ]; then |
380 | echo "Could not run ${SWTPM_EXE} using ${iface}" | |
381 | exit 1 | |
382 | fi | |
f3a14917 | 383 | SWTPM_PID=$! |
35e571b4 SB |
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 | |
f3a14917 SB |
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 | } | |
bd8f3581 SB |
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 | ||
b291eb83 | 415 | ${SWTPM_EXE} socket "$@" \ |
930c7ba1 | 416 | ${SWTPM_TEST_SECCOMP_OPT} \ |
03c7fe45 | 417 | --server type=tcp,port=${SWTPM_SERVER_PORT}${swtpm_server_disconnect} \ |
f3a14917 SB |
418 | --ctrl type=unixio,path=${SWTPM_CTRL_UNIX_PATH} & |
419 | rc=$? | |
35e571b4 SB |
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 | |
f3a14917 | 425 | SWTPM_PID=$! |
35e571b4 SB |
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 | |
f3a14917 SB |
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 | } | |
bd8f3581 SB |
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 | ||
b291eb83 | 457 | ${SWTPM_EXE} socket "$@" \ |
930c7ba1 | 458 | ${SWTPM_TEST_SECCOMP_OPT} \ |
f3a14917 SB |
459 | --server type=unixio,path=${SWTPM_CMD_UNIX_PATH} \ |
460 | --ctrl type=tcp,port=${SWTPM_CTRL_PORT} & | |
461 | rc=$? | |
35e571b4 SB |
462 | if [ $rc -ne 0 ]; then |
463 | echo "Could not run ${SWTPM_EXE} using ${iface}" | |
464 | exit 1 | |
465 | fi | |
f3a14917 | 466 | SWTPM_PID=$! |
35e571b4 SB |
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 | |
f3a14917 SB |
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 | } | |
bd8f3581 SB |
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 | ||
b291eb83 | 498 | ${SWTPM_EXE} socket "$@" \ |
930c7ba1 | 499 | ${SWTPM_TEST_SECCOMP_OPT} \ |
f3a14917 SB |
500 | --server type=unixio,path=${SWTPM_CMD_UNIX_PATH} \ |
501 | --ctrl type=unixio,path=${SWTPM_CTRL_UNIX_PATH} & | |
502 | rc=$? | |
35e571b4 SB |
503 | if [ $rc -ne 0 ]; then |
504 | echo "Could not run ${SWTPM_EXE} using ${iface}" | |
505 | exit 1 | |
506 | fi | |
f3a14917 | 507 | SWTPM_PID=$! |
35e571b4 SB |
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 | |
f3a14917 SB |
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 | } | |
b255d070 | 542 | exec 100>&- |
f3a14917 SB |
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 | } | |
80f98589 SB |
555 | # Must first close on OS/X |
556 | exec 100>&- | |
f3a14917 SB |
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 | ||
27aad728 SB |
576 | cmd_path=$(mktemp) |
577 | ||
b255d070 SB |
578 | swtpm_open_cmddev "${iface}" 100 |
579 | ||
f3a14917 SB |
580 | case "${iface}" in |
581 | cuse) | |
27aad728 SB |
582 | echo -en "$2" > ${cmd_path} |
583 | cat ${cmd_path} >&100 | |
b255d070 | 584 | cat <&100 | \ |
27aad728 SB |
585 | od -t x1 -A n | \ |
586 | tr -s ' ' | \ | |
587 | tr -d '\n' | \ | |
588 | sed 's/ $//g' | |
f3a14917 SB |
589 | ;; |
590 | socket+socket|socket+unix) | |
27aad728 SB |
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' | |
f3a14917 SB |
597 | ;; |
598 | unix+socket|unix+unix) | |
f3a14917 | 599 | echo -en "$2" > ${cmd_path} |
6d33f6eb | 600 | socat -x -t50 \ |
f3a14917 SB |
601 | FILE:${cmd_path},rdonly \ |
602 | UNIX-CLIENT:${SWTPM_CMD_UNIX_PATH} 2>&1 | \ | |
603 | sed -n '/^ /p' | \ | |
604 | tail -n1 | |
f3a14917 SB |
605 | ;; |
606 | *) | |
607 | echo "swtpm_opendev: unsupported interface $iface" | |
27aad728 | 608 | rm -f ${cmd_path} |
f3a14917 SB |
609 | exit 1 |
610 | esac | |
27aad728 SB |
611 | |
612 | rm -f ${cmd_path} | |
f3a14917 SB |
613 | } |
614 | ||
a19a8683 SB |
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} | |
6d33f6eb | 631 | socat -x -t50 \ |
a19a8683 SB |
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 | ||
f3a14917 SB |
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 | } | |
597d06ee SB |
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 | |
15b9ca6b | 692 | stat -c%s "$1" |
597d06ee SB |
693 | else |
694 | # OpenBSD | |
15b9ca6b | 695 | stat -f%z "$1" |
597d06ee SB |
696 | fi |
697 | } | |
698 | ||
f487473c SB |
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 | |
15b9ca6b | 705 | stat -c%a "$1" |
f487473c SB |
706 | else |
707 | # BSDs | |
15b9ca6b | 708 | stat -f%Lp "$1" |
f487473c SB |
709 | fi |
710 | } | |
711 | ||
bb0aa2ad SB |
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 | |
15b9ca6b | 718 | stat -c"%u %g" "$1" |
bb0aa2ad SB |
719 | else |
720 | # BSDs | |
15b9ca6b | 721 | stat -f"%u %g" "$1" |
bb0aa2ad SB |
722 | fi |
723 | } | |
724 | ||
30510820 SB |
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 | |
15b9ca6b | 731 | stat -c"%U %G" "$1" |
30510820 SB |
732 | else |
733 | # BSDs | |
15b9ca6b | 734 | stat -f"%Su %Sg" "$1" |
30510820 SB |
735 | fi |
736 | } | |
737 | ||
597d06ee SB |
738 | # Get the SHA1 of a file |
739 | # | |
740 | # @1: filename | |
741 | function get_sha1_file() | |
742 | { | |
15b9ca6b | 743 | if ! [ -r "$1" ]; then |
08c8820a SB |
744 | echo "[file $1 does not exist]" |
745 | return | |
746 | fi | |
80f98589 SB |
747 | case "$(uname -s)" in |
748 | Linux|CYGWIN*) | |
15b9ca6b | 749 | sha1sum "$1" | cut -f1 -d" " |
80f98589 SB |
750 | ;; |
751 | Darwin) | |
15b9ca6b | 752 | shasum "$1" | cut -f1 -d" " |
80f98589 SB |
753 | ;; |
754 | *) | |
597d06ee | 755 | # OpenBSD |
15b9ca6b | 756 | sha1 "$1" | cut -d "=" -f2 | tr -d " " |
80f98589 | 757 | esac |
597d06ee | 758 | } |
100317d5 SB |
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 | |
08c8820a | 770 | } |
a3820b86 SB |
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 | |
930c7ba1 SB |
804 | if [ -n "${SWTPM_TEST_SECCOMP_OPT}" ]; then |
805 | return 0 | |
806 | fi | |
a3820b86 | 807 | |
1ce7293d SB |
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 | ||
a3820b86 SB |
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 | } | |
01ad1d03 SB |
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" | |
996ad55f | 836 | local rpid="$(cat $pidfile)" |
01ad1d03 | 837 | |
996ad55f SB |
838 | if [ -z "$rpid" ]; then |
839 | sleep 0.1 | |
840 | rpid="$(cat $pidfile)" | |
841 | fi | |
842 | ||
843 | if [ "$pid" != "$rpid" ]; then | |
01ad1d03 SB |
844 | echo "Error: pid file contains unexpected PID value." |
845 | echo "expected: $pid" | |
846 | echo "actual : $(cat $pidfile)" | |
847 | exit 1 | |
848 | fi | |
849 | } | |
f1adde9f SB |
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 | } | |
c48dd1e2 MAL |
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 | } | |
346dc3d5 | 874 | |
122106b8 SB |
875 | # Test whether swtpm has a chardev interface; Returns 0 if true, 1 otherwise |
876 | function test_swtpm_has_chardev() | |
346dc3d5 SB |
877 | { |
878 | local swtpm_exe="$1" | |
879 | ||
880 | local res=$(${swtpm_exe} chardev --help 2>&1 | | |
881 | grep "Unsupported TPM interface") | |
122106b8 SB |
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 | |
346dc3d5 SB |
894 | echo "${swtpm_exe} does not support chardev interface" |
895 | exit 77 | |
896 | fi | |
897 | } | |
30510820 SB |
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 | |
3928bd2c SB |
912 | if [ -n "$(nm "${act_exe}" | grep __asan_)" ]; then |
913 | echo "${act_exe} is built with ASAN" | |
30510820 SB |
914 | exit 77 |
915 | fi | |
916 | fi | |
917 | } | |
e5fdd1c1 SB |
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 | } |