SSH config 兼容读取 + ECDSA KAT 基线: pssh ssh config 优先级 -F > ~/.ssh/config(OpenSSH兼容) > ~/.pssh/config.conf; 新增 build/run_ecdsa_selfcheck.ps1(P-256/384/521 ECDSA sign->verify 自洽防回归, 已跑通); STATUS/AGENT/CHANGELOG 更新
这个提交包含在:
@@ -86,3 +86,9 @@ session ticket key 支持持久化到文件:新增 `paze_tls_config_set_session_
|
||||
|
||||
支持 2 代 ticket key:新增 `paze_tls_config_rotate_ticket_key`(当前 key 转上一代、新 key 装当前,写盘 2×32 字节);验证用所有已就绪 key 遍历匹配 MAC(不依赖 ticket 内槽位),轮换后旧 ticket 仍由上一代 key 平滑验证。`pazessl s_server -rotate_ticket_key`,验证:轮换后旧会话仍恢复 + 新会话跨进程恢复。
|
||||
|
||||
### 7. SSH config 兼容 + ECDSA KAT 基线(✅ 已完成 2026-08-14)
|
||||
|
||||
- `pssh ssh` config 读取优先级:`-F <file>` > `~/.ssh/config`(OpenSSH 兼容) > `~/.pssh/config.conf`;支持 `Host/HostName/Port/User/IdentityFile/ProxyJump/StrictHostKeyChecking`。
|
||||
- 新增 `build/run_ecdsa_selfcheck.ps1`(KAT 基线):对 P-256/384/521 跑 ECDSA sign→verify 自洽,防回归。
|
||||
|
||||
|
||||
|
||||
+5
@@ -4,6 +4,11 @@
|
||||
|
||||
## [开发主线] — 2026-08-14
|
||||
|
||||
### 新增 —— SSH config 兼容读取 + ECDSA KAT 基线
|
||||
|
||||
- `pssh ssh` config 读取优先级:`-F <file>` > `~/.ssh/config`(OpenSSH 兼容) > `~/.pssh/config.conf`;支持 `Host/HostName/Port/User/IdentityFile/ProxyJump/StrictHostKeyChecking`。
|
||||
- 新增可重复回归脚本 `build/run_ecdsa_selfcheck.ps1`(KAT 基线):对 P-256/384/521 各跑 ECDSA sign→verify 自洽,作为防回归基线。
|
||||
|
||||
### 新增 —— TLS 1.3 会话恢复持久化
|
||||
|
||||
- session ticket key:新增 `paze_tls_config_set_session_ticket_file`(持久化文件)与 `paze_tls_ensure_ticket_key`(首次生成时读取/写盘,PSK 验证入口亦加载),服务端**跨进程重启**后 ticket 仍可校验、会话恢复继续有效。
|
||||
|
||||
@@ -44,7 +44,8 @@
|
||||
- 通道:session(exec/shell 真实进程执行)、direct-tcpip(出站桥接)
|
||||
- **SFTP 子系统 v3**:OPEN/READ/WRITE/OPENDIR/READDIR/STAT/REALPATH 等,与 OpenSSH sftp / scp -s 互操作(Git OpenSSH 实测通过)
|
||||
- 客户端命令:
|
||||
- `pssh ssh` — 远程 shell / 执行命令,`-L`/`-R`/`-D` 端口转发,`-J` 代理跳板(单跳)、`-W host:port` stdio 转发、`-N` 仅转发
|
||||
- `pssh ssh` — 远程 shell / 执行命令,`-L`/`-R`/`-D` 端口转发,`-J` 代理跳板(单跳)、`-W host:port` stdio 转发、`-N` 仅转发;config 读取 `-F` / `~/.ssh/config`(OpenSSH 兼容) / `~/.pssh/config.conf`
|
||||
|
||||
- `pssh scp` — SFTP 优先(OpenSSH 9.x 默认),回退 legacy SCP;`-r` 递归、`-p` 保留时间戳
|
||||
- `pssh keygen` / `keyscan` / `copy-id` — 密钥工具
|
||||
- `pssh agent` / `add` / `ssha` — agent 守护进程与密钥管理
|
||||
|
||||
+18
-7
@@ -1,6 +1,6 @@
|
||||
/* pssh ssh —— SSH2 客户端 (平替 ssh)
|
||||
* 支持:交互 shell / 执行命令 / 端口转发 -L -R -D(SOCKS5) / 代理跳转 -J /
|
||||
* config 文件 ~/.pssh/config.conf / 公钥与 agent 认证
|
||||
* config 文件 -F / ~/.ssh/config / ~/.pssh/config.conf / 公钥与 agent 认证
|
||||
*/
|
||||
#include "paze/ssh.h"
|
||||
#include "paze/ssh_agent.h"
|
||||
@@ -340,6 +340,7 @@ int pssh_cmd_ssh(int argc, char **argv) {
|
||||
int stdio_port = 0;
|
||||
int no_command = 0;
|
||||
char stdio_host[256];
|
||||
const char *user_cfg = NULL; /* -F <file>:显式指定 config 文件 */
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
const char *a = argv[i];
|
||||
@@ -423,6 +424,9 @@ int pssh_cmd_ssh(int argc, char **argv) {
|
||||
fwds[nfwds].target_port = 0;
|
||||
if (fwds[nfwds].bind_port > 0) nfwds++;
|
||||
}
|
||||
} else if (strcmp(a, "-F") == 0) {
|
||||
if (opt_missing(argc, i, "-F", "<configfile>") < 0) return 1;
|
||||
user_cfg = argv[++i];
|
||||
} else if (strcmp(a, "-o") == 0) {
|
||||
if (opt_missing(argc, i, "-o", "StrictHostKeyChecking=no|accept-new|yes") < 0) return 1;
|
||||
const char *kv = argv[++i];
|
||||
@@ -447,13 +451,20 @@ int pssh_cmd_ssh(int argc, char **argv) {
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- config 文件 ~/.pssh/config.conf ---- */
|
||||
/* ---- config 文件:优先 -F > ~/.ssh/config(OpenSSH 约定) > ~/.pssh/config.conf ---- */
|
||||
char cfg_path[1024];
|
||||
{
|
||||
const char *home = getenv("USERPROFILE");
|
||||
if (!home) home = getenv("HOME");
|
||||
if (home) snprintf(cfg_path, sizeof(cfg_path), "%s/.pssh/config.conf", home);
|
||||
else snprintf(cfg_path, sizeof(cfg_path), ".pssh/config.conf");
|
||||
const char *home = getenv("USERPROFILE");
|
||||
if (!home) home = getenv("HOME");
|
||||
if (user_cfg) {
|
||||
snprintf(cfg_path, sizeof(cfg_path), "%s", user_cfg);
|
||||
} else if (home) {
|
||||
FILE *probe = NULL;
|
||||
snprintf(cfg_path, sizeof(cfg_path), "%s/.ssh/config", home);
|
||||
probe = fopen(cfg_path, "r");
|
||||
if (probe) fclose(probe);
|
||||
else snprintf(cfg_path, sizeof(cfg_path), "%s/.pssh/config.conf", home);
|
||||
} else {
|
||||
snprintf(cfg_path, sizeof(cfg_path), ".pssh/config.conf");
|
||||
}
|
||||
char cfg_host[256];
|
||||
if (host) {
|
||||
|
||||
在新工单中引用
屏蔽一个用户