feat: M4b publickey 认证(SE 优先/软件回退,sign_callback)
- TXTransport: SSHSigner 协议 + Authentication.publicKeyCallback;SSHSession 用 @convention(c) sshSignCallback(abstract 桥 SignerBox + malloc 出参)接 libssh2_userauth_publickey - app SigningKeyProvider: SE 优先(kSecAttrTokenIDSecureEnclave),未签名/无 SE 回退软件 P-256 (导出落文件持久化),同一 SSHSigner 路径;SecKeyCreateSignature(ecdsa)→ECDSAConv.derToSSHSignature - 公钥 blob=ecdsa-sha2-nistp256||nistp256||X963;-txPubkeyAuth 日志打 authorized_keys 行 - 验证(192.168.9.199):不给密码,公钥加 authorized_keys 后免密登录成功(whoami=kid); 模拟器 SE 生成 hw=true 可达,真机 SE 硬件签名+keychain 持久化待补 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -42,7 +42,7 @@
|
||||
| **R5** Go+gvisor+C+++Swift 同进程 | ✅ retire | 全程真机无崩溃 |
|
||||
| **M2** mosh | ✅ 完成(LAN + tsnet 均验证) | libmoshios(C++)+protobuf-lite→`MoshCore.xcframework`;UDP relay over tsnet;**LAN 直连 + mosh-over-tsnet 均端到端验证通过**(R1 证伪) |
|
||||
| **M3** 生命周期深化 | ✅ mosh 快恢复(真机深挂起待补) | scenePhase FSM + **mosh 挂起→恢复<3s 已验证**(模拟器:15/30s 冻结→前台,wake pulse→1.3s 收到服务器包,"已恢复");冷启动重连(SSP 序号+key 持久化)划入 M4/M5 |
|
||||
| **M4** 安全 | ◐ host key 校验完成 / SE 认证待做 | **host key TOFU pin 已做并验证**(首次信任+不符告警,指纹对齐 ssh-keygen,MITM 敞口关闭;pin 存沙盒文件因未签名 app 无 keychain 权限);Secure Enclave publickey 认证(M4b) 待做 |
|
||||
| **M4** 安全 | ✅ 完成(真机 SE 硬件待补) | **host key TOFU pin**(首次信任+不符告警,指纹对齐 ssh-keygen,MITM 关闭)+ **publickey 认证**(P-256 sign_callback→SecKeyCreateSignature→DER→SSH mpint,免密登录 192.168.9.199 验证通过;SE 优先/未签名回退软件+文件,SE 生成在模拟器 hw=true 可达,真机 SE 硬件签名+keychain 持久化待补) |
|
||||
| **M5** 合规提审 | ⏸️ 暂缓 | 用户指示暂缓 |
|
||||
|
||||
## 5. 代码地图与数据流
|
||||
@@ -55,6 +55,8 @@
|
||||
- `CSSH/`(C target:libssh2 头 + modulemap,供 `import CSSH`)、`CSSHCore`(binaryTarget,library-only)。
|
||||
- `CMosh/`(C target:`moshiosbridge.h`(mosh_main)+modulemap+占位 shim.c,供 `import CMosh`)、`MoshCore`(binaryTarget,library-only);TXTransport 链 `libc++`/`libz`(mosh 是 C++ 且 compressor 用 zlib;CommonCrypto 属 libSystem 自动解析)。
|
||||
- `TXCore/Mosh/MoshConnect.swift`:`MoshConnectScanner` 流式扫描 `MOSH CONNECT <port> <key>`(注意 Swift 视 `\r\n` 为单 Character,行尾判定须用 `isNewline`)。
|
||||
- `TXCore/SSH/`(M4):`SSHWire`(string/mpint 编码)/`ECDSAConv`(DER→SSH 签名·P256 blob)/`HostKey`(opensshFingerprint·evaluate·HostTriple·KnownHostsStore 协议),SSHWireTests 10 单测(真实指纹向量+高位 DER)。
|
||||
- **M4 安全**:`TXTransport` `SSHConfig.hostKeyVerifier`(闭包)+`SSHError.hostKeyMismatch`+`SSHSigner` 协议+`Authentication.publicKeyCallback`;`SSHSession` 握手后 `libssh2_session_hostkey` 校验、`sshSignCallback`(@convention(c)+malloc 出参)接 `libssh2_userauth_publickey`。app:`KeychainKnownHostsStore`(文件后端 TOFU pin)、`SigningKeyProvider`(SE 优先/软件回退+文件持久化,`SecKeyCreateSignature`)、mismatch alert(ContentView)。
|
||||
- **M3 快恢复链**:`bridge.go` 加 `Node.WakeUp()`(tsnet `InjectEvent`+`MagicSock.Rebind/ReSTUN`) 与 `MoshRelay.Rebind()`(同端口重开 loopback、泵按 socket 生成容错);`iosclient.cc` 加 `g_mosh_last_heard`(收到服务器包即更新,导出 `mosh_last_heard_ms()`) 并恢复 SIGCONT 全屏重绘;`MoshSession.nudge()`(SIGCONT) + `lastHeardMs()`;`SSHTerminalModel` 前台执行"唤醒脉冲三连"(WakeUp+Rebind+nudge)+healthy 轮询(探针增长→`moshHealthy`)+恢复看门狗+`beginBackgroundTask`。
|
||||
- `apps/TerminalX/iOS/`
|
||||
- `SSHTerminalModel.swift` —— 核心编排:`OutputGate`(surface-ready 缓冲)、`TransportHolder`、`TsnetManager`(tsnet 节点 up/dial+重试)、`TsnetError`、`TmuxRouter`(raw/gateway 字节分流)、状态机驱动 startSession(直连/tsnet 分支)、`autoConnectIfConfigured`(启动参数)。
|
||||
@@ -66,7 +68,7 @@
|
||||
- **数据流(tsnet)**:`TsnetManager.ensureUp`(auth key)→`dialFD`(socketpair fd)→`SSHSession(preconnectedFD:)`。
|
||||
|
||||
## 6. 已知问题 / TODO(继续工作的入口)
|
||||
- **M4 安全**:`SSHSession.connect()` 有 `TODO(M4)`:不校验 host key(接受任意)。需接 known_hosts 三元组 pin(egress,host,port) + Secure Enclave 私钥(`libssh2_userauth_publickey_frommemory`+`SecKeyCreateSignature`)。
|
||||
- **M4 安全(已完成,剩真机 SE)**:host key TOFU pin(`SSHConfig.hostKeyVerifier`→app `KeychainKnownHostsStore` 文件后端) + publickey 认证(`Authentication.publicKeyCallback(SSHSigner)`→`SSHSession` C `sshSignCallback`→`SigningKeyProvider`)。**剩**:真机验证 SE 硬件密钥生成+签名+keychain 持久化(未签名/模拟器回退软件+文件);`libssh2_session_method_pref` 锁定 pinned hostkey 类型防算法漂移误报(fable 建议,未做);M4DBG NSLog 埋点可清理。
|
||||
- **tmux 多 pane 分屏 + 动态 resize**:✅ 已做(pane-per-surface + layout rect 绝对定位渲染 + 按 pane %output 路由 + tap 切焦点/select-pane + attach `refresh-client -C` 设尺寸 + **iPadOS 拖拽窗口/旋转 → `onChange(geo.size)`→`containerResized`(点×displayScale÷cell像素)→debounce→refresh-client -C→%layout-change→更新 frame**,验证:容器 1032x1280@2x cell16x35→129x73,tmux 精确采纳)。**剩余**:完整 scrollback(仍靠 capture-pane 抓当前屏);pause 流控(`%pause/%continue`,防单 pane 刷屏);split/kill pane 手势;tmux<3.1 降级路径未做。
|
||||
- **tsnet 首连**:已加 dial 重试;更优是等 peer online 再 dial(读 PeersJSON online 状态)。
|
||||
- **签名/真机**:`CODE_SIGNING_ALLOWED=NO`,仅模拟器;上真机/TestFlight 需配置签名 + entitlements(tsnet 用户态**无需** NE entitlement,利好审核)。
|
||||
|
||||
Reference in New Issue
Block a user