mirror of
https://oauth2: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@github.com/m1ngsama/TNT.git
synced 2026-06-26 05:44:38 +08:00
test: stabilize anonymous access checks
This commit is contained in:
parent
cd170d3245
commit
fa16beb7a6
7 changed files with 107 additions and 73 deletions
7
Makefile
7
Makefile
|
|
@ -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))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue