Skip to content

Merge upstream v2.15.0#3

Merged
GT-610 merged 77 commits intolollipopkit:masterfrom
GT-610:merge-v2.15.0
Mar 30, 2026
Merged

Merge upstream v2.15.0#3
GT-610 merged 77 commits intolollipopkit:masterfrom
GT-610:merge-v2.15.0

Conversation

@GT-610
Copy link
Copy Markdown
Collaborator

@GT-610 GT-610 commented Mar 30, 2026

Summary by CodeRabbit

发布说明

  • 新功能

    • 添加 X11 转发与 SSH 代理转发支持;新增可配置的客户端标识(ident)并导出代理相关 API
    • 支持在会话中请求 X11 与代理转发
  • Bug 修复

    • 改进 SSH 版本协商与错误传播(认证中止错误包含底层原因)
    • 修复 SFTP 编解码与扩展载荷原样保留
    • 规范化 HTTP 响应行与 Transfer-Encoding 处理
  • 文档

    • 更新 README、CHANGELOG 与忽略规则
  • 测试

    • 添加大量单元与集成测试覆盖新特性与回归
  • Chore

    • 包版本号升级并新增 CI/测试配置文件(覆盖、测试超时等)

alexander-irion and others added 30 commits March 12, 2025 14:04
When disableHostkeyVerification is set, the verification which is time
consuming in debug mode is omitted.
When a sftp session is created with Client:sftp and on client side
the sshd is killed it caused unhandled exceptions.
…ha2-256-etm@openssh.com", "hmac-sha2-512-etm@openssh.com" algorithms
Add parameter disableHostkeyVerification
Add support for server initiated re-keying
…hm-corrections

Fix implementation of ETM MAC algorithms for SSH transport
…CD-improvements

feat: Implement Automated Publishing via Tag & Disable Dependabot
Early SSH 2.0 implementations often used version 1.99 to indicated SSH 2.0 with fallback to SSH 1.0.

These should be treated as SSH 2.0 for the purposes of this library.
Added SSHAuthAbortError.reason field to propagate the underlying exception so we actually know what happened.

This enables users to handle different error scenarios correctly.
Updated the showcase table to include the NaviTerm title and linked the name and image to the GitHub repository.
Updated alt text for images to improve accessibility and clarity.
vicajilau and others added 17 commits March 20, 2026 10:50
…/pr-139-agent-forwarding

feat: add SSH agent forwarding support
…g-coverage-roadmap

test: increase coverage and organize unit/integration suites
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 30, 2026

📝 Walkthrough

Walkthrough

此 PR 将包版本提升到 2.15.0 并引入多项代码与配置变更:新增 SSH 代理子系统(SSHAgentHandler、SSHKeyPairAgent、SSHAgentChannel)及代理转发请求支持;添加 X11 转发相关 API 与通道类型;在 SSHClient 上暴露并可定制 ident 字段;改进传输关闭时对待处理队列/请求的失败传播并扩展错误类型以携带底层原因;修复 HTTP 响应解析与 SFTP 编码/解码问题;新增并调整大量单元/集成测试;更新项目配置与元文件(.gitignore、codecov.yml、dart_test.yaml、CHANGELOG、README 等)。

Possibly related PRs

  • Merge upstream v2.14.0 #2: 修改了与本次变更相同的消息/常量区域(例如 msg_channel 与 ssh_mac_type),在通道相关常量及临近代码处存在代码级重叠。
  • Sync with upstream #1: 涉及 lib/src/ssh_client.dart 中的传输关闭与客户端行为修改,与本次在 SSHClient、传输关闭和请求失败传播上的变动存在直接代码级关联。
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title 'Merge upstream v2.15.0' directly and accurately reflects the main objective of merging version 2.15.0 upstream changes, as evidenced by the version bump in pubspec.yaml and the comprehensive changelog updates.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

devin-ai-integration[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

…iles

Fixed redundant library declarations in test files and improved error handling logic:
1. Removed redundant library declarations from test files
2. Added a toString method to SSHAuthAbortError
3. Added a failAll method to AsyncQueue to handle pending waits
4. Improved HTTP header validation and RSA signature verification
5. Updated the contributor format in CHANGELOG.md
6. Enhanced the connection closure logic in SSHClient
7. Added validation logic for the ident parameter
coderabbitai[bot]

This comment was marked as resolved.

…nnection is closed

Added a maximum frame size limit for SSHAgentChannel to prevent memory exhaustion

Fixed an issue where the authentication timeout timer was not reset when the connection was closed

Improved error handling to ensure error messages are properly passed when the connection is closed
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
lib/src/ssh_agent.dart (1)

96-104: RSA 回退路径可能忽略客户端请求的签名算法。

_rsaKeyFrom 返回 null 时(即遇到未知的 RSA 密钥类型),代码回退到 identity.sign(data)。但此时 signatureType(由 flags 决定,可能是 SHA-256 或 SHA-512)被忽略,签名可能使用默认的 SHA-1 算法,与客户端请求不符。

建议在回退路径中记录警告日志,或者在签名类型不匹配时返回失败响应。

♻️ 可选的改进方案
   SSHRsaSignature _signRsa(
     SSHKeyPair identity,
     Uint8List data,
     String signatureType,
   ) {
     final key = _rsaKeyFrom(identity);
     if (key == null) {
       final signature = identity.sign(data);
       if (signature is SSHRsaSignature) {
+        // Note: The signature may not use the requested algorithm (signatureType)
+        // since we're falling back to the identity's default signing behavior.
         return signature;
       }
       throw StateError(
           'RSA signing requested but identity produced non-RSA signature: ${signature.runtimeType}');
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/src/ssh_agent.dart` around lines 96 - 104, When _rsaKeyFrom(identity)
returns null, the fallback uses identity.sign(data) but ignores the requested
signatureType/flags and may produce a SHA-1 RSA signature; update the fallback
in the signer code (the block around _rsaKeyFrom, identity.sign, and
SSHRsaSignature) to validate that the produced signature matches the requested
signatureType (derived from flags) and if it does not, either log a warning and
reject/return a failure response or explicitly produce the correct algorithmed
signature; ensure you reference the signatureType/flags when deciding acceptance
so callers receive a matching-algorithm result rather than an incorrect default.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@lib/src/ssh_agent.dart`:
- Around line 96-104: When _rsaKeyFrom(identity) returns null, the fallback uses
identity.sign(data) but ignores the requested signatureType/flags and may
produce a SHA-1 RSA signature; update the fallback in the signer code (the block
around _rsaKeyFrom, identity.sign, and SSHRsaSignature) to validate that the
produced signature matches the requested signatureType (derived from flags) and
if it does not, either log a warning and reject/return a failure response or
explicitly produce the correct algorithmed signature; ensure you reference the
signatureType/flags when deciding acceptance so callers receive a
matching-algorithm result rather than an incorrect default.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: de9f7d0b-3f68-4cdd-b223-89c5e973884c

📥 Commits

Reviewing files that changed from the base of the PR and between 1ce07af and 9646f04.

📒 Files selected for processing (2)
  • lib/src/ssh_agent.dart
  • lib/src/ssh_client.dart

@GT-610 GT-610 merged commit f9c0560 into lollipopkit:master Mar 30, 2026
0 of 2 checks passed
@GT-610 GT-610 deleted the merge-v2.15.0 branch March 30, 2026 10:58
Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

View 13 additional findings in Devin Review.

Open in Devin Review

singleConnection: singleConnection,
x11AuthenticationProtocol: authenticationProtocol,
x11AuthenticationCookie: authenticationCookie,
x11ScreenNumber: screenNumber.toString(),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 X11 screen number encoded as UTF-8 string instead of uint32 per RFC 4254

The new sendX11Req method at lib/src/ssh_channel.dart:143 converts the integer screen number to a string via screenNumber.toString() and passes it to the SSH_Message_Channel_Request.x11 factory. The underlying message encoder at lib/src/message/msg_channel.dart:956 then writes this with writeUtf8() (a length-prefixed string). However, RFC 4254 Section 6.3.1 specifies uint32 x11 screen number — a 4-byte unsigned integer, not a string. On the wire, a string-encoded "0" produces 5 bytes (4-byte length prefix + 1-byte ASCII 0), while a uint32 0 produces 4 bytes. This mismatch means the x11-req message will be malformed when sent to any real SSH server, causing X11 forwarding requests to be rejected or misinterpreted. The roundtrip test passes only because both encode (lib/src/message/msg_channel.dart:956) and decode (lib/src/message/msg_channel.dart:852) use the same wrong string format.

Prompt for agents
The x11 screen number must be encoded as a uint32 per RFC 4254 Section 6.3.1, not as a UTF-8 string. This requires changes in multiple files:

1. In lib/src/message/msg_channel.dart:
   - Change the field type of x11ScreenNumber from String? to int? (line 609)
   - Update the x11 factory constructor parameter type from String to int (line 690)
   - In the decode method (line 852), change reader.readUtf8() to reader.readUint32()
   - In the encode method (line 956), change writer.writeUtf8(x11ScreenNumber!) to writer.writeUint32(x11ScreenNumber!)
   - Update the constructor parameter this.x11ScreenNumber (line 646) accordingly

2. In lib/src/ssh_channel.dart:
   - At line 143, change x11ScreenNumber: screenNumber.toString() to x11ScreenNumber: screenNumber (pass the int directly)

3. In test/src/message/msg_channel_test.dart:
   - At line 199, change x11ScreenNumber: '0' to x11ScreenNumber: 0
   - At line 210, change expect(decoded.x11ScreenNumber, '0') to expect(decoded.x11ScreenNumber, 0)
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

This was referenced Mar 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants