DeterministicESPAsyncWebServer v6.27.1
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
ssh_channel.h File Reference

SSH connection protocol - multiplexed "session" channels (RFC 4254). More...

#include "ServerConfig.h"
#include <stddef.h>
#include <stdint.h>

Go to the source code of this file.

Classes

struct  SshChannel
 Per-connection channel state. More...
 

Typedefs

typedef void(* SshChannelDataCb) (uint8_t slot, uint32_t channel, const uint8_t *data, size_t len)
 Application callback for inbound channel data (raw bytes), tagged with the channel id it arrived on.
 
typedef int(* SshForwardOpenCb) (uint8_t slot, uint32_t channel, const char *host, size_t host_len, uint16_t port)
 "direct-tcpip" forward request: a client asked the server to open a TCP connection to host : port (ssh -L). The forwarding owner (which does the actual TCP I/O - this codec does not) decides whether to allow it; host is not NUL-terminated (host_len bytes).
 
typedef void(* SshForwardDataCb) (uint8_t slot, uint32_t channel, const uint8_t *data, size_t len)
 Inbound data on a direct-tcpip channel (the owner writes it to the forwarded TCP socket). Kept separate from the session data callback.
 
typedef int(* SshRemoteForwardOpenCb) (uint8_t slot, const char *bind_addr, size_t addr_len, uint16_t bind_port)
 "tcpip-forward" remote-forward request (ssh -R): the client asks the server to listen on bind_addr : bind_port and open a channel back for each accepted connection (RFC 4254 §7.1). bind_addr is addr_len bytes (not NUL-terminated). The forwarding owner (which allocates the real listener - this codec does no I/O) decides.
 
typedef int(* SshRemoteForwardCancelCb) (uint8_t slot, const char *bind_addr, size_t addr_len, uint16_t bind_port)
 "cancel-tcpip-forward" request (RFC 4254 §7.1): drop a remote forward.
 
typedef void(* SshForwardConfirmCb) (uint8_t slot, uint32_t channel, bool ok)
 Result of the client's reply to a server-initiated forwarded-tcpip channel: ok = true on CHANNEL_OPEN_CONFIRMATION (the bridge may start), false on CHANNEL_OPEN_FAILURE (the owner tears the bridge down). channel is the local id returned by ssh_channel_open_forwarded().
 

Enumerations

enum class  SshChanType : uint8_t { SSH_CHAN_SESSION = 0 , SSH_CHAN_DIRECT_TCPIP = 1 , SSH_CHAN_FORWARDED_TCPIP = 2 }
 Channel type (RFC 4254). More...
 

Functions

void ssh_channel_set_data_cb (SshChannelDataCb cb)
 Install the inbound-data callback (session channels).
 
void ssh_channel_set_forward_open_cb (SshForwardOpenCb cb)
 Install the direct-tcpip forward open-policy callback (opt-in).
 
void ssh_channel_set_forward_data_cb (SshForwardDataCb cb)
 Install the direct-tcpip forward inbound-data callback.
 
void ssh_channel_set_rforward_open_cb (SshRemoteForwardOpenCb cb)
 Install the remote-forward (ssh -R) open-policy callback (opt-in).
 
void ssh_channel_set_rforward_cancel_cb (SshRemoteForwardCancelCb cb)
 Install the remote-forward (ssh -R) cancel callback (opt-in).
 
void ssh_channel_set_forward_confirm_cb (SshForwardConfirmCb cb)
 Install the forwarded-tcpip open-confirmation callback (opt-in, ssh -R).
 
int ssh_channel_open_forwarded (uint8_t i, const char *conn_addr, uint16_t conn_port, const char *orig_addr, uint16_t orig_port, uint8_t *out, size_t *out_len, size_t cap)
 Open a server-initiated "forwarded-tcpip" channel (RFC 4254 §7.2, ssh -R).
 
