libsshpp¶
A modern C++17 wrapper around libssh, packaged with CMake and Conan 2.
Status
M0 through M3 implemented, plus most of the remaining design (with a few documented scope
trims). Library, error handling, Session, SessionOptions, authenticators, Key/PKI,
KnownHosts, HostKeyVerifier policies, Channel, Exec, Shell (incl. try_interact()
and console prompt helpers under LIBSSHPP_WITH_CONSOLE), the SFTP module
(sftp::Sftp/File/Directory, transfer helpers with path-traversal hardening, pipelined
File::ReadAhead/WriteBehind), SCP (scp::Reader/Writer + try_upload/try_download),
TCP/UNIX-socket port forwarding (open_direct, LocalForward, RemoteForward,
X11Forwarder, SocksProxy, Connector/BidirectionalPump), and both server styles -
message-pull (server::Bind/Session/Message) and event-driven callbacks
(SessionHandler/ChannelHandler, SimpleAuthHandler, CommandHandler,
SftpSubsystemHandler, server::TestServer) - are implemented and tested against a real
sshd (and, for the server module, against libsshpp's own client).
Relative to the full design, the following are not implemented: the forwarding module
still serves one connection at a time per forwarder with a poll-based pump
(BidirectionalPump included) rather than driving everything through ssh_connector via
Event; the callback-style server has no keyboard-interactive auth or
tcpip-forward/direct-tcpip channel handling (the libssh version this targets has no callback
slots for them - use the message style for those) and no Options::faults fault-injection in
TestServer; there is no pcap module. The Design documents remain the
normative reference — code that contradicts them is a bug in one or the other.
What it gives you¶
- RAII everywhere. Sessions, channels, SFTP handles and keys are move-only types with
correct destruction ordering. A
Channelcan never outlive thessh_sessionit belongs to. - One error model. libssh return codes,
ssh_get_error()text, and SFTPSSH_FX_*status codes all land instd::error_code-compatible categories. - Exceptions and error codes. Every fallible operation has a throwing form and a
try_-prefixed form returningResult<T>. Pick one; no API is exception-only. - Type-safe options. No
ssh_options_set(s, SSH_OPTIONS_PORT, &port)void*guessing. - Full feature coverage. Session/auth, channels/exec/PTY, SFTP, SCP, port forwarding, X11, known-hosts, PKI, and the server side.
- Safe by default. Host-key verification is a required explicit step, shell quoting is provided, SFTP tree transfers reject path traversal, and forwarders bind to loopback.
Ten-line example¶
#include <sshpp/sshpp.hpp>
int main() {
sshpp::Library lib;
sshpp::SessionOptions opts;
opts.host = "example.com";
opts.user = "deploy";
opts.timeout = std::chrono::seconds{10};
sshpp::Session ssh{opts};
ssh.connect();
ssh.verify_host_key(sshpp::StrictHostKeyPolicy{});
ssh.authenticate(sshpp::auth::PublicKeyAuto{});
auto r = sshpp::Exec{ssh}.run("uptime");
std::cout << r.stdout_text;
return r.exit_code;
}
Same thing without exceptions:
if (auto r = ssh.try_connect(); !r) { std::cerr << r.error().to_string(); return 1; }
Where to go next¶
- New to libsshpp? Start with the Design overview, which links every design document in reading order.
- Looking for a class or function? See the generated API Reference.
- Building or packaging the library? See 09. Build and packaging.
- Want to contribute? See Contributing.
Requirements¶
- C++17 compiler — GCC 9+, Clang 12+, AppleClang 14+, MSVC 19.29+
- CMake 3.23+
- libssh 0.10.4 – 0.11.x (not vendored; bring your own via Conan, vcpkg, or a system package)
Licensing¶
libsshpp is LGPL-2.1-or-later, matching libssh (see
LICENSE and
THIRD_PARTY_NOTICES.md).
Linking libsshpp statically (or using header-only mode) into a proprietary application
propagates the LGPL's relinking obligations. The Conan recipe therefore defaults to
libssh/*:shared=True. If you need different terms, obtain them from the libssh project — a
wrapper cannot grant what it does not own. See
01 §1.7.
Security¶
Host-key verification is a mandatory, explicit step: Session::connect() does not verify, and
using a channel before verify_host_key() fails. Use StrictHostKeyPolicy or
PinnedHostKeyPolicy in production; AcceptAnyHostKeyPolicy requires an
i_understand_this_is_insecure() tag to construct.
When building remote commands from untrusted input, use the argv overload of Exec::run (or
sshpp::shell_quote) — the std::string_view overload passes the command to the remote shell
verbatim.
Report vulnerabilities privately per SECURITY.md.