mirror of https://github.com/wolfSSL/wolfssh.git
ssh: add a rekey-state accessor
- wolfSSH_RekeyPending() reports whether a key exchange is in flight, returning 0 for a NULL session so a caller may test it directly in a loop condition. - the wolfSSH_worker() block in ssh.h names it as the way to ask, alongside wolfSSH_OutputPending(). - tests/regress.c covers each keying bit alone, both together, and a NULL session for both predicates. - tests/testsuite.c drops its wolfSSH_OutputPending() call; a public function without a WOLFSSH_API prototype fails -Wmissing-prototypes in src/ssh.c, so the call proved nothing the build did not.pull/1260/head
parent
74491247cb
commit
cb902fa0f7
|
|
@ -4715,6 +4715,12 @@ int wolfSSH_OutputPending(const WOLFSSH* ssh)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int wolfSSH_RekeyPending(const WOLFSSH* ssh)
|
||||||
|
{
|
||||||
|
return (ssh != NULL && ssh->isKeying != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef WOLFSSH_FWD
|
#ifdef WOLFSSH_FWD
|
||||||
|
|
||||||
int wolfSSH_CTX_SetFwdCb(WOLFSSH_CTX* ctx,
|
int wolfSSH_CTX_SetFwdCb(WOLFSSH_CTX* ctx,
|
||||||
|
|
|
||||||
|
|
@ -5893,6 +5893,39 @@ static void TestChannelGetSessionGrantedAccessor(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Covers each keying bit alone, both together, and a NULL session. */
|
||||||
|
static void TestRekeyPendingAccessor(void)
|
||||||
|
{
|
||||||
|
WOLFSSH_CTX* ctx;
|
||||||
|
WOLFSSH* ssh;
|
||||||
|
|
||||||
|
AssertIntEQ(wolfSSH_RekeyPending(NULL), 0);
|
||||||
|
AssertIntEQ(wolfSSH_OutputPending(NULL), 0);
|
||||||
|
|
||||||
|
ctx = wolfSSH_CTX_new(WOLFSSH_ENDPOINT_CLIENT, NULL);
|
||||||
|
AssertNotNull(ctx);
|
||||||
|
ssh = wolfSSH_new(ctx);
|
||||||
|
AssertNotNull(ssh);
|
||||||
|
|
||||||
|
AssertIntEQ(wolfSSH_RekeyPending(ssh), 0);
|
||||||
|
|
||||||
|
ssh->isKeying = WOLFSSH_PEER_IS_KEYING;
|
||||||
|
AssertTrue(wolfSSH_RekeyPending(ssh) != 0);
|
||||||
|
|
||||||
|
ssh->isKeying = WOLFSSH_SELF_IS_KEYING;
|
||||||
|
AssertTrue(wolfSSH_RekeyPending(ssh) != 0);
|
||||||
|
|
||||||
|
ssh->isKeying = WOLFSSH_SELF_IS_KEYING | WOLFSSH_PEER_IS_KEYING;
|
||||||
|
AssertTrue(wolfSSH_RekeyPending(ssh) != 0);
|
||||||
|
|
||||||
|
ssh->isKeying = 0;
|
||||||
|
AssertIntEQ(wolfSSH_RekeyPending(ssh), 0);
|
||||||
|
|
||||||
|
wolfSSH_free(ssh);
|
||||||
|
wolfSSH_CTX_free(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* A username change after the first userauth request must end the session. */
|
/* A username change after the first userauth request must end the session. */
|
||||||
static void TestUsernameChangeDisconnects(void)
|
static void TestUsernameChangeDisconnects(void)
|
||||||
{
|
{
|
||||||
|
|
@ -16038,6 +16071,7 @@ int main(int argc, char** argv)
|
||||||
TestChannelReqSubsysCallbackRuns();
|
TestChannelReqSubsysCallbackRuns();
|
||||||
TestSessionReqCallbackSeesCommandSz();
|
TestSessionReqCallbackSeesCommandSz();
|
||||||
TestChannelGetSessionGrantedAccessor();
|
TestChannelGetSessionGrantedAccessor();
|
||||||
|
TestRekeyPendingAccessor();
|
||||||
TestMalformedSessionRequestSkipsCallback();
|
TestMalformedSessionRequestSkipsCallback();
|
||||||
TestSessionReqCallbackMayFreeChannel();
|
TestSessionReqCallbackMayFreeChannel();
|
||||||
TestAppChannelsAcceptKeepsStopWithPendingOutput();
|
TestAppChannelsAcceptKeepsStopWithPendingOutput();
|
||||||
|
|
|
||||||
|
|
@ -241,13 +241,6 @@ int wolfSSH_TestsuiteTest(int argc, char** argv)
|
||||||
|
|
||||||
wolfSSH_Init();
|
wolfSSH_Init();
|
||||||
|
|
||||||
/* Linked against the installed library, so this also proves
|
|
||||||
* wolfSSH_OutputPending() is exported and not hidden. */
|
|
||||||
if (wolfSSH_OutputPending(NULL) != 0) {
|
|
||||||
fprintf(stderr, "wolfSSH_OutputPending(NULL) was not zero\n");
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,2)
|
#if defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,2)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
|
||||||
|
|
@ -7189,6 +7189,8 @@ static int test_WorkerKeyingReportsRekey(void)
|
||||||
if (reportedId != ch->channel) { result = -1818; goto done; }
|
if (reportedId != ch->channel) { result = -1818; goto done; }
|
||||||
/* The flush ran and drained, which the rekey report is gated on. */
|
/* The flush ran and drained, which the rekey report is gated on. */
|
||||||
if (ssh->outputBuffer.length != 0) { result = -1817; goto done; }
|
if (ssh->outputBuffer.length != 0) { result = -1817; goto done; }
|
||||||
|
/* The predicate answers the same pass the status reports. */
|
||||||
|
if (!wolfSSH_RekeyPending(ssh)) { result = -1819; goto done; }
|
||||||
|
|
||||||
done:
|
done:
|
||||||
s_recvPkt = NULL;
|
s_recvPkt = NULL;
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,8 @@ WOLFSSH_API void wolfSSH_free(WOLFSSH* ssh);
|
||||||
* the peer's disconnect, which is how most sessions end.
|
* the peer's disconnect, which is how most sessions end.
|
||||||
* To ask whether a write is still owed, call wolfSSH_OutputPending() rather
|
* To ask whether a write is still owed, call wolfSSH_OutputPending() rather
|
||||||
* than reading a status: it answers after any return, including a success.
|
* than reading a status: it answers after any return, including a success.
|
||||||
|
* To ask whether a key exchange is in flight, call wolfSSH_RekeyPending()
|
||||||
|
* rather than reading a status: it answers after any return.
|
||||||
*
|
*
|
||||||
* For WS_CHAN_RXD, WS_EXTDATA, WS_EOF, WS_SUCCESS and a WS_REKEYING that
|
* For WS_CHAN_RXD, WS_EXTDATA, WS_EOF, WS_SUCCESS and a WS_REKEYING that
|
||||||
* displaced one of those, channelId (when not NULL) names the channel the
|
* displaced one of those, channelId (when not NULL) names the channel the
|
||||||
|
|
@ -118,6 +120,11 @@ WOLFSSH_API int wolfSSH_GetLastRxId(WOLFSSH* ssh, word32* channelId);
|
||||||
/* Returns nonzero if a write is still owed. Session state */
|
/* Returns nonzero if a write is still owed. Session state */
|
||||||
WOLFSSH_API int wolfSSH_OutputPending(const WOLFSSH* ssh);
|
WOLFSSH_API int wolfSSH_OutputPending(const WOLFSSH* ssh);
|
||||||
|
|
||||||
|
/* Returns nonzero while a key exchange is in flight, and 0 otherwise,
|
||||||
|
* including when ssh is NULL. Only NEWKEYS from both sides clears it, so a
|
||||||
|
* peer that abandons the exchange leaves it set. */
|
||||||
|
WOLFSSH_API int wolfSSH_RekeyPending(const WOLFSSH* ssh);
|
||||||
|
|
||||||
WOLFSSH_API int wolfSSH_set_fd(WOLFSSH* ssh, WS_SOCKET_T fd);
|
WOLFSSH_API int wolfSSH_set_fd(WOLFSSH* ssh, WS_SOCKET_T fd);
|
||||||
WOLFSSH_API WS_SOCKET_T wolfSSH_get_fd(const WOLFSSH* ssh);
|
WOLFSSH_API WS_SOCKET_T wolfSSH_get_fd(const WOLFSSH* ssh);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue