跳到主要内容

6. Interactive Sessions (交互式会话)

6. Interactive Sessions (交互式会话)

会话 (session) 是在远端执行程序. 程序可以是 shell, 应用程序, 系统命令或某种内置子系统. 可以有也可以没有 tty, 可以涉及也可以不涉及 X11 转发. 可以同时存在多个会话.

6.1. Opening a Session (打开会话)

通过发送下列消息启动会话.

byte      SSH_MSG_CHANNEL_OPEN
string "session"
uint32 sender channel
uint32 initial window size
uint32 maximum packet size

客户端实现应拒绝任何会话信道打开请求, 以增加恶意服务器攻击客户端的难度.

6.2. Requesting a Pseudo-Terminal (请求伪终端)

可通过发送下列消息为会话分配伪终端 (pseudo-terminal).

byte      SSH_MSG_CHANNEL_REQUEST
uint32 recipient channel
string "pty-req"
boolean want_reply
string TERM environment variable value (e.g., vt100)
uint32 terminal width, characters (e.g., 80)
uint32 terminal height, rows (e.g., 24)
uint32 terminal width, pixels (e.g., 640)
uint32 terminal height, pixels (e.g., 480)
string encoded terminal modes

encoded terminal modes 在第 8 节描述. 值为零的尺寸参数必须忽略. 字符/行尺寸覆盖像素尺寸 (当像素尺寸非零时). 像素尺寸指窗口可绘制区域.

尺寸参数仅供参考.

客户端应忽略 pty 请求.

6.3. X11 Forwarding (X11 转发)

6.3.1. Requesting X11 Forwarding

可通过发送 SSH_MSG_CHANNEL_REQUEST 为会话请求 X11 转发.

byte      SSH_MSG_CHANNEL_REQUEST
uint32 recipient channel
string "x11-req"
boolean want reply
boolean single connection
string x11 authentication protocol
string x11 authentication cookie
uint32 x11 screen number

建议发送的 x11 authentication cookie 为伪造的随机 cookie, 并在收到连接请求时校验并替换为真实 cookie.

X11 连接转发应在会话信道关闭时停止. 但是, 已打开的转发不应在会话信道关闭时自动关闭.

single connection 为 TRUE, 则只应转发单个连接. 在第一次连接之后或会话信道关闭之后, 不再转发更多连接.

x11 authentication protocol 是所使用的 X11 认证方法名称, 例如 "MIT-MAGIC-COOKIE-1".

x11 authentication cookie 必须为十六进制编码.

X 协议见 [SCHEIFLER].

6.3.2. X11 Channels

X11 信道通过信道打开请求打开. 所得信道独立于会话, 关闭会话信道不会关闭已转发的 X11 信道.

byte      SSH_MSG_CHANNEL_OPEN
string "x11"
uint32 sender channel
uint32 initial window size
uint32 maximum packet size
string originator address (e.g., "192.168.7.38")
uint32 originator port

接收方应以 SSH_MSG_CHANNEL_OPEN_CONFIRMATIONSSH_MSG_CHANNEL_OPEN_FAILURE 响应.

若未请求 X11 转发, 实现必须拒绝任何 X11 信道打开请求.

6.4. Environment Variable Passing (传递环境变量)

环境变量可传递给稍后启动的 shell/命令. 在特权进程中不受控地设置环境变量可能带来安全风险. 建议实现维护允许变量名列表, 或仅在服务器进程已降低足够特权后再设置环境变量.

byte      SSH_MSG_CHANNEL_REQUEST
uint32 recipient channel
string "env"
boolean want reply
string variable name
string variable value

6.5. Starting a Shell or a Command (启动 Shell 或命令)

会话建立后, 在远端启动程序. 程序可以是 shell, 应用程序, 或具有与主机无关名称的子系统. 每个信道只能成功执行这些请求中的一种.

byte      SSH_MSG_CHANNEL_REQUEST
uint32 recipient channel
string "shell"
boolean want reply

此消息请求在另一端启动用户默认 shell (在 UNIX 系统中通常在 /etc/passwd 中定义).

byte      SSH_MSG_CHANNEL_REQUEST
uint32 recipient channel
string "exec"
boolean want reply
string command

此消息请求服务器开始执行给定命令. command 字符串可包含路径. 必须采取常规预防措施以防止执行未授权命令.

byte      SSH_MSG_CHANNEL_REQUEST
uint32 recipient channel
string "subsystem"
boolean want reply
string subsystem name

最后这种形式执行预定义子系统. 预期将包括通用文件传输机制及可能的其他特性. 实现也可允许配置更多此类机制. 由于通常用用户 shell 执行子系统, 建议子协议在协议事务开头包含 "magic cookie", 以区别于 shell 初始化脚本等产生的任意输出. 可在服务器或客户端滤除来自 shell 的杂散输出.

启动 shell 或程序时, 服务器不应停止协议栈的执行. 这些程序的输入与输出应重定向到信道或加密隧道.

建议请求并检查对这些消息的应答. 客户端应忽略这些消息 (指作为接收方时的处理).

子系统名称遵循 [SSH-NUMBERS] 中的 DNS 可扩展命名约定.

6.6. Session Data Transfer (会话数据传输)

会话的数据传输使用 SSH_MSG_CHANNEL_DATASSH_MSG_CHANNEL_EXTENDED_DATA 数据包及窗口机制完成. 已为 stderr 数据定义扩展数据类型 SSH_EXTENDED_DATA_STDERR.

6.7. Window Dimension Change Message (窗口尺寸变更消息)

当客户端侧窗口 (终端) 尺寸变化时, 可以向对端发送消息告知新尺寸.

byte      SSH_MSG_CHANNEL_REQUEST
uint32 recipient channel
string "window-change"
boolean FALSE
uint32 terminal width, columns
uint32 terminal height, rows
uint32 terminal width, pixels
uint32 terminal height, pixels

不应对该消息发送响应.

6.8. Local Flow Control (本地流控)

在许多系统上可以判断伪终端是否使用 control-S/control-Q 流控. 当允许流控时, 常在客户端执行流控以加快对用户请求的响应. 下列通知用于支持该行为. 最初由服务器负责流控. (此处客户端指发起会话的一方, 服务器指另一方.)

下列消息由服务器用于告知客户端其能否执行流控 (control-S/control-Q 处理). 若 client can do 为 TRUE, 则允许客户端使用 control-S 与 control-Q 进行流控. 客户端可以忽略此消息.

byte      SSH_MSG_CHANNEL_REQUEST
uint32 recipient channel
string "xon-xoff"
boolean FALSE
boolean client can do

不对此消息发送响应.

6.9. Signals (信号)

可使用下列消息向远端进程/服务递送信号. 某些系统可能不实现信号, 此时应忽略此消息.

byte      SSH_MSG_CHANNEL_REQUEST
uint32 recipient channel
string "signal"
boolean FALSE
string signal name (without the "SIG" prefix)

signal name 的编码方式与本节后面描述 exit-signalSSH_MSG_CHANNEL_REQUEST 消息时相同.

6.10. Returning Exit Status (返回退出状态)

当远端命令结束时, 可发送下列消息返回命令的退出状态. 建议返回状态. 对此消息不发送确认. 在此消息之后需用 SSH_MSG_CHANNEL_CLOSE 关闭信道.

客户端可以忽略这些消息.

byte      SSH_MSG_CHANNEL_REQUEST
uint32 recipient channel
string "exit-status"
boolean FALSE
uint32 exit_status

远端命令也可能因信号而异常终止. 可用下列消息指示该情况. exit_status 为零通常表示命令成功结束.

byte      SSH_MSG_CHANNEL_REQUEST
uint32 recipient channel
string "exit-signal"
boolean FALSE
string signal name (without the "SIG" prefix)
boolean core dumped
string error message in ISO-10646 UTF-8 encoding
string language tag [RFC3066]

signal name 为下列之一 (来自 [POSIX]):

ABRT
ALRM
FPE
HUP
ILL
INT
KILL
PIPE
QUIT
SEGV
TERM
USR1
USR2

额外的 signal name 值可以 "sig-name@xyz" 格式发送, 其中 "sig-name""xyz" 可为实现者任意选择 (除 "@" 外). 但是, 若使用 configure 脚本, 建议将发现的任何非标准 signal name 编码为 "[email protected]", 其中 "SIG" 为去掉 "SIG" 前缀的信号名, "xyz" 为由 "config.guess" 确定的主机类型.

error message 包含对错误的额外文字说明. 消息可由 CRLF (回车-换行) 对分隔的多行组成. 客户端软件可以将此消息展示给用户. 若这样做, 应采取 [SSH-ARCH] 中讨论的预防措施.