int ssh_channel_handle_open_confirm (uint8_t i, const uint8_t *payload, size_t len)
 Handle SSH_MSG_CHANNEL_OPEN_CONFIRMATION for a channel we opened (ssh -R).
 
int ssh_channel_handle_open_failure (uint8_t i, const uint8_t *payload, size_t len)
 Handle SSH_MSG_CHANNEL_OPEN_FAILURE for a channel we opened (ssh -R).
 
int ssh_global_request_handle (uint8_t i, const uint8_t *payload, size_t len, uint8_t *out, size_t *out_len, size_t cap)
 Handle SSH_MSG_GLOBAL_REQUEST (RFC 4254 §4).
 
void ssh_channel_init (uint8_t i)
 Reset channel state for slot i.
 
int ssh_channel_handle_open (uint8_t i, const uint8_t *payload, size_t len, uint8_t *out, size_t *out_len, size_t cap)
 Handle SSH_MSG_CHANNEL_OPEN and emit CHANNEL_OPEN_CONFIRMATION.
 
int ssh_channel_handle_request (uint8_t i, const uint8_t *payload, size_t len, uint8_t *out, size_t *out_len, size_t cap)
 Handle SSH_MSG_CHANNEL_REQUEST.
 
int ssh_channel_handle_data (uint8_t i, const uint8_t *payload, size_t len, uint8_t *out, size_t *out_len, size_t cap)
 Handle SSH_MSG_CHANNEL_DATA: bounds-check, update the window, and invoke the data callback. If the local window is exhausted a CHANNEL_WINDOW_ADJUST is written to out (*out_len > 0).
 
int ssh_channel_build_data (uint8_t i, uint32_t channel, const uint8_t *data, size_t len, uint8_t *out, size_t *out_len, size_t cap)
 Build an SSH_MSG_CHANNEL_DATA message carrying data to the client on channel channel (a local channel id from a prior open).
 
int ssh_channel_handle_window_adjust (uint8_t i, const uint8_t *payload, size_t len)
 Handle SSH_MSG_CHANNEL_WINDOW_ADJUST (grows the peer window).
 
int ssh_channel_build_close (uint8_t i, uint32_t channel, uint8_t *out, size_t *out_len, size_t cap)
 Build SSH_MSG_CHANNEL_EOF + SSH_MSG_CHANNEL_CLOSE for channel channel and mark it closed.
 
int ssh_channel_handle_close (uint8_t i, const uint8_t *payload, size_t len, uint8_t *out, size_t *out_len, size_t cap)
 Handle an inbound SSH_MSG_CHANNEL_CLOSE: route to the recipient channel, reply with EOF + CLOSE, and mark it closed.
 

Variables

SshChannel ssh_chan [MAX_SSH_CONNS][DETWS_SSH_MAX_CHANNELS]
 Channel pool: DETWS_SSH_MAX_CHANNELS channels per SSH connection (BSS). Owned by this layer; src/ code routes through the functions below, never the array (tests inspect it white-box). Index: [connection slot][channel slot].
 

Detailed Description

SSH connection protocol - multiplexed "session" channels (RFC 4254).

After authentication the client opens one or more channels; this layer confirms each, accepts a shell/exec/pty request, and exchanges SSH_MSG_CHANNEL_DATA. Inbound channel data is surfaced to the application as a raw byte stream (no PTY emulation), tagged with its channel id; outbound data is framed back to the client on a given channel. Flow control follows RFC 4254 §5.2 (per-channel window tracking + WINDOW_ADJUST).

Up to DETWS_SSH_MAX_CHANNELS channels per connection are multiplexed, each with its own id, peer id, and windows. The default (1) is the original single-channel control/console link. Every inbound message is routed to its channel by the recipient channel id it carries.

Author
Douglas Quigg (dstroy0)
Date
2026

Definition in file ssh_channel.h.

Typedef Documentation

◆ SshChannelDataCb

typedef void(* SshChannelDataCb) (uint8_t slot, uint32_t channel, const uint8_t *data, size_t len)

Application callback for inbound channel data (raw bytes), tagged with the channel id it arrived on.

Definition at line 59 of file ssh_channel.h.

◆ SshForwardOpenCb

typedef int(* SshForwardOpenCb) (uint8_t slot, uint32_t channel, const char *host, size_t host_len, uint16_t port)

"direct-tcpip" forward request: a client asked the server to open a TCP connection to host : port (ssh -L). The forwarding owner (which does the actual TCP I/O - this codec does not) decides whether to allow it; host is not NUL-terminated (host_len bytes).

Returns
0 to accept (the channel is opened and confirmed), < 0 to refuse (CHANNEL_OPEN_FAILURE, administratively prohibited / connect failed).

If no callback is installed, all forward requests are refused - so forwarding is opt-in (no open relay by default).

Definition at line 75 of file ssh_channel.h.

◆ SshForwardDataCb

typedef void(* SshForwardDataCb) (uint8_t slot, uint32_t channel, const uint8_t *data, size_t len)

Inbound data on a direct-tcpip channel (the owner writes it to the forwarded TCP socket). Kept separate from the session data callback.

Definition at line 79 of file ssh_channel.h.

◆ SshRemoteForwardOpenCb

typedef int(* SshRemoteForwardOpenCb) (uint8_t slot, const char *bind_addr, size_t addr_len, uint16_t bind_port)

"tcpip-forward" remote-forward request (ssh -R): the client asks the server to listen on bind_addr : bind_port and open a channel back for each accepted connection (RFC 4254 §7.1). bind_addr is addr_len bytes (not NUL-terminated). The forwarding owner (which allocates the real listener - this codec does no I/O) decides.

Returns
the bound port on success (echo bind_port, or the port the owner picked when bind_port == 0), or < 0 to refuse. If no callback is installed every request is refused, so remote forwarding is opt-in (no listener is opened).

Definition at line 97 of file ssh_channel.h.

◆ SshRemoteForwardCancelCb

typedef int(* SshRemoteForwardCancelCb) (uint8_t slot, const char *bind_addr, size_t addr_len, uint16_t bind_port)

"cancel-tcpip-forward" request (RFC 4254 §7.1): drop a remote forward.

Returns
0 if a matching forward was cancelled, < 0 if none / unsupported.

Definition at line 101 of file ssh_channel.h.

◆ SshForwardConfirmCb

typedef void(* SshForwardConfirmCb) (uint8_t slot, uint32_t channel, bool ok)

Result of the client's reply to a server-initiated forwarded-tcpip channel: ok = true on CHANNEL_OPEN_CONFIRMATION (the bridge may start), false on CHANNEL_OPEN_FAILURE (the owner tears the bridge down). channel is the local id returned by ssh_channel_open_forwarded().

Definition at line 115 of file ssh_channel.h.

Enumeration Type Documentation

◆ SshChanType

enum class SshChanType : uint8_t
strong

Channel type (RFC 4254).

Enumerator
SSH_CHAN_SESSION 

"session" - shell / exec / data

SSH_CHAN_DIRECT_TCPIP 

"direct-tcpip" - client-initiated TCP forward (ssh -L)

SSH_CHAN_FORWARDED_TCPIP 

"forwarded-tcpip" - server-initiated TCP forward (ssh -R)

Definition at line 32 of file ssh_channel.h.

Function Documentation

◆ ssh_channel_set_data_cb()

void ssh_channel_set_data_cb ( SshChannelDataCb  cb)

Install the inbound-data callback (session channels).

Definition at line 34 of file ssh_channel.cpp.

References SshChannelCtx::data_cb.

◆ ssh_channel_set_forward_open_cb()

void ssh_channel_set_forward_open_cb ( SshForwardOpenCb  cb)

Install the direct-tcpip forward open-policy callback (opt-in).

Definition at line 39 of file ssh_channel.cpp.

References SshChannelCtx::forward_open_cb.

◆ ssh_channel_set_forward_data_cb()

void ssh_channel_set_forward_data_cb ( SshForwardDataCb  cb)

Install the direct-tcpip forward inbound-data callback.

Definition at line 44 of file ssh_channel.cpp.

References SshChannelCtx::forward_data_cb.

◆ ssh_channel_set_rforward_open_cb()

void ssh_channel_set_rforward_open_cb ( SshRemoteForwardOpenCb  cb)

Install the remote-forward (ssh -R) open-policy callback (opt-in).

Definition at line 49 of file ssh_channel.cpp.

References SshChannelCtx::rfwd_open_cb.

◆ ssh_channel_set_rforward_cancel_cb()

void ssh_channel_set_rforward_cancel_cb ( SshRemoteForwardCancelCb  cb)

Install the remote-forward (ssh -R) cancel callback (opt-in).

Definition at line 54 of file ssh_channel.cpp.

References SshChannelCtx::rfwd_cancel_cb.

◆ ssh_channel_set_forward_confirm_cb()

void ssh_channel_set_forward_confirm_cb ( SshForwardConfirmCb  cb)

Install the forwarded-tcpip open-confirmation callback (opt-in, ssh -R).

Definition at line 59 of file ssh_channel.cpp.

References SshChannelCtx::forward_confirm_cb.

◆ ssh_channel_open_forwarded()

int ssh_channel_open_forwarded ( uint8_t  i,
const char *  conn_addr,
uint16_t  conn_port,
const char *  orig_addr,
uint16_t  orig_port,
uint8_t *  out,
size_t *  out_len,
size_t  cap 
)

Open a server-initiated "forwarded-tcpip" channel (RFC 4254 §7.2, ssh -R).

