Skip to content
This repository has been archived by the owner on Sep 6, 2023. It is now read-only.

Feature/better trust running #25

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 119 additions & 0 deletions live/console-helper
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
#!/bin/sh

getinput() {
local chardev="$1" out="$2" msg="$3" b=""
#echo "kid $$ reporting for $chardev"
trap "exit 0" TERM
exec 3>&1
exec >"$chardev" <"$chardev" 2>&1 || {
echo "$name: failed redirect to '$chardev'" >&3
exit 2
}
#echo "redirected to $chardev, now reading" >&3
echo "$msg"
read b
[ $? -eq 0 ] || {
echo "$name: read failed" >&3
exit 1
}
echo "$$:$chardev" > "$out" || {
echo "$name: write to $out failed" >&3
}
exit
}

reap() {
local k="" kids=""
for k in "$@"; do
[ -d "/proc/$k" ] || continue
kids="$kids $k"
done
kids=${kids# }
[ -n "$kids" ] || return 0
#echo "reaping $kids"
kill -TERM $kids
}

main_sigchld() {
local rc=$? pid="" chardev="" line
[ -z "$ACTIVE_TTY" ] || return 0
#echo "processing sigchild: rc=$rc ($KIDS)"
[ -f "$tmpf" ] || { echo "no tmpf '$tmpf'"; exit 1; }
while read line; do
[ -n "$line" ] || continue
#echo "read line=$line"
pid=${line%%:*}
chardev=${line#*:}
[ -n "$chardev" ] && break
done < "$tmpf"
[ -n "$chardev" ] || return 0
ACTIVE_TTY=$chardev
#echo "found dev '$chardev' from kid=$pid: KIDS=$KIDS"
reap $KIDS
KIDS=""
}

main_sigexit() {
reap $KIDS
KIDS=""
[ -z "$TMPF" ] || rm -f "$TMPF"
}

main() {
ACTIVE_TTY=""
KIDS=""
local ttys="/dev/ttyS0 /dev/tty1"
trap main_sigexit TERM
trap main_sigexit EXIT
tmpf=$(mktemp) || exit 1
TMPF="$tmpf"
trap main_sigchld CHLD
for tty in $ttys; do
"$0" getinput "$tty" "$tmpf" "Press any key to continue..." &
KIDS="${KIDS:+${KIDS} }$!"
done
wait
trap "" CHLD
if [ -n "$ACTIVE_TTY" ]; then
echo "got active=$ACTIVE_TTY"
else
echo "no active found"
return 1
fi

# save/duplicate original stdout to fd 3.
exec 3>&2
# redirect output to the selected console.
exec >"$ACTIVE_TTY" <"$ACTIVE_TTY" 2>&1 || {
echo "Failed to open $ACTIVE_TTY" >&3
exit 1
}

local msg="selected '$ACTIVE_TTY' as active."
local curmsg="selected '$ACTIVE_TTY' (current) as active."
[ $# -eq 0 ] || {
msg="$msg executing '$1'"
curmsg="$curmsg executing '$1'"
}

# If this program's stdout is /dev/console, and user hit enter there,
# then we end up writing 'curmsg' o tty1 and 'msg' to /dev/console
# so the user will see both. I don't know how to avoid that.
for tty in $ttys; do
[ "$tty" = "$ACTIVE_TTY" ] && continue
echo "$msg" >"$tty"
done
# write to program's original stdout.
echo "$msg" >&3
# write to the selected console.
echo "$curmsg"

[ $# -gt 0 ] || return 0
exec "$@"
}

case "$1" in
getinput) shift; getinput "$@"; exit;;
main) shift; main "$@"; exit;;
esac
main "$@"
26 changes: 23 additions & 3 deletions live/stacker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,18 @@ rootfs-pkg:
run: |
pkgtool install udev kmod \
tpm2-tools e2fsprogs \
openssh-client openssh-server
openssh-client

rootfs:
from:
type: built
tag: rootfs-pkg
import:
- ../trust
- trust-provision
- trust-provision.service
- trust-provision-failed.service
- console-helper
run: |
#!/bin/sh -ex
writefile() {
Expand All @@ -35,8 +39,24 @@ rootfs:
DHCP=yes
END

cp /stacker/trust /usr/bin/trust
chmod 755 /usr/bin/trust
cd /stacker
cp trust trust-provision console-helper /usr/bin
( cd /usr/bin && chmod 755 trust trust-provision console-helper )

cp trust-provision.service trust-provision-failed.service \
/etc/systemd/system/

cd /
mkdir -p /etc/systemd/system/multi-user.target.wants

cd /etc/systemd/system/
for s in trust-provision*.service; do
ln -s "$PWD/$s" "/etc/systemd/system/multi-user.target.wants/$s"
done
ls -ltr /etc/systemd/system/*.service

systemctl enable debug-shell.service
systemctl mask serial-getty@ttyS0

## FIXME
echo root:passw0rd | chpasswd
39 changes: 39 additions & 0 deletions live/trust-provision
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/sh

fail() { [ $# -eq 0 ] || echo "$@" 1>&2; exit 1; }

name="${0##*/}"
maxwait=10
waited=0
label="trust-data"
devpath="/dev/disk/by-label/$label"

while [ $waited -lt $maxwait ] && waited=$((waited+1)); do
[ -b "$devpath" ] && break
udevadm settle
[ -b "$devpath" ] && break
sleep .5
done

[ -b "$devpath" ] || {
cat<<EOF
=========
$0 did not find disk named $label
========
EOF
fail
}


mp="/run/$name"
mkdir -p "$mp" || fail "failed to mkdir $mp"
mount "$devpath" "$mp" || fail "failed to mount $devpath to $mp"

missing=""
for f in cert.pem privkey.pem; do
[ -f "$mp/$f" ] || missing="$missing $f"
done
[ -z "$missing" ] ||
fail "$devpath was found, but did not contain ${missing# }"

exec trust provision "$mp/cert.pem" "$mp/privkey.pem"
15 changes: 15 additions & 0 deletions live/trust-provision-failed.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[Unit]
Description=Run on failure of trust-provision.
After=getty.target multi-user.target
[email protected]

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/usr/bin/console-helper /bin/bash
StandardInput=tty-force
StandardOutput=inherit
StandardError=inherit

[Install]
WantedBy=multi-user.target
15 changes: 15 additions & 0 deletions live/trust-provision.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[Unit]
Description=Run the tpm stuff.
#After=network-online.target
After=getty.target multi-user.target
[email protected]
OnFailure=trust-provision-failed.service

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/usr/bin/trust-provision
StandardOutput=journal+console

[Install]
WantedBy=multi-user.target