Open-Source Wikis

/

curl

/

Features

/

SSH (SCP and SFTP)

curl/curl

SSH (SCP and SFTP)

Active contributors: Daniel Stenberg, Viktor Szakats, Jan Venekamp

Purpose

curl can upload, download, list, and execute commands over SSH using SCP or SFTP. Three SSH backends are interchangeable: libssh2 (default), libssh, and wolfSSH. The abstraction is lib/vssh/ and follows the same vtable pattern as vtls/vauth.

Source layout

lib/vssh/
├── vssh.[ch]      # The dispatcher: picks a backend at compile time
├── ssh.h          # Internal SSH-state struct definitions
├── libssh2.c      # libssh2 backend (default, ~126 KB)
├── libssh.c       # libssh backend (~93 KB)
└── (wolfSSH lives behind CURL_USE_WOLFSSH inside libssh2.c-style code)

Each .c file exports const struct Curl_protocol Curl_protocol_scp and Curl_protocol_sftp — i.e. the SSH backend is the protocol handler for scp:// and sftp://. There is no separate lib/scp.c or lib/sftp.c.

Capabilities

Capability SCP SFTP
Download file yes yes
Upload file yes yes
List directory no yes
Custom commands before/after transfer (--quote, --post-quote, --pre-quote) no yes
Resume no yes
Public-key authentication yes yes
Password authentication yes yes
Known-hosts checking yes yes
Public-key fingerprint pinning yes yes
ssh-agent yes yes

Key abstractions

Symbol File Description
struct ssh_conn lib/vssh/ssh.h Per-connection SSH state
Curl_protocol_scp/_sftp lib/vssh/libssh*.c Handler registration
Curl_ssh_init/Curl_ssh_cleanup lib/vssh/vssh.c Process-level init/cleanup for the chosen backend
Curl_ssh_version lib/vssh/vssh.c Version string folded into curl_version_info()
Backend-specific myssh_* functions lib/vssh/libssh*.c Connect, channel exchange, file ops

How it works

sequenceDiagram
    participant Easy
    participant Multi as multi.c
    participant H as Curl_protocol_sftp
    participant SSH as libssh2
    Easy->>Multi: setopt URL=sftp://host/path
    Multi->>H: connecting()
    H->>SSH: handshake
    SSH-->>H: session ready
    Multi->>H: do_it()
    H->>SSH: open SFTP channel
    H->>SSH: open file
    Multi->>H: PERFORMING (read/write loop)
    H->>SSH: read/write blocks
    Multi->>H: done()
    H->>SSH: close channel + session

The connecting callback drives the host-key check, authentication, and channel setup. Each step yields back to the multi loop with CURLE_AGAIN when the underlying SSH library reports WANT_READ/WANT_WRITE. The protocol handler's proto_pollset reports the right FDs.

Host-key verification

curl supports ~/.ssh/known_hosts parsing (CURLOPT_SSH_KNOWNHOSTS, --known-hosts) and per-connection fingerprint pinning (CURLOPT_SSH_HOST_PUBLIC_KEY_MD5, CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256, --hostpubmd5, --hostpubsha256). The check happens during connecting; mismatch aborts the connection with CURLE_PEER_FAILED_VERIFICATION.

Authentication selection

By default curl tries (in order):

  1. ~/.ssh/id_* public-key files (or the explicit CURLOPT_SSH_PRIVATE_KEYFILE / --key)
  2. ssh-agent
  3. password / keyboard-interactive

The bitmask CURLOPT_SSH_AUTH_TYPES lets users restrict the set.

Backend selection

Selection is at build time via configure --with-libssh2 / --with-libssh / --with-wolfssh (or the equivalent CMake variables). Only one backend is compiled in per build; the dispatcher in lib/vssh/vssh.c is mostly a thin wrapper that forwards to the chosen one.

Integration points

  • Transfer engine: SSH protocols use the standard state machine. The connecting and doing states do most of the work.
  • Connection filters: SSH does not layer over the cfilter chain the way TLS does — libssh2/libssh own the byte stream. The chain stops at cf-socket.
  • Authentication: SSH credential handling does not use lib/vauth/; it is done inside the SSH backend.

Entry points for modification

  • Adding a feature only one backend supports → guarded inside that backend's .c file. Reflect the gap in docs/cmdline-opts/ if user-visible.
  • Switching default backend → configure.ac and CMakeLists.txt precedence; runtime probe in lib/vssh/vssh.c.
  • Improving known-hosts handling → look in libssh2.c::ssh_check_hostkey (or its libssh equivalent).

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.