diff --git a/src/wolfsftp.c b/src/wolfsftp.c index 699d1e88..76a74052 100644 --- a/src/wolfsftp.c +++ b/src/wolfsftp.c @@ -711,6 +711,15 @@ int wolfSSH_TestSftpRecvSizeCheck(int sz) { return SFTP_CheckRecvSz(sz); } + + +/* Test hook: exposes the static SendPacketType() so the unit tests can + * check that no request is sent when SFTP negotiation did not succeed. */ +int wolfSSH_TestSftpSendPacketType(WOLFSSH* ssh, byte type, byte* buf, + word32 bufSz) +{ + return SendPacketType(ssh, type, buf, bufSz); +} #endif @@ -6905,8 +6914,15 @@ int SendPacketType(WOLFSSH* ssh, byte type, byte* buf, word32 bufSz) /* reset state for sending data */ wolfSSH_SFTP_buffer_rewind(&state->buffer); + state->state = SFTP_SEND_PACKET; } - state->state = SFTP_SEND_PACKET; + else { + if(!NoticeError(ssh)){ + wolfSSH_SFTP_ClearState(ssh, STATE_ID_SEND); + } + return ret; + } + FALL_THROUGH; case SFTP_SEND_PACKET: diff --git a/tests/api.c b/tests/api.c index 5be9c300..dab36b9d 100644 --- a/tests/api.c +++ b/tests/api.c @@ -6267,6 +6267,32 @@ static void test_wolfSSH_SFTP_SaveOfst(void) } +/* SendPacketType must not send a request when negotiation did not succeed */ +static void test_wolfSSH_SFTP_SendPacketType_negotiate(void) +{ +#ifdef WOLFSSH_TEST_INTERNAL + WOLFSSH_CTX* ctx = NULL; + WOLFSSH* ssh = NULL; + byte payload[4] = { 0x00, 0x01, 0x02, 0x03 }; + int ret; + + AssertNotNull(ctx = wolfSSH_CTX_new(WOLFSSH_ENDPOINT_CLIENT, NULL)); + AssertNotNull(ssh = wolfSSH_new(ctx)); + + ret = wolfSSH_TestSftpSendPacketType(ssh, WOLFSSH_FTP_REALPATH, + payload, (word32)sizeof(payload)); + + /* The SFTP connection was not established, so negotiation cannot succeed. + * SendPacketType() must report that failure instead of returning WS_SUCCESS */ + AssertIntNE(ret, WS_SUCCESS); + + wolfSSH_free(ssh); + wolfSSH_CTX_free(ctx); +#endif /* WOLFSSH_TEST_INTERNAL */ +} + + + #if !defined(NO_FILESYSTEM) && !defined(WOLFSSH_USER_FILESYSTEM) && \ !defined(WOLFSSH_ZEPHYR) @@ -6690,6 +6716,7 @@ static void test_wolfSSH_SFTP_StartPathNotConfined(void) { ; } static void test_wolfSSH_SFTP_SetConfinePath(void) { ; } static void test_wolfSSH_SFTP_SetDefaultPath(void) { ; } static void test_wolfSSH_SFTP_SaveOfst(void) { ; } +static void test_wolfSSH_SFTP_SendPacketType_negotiate(void) { ; } static void test_wolfSSH_SFTP_PutResume(void) { ; } static void test_wolfSSH_SFTP_GetResume(void) { ; } #endif /* WOLFSSH_SFTP && !NO_WOLFSSH_CLIENT && !SINGLE_THREADED */ @@ -8823,6 +8850,7 @@ int wolfSSH_ApiTest(int argc, char** argv) test_wolfSSH_SFTP_SetConfinePath(); test_wolfSSH_SFTP_SetDefaultPath(); test_wolfSSH_SFTP_SaveOfst(); + test_wolfSSH_SFTP_SendPacketType_negotiate(); test_wolfSSH_SFTP_PutResume(); test_wolfSSH_SFTP_GetResume(); diff --git a/wolfssh/wolfsftp.h b/wolfssh/wolfsftp.h index 9b3c9aef..fe0a7a08 100644 --- a/wolfssh/wolfsftp.h +++ b/wolfssh/wolfsftp.h @@ -360,6 +360,8 @@ WOLFSSH_LOCAL void wolfSSH_SFTP_ShowSizes(void); WS_SFTP_FILEATRB* atr, word32* idx); WOLFSSH_API int wolfSSH_TestSftpSendCap(WOLFSSH* ssh, word32 cap); WOLFSSH_API int wolfSSH_TestSftpStallPending(WOLFSSH* ssh, word32 count); + WOLFSSH_API int wolfSSH_TestSftpSendPacketType(WOLFSSH* ssh, byte type, + byte* buf, word32 bufSz); #if !defined(NO_WOLFSSH_SERVER) && !defined(NO_FILESYSTEM) WOLFSSH_API int wolfSSH_SFTP_TestRecvStateInit(WOLFSSH* ssh); WOLFSSH_API const byte* wolfSSH_SFTP_TestRecvReply(WOLFSSH* ssh,