From fd67c8b0c8d3d42470dbfc38947610f5591ce22c Mon Sep 17 00:00:00 2001 From: John Safranek Date: Fri, 22 Sep 2023 15:58:17 -0700 Subject: [PATCH] wolfSSH Client 1. Changed the function client_test()'s name to wolfSSH_Client(). 2. Added "destination" to the usage text. 3. Improved the handling of the termios settings. 4. Remove the file names from the ClientFreeBuffers() function. 5. Changed ClientFreeBuffers() to free if the pointers aren't pointing at the static buffers. They may not load because the file is bad, but it will still have a file name. 6. Only try to load the public key or cert if loading the private key was successful. Do not fail out if key cannot load, password may still be possible. --- apps/wolfssh/common.c | 6 +-- apps/wolfssh/common.h | 3 +- apps/wolfssh/wolfssh.c | 91 ++++++++++++++++++++++++++++++++---------- 3 files changed, 74 insertions(+), 26 deletions(-) diff --git a/apps/wolfssh/common.c b/apps/wolfssh/common.c index 0264f28f..3945866c 100644 --- a/apps/wolfssh/common.c +++ b/apps/wolfssh/common.c @@ -523,13 +523,13 @@ int ClientLoadCA(WOLFSSH_CTX* ctx, const char* caCert) } -void ClientFreeBuffers(const char* pubKeyName, const char* privKeyName) +void ClientFreeBuffers(void) { - if (pubKeyName != NULL && userPublicKey != NULL) { + if (userPublicKey != userPublicKeyBuf) { WFREE(userPublicKey, NULL, DYNTYPE_PRIVKEY); } - if (privKeyName != NULL && userPrivateKey != NULL) { + if (userPrivateKey != userPrivateKeyBuf) { WFREE(userPrivateKey, NULL, DYNTYPE_PRIVKEY); } } diff --git a/apps/wolfssh/common.h b/apps/wolfssh/common.h index 5eb510cc..14d45dcb 100644 --- a/apps/wolfssh/common.h +++ b/apps/wolfssh/common.h @@ -31,7 +31,6 @@ WOLFSSH_LOCAL int ClientUserAuth(byte authType, WS_UserAuthData* authData, WOLFSSH_LOCAL int ClientPublicKeyCheck(const byte* pubKey, word32 pubKeySz, void* ctx); WOLFSSH_LOCAL void ClientIPOverride(int flag); -WOLFSSH_LOCAL void ClientFreeBuffers(const char* pubKeyName, - const char* privKeyName); +WOLFSSH_LOCAL void ClientFreeBuffers(void); #endif /* APPS_WOLFSSH_COMMON_H */ diff --git a/apps/wolfssh/wolfssh.c b/apps/wolfssh/wolfssh.c index 1d277785..61d6c6e7 100644 --- a/apps/wolfssh/wolfssh.c +++ b/apps/wolfssh/wolfssh.c @@ -94,7 +94,8 @@ static void ShowUsage(char* appPath) } printf("%s v%s\n", appName, LIBWOLFSSH_VERSION_STRING); - printf("usage: %s [-E logfile] [-G] [-l login_name] [-N] [-p port] [-V]\n", + printf("usage: %s [-E logfile] [-G] [-l login_name] [-N] [-p port] " + "[-V] destination\n", appName); } @@ -149,6 +150,53 @@ static int NonBlockSSH_connect(WOLFSSH* ssh) return ret; } +#ifdef HAVE_TERMIOS_H +WOLFSSH_TERMIOS oldTerm; + +static void modes_store(void) +{ + tcgetattr(STDIN_FILENO, &oldTerm); +} + +static void modes_clear(void) +{ + WOLFSSH_TERMIOS term = oldTerm; + + term.c_lflag &= ~(ICANON | ISIG | IEXTEN | ECHO | ECHOE | ECHOK + | ECHONL | ECHOPRT | NOFLSH | TOSTOP | FLUSHO + | PENDIN | EXTPROC); + + term.c_iflag &= ~(ISTRIP | INLCR | ICRNL | IGNCR | IXON | IXOFF + | IXANY | IGNBRK | INPCK | PARMRK); +#ifdef IUCLC + term.c_iflag &= ~IUCLC; +#endif + term.c_iflag |= IGNPAR; + + term.c_oflag &= ~(OPOST | ONOCR | ONLRET); +#ifdef OUCLC + term.c_oflag &= ~OLCUC; +#endif + + term.c_cflag &= ~(CSTOPB | PARENB | PARODD | CLOCAL | CRTSCTS); + + tcsetattr(STDIN_FILENO, TCSANOW, &term); +} + +static void modes_reset(void) +{ + tcsetattr(STDIN_FILENO, TCSAFLUSH, &oldTerm); +} + +#define MODES_STORE() modes_store() +#define MODES_CLEAR() modes_clear() +#define MODES_RESET() modes_reset() +#else +#define MODES_STORE() do {} while(0) +#define MODES_CLEAR() do {} while(0) +#define MODES_RESET() do {} while(0) +#endif + #if !defined(SINGLE_THREADED) && !defined(WOLFSSL_NUCLEUS) typedef struct thread_args { @@ -814,7 +862,7 @@ static int config_cleanup(struct config* config) } -THREAD_RETURN WOLFSSH_THREAD client_test(void* args) +static THREAD_RETURN WOLFSSH_THREAD wolfSSH_Client(void* args) { WOLFSSH_CTX* ctx = NULL; WOLFSSH* ssh = NULL; @@ -833,6 +881,8 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args) #endif struct config config; + MODES_STORE(); + ((func_args*)args)->return_code = 0; config_init_default(&config); @@ -850,26 +900,20 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args) if (config.keyFile) { ret = ClientSetPrivateKey(config.keyFile); - if (ret != 0) { - err_sys("Error setting private key"); + if (ret == 0) { + #ifdef WOLFSSH_CERTS + /* passed in certificate to use */ + if (certName) { + (void)ClientUseCert(certName); + } + else + #endif + if (config.pubKeyFile) { + (void)ClientUsePubKey(config.pubKeyFile); + } } } -#ifdef WOLFSSH_CERTS - /* passed in certificate to use */ - if (certName) { - ret = ClientUseCert(certName); - } - else -#endif - - if (config.pubKeyFile) { - ret = ClientUsePubKey(config.pubKeyFile); - } - if (ret != 0) { - err_sys("Error setting public key"); - } - ctx = wolfSSH_CTX_new(WOLFSSH_ENDPOINT_CLIENT, NULL); if (ctx == NULL) err_sys("Couldn't create wolfSSH client context."); @@ -949,8 +993,12 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args) err_sys("Couldn't connect SSH stream."); #if !defined(SINGLE_THREADED) && !defined(WOLFSSL_NUCLEUS) +#if 0 if (keepOpen) /* set up for psuedo-terminal */ ClientSetEcho(2); +#endif + + MODES_CLEAR(); if (config.command != NULL || keepOpen == 1) { #if defined(_POSIX_THREADS) @@ -1053,12 +1101,13 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args) if (ret != WS_SUCCESS && ret != WS_SOCKET_ERROR_E) err_sys("Closing client stream failed"); - ClientFreeBuffers(config.pubKeyFile, config.keyFile); + ClientFreeBuffers(); #if !defined(WOLFSSH_NO_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS) wc_ecc_fp_free(); /* free per thread cache */ #endif config_cleanup(&config); + MODES_RESET(); return 0; } @@ -1081,7 +1130,7 @@ int main(int argc, char** argv) wolfSSH_Init(); - client_test(&args); + wolfSSH_Client(&args); wolfSSH_Cleanup();