Skip to content

Commit 0ab5c69

Browse files
add rekey check to sftp client and use reletave path to file in test case
1 parent 462d77b commit 0ab5c69

File tree

2 files changed

+57
-38
lines changed

2 files changed

+57
-38
lines changed

.github/workflows/windows-sftp.yml

Lines changed: 49 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,13 @@ jobs:
8383
cp ${{env.USER_SETTINGS_H_NEW}} ${{env.USER_SETTINGS_H}}
8484
# For large_rw test: add SFTP large file defines
8585
if [ "${{ matrix.test_type }}" = "large_rw" ]; then
86-
echo "" >> ${{env.USER_SETTINGS_H}}
87-
echo "/* SFTP large file test defines */" >> ${{env.USER_SETTINGS_H}}
88-
echo "#define WOLFSSH_NO_SFTP_TIMEOUT" >> ${{env.USER_SETTINGS_H}}
89-
echo "#define WOLFSSH_MAX_SFTP_RW 10485760" >> ${{env.USER_SETTINGS_H}}
90-
echo "#define WOLFSSH_MAX_CHN_NAMESZ 4200" >> ${{env.USER_SETTINGS_H}}
86+
echo "" >> ${{env.USER_SETTINGS_H_NEW}}
87+
echo "/* SFTP large file test defines */" >> ${{env.USER_SETTINGS_H_NEW}}
88+
echo "#define WOLFSSH_NO_SFTP_TIMEOUT" >> ${{env.USER_SETTINGS_H_NEW}}
89+
echo "#define WOLFSSH_MAX_SFTP_RW 10485760" >> ${{env.USER_SETTINGS_H_NEW}}
90+
echo "#define WOLFSSH_MAX_CHN_NAMESZ 4200" >> ${{env.USER_SETTINGS_H_NEW}}
9191
echo "Added WOLFSSH_NO_SFTP_TIMEOUT, WOLFSSH_MAX_SFTP_RW=10485760, WOLFSSH_MAX_CHN_NAMESZ=4200"
92+
cp ${{env.USER_SETTINGS_H_NEW}} ${{env.USER_SETTINGS_H}}
9293
fi
9394
9495
- name: Restore NuGet packages
@@ -162,6 +163,13 @@ jobs:
162163
"" | Out-File -FilePath $authKeysFile -Encoding ASCII -NoNewline
163164
icacls $authKeysFile /grant "testuser:R" /q
164165
166+
# Grant testuser full control of their home directory.
167+
# New-Item creates the directory owned by the runner account; Windows
168+
# only sets correct user ACLs during the normal profile-creation flow.
169+
# Without this, ImpersonateLoggedOnUser succeeds but CreateFile fails
170+
# with ACCESS_DENIED when wolfsshd tries to write files as testuser.
171+
icacls $homeDir /grant "testuser:(OI)(CI)F" /T /q
172+
165173
$sid = (New-Object System.Security.Principal.NTAccount("testuser")).Translate([System.Security.Principal.SecurityIdentifier]).Value
166174
$profKey = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$sid"
167175
if (-not (Test-Path $profKey)) { New-Item -Path $profKey -Force | Out-Null }
@@ -318,16 +326,16 @@ jobs:
318326
}
319327
Write-Host "Basic SFTP test passed"
320328
321-
- name: Create 3GB test file and run SFTP get/put (large_rw)
329+
- name: Create 3GB test file and run SFTP get/put
322330
if: matrix.test_type == 'large_rw'
323331
working-directory: ${{ github.workspace }}\wolfssh
324332
shell: pwsh
325333
timeout-minutes: 25
326334
run: |
327335
$sftpPath = $env:SFTP_PATH
328-
$workDir = (Get-Location).Path
336+
$workDir = Join-Path $env:GITHUB_WORKSPACE "wolfssh"
329337
$largeFile = Join-Path $workDir "large_test.dat"
330-
$getDest = Join-Path $workDir "large_test_copy.dat"
338+
$getDestPath = Join-Path $workDir "large_test_copy.dat"
331339
332340
# Create 3GB file: one random 10MB chunk repeated 307x + 2MB
333341
Write-Host "Creating 3GB test file..."
@@ -346,57 +354,68 @@ jobs:
346354
$fs.Close()
347355
348356
$hash = Get-FileHash -Path $largeFile -Algorithm SHA256
349-
$hash.Hash | Out-File -FilePath large_test.dat.sha256
357+
$hash.Hash | Out-File -FilePath (Join-Path $workDir "large_test.dat.sha256")
350358
Write-Host "Created 3GB file, SHA256: $($hash.Hash)"
351359
352360
# SFTP PUT (upload)
361+
# Use a relative remote path (no leading /) so the server resolves it
362+
# under testuser's home directory. An absolute /large_test.dat maps to
363+
# the drive root (C:\) where testuser has no write permission; relative
364+
# large_test.dat is prefixed by workingDir (C:\Users\testuser) on the
365+
# client and becomes C:\Users\testuser\large_test.dat on the server.
353366
Write-Host "SFTP PUT 3GB file..."
354-
$putCommands = "put $largeFile /large_test.dat`nquit"
355-
$putCommands | Out-File -FilePath sftp_put_commands.txt -Encoding ASCII
367+
$putCommands = "put $largeFile large_test.dat`nquit"
368+
$putCommands | Out-File -FilePath (Join-Path $workDir "sftp_put_commands.txt") -Encoding ASCII
356369
$proc = Start-Process -FilePath $sftpPath `
357370
-ArgumentList "-u", "testuser", "-P", $env:TESTUSER_PASSWORD, "-h", "localhost", "-p", "${{env.TEST_PORT}}" `
358-
-RedirectStandardInput "sftp_put_commands.txt" `
359-
-RedirectStandardOutput "sftp_put_out.txt" `
360-
-RedirectStandardError "sftp_put_err.txt" `
371+
-WorkingDirectory $workDir `
372+
-RedirectStandardInput (Join-Path $workDir "sftp_put_commands.txt") `
373+
-RedirectStandardOutput (Join-Path $workDir "sftp_put_out.txt") `
374+
-RedirectStandardError (Join-Path $workDir "sftp_put_err.txt") `
361375
-Wait -NoNewWindow -PassThru
362376
363-
if ($proc.ExitCode -ne 0) {
364-
Get-Content sftp_put_out.txt
365-
Get-Content sftp_put_err.txt
377+
$putOut = Get-Content (Join-Path $workDir "sftp_put_out.txt") -Raw -ErrorAction SilentlyContinue
378+
Write-Host "=== SFTP PUT output ==="; Write-Host $putOut
379+
if ($proc.ExitCode -ne 0 -or $putOut -match "Error pushing file") {
380+
Get-Content (Join-Path $workDir "sftp_put_err.txt") -ErrorAction SilentlyContinue
366381
Write-Host "ERROR: SFTP PUT failed"
367382
exit 1
368383
}
369384
Write-Host "PUT succeeded"
370385
371-
# SFTP GET (download)
386+
# SFTP GET (download) - relative remote and local paths.
387+
# Remote large_test.dat resolves to C:\Users\testuser\large_test.dat.
388+
# Local large_test_copy.dat is relative to wolfsftp's CWD ($workDir).
372389
Write-Host "SFTP GET 3GB file..."
373-
$getCommands = "get /large_test.dat $getDest`nquit"
374-
$getCommands | Out-File -FilePath sftp_get_commands.txt -Encoding ASCII
390+
$getCommands = "get large_test.dat large_test_copy.dat`nquit"
391+
$getCommands | Out-File -FilePath (Join-Path $workDir "sftp_get_commands.txt") -Encoding ASCII
375392
$proc2 = Start-Process -FilePath $sftpPath `
376393
-ArgumentList "-u", "testuser", "-P", $env:TESTUSER_PASSWORD, "-h", "localhost", "-p", "${{env.TEST_PORT}}" `
377-
-RedirectStandardInput "sftp_get_commands.txt" `
378-
-RedirectStandardOutput "sftp_get_out.txt" `
379-
-RedirectStandardError "sftp_get_err.txt" `
394+
-WorkingDirectory $workDir `
395+
-RedirectStandardInput (Join-Path $workDir "sftp_get_commands.txt") `
396+
-RedirectStandardOutput (Join-Path $workDir "sftp_get_out.txt") `
397+
-RedirectStandardError (Join-Path $workDir "sftp_get_err.txt") `
380398
-Wait -NoNewWindow -PassThru
381399
382-
if ($proc2.ExitCode -ne 0) {
383-
Get-Content sftp_get_out.txt
384-
Get-Content sftp_get_err.txt
400+
$getOut = Get-Content (Join-Path $workDir "sftp_get_out.txt") -Raw -ErrorAction SilentlyContinue
401+
Write-Host "=== SFTP GET output ==="; Write-Host $getOut
402+
if ($proc2.ExitCode -ne 0 -or $getOut -match "Error getting file") {
403+
Get-Content (Join-Path $workDir "sftp_get_err.txt") -ErrorAction SilentlyContinue
385404
Write-Host "ERROR: SFTP GET failed"
386405
exit 1
387406
}
388407
Write-Host "GET succeeded"
389408
390-
# Verify integrity
391-
$expectedHash = (Get-Content large_test.dat.sha256).Trim()
392-
$actualHash = (Get-FileHash -Path $getDest -Algorithm SHA256).Hash
409+
# Verify integrity (file is in $workDir from GET with relative path)
410+
$expectedHash = (Get-Content (Join-Path $workDir "large_test.dat.sha256")).Trim()
411+
$actualHash = (Get-FileHash -Path $getDestPath -Algorithm SHA256).Hash
393412
if ($expectedHash -ne $actualHash) {
394413
Write-Host "ERROR: SHA256 mismatch - PUT/GET corruption"
395414
Write-Host "Expected: $expectedHash"
396415
Write-Host "Actual: $actualHash"
397416
exit 1
398417
}
399-
Write-Host "PASS: 3GB SFTP get/put with WOLFSSH_MAX_SFTP_RW=10485760 succeeded"
418+
Write-Host "PASS: 3GB SFTP get/put succeeded"
400419
401420
- name: Cleanup
402421
if: always()

examples/sftpclient/sftpclient.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -769,8 +769,8 @@ static int doCmds(func_args* args)
769769

770770
ret = wolfSSH_SFTP_STAT(ssh, pt, &atrb);
771771
err = wolfSSH_get_error(ssh);
772-
} while ((err == WS_WANT_READ || err == WS_WANT_WRITE)
773-
&& ret != WS_SUCCESS);
772+
} while ((err == WS_WANT_READ || err == WS_WANT_WRITE ||
773+
err == WS_REKEYING) && ret != WS_SUCCESS);
774774
if (ret != WS_SUCCESS) {
775775
if (SFTP_FPUTS(args, "Error changing directory\n") < 0) {
776776
err_msg("fputs error");
@@ -857,8 +857,8 @@ static int doCmds(func_args* args)
857857

858858
ret = wolfSSH_SFTP_CHMOD(ssh, pt, mode);
859859
err = wolfSSH_get_error(ssh);
860-
} while ((err == WS_WANT_READ || err == WS_WANT_WRITE)
861-
&& ret != WS_SUCCESS);
860+
} while ((err == WS_WANT_READ || err == WS_WANT_WRITE ||
861+
err == WS_REKEYING) && ret != WS_SUCCESS);
862862
if (ret != WS_SUCCESS) {
863863
if (SFTP_FPUTS(args, "Unable to change permissions of ") < 0) {
864864
err_msg("fputs error");
@@ -914,8 +914,8 @@ static int doCmds(func_args* args)
914914

915915
ret = wolfSSH_SFTP_RMDIR(ssh, pt);
916916
err = wolfSSH_get_error(ssh);
917-
} while ((err == WS_WANT_READ || err == WS_WANT_WRITE)
918-
&& ret != WS_SUCCESS);
917+
} while ((err == WS_WANT_READ || err == WS_WANT_WRITE ||
918+
err == WS_REKEYING) && ret != WS_SUCCESS);
919919
if (ret != WS_SUCCESS) {
920920
if (ret == WS_PERMISSIONS) {
921921
if (SFTP_FPUTS(args, "Insufficient permissions\n") < 0) {
@@ -967,8 +967,8 @@ static int doCmds(func_args* args)
967967

968968
ret = wolfSSH_SFTP_Remove(ssh, pt);
969969
err = wolfSSH_get_error(ssh);
970-
} while ((err == WS_WANT_READ || err == WS_WANT_WRITE)
971-
&& ret != WS_SUCCESS);
970+
} while ((err == WS_WANT_READ || err == WS_WANT_WRITE ||
971+
err == WS_REKEYING) && ret != WS_SUCCESS);
972972
if (ret != WS_SUCCESS) {
973973
if (ret == WS_PERMISSIONS) {
974974
if (SFTP_FPUTS(args, "Insufficient permissions\n") < 0) {

0 commit comments

Comments
 (0)