Allocates a local channel on connection i (state = pending, awaiting the client's confirmation) and builds the SSH_MSG_CHANNEL_OPEN in out. conn_addr / conn_port are the forward's bound address/port (the "address that was connected"); orig_addr / orig_port are the peer that connected.

Returns
the local channel id (>= 0) on success, or -1 (pool full, or out too small). On success the caller emits out and, on the eventual confirm, bridges bytes on the returned channel.

Definition at line 257 of file ssh_channel.cpp.

References SshChannel::local_id, SshChannel::local_window, MAX_SSH_CONNS, SshChannel::open, SshChannel::peer_id, SshChannel::peer_max_pkt, SshChannel::peer_window, SshChannel::pending, ssh_chan, SSH_CHAN_FORWARDED_TCPIP, SSH_CHAN_MAX_PACKET, SSH_CHAN_WINDOW, SSH_MSG_CHANNEL_OPEN, and SshChannel::type.

Referenced by ssh_conn_open_forwarded().

◆ ssh_channel_handle_open_confirm()

int ssh_channel_handle_open_confirm ( uint8_t  i,
const uint8_t *  payload,
size_t  len 
)

Handle SSH_MSG_CHANNEL_OPEN_CONFIRMATION for a channel we opened (ssh -R).

Matches the pending channel by our recipient id, records the peer's channel id / window / max-packet, and marks it open. Fires the confirm callback (ok = true).

Returns
0 on success, -1 if malformed or no matching pending channel.

Definition at line 309 of file ssh_channel.cpp.

References SshChannelCtx::forward_confirm_cb, SshChannel::local_id, MAX_SSH_CONNS, SshChannel::open, SshChannel::peer_id, SshChannel::peer_max_pkt, SshChannel::peer_window, SshChannel::pending, and SSH_MSG_CHANNEL_OPEN_CONFIRM.

Referenced by ssh_server_dispatch().

◆ ssh_channel_handle_open_failure()

int ssh_channel_handle_open_failure ( uint8_t  i,
const uint8_t *  payload,
size_t  len 
)

Handle SSH_MSG_CHANNEL_OPEN_FAILURE for a channel we opened (ssh -R).

Frees the pending channel and fires the confirm callback (ok = false).

Returns
0 on success, -1 if malformed or no matching pending channel.

Definition at line 327 of file ssh_channel.cpp.

References SshChannelCtx::forward_confirm_cb, SshChannel::local_id, MAX_SSH_CONNS, SshChannel::open, SshChannel::pending, and SSH_MSG_CHANNEL_OPEN_FAILURE.

Referenced by ssh_server_dispatch().

◆ ssh_global_request_handle()

int ssh_global_request_handle ( uint8_t  i,
const uint8_t *  payload,
size_t  len,
uint8_t *  out,
size_t *  out_len,
size_t  cap 
)

Handle SSH_MSG_GLOBAL_REQUEST (RFC 4254 §4).

Parses the request name and want_reply flag. "tcpip-forward" / "cancel-tcpip-forward" are routed to the remote-forward seam above (accepted only when a callback is installed); a "tcpip-forward" that bound port 0 gets its allocated port echoed in the reply (RFC 4254 §7.1). Any other request name is unrecognized: per §4 it is answered with SSH_MSG_REQUEST_FAILURE when want_reply is set, and silently ignored otherwise (never SSH_MSG_UNIMPLEMENTED - GLOBAL_REQUEST is a known message type; only the request name is unknown).

Returns
0 on success (a reply is in out with *out_len bytes, or *out_len is 0 when no reply is due), -1 if the message is malformed.

Definition at line 171 of file ssh_channel.cpp.

References MAX_SSH_CONNS, SshChannelCtx::rfwd_cancel_cb, SshChannelCtx::rfwd_open_cb, SSH_MSG_GLOBAL_REQUEST, SSH_MSG_REQUEST_FAILURE, and SSH_MSG_REQUEST_SUCCESS.

Referenced by ssh_server_dispatch().

◆ ssh_channel_init()

void ssh_channel_init ( uint8_t  i)

Reset channel state for slot i.

Definition at line 64 of file ssh_channel.cpp.

References MAX_SSH_CONNS, and ssh_chan.

Referenced by ssh_conn_accept().

◆ ssh_channel_handle_open()

int ssh_channel_handle_open ( uint8_t  i,
const uint8_t *  payload,
size_t  len,
uint8_t *  out,
size_t *  out_len,
size_t  cap 
)

Handle SSH_MSG_CHANNEL_OPEN and emit CHANNEL_OPEN_CONFIRMATION.

Accepts a "session" channel; any other type yields CHANNEL_OPEN_FAILURE.

Returns
0 if a response was produced, -1 if malformed.

Definition at line 343 of file ssh_channel.cpp.

References SshChannelCtx::forward_open_cb, SshChannel::local_id, SshChannel::local_window, MAX_SSH_CONNS, SshChannel::open, SshChannel::peer_id, SshChannel::peer_max_pkt, SshChannel::peer_window, ssh_chan, SSH_CHAN_DIRECT_TCPIP, SSH_CHAN_SESSION, SSH_CHAN_WINDOW, SSH_MSG_CHANNEL_OPEN, and SshChannel::type.

Referenced by ssh_server_dispatch().

◆ ssh_channel_handle_request()

int ssh_channel_handle_request ( uint8_t  i,
const uint8_t *  payload,
size_t  len,
uint8_t *  out,
size_t *  out_len,
size_t  cap 
)

Handle SSH_MSG_CHANNEL_REQUEST.

"shell", "exec", and "pty-req" are accepted; anything else is refused. When want_reply is set, CHANNEL_SUCCESS / CHANNEL_FAILURE is written to out and *out_len > 0; otherwise *out_len is 0.

Returns
0 on success, -1 if malformed.

Definition at line 408 of file ssh_channel.cpp.

References MAX_SSH_CONNS, SshChannel::peer_id, SSH_MSG_CHANNEL_FAILURE, SSH_MSG_CHANNEL_REQUEST, and SSH_MSG_CHANNEL_SUCCESS.

Referenced by ssh_server_dispatch().

◆ ssh_channel_handle_data()

int ssh_channel_handle_data ( uint8_t  i,
const uint8_t *  payload,
size_t  len,
uint8_t *  out,
size_t *  out_len,
size_t  cap 
)

Handle SSH_MSG_CHANNEL_DATA: bounds-check, update the window, and invoke the data callback. If the local window is exhausted a CHANNEL_WINDOW_ADJUST is written to out (*out_len > 0).

Returns
0 on success, -1 if malformed or channel not open.

Definition at line 450 of file ssh_channel.cpp.

References SshChannelCtx::data_cb, SshChannelCtx::forward_data_cb, SshChannel::local_id, SshChannel::local_window, MAX_SSH_CONNS, SshChannel::peer_id, SSH_CHAN_SESSION, SSH_CHAN_WINDOW, SSH_MSG_CHANNEL_DATA, SSH_MSG_CHANNEL_WINDOW_ADJUST, and SshChannel::type.

Referenced by ssh_server_dispatch().

◆ ssh_channel_build_data()

int ssh_channel_build_data ( uint8_t  i,
uint32_t  channel,
const uint8_t *  data,
size_t  len,
uint8_t *  out,
size_t *  out_len,
size_t  cap 
)

Build an SSH_MSG_CHANNEL_DATA message carrying data to the client on channel channel (a local channel id from a prior open).

Returns
0 on success, -1 if the channel is closed/unknown, the peer window is too small, or out is too small.

Definition at line 506 of file ssh_channel.cpp.

References MAX_SSH_CONNS, SshChannel::peer_id, SshChannel::peer_max_pkt, SshChannel::peer_window, and SSH_MSG_CHANNEL_DATA.

Referenced by ssh_conn_send().

◆ ssh_channel_handle_window_adjust()

int ssh_channel_handle_window_adjust ( uint8_t  i,
const uint8_t *  payload,
size_t  len 
)

Handle SSH_MSG_CHANNEL_WINDOW_ADJUST (grows the peer window).

Returns
0 on success, -1 if malformed.

Definition at line 530 of file ssh_channel.cpp.

References MAX_SSH_CONNS, SshChannel::peer_window, and SSH_MSG_CHANNEL_WINDOW_ADJUST.

Referenced by ssh_server_dispatch().

◆ ssh_channel_build_close()

int ssh_channel_build_close ( uint8_t  i,
uint32_t  channel,
uint8_t *  out,
size_t *  out_len,
size_t  cap 
)

Build SSH_MSG_CHANNEL_EOF + SSH_MSG_CHANNEL_CLOSE for channel channel and mark it closed.

Returns
0 on success, -1 if the channel is closed/unknown or out is too small.

Definition at line 564 of file ssh_channel.cpp.

References MAX_SSH_CONNS.

Referenced by ssh_conn_close_channel().

◆ ssh_channel_handle_close()

int ssh_channel_handle_close ( uint8_t  i,
const uint8_t *  payload,
size_t  len,
uint8_t *  out,
size_t *  out_len,
size_t  cap 
)

Handle an inbound SSH_MSG_CHANNEL_CLOSE: route to the recipient channel, reply with EOF + CLOSE, and mark it closed.

Returns
0 if a response was produced, -1 if malformed or the channel is unknown.

Definition at line 571 of file ssh_channel.cpp.

References MAX_SSH_CONNS, and SSH_MSG_CHANNEL_CLOSE.

Referenced by ssh_server_dispatch().

Variable Documentation

◆ ssh_chan

Channel pool: DETWS_SSH_MAX_CHANNELS channels per SSH connection (BSS). Owned by this layer; src/ code routes through the functions below, never the array (tests inspect it white-box). Index: [connection slot][channel slot].

Definition at line 18 of file ssh_channel.cpp.

Referenced by ssh_channel_handle_open(), ssh_channel_init(), and ssh_channel_open_forwarded().