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 Buildroot/board/FOG/FOS/rootfs_overlay/bin/fog.enrollsb
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ debugPause
# running a kernel this same server signed and served, so a server that could
# hand us the wrong certificate could equally have handed us the wrong kernel.
# The value of it is that it matches what the Secure Boot page displays and
# what sbReport stores against the host, so an enrolment can be audited after
# what sbReport stores against the host, so an enrollment can be audited after
# the fact -- "enrolled in March" says nothing about whether this machine
# trusts what the server is serving today, and a fingerprint does.
fingerprint=$(sbCertFingerprint "$cert")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ sbCertFingerprint() {
[[ -z $cert ]] && handleError "No certificate passed (${FUNCNAME[0]})\n Args Passed: $*"
sha256sum "$cert" 2>/dev/null | awk '{print toupper($1)}' | sed 's/../&:/g;s/:$//'
}
# Tell the server what this enrolment actually did.
# Tell the server what this enrollment actually did.
#
# WHY THIS IS NOT INFERRED FROM THE TASK COMPLETING
#
Expand All @@ -166,15 +166,15 @@ sbCertFingerprint() {
# mok a request was STAGED. The machine is NOT enrolled and will not
# boot with Secure Boot on until a human confirms it at MokManager
#
# Recording the third as an enrolment is a lie an administrator acts on: they
# Recording the third as an enrollment is a lie an administrator acts on: they
# turn Secure Boot on in firmware and the machine stops booting. So the outcome
# is reported by the only party that knows it, which is this one.
#
# Best-effort by design. A server too old to have the endpoint answers 404 and
# a server that never hears us changes nothing -- in both cases the enrolment
# a server that never hears us changes nothing -- in both cases the enrollment
# itself already happened and the task must still complete. So this NEVER calls
# handleError and never fails the task; it says what it did and moves on. The
# record is a convenience for the administrator, not a step in the enrolment.
# record is a convenience for the administrator, not a step in the enrollment.
#
# $1 the result: db, trusted or mok
# $2 the certificate's SHA-256 fingerprint
Expand All @@ -193,9 +193,9 @@ sbReport() {
"mac=${mactosend}&result=${result}&cert=${cert}&sbstate=$(sbState)"
[[ $serverBody == "##ok" ]] && return 0
# Said out loud rather than swallowed. It is not a failure of the
# enrolment, and the wording has to make that clear, or the next person
# enrollment, and the wording has to make that clear, or the next person
# reads it as one and goes looking at firmware that is perfectly fine.
echo " * Note: the enrolment succeeded but could not be recorded on the"
echo " * Note: the enrollment succeeded but could not be recorded on the"
echo " FOG server (${serverReason:-${serverBody:-no answer}})."
echo " Set it by hand on the host's General tab if you need the record."
return 0
Expand Down
6 changes: 3 additions & 3 deletions tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,18 +118,18 @@ tests/checks/secureboot.sh # secureboot-funcs.sh: derives the right firmware
# a failed download writes nothing at all, and a
# SetupMode that does not flip 1 -> 0 is a refusal
# rather than a success
tests/checks/secureboot-enrolment-report.sh
tests/checks/secureboot-enrollment-report.sh
# sbReport() tells the FOG server WHICH of
# fog.enrollsb's three exits was reached -- all
# three otherwise end in the same argument-free
# completion POST and look identical from the
# server. Pins that a staged MOK is reported as
# 'mok' and never as an enrolment (turning Secure
# 'mok' and never as an enrollment (turning Secure
# Boot on after that lie stops the machine
# booting), that every exit reports BEFORE
# completing the task, and that a server that is
# unreachable, 404s or answers nothing never
# fails the task the enrolment already finished
# fails the task the enrollment already finished
tests/checks/secureboot-config.sh
# configs/kernel*.config carry the Secure Boot
# hardening symbols (lockdown LSM in CONFIG_LSM,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
#
# Assertion harness for sbReport() and the three exits that call it.
#
# tests/checks/secureboot-enrolment-report.sh
# tests/checks/secureboot-enrollment-report.sh
#
# What it proves: that a Secure Boot enrolment task tells the FOG server WHICH
# What it proves: that a Secure Boot enrollment task tells the FOG server WHICH
# of its three outcomes it reached, and that failing to tell it never fails the
# task.
#
Expand All @@ -18,18 +18,18 @@
# mok a request was STAGED. The machine is NOT enrolled and will not
# boot with Secure Boot on until a human confirms it at MokManager
#
# Recording the third as an enrolment is a lie an administrator acts on: they
# Recording the third as an enrollment is a lie an administrator acts on: they
# turn Secure Boot on in firmware and the machine stops booting. Case 4 is the
# one that holds that shut, and it is anchored on the whole call line -- a grep
# for "sbReport" alone passes when the argument has been changed to "db", which
# is the exact regression worth catching.
#
# The other half is that this must never be able to fail a task. The enrolment
# The other half is that this must never be able to fail a task. The enrollment
# has already happened by the time sbReport runs; a server that is too old to
# have the endpoint answers 404, and one that is unreachable answers nothing.
# In both cases the machine is enrolled and the task must still complete. So
# sbReport returns 0 unconditionally, says on screen what went wrong, and says
# it in words that do not read as an enrolment failure -- cases 5 to 8.
# it in words that do not read as an enrollment failure -- cases 5 to 8.
#
# Mechanism mirrors tests/checks/server-post-reporting.sh: source sandbox
# copies of funcs.sh (for callServer) and secureboot-funcs.sh with their
Expand Down Expand Up @@ -127,7 +127,7 @@ note "2. the report is a POST carrying its body" "$err"
# --- 3. nothing is posted when there is nothing to say --------------------
# Guards against a half-populated row: a blank fingerprint stored against a
# host reads as "enrolled, certificate unknown", which is worse than no record
# because it cannot be told apart from a real enrolment whose cert was cleared.
# because it cannot be told apart from a real enrollment whose cert was cleared.
for args in '"db" ""' '"" "AA:BB"'; do
rm -f "$SANDBOX/curl.argv"
eval "out=\$(FAKE_CODE=200 FAKE_BODY='##ok' drive $args)"
Expand All @@ -139,7 +139,7 @@ done

# --- 4-8. a failure to record must never fail the task --------------------
# Each arm returns 0 and says something. The wording matters as much as the
# status: "enrolment failed" sends the next person to a firmware screen that is
# status: "enrollment failed" sends the next person to a firmware screen that is
# perfectly fine, so the message has to name the RECORDING as the thing that
# did not happen.
for arm in "unreachable:FAKE_CURL_RC=7" "http404:FAKE_CODE=404" \
Expand All @@ -151,8 +151,8 @@ for arm in "unreachable:FAKE_CURL_RC=7" "http404:FAKE_CODE=404" \
err=""
[[ $out == *"RC=0"* ]] || err="rc not 0 -- this would fail the task"
grep -qi 'could not be recorded' <<<"$out" || err="$err; said nothing"
grep -qi 'enrolment succeeded' <<<"$out" \
|| err="$err; does not say the enrolment itself was fine"
grep -qi 'enrollment succeeded' <<<"$out" \
|| err="$err; does not say the enrollment itself was fine"
note "4. $name: reports the problem and still returns 0" "$err"
done

Expand All @@ -177,7 +177,7 @@ for want in 'sbReport "trusted" "$fingerprint"' \
done
note "10. all three exits report their own outcome" "$err"

# --- 11. the staged-MOK exit must not claim an enrolment ------------------
# --- 11. the staged-MOK exit must not claim an enrollment ------------------
# THE assertion in this file. Everything else is plumbing; this is the one that
# stops FOG telling an administrator a machine is enrolled when it is not.
err=""
Expand All @@ -188,9 +188,9 @@ note "11. the staged-MOK exit reports 'mok', never 'db'" "$err"

# --- 12. the report happens BEFORE the task is completed ------------------
# Order is load-bearing: fog.nonimgcomplete is what clears the task, and a
# report that arrives after it is refused -- the endpoint requires the enrolment
# report that arrives after it is refused -- the endpoint requires the enrollment
# task to still be in flight, so that a caller who merely knows a MAC cannot
# stamp an enrolment onto a host that was never asked to enrol.
# stamp an enrollment onto a host that was never asked to enroll.
err=""
last_report=""
while read -r n line; do
Expand Down