Skip to content
Merged
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
2 changes: 1 addition & 1 deletion build/recipes/console.sh
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ if [ -x /usr/sbin/agetty ]; then
# serial console is the installer's root shell: -n -l skips login(1).
# On an installed system it is an ordinary login prompt; root is locked,
# so it admits the first-boot user, not root.
if grep -qw 'kryptik\.media=[a-z]' /proc/cmdline 2>/dev/null; then
if grep -qE '(^| )kryptik\.media=[a-z]+( |$)' /proc/cmdline 2>/dev/null; then
exec /usr/sbin/agetty -n -l /usr/bin/bash --keep-baud \
115200,57600,38400,9600 "$dev" vt220
fi
Expand Down
2 changes: 1 addition & 1 deletion build/service-scripts/testctl.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ testctl_signed() { # testctl_signed FILE

testctl_media() {
grep -qs '^media=.\+' /run/kryptik/boot-identity 2>/dev/null && return 0
grep -qw 'kryptik\.media=[a-z]' /proc/cmdline 2>/dev/null
grep -qE '(^| )kryptik\.media=[a-z]+( |$)' /proc/cmdline 2>/dev/null
}

testctl_load() {
Expand Down
2 changes: 1 addition & 1 deletion build/services/getty-tty1/run
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Authenticated login on tty1; the desktop session starts from the user's
# profile. An install medium's passwordless root shell is here as well as on a
# serial console (kryptik-console), since whoever installs may be at either.
if grep -qw 'kryptik\.media=[a-z]' /proc/cmdline 2>/dev/null; then
if grep -qE '(^| )kryptik\.media=[a-z]+( |$)' /proc/cmdline 2>/dev/null; then
exec /usr/sbin/agetty -n -l /usr/bin/bash --noclear tty1 linux
fi
exec /usr/sbin/agetty --noclear tty1 linux
5 changes: 5 additions & 0 deletions tools/acceptance.sh
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,10 @@ it_ovmf_vars() {
"${IMG}/ovmf-vars.sh" --cert "$MEDIUM_CERT"
}
it_smoke_usb() { "${IMG}/media-smoke.sh" --usb "$MEDIA_USB" --vars clean; }
it_medium_shell() {
local m=(--usb "$MEDIA_USB"); [[ -f "$MEDIA_ISO" ]] && m+=(--iso "$MEDIA_ISO")
"${IMG}/medium-shell-test.sh" "${m[@]}"
}
it_smoke_iso() { "${IMG}/media-smoke.sh" --iso "$MEDIA_ISO" --vars clean; }
it_smoke_sb() { "${IMG}/media-smoke.sh" --usb "$MEDIA_USB" --vars enrolled; }
it_refused() { "${IMG}/media-smoke.sh" --usb "$MEDIA_USB" --vars ms --expect-refused; }
Expand Down Expand Up @@ -431,6 +435,7 @@ item build licences M host 0 it_licences need_sysroot
item build kernel-config M host 0 it_kernel_config need_sources
item build support-status M host 0 it_support_status
item boot media-smoke-usb M vm 25 it_smoke_usb need_vm
item boot medium-shell M vm 3 it_medium_shell need_vm
item boot media-smoke-iso M vm 25 it_smoke_iso need_vm_iso
item install install-test M vm 10 it_install need_vm
item install state-test M vm 10 it_state need_vm
Expand Down
56 changes: 56 additions & 0 deletions tools/image/medium-shell-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/usr/bin/env bash
# The install medium's console is a root shell: whoever boots it types
# kryptik-install there. Every suite installs through a control disk, so this
# is the one that types: a command runs as root, the installer and the
# recovery tool are found by name, and poweroff ends the session.
#
# tools/image/medium-shell-test.sh (--usb IMG | --iso ISO)... [--timeout N]
set -uo pipefail
SELF="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=/dev/null
source "${SELF}/../../build/lib/common.sh"
trap - ERR; set +e

MEDIA=(); TIMEOUT=300
while [[ "$#" -gt 0 ]]; do
case "$1" in
--usb|--iso) MEDIA+=("$1" "${2:?}"); shift 2 ;;
--timeout) TIMEOUT="${2:?}"; shift 2 ;;
-h|--help) sed -n '2,7p' "${BASH_SOURCE[0]}"; exit 0 ;;
*) die "unknown argument: $1" ;;
esac
done
[[ "${#MEDIA[@]}" -gt 0 ]] || die "--usb IMG or --iso ISO is required"
VMDIR="${KRYPTIK_WORK}/vm"; mkdir -p "$VMDIR"

# shellcheck source=tools/image/suite-lib.sh
source "${SELF}/suite-lib.sh"

for ((i = 0; i < ${#MEDIA[@]}; i += 2)); do
kind="${MEDIA[i]#--}"; medium="${MEDIA[i+1]}"
[[ -f "$medium" ]] || die "no such medium: ${medium}"
step "the ${kind} medium's console"
out="$("${SELF}/run-ovmf.sh" "--${kind}" "$medium" --mode serve --name "medium-shell-${kind}")"
SER="$(sed -n 's/^serial=//p' <<<"$out")"; PIDF="$(sed -n 's/^pid=//p' <<<"$out")"; LOG="$(sed -n 's/^log=//p' <<<"$out")"
[[ -S "$SER" ]] || die "no serial socket: ${out}"
# The shell's own arithmetic and substitutions answer, never the echo of
# what was typed; a getty drops its first second's input, so the first
# line goes twice.
python3 "$DRV" --serial "$SER" --timeout "$TIMEOUT" \
"expect:KRYPTIK_SMOKE: END" "sleep:3" \
'send:echo shell-$((6 * 7))' "sleep:2" 'send:echo shell-$((6 * 7))' "expect:shell-42" \
'send:echo uid-$(id -u)' "expect:uid-0" \
'send:echo found-$(command -v kryptik-install)-$(command -v kryptik-recover)' \
"expect:found-/usr/sbin/kryptik-install-/usr/sbin/kryptik-recover" \
"send:kryptik-install --help" "expect:usage: kryptik-install --target" \
"send:poweroff" "expect:Power down" "wait-exit"
drc=$?
stop_vm
[[ "$drc" -eq 0 ]] && green "${kind}: commands typed at the console ran as root, the installer is on its path, and poweroff took" \
|| red "${kind}: the console did not take commands (see above)"
if txt | grep -q 'kryptik login:'; then red "${kind}: the medium's console asked for a login"; else green "${kind}: no login prompt on the medium"; fi
if txt | grep -qE 'KRYPTIK_SMOKE: early_getty_pid=[0-9]+ comm=bash'; then green "${kind}: the console's process is the shell"; else red "${kind}: the console's process is not a shell: $(txt | grep -m1 -o 'early_getty_pid=.*' | cut -c1-80)"; fi
done

printf '\n%d passed, %d failed\n' "$PASS" "$FAIL"
[[ "$FAIL" -eq 0 ]] || exit 1
39 changes: 39 additions & 0 deletions tools/tests/medium-shell.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/usr/bin/env bash
# The test "this is an install medium", as the console wrapper, the tty1 getty
# and the control-disk reader each make it, against the four command lines
# stage 06 signs: a medium gets the root shell, an installed slot the login
# prompt. Offline.
set -uo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"

PASS=0; FAIL=0
green() { printf ' PASS %s\n' "$1"; PASS=$((PASS + 1)); }
red() { printf ' FAIL %s\n' "$1"; FAIL=$((FAIL + 1)); }
T="$(mktemp -d)"; trap 'rm -rf "$T"' EXIT

# As 06-iso.sh writes them; the verity table is one long quoted word.
common='ro rootwait console=tty0 console=ttyS0,115200 panic=10 loglevel=4 mitigations=auto,nosmt pti=on page_alloc.shuffle=1 hash_pointers=always nosmt'
table='0 3145728 verity 1 PARTLABEL=kryptik-media PARTLABEL=kryptik-media 4096 4096 393216 393216 sha256 ab12 cd34 1 panic_on_corruption'
printf 'dm-mod.waitfor=PARTLABEL=kryptik-media dm-mod.create="kroot,,0,ro,%s" root=/dev/dm-0 %s kryptik.media=usb\n' "$table" "$common" > "$T/usb"
printf 'dm-mod.create="kmedia,,0,ro,0 6291456 linear /dev/sr0 1234;kroot,,1,ro,%s" root=/dev/dm-1 %s kryptik.media=iso\n' "$table" "$common" > "$T/iso"
printf 'dm-mod.waitfor=PARTLABEL=kryptik-a dm-mod.create="kroot,,0,ro,%s" root=/dev/dm-0 %s kryptik.slot=a\n' "$table" "$common" > "$T/slot-a"
printf 'dm-mod.waitfor=PARTLABEL=kryptik-b dm-mod.create="kroot,,0,ro,%s" root=/dev/dm-0 %s kryptik.slot=b\n' "$table" "$common" > "$T/slot-b"

first=""
for f in build/recipes/console.sh build/services/getty-tty1/run build/service-scripts/testctl.sh; do
# The file's own grep, its file argument left off.
cmd="$(sed -n "s|.*\(grep -q[A-Za-z]* '[^']*kryptik[^']*'\) /proc/cmdline.*|\1|p" "${ROOT}/${f}")"
if [[ "$(grep -c . <<<"$cmd")" -ne 1 ]]; then red "${f}: one test of /proc/cmdline for kryptik.media expected, found: ${cmd:-none}"; continue; fi
[[ -z "$first" ]] && first="$cmd"
[[ "$cmd" == "$first" ]] && green "${f}: the same test as the others" || red "${f}: its test differs: ${cmd}"
for line in usb iso; do
if eval "$cmd" '"$T/$line"'; then green "${f}: the ${line} medium's command line is a medium's"; else red "${f}: the ${line} medium is not seen as one"; fi
done
for line in slot-a slot-b; do
if eval "$cmd" '"$T/$line"'; then red "${f}: an installed ${line} is taken for a medium"; else green "${f}: an installed ${line} is not a medium"; fi
done
done

echo
echo "${PASS} passed, ${FAIL} failed"
[[ "$FAIL" -eq 0 ]]
Loading