static THREAD_RETURN WOLFSSH_THREAD server_worker(void* vArgs) { int ret = 0; thread_ctx_t* threadCtx = (thread_ctx_t*)vArgs; if (!threadCtx->nonBlock) ret = wolfSSH_accept(threadCtx->ssh); else ret = NonBlockSSH_accept(threadCtx->ssh); switch (ret) { case WS_SCP_COMPLETE: printf("scp file transfer completed\n"); ret = 0; break; case WS_SFTP_COMPLETE: #ifdef WOLFSSH_SFTP ret = sftp_worker(threadCtx); #else err_sys("SFTP not compiled in. Please use --enable-sftp"); #endif break; case WS_SUCCESS: ret = ssh_worker(threadCtx); break; } if (ret == WS_FATAL_ERROR && wolfSSH_get_error(threadCtx->ssh) == WS_VERSION_E) { ret = 0; /* don't break out of loop with version miss match */ printf("Unsupported version error\n"); } if (wolfSSH_shutdown(threadCtx->ssh) != WS_SUCCESS) { fprintf(stderr, "Error with SSH shutdown.\n"); } WCLOSESOCKET(threadCtx->fd); wolfSSH_free(threadCtx->ssh); if (ret != 0) { fprintf(stderr, "Error [%d] \"%s\" with handling connection.\n", ret, wolfSSH_ErrorToName(ret)); #ifndef WOLFSSH_NO_EXIT wc_LockMutex(&doneLock); quit = 1; wc_UnLockMutex(&doneLock); #endif } free(threadCtx); return 0; }
THREAD_RETURN WOLFSSH_THREAD client_test(void* args) { WOLFSSH_CTX* ctx = NULL; WOLFSSH* ssh = NULL; SOCKET_T sockFd = WOLFSSH_SOCKET_INVALID; SOCKADDR_IN_T clientAddr; socklen_t clientAddrSz = sizeof(clientAddr); char rxBuf[80]; int ret; int ch; word16 port = wolfSshPort; char* host = (char*)wolfSshIp; const char* username = NULL; const char* password = NULL; const char* cmd = NULL; byte imExit = 0; byte nonBlock = 0; byte keepOpen = 0; #ifdef USE_WINDOWS_API byte rawMode = 0; #endif int argc = ((func_args*)args)->argc; char** argv = ((func_args*)args)->argv; ((func_args*)args)->return_code = 0; while ((ch = mygetopt(argc, argv, "?NP:h:p:u:xc:Rtz")) != -1) { switch (ch) { case 'h': host = myoptarg; break; case 'z': #ifdef WOLFSSH_SHOW_SIZES wolfSSH_ShowSizes(); exit(EXIT_SUCCESS); #endif break; case 'p': port = (word16)atoi(myoptarg); #if !defined(NO_MAIN_DRIVER) || defined(USE_WINDOWS_API) if (port == 0) err_sys("port number cannot be 0"); #endif break; case 'u': username = myoptarg; break; case 'P': password = myoptarg; break; case 'x': /* exit after successful connection without read/write */ imExit = 1; break; case 'N': nonBlock = 1; break; #if !defined(SINGLE_THREADED) && !defined(WOLFSSL_NUCLEUS) case 'c': cmd = myoptarg; break; #ifdef USE_WINDOWS_API case 'R': rawMode = 1; break; #endif /* USE_WINDOWS_API */ #endif #ifdef WOLFSSH_TERM case 't': keepOpen = 1; break; #endif case '?': ShowUsage(); exit(EXIT_SUCCESS); default: ShowUsage(); exit(MY_EX_USAGE); } } myoptind = 0; /* reset for test cases */ if (username == NULL) err_sys("client requires a username parameter."); #ifdef SINGLE_THREADED if (keepOpen) err_sys("Threading needed for terminal session\n"); #endif ctx = wolfSSH_CTX_new(WOLFSSH_ENDPOINT_CLIENT, NULL); if (ctx == NULL) err_sys("Couldn't create wolfSSH client context."); if (((func_args*)args)->user_auth == NULL) wolfSSH_SetUserAuth(ctx, wsUserAuth); else wolfSSH_SetUserAuth(ctx, ((func_args*)args)->user_auth); ssh = wolfSSH_new(ctx); if (ssh == NULL) err_sys("Couldn't create wolfSSH session."); if (password != NULL) wolfSSH_SetUserAuthCtx(ssh, (void*)password); wolfSSH_CTX_SetPublicKeyCheck(ctx, wsPublicKeyCheck); wolfSSH_SetPublicKeyCheckCtx(ssh, (void*)"You've been sampled!"); ret = wolfSSH_SetUsername(ssh, username); if (ret != WS_SUCCESS) err_sys("Couldn't set the username."); build_addr(&clientAddr, host, port); tcp_socket(&sockFd); ret = connect(sockFd, (const struct sockaddr *)&clientAddr, clientAddrSz); if (ret != 0) err_sys("Couldn't connect to server."); if (nonBlock) tcp_set_nonblocking(&sockFd); ret = wolfSSH_set_fd(ssh, (int)sockFd); if (ret != WS_SUCCESS) err_sys("Couldn't set the session's socket."); if (cmd != NULL) { ret = wolfSSH_SetChannelType(ssh, WOLFSSH_SESSION_EXEC, (byte*)cmd, (word32)WSTRLEN((char*)cmd)); if (ret != WS_SUCCESS) err_sys("Couldn't set the channel type."); } #ifdef WOLFSSH_TERM if (keepOpen) { ret = wolfSSH_SetChannelType(ssh, WOLFSSH_SESSION_TERMINAL, NULL, 0); if (ret != WS_SUCCESS) err_sys("Couldn't set the terminal channel type."); } #endif if (!nonBlock) ret = wolfSSH_connect(ssh); else ret = NonBlockSSH_connect(ssh); if (ret != WS_SUCCESS) { printf("err = %s\n", wolfSSH_get_error_name(ssh)); err_sys("Couldn't connect SSH stream."); } #if !defined(SINGLE_THREADED) && !defined(WOLFSSL_NUCLEUS) if (keepOpen) /* set up for psuedo-terminal */ SetEcho(2); if (cmd != NULL || keepOpen == 1) { #if defined(_POSIX_THREADS) thread_args arg; pthread_t thread[2]; arg.ssh = ssh; wc_InitMutex(&arg.lock); pthread_create(&thread[0], NULL, readInput, (void*)&arg); pthread_create(&thread[1], NULL, readPeer, (void*)&arg); pthread_join(thread[1], NULL); pthread_cancel(thread[0]); #elif defined(_MSC_VER) thread_args arg; HANDLE thread[2]; arg.ssh = ssh; arg.rawMode = rawMode; wc_InitMutex(&arg.lock); thread[0] = CreateThread(NULL, 0, readInput, (void*)&arg, 0, 0); thread[1] = CreateThread(NULL, 0, readPeer, (void*)&arg, 0, 0); WaitForSingleObject(thread[1], INFINITE); CloseHandle(thread[0]); CloseHandle(thread[1]); #else err_sys("No threading to use"); #endif if (keepOpen) SetEcho(1); } else #endif if (!imExit) { ret = wolfSSH_stream_send(ssh, (byte*)testString, (word32)strlen(testString)); if (ret <= 0) err_sys("Couldn't send test string."); do { ret = wolfSSH_stream_read(ssh, (byte*)rxBuf, sizeof(rxBuf) - 1); if (ret <= 0) { ret = wolfSSH_get_error(ssh); if (ret != WS_WANT_READ && ret != WS_WANT_WRITE) err_sys("Stream read failed."); } } while (ret == WS_WANT_READ || ret == WS_WANT_WRITE); rxBuf[ret] = '\0'; printf("Server said: %s\n", rxBuf); } ret = wolfSSH_shutdown(ssh); WCLOSESOCKET(sockFd); wolfSSH_free(ssh); wolfSSH_CTX_free(ctx); if (ret != WS_SUCCESS) err_sys("Closing stream failed. Connection could have been closed by peer"); #if defined(HAVE_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS) wc_ecc_fp_free(); /* free per thread cache */ #endif return 0; }