70 Commits
Author SHA1 Message Date
胡飞 23cb37bc6f chore(deps): 升级 gpui-fast v0.1.12、gpui-kit v0.8.1、russh 0.65.0 并适配 API 变更
gpui-fast(fork 分支 release/v0.1.12,快照 5e8e231f)
- 快照自含 24 个 crate + 全套 gpui-pre-* shim(0.3.126),并剥离 iOS:
  gpui_platform 不再引用 gpui_ios/gpui-pre-ios,navop 依赖解析不再需要该包
- 随上游同步:objc2 迁移、字体缓存、Taffy 0.15、wgpu 30.0.1、
  Windows 按需帧调度、未测量文本的测量修复

gpui-kit(fork 分支 port-ce-generic-to-main,rev 62035f8d,v0.8.1)
- gpui-component-shell 并入 gpui-shell,navop 改用 gpui_shell::components
  (components.rs 的 components()/init、渲染测试的 init/new_isolated_runtime)
- quickjs 系全部改 crates.io quickjs-jit 0.14.1(stdlib 已 vendor llrt 模块),
  删除 rquickjs 的 [patch.crates-io] 与 rquickjs-compat 依赖
- 保留 fork 的 gpui-base 状态桥:组件元素接受 gpui-base 铸造的 state 句柄。
  上游 #3505 会以 "expects the InputState from gpui-component" 拒绝,而扩展页
  的状态一律来自 gpui-base,故 fork 侧维持先认 base 句柄、诊断只拦真正异类句柄
- 新增 gpui_component::active_dialog_count(window, cx):对话框层改为 Presence
  动画后只能在渲染期采样,测试改为查询活动对话框数

API 适配
- ScrollWheelEvent → ScrollEvent,on_scroll_wheel → on_scroll(含 vendor/ferrum-flow)
- Modifiers::secondary() → secondary(cx):secondary 在 macOS 是 platform 键,
  需要 App 才能判定
- 动态字符串的 KeyBinding 统一走 one_core::keybindings::load_dynamic_keybinding
  (KeyBinding::load + context predicate),Keystroke::parse → parse_with_os(...,
  current_os());KeybindingKeystroke 不再实现 Display,改用 display(os)
- 测试侧:ScrollEvent 补 source 字段、用 VisualTestContext::read 取 &App 调
  secondary_key、Keystroke 断言改成 parse_with_os(..., Mac)

russh / russh-sftp
- russh 0.63.3 → 0.65.0,russh-sftp 3.0.0 → 3.0.1
- 0.65.0 仍钉 rsa 0.10.0-rc.18,与 quickjs-jit-stdlib 的 rsa 0.10.0-rc.19 冲突,
  继续用 fork feigeCode/russh 的 tag v0.65.0-navop.1(只改 rsa/pkcs1 版本,
  pkcs8 处改取 RsaPrivateKeyRef 以适配 pkcs1 rc.5 的泛型化)
- server::Handler::auth_publickey 改用 VerifiedPublicKey<'_>

验证
- RUSTFLAGS="-D warnings" cargo check --workspace 通过
- cargo test 覆盖 core、one_ui、markdown-editor、db_view、redis_view、
  terminal_view、ai_chat_view、notes、ssh、sftp、universal-plugins 全绿
2026-10-27 18:53:54 +08:00
胡飞 93701c5301 checkpoint: before creating branch feat/issue-313-sql-library 2026-10-10 22:06:24 +08:00
胡飞 76cb55f6f8 style: 本机 rustfmt 重排 52 个文件(无逻辑改动)
本机 rustfmt 与仓库基线版本不同,`cargo fmt` 在整仓重排了 52 个文件:主要是
`pub mod` / `use` 的排序与少量换行,与本次 SSH 修复无逻辑关联。

已核对:在 HEAD 的临时 worktree 里重跑一遍 rustfmt,它单独改动出来的文件集合
与这 52 个完全一致(两个方向都无差异)⇒ 这些文件相对 HEAD 只差格式化,不含
其它未提交改动。
2026-10-09 10:58:23 +08:00
German Skalaukhov da75168fd3 fix: cargo tests 2026-09-30 16:22:25 +03:00
German Skalaukhov 8e6be90e1e feat: ssh agent frowarding 2026-09-30 11:52:00 +03:00
胡飞 08509b085c feat(ssh): 支持「密码 + 密钥」组合认证(MFA password,publickey)
防火墙、交换机等设备配置 AuthenticationMethods password,publickey 后,客户端必须在
同一条连接上依次通过两个因素。原来的单选认证方式无法表达这种组合,凭据引用还会拒绝
密码与私钥同时出现,于是这类设备只能报「密码认证失败 / 公钥认证失败」。

