-
Notifications
You must be signed in to change notification settings - Fork 115
fix: send SSH_MSG_DISCONNECT on KEX failure #1091
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5332,6 +5332,11 @@ static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) | |
| ret = ssh->error; | ||
| } | ||
| } | ||
| /* RFC 4253 11.1: best-effort SSH_MSG_DISCONNECT on negotiation failure. */ | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 [Medium] Missing regression coverage for the new disconnect side effect The PR adds observable behavior: negotiation match failures should now send Recommendation: Add a regression test using a send-capture IO callback for at least one negotiation mismatch path, and assert that the emitted packet is |
||
| if (ret == WS_MATCH_KEX_ALGO_E || ret == WS_MATCH_KEY_ALGO_E || | ||
| ret == WS_MATCH_ENC_ALGO_E || ret == WS_MATCH_MAC_ALGO_E) { | ||
| (void)SendDisconnect(ssh, WOLFSSH_DISCONNECT_KEY_EXCHANGE_FAILED); | ||
|
Comment on lines
+5335
to
+5338
|
||
| } | ||
| WLOG(WS_LOG_DEBUG, "Leaving DoKexInit(), ret = %d", ret); | ||
| return ret; | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟠 [High] Disconnect can be followed by another KEX packet during rekey failure
🚫 BLOCK
bugThe new
SendDisconnect()call is placed insideDoKexInit(), but the production caller still continues its post-DoKexInit()rekey send path based only onssh->isKeying.DoKexInit()setsWOLFSSH_PEER_IS_KEYINGbefore negotiation completes, so on a post-auth rekey (connectState == CONNECT_SERVER_CHANNEL_REQUEST_DONE) a host-key, cipher, or MAC mismatch can sendSSH_MSG_DISCONNECThere and then return toDoPacket(), which can immediately callSendKexDhInit()orSendKexDhGexRequest()becauseretis not checked. That means the PR can emit a key-exchange packet after the disconnect it just added, which breaks the intended terminate-on-negotiation-failure behavior.Recommendation: Gate the rekey response in
DoPacket()on successfulDoKexInit()completion (e.g.if (ret == WS_SUCCESS && ssh->isKeying && ssh->connectState == CONNECT_SERVER_CHANNEL_REQUEST_DONE)) so no follow-on KEX response is emitted afterDoKexInit()returns a negotiation-failure error.