-
Notifications
You must be signed in to change notification settings - Fork 89
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #38 from ejohnstown/client
Client
- Loading branch information
Showing
26 changed files
with
1,834 additions
and
494 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,6 +48,7 @@ diff | |
.vimrc | ||
|
||
# examples | ||
examples/client/client | ||
examples/echoserver/echoserver | ||
examples/server/server | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,295 @@ | ||
/* client.c | ||
* | ||
* Copyright (C) 2014-2017 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 <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
|
||
#define SINGLE_THREADED | ||
/* The client doesn't use threading. */ | ||
|
||
#include <wolfssh/ssh.h> | ||
#include <wolfssh/test.h> | ||
#include "examples/client/client.h" | ||
#ifndef USE_WINDOWS_API | ||
#include <termios.h> | ||
#endif | ||
|
||
|
||
const char testString[] = "Hello, wolfSSH!"; | ||
|
||
|
||
#ifndef USE_WINDOWS_API | ||
static struct termios originalTerm; | ||
#else | ||
static DWORD originalTerm; | ||
#endif | ||
|
||
static int InitEcho(void) | ||
{ | ||
#ifndef USE_WINDOWS_API | ||
return tcgetattr(STDIN_FILENO, &originalTerm); | ||
#else | ||
HANDLE stdinHandle = GetStdHandle(STD_INPUT_HANDLE); | ||
return (GetConsoleMode(stdinHandle, &originalTerm) == 0); | ||
#endif | ||
} | ||
|
||
|
||
static int SetEcho(int on) | ||
{ | ||
#ifndef USE_WINDOWS_API | ||
if (on) { | ||
if (tcsetattr(STDIN_FILENO, TCSANOW, &originalTerm) != 0) { | ||
printf("Couldn't restore the terminal settings.\n"); | ||
return -1; | ||
} | ||
} | ||
else { | ||
struct termios newTerm; | ||
memcpy(&newTerm, &originalTerm, sizeof(struct termios)); | ||
|
||
newTerm.c_lflag &= ~ECHO; | ||
newTerm.c_lflag |= (ICANON | ECHONL); | ||
|
||
if (tcsetattr(STDIN_FILENO, TCSANOW, &newTerm) != 0) { | ||
printf("Couldn't turn off echo.\n"); | ||
return -1; | ||
} | ||
} | ||
#else | ||
HANDLE stdinHandle = GetStdHandle(STD_INPUT_HANDLE); | ||
if (on) { | ||
if (SetConsoleMode(stdinHandle, originalTerm) == 0) { | ||
printf("Couldn't restore the terminal settings.\n"); | ||
return -1; | ||
} | ||
} | ||
else { | ||
DWORD newTerm = originalTerm; | ||
|
||
newTerm &= ~ENABLE_ECHO_INPUT; | ||
|
||
if (SetConsoleMode(stdinHandle, newTerm) == 0) { | ||
printf("Couldn't turn off echo.\n"); | ||
return -1; | ||
} | ||
} | ||
#endif | ||
|
||
return 0; | ||
} | ||
|
||
|
||
static void ShowUsage(void) | ||
{ | ||
printf("client %s\n", LIBWOLFSSH_VERSION_STRING); | ||
printf(" -? display this help and exit\n"); | ||
printf(" -h <host> host to connect to, default %s\n", wolfSshIp); | ||
printf(" -p <num> port to connect on, default %d\n", wolfSshPort); | ||
printf(" -u <username> username to authenticate as (REQUIRED)\n"); | ||
printf(" -P <password> password for username, prompted if omitted\n"); | ||
} | ||
|
||
|
||
byte userPassword[256]; | ||
|
||
static int wsUserAuth(byte authType, | ||
WS_UserAuthData* authData, | ||
void* ctx) | ||
{ | ||
const char* defaultPassword = (const char*)ctx; | ||
word32 passwordSz; | ||
int ret = WOLFSSH_USERAUTH_SUCCESS; | ||
|
||
(void)authType; | ||
if (defaultPassword != NULL) { | ||
passwordSz = (word32)strlen(defaultPassword); | ||
memcpy(userPassword, defaultPassword, passwordSz); | ||
} | ||
else { | ||
printf("Password: "); | ||
SetEcho(0); | ||
if (fgets((char*)userPassword, sizeof(userPassword), stdin) == NULL) { | ||
printf("Getting password failed.\n"); | ||
ret = WOLFSSH_USERAUTH_FAILURE; | ||
} | ||
else { | ||
char* c = strpbrk((char*)userPassword, "\r\n");; | ||
if (c != NULL) | ||
*c = '\0'; | ||
passwordSz = (word32)strlen((const char*)userPassword); | ||
} | ||
SetEcho(1); | ||
#ifdef USE_WINDOWS_API | ||
printf("\r\n"); | ||
#endif | ||
} | ||
|
||
if (ret == WOLFSSH_USERAUTH_SUCCESS) { | ||
authData->sf.password.password = userPassword; | ||
authData->sf.password.passwordSz = passwordSz; | ||
} | ||
|
||
return ret; | ||
} | ||
|
||
|
||
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; | ||
char ch; | ||
word16 port = wolfSshPort; | ||
char* host = (char*)wolfSshIp; | ||
const char* username = NULL; | ||
const char* password = NULL; | ||
|
||
int argc = ((func_args*)args)->argc; | ||
char** argv = ((func_args*)args)->argv; | ||
((func_args*)args)->return_code = 0; | ||
|
||
while ((ch = mygetopt(argc, argv, "?h:p:u:P:")) != -1) { | ||
switch (ch) { | ||
case 'h': | ||
host = myoptarg; | ||
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 '?': | ||
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."); | ||
|
||
ctx = wolfSSH_CTX_new(WOLFSSH_ENDPOINT_CLIENT, NULL); | ||
if (ctx == NULL) | ||
err_sys("Couldn't create wolfSSH client context."); | ||
|
||
wolfSSH_SetUserAuth(ctx, wsUserAuth); | ||
|
||
ssh = wolfSSH_new(ctx); | ||
if (ssh == NULL) | ||
err_sys("Couldn't create wolfSSH session."); | ||
|
||
if (password != NULL) | ||
wolfSSH_SetUserAuthCtx(ssh, (void*)password); | ||
|
||
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."); | ||
|
||
ret = wolfSSH_set_fd(ssh, (int)sockFd); | ||
if (ret != WS_SUCCESS) | ||
err_sys("Couldn't set the session's socket."); | ||
|
||
ret = wolfSSH_connect(ssh); | ||
if (ret != WS_SUCCESS) | ||
err_sys("Couldn't connect SSH stream."); | ||
|
||
ret = wolfSSH_stream_send(ssh, (byte*)testString, | ||
(word32)strlen(testString)); | ||
if (ret <= 0) | ||
err_sys("Couldn't send test string."); | ||
|
||
ret = wolfSSH_stream_read(ssh, (byte*)rxBuf, sizeof(rxBuf) - 1); | ||
if (ret <= 0) | ||
err_sys("Stream read failed."); | ||
rxBuf[ret] = '\0'; | ||
printf("Server said: %s\n", rxBuf); | ||
|
||
ret = wolfSSH_shutdown(ssh); | ||
if (ret != WS_SUCCESS) | ||
err_sys("Closing stream failed."); | ||
|
||
WCLOSESOCKET(sockFd); | ||
wolfSSH_free(ssh); | ||
wolfSSH_CTX_free(ctx); | ||
|
||
return 0; | ||
} | ||
|
||
|
||
#ifndef NO_MAIN_DRIVER | ||
|
||
int main(int argc, char** argv) | ||
{ | ||
func_args args; | ||
|
||
args.argc = argc; | ||
args.argv = argv; | ||
args.return_code = 0; | ||
|
||
WSTARTTCP(); | ||
|
||
if (InitEcho() != 0) | ||
err_sys("Couldn't initialize terminal."); | ||
|
||
#ifdef DEBUG_WOLFSSH | ||
wolfSSH_Debugging_ON(); | ||
#endif | ||
|
||
wolfSSH_Init(); | ||
|
||
ChangeToWolfSshRoot(); | ||
#ifndef NO_WOLFSSH_CLIENT | ||
client_test(&args); | ||
#endif /* NO_WOLFSSH_CLIENT */ | ||
|
||
wolfSSH_Cleanup(); | ||
|
||
return args.return_code; | ||
} | ||
|
||
int myoptind = 0; | ||
char* myoptarg = NULL; | ||
|
||
#endif /* NO_MAIN_DRIVER */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/* client.h | ||
* | ||
* Copyright (C) 2014-2017 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 <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
|
||
#pragma once | ||
|
||
#ifndef _WOLFSSH_CLIENT_H_ | ||
#define _WOLFSSH_CLIENT_H_ | ||
|
||
|
||
THREAD_RETURN WOLFSSH_THREAD client_test(void* args); | ||
|
||
|
||
#endif /* _WOLFSSH_CLIENT_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# vim:ft=automake | ||
# All paths should be given relative to the root | ||
|
||
noinst_PROGRAMS += examples/client/client | ||
noinst_HEADERS += examples/client/client.h | ||
examples_client_client_SOURCES = examples/client/client.c | ||
examples_client_client_LDADD = src/libwolfssh.la | ||
examples_client_client_DEPENDENCIES = src/libwolfssh.la | ||
|
||
dist_example_DATA+= examples/client/client.c | ||
DISTCLEANFILES+= examples/client/.libs/client |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.