Secure FTP Plugin for Total Commander

SFTP Plugin Demo

**Modern C++20 SFTP/SCP Implementation with Advanced Authentication and Transfer Capabilities** *Complete rewrite from C to C++ with native PPK decoding, shell-transfer fallback for restricted hosts, and comprehensive security features.* **Based on the original SFTP plugin by Christian Ghisler**

πŸ“š Table of Contents


Feature Overview

This plugin is a complete C++20 rewrite of the original SFTP plugin by Christian Ghisler (creator of Total Commander). The original C implementation served as the foundation, but has been completely re-engineered with modern C++ patterns, enhanced security features, and extended functionality.

This plugin targets Total Commander on Windows x64 and provides comprehensive secure file transfer capabilities:

Core Transfer Protocols

  • SFTP (primary) with resume support and streaming transfers
  • SCP (native) with >2GB file detection for 64-bit servers
  • Shell Transfer Fallback (DD/base64) for restricted hosts blocking SFTP/SCP

Authentication Methods

  • Password authentication with Keyboard-Interactive support
  • Public key authentication (PEM/OpenSSH format)
  • Native PPK v2/v3 decoding without external tools
  • Pageant (SSH Agent) integration with auto-launch

Advanced Features

  • Session import from PuTTY and WinSCP registry
  • Comprehensive proxy support (HTTP CONNECT, SOCKS4/4a/5)
  • Remote checksum calculation (MD5, SHA1, SHA256, SHA512)
  • Automatic UTF-8 and line ending detection
  • Host key fingerprint verification

Design Priorities

  1. Practical interoperability on heterogeneous SSH servers
  2. Deterministic failure behavior (timeouts, cleanup, no hidden loops)
  3. Modern C++ architecture with RAII and interface abstraction
  4. Zero external dependencies beyond statically-linked libssh2

Architecture

Layered Structure

flowchart TD A[Total Commander WFX API] --> B[Plugin Entry Points] B --> C[SftpConnection / Auth] B --> D[SftpTransfer / RemoteOps / Shell] C --> E[ISshBackend Abstraction] D --> E E --> F[Libssh2Backend Implementation] B --> G[IUserFeedback Interface] G --> H[WindowsUserFeedback]
WFX API Layer
  ↓
Plugin Entry Points (FsFindFirst/FsGetFile/FsPutFile/FsExecuteFile/...)
  ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Business Logic Layer                   β”‚
β”‚  β”œβ”€ Connection/Auth                     β”‚
β”‚  β”œβ”€ Transfer/RemoteOps                  β”‚
β”‚  └─ UI Separation (IUserFeedback)       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  ↓
ISshBackend Interface (ISshSession/ISshChannel/ISftpHandle)
  ↓
Libssh2Backend Implementation (libssh2)

Why This Architecture Matters

Backend Abstraction via ISshBackend
Polymorphic interfaces (ISshSession, ISshChannel, ISftpHandle) decouple the plug-in from direct libssh2 calls. This enables:

  • Future backend migration without rewriting business logic
  • Potential multi-backend support (libssh2, libssh, etc.)
  • Easier unit testing via mock implementations

RAII Memory Management
Extensive use of std::unique_ptr for session/channel objects and handle_util::AutoHandle<HANDLE> for Windows file handles eliminates memory leaks common in older Total Commander plugins.

UI Separation via IUserFeedback
The IUserFeedback pattern (implemented by WindowsUserFeedback) separates transfer/connection logic from MessageBox dialogs, improving background thread stability in Total Commander's multi-threaded environment.


Connection Lifecycle

flowchart LR R[Resolve host/port] --> S[Socket connect] S --> P{Proxy enabled?} P -->|Yes| PN[Proxy negotiation] P -->|No| I[SSH session init] PN --> I I --> F[Host fingerprint verification] F --> A[Auth sequence] A --> M{SFTP or SCP-only profile} M -->|SFTP| SI[SFTP subsystem init] M -->|SCP| SH[Shell/SCP path init] SI --> O[Operations] SH --> O

Operational Requirements:

  • No unbounded EAGAIN loops
  • Readiness checks in all network loops
  • Stage timeout per critical phase (connect/auth/read)
  • Cleanup on every failing exit path

File Transfer Capabilities

Standard SFTP & Native SCP

Feature Description
SFTP Protocol Full support for downloading/uploading via SFTP subsystem
SCP Protocol Native SCP for servers without SFTP
Transfer Resume Resume interrupted SFTP transfers
Encoding Detection Auto-detect UTF-8 and line endings (CRLF vs LF)
Permissions Remote chmod for file permissions
Timestamps touch command support via SCP console

Shell DD / Base64 Fallback (New!)

Advanced workaround for servers with blocked SFTP subsystem and unavailable scp command. Uses hidden interactive channel for transfers.

sequenceDiagram participant L as Local File participant P as Plugin participant C as SSH Shell Channel participant S as Server Shell L->>P: Read chunk P->>P: Base64 encode P->>C: Send command payload C->>S: printf '%s' | base64 -d >> target S-->>C: Status/output C-->>P: Parse result

Upload Path:

  1. Split local data into chunks
  2. Base64 encode each chunk
  3. Send via printf '%s' | base64 -d through shell channel
  4. Decode and append server-side

Download Path:

  1. Try fast path via cat
  2. Fallback to base64 -w 0 when needed
  3. Incremental decode (streaming, no full-file buffering)

Throughput Note: Base64 adds ~33% overhead. Native SFTP/SCP is faster. Shell fallback is compatibility-first, not speed-first.

SCP > 2GB File Support

Detection Method Implementation
64-bit Server Check file and which scp commands
Transfer Mode Automatic adjustment for large files
Fallback Shell transfer if SCP limit detected

Remote Checksum Support

Calculate file hashes directly on the server without local computation:

Algorithm Command
MD5 md5sum / md5 -q
SHA1 sha1sum / sha1 -q
SHA256 sha256sum / shasum -a 256
SHA512 sha512sum / shasum -a 512

Authentication System

Supported Methods

  • Password - Traditional password authentication
  • Keyboard-Interactive - With password change request handling
  • PEM (OpenSSH) - Traditional private key format
  • PPK v2/v3 - Native PuTTY format decoding (New!)
  • Pageant - SSH Agent integration

Native PPK v2 & v3 Decoder (New!)

Revolutionary native parsing of PuTTY Private Key files without external tools:

Component Implementation
Key Derivation Windows BCrypt + Argon2d/i/id
Dynamic Loading argon2.dll loaded on-demand
Encryption AES-256-CBC support
MAC Validation HMAC-SHA-256 verification
Output Format Traditional PEM for libssh2

Authentication Fallback Strategy

flowchart TD P0[Start Auth] --> P1{Pageant Enabled?} P1 -->|Yes| P2[Try Pageant] P1 -->|No| K1 P2 -->|Success| OK[Authenticated] P2 -->|Fail| K1[Try Public Key File] K1 -->|Success| OK K1 -->|Fail| K2{Keyboard-Interactive?} K2 -->|Yes| K3[Try Keyboard-Interactive] K2 -->|No| PW1 K3 -->|Success| OK K3 -->|Fail| PW1[Try Password] PW1 -->|Success| OK PW1 -->|Fail| ERR[Auth Failed]

Key-Path Validation (Fail-Fast)

Condition Behavior
Missing privkeyfile Immediate local error (no fallback stall)
Missing pubkeyfile (explicit) Immediate local error
Invalid PPK format Precise error with MAC/KDF details

This avoids minute-long UI freezes on impossible auth attempts.

Pageant Integration

  • Full integration with PuTTY Pageant
  • Auto-launch pageant.lnk when needed
  • Seamless fallback to file-based auth if agent unavailable

Security & Password Storage

Storage Modes

Mode Format Description
TC Master password=! Total Commander CryptProc API
DPAPI password=dpapi:... Windows DPAPI user-scoped
Plaintext password=plain:... Explicit marker (controlled fallback)
Legacy XOR (legacy) Read-only compatibility
graph LR A[Password Storage] --> B{TC Master Password?} B -->|Yes| C[CryptProc API] B -->|No| D[DPAPI] D --> E[CryptProtectData] C --> F[Encrypted INI] E --> F

Security Enhancements

Feature Implementation
Primary Encryption DPAPI (CryptProtectData)
TC Integration CryptProc API when available
Legacy Support XOR read-only (compatibility)
PPK v3 Keys Argon2 key derivation
Memory Handling Secure zeroing of sensitive buffers

Connection Management

Session Import (New!)

Import configurations from Windows Registry:

Source Registry Path
PuTTY HKCU\Software\SimonTatham\PuTTY\Sessions
WinSCP HKCU\Software\Martin Prikryl\WinSCP 2\Sessions

Import Features:

  • Non-conflicting conversion to plugin INI format
  • Preserves connectivity fields (host, port, user, keys)
  • No auto-connect side effects during import

Proxy Support

Type Authentication
HTTP CONNECT Basic auth
SOCKS4 None
SOCKS4a None
SOCKS5 None / Username-Password

Network Features

  • IPv4 / IPv6 dual-stack support
  • Custom port configuration
  • Host key verification with fingerprint storage
  • First-time connection warnings
  • Fingerprint changed alerts

Shell Engineering Highlights

Marker-Aware SCP Parsing

Real-world SSH servers differ in shell behavior. KVC handles edge cases:

Technique Purpose
__WFX_LIST_BEGIN__ Directory listing start marker
__WFX_LIST_END__ Directory listing end marker
echo $? Exit code detection
Defensive parsing Skip echoed commands/prompts

Restricted Shell Handling

Scenario Solution
Blocked SFTP Shell transfer fallback
No scp command cat / dd / base64
Noisy prompts Buffer filtering
Delayed output Staggered read timeouts

Module Map (for Maintainers)

Module Responsibility C++ Modernization Status
SftpConnection.cpp Connect lifecycle, auth orchestration RAII session management
SftpAuth.cpp Auth methods, PPK conversion Native PPK v2/v3 decoder
SftpTransfer.cpp Upload/download, fallback wiring Streaming buffers
SftpRemoteOps.cpp Listing, remote operations Marker-aware parsing
SftpShell.cpp Shell channel execution EAGAIN loop guards
SessionImport.cpp PuTTY/WinSCP import Registry β†’ INI conversion
PpkConverter.cpp PPK β†’ PEM conversion BCrypt + Argon2
Libssh2Backend.cpp SSH backend implementation ISshBackend interface
PluginEntryPoints.cpp TC WFX API entry points Legacy C interface
WindowsUserFeedback.cpp UI separation IUserFeedback pattern
CoreUtils.cpp Utility functions (BASE64, time, strings) Modern C++20
FtpDirectoryParser.cpp Directory listing parser Unicode helpers

System Requirements

Component Requirement
Operating System Windows 7 or later (10/11 recommended)
Total Commander Version 9.0 or later (x64)
Compiler Visual Studio 2026 (v145 toolset), C++20
Dependencies libssh2 (statically linked)
Optional argon2.dll (for PPK v3 with Argon2)
APIs Windows BCrypt, DPAPI

Packaging

Distribution package contents:

File Purpose
sftpplug.wfx64 x64 binary plugin
pluginst.inf Total Commander auto-install
No external DLLs libssh2 statically linked

Roadmap

Completed / Stable

  • Backend abstraction layer (ISshBackend)
  • Native PPK v2/v3 conversion with Argon2
  • Shell DD/base64 fallback transfer
  • Session import (WinSCP/PuTTY)
  • Remote checksum support (MD5/SHA1/SHA256/SHA512)
  • SCP >2GB file detection
  • DPAPI + TC password manager integration
  • x64 packaging flow

In Progress

  • Splitting oversized legacy functions
  • C-style buffer cleanup to safer C++ constructs
  • UI/business-logic decoupling (WFX constraints)

Deferred (Intentional)

  • Full rewrite of legacy parser modules
  • Multi-platform support (Linux/macOS)
  • Alternative backend (libssh)

**Secure FTP Plugin v1.0** *Modern C++20 Implementation for Secure File Transfer* 🌐 [kvc.pl](https://kvc.pl) | πŸ“§ [Contact](mailto:[email protected]) *Last updated: March 2026*