豫言 / 安全外壳终端 @ 0.1.0

伪终端及独立标准流子进程的非阻塞接口(由宿主实现,Node 宿主尚未实现)。

源码浏览已生成;不能解析的文件以纯文本展示,不表示通过类型检查。

包说明.汉语.md

# 安全外壳终端

`标准流子进程。豫` 面向无 PTY 的 SSH 会话,以当前用户身份启动绝对路径程序,分别返回可写 stdin、可读 stdout 和可读 stderr。三个父端均为非阻塞并在执行其他程序时关闭;stdin 使用本地连接,使子进程关闭输入后写入返回错误而不触发宿主 SIGPIPE。调用方须分别处理部分写入、EOF、三路描述符关闭及子进程回收。它不更换用户身份、不净化继承环境,也不解释客户端命令;高权限多用户 SSHD 须另加身份与环境策略。

`等待连接与标准流` 在同一次原生 `poll` 中观察 SSH 连接及仍活动的三路标准流;调用方用关注位选择 stdin 可写、stdout 可读和 stderr 可读,返回固定位置的四个事件码。已关闭的标准流可传 `-1` 并取消对应关注位,以免挂断事件造成空转。

`检验标准流命令` 将 SSH exec 命令的原始字节交给子进程参数接口前拒绝空值、超过 65536 字节和内部 NUL;它不改变命令内容或替代 SSHD 授权。只有完成用户认证并确定执行策略后,调用方才应把命令交给 shell。

`发送标准流程序信号` 与 `发送伪终端程序信号` 把 RFC 4254 列出的标准信号名映射到宿主 `SIG*` 常量,仅对本库仍登记的 PID 或 PTY 进程组发信号;未知名返回 `-EINVAL`。对应的信号名称接口把退出时的宿主信号号转回 SSH 名称,未知号返回空字节串。

`收取标准流程序` 与 `收取伪终端程序` 返回四个整数:状态、正常退出码、终止信号号和 core dumped 标记。状态为 0 表示仍在运行,1 表示正常退出,2 表示受信号终止;仅状态为 2 时,后两项中的信号号和转储标记可用于 `exit-signal`。

待办事项:原先的 C 实现(`openpty` 伪终端与标准流子进程)已随编译器改为单一 Wasm 后端而删除,Node 宿主尚未实现这两组原语,调用会报“未实现 Node 宿主原语”;以下是接口约定。本包原先面向原生 macOS/Linux,使用 `openpty` 分配主从伪终端,提供非阻塞读写、可读与可写等待、窗口尺寸的设置与查询、原始模式设置、单独关闭回显及描述符关闭。开启返回状态码与两个文件描述符;状态 0 表示成功,负值为 `-errno`。读返回读得字节数及字节串;0 表示 EOF(包括 Linux PTY 对端关闭时的 `EIO`),负值表示其他系统错误或暂不可读。写返回实际写入数或负错误码。可写等待只在 `POLLOUT` 时返回 1;超时为 0,挂断或错误为负值。原始模式关闭规范行缓冲与回显;单独关闭回显保留规范行和 EOT 的 EOF 语义。是否采用这些模式须由会话层根据客户端请求决定。

调用方须关闭主从两个描述符。终端读写不会启动子进程,也不会建立控制终端;SSHD 仍须在授权与会话生命周期管理后接入受控的程序启动接口。窗口尺寸以平台 `winsize` 的 16 位无符号字段为界。

`伪终端子进程。豫` 可在当前用户身份下启动明确指定的绝对路径程序。子进程建立新会话,重新打开 PTY 从端作为标准输入、输出、错误,并取得控制终端;不支持 `POSIX_SPAWN_SETSID` 的宿主返回 `-ENOTSUP`。接口只接收程序路径和参数列表,不解释 shell 命令;远程 `exec` 内容仍须由 SSHD 独立授权和映射。调用方须用非阻塞收取接口回收子进程;终止接口向登记中的进程组发 `SIGTERM`。此接口不会更换用户身份或净化继承环境,不能直接用于高权限的多用户 SSHD。

包说明.文言.md

# 安全外壳终端

「标准流子进程。豫」供无 PTY 会话,以当前用户身起绝对径程序,别返可写 stdin、可读 stdout 与 stderr。三父端皆非阻塞,别启他程序时自闭;stdin 用本地连接,子进程闭入后再写惟返误,不以 SIGPIPE 断宿主。调用者须治部分写入、EOF、三端之闭及子进程之收。此术不改用户身、不净继承环境,亦不释远客命令;高权限多用户 SSHD 须另备身份与环境之策。

「等待连接与标准流」以一原生 `poll` 兼候 SSH 网连与三常流;调用者以关注位择 stdin 可写、stdout 可读、stderr 可读,返固定四位之事件码。已闭之端可授 `-1` 且去其关注位,免挂断事致空转。

「检验标准流命令」于 SSH exec 原字入子进程参列前,拒空、逾六万五千五百三十六字及内零;不改其文,亦不能代 SSHD 授权。调用者惟认证用户、定执行之策后,方可授命于 shell。

「发送标准流程序信号」与「发送伪终端程序信号」依 RFC 4254 常名求宿主 `SIG*` 号,惟向本库仍在籍 PID 或 PTY 进程组发之;未知名返 `-EINVAL`。其反求名之术,宿主退出信号号若不知则返空字。

「收取标准流程序」与「收取伪终端程序」返四整数:态、常退码、终止信号号、核心转储记。态零为未终,一为常退,二为信号所断;惟态二时,信号号与转储记可用于 `exit-signal`。

待办之事:旧之 C 实(`openpty` 伪终端与标准流子进程)随编译器改为唯一 Wasm 后端而删,Node 宿主未备此二组原语,呼之则报“未实现 Node 宿主原语”;下述乃接口之约。此包旧施于原生 macOS/Linux,以 `openpty` 开主从伪终端,备非阻塞读写、可读可写之候、窗尺寸之设与取、原始模式之设、独禁回显及描述符之闭。开返状态码与二描述符;零为成,负数为 `-errno`。读返所得字数与字节串;零为终,兼纳 Linux PTY 彼端闭时之 `EIO`;负数为余系统误或暂不可读。写返已写数或负误码。候可写惟 `POLLOUT` 返一,逾时返零,挂断或误返负。原始模式除规范行缓冲及回显;独禁回显则存规范行与 EOT 终流之义。会话层须依客户所请而定其用否。

调用者须各闭主从描述符。读写不启子进程,亦不立控制终端;SSHD 尚须先核授权、掌会话寿命,再接受控程序启动之术。窗尺寸以宿主 `winsize` 十六位无符号数为界。

「伪终端子进程。豫」得以当前用户之身,启明定绝对径程序。子进程另立会话,复开 PTY 从端为三常流,得控制终端;宿主若无 `POSIX_SPAWN_SETSID` 则返 `-ENOTSUP`。接口惟受程序径及参数列,不释 shell 命令;远方 `exec` 之文仍须 SSHD 另行授权并映射。调用者须以非阻塞收取术回收;终止术向在籍进程组发 `SIGTERM`。此术不改用户身份,亦不净继承环境,不可径施于高权限多用户 SSHD。