Skip to content

fix(sftp): handle Bitvise strict SFTP compliance for directory navigation - #50

Merged
Orinks merged 16 commits into
devfrom
fix/sftp-bitvise-compliance
Mar 2, 2026
Merged

fix(sftp): handle Bitvise strict SFTP compliance for directory navigation#50
Orinks merged 16 commits into
devfrom
fix/sftp-bitvise-compliance

Conversation

@Orinks

@Orinks Orinks commented Mar 2, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes #46 — cannot enter .ssh directory on Bitvise SSH Server after asyncssh migration.

Root cause: Bitvise negotiates SFTP v4+ where file type (directory, regular, symlink) is communicated via a separate attrs.type field rather than being embedded in Unix permission bits (attrs.permissions). The existing code only checked stat.S_ISDIR(attrs.permissions), which returns False when the type bits are absent — causing directories like .ssh to appear as regular files and making navigation silently fail (click tries download instead of chdir).

Changes:

  • list_dir: check attrs.type (SFTP v4+ file type constant) as fallback when permissions lack file type bits, for both directory and symlink detection
  • chdir: validate the target is actually a directory via stat() after realpath(), instead of blindly trusting the canonicalised path. Surfaces NotADirectoryError and PermissionError to the UI
  • stat: use attrs.type fallback for is_dir detection

Test plan

  • New TestSFTPBitviseCompliance class with 8 tests covering:
    • list_dir detects directories via type field when permissions are None
    • list_dir detects directories via type field when permissions lack S_IFDIR bits
    • Regular files with type=REGULAR stay as files (no false positives)
    • Symlinks resolved via type field fallback
    • chdir accepts directories identified via type field
    • chdir accepts directories identified via permissions (backward compat)
    • chdir surfaces PermissionError from stat
    • stat() detects directories via type field
  • chdir rejects non-directories with NotADirectoryError
  • chdir validates via stat() call
  • All 362 existing tests still pass
  • Ruff lint + format clean

🤖 Generated with Claude Code

Orinks and others added 16 commits March 2, 2026 16:44
…tion

Bitvise SSH Server negotiates SFTP v4+ where file type is communicated
via a separate `type` field rather than embedded in the Unix permission
bits. The existing code only checked `attrs.permissions` with
`stat.S_ISDIR()`, which returns False when the file type bits are
absent — causing directories like .ssh to appear as regular files and
making navigation silently fail.

Changes:
- list_dir: check attrs.type (SFTP v4+ type field) as fallback when
  permissions lack file type bits, for both directories and symlinks
- chdir: validate target is a directory via stat() after realpath()
  instead of blindly trusting the canonicalised path
- stat: use attrs.type fallback for is_dir detection

Closes #46

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Orinks
Orinks merged commit 1d68e85 into dev Mar 2, 2026
6 checks passed
@Orinks
Orinks deleted the fix/sftp-bitvise-compliance branch March 2, 2026 21:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant