Skip to content

Commit e7bb6de

Browse files
ssh: keep a successful rekey trigger out of ssh->error
- wolfSSH_TriggerKeyExchange() writes ssh->error only when SendKexInit() fails. It runs from HighwaterCheck() inside wolfSSH_SendPacket(), so writing WS_SUCCESS there erased what the pass the mark fired on had already reported. - test_TriggerKeyExchangeKeepsError() seeds ssh->error and checks a rekey that starts cleanly leaves it alone.
1 parent 238168a commit e7bb6de

2 files changed

Lines changed: 52 additions & 2 deletions

File tree

src/ssh.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,8 +1262,11 @@ int wolfSSH_TriggerKeyExchange(WOLFSSH* ssh)
12621262
if (ret == WS_SUCCESS && SendAfterDisconnect(ssh))
12631263
ret = WS_FATAL_ERROR;
12641264

1265-
if (ret == WS_SUCCESS)
1266-
ret = ssh->error = SendKexInit(ssh);
1265+
if (ret == WS_SUCCESS) {
1266+
ret = SendKexInit(ssh);
1267+
if (ret != WS_SUCCESS)
1268+
ssh->error = ret;
1269+
}
12671270

12681271
WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_TriggerKeyExchange(), ret = %d", ret);
12691272
return ret;

tests/unit.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7174,6 +7174,46 @@ static int test_StreamReadHeadOpenFailed(void)
71747174
}
71757175
#endif /* NO_WOLFSSH_CLIENT */
71767176

7177+
#ifndef NO_WOLFSSH_CLIENT
7178+
/* A rekey that starts cleanly leaves ssh->error alone. It runs from
7179+
* HighwaterCheck() inside wolfSSH_SendPacket(), so writing WS_SUCCESS there
7180+
* would erase what the pass the mark fired on had already reported. */
7181+
static int test_TriggerKeyExchangeKeepsError(void)
7182+
{
7183+
WOLFSSH_CTX* ctx = NULL;
7184+
WOLFSSH* ssh = NULL;
7185+
int result = 0;
7186+
int ret;
7187+
7188+
ctx = wolfSSH_CTX_new(WOLFSSH_ENDPOINT_CLIENT, NULL);
7189+
if (ctx == NULL)
7190+
return -1795;
7191+
wolfSSH_SetIOSend(ctx, CountIoSend);
7192+
wolfSSH_SetIORecv(ctx, PacketIoRecv);
7193+
7194+
ssh = wolfSSH_new(ctx);
7195+
if (ssh == NULL) { result = -1796; goto done; }
7196+
7197+
/* The status the pass was carrying when the mark fired. */
7198+
ssh->error = WS_CHANNEL_CLOSED;
7199+
7200+
ret = wolfSSH_TriggerKeyExchange(ssh);
7201+
if (ret != WS_SUCCESS) { result = -1797; goto done; }
7202+
if (wolfSSH_get_error(ssh) != WS_CHANNEL_CLOSED) {
7203+
result = -1798;
7204+
goto done;
7205+
}
7206+
7207+
done:
7208+
s_recvPkt = NULL;
7209+
s_recvPktSz = 0;
7210+
s_recvPktOff = 0;
7211+
wolfSSH_free(ssh);
7212+
wolfSSH_CTX_free(ctx);
7213+
return result;
7214+
}
7215+
#endif /* NO_WOLFSSH_CLIENT */
7216+
71777217

71787218
/* A peer may half-close its channel before it makes its shell/exec/subsystem
71797219
* request, RFC 4254 section 5.3. DoChannelEof() reports that as WS_EOF, and
@@ -20028,6 +20068,13 @@ int wolfSSH_UnitTest(int argc, char** argv)
2002820068
(unitResult == 0 ? "SUCCESS" : "FAILED"));
2002920069
testResult = testResult || unitResult;
2003020070

20071+
#ifndef NO_WOLFSSH_CLIENT
20072+
unitResult = test_TriggerKeyExchangeKeepsError();
20073+
printf("TriggerKeyExchangeKeepsError: %s\n",
20074+
(unitResult == 0 ? "SUCCESS" : "FAILED"));
20075+
testResult = testResult || unitResult;
20076+
#endif
20077+
2003120078
unitResult = test_StreamReadExtDataHeadChannel();
2003220079
printf("StreamReadExtDataHeadChannel: %s\n",
2003320080
(unitResult == 0 ? "SUCCESS" : "FAILED"));

0 commit comments

Comments
 (0)