diff --git a/AGENT.MD b/AGENT.MD index 9cd0730..7dfcc7d 100644 --- a/AGENT.MD +++ b/AGENT.MD @@ -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 ` > `~/.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 自洽,防回归。 + + diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ee711c..845112b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ ## [开发主线] — 2026-08-14 +### 新增 —— SSH config 兼容读取 + ECDSA KAT 基线 + +- `pssh ssh` config 读取优先级:`-F ` > `~/.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 仍可校验、会话恢复继续有效。 diff --git a/STATUS.md b/STATUS.md index acf25ba..ec2bcf2 100644 --- a/STATUS.md +++ b/STATUS.md @@ -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 守护进程与密钥管理 diff --git a/apps/ssh/main.c b/apps/ssh/main.c index 7c664c6..26df2ef 100644 --- a/apps/ssh/main.c +++ b/apps/ssh/main.c @@ -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 :显式指定 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", "") < 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) {