test: stabilize anonymous access checks

This commit is contained in:
m1ngsama 2026-05-23 23:30:43 +08:00
parent cd170d3245
commit fa16beb7a6
7 changed files with 107 additions and 73 deletions

View file

@ -31,7 +31,7 @@ MANDIR ?= $(PREFIX)/share/man
SYSTEMD_UNIT_DIR ?= $(PREFIX)/lib/systemd/system SYSTEMD_UNIT_DIR ?= $(PREFIX)/lib/systemd/system
CI_TEST_PORT ?= $(if $(PORT),$(PORT),2222) CI_TEST_PORT ?= $(if $(PORT),$(PORT),2222)
.PHONY: all clean install install-systemd uninstall uninstall-systemd debug release release-check release-check-strict asan valgrind check test test-advisory ci-test unit-test integration-test connection-limit-test security-test info .PHONY: all clean install install-systemd uninstall uninstall-systemd debug release release-check release-check-strict asan valgrind check test test-advisory ci-test unit-test integration-test anonymous-access-test connection-limit-test security-test info
all: $(TARGET) all: $(TARGET)
@ -113,6 +113,10 @@ integration-test: all
@cd tests && PORT=$$(($${PORT:-2222} + 1)) ./test_exec_mode.sh @cd tests && PORT=$$(($${PORT:-2222} + 1)) ./test_exec_mode.sh
@cd tests && PORT=$$(($${PORT:-2222} + 2)) ./test_interactive_input.sh @cd tests && PORT=$$(($${PORT:-2222} + 2)) ./test_interactive_input.sh
anonymous-access-test: all
@echo "Running anonymous access tests..."
@cd tests && PORT=$${PORT:-2222} ./test_anonymous_access.sh
connection-limit-test: all connection-limit-test: all
@echo "Running connection limit tests..." @echo "Running connection limit tests..."
@cd tests && PORT=$${PORT:-2222} ./test_connection_limits.sh @cd tests && PORT=$${PORT:-2222} ./test_connection_limits.sh
@ -123,6 +127,7 @@ security-test: all
ci-test: ci-test:
@$(MAKE) test PORT=$(CI_TEST_PORT) @$(MAKE) test PORT=$(CI_TEST_PORT)
@$(MAKE) anonymous-access-test PORT=$$(($(CI_TEST_PORT) + 5))
@$(MAKE) connection-limit-test PORT=$$(($(CI_TEST_PORT) + 10)) @$(MAKE) connection-limit-test PORT=$$(($(CI_TEST_PORT) + 10))
@$(MAKE) security-test PORT=$$(($(CI_TEST_PORT) + 20)) @$(MAKE) security-test PORT=$$(($(CI_TEST_PORT) + 20))

View file

@ -202,6 +202,7 @@ make clean # clean build artifacts
```sh ```sh
make test # run comprehensive test suite and fail on regressions make test # run comprehensive test suite and fail on regressions
make test-advisory # run integration tests as advisory checks make test-advisory # run integration tests as advisory checks
make anonymous-access-test # verify default anonymous login behavior
make connection-limit-test # verify per-IP concurrency and rate limits make connection-limit-test # verify per-IP concurrency and rate limits
make security-test # run security feature checks make security-test # run security feature checks
make ci-test # run the same checks as GitHub Actions make ci-test # run the same checks as GitHub Actions
@ -218,7 +219,7 @@ cd tests
**Test coverage:** **Test coverage:**
- Basic functionality: 3 tests - Basic functionality: 3 tests
- Anonymous access: 2 tests - Anonymous access: 2 tests
- Security features: 11 tests - Security features: 12 tests
- Stress test: concurrent connections - Stress test: concurrent connections
### Dependencies ### Dependencies

View file

@ -53,6 +53,9 @@
`host_key` / `messages.log` into the test directory. `host_key` / `messages.log` into the test directory.
- Added `make security-test` and `make ci-test` so local runs can use the same - Added `make security-test` and `make ci-test` so local runs can use the same
full verification path as GitHub Actions. full verification path as GitHub Actions.
- Anonymous access checks now use isolated state, wait for real SSH health,
avoid external `timeout` helpers, and run through `make anonymous-access-test`
as part of `make ci-test`.
- Refreshed README and quick-reference module maps to match the current - Refreshed README and quick-reference module maps to match the current
`cli_text`, `help_text`, `support_text`, i18n, exec, and rate-limit modules. `cli_text`, `help_text`, `support_text`, i18n, exec, and rate-limit modules.
- NORMAL mode now opens at the latest visible messages instead of the oldest - NORMAL mode now opens at the latest visible messages instead of the oldest

View file

@ -6,7 +6,8 @@ AUTOMATIC TESTING
Every push or PR automatically runs: Every push or PR automatically runs:
- Build on Ubuntu - Build on Ubuntu
- AddressSanitizer build - AddressSanitizer build
- `make ci-test` - `make ci-test` (strict integration, anonymous access, connection limits,
and security feature checks)
- Release/package preflight (`make release-check`) - Release/package preflight (`make release-check`)
Check status: Check status:

View file

@ -161,6 +161,7 @@ make install # Install to /usr/local/bin
```sh ```sh
make test # Run all tests and fail on regressions make test # Run all tests and fail on regressions
make test-advisory # Run integration tests as advisory checks make test-advisory # Run integration tests as advisory checks
make anonymous-access-test # Verify default anonymous login behavior
make connection-limit-test # Verify per-IP concurrency and rate limits make connection-limit-test # Verify per-IP concurrency and rate limits
make security-test # Run security feature checks make security-test # Run security feature checks
make ci-test # Run the same checks as GitHub Actions make ci-test # Run the same checks as GitHub Actions

View file

@ -11,6 +11,7 @@ BUILD
TEST TEST
make test strict unit + integration tests make test strict unit + integration tests
make test-advisory unit tests + advisory integration checks make test-advisory unit tests + advisory integration checks
make anonymous-access-test default anonymous login checks
make connection-limit-test per-IP concurrency/rate-limit checks make connection-limit-test per-IP concurrency/rate-limit checks
make security-test security feature checks make security-test security feature checks
make ci-test same checks as GitHub Actions make ci-test same checks as GitHub Actions

View file

@ -1,90 +1,112 @@
#!/bin/bash #!/bin/bash
# Test anonymous SSH access # Anonymous SSH access regression tests for TNT
BIN="../tnt" BIN="../tnt"
PORT=${PORT:-2222} PORT=${PORT:-2222}
PASS=0
FAIL=0
STATE_DIR=$(mktemp -d "${TMPDIR:-/tmp}/tnt-anonymous-test.XXXXXX")
SERVER_PID=""
cleanup() {
if [ -n "$SERVER_PID" ]; then
kill "$SERVER_PID" 2>/dev/null || true
wait "$SERVER_PID" 2>/dev/null || true
fi
rm -rf "$STATE_DIR"
}
trap cleanup EXIT
if [ ! -f "$BIN" ]; then if [ ! -f "$BIN" ]; then
echo "Error: Binary $BIN not found." echo "Error: Binary $BIN not found."
exit 1 exit 1
fi fi
echo "Starting TNT server on port $PORT..." SSH_BASE="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o PubkeyAuthentication=no -p $PORT"
TNT_LANG=zh $BIN -p $PORT > /dev/null 2>&1 &
wait_for_health() {
local out
for _ in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15; do
if [ -n "$SERVER_PID" ] && ! kill -0 "$SERVER_PID" 2>/dev/null; then
return 1
fi
out=$(ssh -n $SSH_BASE localhost health 2>/dev/null || true)
[ "$out" = "ok" ] && return 0
sleep 1
done
return 1
}
run_password_test() {
local name="$1"
local user="$2"
local password="$3"
local display_name="$4"
local script="$STATE_DIR/$name.expect"
local log="$STATE_DIR/$name.log"
cat >"$script" <<EOF
set timeout 10
spawn ssh $SSH_BASE -o PreferredAuthentications=password $user@localhost
expect {
-re "(?i)password:" {
send -- "$password\r"
exp_continue
}
"请输入用户名" {
send -- "$display_name\r"
send -- "\003"
expect eof
exit 0
}
timeout { exit 1 }
eof { exit 1 }
}
EOF
if expect "$script" >"$log" 2>&1; then
return 0
fi
sed -n '1,120p' "$log"
return 1
}
echo "=== TNT Anonymous Access Tests ==="
TNT_LANG=zh TNT_RATE_LIMIT=0 "$BIN" -p "$PORT" -d "$STATE_DIR" \
>"$STATE_DIR/server.log" 2>&1 &
SERVER_PID=$! SERVER_PID=$!
sleep 2
cleanup() { if wait_for_health; then
kill $SERVER_PID 2>/dev/null echo "✓ server started"
wait 2>/dev/null PASS=$((PASS + 1))
}
trap cleanup EXIT
# Detect timeout command
TIMEOUT_CMD="timeout"
if command -v gtimeout >/dev/null 2>&1; then
TIMEOUT_CMD="gtimeout"
fi
echo "Testing anonymous SSH access to TNT server..."
echo ""
# Test 1: Connection with any username and password
echo "Test 1: Connection with any username (should succeed)"
$TIMEOUT_CMD 10 expect -c "
spawn ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p $PORT testuser@localhost
expect {
\"password:\" {
send \"anypassword\r\"
expect {
\"请输入用户名\" {
send \"TestUser\r\"
send \"\003\"
exit 0
}
timeout { exit 1 }
}
}
timeout { exit 1 }
}
" 2>&1 | grep -q "请输入用户名"
if [ $? -eq 0 ]; then
echo "✓ Test 1 PASSED: Can connect with any password"
else else
echo "✗ Test 1 FAILED: Cannot connect with any password" echo "✗ server failed to start"
sed -n '1,120p' "$STATE_DIR/server.log"
exit 1 exit 1
fi fi
echo "" if run_password_test "any-password" "testuser" "anypassword" "TestUser"; then
echo "✓ accepts any password when no access token is configured"
# Test 2: Connection should work with empty password PASS=$((PASS + 1))
echo "Test 2: Simple connection (standard SSH command)"
$TIMEOUT_CMD 10 expect -c "
spawn ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p $PORT anonymous@localhost
expect {
\"password:\" {
send \"\r\"
expect {
\"请输入用户名\" {
send \"\r\"
send \"\003\"
exit 0
}
timeout { exit 1 }
}
}
timeout { exit 1 }
}
" 2>&1 | grep -q "请输入用户名"
if [ $? -eq 0 ]; then
echo "✓ Test 2 PASSED: Can connect with empty password"
else else
echo "✗ Test 2 FAILED: Cannot connect with empty password" echo "✗ any-password login failed"
exit 1 FAIL=$((FAIL + 1))
fi
if run_password_test "empty-password" "anonymous" "" ""; then
echo "✓ accepts empty password when no access token is configured"
PASS=$((PASS + 1))
else
echo "✗ empty-password login failed"
FAIL=$((FAIL + 1))
fi fi
echo "" echo ""
echo "Anonymous access test completed." echo "PASSED: $PASS"
exit 0 echo "FAILED: $FAIL"
[ "$FAIL" -eq 0 ] && echo "All tests passed" || echo "Some tests failed"
exit "$FAIL"