/* test.h * * Copyright (C) 2014-2019 wolfSSL Inc. * * This file is part of wolfSSH. * * wolfSSH is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * wolfSSH is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with wolfSSH. If not, see . */ #pragma once #ifndef _WOLFSSH_TEST_H_ #define _WOLFSSH_TEST_H_ #include #include /*#include */ #include /*#include */ /* Socket Handling */ #ifndef WOLFSSH_SOCKET_INVALID #if defined(USE_WINDOWS_API) || defined(MICROCHIP_MPLAB_HARMONY) #define WOLFSSH_SOCKET_INVALID ((SOCKET_T)INVALID_SOCKET) #elif defined(WOLFSSH_TIRTOS) #define WOLFSSH_SOCKET_INVALID ((SOCKET_T)-1) #else #define WOLFSSH_SOCKET_INVALID (SOCKET_T)(0) #endif #endif /* WOLFSSH_SOCKET_INVALID */ #ifndef WOLFSSL_SOCKET_IS_INVALID #if defined(USE_WINDOWS_API) || defined(WOLFSSL_TIRTOS) #define WOLFSSL_SOCKET_IS_INVALID(s) ((SOCKET_T)(s) == WOLFSSL_SOCKET_INVALID) #else #define WOLFSSL_SOCKET_IS_INVALID(s) ((SOCKET_T)(s) < WOLFSSL_SOCKET_INVALID) #endif #endif /* WOLFSSL_SOCKET_IS_INVALID */ #if defined(__MACH__) || defined(USE_WINDOWS_API) #ifndef _SOCKLEN_T typedef int socklen_t; #endif #endif #ifdef USE_WINDOWS_API #define WCLOSESOCKET(s) closesocket(s) #define WSTARTTCP() do { WSADATA wsd; WSAStartup(0x0002, &wsd); } while(0) #elif defined(MICROCHIP_TCPIP) || defined(MICROCHIP_MPLAB_HARMONY) #ifdef MICROCHIP_MPLAB_HARMONY #define WCLOSESOCKET(s) TCPIP_TCP_Close((s)) #else #define WCLOSESOCKET(s) closesocket((s)) #endif #define WSTARTTCP() #elif defined(WOLFSSL_NUCLEUS) #define WCLOSESOCKET(s) NU_Close_Socket((s)) #define WSTARTTCP() #else #define WCLOSESOCKET(s) close(s) #define WSTARTTCP() #endif #ifdef SINGLE_THREADED typedef unsigned int THREAD_RETURN; typedef void* THREAD_TYPE; #define WOLFSSH_THREAD #else #if defined(_POSIX_THREADS) && !defined(__MINGW32__) typedef void* THREAD_RETURN; typedef pthread_t THREAD_TYPE; #define WOLFSSH_THREAD #define INFINITE -1 #define WAIT_OBJECT_0 0L #elif defined(WOLFSSL_NUCLEUS) typedef unsigned int THREAD_RETURN; typedef intptr_t THREAD_TYPE; #define WOLFSSH_THREAD #else typedef unsigned int THREAD_RETURN; typedef intptr_t THREAD_TYPE; #define WOLFSSH_THREAD __stdcall #endif #endif #ifdef TEST_IPV6 typedef struct sockaddr_in6 SOCKADDR_IN_T; #define AF_INET_V AF_INET6 #else #ifndef WOLFSSL_NUCLEUS typedef struct sockaddr_in SOCKADDR_IN_T; #endif #define AF_INET_V AF_INET #endif #define serverKeyRsaPemFile "./keys/server-key-rsa.pem" #ifndef TEST_IPV6 static const char* const wolfSshIp = "127.0.0.1"; #else /* TEST_IPV6 */ static const char* const wolfSshIp = "::1"; #endif /* TEST_IPV6 */ #ifdef __GNUC__ #define WS_NORETURN __attribute__((noreturn)) #else #define WS_NORETURN #endif #ifdef USE_WINDOWS_API #pragma warning(push) #pragma warning(disable:4996) /* For Windows builds, disable compiler warnings for: * - 4996: deprecated function */ #endif #if defined(WOLFSSH_TEST_CLIENT) || defined(WOLFSSH_TEST_SERVER) #ifdef USE_WINDOWS_API #pragma warning(pop) #endif #endif /* WOLFSSH_TEST_CLIENT || WOLFSSH_TEST_SERVER */ #ifndef XNTOHS #define XNTOHS(a) ntohs((a)) #endif #if (defined(WOLFSSH_TEST_SERVER) || defined(WOLFSSH_TEST_CLIENT)) #ifdef WOLFSSL_NUCLEUS #define WFD_SET_TYPE FD_SET #define WFD_SET NU_FD_Set #define WFD_ZERO NU_FD_Init #define WFD_ISSET NU_FD_Check #else #define WFD_SET_TYPE fd_set #define WFD_SET FD_SET #define WFD_ZERO FD_ZERO #define WFD_ISSET FD_ISSET #endif /* returns 1 or greater when something is ready to be read */ static INLINE int wSelect(int nfds, WFD_SET_TYPE* recvfds, WFD_SET_TYPE *writefds, WFD_SET_TYPE *errfds, struct timeval* timeout) { #ifdef WOLFSSL_NUCLEUS int ret = NU_Select (nfds, recvfds, writefds, errfds, (UNSIGNED)timeout->tv_sec); if (ret == NU_SUCCESS) { return 1; } return 0; #else return select(nfds, recvfds, writefds, errfds, timeout); #endif } #endif /* WOLFSSH_TEST_SERVER || WOLFSSH_TEST_CLIENT */ /* Wolf Root Directory Helper */ /* KEIL-RL File System does not support relative directory */ #if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_FS) && !defined(WOLFSSL_TIRTOS) \ && !defined(NO_WOLFSSL_DIR) && !defined(WOLFSSL_NUCLEUS) /* Maximum depth to search for WolfSSL root */ #define MAX_WOLF_ROOT_DEPTH 5 static INLINE int ChangeToWolfSshRoot(void) { #if !defined(NO_FILESYSTEM) int depth, res; WFILE* file; for(depth = 0; depth <= MAX_WOLF_ROOT_DEPTH; depth++) { if (WFOPEN(&file, serverKeyRsaPemFile, "rb") == 0) { WFCLOSE(file); return depth; } #ifdef USE_WINDOWS_API res = SetCurrentDirectoryA("..\\"); #else res = chdir("../"); #endif if (res < 0) { printf("chdir to ../ failed!\n"); break; } } err_sys("wolfSSH root not found"); return -1; #else return 0; #endif } #endif /* !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_FS) && !defined(WOL FSSL_TIRTOS) */ #ifdef WOLFSSH_SFTP typedef int (*WS_CallbackSftpCommand)(const char* in, char* out, int outSz); #endif typedef struct ssh_func_args { int argc; char** argv; int return_code; tcp_ready* signal; WS_CallbackUserAuth user_auth; #ifdef WOLFSSH_SFTP /* callback for example sftp client commands instead of WFGETS */ WS_CallbackSftpCommand sftp_cb; #endif } ssh_func_args; #ifdef WOLFSSH_TEST_LOCKING static INLINE void InitTcpReady(tcp_ready* ready) { ready->ready = 0; ready->port = 0; ready->srfName = NULL; #ifdef SINGLE_THREADED #elif defined(_POSIX_THREADS) && !defined(__MINGW32__) pthread_mutex_init(&ready->mutex, 0); pthread_cond_init(&ready->cond, 0); #endif } static INLINE void FreeTcpReady(tcp_ready* ready) { #ifdef SINGLE_THREADED (void)ready; #elif defined(_POSIX_THREADS) && !defined(__MINGW32__) pthread_mutex_destroy(&ready->mutex); pthread_cond_destroy(&ready->cond); #else (void)ready; #endif } static INLINE void WaitTcpReady(ssh_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 */ #ifdef WOLFSSH_TEST_THREADING typedef THREAD_RETURN WOLFSSH_THREAD THREAD_FUNC(void*); static INLINE void ThreadStart(THREAD_FUNC fun, void* args, THREAD_TYPE* thread) { #ifdef SINGLE_THREADED (void)fun; (void)args; (void)thread; #elif defined(_POSIX_THREADS) && !defined(__MINGW32__) pthread_create(thread, 0, fun, args); return; #elif defined(WOLFSSL_TIRTOS) /* Initialize the defaults and set the parameters. */ Task_Params taskParams; Task_Params_init(&taskParams); taskParams.arg0 = (UArg)args; taskParams.stackSize = 65535; *thread = Task_create((Task_FuncPtr)fun, &taskParams, NULL); if (*thread == NULL) { printf("Failed to create new Task\n"); } Task_yield(); #else *thread = (THREAD_TYPE)_beginthreadex(0, 0, fun, args, 0, 0); #endif } static INLINE void ThreadJoin(THREAD_TYPE thread) { #ifdef SINGLE_THREADED (void)thread; #elif defined(_POSIX_THREADS) && !defined(__MINGW32__) pthread_join(thread, 0); #elif defined(WOLFSSL_TIRTOS) while(1) { if (Task_getMode(thread) == Task_Mode_TERMINATED) { Task_sleep(5); break; } Task_yield(); } #else int res = WaitForSingleObject((HANDLE)thread, INFINITE); assert(res == WAIT_OBJECT_0); res = CloseHandle((HANDLE)thread); assert(res); (void)res; /* Suppress un-used variable warning */ #endif } static INLINE void ThreadDetach(THREAD_TYPE thread) { #ifdef SINGLE_THREADED (void)thread; #elif defined(_POSIX_THREADS) && !defined(__MINGW32__) pthread_detach(thread); #elif defined(WOLFSSL_TIRTOS) #if 0 while(1) { if (Task_getMode(thread) == Task_Mode_TERMINATED) { Task_sleep(5); break; } Task_yield(); } #endif #else int res = CloseHandle((HANDLE)thread); assert(res); (void)res; /* Suppress un-used variable warning */ #endif } #endif /* WOLFSSH_TEST_THREADING */ #endif /* _WOLFSSH_TEST_H_ */