ssh
Embed:
(wiki syntax)
Show/hide line numbers
test.h
00001 /* test.h */ 00002 00003 #pragma once 00004 00005 #ifndef _WOLFSSH_TEST_H_ 00006 #define _WOLFSSH_TEST_H_ 00007 00008 00009 #include <stdio.h> 00010 /*#include <stdlib.h>*/ 00011 #include <ctype.h> 00012 /*#include <wolfssh/error.h>*/ 00013 00014 #ifdef USE_WINDOWS_API 00015 #include <winsock2.h> 00016 #include <process.h> 00017 #include <assert.h> 00018 #ifdef TEST_IPV6 /* don't require newer SDK for IPV4 */ 00019 #include <ws2tcpip.h> 00020 #include <wspiapi.h> 00021 #endif 00022 #define SOCKET_T SOCKET 00023 #else /* USE_WINDOWS_API */ 00024 #include <unistd.h> 00025 #include <netdb.h> 00026 #include <netinet/in.h> 00027 //#include <netinet/tcp.h> 00028 #include <arpa/inet.h> 00029 #include <sys/ioctl.h> 00030 #include <sys/socket.h> 00031 #include <pthread.h> 00032 #include <fcntl.h> 00033 #ifndef SO_NOSIGPIPE // FIX: ESP32 00034 #include <signal.h> /* ignore SIGPIPE */ 00035 #endif 00036 #define SOCKET_T int 00037 #endif /* USE_WINDOWS_API */ 00038 00039 00040 /* Socket Handling */ 00041 #ifndef WOLFSSH_SOCKET_INVALID 00042 #ifdef USE_WINDOWS_API 00043 #define WOLFSSH_SOCKET_INVALID ((SOCKET_T)INVALID_SOCKET) 00044 #elif defined(WOLFSSH_TIRTOS) 00045 #define WOLFSSH_SOCKET_INVALID ((SOCKET_T)-1) 00046 #else 00047 #define WOLFSSH_SOCKET_INVALID (SOCKET_T)(0) 00048 #endif 00049 #endif /* WOLFSSH_SOCKET_INVALID */ 00050 00051 #ifndef WOLFSSL_SOCKET_IS_INVALID 00052 #if defined(USE_WINDOWS_API) || defined(WOLFSSL_TIRTOS) 00053 #define WOLFSSL_SOCKET_IS_INVALID(s) ((SOCKET_T)(s) == WOLFSSL_SOCKET_INVALID) 00054 #else 00055 #define WOLFSSL_SOCKET_IS_INVALID(s) ((SOCKET_T)(s) < WOLFSSL_SOCKET_INVALID) 00056 #endif 00057 #endif /* WOLFSSL_SOCKET_IS_INVALID */ 00058 00059 00060 #if defined(__MACH__) || defined(USE_WINDOWS_API) 00061 #ifndef _SOCKLEN_T 00062 typedef int socklen_t; 00063 #endif 00064 #endif 00065 00066 00067 #ifdef USE_WINDOWS_API 00068 #define WCLOSESOCKET(s) closesocket(s) 00069 #define WSTARTTCP() do { WSADATA wsd; WSAStartup(0x0002, &wsd); } while(0) 00070 #else 00071 #define WCLOSESOCKET(s) close(s) 00072 #define WSTARTTCP() 00073 #endif 00074 00075 00076 #ifdef SINGLE_THREADED 00077 typedef unsigned int THREAD_RETURN; 00078 typedef void* THREAD_TYPE; 00079 #define WOLFSSH_THREAD 00080 #else 00081 #if defined(_POSIX_THREADS) && !defined(__MINGW32__) 00082 typedef void* THREAD_RETURN; 00083 typedef pthread_t THREAD_TYPE; 00084 #define WOLFSSH_THREAD 00085 #define INFINITE -1 00086 #define WAIT_OBJECT_0 0L 00087 #else 00088 typedef unsigned int THREAD_RETURN; 00089 typedef intptr_t THREAD_TYPE; 00090 #define WOLFSSH_THREAD __stdcall 00091 #endif 00092 #endif 00093 00094 #ifdef TEST_IPV6 00095 typedef struct sockaddr_in6 SOCKADDR_IN_T; 00096 #define AF_INET_V AF_INET6 00097 #else 00098 typedef struct sockaddr_in SOCKADDR_IN_T; 00099 #define AF_INET_V AF_INET 00100 #endif 00101 00102 00103 #define serverKeyRsaPemFile "./keys/server-key-rsa.pem" 00104 00105 00106 typedef struct tcp_ready { 00107 word16 ready; /* predicate */ 00108 word16 port; 00109 char* srfName; /* server ready file name */ 00110 #if defined(_POSIX_THREADS) && !defined(__MINGW32__) 00111 pthread_mutex_t mutex; 00112 pthread_cond_t cond; 00113 #endif 00114 } tcp_ready; 00115 00116 00117 static INLINE void InitTcpReady(tcp_ready* ready) 00118 { 00119 ready->ready = 0; 00120 ready->port = 0; 00121 ready->srfName = NULL; 00122 #ifdef SINGLE_THREADED 00123 #elif defined(_POSIX_THREADS) && !defined(__MINGW32__) 00124 pthread_mutex_init(&ready->mutex, 0); 00125 pthread_cond_init(&ready->cond, 0); 00126 #endif 00127 } 00128 00129 00130 static INLINE void FreeTcpReady(tcp_ready* ready) 00131 { 00132 #ifdef SINGLE_THREADED 00133 (void)ready; 00134 #elif defined(_POSIX_THREADS) && !defined(__MINGW32__) 00135 pthread_mutex_destroy(&ready->mutex); 00136 pthread_cond_destroy(&ready->cond); 00137 #else 00138 (void)ready; 00139 #endif 00140 } 00141 00142 00143 typedef struct func_args { 00144 int argc; 00145 char** argv; 00146 int return_code; 00147 tcp_ready* signal; 00148 WS_CallbackUserAuth user_auth; 00149 } func_args; 00150 00151 00152 typedef THREAD_RETURN WOLFSSH_THREAD THREAD_FUNC(void*); 00153 void ThreadStart(THREAD_FUNC, void*, THREAD_TYPE*); 00154 void ThreadJoin(THREAD_TYPE); 00155 void ThreadDetach(THREAD_TYPE); 00156 void WaitTcpReady(func_args*); 00157 00158 00159 #ifndef TEST_IPV6 00160 static const char* const wolfSshIp = "127.0.0.1"; 00161 #else /* TEST_IPV6 */ 00162 static const char* const wolfSshIp = "::1"; 00163 #endif /* TEST_IPV6 */ 00164 static const word16 wolfSshPort = 22222; 00165 00166 00167 #ifdef __GNUC__ 00168 #define WS_NORETURN __attribute__((noreturn)) 00169 #else 00170 #define WS_NORETURN 00171 #endif 00172 00173 static INLINE WS_NORETURN void err_sys(const char* msg) 00174 { 00175 printf("wolfSSH error: %s\n", msg); 00176 00177 #ifndef __GNUC__ 00178 /* scan-build (which pretends to be gnuc) can get confused and think the 00179 * msg pointer can be null even when hardcoded and then it won't exit, 00180 * making null pointer checks above the err_sys() call useless. 00181 * We could just always exit() but some compilers will complain about no 00182 * possible return, with gcc we know the attribute to handle that with 00183 * WS_NORETURN. */ 00184 if (msg) 00185 #endif 00186 { 00187 exit(EXIT_FAILURE); 00188 } 00189 } 00190 00191 00192 #define MY_EX_USAGE 2 00193 00194 extern int myoptind; 00195 extern char* myoptarg; 00196 00197 static INLINE int mygetopt(int argc, char** argv, const char* optstring) 00198 { 00199 static char* next = NULL; 00200 00201 char c; 00202 char* cp; 00203 00204 if (myoptind == 0) 00205 next = NULL; /* we're starting new/over */ 00206 00207 if (next == NULL || *next == '\0') { 00208 if (myoptind == 0) 00209 myoptind++; 00210 00211 if (myoptind >= argc || argv[myoptind][0] != '-' || 00212 argv[myoptind][1] == '\0') { 00213 myoptarg = NULL; 00214 if (myoptind < argc) 00215 myoptarg = argv[myoptind]; 00216 00217 return -1; 00218 } 00219 00220 if (strcmp(argv[myoptind], "--") == 0) { 00221 myoptind++; 00222 myoptarg = NULL; 00223 00224 if (myoptind < argc) 00225 myoptarg = argv[myoptind]; 00226 00227 return -1; 00228 } 00229 00230 next = argv[myoptind]; 00231 next++; /* skip - */ 00232 myoptind++; 00233 } 00234 00235 c = *next++; 00236 /* The C++ strchr can return a different value */ 00237 cp = (char*)strchr(optstring, c); 00238 00239 if (cp == NULL || c == ':') 00240 return '?'; 00241 00242 cp++; 00243 00244 if (*cp == ':') { 00245 if (*next != '\0') { 00246 myoptarg = next; 00247 next = NULL; 00248 } 00249 else if (myoptind < argc) { 00250 myoptarg = argv[myoptind]; 00251 myoptind++; 00252 } 00253 else 00254 return '?'; 00255 } 00256 00257 return c; 00258 } 00259 00260 00261 #ifdef USE_WINDOWS_API 00262 #pragma warning(push) 00263 #pragma warning(disable:4996) 00264 /* For Windows builds, disable compiler warnings for: 00265 * - 4996: deprecated function */ 00266 #endif 00267 00268 static INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer, 00269 word16 port) 00270 { 00271 int useLookup = 0; 00272 (void)useLookup; 00273 00274 memset(addr, 0, sizeof(SOCKADDR_IN_T)); 00275 00276 #ifndef TEST_IPV6 00277 /* peer could be in human readable form */ 00278 if ( ((size_t)peer != INADDR_ANY) && isalpha((int)peer[0])) { 00279 #ifdef CYASSL_MDK_ARM 00280 int err; 00281 struct hostent* entry = gethostbyname(peer, &err); 00282 #else 00283 struct hostent* entry = gethostbyname(peer); 00284 #endif 00285 00286 if (entry) { 00287 memcpy(&addr->sin_addr.s_addr, entry->h_addr_list[0], 00288 entry->h_length); 00289 useLookup = 1; 00290 } 00291 else 00292 err_sys("no entry for host"); 00293 } 00294 #endif 00295 00296 #ifndef TEST_IPV6 00297 #if defined(CYASSL_MDK_ARM) 00298 addr->sin_family = PF_INET; 00299 #else 00300 addr->sin_family = AF_INET_V; 00301 #endif 00302 addr->sin_port = htons(port); 00303 if ((size_t)peer == INADDR_ANY) 00304 addr->sin_addr.s_addr = INADDR_ANY; 00305 else { 00306 if (!useLookup) 00307 addr->sin_addr.s_addr = inet_addr(peer); 00308 } 00309 #else 00310 addr->sin6_family = AF_INET_V; 00311 addr->sin6_port = htons(port); 00312 if ((size_t)peer == INADDR_ANY) 00313 addr->sin6_addr = in6addr_any; 00314 else { 00315 #ifdef HAVE_GETADDRINFO 00316 struct addrinfo hints; 00317 struct addrinfo* answer = NULL; 00318 int ret; 00319 char strPort[80]; 00320 00321 memset(&hints, 0, sizeof(hints)); 00322 00323 hints.ai_family = AF_INET_V; 00324 hints.ai_socktype = udp ? SOCK_DGRAM : SOCK_STREAM; 00325 hints.ai_protocol = udp ? IPPROTO_UDP : IPPROTO_TCP; 00326 00327 WSNPRINTF(strPort, sizeof(strPort), "%d", port); 00328 strPort[79] = '\0'; 00329 00330 ret = getaddrinfo(peer, strPort, &hints, &answer); 00331 if (ret < 0 || answer == NULL) 00332 err_sys("getaddrinfo failed"); 00333 00334 memcpy(addr, answer->ai_addr, answer->ai_addrlen); 00335 freeaddrinfo(answer); 00336 #else 00337 printf("no ipv6 getaddrinfo, loopback only tests/examples\n"); 00338 addr->sin6_addr = in6addr_loopback; 00339 #endif 00340 } 00341 #endif 00342 } 00343 00344 #ifdef USE_WINDOWS_API 00345 #pragma warning(pop) 00346 #endif 00347 00348 00349 static INLINE void tcp_socket(SOCKET_T* sockFd) 00350 { 00351 *sockFd = socket(AF_INET_V, SOCK_STREAM, 0); 00352 00353 #ifdef USE_WINDOWS_API 00354 if (*sockFd == INVALID_SOCKET) 00355 err_sys("socket failed\n"); 00356 #else 00357 if (*sockFd < 0) 00358 err_sys("socket failed\n"); 00359 #endif 00360 00361 #ifndef USE_WINDOWS_API 00362 #ifdef SO_NOSIGPIPE 00363 { 00364 int on = 1; 00365 socklen_t len = sizeof(on); 00366 int res = setsockopt(*sockFd, SOL_SOCKET, SO_NOSIGPIPE, &on, len); 00367 if (res < 0) 00368 err_sys("setsockopt SO_NOSIGPIPE failed\n"); 00369 } 00370 #elif defined(CYASSL_MDK_ARM) 00371 /* nothing to define */ 00372 #else /* no S_NOSIGPIPE */ 00373 // signal(SIGPIPE, SIG_IGN); // FIX: ESP32 00374 #endif /* S_NOSIGPIPE */ 00375 00376 #if defined(TCP_NODELAY) 00377 { 00378 int on = 1; 00379 socklen_t len = sizeof(on); 00380 int res = setsockopt(*sockFd, IPPROTO_TCP, TCP_NODELAY, &on, len); 00381 if (res < 0) 00382 err_sys("setsockopt TCP_NODELAY failed\n"); 00383 } 00384 #endif 00385 #endif /* USE_WINDOWS_API */ 00386 } 00387 00388 00389 #ifndef XNTOHS 00390 #define XNTOHS(a) ntohs((a)) 00391 #endif 00392 00393 00394 static INLINE void tcp_listen(SOCKET_T* sockfd, word16* port, int useAnyAddr) 00395 { 00396 SOCKADDR_IN_T addr; 00397 00398 /* don't use INADDR_ANY by default, firewall may block, make user switch 00399 on */ 00400 build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSshIp), *port); 00401 tcp_socket(sockfd); 00402 00403 #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_ARM)\ 00404 && !defined(WOLFSSL_KEIL_TCP_NET) 00405 { 00406 int res, on = 1; 00407 socklen_t len = sizeof(on); 00408 res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len); 00409 if (res < 0) 00410 err_sys("setsockopt SO_REUSEADDR failed\n"); 00411 } 00412 #endif 00413 00414 00415 if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0) 00416 err_sys("tcp bind failed"); 00417 if (listen(*sockfd, 5) != 0) 00418 err_sys("tcp listen failed"); 00419 #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_TIRTOS) 00420 if (*port == 0) { 00421 socklen_t len = sizeof(addr); 00422 if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) { 00423 #ifndef TEST_IPV6 00424 *port = XNTOHS(addr.sin_port); 00425 #else 00426 *port = XNTOHS(addr.sin6_port); 00427 #endif 00428 } 00429 } 00430 #endif 00431 } 00432 00433 00434 /* Wolf Root Directory Helper */ 00435 /* KEIL-RL File System does not support relative directory */ 00436 #if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_FS) && !defined(WOLFSSL_TIRTOS) 00437 /* Maximum depth to search for WolfSSL root */ 00438 #define MAX_WOLF_ROOT_DEPTH 5 00439 00440 static INLINE int ChangeToWolfSshRoot(void) 00441 { 00442 #if !defined(NO_FILESYSTEM) 00443 int depth, res; 00444 WFILE* file; 00445 for(depth = 0; depth <= MAX_WOLF_ROOT_DEPTH; depth++) { 00446 if (WFOPEN(&file, serverKeyRsaPemFile, "rb") == 0) { 00447 WFCLOSE(file); 00448 return depth; 00449 } 00450 #ifdef USE_WINDOWS_API 00451 res = SetCurrentDirectoryA("..\\"); 00452 #else 00453 res = chdir("../"); 00454 #endif 00455 if (res < 0) { 00456 printf("chdir to ../ failed!\n"); 00457 break; 00458 } 00459 } 00460 00461 err_sys("wolfSSH root not found"); 00462 return -1; 00463 #else 00464 return 0; 00465 #endif 00466 } 00467 #endif /* !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_FS) && !defined(WOL 00468 FSSL_TIRTOS) */ 00469 00470 00471 #endif /* _WOLFSSH_TEST_H_ */
Generated on Tue Jul 12 2022 21:46:52 by 1.7.2