mirror of https://github.com/wolfSSL/wolfssh.git
Enforce LoginGraceTime in wolfsshd on Windows and make the grace flag per-connection
parent
09cbe92daa
commit
62639efd35
|
|
@ -43,13 +43,12 @@ jobs:
|
|||
working-directory: ${{env.GITHUB_WORKSPACE}}wolfssl
|
||||
run: nuget restore ${{env.WOLFSSL_SOLUTION_FILE_PATH}}
|
||||
|
||||
- name: updated user_settings.h for sshd and x509
|
||||
- name: Enable wolfSSH options (sshd, sftp, x509) in user_settings.h
|
||||
working-directory: ${{env.GITHUB_WORKSPACE}}
|
||||
run: cp ${{env.USER_SETTINGS_H_NEW}} ${{env.USER_SETTINGS_H}}
|
||||
|
||||
- name: replace wolfSSL user_settings.h with wolfSSH user_settings.h
|
||||
working-directory: ${{env.GITHUB_WORKSPACE}}
|
||||
run: get-content ${{env.USER_SETTINGS_H_NEW}} | %{$_ -replace "if 0","if 1"}
|
||||
shell: bash
|
||||
run: |
|
||||
sed -i 's/#if 0/#if 1/g' ${{env.USER_SETTINGS_H_NEW}}
|
||||
cp ${{env.USER_SETTINGS_H_NEW}} ${{env.USER_SETTINGS_H}}
|
||||
|
||||
- name: Build wolfssl library
|
||||
working-directory: ${{env.GITHUB_WORKSPACE}}wolfssl
|
||||
|
|
@ -65,6 +64,30 @@ jobs:
|
|||
# See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference
|
||||
run: msbuild /m /p:PlatformToolset=v142 /p:Platform=${{env.BUILD_PLATFORM}} /p:WindowsTargetPlatformVersion=${{env.TARGET_PLATFORM}} /p:Configuration=${{env.WOLFSSH_BUILD_CONFIGURATION}} ${{env.SOLUTION_FILE_PATH}}
|
||||
|
||||
- name: Locate wolfsshd.exe and stage wolfssl.dll
|
||||
working-directory: ${{ github.workspace }}\wolfssh
|
||||
shell: pwsh
|
||||
run: |
|
||||
$sshdExe = Get-ChildItem -Path "${{ github.workspace }}\wolfssh" -Recurse -Filter "wolfsshd.exe" -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.FullName -like "*Release*" } | Select-Object -First 1
|
||||
if (-not $sshdExe) {
|
||||
Write-Host "ERROR: wolfsshd.exe not found"
|
||||
exit 1
|
||||
}
|
||||
Add-Content -Path $env:GITHUB_ENV -Value "SSHD_PATH=$($sshdExe.FullName)"
|
||||
|
||||
$sshdDir = Split-Path -Parent $sshdExe.FullName
|
||||
$wolfsslDll = Get-ChildItem -Path "${{ github.workspace }}\wolfssl" -Recurse -Filter "wolfssl.dll" -ErrorAction SilentlyContinue | Select-Object -First 1
|
||||
if ($wolfsslDll -and -not (Test-Path (Join-Path $sshdDir "wolfssl.dll"))) {
|
||||
Copy-Item -Path $wolfsslDll.FullName -Destination (Join-Path $sshdDir "wolfssl.dll") -Force
|
||||
}
|
||||
|
||||
- name: Test LoginGraceTime enforcement on Windows
|
||||
working-directory: ${{ github.workspace }}\wolfssh\apps\wolfsshd\test
|
||||
shell: pwsh
|
||||
timeout-minutes: 2
|
||||
run: .\sshd_login_grace_test.ps1 -SshdExe "$env:SSHD_PATH"
|
||||
|
||||
# Build and run the self-contained unit tests with the MSVC AddressSanitizer.
|
||||
# This is the only job that executes wolfSSH tests under a sanitizer on
|
||||
# Windows, where the USE_WINDOWS_API console code (e.g. wolfSSH_DoOSC) is
|
||||
|
|
|
|||
|
|
@ -370,7 +370,6 @@ else
|
|||
|
||||
#Github actions needs resolved for these test cases
|
||||
#run_test "error_return.sh"
|
||||
#run_test "sshd_login_grace_test.sh"
|
||||
|
||||
# add additional tests here, check on var USING_LOCAL_HOST if can make sshd
|
||||
# server start/restart with changes
|
||||
|
|
@ -397,9 +396,10 @@ else
|
|||
run_test "sshd_window_full_test.sh"
|
||||
run_test "sshd_empty_password_test.sh"
|
||||
run_strictmodes_negative_test
|
||||
run_test "sshd_login_grace_test.sh"
|
||||
else
|
||||
printf "Skipping tests that need to setup local SSHD\n"
|
||||
SKIPPED=$((SKIPPED+4))
|
||||
SKIPPED=$((SKIPPED+5))
|
||||
fi
|
||||
|
||||
# these tests run with X509 sshd-config loaded
|
||||
|
|
|
|||
|
|
@ -0,0 +1,136 @@
|
|||
#!/usr/bin/env pwsh
|
||||
#
|
||||
# Windows regression test for wolfsshd LoginGraceTime enforcement.
|
||||
#
|
||||
# Opens a raw TCP connection that never authenticates and verifies that
|
||||
# wolfsshd drops it at the login grace deadline. No Windows user account or
|
||||
# authorized key is required, because the connection is closed before
|
||||
# authentication ever completes - this exercises the pre-auth grace timer only.
|
||||
#
|
||||
# The positive path - a successful authentication calling CancelLoginTimer so
|
||||
# the session survives past the grace deadline - is deliberately not covered
|
||||
# here, as it would require provisioning a real Windows user account and key.
|
||||
# That cancel-on-success path is exercised on POSIX by sshd_login_grace_test.sh.
|
||||
#
|
||||
# Enforcement is checked behaviorally (the server closes the connection at the
|
||||
# grace deadline), not by reading the daemon log, so the test does not depend on
|
||||
# debug logging being compiled into the wolfSSH Windows build.
|
||||
#
|
||||
# Usage:
|
||||
# pwsh sshd_login_grace_test.ps1 -SshdExe <path-to-wolfsshd.exe> [-Port N] [-Grace N]
|
||||
# (SshdExe also accepts the SSHD_PATH environment variable.)
|
||||
|
||||
param(
|
||||
[string]$SshdExe = $env:SSHD_PATH,
|
||||
[int]$Port = 22224,
|
||||
[int]$Grace = 5
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$exitCode = 1
|
||||
|
||||
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
$repoRoot = (Resolve-Path (Join-Path $scriptDir "..\..\..")).Path
|
||||
$keyPath = (Resolve-Path (Join-Path $repoRoot "keys\server-key.pem")).Path
|
||||
$confFile = Join-Path $scriptDir "sshd_config_test_login_grace"
|
||||
$authFile = Join-Path $scriptDir "authorized_keys_test"
|
||||
|
||||
if (-not $SshdExe -or -not (Test-Path $SshdExe)) {
|
||||
Write-Host "ERROR: wolfsshd.exe not found (pass -SshdExe or set SSHD_PATH)"
|
||||
exit 1
|
||||
}
|
||||
|
||||
@"
|
||||
Port $Port
|
||||
Protocol 2
|
||||
LoginGraceTime $Grace
|
||||
PermitRootLogin yes
|
||||
PasswordAuthentication yes
|
||||
PermitEmptyPasswords no
|
||||
UseDNS no
|
||||
HostKey $keyPath
|
||||
AuthorizedKeysFile $authFile
|
||||
"@ | Out-File -FilePath $confFile -Encoding ASCII
|
||||
|
||||
"" | Out-File -FilePath $authFile -Encoding ASCII
|
||||
|
||||
# Run wolfsshd in the foreground (-D selects the non-service path on Windows).
|
||||
$sshd = Start-Process -FilePath $SshdExe `
|
||||
-ArgumentList "-D", "-f", "`"$confFile`"", "-p", "$Port" `
|
||||
-NoNewWindow -PassThru
|
||||
|
||||
try {
|
||||
# Wait for the listener to accept connections.
|
||||
$up = $false
|
||||
for ($i = 0; $i -lt 20; $i++) {
|
||||
try {
|
||||
$probe = New-Object System.Net.Sockets.TcpClient
|
||||
$probe.Connect("127.0.0.1", $Port)
|
||||
$probe.Close()
|
||||
$up = $true
|
||||
break
|
||||
}
|
||||
catch {
|
||||
Start-Sleep -Milliseconds 500
|
||||
}
|
||||
}
|
||||
if (-not $up) {
|
||||
# throw rather than exit so the finally block still stops the daemon
|
||||
throw "wolfsshd did not start listening on port $Port"
|
||||
}
|
||||
|
||||
# Open a raw TCP connection and never authenticate. The server sends its
|
||||
# banner, waits for ours, and must close the connection once the login grace
|
||||
# time expires. Block on Read (with a timeout well past the grace time) and
|
||||
# measure when the server closes the connection.
|
||||
$stall = New-Object System.Net.Sockets.TcpClient
|
||||
$stall.Connect("127.0.0.1", $Port)
|
||||
$stream = $stall.GetStream()
|
||||
$stream.ReadTimeout = ($Grace + 5) * 1000
|
||||
|
||||
$buf = New-Object byte[] 4096
|
||||
$dropped = $false
|
||||
$sw = [System.Diagnostics.Stopwatch]::StartNew()
|
||||
try {
|
||||
while ($true) {
|
||||
$n = $stream.Read($buf, 0, $buf.Length)
|
||||
if ($n -le 0) {
|
||||
$dropped = $true # server closed the connection
|
||||
break
|
||||
}
|
||||
# otherwise the server sent its banner; keep waiting for the drop
|
||||
}
|
||||
}
|
||||
catch [System.IO.IOException] {
|
||||
# A server close can surface as a reset (IOException), not a graceful
|
||||
# EOF. Decide by elapsed time like the .sh test: a throw before the read
|
||||
# timeout means the server closed the connection.
|
||||
$dropped = $sw.Elapsed.TotalSeconds -lt ($Grace + 4)
|
||||
}
|
||||
$elapsed = [math]::Round($sw.Elapsed.TotalSeconds, 1)
|
||||
$stall.Close()
|
||||
|
||||
Write-Host "connection closed=$dropped after ${elapsed}s (grace=$Grace)"
|
||||
|
||||
if ($dropped -and ($elapsed -ge ($Grace - 1)) -and ($elapsed -le ($Grace + 4))) {
|
||||
Write-Host "PASS: unauthenticated connection dropped at login grace deadline"
|
||||
$exitCode = 0
|
||||
}
|
||||
elseif ($dropped) {
|
||||
Write-Host "FAIL: connection closed at ${elapsed}s, not near the grace deadline ($Grace s)"
|
||||
}
|
||||
else {
|
||||
Write-Host "FAIL: connection still open past the grace time (not enforced)"
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Host "ERROR: $_"
|
||||
$exitCode = 1
|
||||
}
|
||||
finally {
|
||||
if ($sshd -and -not $sshd.HasExited) {
|
||||
Stop-Process -Id $sshd.Id -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
|
||||
exit $exitCode
|
||||
|
|
@ -33,6 +33,9 @@ AuthorizedKeysFile $PWD/authorized_keys_test
|
|||
EOF
|
||||
|
||||
start_wolfsshd "sshd_config_test_login_grace"
|
||||
# ensure the daemon is stopped on every exit path, including the failure
|
||||
# exits below, so a leftover wolfsshd cannot interfere with later tests
|
||||
trap stop_wolfsshd EXIT
|
||||
pushd ../../..
|
||||
|
||||
TEST_CLIENT="./examples/client/client"
|
||||
|
|
@ -47,22 +50,55 @@ if [ "$RESULT" != 0 ]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
# attempt clearing out stdin from previous echo/grep
|
||||
read -t 1 -n 1000 discard
|
||||
|
||||
# test grace login timeout by stalling on password prompt
|
||||
timeout --foreground 7 "$TEST_CLIENT" -u "$USER" -h "$TEST_HOST" -p "$TEST_PORT" -t
|
||||
|
||||
popd
|
||||
cat ./log.txt | grep "Failed login within grace period"
|
||||
RESULT=$?
|
||||
if [ "$RESULT" != 0 ]; then
|
||||
echo "FAIL: Grace period not hit"
|
||||
cat ./log.txt
|
||||
|
||||
# Test the grace-time timeout behaviorally: open a raw TCP connection, never
|
||||
# authenticate, and confirm the server closes it at the grace deadline. This
|
||||
# asserts the actual behavior rather than scraping the log, matching the Windows
|
||||
# PowerShell test (and not relying on the daemon log being readable).
|
||||
GRACE=5
|
||||
if ! exec 3<>"/dev/tcp/$TEST_HOST/$TEST_PORT"; then
|
||||
echo "FAIL: could not connect to $TEST_HOST:$TEST_PORT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# The server sends its banner, waits for ours (which never comes), then closes
|
||||
# the connection once the grace time expires. Read until the server closes the
|
||||
# connection (EOF) or the per-read timeout elapses, and measure how long it
|
||||
# took. Use a large read timeout (GRACE + 8) and decide by elapsed time rather
|
||||
# than read's exit status, which differs across bash versions (timeout returns
|
||||
# >128 on modern bash but 1 on the macOS bash 3.2).
|
||||
START=$SECONDS
|
||||
while true; do
|
||||
if IFS= read -r -t $((GRACE + 8)) -n 1024 _ <&3; then
|
||||
: # received banner/data, keep waiting for the server to close
|
||||
else
|
||||
break # server closed (EOF) or the read timeout elapsed
|
||||
fi
|
||||
done
|
||||
ELAPSED=$((SECONDS - START))
|
||||
exec 3>&-
|
||||
|
||||
# An exit well before the read timeout means the server closed the connection;
|
||||
# an exit near GRACE + 8 means it stayed open (not enforced).
|
||||
if [ "$ELAPSED" -le $((GRACE + 4)) ]; then
|
||||
DROPPED=1
|
||||
else
|
||||
DROPPED=0
|
||||
fi
|
||||
|
||||
echo "connection closed=$DROPPED after ${ELAPSED}s (grace=$GRACE)"
|
||||
|
||||
if [ "$DROPPED" = 1 ] && [ "$ELAPSED" -ge $((GRACE - 1)) ]; then
|
||||
echo "PASS: unauthenticated connection dropped at login grace deadline"
|
||||
elif [ "$DROPPED" = 1 ]; then
|
||||
echo "FAIL: connection closed at ${ELAPSED}s, before the grace deadline ($GRACE s)"
|
||||
exit 1
|
||||
else
|
||||
echo "FAIL: connection still open past the grace time (not enforced)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
stop_wolfsshd
|
||||
exit 0
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -117,6 +117,12 @@ typedef struct WOLFSSHD_CONNECTION {
|
|||
int listenFd;
|
||||
char ip[INET6_ADDRSTRLEN];
|
||||
byte isThreaded;
|
||||
#ifdef _WIN32
|
||||
/* set when the login grace time expires before authentication completes;
|
||||
* POSIX uses the file-scope loginGraceTimedOut flag instead */
|
||||
volatile byte timeOut;
|
||||
PTP_TIMER loginTimer; /* threadpool timer enforcing login grace time */
|
||||
#endif
|
||||
} WOLFSSHD_CONNECTION;
|
||||
|
||||
#ifdef __unix__
|
||||
|
|
@ -217,11 +223,11 @@ static void interruptCatch(int in)
|
|||
static void wolfSSHDLoggingCb(enum wolfSSH_LogLevel lvl, const char *const str)
|
||||
{
|
||||
/* always log errors and optionally log other info/debug level messages */
|
||||
if (lvl == WS_LOG_ERROR) {
|
||||
fprintf(logFile, "[PID %d]: %s\n", WGETPID(), str);
|
||||
}
|
||||
else if (debugMode) {
|
||||
if (lvl == WS_LOG_ERROR || debugMode) {
|
||||
fprintf(logFile, "[PID %d]: %s\n", WGETPID(), str);
|
||||
/* flush so each line is visible immediately, e.g. to a consumer
|
||||
* reading the log file while the daemon is still running */
|
||||
fflush(logFile);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1946,26 +1952,72 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
static volatile int timeOut = 0;
|
||||
#ifdef _WIN32
|
||||
/* Cancels and frees the login grace time threadpool timer for a connection. */
|
||||
static void CancelLoginTimer(WOLFSSHD_CONNECTION* conn)
|
||||
{
|
||||
if (conn != NULL && conn->loginTimer != NULL) {
|
||||
/* setting the due time to NULL cancels any pending timer */
|
||||
SetThreadpoolTimer(conn->loginTimer, NULL, 0, 0);
|
||||
WaitForThreadpoolTimerCallbacks(conn->loginTimer, TRUE);
|
||||
CloseThreadpoolTimer(conn->loginTimer);
|
||||
conn->loginTimer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* threadpool callback marking a connection as timed out at the grace deadline */
|
||||
static VOID CALLBACK GraceTimeoutCb(PTP_CALLBACK_INSTANCE instance, PVOID ctx,
|
||||
PTP_TIMER timer)
|
||||
{
|
||||
WOLFSSHD_CONNECTION* conn = (WOLFSSHD_CONNECTION*)ctx;
|
||||
|
||||
if (conn != NULL) {
|
||||
/* published with an interlocked write so the connection thread reading
|
||||
* the flag in LoginGraceExpired() sees it without a data race */
|
||||
InterlockedExchange8((volatile CHAR*)&conn->timeOut, 1);
|
||||
}
|
||||
(void)instance;
|
||||
(void)timer;
|
||||
}
|
||||
#else
|
||||
static __thread int timeOut = 0;
|
||||
#endif
|
||||
/* Set by the SIGALRM handler when the login grace time expires. A signal
|
||||
* handler may only access a volatile sig_atomic_t object, so the handler sets
|
||||
* just this flag and the accept loop observes it. */
|
||||
static volatile sig_atomic_t loginGraceTimedOut = 0;
|
||||
|
||||
static void alarmCatch(int signum)
|
||||
{
|
||||
timeOut = 1;
|
||||
loginGraceTimedOut = 1;
|
||||
(void)signum;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Returns non-zero once the login grace time has expired for this connection.
|
||||
* On Windows the threadpool callback records it on the connection; on POSIX the
|
||||
* SIGALRM handler sets a sig_atomic_t flag that the accept loop reads here. */
|
||||
static int LoginGraceExpired(WOLFSSHD_CONNECTION* conn)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
/* interlocked read pairs with the InterlockedExchange8 in GraceTimeoutCb;
|
||||
* the OR with 0 is a read-modify-write, hence the non-const parameter */
|
||||
return InterlockedOr8((volatile CHAR*)&conn->timeOut, 0);
|
||||
#else
|
||||
(void)conn;
|
||||
return (int)loginGraceTimedOut;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int UserAuthResult(byte result,
|
||||
WS_UserAuthData* authData, void* userAuthResultCtx)
|
||||
{
|
||||
(void)authData;
|
||||
(void)userAuthResultCtx;
|
||||
|
||||
if (result == WOLFSSH_USERAUTH_SUCCESS) {
|
||||
#ifndef WIN32
|
||||
/* @TODO alarm catch on windows */
|
||||
/* authentication finished in time, cancel the login grace timer */
|
||||
#ifdef _WIN32
|
||||
CancelLoginTimer((WOLFSSHD_CONNECTION*)userAuthResultCtx);
|
||||
#else
|
||||
(void)userAuthResultCtx;
|
||||
alarm(0);
|
||||
#endif
|
||||
}
|
||||
|
|
@ -2002,28 +2054,47 @@ static void* HandleConnection(void* arg)
|
|||
|
||||
if (ret == WS_SUCCESS) {
|
||||
int select_ret = 0;
|
||||
int timedOut = 0;
|
||||
long graceTime;
|
||||
|
||||
wolfSSH_set_fd(ssh, conn->fd);
|
||||
wolfSSH_SetUserAuthCtx(ssh, conn->auth);
|
||||
/* let UserAuthResult reach this connection to cancel the grace timer */
|
||||
wolfSSH_SetUserAuthResultCtx(ssh, conn);
|
||||
|
||||
/* set alarm for login grace time */
|
||||
/* arm the login grace timer */
|
||||
graceTime = wolfSSHD_AuthGetGraceTime(conn->auth);
|
||||
if (graceTime > 0) {
|
||||
#ifdef WIN32
|
||||
/* LoginGraceTime enforcement is not yet implemented on Windows.
|
||||
* @TODO implement via CreateWaitableTimer or similar. */
|
||||
wolfSSH_Log(WS_LOG_WARN, "[SSHD] LoginGraceTime is set but "
|
||||
"not enforced on this platform");
|
||||
#ifdef _WIN32
|
||||
FILETIME due;
|
||||
ULARGE_INTEGER rel;
|
||||
|
||||
/* negative relative time, in 100 ns units */
|
||||
rel.QuadPart = (ULONGLONG)(-((LONGLONG)graceTime * 10000000LL));
|
||||
due.dwLowDateTime = rel.LowPart;
|
||||
due.dwHighDateTime = rel.HighPart;
|
||||
|
||||
conn->loginTimer = CreateThreadpoolTimer(GraceTimeoutCb, conn, NULL);
|
||||
if (conn->loginTimer == NULL) {
|
||||
/* fail closed: mark the connection as timed out so the accept
|
||||
* loop exits immediately rather than enforcing no grace time */
|
||||
InterlockedExchange8((volatile CHAR*)&conn->timeOut, 1);
|
||||
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Unable to create login grace "
|
||||
"timer, closing connection");
|
||||
}
|
||||
else {
|
||||
SetThreadpoolTimer(conn->loginTimer, &due, 0, 0);
|
||||
}
|
||||
#else
|
||||
signal(SIGALRM, alarmCatch);
|
||||
loginGraceTimedOut = 0; /* clear any stale state before arming */
|
||||
alarm((unsigned int)graceTime);
|
||||
#endif
|
||||
}
|
||||
|
||||
ret = wolfSSH_accept(ssh);
|
||||
error = wolfSSH_get_error(ssh);
|
||||
while (timeOut == 0 && (ret != WS_SUCCESS
|
||||
while (LoginGraceExpired(conn) == 0 && (ret != WS_SUCCESS
|
||||
&& ret != WS_SCP_INIT && ret != WS_SFTP_COMPLETE)
|
||||
&& (error == WS_WANT_READ || error == WS_WANT_WRITE)) {
|
||||
|
||||
|
|
@ -2041,16 +2112,24 @@ static void* HandleConnection(void* arg)
|
|||
error = WS_FATAL_ERROR;
|
||||
}
|
||||
|
||||
wolfSSH_Log(WS_LOG_ERROR,
|
||||
"[SSHD] grace time = %ld timeout = %d", graceTime, timeOut);
|
||||
/* read the flag once through the accessor; on Windows this is an
|
||||
* interlocked read of the value the threadpool callback published, on
|
||||
* POSIX it is the SIGALRM handler's loginGraceTimedOut flag */
|
||||
timedOut = LoginGraceExpired(conn);
|
||||
wolfSSH_Log(WS_LOG_INFO,
|
||||
"[SSHD] grace time = %ld timeout = %d", graceTime,
|
||||
timedOut);
|
||||
if (graceTime > 0) {
|
||||
if (timeOut) {
|
||||
/* only report a grace failure when authentication did not also
|
||||
* complete in the same accept iteration */
|
||||
if (timedOut && ret != WS_SUCCESS &&
|
||||
ret != WS_SFTP_COMPLETE && ret != WS_SCP_INIT) {
|
||||
wolfSSH_Log(WS_LOG_ERROR,
|
||||
"[SSHD] Failed login within grace period");
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
/* @TODO SetTimer(NULL, NULL, graceTime, alarmCatch); */
|
||||
#ifdef _WIN32
|
||||
CancelLoginTimer(conn); /* cancel any pending timer */
|
||||
#else
|
||||
alarm(0); /* cancel any alarm */
|
||||
#endif
|
||||
|
|
@ -2736,6 +2815,10 @@ static int StartSSHD(int argc, char** argv)
|
|||
conn->auth = auth;
|
||||
conn->listenFd = (int)listenFd;
|
||||
conn->isThreaded = isDaemon;
|
||||
#ifdef _WIN32
|
||||
conn->timeOut = 0;
|
||||
conn->loginTimer = NULL;
|
||||
#endif
|
||||
|
||||
/* wait for a connection */
|
||||
if (PendingConnection(listenFd)) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue