Merge pull request #882 from JacobBarthelmeh/sftp

More robust SFTP send/read handling
pull/889/head
John Safranek 2026-03-06 07:35:58 -08:00 committed by GitHub
commit be69a46db0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 590 additions and 79 deletions

View File

@ -42,7 +42,7 @@ jobs:
id: cache-wolfssl id: cache-wolfssl
with: with:
path: build-dir/ path: build-dir/
key: wolfssh-sftp-wolfssl-${{ matrix.wolfssl }}-${{ matrix.os }} key: wolfssh-sftp-wolfssl-${{ matrix.wolfssl }}-${{ matrix.os }}-keygen
lookup-only: true lookup-only: true
- name: Checkout, build, and install wolfssl - name: Checkout, build, and install wolfssl
@ -52,7 +52,7 @@ jobs:
repository: wolfssl/wolfssl repository: wolfssl/wolfssl
ref: ${{ matrix.wolfssl }} ref: ${{ matrix.wolfssl }}
path: wolfssl path: wolfssl
configure: --enable-ssh configure: --enable-ssh --enable-keygen
check: false check: false
install: true install: true
@ -73,7 +73,7 @@ jobs:
uses: actions/cache@v4 uses: actions/cache@v4
with: with:
path: build-dir/ path: build-dir/
key: wolfssh-sftp-wolfssl-${{ matrix.wolfssl }}-${{ matrix.os }} key: wolfssh-sftp-wolfssl-${{ matrix.wolfssl }}-${{ matrix.os }}-keygen
fail-on-cache-miss: true fail-on-cache-miss: true
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@ -124,13 +124,13 @@ jobs:
expect eof expect eof
EOF EOF
chmod +x /tmp/sftp_test.exp chmod +x /tmp/sftp_test.exp
# Install expect # Install expect
sudo apt-get update && sudo apt-get install -y expect sudo apt-get update && sudo apt-get install -y expect
# Run the expect script # Run the expect script
/tmp/sftp_test.exp /tmp/sftp_test.exp
# Verify the files match # Verify the files match
echo "Verifying file integrity..." echo "Verifying file integrity..."
if cmp -s /tmp/test.dat /tmp/sftp_test_dir/test_received.dat; then if cmp -s /tmp/test.dat /tmp/sftp_test_dir/test_received.dat; then
@ -139,3 +139,90 @@ jobs:
echo "SFTP Test FAILED: Files do not match" echo "SFTP Test FAILED: Files do not match"
exit 1 exit 1
fi fi
build_wolfssh_large_rw:
needs:
- build_wolfssl
- create_matrix
strategy:
fail-fast: false
matrix:
os: [ ubuntu-latest ]
wolfssl: ${{ fromJson(needs.create_matrix.outputs['versions']) }}
name: Test wolfsftp large RW (10MB chunks, 3GB file)
runs-on: ${{ matrix.os }}
timeout-minutes: 20
steps:
- name: Checking cache for wolfssl
uses: actions/cache@v4
with:
path: build-dir/
key: wolfssh-sftp-wolfssl-${{ matrix.wolfssl }}-${{ matrix.os }}-keygen
fail-on-cache-miss: true
- uses: actions/checkout@v4
with:
path: wolfssh/
- name: autogen
working-directory: ./wolfssh/
run: ./autogen.sh
- name: configure
working-directory: ./wolfssh/
run: |
./configure --enable-all \
LDFLAGS="-L${{ github.workspace }}/build-dir/lib" \
CPPFLAGS="-I${{ github.workspace }}/build-dir/include -DWOLFSSH_NO_SFTP_TIMEOUT -DWOLFSSH_MAX_SFTP_RW=10485760 -DWOLFSSH_MAX_CHN_NAMESZ=4200"
- name: make
working-directory: ./wolfssh/
run: make
- name: Create 3GB test file
working-directory: ./wolfssh/
run: |
dd if=/dev/urandom of=seed.dat bs=1M count=10
for i in $(seq 1 308); do cat seed.dat >> large_test.dat; done
rm seed.dat
sha256sum large_test.dat > large_test.dat.sha256
echo "Created 3GB test file, SHA-256: $(cat large_test.dat.sha256)"
- name: Start echoserver
working-directory: ./wolfssh/
run: |
./examples/echoserver/echoserver -N -1 -R /tmp/echoserver_ready -d "$(pwd)" &
echo $! > /tmp/echoserver.pid
for i in $(seq 1 30); do
[ -s /tmp/echoserver_ready ] && break
sleep 0.2
done
if [ ! -s /tmp/echoserver_ready ]; then
echo "ERROR: echoserver failed to start"
exit 1
fi
echo "Echoserver ready on port $(cat /tmp/echoserver_ready)"
- name: SFTP get 3GB file with 10MB chunk size
working-directory: ./wolfssh/
run: |
port=$(cat /tmp/echoserver_ready)
./examples/sftpclient/wolfsftp -N -u jill -P upthehill -p "$port" \
-G -l /tmp/large_test_copy.dat -r "$(pwd)/large_test.dat"
- name: Verify file integrity
working-directory: ./wolfssh/
run: |
expected=$(awk '{print $1}' large_test.dat.sha256)
actual=$(sha256sum /tmp/large_test_copy.dat | awk '{print $1}')
echo "Expected SHA-256: $expected"
echo "Actual SHA-256: $actual"
if [ "$expected" != "$actual" ]; then
echo "FAIL: SHA-256 mismatch"
exit 1
fi
echo "PASS: 3GB SFTP transfer with WOLFSSH_MAX_SFTP_RW=10485760 succeeded"
- name: Stop echoserver
if: always()
run: kill "$(cat /tmp/echoserver.pid)" 2>/dev/null || true

View File

@ -0,0 +1,432 @@
name: Windows wolfsshd SFTP Test
# This workflow tests wolfsshd and SFTP on Windows with:
# 1. Basic test: wolfsshd + SFTP client (pwd, ls, put/get small file)
# 2. Large file test: WOLFSSH_NO_SFTP_TIMEOUT, WOLFSSH_MAX_SFTP_RW=10485760,
# WOLFSSH_MAX_CHN_NAMESZ=4200 - get and put a 3GB file
on:
push:
branches: [ 'master', 'main', 'release/**' ]
pull_request:
branches: [ '*' ]
env:
WOLFSSL_SOLUTION_FILE_PATH: wolfssl64.sln
SOLUTION_FILE_PATH: wolfssh.sln
USER_SETTINGS_H_NEW: wolfssh/ide/winvs/user_settings.h
USER_SETTINGS_H: wolfssl/IDE/WIN/user_settings.h
INCLUDE_DIR: wolfssh
WOLFSSL_BUILD_CONFIGURATION: Release
WOLFSSH_BUILD_CONFIGURATION: Release
BUILD_PLATFORM: x64
TARGET_PLATFORM: 10
TEST_PORT: 22222
jobs:
build:
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
include:
- test_type: basic
artifact_name: wolfssh-windows-build
- test_type: large_rw
artifact_name: wolfssh-windows-build-large-rw
steps:
- uses: actions/checkout@v4
with:
repository: wolfssl/wolfssl
path: wolfssl
- uses: actions/checkout@v4
with:
path: wolfssh
- name: Add MSBuild to PATH
uses: microsoft/setup-msbuild@v1
- name: Update user_settings.h for wolfSSL build
working-directory: ${{env.GITHUB_WORKSPACE}}
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: Restore wolfSSL NuGet packages
working-directory: ${{ github.workspace }}\wolfssl
run: nuget restore ${{env.WOLFSSL_SOLUTION_FILE_PATH}}
- name: Build wolfssl library
working-directory: ${{ github.workspace }}\wolfssl
run: msbuild /m /p:PlatformToolset=v142 /p:Platform=${{env.BUILD_PLATFORM}} /p:Configuration=${{env.WOLFSSL_BUILD_CONFIGURATION}} /t:wolfssl ${{env.WOLFSSL_SOLUTION_FILE_PATH}}
- name: Upload wolfSSL build artifacts
if: matrix.test_type == 'basic'
uses: actions/upload-artifact@v4
with:
name: wolfssl-windows-build
path: |
wolfssl/IDE/WIN/${{env.WOLFSSL_BUILD_CONFIGURATION}}/${{env.BUILD_PLATFORM}}/**
wolfssl/IDE/WIN/${{env.WOLFSSL_BUILD_CONFIGURATION}}/**
wolfssl/${{env.WOLFSSL_BUILD_CONFIGURATION}}/${{env.BUILD_PLATFORM}}/**
wolfssl/${{env.WOLFSSL_BUILD_CONFIGURATION}}/**
- name: Update user_settings.h for sshd and SFTP
working-directory: ${{env.GITHUB_WORKSPACE}}
shell: bash
run: |
# Enable SSHD, SFTP support (second #if 0 block)
sed -i 's/#if 0/#if 1/g' ${{env.USER_SETTINGS_H_NEW}}
cp ${{env.USER_SETTINGS_H_NEW}} ${{env.USER_SETTINGS_H}}
# For large_rw test: add SFTP large file defines
if [ "${{ matrix.test_type }}" = "large_rw" ]; then
echo "" >> ${{env.USER_SETTINGS_H_NEW}}
echo "/* SFTP large file test defines */" >> ${{env.USER_SETTINGS_H_NEW}}
echo "#define WOLFSSH_NO_SFTP_TIMEOUT" >> ${{env.USER_SETTINGS_H_NEW}}
echo "#define WOLFSSH_MAX_SFTP_RW 10485760" >> ${{env.USER_SETTINGS_H_NEW}}
echo "#define WOLFSSH_MAX_CHN_NAMESZ 4200" >> ${{env.USER_SETTINGS_H_NEW}}
echo "Added WOLFSSH_NO_SFTP_TIMEOUT, WOLFSSH_MAX_SFTP_RW=10485760, WOLFSSH_MAX_CHN_NAMESZ=4200"
cp ${{env.USER_SETTINGS_H_NEW}} ${{env.USER_SETTINGS_H}}
fi
- name: Restore NuGet packages
working-directory: ${{ github.workspace }}\wolfssh\ide\winvs
run: nuget restore ${{env.SOLUTION_FILE_PATH}}
- name: Build wolfssh
working-directory: ${{ github.workspace }}\wolfssh\ide\winvs
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: Upload wolfSSH build artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact_name }}
if-no-files-found: error
path: |
wolfssh/ide/winvs/**/Release/**
test:
needs: build
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
include:
- test_type: basic
artifact_name: wolfssh-windows-build
- test_type: large_rw
artifact_name: wolfssh-windows-build-large-rw
steps:
- uses: actions/checkout@v4
with:
path: wolfssh
- name: Download wolfSSH build artifacts
uses: actions/download-artifact@v4
with:
name: ${{ matrix.artifact_name }}
path: .
- name: Download wolfSSL build artifacts
uses: actions/download-artifact@v4
with:
name: wolfssl-windows-build
path: .
- name: Create Windows user testuser and authorized_keys
working-directory: ${{ github.workspace }}\wolfssh
shell: pwsh
run: |
$homeDir = "C:\Users\testuser"
$sshDir = "$homeDir\.ssh"
$authKeysFile = "$sshDir\authorized_keys"
$pw = 'T3stP@ss!xY9'
New-Item -ItemType Directory -Path $homeDir -Force | Out-Null
New-Item -ItemType Directory -Path $sshDir -Force | Out-Null
$o = net user testuser $pw /add /homedir:$homeDir 2>&1
if ($LASTEXITCODE -ne 0) {
if ($o -match "already exists") {
net user testuser /homedir:$homeDir 2>$null
} else {
Write-Host "net user failed: $o"
exit 1
}
}
Add-Content -Path $env:GITHUB_ENV -Value "TESTUSER_PASSWORD=$pw"
"" | Out-File -FilePath $authKeysFile -Encoding ASCII -NoNewline
icacls $authKeysFile /grant "testuser:R" /q
# Grant testuser full control of their home directory.
# New-Item creates the directory owned by the runner account; Windows
# only sets correct user ACLs during the normal profile-creation flow.
# Without this, ImpersonateLoggedOnUser succeeds but CreateFile fails
# with ACCESS_DENIED when wolfsshd tries to write files as testuser.
icacls $homeDir /grant "testuser:(OI)(CI)F" /T /q
$sid = (New-Object System.Security.Principal.NTAccount("testuser")).Translate([System.Security.Principal.SecurityIdentifier]).Value
$profKey = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$sid"
if (-not (Test-Path $profKey)) { New-Item -Path $profKey -Force | Out-Null }
Set-ItemProperty -Path $profKey -Name "ProfileImagePath" -Value $homeDir -Force
- name: Create wolfSSHd config file
working-directory: ${{ github.workspace }}\wolfssh
shell: pwsh
run: |
$keyPath = Join-Path "${{ github.workspace }}" "wolfssh\keys\server-key.pem"
$keyPathFull = (Resolve-Path $keyPath -ErrorAction Stop)
$configContent = @"
Port ${{env.TEST_PORT}}
PasswordAuthentication yes
PermitRootLogin yes
HostKey $($keyPathFull.Path)
AuthorizedKeysFile C:\Users\testuser\.ssh\authorized_keys
"@
$configContent | Out-File -FilePath sshd_config_test -Encoding ASCII
Get-Content sshd_config_test
- name: Find wolfSSH executables
working-directory: ${{ github.workspace }}\wolfssh
shell: pwsh
run: |
$searchRoot = "${{ github.workspace }}"
$sshdExe = Get-ChildItem -Path $searchRoot -Recurse -Filter "wolfsshd.exe" -ErrorAction SilentlyContinue |
Where-Object { $_.FullName -like "*Release*" } | Select-Object -First 1
if ($sshdExe) {
Add-Content -Path $env:GITHUB_ENV -Value "SSHD_PATH=$($sshdExe.FullName)"
} else {
Write-Host "ERROR: wolfsshd.exe not found"
exit 1
}
$sftpExe = Get-ChildItem -Path $searchRoot -Recurse -Filter "wolfsftp.exe" -ErrorAction SilentlyContinue |
Where-Object { $_.FullName -like "*Release*" } | Select-Object -First 1
if (-not $sftpExe) {
$sftpExe = Get-ChildItem -Path $searchRoot -Recurse -Filter "wolfsftp-client.exe" -ErrorAction SilentlyContinue |
Where-Object { $_.FullName -like "*Release*" } | Select-Object -First 1
}
if ($sftpExe) {
Add-Content -Path $env:GITHUB_ENV -Value "SFTP_PATH=$($sftpExe.FullName)"
} else {
Write-Host "ERROR: SFTP client exe not found"
exit 1
}
- name: Copy wolfSSL DLL to executable directory
working-directory: ${{ github.workspace }}
shell: pwsh
run: |
$sshdPath = $env:SSHD_PATH
$sshdDir = Split-Path -Parent $sshdPath
if (Test-Path (Join-Path $sshdDir "wolfssl.lib")) { exit 0 }
$wolfsslDll = Get-ChildItem -Path "${{ github.workspace }}\wolfssl" -Recurse -Filter "wolfssl.dll" -ErrorAction SilentlyContinue | Select-Object -First 1
if ($wolfsslDll) {
Copy-Item -Path $wolfsslDll.FullName -Destination (Join-Path $sshdDir "wolfssl.dll") -Force
}
- name: Grant service access to config and keys
working-directory: ${{ github.workspace }}\wolfssh
shell: pwsh
run: |
icacls (Get-Location).Path /grant "NT AUTHORITY\SYSTEM:(OI)(CI)RX" /T /q
- name: Start wolfSSHd as Windows service
working-directory: ${{ github.workspace }}\wolfssh
shell: pwsh
run: |
$sshdPath = $env:SSHD_PATH
$configPathFull = (Resolve-Path "sshd_config_test").Path
$serviceName = "wolfsshd"
$existingService = Get-Service -Name $serviceName -ErrorAction SilentlyContinue
if ($existingService) {
if ($existingService.Status -eq 'Running') { Stop-Service -Name $serviceName -Force }
sc.exe delete $serviceName | Out-Null
Start-Sleep -Seconds 2
}
$binPath = "`"$sshdPath`" -f `"$configPathFull`" -p ${{env.TEST_PORT}}"
sc.exe create $serviceName binPath= $binPath
sc.exe start $serviceName
Start-Sleep -Seconds 5
$service = Get-Service -Name $serviceName -ErrorAction SilentlyContinue
if ($service.Status -ne 'Running') {
Write-Host "ERROR: Service failed to start"
sc.exe query $serviceName
exit 1
}
Add-Content -Path $env:GITHUB_ENV -Value "SSHD_SERVICE_NAME=$serviceName"
- name: Test SFTP get non-existent file (no hang, correct error)
working-directory: ${{ github.workspace }}\wolfssh
shell: pwsh
timeout-minutes: 1
run: |
$sftpPath = $env:SFTP_PATH
$destFile = Join-Path $env:TEMP "copy.dat"
$getCommands = "get /this_file_does_not_exist_xyz $destFile`nquit"
$getCommands | Out-File -FilePath sftp_get_nonexistent_commands.txt -Encoding ASCII
$proc = Start-Process -FilePath $sftpPath `
-ArgumentList "-u", "testuser", "-P", $env:TESTUSER_PASSWORD, "-h", "localhost", "-p", "${{env.TEST_PORT}}" `
-RedirectStandardInput "sftp_get_nonexistent_commands.txt" `
-RedirectStandardOutput "sftp_get_nonexistent_out.txt" `
-RedirectStandardError "sftp_get_nonexistent_err.txt" `
-Wait -NoNewWindow -PassThru
Write-Host "=== SFTP Output ==="
$output = ""
if (Test-Path sftp_get_nonexistent_out.txt) {
$output = Get-Content sftp_get_nonexistent_out.txt -Raw
Write-Host $output
}
Write-Host "=== SFTP Error ==="
if (Test-Path sftp_get_nonexistent_err.txt) { Get-Content sftp_get_nonexistent_err.txt }
# Verify file was NOT created
if (Test-Path $destFile) {
Write-Host "ERROR: $destFile was created despite non-existent source file"
exit 1
}
# Verify error message was emitted
if ($output -notmatch "Error getting file") {
Write-Host "ERROR: Expected 'Error getting file' in output"
exit 1
}
Write-Host "PASS: SFTP get non-existent file did not create file, reported error correctly, did not hang"
- name: Test SFTP connection (basic)
if: matrix.test_type == 'basic'
working-directory: ${{ github.workspace }}\wolfssh
shell: pwsh
run: |
$sftpPath = $env:SFTP_PATH
$testCommands = "pwd`nls`nquit"
$testCommands | Out-File -FilePath sftp_commands.txt -Encoding ASCII
$process = Start-Process -FilePath $sftpPath `
-ArgumentList "-u", "testuser", "-P", $env:TESTUSER_PASSWORD, "-h", "localhost", "-p", "${{env.TEST_PORT}}" `
-RedirectStandardInput "sftp_commands.txt" `
-RedirectStandardOutput "sftp_output.txt" `
-RedirectStandardError "sftp_error.txt" `
-Wait -NoNewWindow -PassThru
Get-Content sftp_output.txt
Get-Content sftp_error.txt
if ($process.ExitCode -ne 0) {
Write-Host "ERROR: SFTP basic test failed with exit $($process.ExitCode)"
exit 1
}
Write-Host "Basic SFTP test passed"
- name: Create 3GB test file and run SFTP get/put
if: matrix.test_type == 'large_rw'
working-directory: ${{ github.workspace }}\wolfssh
shell: pwsh
timeout-minutes: 25
run: |
$sftpPath = $env:SFTP_PATH
$workDir = Join-Path $env:GITHUB_WORKSPACE "wolfssh"
$largeFile = Join-Path $workDir "large_test.dat"
$getDestPath = Join-Path $workDir "large_test_copy.dat"
# Create 3GB file: one random 10MB chunk repeated 307x + 2MB
Write-Host "Creating 3GB test file..."
$chunkSize = 10485760 # 10MB
$totalSize = [long]3221225472 # 3GB
$rng = New-Object System.Security.Cryptography.RNGCryptoServiceProvider
$chunk = New-Object byte[] $chunkSize
$rng.GetBytes($chunk)
$fs = [System.IO.File]::Create($largeFile)
$remaining = $totalSize
while ($remaining -gt 0) {
$toWrite = [int][Math]::Min([long]$chunkSize, $remaining)
$fs.Write($chunk, 0, $toWrite)
$remaining -= $toWrite
}
$fs.Close()
$hash = Get-FileHash -Path $largeFile -Algorithm SHA256
$hash.Hash | Out-File -FilePath (Join-Path $workDir "large_test.dat.sha256")
Write-Host "Created 3GB file, SHA256: $($hash.Hash)"
# SFTP PUT (upload)
# Use a relative remote path (no leading /) so the server resolves it
# under testuser's home directory. An absolute /large_test.dat maps to
# the drive root (C:\) where testuser has no write permission; relative
# large_test.dat is prefixed by workingDir (C:\Users\testuser) on the
# client and becomes C:\Users\testuser\large_test.dat on the server.
Write-Host "SFTP PUT 3GB file..."
$putCommands = "put $largeFile large_test.dat`nquit"
$putCommands | Out-File -FilePath (Join-Path $workDir "sftp_put_commands.txt") -Encoding ASCII
$proc = Start-Process -FilePath $sftpPath `
-ArgumentList "-u", "testuser", "-P", $env:TESTUSER_PASSWORD, "-h", "localhost", "-p", "${{env.TEST_PORT}}" `
-WorkingDirectory $workDir `
-RedirectStandardInput (Join-Path $workDir "sftp_put_commands.txt") `
-RedirectStandardOutput (Join-Path $workDir "sftp_put_out.txt") `
-RedirectStandardError (Join-Path $workDir "sftp_put_err.txt") `
-Wait -NoNewWindow -PassThru
$putOut = Get-Content (Join-Path $workDir "sftp_put_out.txt") -Raw -ErrorAction SilentlyContinue
Write-Host "=== SFTP PUT output ==="; Write-Host $putOut
if ($proc.ExitCode -ne 0 -or $putOut -match "Error pushing file") {
Get-Content (Join-Path $workDir "sftp_put_err.txt") -ErrorAction SilentlyContinue
Write-Host "ERROR: SFTP PUT failed"
exit 1
}
Write-Host "PUT succeeded"
# SFTP GET (download) - relative remote and local paths.
# Remote large_test.dat resolves to C:\Users\testuser\large_test.dat.
# Local large_test_copy.dat is relative to wolfsftp's CWD ($workDir).
Write-Host "SFTP GET 3GB file..."
$getCommands = "get large_test.dat large_test_copy.dat`nquit"
$getCommands | Out-File -FilePath (Join-Path $workDir "sftp_get_commands.txt") -Encoding ASCII
$proc2 = Start-Process -FilePath $sftpPath `
-ArgumentList "-u", "testuser", "-P", $env:TESTUSER_PASSWORD, "-h", "localhost", "-p", "${{env.TEST_PORT}}" `
-WorkingDirectory $workDir `
-RedirectStandardInput (Join-Path $workDir "sftp_get_commands.txt") `
-RedirectStandardOutput (Join-Path $workDir "sftp_get_out.txt") `
-RedirectStandardError (Join-Path $workDir "sftp_get_err.txt") `
-Wait -NoNewWindow -PassThru
$getOut = Get-Content (Join-Path $workDir "sftp_get_out.txt") -Raw -ErrorAction SilentlyContinue
Write-Host "=== SFTP GET output ==="; Write-Host $getOut
if ($proc2.ExitCode -ne 0 -or $getOut -match "Error getting file") {
Get-Content (Join-Path $workDir "sftp_get_err.txt") -ErrorAction SilentlyContinue
Write-Host "ERROR: SFTP GET failed"
exit 1
}
Write-Host "GET succeeded"
# Verify integrity (file is in $workDir from GET with relative path)
$expectedHash = (Get-Content (Join-Path $workDir "large_test.dat.sha256")).Trim()
$actualHash = (Get-FileHash -Path $getDestPath -Algorithm SHA256).Hash
Write-Host "File: $getDestPath"
Write-Host "Expected SHA256: $expectedHash"
Write-Host "Actual SHA256: $actualHash"
if ($expectedHash -ne $actualHash) {
Write-Host "ERROR: SHA256 mismatch - PUT/GET corruption"
exit 1
}
Write-Host "PASS: 3GB SFTP get/put succeeded"
- name: Cleanup
if: always()
working-directory: ${{ github.workspace }}\wolfssh
shell: pwsh
run: |
$serviceName = $env:SSHD_SERVICE_NAME
if (-not $serviceName) { $serviceName = "wolfsshd" }
$service = Get-Service -Name $serviceName -ErrorAction SilentlyContinue
if ($service) {
if ($service.Status -eq 'Running') { Stop-Service -Name $serviceName -Force }
sc.exe delete $serviceName | Out-Null
}

View File

@ -154,6 +154,7 @@ static void myStatusCb(WOLFSSH* sshIn, word32* bytes, char* name)
word32 currentTime; word32 currentTime;
#ifndef WOLFSSH_NO_TIMESTAMP #ifndef WOLFSSH_NO_TIMESTAMP
static word32 lastOutputTime = 0; static word32 lastOutputTime = 0;
static word32 lastPrintedBytes[2] = {0, 0};
word32 elapsedTime; word32 elapsedTime;
#endif #endif
char buf[80]; char buf[80];
@ -162,12 +163,24 @@ static void myStatusCb(WOLFSSH* sshIn, word32* bytes, char* name)
#ifndef WOLFSSH_NO_TIMESTAMP #ifndef WOLFSSH_NO_TIMESTAMP
currentTime = current_time(0); currentTime = current_time(0);
if (currentTime == lastOutputTime) { if (currentTime == lastOutputTime) {
return; if (bytes[0] != lastPrintedBytes[0] || bytes[1] != lastPrintedBytes[1]) {
/* Progress made in the same second — throttle but track latest */
lastPrintedBytes[0] = bytes[0];
lastPrintedBytes[1] = bytes[1];
return;
}
/* bytes unchanged: EOF final call — fall through to print */
} }
lastOutputTime = currentTime; else {
lastOutputTime = currentTime;
}
lastPrintedBytes[0] = bytes[0];
lastPrintedBytes[1] = bytes[1];
if (WSTRNCMP(currentFile, name, WSTRLEN(name)) != 0) { if (WSTRNCMP(currentFile, name, WSTRLEN(name)) != 0) {
startTime = current_time(1); startTime = current_time(1);
lastOutputTime = 0; /* Reset timer for new file transfer */ lastOutputTime = 0; /* Reset timer for new file transfer */
lastPrintedBytes[0] = 0;
lastPrintedBytes[1] = 0;
WMEMSET(currentFile, 0, WOLFSSH_MAX_FILENAME); WMEMSET(currentFile, 0, WOLFSSH_MAX_FILENAME);
WSTRNCPY(currentFile, name, WOLFSSH_MAX_FILENAME); WSTRNCPY(currentFile, name, WOLFSSH_MAX_FILENAME);
} }
@ -756,8 +769,8 @@ static int doCmds(func_args* args)
ret = wolfSSH_SFTP_STAT(ssh, pt, &atrb); ret = wolfSSH_SFTP_STAT(ssh, pt, &atrb);
err = wolfSSH_get_error(ssh); err = wolfSSH_get_error(ssh);
} while ((err == WS_WANT_READ || err == WS_WANT_WRITE) } while ((err == WS_WANT_READ || err == WS_WANT_WRITE ||
&& ret != WS_SUCCESS); err == WS_REKEYING) && ret != WS_SUCCESS);
if (ret != WS_SUCCESS) { if (ret != WS_SUCCESS) {
if (SFTP_FPUTS(args, "Error changing directory\n") < 0) { if (SFTP_FPUTS(args, "Error changing directory\n") < 0) {
err_msg("fputs error"); err_msg("fputs error");
@ -844,8 +857,8 @@ static int doCmds(func_args* args)
ret = wolfSSH_SFTP_CHMOD(ssh, pt, mode); ret = wolfSSH_SFTP_CHMOD(ssh, pt, mode);
err = wolfSSH_get_error(ssh); err = wolfSSH_get_error(ssh);
} while ((err == WS_WANT_READ || err == WS_WANT_WRITE) } while ((err == WS_WANT_READ || err == WS_WANT_WRITE ||
&& ret != WS_SUCCESS); err == WS_REKEYING) && ret != WS_SUCCESS);
if (ret != WS_SUCCESS) { if (ret != WS_SUCCESS) {
if (SFTP_FPUTS(args, "Unable to change permissions of ") < 0) { if (SFTP_FPUTS(args, "Unable to change permissions of ") < 0) {
err_msg("fputs error"); err_msg("fputs error");
@ -901,8 +914,8 @@ static int doCmds(func_args* args)
ret = wolfSSH_SFTP_RMDIR(ssh, pt); ret = wolfSSH_SFTP_RMDIR(ssh, pt);
err = wolfSSH_get_error(ssh); err = wolfSSH_get_error(ssh);
} while ((err == WS_WANT_READ || err == WS_WANT_WRITE) } while ((err == WS_WANT_READ || err == WS_WANT_WRITE ||
&& ret != WS_SUCCESS); err == WS_REKEYING) && ret != WS_SUCCESS);
if (ret != WS_SUCCESS) { if (ret != WS_SUCCESS) {
if (ret == WS_PERMISSIONS) { if (ret == WS_PERMISSIONS) {
if (SFTP_FPUTS(args, "Insufficient permissions\n") < 0) { if (SFTP_FPUTS(args, "Insufficient permissions\n") < 0) {
@ -954,8 +967,8 @@ static int doCmds(func_args* args)
ret = wolfSSH_SFTP_Remove(ssh, pt); ret = wolfSSH_SFTP_Remove(ssh, pt);
err = wolfSSH_get_error(ssh); err = wolfSSH_get_error(ssh);
} while ((err == WS_WANT_READ || err == WS_WANT_WRITE) } while ((err == WS_WANT_READ || err == WS_WANT_WRITE ||
&& ret != WS_SUCCESS); err == WS_REKEYING) && ret != WS_SUCCESS);
if (ret != WS_SUCCESS) { if (ret != WS_SUCCESS) {
if (ret == WS_PERMISSIONS) { if (ret == WS_PERMISSIONS) {
if (SFTP_FPUTS(args, "Insufficient permissions\n") < 0) { if (SFTP_FPUTS(args, "Insufficient permissions\n") < 0) {

View File

@ -6435,7 +6435,7 @@ static WS_SFTPNAME* wolfSSH_SFTP_DoName(WOLFSSH* ssh)
ret = wolfSSH_SFTP_buffer_read(ssh, &state->buffer, ret = wolfSSH_SFTP_buffer_read(ssh, &state->buffer,
wolfSSH_SFTP_buffer_size(&state->buffer)); wolfSSH_SFTP_buffer_size(&state->buffer));
if (ret < 0) { if (ret < 0) {
if (ssh->error != WS_WANT_READ) { if (!NoticeError(ssh)) {
wolfSSH_SFTP_ClearState(ssh, STATE_ID_NAME); wolfSSH_SFTP_ClearState(ssh, STATE_ID_NAME);
} }
return NULL; return NULL;
@ -6443,7 +6443,7 @@ static WS_SFTPNAME* wolfSSH_SFTP_DoName(WOLFSSH* ssh)
wolfSSH_SFTP_buffer_rewind(&state->buffer); wolfSSH_SFTP_buffer_rewind(&state->buffer);
wolfSSH_SFTP_DoStatus(ssh, reqId, &state->buffer); wolfSSH_SFTP_DoStatus(ssh, reqId, &state->buffer);
if (ssh->error != WS_WANT_READ) { if (!NoticeError(ssh)) {
wolfSSH_SFTP_ClearState(ssh, STATE_ID_NAME); wolfSSH_SFTP_ClearState(ssh, STATE_ID_NAME);
} }
return NULL; return NULL;
@ -6458,7 +6458,7 @@ static WS_SFTPNAME* wolfSSH_SFTP_DoName(WOLFSSH* ssh)
wolfSSH_SFTP_buffer_size(&state->buffer) - wolfSSH_SFTP_buffer_size(&state->buffer) -
wolfSSH_SFTP_buffer_idx(&state->buffer)); wolfSSH_SFTP_buffer_idx(&state->buffer));
if (ret <= 0) { if (ret <= 0) {
if (ssh->error != WS_WANT_READ) { if (!NoticeError(ssh)) {
wolfSSH_SFTP_ClearState(ssh, STATE_ID_NAME); wolfSSH_SFTP_ClearState(ssh, STATE_ID_NAME);
} }
return NULL; return NULL;
@ -6909,8 +6909,7 @@ int wolfSSH_SFTP_CHMOD(WOLFSSH* ssh, char* n, char* oct)
case STATE_CHMOD_GET: case STATE_CHMOD_GET:
/* get current attributes of path */ /* get current attributes of path */
if ((ret = wolfSSH_SFTP_STAT(ssh, n, &state->atr)) != WS_SUCCESS) { if ((ret = wolfSSH_SFTP_STAT(ssh, n, &state->atr)) != WS_SUCCESS) {
if (ssh->error != WS_WANT_READ if (!NoticeError(ssh)) {
&& ssh->error != WS_WANT_WRITE) {
break; break;
} }
return ret; return ret;
@ -6990,14 +6989,12 @@ static int SFTP_STAT(WOLFSSH* ssh, char* dir, WS_SFTP_FILEATRB* atr, byte type)
WLOG(WS_LOG_SFTP, "SFTP LSTAT STATE: SEND_TYPE_REQ"); WLOG(WS_LOG_SFTP, "SFTP LSTAT STATE: SEND_TYPE_REQ");
ret = SendPacketType(ssh, type, (byte*)dir, state->dirSz); ret = SendPacketType(ssh, type, (byte*)dir, state->dirSz);
if (ret != WS_SUCCESS) { if (ret != WS_SUCCESS) {
if (ssh->error == WS_WANT_READ || if (NoticeError(ssh)) {
ssh->error == WS_WANT_WRITE)
return WS_FATAL_ERROR; return WS_FATAL_ERROR;
else {
ret_fatal = 1;
state->state = STATE_LSTAT_CLEANUP;
continue;
} }
ret_fatal = 1;
state->state = STATE_LSTAT_CLEANUP;
continue;
} }
state->state = STATE_LSTAT_GET_HEADER; state->state = STATE_LSTAT_GET_HEADER;
FALL_THROUGH; FALL_THROUGH;
@ -7008,14 +7005,12 @@ static int SFTP_STAT(WOLFSSH* ssh, char* dir, WS_SFTP_FILEATRB* atr, byte type)
ret = SFTP_GetHeader(ssh, &state->reqId, &state->type, ret = SFTP_GetHeader(ssh, &state->reqId, &state->type,
&state->buffer); &state->buffer);
if (ret <= 0) { if (ret <= 0) {
if (ssh->error == WS_WANT_READ || if (NoticeError(ssh)) {
ssh->error == WS_WANT_WRITE)
return WS_FATAL_ERROR; return WS_FATAL_ERROR;
else {
state->state = STATE_LSTAT_CLEANUP;
ret_fatal = 1;
continue;
} }
state->state = STATE_LSTAT_CLEANUP;
ret_fatal = 1;
continue;
} }
state->state = STATE_LSTAT_CHECK_REQ_ID; state->state = STATE_LSTAT_CHECK_REQ_ID;
@ -7042,7 +7037,7 @@ static int SFTP_STAT(WOLFSSH* ssh, char* dir, WS_SFTP_FILEATRB* atr, byte type)
ret = wolfSSH_SFTP_buffer_read(ssh, &state->buffer, ret = wolfSSH_SFTP_buffer_read(ssh, &state->buffer,
wolfSSH_SFTP_buffer_size(&state->buffer)); wolfSSH_SFTP_buffer_size(&state->buffer));
if (ret < 0) { if (ret < 0) {
if (ssh->error != WS_WANT_READ) { if (!NoticeError(ssh)) {
wolfSSH_SFTP_ClearState(ssh, STATE_ID_LSTAT); wolfSSH_SFTP_ClearState(ssh, STATE_ID_LSTAT);
} }
return WS_FATAL_ERROR; return WS_FATAL_ERROR;
@ -7211,8 +7206,7 @@ int wolfSSH_SFTP_SetSTAT(WOLFSSH* ssh, char* dir, WS_SFTP_FILEATRB* atr)
/* send header and type specific data */ /* send header and type specific data */
case STATE_SET_ATR_SEND: case STATE_SET_ATR_SEND:
if (wolfSSH_SFTP_buffer_send(ssh, &state->buffer) < 0) { if (wolfSSH_SFTP_buffer_send(ssh, &state->buffer) < 0) {
if (ssh->error != WS_WANT_READ if (!NoticeError(ssh)) {
&& ssh->error != WS_WANT_WRITE) {
ret = WS_FATAL_ERROR; ret = WS_FATAL_ERROR;
break; break;
} }
@ -7229,8 +7223,7 @@ int wolfSSH_SFTP_SetSTAT(WOLFSSH* ssh, char* dir, WS_SFTP_FILEATRB* atr)
case STATE_SET_ATR_GET: case STATE_SET_ATR_GET:
maxSz = SFTP_GetHeader(ssh, &state->reqId, &type, &state->buffer); maxSz = SFTP_GetHeader(ssh, &state->reqId, &type, &state->buffer);
if (maxSz <= 0) { if (maxSz <= 0) {
if (ssh->error != WS_WANT_READ if (!NoticeError(ssh)) {
&& ssh->error != WS_WANT_WRITE) {
ret = WS_FATAL_ERROR; ret = WS_FATAL_ERROR;
break; break;
} }
@ -7257,8 +7250,7 @@ int wolfSSH_SFTP_SetSTAT(WOLFSSH* ssh, char* dir, WS_SFTP_FILEATRB* atr)
ret = wolfSSH_SFTP_buffer_read(ssh, &state->buffer, ret = wolfSSH_SFTP_buffer_read(ssh, &state->buffer,
wolfSSH_SFTP_buffer_size(&state->buffer)); wolfSSH_SFTP_buffer_size(&state->buffer));
if (ret < 0) { if (ret < 0) {
if (ssh->error != WS_WANT_READ if (!NoticeError(ssh)) {
&& ssh->error != WS_WANT_WRITE) {
ret = WS_FATAL_ERROR; ret = WS_FATAL_ERROR;
break; break;
} }
@ -7730,12 +7722,8 @@ int wolfSSH_SFTP_SendReadPacket(WOLFSSH* ssh, byte* handle, word32 handleSz,
if (NoticeError(ssh)) { if (NoticeError(ssh)) {
return WS_FATAL_ERROR; return WS_FATAL_ERROR;
} }
if (ssh->error != WS_WANT_READ && state->state = STATE_SEND_READ_CLEANUP;
ssh->error != WS_WANT_WRITE) { continue;
state->state = STATE_SEND_READ_CLEANUP;
continue;
}
return ret;
} }
wolfSSH_SFTP_buffer_free(ssh, &state->buffer); wolfSSH_SFTP_buffer_free(ssh, &state->buffer);
state->state = STATE_SEND_READ_GET_HEADER; state->state = STATE_SEND_READ_GET_HEADER;
@ -7746,11 +7734,11 @@ int wolfSSH_SFTP_SendReadPacket(WOLFSSH* ssh, byte* handle, word32 handleSz,
/* Get response */ /* Get response */
if ((ret = SFTP_GetHeader(ssh, &state->reqId, &state->type, if ((ret = SFTP_GetHeader(ssh, &state->reqId, &state->type,
&state->buffer)) <= 0) { &state->buffer)) <= 0) {
if (!NoticeError(ssh)) { if (NoticeError(ssh)) {
state->state = STATE_SEND_READ_CLEANUP; return WS_FATAL_ERROR;
continue;
} }
return WS_FATAL_ERROR; state->state = STATE_SEND_READ_CLEANUP;
continue;
} }
ret = wolfSSH_SFTP_buffer_create(ssh, &state->buffer, ret); ret = wolfSSH_SFTP_buffer_create(ssh, &state->buffer, ret);
if (ret != WS_SUCCESS) { if (ret != WS_SUCCESS) {
@ -7789,11 +7777,11 @@ int wolfSSH_SFTP_SendReadPacket(WOLFSSH* ssh, byte* handle, word32 handleSz,
/* get size of string and place it into out buffer */ /* get size of string and place it into out buffer */
ret = wolfSSH_stream_read(ssh, szFlat, UINT32_SZ); ret = wolfSSH_stream_read(ssh, szFlat, UINT32_SZ);
if (ret < 0) { if (ret < 0) {
if (!NoticeError(ssh)) { if (NoticeError(ssh)) {
state->state = STATE_SEND_READ_CLEANUP; return WS_FATAL_ERROR;
continue;
} }
return ret; state->state = STATE_SEND_READ_CLEANUP;
continue;
} }
ato32(szFlat, &sz); ato32(szFlat, &sz);
wolfSSH_SFTP_buffer_create(ssh, &state->buffer, sz); wolfSSH_SFTP_buffer_create(ssh, &state->buffer, sz);
@ -7814,8 +7802,7 @@ int wolfSSH_SFTP_SendReadPacket(WOLFSSH* ssh, byte* handle, word32 handleSz,
out + state->recvSz, out + state->recvSz,
wolfSSH_SFTP_buffer_size(&state->buffer)); wolfSSH_SFTP_buffer_size(&state->buffer));
if (ret < 0) { if (ret < 0) {
if (ssh->error == WS_WANT_READ || if (NoticeError(ssh)) {
ssh->error == WS_WANT_WRITE) {
return WS_FATAL_ERROR; return WS_FATAL_ERROR;
} }
WLOG(WS_LOG_SFTP, "Error reading remainder of data"); WLOG(WS_LOG_SFTP, "Error reading remainder of data");
@ -7852,12 +7839,11 @@ int wolfSSH_SFTP_SendReadPacket(WOLFSSH* ssh, byte* handle, word32 handleSz,
ret = wolfSSH_SFTP_buffer_read(ssh, &state->buffer, ret = wolfSSH_SFTP_buffer_read(ssh, &state->buffer,
wolfSSH_SFTP_buffer_size(&state->buffer)); wolfSSH_SFTP_buffer_size(&state->buffer));
if (ret < 0) { if (ret < 0) {
if (ssh->error != WS_WANT_READ && if (NoticeError(ssh)) {
ssh->error != WS_WANT_WRITE) { return WS_FATAL_ERROR;
state->state = STATE_SEND_READ_CLEANUP;
continue;
} }
return WS_FATAL_ERROR; state->state = STATE_SEND_READ_CLEANUP;
continue;
} }
wolfSSH_SFTP_buffer_rewind(&state->buffer); wolfSSH_SFTP_buffer_rewind(&state->buffer);
ret = wolfSSH_SFTP_DoStatus(ssh, ret = wolfSSH_SFTP_DoStatus(ssh,
@ -8176,8 +8162,7 @@ int wolfSSH_SFTP_Close(WOLFSSH* ssh, byte* handle, word32 handleSz)
ret = wolfSSH_SFTP_buffer_read(ssh, &state->buffer, ret = wolfSSH_SFTP_buffer_read(ssh, &state->buffer,
wolfSSH_SFTP_buffer_size(&state->buffer)); wolfSSH_SFTP_buffer_size(&state->buffer));
if (ret < 0) { if (ret < 0) {
if (ssh->error != WS_WANT_WRITE && if (!NoticeError(ssh)) {
ssh->error != WS_WANT_READ) {
wolfSSH_SFTP_buffer_free(ssh, &state->buffer); wolfSSH_SFTP_buffer_free(ssh, &state->buffer);
} }
return WS_FATAL_ERROR; return WS_FATAL_ERROR;
@ -8523,8 +8508,7 @@ int wolfSSH_SFTP_Remove(WOLFSSH* ssh, char* f)
case STATE_RM_LSTAT: case STATE_RM_LSTAT:
/* check file is there to be removed */ /* check file is there to be removed */
if ((ret = wolfSSH_SFTP_LSTAT(ssh, f, &atrb)) != WS_SUCCESS) { if ((ret = wolfSSH_SFTP_LSTAT(ssh, f, &atrb)) != WS_SUCCESS) {
if (ssh->error != WS_WANT_WRITE if (!NoticeError(ssh)) {
&& ssh->error != WS_WANT_READ) {
WLOG(WS_LOG_SFTP, "Error verifying file"); WLOG(WS_LOG_SFTP, "Error verifying file");
wolfSSH_SFTP_ClearState(ssh, STATE_ID_RM); wolfSSH_SFTP_ClearState(ssh, STATE_ID_RM);
} }
@ -8537,8 +8521,7 @@ int wolfSSH_SFTP_Remove(WOLFSSH* ssh, char* f)
ret = SendPacketType(ssh, WOLFSSH_FTP_REMOVE, (byte*)f, ret = SendPacketType(ssh, WOLFSSH_FTP_REMOVE, (byte*)f,
(word32)WSTRLEN(f)); (word32)WSTRLEN(f));
if (ret != WS_SUCCESS) { if (ret != WS_SUCCESS) {
if (ssh->error != WS_WANT_WRITE if (!NoticeError(ssh)) {
&& ssh->error != WS_WANT_READ) {
wolfSSH_SFTP_ClearState(ssh, STATE_ID_RM); wolfSSH_SFTP_ClearState(ssh, STATE_ID_RM);
} }
return ret; return ret;
@ -8549,8 +8532,7 @@ int wolfSSH_SFTP_Remove(WOLFSSH* ssh, char* f)
case STATE_RM_GET: case STATE_RM_GET:
ret = SFTP_GetHeader(ssh, &state->reqId, &type, &state->buffer); ret = SFTP_GetHeader(ssh, &state->reqId, &type, &state->buffer);
if (ret <= 0 || type != WOLFSSH_FTP_STATUS) { if (ret <= 0 || type != WOLFSSH_FTP_STATUS) {
if (ssh->error != WS_WANT_WRITE if (!NoticeError(ssh)) {
&& ssh->error != WS_WANT_READ) {
WLOG(WS_LOG_SFTP, "Unexpected packet type"); WLOG(WS_LOG_SFTP, "Unexpected packet type");
wolfSSH_SFTP_ClearState(ssh, STATE_ID_RM); wolfSSH_SFTP_ClearState(ssh, STATE_ID_RM);
} }
@ -8568,8 +8550,7 @@ int wolfSSH_SFTP_Remove(WOLFSSH* ssh, char* f)
ret = wolfSSH_SFTP_buffer_read(ssh, &state->buffer, ret = wolfSSH_SFTP_buffer_read(ssh, &state->buffer,
wolfSSH_SFTP_buffer_size(&state->buffer)); wolfSSH_SFTP_buffer_size(&state->buffer));
if (ret < 0) { if (ret < 0) {
if (ssh->error != WS_WANT_WRITE if (!NoticeError(ssh)) {
&& ssh->error != WS_WANT_READ) {
WLOG(WS_LOG_SFTP, "Unexpected packet type"); WLOG(WS_LOG_SFTP, "Unexpected packet type");
wolfSSH_SFTP_ClearState(ssh, STATE_ID_RM); wolfSSH_SFTP_ClearState(ssh, STATE_ID_RM);
} }
@ -8630,8 +8611,7 @@ int wolfSSH_SFTP_RMDIR(WOLFSSH* ssh, char* dir)
ret = SendPacketType(ssh, WOLFSSH_FTP_RMDIR, (byte*)dir, ret = SendPacketType(ssh, WOLFSSH_FTP_RMDIR, (byte*)dir,
(word32)WSTRLEN(dir)); (word32)WSTRLEN(dir));
if (ret != WS_SUCCESS) { if (ret != WS_SUCCESS) {
if (ssh->error != WS_WANT_READ if (!NoticeError(ssh)) {
&& ssh->error != WS_WANT_WRITE) {
wolfSSH_SFTP_ClearState(ssh, STATE_ID_RMDIR); wolfSSH_SFTP_ClearState(ssh, STATE_ID_RMDIR);
} }
return ret; return ret;
@ -8642,7 +8622,7 @@ int wolfSSH_SFTP_RMDIR(WOLFSSH* ssh, char* dir)
case STATE_RMDIR_GET: case STATE_RMDIR_GET:
ret = SFTP_GetHeader(ssh, &state->reqId, &type, &state->buffer); ret = SFTP_GetHeader(ssh, &state->reqId, &type, &state->buffer);
if (ret <= 0 || type != WOLFSSH_FTP_STATUS) { if (ret <= 0 || type != WOLFSSH_FTP_STATUS) {
if (ssh->error != WS_WANT_READ) { if (!NoticeError(ssh)) {
wolfSSH_SFTP_ClearState(ssh, STATE_ID_RMDIR); wolfSSH_SFTP_ClearState(ssh, STATE_ID_RMDIR);
WLOG(WS_LOG_SFTP, "Unexpected packet type"); WLOG(WS_LOG_SFTP, "Unexpected packet type");
} }
@ -8659,7 +8639,7 @@ int wolfSSH_SFTP_RMDIR(WOLFSSH* ssh, char* dir)
ret = wolfSSH_SFTP_buffer_read(ssh, &state->buffer, ret = wolfSSH_SFTP_buffer_read(ssh, &state->buffer,
wolfSSH_SFTP_buffer_size(&state->buffer)); wolfSSH_SFTP_buffer_size(&state->buffer));
if (ret < 0) { if (ret < 0) {
if (ssh->error != WS_WANT_READ) if (!NoticeError(ssh))
wolfSSH_SFTP_ClearState(ssh, STATE_ID_RMDIR); wolfSSH_SFTP_ClearState(ssh, STATE_ID_RMDIR);
return WS_FATAL_ERROR; return WS_FATAL_ERROR;
} }
@ -8867,9 +8847,9 @@ int wolfSSH_SFTP_Get(WOLFSSH* ssh, char* from,
WLOG(WS_LOG_SFTP, "SFTP GET STATE: STAT"); WLOG(WS_LOG_SFTP, "SFTP GET STATE: STAT");
ret = wolfSSH_SFTP_STAT(ssh, from, &state->attrib); ret = wolfSSH_SFTP_STAT(ssh, from, &state->attrib);
if (ret != WS_SUCCESS) { if (ret != WS_SUCCESS) {
if (ssh->error == WS_WANT_READ || if (NoticeError(ssh)) {
ssh->error == WS_WANT_WRITE)
return WS_FATAL_ERROR; return WS_FATAL_ERROR;
}
WLOG(WS_LOG_SFTP, "Error verifying file"); WLOG(WS_LOG_SFTP, "Error verifying file");
state->state = STATE_GET_CLEANUP; state->state = STATE_GET_CLEANUP;
continue; continue;
@ -8894,8 +8874,7 @@ int wolfSSH_SFTP_Get(WOLFSSH* ssh, char* from,
ret = wolfSSH_SFTP_Open(ssh, from, WOLFSSH_FXF_READ, NULL, ret = wolfSSH_SFTP_Open(ssh, from, WOLFSSH_FXF_READ, NULL,
state->handle, &state->handleSz); state->handle, &state->handleSz);
if (ret != WS_SUCCESS) { if (ret != WS_SUCCESS) {
if (ssh->error == WS_WANT_READ || if (NoticeError(ssh)) {
ssh->error == WS_WANT_WRITE) {
return WS_FATAL_ERROR; return WS_FATAL_ERROR;
} }
WLOG(WS_LOG_SFTP, "Error getting handle"); WLOG(WS_LOG_SFTP, "Error getting handle");