mirror of
https://github.com/jmcorgan/fips.git
synced 2026-07-30 19:46:15 +00:00
Stop the firewall peer reader turning a silent container into a count of zero
wait_for_peers_exact read the connected-peer count through a pipeline ending in `|| echo 0`, so a container that never answered and a daemon that answered zero produced the same value. That is only harmless while every caller expects a non-zero count, which is true here today and is the reason this copy was left alone when the acl suite's copy was fixed. It leaves the trap armed for whoever adds the first caller expecting zero: the check would be satisfied on its first iteration without the property it exists to verify ever being observed. The read moves into its own function that returns the empty string when the container does not answer, and the caller treats empty as "no answer" rather than as a count. A run that never gets an answer now fails saying so, distinctly from one that answered the wrong count, and the diagnostic peer dump runs only on the latter, since dumping from a container that cannot answer prints a docker error rather than evidence. This is the shape the acl-allowlist suite already uses. The two copies had diverged on whether a silent container counts as an answer, which is the kind of disagreement that decides a security assertion in whichever file is read last. Checked by construction rather than by a green run: driving the old form against an absent container with an expected count of zero returns success on the first iteration, and the new form fails; with an expected count of one, the shape both real callers use, both forms still fail, and a genuine zero from a live daemon is still reported as zero.
This commit is contained in:
@@ -81,21 +81,46 @@ wait_for_fips0() {
|
|||||||
fail "$container fips0 did not come up within ${timeout}s"
|
fail "$container fips0 did not come up within ${timeout}s"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Connected-peer count for a container, or the empty string if it did not
|
||||||
|
# answer.
|
||||||
|
#
|
||||||
|
# Empty is deliberately distinct from a real 0. An `|| echo 0` fallback here
|
||||||
|
# would make "the container is unreachable, or its daemon never came up" and
|
||||||
|
# "the daemon answered, and the answer was zero" the same value, so any caller
|
||||||
|
# expecting zero would be satisfied on the first iteration without the
|
||||||
|
# property it is checking ever being observed. No caller in this file expects
|
||||||
|
# zero today, which is exactly why the fallback has to go now rather than when
|
||||||
|
# one is added. Same shape as the acl-allowlist suite's read_connected_peers.
|
||||||
|
read_connected_peers() {
|
||||||
|
local container="$1"
|
||||||
|
docker exec "$container" fipsctl show peers 2>/dev/null \
|
||||||
|
| python3 -c 'import json,sys; data=json.load(sys.stdin); print(sum(1 for p in data.get("peers", []) if p.get("connectivity") == "connected"))' 2>/dev/null \
|
||||||
|
|| true
|
||||||
|
}
|
||||||
|
|
||||||
# Wait for the peer count on a container to reach the expected value.
|
# Wait for the peer count on a container to reach the expected value.
|
||||||
wait_for_peers_exact() {
|
wait_for_peers_exact() {
|
||||||
local container="$1"
|
local container="$1"
|
||||||
local expected_count="$2"
|
local expected_count="$2"
|
||||||
local timeout="${3:-30}"
|
local timeout="${3:-30}"
|
||||||
|
|
||||||
|
local count="" answered=false
|
||||||
for _ in $(seq 1 "$timeout"); do
|
for _ in $(seq 1 "$timeout"); do
|
||||||
local count
|
count=$(read_connected_peers "$container")
|
||||||
count=$(docker exec "$container" fipsctl show peers 2>/dev/null \
|
if [ -n "$count" ]; then
|
||||||
| python3 -c 'import json,sys; data=json.load(sys.stdin); print(sum(1 for p in data.get("peers", []) if p.get("connectivity") == "connected"))' 2>/dev/null || echo 0)
|
answered=true
|
||||||
if [ "$count" -eq "$expected_count" ]; then
|
if [ "$count" -eq "$expected_count" ]; then
|
||||||
return 0
|
return 0
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
fail "$container did not reach $expected_count connected peers in ${timeout}s"
|
|
||||||
|
if [ "$answered" = false ]; then
|
||||||
|
fail "$container never answered a peer query in ${timeout}s, so a count of $expected_count was never actually observed"
|
||||||
|
fi
|
||||||
|
docker exec "$container" fipsctl show peers >&2 || true
|
||||||
|
fail "$container did not reach $expected_count connected peers in ${timeout}s (last answer: $count)"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Resolve `<npub>.fips` inside a container and print the AAAA answer.
|
# Resolve `<npub>.fips` inside a container and print the AAAA answer.
|
||||||
|
|||||||
Reference in New Issue
Block a user