/* handle SFTP operations * returns 0 on success */ static int sftp_worker(thread_ctx_t* threadCtx) { int ret = WS_SUCCESS; int error = WS_SUCCESS; SOCKET_T sockfd; int select_ret = 0; sockfd = (SOCKET_T)wolfSSH_get_fd(threadCtx->ssh); do { if (threadCtx->nonBlock) { if (error == WS_WANT_READ) printf("... sftp server would read block\n"); else if (error == WS_WANT_WRITE) printf("... sftp server would write block\n"); } select_ret = tcp_select(sockfd, TEST_SFTP_TIMEOUT); if (select_ret == WS_SELECT_RECV_READY || select_ret == WS_SELECT_ERROR_READY || error == WS_WANT_WRITE) { ret = wolfSSH_SFTP_read(threadCtx->ssh); error = wolfSSH_get_error(threadCtx->ssh); } else if (select_ret == WS_SELECT_TIMEOUT) error = WS_WANT_READ; else error = WS_FATAL_ERROR; if (error == WS_WANT_READ || error == WS_WANT_WRITE) ret = WS_WANT_READ; } while (ret != WS_FATAL_ERROR); return ret; }
static int NonBlockSSH_connect(WOLFSSH* ssh) { int ret; int error; SOCKET_T sockfd; int select_ret = 0; ret = wolfSSH_connect(ssh); error = wolfSSH_get_error(ssh); sockfd = (SOCKET_T)wolfSSH_get_fd(ssh); while (ret != WS_SUCCESS && (error == WS_WANT_READ || error == WS_WANT_WRITE)) { if (error == WS_WANT_READ) printf("... client would read block\n"); else if (error == WS_WANT_WRITE) printf("... client would write block\n"); select_ret = tcp_select(sockfd, 1); if (select_ret == WS_SELECT_RECV_READY || select_ret == WS_SELECT_ERROR_READY) { ret = wolfSSH_connect(ssh); } else if (select_ret == WS_SELECT_TIMEOUT) error = WS_WANT_READ; else error = WS_FATAL_ERROR; } return ret; }
static THREAD_RET readPeer(void* in) { byte buf[80]; int bufSz = sizeof(buf); thread_args* args = (thread_args*)in; int ret = 0; int fd = wolfSSH_get_fd(args->ssh); word32 bytes; #ifdef USE_WINDOWS_API HANDLE stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE); #endif fd_set readSet; fd_set errSet; FD_ZERO(&readSet); FD_ZERO(&errSet); FD_SET(fd, &readSet); FD_SET(fd, &errSet); while (ret >= 0) { bytes = select(fd + 1, &readSet, NULL, &errSet, NULL); wc_LockMutex(&args->lock); while (bytes > 0 && (FD_ISSET(fd, &readSet) || FD_ISSET(fd, &errSet))) { /* there is something to read off the wire */ WMEMSET(buf, 0, bufSz); ret = wolfSSH_stream_read(args->ssh, buf, bufSz - 1); if (ret == WS_EXTDATA) { /* handle extended data */ do { WMEMSET(buf, 0, bufSz); ret = wolfSSH_extended_data_read(args->ssh, buf, bufSz - 1); if (ret < 0) err_sys("Extended data read failed."); buf[bufSz - 1] = '\0'; fprintf(stderr, "%s", buf); } while (ret > 0); } else if (ret <= 0) { if (ret != WS_EOF) { err_sys("Stream read failed."); } } else { buf[bufSz - 1] = '\0'; #ifdef USE_WINDOWS_API if (args->rawMode == 0) { ret = wolfSSH_ConvertConsole(args->ssh, stdoutHandle, buf, ret); if (ret != WS_SUCCESS && ret != WS_WANT_READ) { err_sys("issue with print out"); } if (ret == WS_WANT_READ) { ret = 0; } } else { printf("%s", buf); fflush(stdout); } #else printf("%s", buf); fflush(stdout); #endif } if (wolfSSH_stream_peek(args->ssh, buf, bufSz) <= 0) { bytes = 0; /* read it all */ } } wc_UnLockMutex(&args->lock); } #if defined(HAVE_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS) wc_ecc_fp_free(); /* free per thread cache */ #endif return THREAD_RET_SUCCESS; }
/* handle SSH echo operations * returns 0 on success */ static int ssh_worker(thread_ctx_t* threadCtx) { byte* buf = NULL; byte* tmpBuf; int bufSz, backlogSz = 0, rxSz, txSz, stop = 0, txSum; do { bufSz = EXAMPLE_BUFFER_SZ + backlogSz; tmpBuf = (byte*)realloc(buf, bufSz); if (tmpBuf == NULL) stop = 1; else buf = tmpBuf; if (!stop) { if (threadCtx->nonBlock) { SOCKET_T sockfd; int select_ret = 0; sockfd = (SOCKET_T)wolfSSH_get_fd(threadCtx->ssh); select_ret = tcp_select(sockfd, 1); if (select_ret != WS_SELECT_RECV_READY && select_ret != WS_SELECT_ERROR_READY && select_ret != WS_SELECT_TIMEOUT) { break; } } rxSz = wolfSSH_stream_read(threadCtx->ssh, buf + backlogSz, EXAMPLE_BUFFER_SZ); if (rxSz > 0) { backlogSz += rxSz; txSum = 0; txSz = 0; while (backlogSz != txSum && txSz >= 0 && !stop) { txSz = wolfSSH_stream_send(threadCtx->ssh, buf + txSum, backlogSz - txSum); if (txSz > 0) { byte c; const byte matches[] = { 0x03, 0x05, 0x06, 0x00 }; c = find_char(matches, buf + txSum, txSz); switch (c) { case 0x03: stop = 1; break; case 0x06: if (wolfSSH_TriggerKeyExchange(threadCtx->ssh) != WS_SUCCESS) stop = 1; break; case 0x05: if (dump_stats(threadCtx) <= 0) stop = 1; break; } txSum += txSz; } else if (txSz != WS_REKEYING) { int error = wolfSSH_get_error(threadCtx->ssh); if (error != WS_WANT_WRITE) { stop = 1; } else { txSz = 0; } } } if (txSum < backlogSz) memmove(buf, buf + txSum, backlogSz - txSum); backlogSz -= txSum; } else { int error = wolfSSH_get_error(threadCtx->ssh); if (error != WS_WANT_READ) stop = 1; } } } while (!stop); free(buf); return 0; }