- ssh:新增 SshAuth::Chain 与 authenticate_with_chain 编排器。先发一次 none 探测拿到
  服务器的 remaining_methods,再交给服务器决定因素顺序,因此
  password,publickey 与 publickey,password 两种设备都能登录;硬失败即停,不做方法
  轮询(避免设备掐断连接),轮次上限 6。链内只接受密码与私钥,遇到 SSH Agent /
  Pageant / 自动公钥直接报错,不静默降级。单因素链退化为原有路径,行为零变化。
- core:SshAuthMethod::Chain、contains_password/contains_private_key;
  tunnel_auth_fields 把链摊平成 auth_type=password_and_private_key;
  凭据解析不再拒绝「密码 + 私钥」同时引用,改为组装认证链。
- 表单:新增「密码 + 密钥」认证方式(目标机与跳板机各一套单选项与字段)。该选项只由
  手工选择进入,不进 ALL/TUNNEL,避免数据库隧道等入口出现没有对应字段的坏选项;
  凭据选择器的能力集随所选认证方式变化。
- 运行时:terminal(含 MFA 回调与运行时密码注入)、sftp、sftp_transfer、
  port_forwarding、navop_runtime、connection_tunnel、redis-runtime 全部透传 Chain;
  数据库隧道复用组合认证连接时缺因素直接报错,不再降级成「密码」。
- 文案:ssh / sftp / connection_form / terminal_view / main 五处 locale 的
  en、zh-CN、zh-HK。
- 测试:ssh crate 新增假服务器链式认证用例(两种顺序、乱序方法列表、密码 + 密钥 +
  验证码);补表单能力映射、存储序列化向后兼容、隧道与凭据解析回归测试。
2026-09-26 13:00:53 +08:00
胡飞 31be6dd604 fix(ssh): 认证阶段断开可诊断,设备掐断 keyboard-interactive 时自动降级
交换机/防火墙场景下 navop 只报 `Unable to receive more messages from the channel`
(russh RecvError)或裸 `Disconnected`,报错里看不出真因,也不会自愈:

- ssh.rs:password / none 探测 / keyboard-interactive start、restart、respond 五处认证
  往返补 context;收到 InfoRequest 时记录 debug 日志,避免只剩一个裸传输错误
- ssh.rs:实现 `Handler::disconnected`,把设备给出的 `SSH_MSG_DISCONNECT` 原因码与文本
  以 warn 输出(russh 默认实现只在 debug 打印,设备侧原因此前完全丢失)
- ssh_backend.rs:识别认证阶段的 RecvError 并补充排查提示(密码被拒 / 账号已登录、
  VTY 并发达上限 / RADIUS、TACACS、LDAP 不可达 / 设备认证超时短于登录往返)
- ssh_backend.rs:会话通道建立失败时若传输层已被设备断开,同样重建连接并降级为单个
  裸交互 channel。原先只认 `probe_killed_transport`,而它取决于本地 transport 状态,
  与设备的 FIN 存在竞态:抢到就重建成功,没抢到只报 `Disconnected` 且不重连
- terminal.rs:新增会话级降级兜底——设备在 keyboard-interactive 往返中掐断传输层时,
  改用纯密码认证重试一次;判定收敛到 `should_retry_ssh_without_keyboard_interactive`,
  降级只在本次会话内生效,连接参数重新应用时复位,因此一次连接序列最多降级一次
- locales:修正「服务器需要 MFA/二次认证」的误导表述,改为「当前认证方式被拒绝 +
  服务器要求 keyboard-interactive」并提示先确认凭据;双因素 tooltip 补充自动降级说明

验证:`cargo test -p ssh -p terminal --lib`(151 / 513 通过,含 3 个新增用例:
RecvError 提示包裹、keyboard-interactive 判定、降级触发条件);`cargo check -p
terminal_view` 通过;`rustfmt --check` 仅剩 ssh_backend.rs 两处既有偏差;
`cargo clippy -p terminal --all-targets` 无新增告警。
2026-09-24 14:58:15 +08:00
胡飞 ebf8fc5054 fix(ssh): 兼容老设备的非规范 mpint 主机公钥
- 老设备(华为 VRP 系等)会在 `ssh-rsa` 主机公钥的 e/n 里带多余的前导 `0x00`,
  RFC 4251 § 5 禁止该编码,但 OpenSSH 读取对端报文时会裁掉前导零而不是报错。
  navop 侧此前直接失败,用户看到 `Connection Lost` + `SshKey: `mpint` encoding
  invalid`(连打 2~3 遍,是错误链被 `{:#}` 打平)。
- 通过 `[patch.crates-io]` 挂 ssh-encoding fork(tag `ssh-encoding/v0.3.0-navop.1`,
  仓库 feigeCode/SSH):`Decode for Mpint` 改为归一化(裁掉多余前导零、必要时补回
  一个符号字节),负数与已规范编码逐字节保持不变;`Mpint::from_bytes` 仍严格,
  本地构造的值继续受 RFC 4251 约束。
- 新增 `crates/ssh/tests/legacy_hostkey_mpint.rs`:非规范 blob 可解析、解析出的
  e/n 数值不变、规范编码不受影响。
- 该 patch 是临时的:上游 RustCrypto/SSH 接受改动后即可摘除。

验证:
- `cargo test -p ssh --test legacy_hostkey_mpint` → 3 passed
- `cargo test -p ssh` → 全绿
- 变异验证:把 patch 指向 fork 里未打补丁的 rev,上述测试报
  `Encoding(MpintEncoding)` 失败,证明 patch 确实必要
