Merge pull request #190 from JacobBarthelmeh/sftp

add test case for wolfSSH_SFTP_SendReadPacket
pull/194/head
John Safranek 2019-08-29 14:29:12 -07:00 committed by GitHub
commit 62335d9a7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 246 additions and 26 deletions

View File

@ -5907,21 +5907,23 @@ int wolfSSH_SFTP_SendReadPacket(WOLFSSH* ssh, byte* handle, word32 handleSz,
state->idx += UINT32_SZ; state->idx += UINT32_SZ;
state->state = STATE_SEND_READ_SEND_REQ; state->state = STATE_SEND_READ_SEND_REQ;
FALL_THROUGH; FALL_THROUGH;
case STATE_SEND_READ_SEND_REQ: case STATE_SEND_READ_SEND_REQ:
WLOG(WS_LOG_SFTP, "SFTP SEND_READ STATE: SEND_REQ"); WLOG(WS_LOG_SFTP, "SFTP SEND_READ STATE: SEND_REQ");
/* send header and type specific data */ /* send header and type specific data */
ret = wolfSSH_stream_send(ssh, state->data, state->idx); ret = wolfSSH_stream_send(ssh, state->data, state->idx);
if (ssh->error == WS_WANT_READ || ssh->error == WS_WANT_WRITE) { if (ret < 0) {
if (ssh->error != WS_WANT_READ &&
ssh->error != WS_WANT_WRITE) {
state->state = STATE_SEND_READ_CLEANUP;
continue;
}
return ret; return ret;
} }
WFREE(state->data, ssh->ctx->heap, DYNTYPE_BUFFER); WFREE(state->data, ssh->ctx->heap, DYNTYPE_BUFFER);
state->data = NULL; state->data = NULL;
if (ret < 0) {
return ret;
}
state->state = STATE_SEND_READ_GET_HEADER; state->state = STATE_SEND_READ_GET_HEADER;
FALL_THROUGH; FALL_THROUGH;
@ -5929,8 +5931,14 @@ int wolfSSH_SFTP_SendReadPacket(WOLFSSH* ssh, byte* handle, word32 handleSz,
WLOG(WS_LOG_SFTP, "SFTP SEND_READ STATE: GET_HEADER"); WLOG(WS_LOG_SFTP, "SFTP SEND_READ STATE: GET_HEADER");
/* Get response */ /* Get response */
if ((ret = SFTP_GetHeader(ssh, &state->reqId, &state->type)) if ((ret = SFTP_GetHeader(ssh, &state->reqId, &state->type))
<= 0) <= 0) {
if (ssh->error != WS_WANT_READ &&
ssh->error != WS_WANT_WRITE) {
state->state = STATE_SEND_READ_CLEANUP;
continue;
}
return WS_FATAL_ERROR; return WS_FATAL_ERROR;
}
state->sz = ret; state->sz = ret;
state->state = STATE_SEND_READ_CHECK_REQ_ID; state->state = STATE_SEND_READ_CHECK_REQ_ID;
@ -5941,7 +5949,9 @@ int wolfSSH_SFTP_SendReadPacket(WOLFSSH* ssh, byte* handle, word32 handleSz,
/* check request ID */ /* check request ID */
if (state->reqId != ssh->reqId) { if (state->reqId != ssh->reqId) {
WLOG(WS_LOG_SFTP, "Bad request ID received"); WLOG(WS_LOG_SFTP, "Bad request ID received");
return WS_FATAL_ERROR; ret = WS_FATAL_ERROR;
state->state = STATE_SEND_READ_CLEANUP;
continue;
} }
else else
ssh->reqId++; ssh->reqId++;
@ -5952,7 +5962,8 @@ int wolfSSH_SFTP_SendReadPacket(WOLFSSH* ssh, byte* handle, word32 handleSz,
state->state = STATE_SEND_READ_FTP_STATUS; state->state = STATE_SEND_READ_FTP_STATUS;
else { else {
WLOG(WS_LOG_SFTP, "Unexpected packet type"); WLOG(WS_LOG_SFTP, "Unexpected packet type");
return WS_FATAL_ERROR; ret = WS_FATAL_ERROR;
state->state = STATE_SEND_READ_CLEANUP;
} }
continue; continue;
@ -5961,12 +5972,19 @@ int wolfSSH_SFTP_SendReadPacket(WOLFSSH* ssh, byte* handle, word32 handleSz,
/* get size of string and place it into out buffer */ /* get size of string and place it into out buffer */
ret = wolfSSH_stream_read(ssh, szFlat, UINT32_SZ); ret = wolfSSH_stream_read(ssh, szFlat, UINT32_SZ);
if (ret < 0) { if (ret < 0) {
if (ssh->error != WS_WANT_READ &&
ssh->error != WS_WANT_WRITE) {
state->state = STATE_SEND_READ_CLEANUP;
continue;
}
return ret; return ret;
} }
ato32(szFlat, &state->sz); ato32(szFlat, &state->sz);
if (state->sz > outSz) { if (state->sz > outSz) {
WLOG(WS_LOG_SFTP, "Server sent more data then expected"); WLOG(WS_LOG_SFTP, "Server sent more data then expected");
return WS_FATAL_ERROR; ret = WS_FATAL_ERROR;
state->state = STATE_SEND_READ_CLEANUP;
continue;
} }
state->state = STATE_SEND_READ_REMAINDER; state->state = STATE_SEND_READ_REMAINDER;
@ -6004,6 +6022,11 @@ int wolfSSH_SFTP_SendReadPacket(WOLFSSH* ssh, byte* handle, word32 handleSz,
ssh->ctx->heap, DYNTYPE_BUFFER); ssh->ctx->heap, DYNTYPE_BUFFER);
ret = wolfSSH_stream_read(ssh, data, state->sz); ret = wolfSSH_stream_read(ssh, data, state->sz);
if (ret < 0) { if (ret < 0) {
if (ssh->error != WS_WANT_READ &&
ssh->error != WS_WANT_WRITE) {
state->state = STATE_SEND_READ_CLEANUP;
continue;
}
return WS_FATAL_ERROR; return WS_FATAL_ERROR;
} }
ret = wolfSSH_SFTP_DoStatus(ssh, state->reqId, data, ret = wolfSSH_SFTP_DoStatus(ssh, state->reqId, data,

View File

@ -25,6 +25,21 @@
#ifdef WOLFSSH_SCP #ifdef WOLFSSH_SCP
#include <wolfssh/wolfscp.h> #include <wolfssh/wolfscp.h>
#endif #endif
#ifdef WOLFSSH_SFTP
#define WOLFSSH_TEST_LOCKING
#define WOLFSSH_TEST_THREADING
#define WOLFSSH_TEST_SERVER
#define WOLFSSH_TEST_ECHOSERVER
#include <wolfssh/test.h>
#include "examples/echoserver/echoserver.h"
#endif
/* for echoserver test cases */
int myoptind = 0;
char* myoptarg = NULL;
#define Fail(description, result) do { \ #define Fail(description, result) do { \
@ -231,6 +246,93 @@ static int ConvertHexToBin(const char* h1, byte** b1, word32* b1Sz,
return 0; return 0;
} }
#ifdef WOLFSSH_SFTP
byte userPassword[256];
static int sftpUserAuth(byte authType, WS_UserAuthData* authData, void* ctx)
{
int ret = WOLFSSH_USERAUTH_INVALID_AUTHTYPE;
if (authType == WOLFSSH_USERAUTH_PASSWORD) {
const char* defaultPassword = (const char*)ctx;
word32 passwordSz;
ret = WOLFSSH_USERAUTH_SUCCESS;
if (defaultPassword != NULL) {
passwordSz = (word32)strlen(defaultPassword);
memcpy(userPassword, defaultPassword, passwordSz);
}
else {
printf("Expecting password set for test cases\n");
return ret;
}
if (ret == WOLFSSH_USERAUTH_SUCCESS) {
authData->sf.password.password = userPassword;
authData->sf.password.passwordSz = passwordSz;
}
}
return ret;
}
/* preforms connection to port, sets WOLFSSH_CTX and WOLFSSH on success
* caller needs to free ctx and ssh when done
*/
static void sftp_client_connect(WOLFSSH_CTX** ctx, WOLFSSH** ssh, int port)
{
SOCKET_T sockFd = WOLFSSH_SOCKET_INVALID;
SOCKADDR_IN_T clientAddr;
socklen_t clientAddrSz = sizeof(clientAddr);
int ret;
char* host = (char*)wolfSshIp;
const char* username = "jill";
const char* password = "upthehill";
if (ctx == NULL || ssh == NULL) {
return;
}
*ctx = wolfSSH_CTX_new(WOLFSSH_ENDPOINT_CLIENT, NULL);
if (*ctx == NULL) {
return;
}
wolfSSH_SetUserAuth(*ctx, sftpUserAuth);
*ssh = wolfSSH_new(*ctx);
if (*ssh == NULL) {
wolfSSH_CTX_free(*ctx);
*ctx = NULL;
return;
}
build_addr(&clientAddr, host, port);
tcp_socket(&sockFd);
ret = connect(sockFd, (const struct sockaddr *)&clientAddr, clientAddrSz);
if (ret != 0){
wolfSSH_free(*ssh);
wolfSSH_CTX_free(*ctx);
*ctx = NULL;
*ssh = NULL;
return;
}
wolfSSH_SetUserAuthCtx(*ssh, (void*)password);
ret = wolfSSH_SetUsername(*ssh, username);
if (ret == WS_SUCCESS)
ret = wolfSSH_set_fd(*ssh, (int)sockFd);
if (ret == WS_SUCCESS)
ret = wolfSSH_SFTP_connect(*ssh);
if (ret != WS_SUCCESS){
wolfSSH_free(*ssh);
wolfSSH_CTX_free(*ctx);
*ctx = NULL;
*ssh = NULL;
return;
}
}
#endif /* WOLFSSH_SFTP */
enum WS_TestEndpointTypes { enum WS_TestEndpointTypes {
TEST_GOOD_ENDPOINT_SERVER = WOLFSSH_ENDPOINT_SERVER, TEST_GOOD_ENDPOINT_SERVER = WOLFSSH_ENDPOINT_SERVER,
@ -529,6 +631,97 @@ static void test_wolfSSH_SCP_CB(void)
#endif /* WOLFSSH_NO_CLIENT */ #endif /* WOLFSSH_NO_CLIENT */
} }
static void test_wolfSSH_SFTP_SendReadPacket(void)
{
#ifdef WOLFSSH_SFTP
func_args ser;
tcp_ready ready;
int argsCount;
const char* args[10];
WOLFSSH_CTX* ctx = NULL;
WOLFSSH* ssh = NULL;
THREAD_TYPE serThread;
WMEMSET(&ser, 0, sizeof(func_args));
argsCount = 0;
args[argsCount++] = ".";
args[argsCount++] = "-1";
#ifndef USE_WINDOWS_API
args[argsCount++] = "-p";
args[argsCount++] = "0";
#endif
ser.argv = (char**)args;
ser.argc = argsCount;
ser.signal = &ready;
InitTcpReady(ser.signal);
ThreadStart(echoserver_test, (void*)&ser, &serThread);
WaitTcpReady(&ser);
sftp_client_connect(&ctx, &ssh, ready.port);
AssertNotNull(ctx);
AssertNotNull(ssh);
{
WS_SFTPNAME* tmp;
WS_SFTPNAME* current;
byte handle[WOLFSSH_MAX_HANDLE];
word32 handleSz = WOLFSSH_MAX_HANDLE;
const char* currentDir = ".";
byte* out = NULL;
int outSz = 18;
const word32 ofst[2] = {0};
current = wolfSSH_SFTP_LS(ssh, (char*)currentDir);
tmp = current;
while (tmp != NULL) {
if ((tmp->atrb.sz[0] > 0) &&
(tmp->atrb.flags & WOLFSSH_FILEATRB_PERM) &&
!(tmp->atrb.per & 0x4000)) {
break;
}
tmp = tmp->next;
}
if (tmp != NULL) {
out = (byte*)malloc(tmp->atrb.sz[0]);
AssertIntEQ(wolfSSH_SFTP_Open(ssh, tmp->fName, WOLFSSH_FXF_READ,
NULL, handle, &handleSz), WS_SUCCESS);
/* read 18 bytes */
if (tmp->atrb.sz[0] >= 18) {
outSz = 18;
AssertIntEQ(wolfSSH_SFTP_SendReadPacket(ssh, handle, handleSz,
ofst, out, outSz), outSz);
}
/* partial read */
outSz = tmp->atrb.sz[0] / 2;
AssertIntEQ(wolfSSH_SFTP_SendReadPacket(ssh, handle, handleSz, ofst,
out, outSz), outSz);
/* read all */
outSz = tmp->atrb.sz[0];
AssertIntEQ(wolfSSH_SFTP_SendReadPacket(ssh, handle, handleSz, ofst,
out, outSz), outSz);
free(out);
wolfSSH_SFTP_Close(ssh, handle, handleSz);
wolfSSH_SFTPNAME_list_free(current);
}
}
AssertIntEQ(wolfSSH_shutdown(ssh), WS_SUCCESS);
wolfSSH_free(ssh);
wolfSSH_CTX_free(ctx);
ThreadJoin(serThread);
#endif
}
#ifdef USE_WINDOWS_API #ifdef USE_WINDOWS_API
static byte color_test[] = { static byte color_test[] = {
0x1B, 0x5B, 0x34, 0x6D, 0x75, 0x6E, 0x64, 0x65, 0x1B, 0x5B, 0x34, 0x6D, 0x75, 0x6E, 0x64, 0x65,
@ -636,6 +829,10 @@ int main(void)
/* SCP tests */ /* SCP tests */
test_wolfSSH_SCP_CB(); test_wolfSSH_SCP_CB();
/* SFTP tests */
test_wolfSSH_SFTP_SendReadPacket();
AssertIntEQ(wolfSSH_Cleanup(), WS_SUCCESS); AssertIntEQ(wolfSSH_Cleanup(), WS_SUCCESS);
return 0; return 0;

View File

@ -18,7 +18,8 @@ endif
tests_unit_test_LDADD = src/libwolfssh.la tests_unit_test_LDADD = src/libwolfssh.la
tests_unit_test_DEPENDENCIES = src/libwolfssh.la tests_unit_test_DEPENDENCIES = src/libwolfssh.la
tests_api_test_SOURCES = tests/api.c tests_api_test_SOURCES = tests/api.c \
examples/echoserver/echoserver.c
tests_api_test_CPPFLAGS = -DNO_MAIN_DRIVER tests_api_test_CPPFLAGS = -DNO_MAIN_DRIVER
if BUILD_SCP if BUILD_SCP
tests_api_test_CPPFLAGS += -DWOLFSSH_SCP tests_api_test_CPPFLAGS += -DWOLFSSH_SCP

View File

@ -164,18 +164,3 @@ int TestsuiteTest(int argc, char** argv)
#endif /* !NO_WOLFSSH_SERVER && !NO_WOLFSSH_CLIENT */ #endif /* !NO_WOLFSSH_SERVER && !NO_WOLFSSH_CLIENT */
void WaitTcpReady(func_args* args)
{
#if defined(_POSIX_THREADS) && !defined(__MINGW32__)
pthread_mutex_lock(&args->signal->mutex);
if (!args->signal->ready)
pthread_cond_wait(&args->signal->cond, &args->signal->mutex);
args->signal->ready = 0; /* reset */
pthread_mutex_unlock(&args->signal->mutex);
#else
(void)args;
#endif
}

View File

@ -741,7 +741,21 @@ static INLINE void FreeTcpReady(tcp_ready* ready)
} }
void WaitTcpReady(func_args*); static INLINE void WaitTcpReady(func_args* args)
{
#if defined(_POSIX_THREADS) && !defined(__MINGW32__)
pthread_mutex_lock(&args->signal->mutex);
if (!args->signal->ready)
pthread_cond_wait(&args->signal->cond, &args->signal->mutex);
args->signal->ready = 0; /* reset */
pthread_mutex_unlock(&args->signal->mutex);
#else
(void)args;
#endif
}
#endif /* WOLFSSH_TEST_LOCKING */ #endif /* WOLFSSH_TEST_LOCKING */