fix: calculate ban expiration correctly (#8)

* fix: calculate ban expiration correctly

* fix: handle negative ban time and long durations

* fix: display remaining ban time with days

* test: add time formatter coverage
This commit is contained in:
2025-07-01 16:53:05 +03:00
committed by GitHub
parent 84e2af0c2c
commit f93b0fcdfb
2 changed files with 29 additions and 13 deletions

30
f2b
View File

@@ -222,11 +222,11 @@ f2b_jail_exists() {
exit 1
}
# Convert seconds to hours, minutes, and seconds
# Convert seconds to days, hours, minutes, and seconds
# Usage: f2b_secs_to_hours_minutes_seconds <seconds>
# Example: f2b_secs_to_hours_minutes_seconds 3600 (01:00:00)
# Example: f2b_secs_to_hours_minutes_seconds 3661 (01:01:01)
# Returns: hours:minutes:seconds
# Example: f2b_secs_to_hours_minutes_seconds 3600 (00:01:00:00)
# Example: f2b_secs_to_hours_minutes_seconds 90061 (01:01:01:01)
# Returns: days:hours:minutes:seconds
f2b_secs_to_hours_minutes_seconds() {
local SECONDS=${1:-0}
@@ -240,14 +240,15 @@ f2b_secs_to_hours_minutes_seconds() {
exit 1
fi
local SECONDS=$((SECONDS % 86400))
local DAYS=$((SECONDS / 86400))
SECONDS=$((SECONDS % 86400))
local HOURS=$((SECONDS / 3600))
local SECONDS=$((SECONDS % 3600))
SECONDS=$((SECONDS % 3600))
local MINUTES=$((SECONDS / 60))
local SECONDS=$((SECONDS % 60))
SECONDS=$((SECONDS % 60))
# Pad hours, minutes, and seconds with zeros if they are less than 10
echo "$(printf "%02d" "$HOURS"):$(printf "%02d" "$MINUTES"):$(printf "%02d" "$SECONDS")"
# Pad all components with zeros if needed
echo "$(printf "%02d" "$DAYS"):$(printf "%02d" "$HOURS"):$(printf "%02d" "$MINUTES"):$(printf "%02d" "$SECONDS")"
}
# Ban IP address in a specific jail, if provided
@@ -442,7 +443,7 @@ f2b_banned_ips() {
local R2W=4 # Jail, sshd might be the most common
local R3W=15 # IP Address, 3+1+3+1+3+1+3=15 (xxx.xxx.xxx)
local R4W=19 # Banned Date, 10+1+8=19 (YYYY-MM-DD HH:MM:SS)
local R5W=8 # Ban Expires, 2+1+2+1+2=8 (HH:MM:SS)
local R5W=11 # Ban Expires, 2+1+2+1+2+1+2=11 (DD:HH:MM:SS)
# Use BANNED_IPS to loop through the banned IPs and get values for the upcoming table
# The table will have the following columns:
@@ -482,11 +483,14 @@ f2b_banned_ips() {
local BAN_EXPIRES_SECS=""
BAN_EXPIRES_SECS=$(date -d "$BAN_EXPIRES" +%s)
# Calculate the time remaining until the IP is unbanned
local BAN_REMAINING=$((BAN_EXPIRES_SECS - CURRENT_TIME))
local BAN_REMAINING_SECS=$((BAN_EXPIRES_SECS - CURRENT_TIME))
if [ "$BAN_REMAINING_SECS" -lt 0 ]; then
BAN_REMAINING_SECS=0
fi
# Format the time remaining until the IP is unbanned
local BAN_REMAINING=""
BAN_REMAINING=$(f2b_secs_to_hours_minutes_seconds "$BAN_REMAINING")
BAN_REMAINING=$(f2b_secs_to_hours_minutes_seconds "$BAN_REMAINING_SECS")
# Get the length of the ban number
local BAN_NO_LENGTH=${#BAN_NO}
@@ -560,7 +564,7 @@ f2b_banned_ips() {
printf "+-%-${R1W}s-+-%-${R2W}s-+-%-${R3W}s-+-%-${R4W}s-+-%-${R5W}s-+\n" \
"" "" "" "" ""
echo ""
echo "Expiration time is in days:hours:minutes format."
echo "Expiration time is in days:hours:minutes:seconds format."
echo ""
}

View File

@@ -47,3 +47,15 @@ MOCK
run "$BATS_TEST_DIRNAME/../f2b" logs sshd
[ "$status" -eq 0 ]
}
@test "format seconds into DD:HH:MM:SS" {
run bash -c "source <(awk '/^f2b_secs_to_hours_minutes_seconds()/,/^}/' '$BATS_TEST_DIRNAME/../f2b'); f2b_secs_to_hours_minutes_seconds 90061"
[ "$status" -eq 0 ]
[ "$output" = "01:01:01:01" ]
}
@test "negative seconds returns error" {
run bash -c "source <(awk '/^f2b_secs_to_hours_minutes_seconds()/,/^}/' '$BATS_TEST_DIRNAME/../f2b'); f2b_secs_to_hours_minutes_seconds -1"
[ "$status" -eq 1 ]
[[ "$output" == *"positive integer"* ]]
}