2026-09-23 14:28:09 +08:00
胡飞 5a9a08c229 fix(ssh): MFA 优先走 keyboard-interactive,密码不再被当作验证码应答
PAM 栈要求「先验证码、后密码」时,password 方法无法区分各个提示的内容:
sshd 会把保存的密码当作第一个提示(验证码)的应答提交,服务器记一次无效
验证码后,本次认证就再无机会让用户输入验证码,客户端只拿到
auth_keyboard_interactive_failed,验证码输入框也不会出现(issue #284)。

连接启用了 MFA 回调时改为:

- 先用 RFC 4252 的 "none" 方法探测服务器是否提供 keyboard-interactive,
  sshd 不把该探测记为一次认证失败;
- 服务器提供该方法则先走 keyboard-interactive:验证码由用户输入,密码仍在
  password 提示处用保存的凭据应答;
- 服务器拒绝了用户实际作答的验证码 → 直接报 MFA 失败(重试没有意义);
- 服务器从未下发提示(如 AuthenticationMethods password,keyboard-interactive
  要求先完成密码)→ 回退到原有密码认证顺序,必要时再由密码结果联动
  keyboard-interactive;
- 服务器未提供该方法、或连接未启用 MFA 回调 → 保持原有的密码认证顺序。

新增 crates/ssh/tests/mfa_verification_code_order.rs,用假 MFA 服务器复刻
「password 方法把密码当成验证码」的服务端行为,覆盖验证码优先、无
keyboard-interactive 回退、password,keyboard-interactive 链路三种场景;
修复前该测试复现 issue #284(先发 Password,随后 keyboard-interactive 直接失败)。

Refs #284
2026-09-22 19:58:12 +08:00
胡飞 e0bfa684be fix(ssh): give kex compatibility tests more connect-timeout headroom 2026-09-09 21:00:25 +08:00
胡飞 3d340b0bd4 feat(known-hosts): add trusted host management view 2026-09-08 22:21:35 +08:00
胡飞 1b3d03f6ec Bump v0.15.2 2026-08-31 23:02:35 +08:00
胡飞 77f39ecff0 style: apply rustfmt formatting across crates 2026-08-29 12:06:28 +08:00
胡飞 49b456e675 feat(terminal): runtime SSH shell integration without remote writes
Replace the persistent remote install (exec-channel script that wrote
~/.config/onetcli/shell_integration.sh and managed blocks into rc files)
with a meatshell-style runtime PTY injection:

- Read-only probe on a separate exec channel confirms bash/zsh before
  injecting; ash/fish/restricted CLIs fall back to a plain shell.
- After the first output chunk (login expect complete), the integration
  script is injected as a single line via ANSI-C quoted eval with a
  leading space (history ignorespace) and bash history -d self-cleanup.
- Echo of the injected command is suppressed until the private
  OSC 1337;ShellIntegrationReady=1 marker; OSC 133/7/1337 protocol is
  preserved, so prompt readiness, cwd tracking, and command recording
  keep working.
- Terminal input and exec requests are deferred while injecting; a 5s
  timeout sends Ctrl+C and degrades to a plain terminal.
- Sessions that still carry legacy rc blocks are detected via an early
  OSC 133;B and skip injection.
- Drop the session-bound ShellIntegrationSetup cache; keep the explicit
  uninstall path as one-shot cleanup for legacy leftovers.
- Remove the "disable shell integration" form toggle (runtime injection
  no longer writes remote files); rework the form section into a legacy
  cleanup card.
- Add a #[ignore] live integration test (NAVOP_LIVE_SSH env) verifying
  probe -> inject -> echo suppression -> 133;B readiness -> command
  recording -> zero remote filesystem changes, with md5 snapshots
  before/after.
2026-08-28 14:18:05 +08:00
胡飞 32a3a2c973 feat(terminal): add background transfer progress 2026-08-26 16:41:44 +08:00
胡飞 a376b01dc6 style(core): 优化代码格式和导入顺序整理
- 调整 core 模块中 use 导入的顺序,使代码风格统一
- 格式化连接排序相关函数,提升代码可读性
- 优化 RemoteDesktopForm 中连接测试结果的匹配代码格式
- 格式化 windows_native_shutdown 模块中函数调用的换行
- 统一 ssh 模块中错误处理和测试断言的代码排版
- 修复连接导入相关模块中的未对齐和多余空白
- 完善对异步任务错误处理的格式,增强错误提示清晰度
- 调整 home_tab 和 connection_sort 模块的代码换行以符合风格规范
2026-08-24 22:10:19 +08:00
胡飞 b3d62f0a7b chore(deps): 更新依赖版本以提升安全性和功能
- 将clickhouse依赖版本从0.14.1升级到0.15.1
- 将sqlparser依赖版本从0.60.0升级到0.62.0
- 将russh依赖版本从0.62.4升级到0.63.1
- 将russh-sftp依赖版本从2.3.0升级到2.4.0
2026-08-24 20:54:40 +08:00
ariesshen 21c4e6f7a3 feat(ssh): add opt-in compatibility support for old SSH servers
- 支持老旧 SSH 设备的 1024 位 DH 组协商
- 调整 GEX 参数与 KEX 顺序,避免 Key exchange init failed
- 补充真实连接测试与错误提示
2026-08-24 16:08:47 +08:00
泡芙 d5522e0887 fix(ssh): 修复 windows_agent_backend_for_auth 未使用警告,收窄为仅测试编译 2026-08-23 19:02:53 +08:00
胡飞 57da0435a9 feat(ssh): add Pageant authentication 2026-08-23 09:44:22 +08:00
胡飞 a6e4fc8be4 feat(ssh): add opt-in support for legacy ssh-dss host keys 2026-08-20 15:27:48 +08:00
胡飞 893c5cdfd4 fix(terminal): preserve buffers and continue MFA auth 2026-08-12 10:17:24 +08:00
胡飞 438f1c3c68 fix(ssh): preserve full connection errors 2026-08-07 13:29:21 +08:00
胡飞 53a1047157 feat(ssh): require confirmation before accepting changed host keys 2026-08-06 17:56:55 +08:00
胡飞 fea22fbd16 fix(ssh): hint when legacy kex is required 2026-08-03 12:10:26 +08:00
胡飞 cad1e39201 feat(ssh): add opt-in legacy algorithm support
Add a per-connection legacy KEX toggle that defaults to disabled, propagate it through SSH/SFTP and connection pooling, and prioritize trusted host-key algorithms without weakening verification.
2026-08-03 10:40:31 +08:00
胡飞 8374448e7b Merge branch 'dev' into feat/terminal-optimization-rework 2026-07-31 09:50:22 +08:00
胡飞 c4cdd182a8 feat(port-forwarding): add SSH remote port forwarding 2026-07-30 22:33:12 +08:00
胡飞 b9acf00fc8 feat(terminal): improve SSH trust and reconnect behavior 2026-07-30 22:10:21 +08:00
胡飞 a19db35e73 fix(ssh): scope transport invalidation to client generation 2026-07-27 06:51:24 +08:00
胡飞 ac090f123d feat(ssh): add application session service 2026-07-27 05:49:46 +08:00
胡飞 efe9c076e1 feat(ssh): reap idle session generations 2026-07-27 03:06:45 +08:00
胡飞 d026738b7a feat(ssh): add generation-bound session leases 2026-07-27 02:03:54 +08:00
胡飞 0038747e96 feat(ssh): add single-flight session registry 2026-07-27 01:28:38 +08:00
胡飞 7dc2452401 feat(ssh): define secure connection keys 2026-07-27 00:51:51 +08:00
胡飞 003719b425 fix(ssh): verify server host keys 2026-07-26 18:28:17 +08:00
胡飞 4bfa7d8456 feat(ssh): add shared host-key verifier 2026-07-26 18:12:05 +08:00
胡飞 062df0ca62 fix(ssh): reload latest config on reconnect 2026-07-25 16:47:59 +08:00
胡飞 7835005afb chore(ssh): upgrade russh dependencies 2026-07-25 13:49:25 +08:00
胡飞 f898b23eb4 feat(ssh): 支持 SSH X11 转发
基于 X.Org 公开的 X11 协议规范独立实现:

- 新增 x11_forwarding crate:DISPLAY 解析并在解析期求出本机端点
  (含 macOS XQuartz launchd 套接字)、迭代器风格 Xauthority 读取与
  按匹配度排序选条目、定长 16 字节 MIT-MAGIC-COOKIE-1 类型、setup
  报文"解码-校验-重编码"(read_exact 两阶段精确读取,不过量消费)、
  按 fake cookie 路由的连接级授权表(dashmap)、回连通道桥接运行时
- ssh crate:SshConnectConfig 增加 x11_forwarding 开关;连接建立时探测
  本机 X server(DISPLAY 缺失时回退 launchctl getenv DISPLAY),失败
  仅告警降级;RusshHandler 实现 server_channel_open_x11,校验 fake
  cookie 后换成本机真实 cookie 再桥接,未校验字节不到达本机 X server
- terminal:交互 shell 在 pty 之后、shell 之前发送 x11-req,服务端拒绝
  (如未开 X11Forwarding)时撤销授权并告警,不影响终端使用
- 连接配置与 SSH 表单新增 X11 转发开关(en/zh-CN/zh-HK),sftp/隧道等
  非交互连接固定关闭
2026-07-23 21:03:53 +08:00
胡飞 55a4ee25c0 fix(ci): isolate ssh key discovery tests 2026-07-19 06:25:59 +08:00
胡飞 8ef141fde6 fix(ci): remove remaining platform assumptions 2026-07-19 03:15:57 +08:00
胡飞 71692c5a4a fix(ssh): add transparent legacy kex fallback 2026-07-16 21:44:51 +08:00
胡飞 ef04fb8877 fix(port-forwarding): keep tunnels alive and record traffic 2026-07-13 17:46:54 +08:00
胡飞 e00821404a fix(port-forwarding): polish activity and shutdown 2026-07-13 14:28:52 +08:00
胡飞 382ce6007b feat: 支持数据库远程桌面代理与终端 profile 2026-07-11 07:01:47 +08:00
胡飞 20ac487e13 feat(proxy): 添加通用本地代理隧道 2026-07-10 22:55:21 +08:00
胡飞 eb83634037 feat: support synced ssh private key content 2026-07-07 11:25:10 +08:00
胡飞 0933290cd6 Add port forwarding connections 2026-06-22 08:04:10 +08:00
胡飞 c9f96c4324 feat(ssh): 支持keyboard-interactive多因素认证(MFA)并在跳板机登录中集成
- 在ssh连接配置中添加keyboard_interactive_responder字段支持MFA回调
- 实现keyboard-interactive认证流程,包括提示请求与响应处理逻辑
- 扩展ssh认证策略自动判断并支持keyboard-interactive认证
- 新增多语言支持,增加MFA相关的国际化文案
- 在跳板机认证中集成MFA支持,UI新增跳板机MFA表单填写界面
- 跳板机MFA表单支持动态请求提示和用户输入响应管理
- 添加跳板机MFA验证结果标记和表单错误处理逻辑
- 测试覆盖keyboard-interactive认证流程及响应处理器行为
- 更新相关依赖,支持异步trait以实现响应器接口异步处理
2026-04-30 13:27:07 +08:00