mirror of https://github.com/wolfSSL/wolfssh.git
Client
1. Added support to the library for clients. 2. Added example client. 3. Added VS solutions for building client example. 4. Added ECC client keys. Renamed existing keys. 5. Since defunct server is copy of echoserver, updated it.pull/38/head
parent
8e2d1056a0
commit
65fb16ddc4
|
|
@ -48,6 +48,7 @@ diff
|
|||
.vimrc
|
||||
|
||||
# examples
|
||||
examples/client/client
|
||||
examples/echoserver/echoserver
|
||||
examples/server/server
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ wolfSSH is dependent on wolfCrypt. The simplest configuration of wolfSSL
|
|||
required for wolfSSH is the default build.
|
||||
|
||||
$ cd wolfssl
|
||||
$ ./configure [OPTIONS]
|
||||
$ ./configure [OPTIONS] CPPFLAGS=-DWOLFSSL_PUBLIC_MP
|
||||
$ make check
|
||||
$ sudo make install
|
||||
|
||||
|
|
@ -95,6 +95,8 @@ release notes
|
|||
- Added ECDH Group Exchange with SHA2 hashing and curves nistp256,
|
||||
nistp384, and nistp521.
|
||||
- Added ECDSA with SHA2 hashing and curves nistp256, nistp384, and nistp521.
|
||||
- Added client support.
|
||||
- Added an example client.
|
||||
- Changed the echoserver to allow only one connection, but multiple
|
||||
connections are allowed with a command line option.
|
||||
- Added option to echoserver to offer an ECC public key.
|
||||
|
|
|
|||
|
|
@ -68,9 +68,6 @@ TAO_REQUIRE_LIBWOLFSSL
|
|||
#REQUIRE_CYASSL([scep])
|
||||
#REQUIRE_WOLFCRYPT([aes rsa dh])
|
||||
|
||||
# Disable any client code. For size, as nothing calls it.
|
||||
AM_CPPFLAGS="$AM_CPPFLAGS -DWOLFSSL_NO_CLIENT"
|
||||
|
||||
# since we have autoconf available, we can use cyassl options header
|
||||
AM_CPPFLAGS="$AM_CPPFLAGS -DHAVE_CYASSL_OPTIONS"
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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
|
||||
|
|
@ -2,4 +2,5 @@
|
|||
# included from Top Level Makefile.am
|
||||
# All paths should be given relative to the root
|
||||
|
||||
include examples/client/include.am
|
||||
include examples/echoserver/include.am
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* server.c
|
||||
*
|
||||
* Copyright (C) 2014-2016 wolfSSL Inc.
|
||||
* Copyright (C) 2014-2017 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSH.
|
||||
*
|
||||
|
|
@ -19,286 +19,165 @@
|
|||
*/
|
||||
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#ifdef WOLFSSL_USER_SETTINGS
|
||||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
#else
|
||||
#include <wolfssl/options.h>
|
||||
#endif
|
||||
|
||||
#include <wolfssl/wolfcrypt/sha256.h>
|
||||
#include <wolfssl/wolfcrypt/coding.h>
|
||||
#include <wolfssh/ssh.h>
|
||||
#ifndef SO_NOSIGPIPE
|
||||
#include <signal.h>
|
||||
#endif
|
||||
#include <wolfssh/test.h>
|
||||
#include "examples/server/server.h"
|
||||
|
||||
|
||||
typedef int SOCKET_T;
|
||||
#ifdef TEST_IPV6
|
||||
typedef struct sockaddr_in6 SOCKADDR_IN_T;
|
||||
#define AF_INET_V AF_INET6
|
||||
static const char* wolfsshIP = "::1";
|
||||
#else
|
||||
typedef struct sockaddr_in SOCKADDR_IN_T;
|
||||
#define AF_INET_V AF_INET
|
||||
static const char* wolfsshIP = "127.0.0.1";
|
||||
#endif
|
||||
#define SERVER_PORT_NUMBER 22222
|
||||
#define SCRATCH_BUFFER_SIZE 1200
|
||||
static const char serverBanner[] = "wolfSSH Example Server\n";
|
||||
|
||||
#if defined(__MACH__) || defined(USE_WINDOWS_API)
|
||||
#ifndef _SOCKLEN_T
|
||||
typedef int socklen_t;
|
||||
#endif
|
||||
#endif
|
||||
/* HPUX doesn't use socklent_t for third parameter to accept, unless
|
||||
_XOPEN_SOURCE_EXTENDED is defined */
|
||||
#if !defined(__hpux__) && !defined(CYASSL_MDK_ARM) && !defined(CYASSL_IAR_ARM)
|
||||
typedef socklen_t SOCKLEN_T;
|
||||
#else
|
||||
#if defined _XOPEN_SOURCE_EXTENDED
|
||||
typedef socklen_t SOCKLEN_T;
|
||||
#else
|
||||
typedef int SOCKLEN_T;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(_POSIX_THREADS) && !defined(__MINGW32__)
|
||||
typedef void* THREAD_RETURN;
|
||||
typedef pthread_t THREAD_TYPE;
|
||||
#define CYASSL_THREAD
|
||||
#define INFINITE -1
|
||||
#define WAIT_OBJECT_0 0L
|
||||
#elif defined(CYASSL_MDK_ARM)
|
||||
typedef unsigned int THREAD_RETURN;
|
||||
typedef int THREAD_TYPE;
|
||||
#define CYASSL_THREAD
|
||||
#else
|
||||
typedef unsigned int THREAD_RETURN;
|
||||
typedef intptr_t THREAD_TYPE;
|
||||
#define CYASSL_THREAD __stdcall
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
SOCKET_T clientFd;
|
||||
WOLFSSH* ssh;
|
||||
SOCKET_T fd;
|
||||
word32 id;
|
||||
} thread_ctx_t;
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define WS_NORETURN __attribute__((noreturn))
|
||||
#else
|
||||
#define WS_NORETURN
|
||||
#ifndef EXAMPLE_HIGHWATER_MARK
|
||||
#define EXAMPLE_HIGHWATER_MARK 0x3FFF8000 /* 1GB - 32kB */
|
||||
#endif
|
||||
|
||||
|
||||
static INLINE WS_NORETURN void err_sys(const char* msg)
|
||||
{
|
||||
printf("server error: %s\n", msg);
|
||||
|
||||
#ifndef __GNUC__
|
||||
/* scan-build (which pretends to be gnuc) can get confused and think the
|
||||
* msg pointer can be null even when hardcoded and then it won't exit,
|
||||
* making null pointer checks above the err_sys() call useless.
|
||||
* We could just always exit() but some compilers will complain about no
|
||||
* possible return, with gcc we know the attribute to handle that with
|
||||
* WS_NORETURN. */
|
||||
if (msg)
|
||||
#ifndef EXAMPLE_BUFFER_SZ
|
||||
#define EXAMPLE_BUFFER_SZ 4096
|
||||
#endif
|
||||
{
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
#define SCRATCH_BUFFER_SZ 1200
|
||||
|
||||
|
||||
static INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer,
|
||||
uint16_t port)
|
||||
static byte find_char(const byte* str, const byte* buf, word32 bufSz)
|
||||
{
|
||||
int useLookup = 0;
|
||||
(void)useLookup;
|
||||
const byte* cur;
|
||||
|
||||
memset(addr, 0, sizeof(SOCKADDR_IN_T));
|
||||
|
||||
#ifndef TEST_IPV6
|
||||
/* peer could be in human readable form */
|
||||
if ( (peer != INADDR_ANY) && isalpha((int)peer[0])) {
|
||||
#ifdef CYASSL_MDK_ARM
|
||||
int err;
|
||||
struct hostent* entry = gethostbyname(peer, &err);
|
||||
#else
|
||||
struct hostent* entry = gethostbyname(peer);
|
||||
#endif
|
||||
|
||||
if (entry) {
|
||||
memcpy(&addr->sin_addr.s_addr, entry->h_addr_list[0],
|
||||
entry->h_length);
|
||||
useLookup = 1;
|
||||
while (bufSz) {
|
||||
cur = str;
|
||||
while (*cur != '\0') {
|
||||
if (*cur == *buf)
|
||||
return *cur;
|
||||
cur++;
|
||||
}
|
||||
else
|
||||
err_sys("no entry for host");
|
||||
buf++;
|
||||
bufSz--;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef TEST_IPV6
|
||||
#if defined(CYASSL_MDK_ARM)
|
||||
addr->sin_family = PF_INET;
|
||||
#else
|
||||
addr->sin_family = AF_INET_V;
|
||||
#endif
|
||||
addr->sin_port = htons(port);
|
||||
if (peer == INADDR_ANY)
|
||||
addr->sin_addr.s_addr = INADDR_ANY;
|
||||
else {
|
||||
if (!useLookup)
|
||||
addr->sin_addr.s_addr = inet_addr(peer);
|
||||
}
|
||||
#else
|
||||
addr->sin6_family = AF_INET_V;
|
||||
addr->sin6_port = htons(port);
|
||||
if (peer == INADDR_ANY)
|
||||
addr->sin6_addr = in6addr_any;
|
||||
else {
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
struct addrinfo hints;
|
||||
struct addrinfo* answer = NULL;
|
||||
int ret;
|
||||
char strPort[80];
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
|
||||
hints.ai_family = AF_INET_V;
|
||||
hints.ai_socktype = udp ? SOCK_DGRAM : SOCK_STREAM;
|
||||
hints.ai_protocol = udp ? IPPROTO_UDP : IPPROTO_TCP;
|
||||
|
||||
SNPRINTF(strPort, sizeof(strPort), "%d", port);
|
||||
strPort[79] = '\0';
|
||||
|
||||
ret = getaddrinfo(peer, strPort, &hints, &answer);
|
||||
if (ret < 0 || answer == NULL)
|
||||
err_sys("getaddrinfo failed");
|
||||
|
||||
memcpy(addr, answer->ai_addr, answer->ai_addrlen);
|
||||
freeaddrinfo(answer);
|
||||
#else
|
||||
printf("no ipv6 getaddrinfo, loopback only tests/examples\n");
|
||||
addr->sin6_addr = in6addr_loopback;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static INLINE void tcp_socket(SOCKET_T* sockFd)
|
||||
{
|
||||
*sockFd = socket(AF_INET_V, SOCK_STREAM, 0);
|
||||
|
||||
#ifdef USE_WINDOWS_API
|
||||
if (*sockFd == INVALID_SOCKET)
|
||||
err_sys("socket failed\n");
|
||||
#else
|
||||
if (*sockFd < 0)
|
||||
err_sys("socket failed\n");
|
||||
#endif
|
||||
|
||||
#ifndef USE_WINDOWS_API
|
||||
#ifdef SO_NOSIGPIPE
|
||||
{
|
||||
int on = 1;
|
||||
socklen_t len = sizeof(on);
|
||||
int res = setsockopt(*sockFd, SOL_SOCKET, SO_NOSIGPIPE, &on, len);
|
||||
if (res < 0)
|
||||
err_sys("setsockopt SO_NOSIGPIPE failed\n");
|
||||
}
|
||||
#elif defined(CYASSL_MDK_ARM)
|
||||
/* nothing to define */
|
||||
#else /* no S_NOSIGPIPE */
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
#endif /* S_NOSIGPIPE */
|
||||
|
||||
#if defined(TCP_NODELAY)
|
||||
{
|
||||
int on = 1;
|
||||
socklen_t len = sizeof(on);
|
||||
int res = setsockopt(*sockFd, IPPROTO_TCP, TCP_NODELAY, &on, len);
|
||||
if (res < 0)
|
||||
err_sys("setsockopt TCP_NODELAY failed\n");
|
||||
}
|
||||
#endif
|
||||
#endif /* USE_WINDOWS_API */
|
||||
}
|
||||
|
||||
|
||||
static INLINE void tcp_bind(SOCKET_T* sockFd, uint16_t port, int useAnyAddr)
|
||||
{
|
||||
SOCKADDR_IN_T addr;
|
||||
|
||||
/* don't use INADDR_ANY by default, firewall may block, make user switch
|
||||
on */
|
||||
build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfsshIP), port);
|
||||
tcp_socket(sockFd);
|
||||
|
||||
#if !defined(USE_WINDOWS_API) && !defined(CYASSL_MDK_ARM)
|
||||
{
|
||||
int res, on = 1;
|
||||
socklen_t len = sizeof(on);
|
||||
res = setsockopt(*sockFd, SOL_SOCKET, SO_REUSEADDR, &on, len);
|
||||
if (res < 0)
|
||||
err_sys("setsockopt SO_REUSEADDR failed\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (bind(*sockFd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
|
||||
err_sys("tcp bind failed");
|
||||
}
|
||||
|
||||
|
||||
static THREAD_RETURN CYASSL_THREAD server_worker(void* vArgs)
|
||||
{
|
||||
WOLFSSH* ssh = (WOLFSSH*)vArgs;
|
||||
SOCKET_T clientFd = wolfSSH_get_fd(ssh);
|
||||
const char* msgA = "Who's there?!\r\n";
|
||||
const char* msgB = "Go away!\r\n";
|
||||
|
||||
char rxBuf[4096];
|
||||
int rxBufSz;
|
||||
|
||||
if (wolfSSH_accept(ssh) == WS_SUCCESS) {
|
||||
|
||||
wolfSSH_stream_send(ssh, (uint8_t*)msgA, (uint32_t)strlen(msgA));
|
||||
|
||||
rxBufSz = wolfSSH_stream_read(ssh, (uint8_t*)rxBuf, sizeof(rxBuf));
|
||||
if (rxBufSz > 0) {
|
||||
rxBuf[rxBufSz] = 0;
|
||||
printf("client sent %d bytes\n%s", rxBufSz, rxBuf);
|
||||
}
|
||||
else
|
||||
printf("wolfSSH_stream_read returned %d\n", rxBufSz);
|
||||
|
||||
wolfSSH_stream_send(ssh, (uint8_t*)msgB, (uint32_t)strlen(msgB));
|
||||
}
|
||||
close(clientFd);
|
||||
wolfSSH_free(ssh);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int load_file(const char* fileName, uint8_t* buf, uint32_t bufSz)
|
||||
static int dump_stats(thread_ctx_t* ctx)
|
||||
{
|
||||
char stats[1024];
|
||||
word32 statsSz;
|
||||
word32 txCount, rxCount, seq, peerSeq;
|
||||
|
||||
wolfSSH_GetStats(ctx->ssh, &txCount, &rxCount, &seq, &peerSeq);
|
||||
|
||||
WSNPRINTF(stats, sizeof(stats),
|
||||
"Statistics for Thread #%u:\r\n"
|
||||
" txCount = %u\r\n rxCount = %u\r\n"
|
||||
" seq = %u\r\n peerSeq = %u\r\n",
|
||||
ctx->id, txCount, rxCount, seq, peerSeq);
|
||||
statsSz = (word32)strlen(stats);
|
||||
|
||||
fprintf(stderr, "%s", stats);
|
||||
return wolfSSH_stream_send(ctx->ssh, (byte*)stats, statsSz);
|
||||
}
|
||||
|
||||
|
||||
static THREAD_RETURN WOLFSSH_THREAD server_worker(void* vArgs)
|
||||
{
|
||||
thread_ctx_t* threadCtx = (thread_ctx_t*)vArgs;
|
||||
|
||||
if (wolfSSH_accept(threadCtx->ssh) == WS_SUCCESS) {
|
||||
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) {
|
||||
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)
|
||||
stop = 1;
|
||||
}
|
||||
|
||||
if (txSum < backlogSz)
|
||||
memmove(buf, buf + txSum, backlogSz - txSum);
|
||||
backlogSz -= txSum;
|
||||
}
|
||||
else
|
||||
stop = 1;
|
||||
}
|
||||
} while (!stop);
|
||||
|
||||
free(buf);
|
||||
}
|
||||
WCLOSESOCKET(threadCtx->fd);
|
||||
wolfSSH_free(threadCtx->ssh);
|
||||
free(threadCtx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int load_file(const char* fileName, byte* buf, word32 bufSz)
|
||||
{
|
||||
FILE* file;
|
||||
uint32_t fileSz;
|
||||
uint32_t readSz;
|
||||
word32 fileSz;
|
||||
word32 readSz;
|
||||
|
||||
if (fileName == NULL) return 0;
|
||||
|
||||
file = fopen(fileName, "rb");
|
||||
if (file == NULL) return 0;
|
||||
if (WFOPEN(&file, fileName, "rb") != 0)
|
||||
return 0;
|
||||
fseek(file, 0, SEEK_END);
|
||||
fileSz = (uint32_t)ftell(file);
|
||||
fileSz = (word32)ftell(file);
|
||||
rewind(file);
|
||||
|
||||
if (fileSz > bufSz) {
|
||||
|
|
@ -306,24 +185,324 @@ static int load_file(const char* fileName, uint8_t* buf, uint32_t bufSz)
|
|||
return 0;
|
||||
}
|
||||
|
||||
readSz = (uint32_t)fread(buf, 1, fileSz, file);
|
||||
readSz = (word32)fread(buf, 1, fileSz, file);
|
||||
if (readSz < fileSz) {
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
|
||||
return fileSz;
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
static INLINE void c32toa(word32 u32, byte* c)
|
||||
{
|
||||
c[0] = (u32 >> 24) & 0xff;
|
||||
c[1] = (u32 >> 16) & 0xff;
|
||||
c[2] = (u32 >> 8) & 0xff;
|
||||
c[3] = u32 & 0xff;
|
||||
}
|
||||
|
||||
|
||||
/* Map user names to passwords */
|
||||
/* Use arrays for username and p. The password or public key can
|
||||
* be hashed and the hash stored here. Then I won't need the type. */
|
||||
typedef struct PwMap {
|
||||
byte type;
|
||||
byte username[32];
|
||||
word32 usernameSz;
|
||||
byte p[SHA256_DIGEST_SIZE];
|
||||
struct PwMap* next;
|
||||
} PwMap;
|
||||
|
||||
|
||||
typedef struct PwMapList {
|
||||
PwMap* head;
|
||||
} PwMapList;
|
||||
|
||||
|
||||
static PwMap* PwMapNew(PwMapList* list, byte type, const byte* username,
|
||||
word32 usernameSz, const byte* p, word32 pSz)
|
||||
{
|
||||
PwMap* map;
|
||||
|
||||
map = (PwMap*)malloc(sizeof(PwMap));
|
||||
if (map != NULL) {
|
||||
Sha256 sha;
|
||||
byte flatSz[4];
|
||||
|
||||
map->type = type;
|
||||
if (usernameSz >= sizeof(map->username))
|
||||
usernameSz = sizeof(map->username) - 1;
|
||||
memcpy(map->username, username, usernameSz + 1);
|
||||
map->username[usernameSz] = 0;
|
||||
map->usernameSz = usernameSz;
|
||||
|
||||
wc_InitSha256(&sha);
|
||||
c32toa(pSz, flatSz);
|
||||
wc_Sha256Update(&sha, flatSz, sizeof(flatSz));
|
||||
wc_Sha256Update(&sha, p, pSz);
|
||||
wc_Sha256Final(&sha, map->p);
|
||||
|
||||
map->next = list->head;
|
||||
list->head = map;
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
static void PwMapListDelete(PwMapList* list)
|
||||
{
|
||||
if (list != NULL) {
|
||||
PwMap* head = list->head;
|
||||
|
||||
while (head != NULL) {
|
||||
PwMap* cur = head;
|
||||
head = head->next;
|
||||
memset(cur, 0, sizeof(PwMap));
|
||||
free(cur);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const char samplePasswordBuffer[] =
|
||||
"jill:upthehill\n"
|
||||
"jack:fetchapail\n";
|
||||
|
||||
|
||||
static const char samplePublicKeyEccBuffer[] =
|
||||
"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAA"
|
||||
"BBBNkI5JTP6D0lF42tbxX19cE87hztUS6FSDoGvPfiU0CgeNSbI+aFdKIzTP5CQEJSvm25"
|
||||
"qUzgDtH7oyaQROUnNvk= hansel\n"
|
||||
"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAA"
|
||||
"BBBKAtH8cqaDbtJFjtviLobHBmjCtG56DMkP6A4M2H9zX2/YCg1h9bYS7WHd9UQDwXO1Hh"
|
||||
"IZzRYecXh7SG9P4GhRY= gretel\n";
|
||||
|
||||
|
||||
static const char samplePublicKeyRsaBuffer[] =
|
||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC9P3ZFowOsONXHD5MwWiCciXytBRZGho"
|
||||
"MNiisWSgUs5HdHcACuHYPi2W6Z1PBFmBWT9odOrGRjoZXJfDDoPi+j8SSfDGsc/hsCmc3G"
|
||||
"p2yEhUZUEkDhtOXyqjns1ickC9Gh4u80aSVtwHRnJZh9xPhSq5tLOhId4eP61s+a5pwjTj"
|
||||
"nEhBaIPUJO2C/M0pFnnbZxKgJlX7t1Doy7h5eXxviymOIvaCZKU+x5OopfzM/wFkey0EPW"
|
||||
"NmzI5y/+pzU5afsdeEWdiQDIQc80H6Pz8fsoFPvYSG+s4/wz0duu7yeeV1Ypoho65Zr+pE"
|
||||
"nIf7dO0B8EblgWt+ud+JI8wrAhfE4x hansel\n"
|
||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqDwRVTRVk/wjPhoo66+Mztrc31KsxDZ"
|
||||
"+kAV0139PHQ+wsueNpba6jNn5o6mUTEOrxrz0LMsDJOBM7CmG0983kF4gRIihECpQ0rcjO"
|
||||
"P6BSfbVTE9mfIK5IsUiZGd8SoE9kSV2pJ2FvZeBQENoAxEFk0zZL9tchPS+OCUGbK4SDjz"
|
||||
"uNZl/30Mczs73N3MBzi6J1oPo7sFlqzB6ecBjK2Kpjus4Y1rYFphJnUxtKvB0s+hoaadru"
|
||||
"biE57dK6BrH5iZwVLTQKux31uCJLPhiktI3iLbdlGZEctJkTasfVSsUizwVIyRjhVKmbdI"
|
||||
"RGwkU38D043AR1h0mUoGCPIKuqcFMf gretel\n";
|
||||
|
||||
|
||||
static int LoadPasswordBuffer(byte* buf, word32 bufSz, PwMapList* list)
|
||||
{
|
||||
char* str = (char*)buf;
|
||||
char* delimiter;
|
||||
char* username;
|
||||
char* password;
|
||||
|
||||
/* Each line of passwd.txt is in the format
|
||||
* username:password\n
|
||||
* This function modifies the passed-in buffer. */
|
||||
|
||||
if (list == NULL)
|
||||
return -1;
|
||||
|
||||
if (buf == NULL || bufSz == 0)
|
||||
return 0;
|
||||
|
||||
while (*str != 0) {
|
||||
delimiter = strchr(str, ':');
|
||||
username = str;
|
||||
*delimiter = 0;
|
||||
password = delimiter + 1;
|
||||
str = strchr(password, '\n');
|
||||
*str = 0;
|
||||
str++;
|
||||
if (PwMapNew(list, WOLFSSH_USERAUTH_PASSWORD,
|
||||
(byte*)username, (word32)strlen(username),
|
||||
(byte*)password, (word32)strlen(password)) == NULL ) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int LoadPublicKeyBuffer(byte* buf, word32 bufSz, PwMapList* list)
|
||||
{
|
||||
char* str = (char*)buf;
|
||||
char* delimiter;
|
||||
byte* publicKey64;
|
||||
word32 publicKey64Sz;
|
||||
byte* username;
|
||||
word32 usernameSz;
|
||||
byte publicKey[300];
|
||||
word32 publicKeySz;
|
||||
|
||||
/* Each line of passwd.txt is in the format
|
||||
* ssh-rsa AAAB3BASE64ENCODEDPUBLICKEYBLOB username\n
|
||||
* This function modifies the passed-in buffer. */
|
||||
if (list == NULL)
|
||||
return -1;
|
||||
|
||||
if (buf == NULL || bufSz == 0)
|
||||
return 0;
|
||||
|
||||
while (*str != 0) {
|
||||
/* Skip the public key type. This example will always be ssh-rsa. */
|
||||
delimiter = strchr(str, ' ');
|
||||
str = delimiter + 1;
|
||||
delimiter = strchr(str, ' ');
|
||||
publicKey64 = (byte*)str;
|
||||
*delimiter = 0;
|
||||
publicKey64Sz = (word32)(delimiter - str);
|
||||
str = delimiter + 1;
|
||||
delimiter = strchr(str, '\n');
|
||||
username = (byte*)str;
|
||||
*delimiter = 0;
|
||||
usernameSz = (word32)(delimiter - str);
|
||||
str = delimiter + 1;
|
||||
publicKeySz = sizeof(publicKey);
|
||||
|
||||
if (Base64_Decode(publicKey64, publicKey64Sz,
|
||||
publicKey, &publicKeySz) != 0) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (PwMapNew(list, WOLFSSH_USERAUTH_PUBLICKEY,
|
||||
username, usernameSz,
|
||||
publicKey, publicKeySz) == NULL ) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int wsUserAuth(byte authType,
|
||||
WS_UserAuthData* authData,
|
||||
void* ctx)
|
||||
{
|
||||
PwMapList* list;
|
||||
PwMap* map;
|
||||
byte authHash[SHA256_DIGEST_SIZE];
|
||||
|
||||
if (ctx == NULL) {
|
||||
fprintf(stderr, "wsUserAuth: ctx not set");
|
||||
return WOLFSSH_USERAUTH_FAILURE;
|
||||
}
|
||||
|
||||
if (authType != WOLFSSH_USERAUTH_PASSWORD &&
|
||||
authType != WOLFSSH_USERAUTH_PUBLICKEY) {
|
||||
|
||||
return WOLFSSH_USERAUTH_FAILURE;
|
||||
}
|
||||
|
||||
/* Hash the password or public key with its length. */
|
||||
{
|
||||
Sha256 sha;
|
||||
byte flatSz[4];
|
||||
wc_InitSha256(&sha);
|
||||
if (authType == WOLFSSH_USERAUTH_PASSWORD) {
|
||||
c32toa(authData->sf.password.passwordSz, flatSz);
|
||||
wc_Sha256Update(&sha, flatSz, sizeof(flatSz));
|
||||
wc_Sha256Update(&sha,
|
||||
authData->sf.password.password,
|
||||
authData->sf.password.passwordSz);
|
||||
}
|
||||
else if (authType == WOLFSSH_USERAUTH_PUBLICKEY) {
|
||||
c32toa(authData->sf.publicKey.publicKeySz, flatSz);
|
||||
wc_Sha256Update(&sha, flatSz, sizeof(flatSz));
|
||||
wc_Sha256Update(&sha,
|
||||
authData->sf.publicKey.publicKey,
|
||||
authData->sf.publicKey.publicKeySz);
|
||||
}
|
||||
wc_Sha256Final(&sha, authHash);
|
||||
}
|
||||
|
||||
list = (PwMapList*)ctx;
|
||||
map = list->head;
|
||||
|
||||
while (map != NULL) {
|
||||
if (authData->usernameSz == map->usernameSz &&
|
||||
memcmp(authData->username, map->username, map->usernameSz) == 0) {
|
||||
|
||||
if (authData->type == map->type) {
|
||||
if (memcmp(map->p, authHash, SHA256_DIGEST_SIZE) == 0) {
|
||||
return WOLFSSH_USERAUTH_SUCCESS;
|
||||
}
|
||||
else {
|
||||
return (authType == WOLFSSH_USERAUTH_PASSWORD ?
|
||||
WOLFSSH_USERAUTH_INVALID_PASSWORD :
|
||||
WOLFSSH_USERAUTH_INVALID_PUBLICKEY);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return WOLFSSH_USERAUTH_INVALID_AUTHTYPE;
|
||||
}
|
||||
}
|
||||
map = map->next;
|
||||
}
|
||||
|
||||
return WOLFSSH_USERAUTH_INVALID_USER;
|
||||
}
|
||||
|
||||
|
||||
static void ShowUsage(void)
|
||||
{
|
||||
printf("server %s\n", LIBWOLFSSH_VERSION_STRING);
|
||||
printf("-h Help, print this usage\n");
|
||||
printf("-m Allow multiple connections\n");
|
||||
printf("-e Use ECC private key\n");
|
||||
}
|
||||
|
||||
|
||||
THREAD_RETURN WOLFSSH_THREAD server_test(void* args)
|
||||
{
|
||||
WOLFSSH_CTX* ctx = NULL;
|
||||
PwMapList pwMapList;
|
||||
SOCKET_T listenFd = 0;
|
||||
word32 defaultHighwater = EXAMPLE_HIGHWATER_MARK;
|
||||
word32 threadCount = 0;
|
||||
int multipleConnections = 0;
|
||||
int useEcc = 0;
|
||||
char ch;
|
||||
word16 port = wolfSshPort;
|
||||
|
||||
#ifdef DEBUG_WOLFSSH
|
||||
wolfSSH_Debugging_ON();
|
||||
#endif
|
||||
int argc = ((func_args*)args)->argc;
|
||||
char** argv = ((func_args*)args)->argv;
|
||||
((func_args*)args)->return_code = 0;
|
||||
|
||||
while ((ch = mygetopt(argc, argv, "hme")) != -1) {
|
||||
switch (ch) {
|
||||
case 'h' :
|
||||
ShowUsage();
|
||||
exit(EXIT_SUCCESS);
|
||||
|
||||
case 'm' :
|
||||
multipleConnections = 1;
|
||||
break;
|
||||
|
||||
case 'e' :
|
||||
useEcc = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
ShowUsage();
|
||||
exit(MY_EX_USAGE);
|
||||
}
|
||||
}
|
||||
myoptind = 0; /* reset for test cases */
|
||||
|
||||
if (wolfSSH_Init() != WS_SUCCESS) {
|
||||
fprintf(stderr, "Couldn't initialize wolfSSH.\n");
|
||||
|
|
@ -336,62 +515,91 @@ int main(void)
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
memset(&pwMapList, 0, sizeof(pwMapList));
|
||||
wolfSSH_SetUserAuth(ctx, wsUserAuth);
|
||||
wolfSSH_CTX_SetBanner(ctx, serverBanner);
|
||||
|
||||
{
|
||||
uint8_t buf[SCRATCH_BUFFER_SIZE];
|
||||
uint32_t bufSz;
|
||||
const char* bufName;
|
||||
byte buf[SCRATCH_BUFFER_SZ];
|
||||
word32 bufSz;
|
||||
|
||||
bufSz = load_file("./certs/server-cert.der", buf, SCRATCH_BUFFER_SIZE);
|
||||
if (bufSz == 0) {
|
||||
fprintf(stderr, "Couldn't load certificate file.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (wolfSSH_CTX_UseCert_buffer(ctx,
|
||||
buf, bufSz, WOLFSSH_FORMAT_ASN1) < 0) {
|
||||
fprintf(stderr, "Couldn't use certificate buffer.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
bufSz = load_file("./certs/server-key.der", buf, SCRATCH_BUFFER_SIZE);
|
||||
bufName = useEcc ? "./keys/server-key-ecc.der" :
|
||||
"./keys/server-key-rsa.der" ;
|
||||
bufSz = load_file(bufName, buf, SCRATCH_BUFFER_SZ);
|
||||
if (bufSz == 0) {
|
||||
fprintf(stderr, "Couldn't load key file.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (wolfSSH_CTX_UsePrivateKey_buffer(ctx,
|
||||
buf, bufSz, WOLFSSH_FORMAT_ASN1) < 0) {
|
||||
if (wolfSSH_CTX_UsePrivateKey_buffer(ctx, buf, bufSz,
|
||||
WOLFSSH_FORMAT_ASN1) < 0) {
|
||||
fprintf(stderr, "Couldn't use key buffer.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
bufSz = (word32)strlen(samplePasswordBuffer);
|
||||
memcpy(buf, samplePasswordBuffer, bufSz);
|
||||
buf[bufSz] = 0;
|
||||
LoadPasswordBuffer(buf, bufSz, &pwMapList);
|
||||
|
||||
bufName = useEcc ? samplePublicKeyEccBuffer :
|
||||
samplePublicKeyRsaBuffer;
|
||||
bufSz = (word32)strlen(bufName);
|
||||
memcpy(buf, bufName, bufSz);
|
||||
buf[bufSz] = 0;
|
||||
LoadPublicKeyBuffer(buf, bufSz, &pwMapList);
|
||||
}
|
||||
|
||||
tcp_bind(&listenFd, SERVER_PORT_NUMBER, 0);
|
||||
tcp_listen(&listenFd, &port, 1);
|
||||
|
||||
for (;;) {
|
||||
do {
|
||||
SOCKET_T clientFd = 0;
|
||||
SOCKADDR_IN_T clientAddr;
|
||||
SOCKLEN_T clientAddrSz = sizeof(clientAddr);
|
||||
socklen_t clientAddrSz = sizeof(clientAddr);
|
||||
THREAD_TYPE thread;
|
||||
WOLFSSH* ssh;
|
||||
thread_ctx_t* threadCtx;
|
||||
|
||||
threadCtx = (thread_ctx_t*)malloc(sizeof(thread_ctx_t));
|
||||
if (threadCtx == NULL) {
|
||||
fprintf(stderr, "Couldn't allocate thread context data.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ssh = wolfSSH_new(ctx);
|
||||
if (ssh == NULL) {
|
||||
fprintf(stderr, "Couldn't allocate SSH data.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (listen(listenFd, 5) != 0)
|
||||
err_sys("tcp listen failed");
|
||||
wolfSSH_SetUserAuthCtx(ssh, &pwMapList);
|
||||
/* Use the session object for its own highwater callback ctx */
|
||||
if (defaultHighwater > 0) {
|
||||
wolfSSH_SetHighwaterCtx(ssh, (void*)ssh);
|
||||
wolfSSH_SetHighwater(ssh, defaultHighwater);
|
||||
}
|
||||
|
||||
clientFd = accept(listenFd, (struct sockaddr*)&clientAddr,
|
||||
&clientAddrSz);
|
||||
if (clientFd == -1)
|
||||
err_sys("tcp accept failed");
|
||||
|
||||
wolfSSH_set_fd(ssh, clientFd);
|
||||
wolfSSH_set_fd(ssh, (int)clientFd);
|
||||
|
||||
pthread_create(&thread, 0, server_worker, ssh);
|
||||
pthread_detach(thread);
|
||||
}
|
||||
threadCtx->ssh = ssh;
|
||||
threadCtx->fd = clientFd;
|
||||
threadCtx->id = threadCount++;
|
||||
|
||||
start_thread(server_worker, threadCtx, &thread);
|
||||
|
||||
if (multipleConnections)
|
||||
detach_thread(thread);
|
||||
else
|
||||
join_thread(thread);
|
||||
|
||||
} while (multipleConnections);
|
||||
|
||||
PwMapListDelete(&pwMapList);
|
||||
wolfSSH_CTX_free(ctx);
|
||||
if (wolfSSH_Cleanup() != WS_SUCCESS) {
|
||||
fprintf(stderr, "Couldn't clean up wolfSSH.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
|
|
@ -400,3 +608,34 @@ int main(void)
|
|||
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();
|
||||
|
||||
ChangeToWolfSshRoot();
|
||||
#ifdef DEBUG_WOLFSSH
|
||||
wolfSSH_Debugging_ON();
|
||||
#endif
|
||||
|
||||
wolfSSH_Init();
|
||||
|
||||
server_test(&args);
|
||||
|
||||
wolfSSH_Cleanup();
|
||||
|
||||
return args.return_code;
|
||||
}
|
||||
|
||||
|
||||
int myoptind = 0;
|
||||
char* myoptarg = NULL;
|
||||
|
||||
#endif /* NO_MAIN_DRIVER */
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
/* server.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_SERVER_H_
|
||||
#define _WOLFSSH_SERVER_H_
|
||||
|
||||
|
||||
THREAD_RETURN WOLFSSH_THREAD server_test(void* args);
|
||||
|
||||
|
||||
#endif /* _WOLFSSH_SERVER_H_ */
|
||||
|
|
@ -0,0 +1,334 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="DLL Debug|Win32">
|
||||
<Configuration>DLL Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="DLL Debug|x64">
|
||||
<Configuration>DLL Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="DLL Release|Win32">
|
||||
<Configuration>DLL Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="DLL Release|x64">
|
||||
<Configuration>DLL Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\examples\client\client.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\wolfssh\wolfssh.vcxproj">
|
||||
<Project>{7c2ccf0d-a155-4914-bd1c-9a47c0530e65}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{663A7133-B13B-4C37-A5EC-97CA4D60CA3A}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>client</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\wolfssh.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='DLL Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\wolfssh.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\wolfssh.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='DLL Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\wolfssh.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\wolfssh.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='DLL Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\wolfssh.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\wolfssh.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='DLL Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\wolfssh.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IntDir>$(Configuration)\$(Platform)\obj\</IntDir>
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Debug|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IntDir>$(Configuration)\$(Platform)\obj\</IntDir>
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IntDir>$(Configuration)\$(Platform)\obj\</IntDir>
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Debug|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IntDir>$(Configuration)\$(Platform)\obj\</IntDir>
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(Platform)\obj\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(Platform)\obj\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(Platform)\obj\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(Platform)\obj\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>wolfssl.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries>
|
||||
<AdditionalLibraryDirectories>$(wolfCryptDebug32)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DLL Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>wolfssl.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries>
|
||||
<AdditionalLibraryDirectories>$(wolfCryptDllDebug32)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>wolfssl.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries>
|
||||
<AdditionalLibraryDirectories>$(wolfCryptDebug64)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DLL Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>wolfssl.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries>
|
||||
<AdditionalLibraryDirectories>$(wolfCryptDllDebug64)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>wolfssl.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>$(wolfCryptRelease32)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DLL Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>wolfssl.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>$(wolfCryptDllRelease32)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>wolfssl.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>$(wolfCryptRelease64)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DLL Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>wolfssl.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>$(wolfCryptDllRelease64)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Debug|Win32'">
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
<LocalDebuggerEnvironment>PATH=$(wolfCryptDllDebug32);%PATH%</LocalDebuggerEnvironment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Debug|x64'">
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
<LocalDebuggerEnvironment>PATH=$(wolfCryptDllDebug64);%PATH%</LocalDebuggerEnvironment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Release|Win32'">
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
<LocalDebuggerEnvironment>PATH=$(wolfCryptDllRelease32);%PATH%</LocalDebuggerEnvironment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Release|x64'">
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
<LocalDebuggerEnvironment>PATH=$(wolfCryptDllRelease64);%PATH%</LocalDebuggerEnvironment>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
@ -10,5 +10,7 @@ EXTRA_DIST+= ide/winvs/api-test/api-test.vcxproj
|
|||
EXTRA_DIST+= ide/winvs/api-test/api-test.vcxproj.user
|
||||
EXTRA_DIST+= ide/winvs/unit-test/unit-test.vcxproj
|
||||
EXTRA_DIST+= ide/winvs/unit-test/unit-test.vcxproj.user
|
||||
EXTRA_DIST+= ide/winvs/client/client.vcxproj
|
||||
EXTRA_DIST+= ide/winvs/client/client.vcxproj.user
|
||||
EXTRA_DIST+= ide/winvs/echoserver/echoserver.vcxproj
|
||||
EXTRA_DIST+= ide/winvs/echoserver/echoserver.vcxproj.user
|
||||
|
|
|
|||
|
|
@ -1,98 +1,116 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Express 2012 for Windows Desktop
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wolfssh", "wolfssh\wolfssh.vcxproj", "{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "api-test", "api-test\api-test.vcxproj", "{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65} = {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "echoserver", "echoserver\echoserver.vcxproj", "{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65} = {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unit-test", "unit-test\unit-test.vcxproj", "{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
DLL Debug|Win32 = DLL Debug|Win32
|
||||
DLL Debug|x64 = DLL Debug|x64
|
||||
DLL Release|Win32 = DLL Release|Win32
|
||||
DLL Release|x64 = DLL Release|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Debug|x64.Build.0 = Debug|x64
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.DLL Debug|Win32.Build.0 = DLL Debug|Win32
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.DLL Debug|x64.ActiveCfg = DLL Debug|x64
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.DLL Debug|x64.Build.0 = DLL Debug|x64
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.DLL Release|Win32.ActiveCfg = DLL Release|Win32
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.DLL Release|Win32.Build.0 = DLL Release|Win32
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.DLL Release|x64.ActiveCfg = DLL Release|x64
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.DLL Release|x64.Build.0 = DLL Release|x64
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Release|Win32.Build.0 = Release|Win32
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Release|x64.ActiveCfg = Release|x64
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Release|x64.Build.0 = Release|x64
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Debug|x64.Build.0 = Debug|x64
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.DLL Debug|Win32.Build.0 = DLL Debug|Win32
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.DLL Debug|x64.ActiveCfg = DLL Debug|x64
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.DLL Debug|x64.Build.0 = DLL Debug|x64
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.DLL Release|Win32.ActiveCfg = DLL Release|Win32
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.DLL Release|Win32.Build.0 = DLL Release|Win32
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.DLL Release|x64.ActiveCfg = DLL Release|x64
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.DLL Release|x64.Build.0 = DLL Release|x64
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Release|Win32.Build.0 = Release|Win32
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Release|x64.ActiveCfg = Release|x64
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Release|x64.Build.0 = Release|x64
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Debug|x64.Build.0 = Debug|x64
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.DLL Debug|Win32.Build.0 = DLL Debug|Win32
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.DLL Debug|x64.ActiveCfg = DLL Debug|x64
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.DLL Debug|x64.Build.0 = DLL Debug|x64
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.DLL Release|Win32.ActiveCfg = DLL Release|Win32
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.DLL Release|Win32.Build.0 = DLL Release|Win32
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.DLL Release|x64.ActiveCfg = DLL Release|x64
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.DLL Release|x64.Build.0 = DLL Release|x64
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Release|Win32.Build.0 = Release|Win32
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Release|x64.ActiveCfg = Release|x64
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Release|x64.Build.0 = Release|x64
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.Debug|x64.Build.0 = Debug|x64
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.DLL Debug|Win32.Build.0 = DLL Debug|Win32
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.DLL Debug|x64.ActiveCfg = DLL Debug|x64
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.DLL Debug|x64.Build.0 = DLL Debug|x64
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.DLL Release|Win32.ActiveCfg = DLL Release|Win32
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.DLL Release|Win32.Build.0 = DLL Release|Win32
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.DLL Release|x64.ActiveCfg = DLL Release|x64
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.DLL Release|x64.Build.0 = DLL Release|x64
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.Release|Win32.Build.0 = Release|Win32
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.Release|x64.ActiveCfg = Release|x64
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Express 2012 for Windows Desktop
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wolfssh", "wolfssh\wolfssh.vcxproj", "{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "api-test", "api-test\api-test.vcxproj", "{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65} = {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "echoserver", "echoserver\echoserver.vcxproj", "{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65} = {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unit-test", "unit-test\unit-test.vcxproj", "{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "client", "client\client.vcxproj", "{663A7133-B13B-4C37-A5EC-97CA4D60CA3A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
DLL Debug|Win32 = DLL Debug|Win32
|
||||
DLL Debug|x64 = DLL Debug|x64
|
||||
DLL Release|Win32 = DLL Release|Win32
|
||||
DLL Release|x64 = DLL Release|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Debug|x64.Build.0 = Debug|x64
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.DLL Debug|Win32.Build.0 = DLL Debug|Win32
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.DLL Debug|x64.ActiveCfg = DLL Debug|x64
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.DLL Debug|x64.Build.0 = DLL Debug|x64
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.DLL Release|Win32.ActiveCfg = DLL Release|Win32
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.DLL Release|Win32.Build.0 = DLL Release|Win32
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.DLL Release|x64.ActiveCfg = DLL Release|x64
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.DLL Release|x64.Build.0 = DLL Release|x64
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Release|Win32.Build.0 = Release|Win32
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Release|x64.ActiveCfg = Release|x64
|
||||
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Release|x64.Build.0 = Release|x64
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Debug|x64.Build.0 = Debug|x64
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.DLL Debug|Win32.Build.0 = DLL Debug|Win32
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.DLL Debug|x64.ActiveCfg = DLL Debug|x64
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.DLL Debug|x64.Build.0 = DLL Debug|x64
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.DLL Release|Win32.ActiveCfg = DLL Release|Win32
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.DLL Release|Win32.Build.0 = DLL Release|Win32
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.DLL Release|x64.ActiveCfg = DLL Release|x64
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.DLL Release|x64.Build.0 = DLL Release|x64
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Release|Win32.Build.0 = Release|Win32
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Release|x64.ActiveCfg = Release|x64
|
||||
{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Release|x64.Build.0 = Release|x64
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Debug|x64.Build.0 = Debug|x64
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.DLL Debug|Win32.Build.0 = DLL Debug|Win32
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.DLL Debug|x64.ActiveCfg = DLL Debug|x64
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.DLL Debug|x64.Build.0 = DLL Debug|x64
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.DLL Release|Win32.ActiveCfg = DLL Release|Win32
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.DLL Release|Win32.Build.0 = DLL Release|Win32
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.DLL Release|x64.ActiveCfg = DLL Release|x64
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.DLL Release|x64.Build.0 = DLL Release|x64
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Release|Win32.Build.0 = Release|Win32
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Release|x64.ActiveCfg = Release|x64
|
||||
{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Release|x64.Build.0 = Release|x64
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.Debug|x64.Build.0 = Debug|x64
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.DLL Debug|Win32.Build.0 = DLL Debug|Win32
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.DLL Debug|x64.ActiveCfg = DLL Debug|x64
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.DLL Debug|x64.Build.0 = DLL Debug|x64
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.DLL Release|Win32.ActiveCfg = DLL Release|Win32
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.DLL Release|Win32.Build.0 = DLL Release|Win32
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.DLL Release|x64.ActiveCfg = DLL Release|x64
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.DLL Release|x64.Build.0 = DLL Release|x64
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.Release|Win32.Build.0 = Release|Win32
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.Release|x64.ActiveCfg = Release|x64
|
||||
{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.Release|x64.Build.0 = Release|x64
|
||||
{663A7133-B13B-4C37-A5EC-97CA4D60CA3A}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{663A7133-B13B-4C37-A5EC-97CA4D60CA3A}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{663A7133-B13B-4C37-A5EC-97CA4D60CA3A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{663A7133-B13B-4C37-A5EC-97CA4D60CA3A}.Debug|x64.Build.0 = Debug|x64
|
||||
{663A7133-B13B-4C37-A5EC-97CA4D60CA3A}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32
|
||||
{663A7133-B13B-4C37-A5EC-97CA4D60CA3A}.DLL Debug|Win32.Build.0 = DLL Debug|Win32
|
||||
{663A7133-B13B-4C37-A5EC-97CA4D60CA3A}.DLL Debug|x64.ActiveCfg = DLL Debug|x64
|
||||
{663A7133-B13B-4C37-A5EC-97CA4D60CA3A}.DLL Debug|x64.Build.0 = DLL Debug|x64
|
||||
{663A7133-B13B-4C37-A5EC-97CA4D60CA3A}.DLL Release|Win32.ActiveCfg = DLL Release|Win32
|
||||
{663A7133-B13B-4C37-A5EC-97CA4D60CA3A}.DLL Release|Win32.Build.0 = DLL Release|Win32
|
||||
{663A7133-B13B-4C37-A5EC-97CA4D60CA3A}.DLL Release|x64.ActiveCfg = DLL Release|x64
|
||||
{663A7133-B13B-4C37-A5EC-97CA4D60CA3A}.DLL Release|x64.Build.0 = DLL Release|x64
|
||||
{663A7133-B13B-4C37-A5EC-97CA4D60CA3A}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{663A7133-B13B-4C37-A5EC-97CA4D60CA3A}.Release|Win32.Build.0 = Release|Win32
|
||||
{663A7133-B13B-4C37-A5EC-97CA4D60CA3A}.Release|x64.ActiveCfg = Release|x64
|
||||
{663A7133-B13B-4C37-A5EC-97CA4D60CA3A}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIFWdSB6pL/oYzrP6d0YAxNvTiz6d72/NN0aHIzx3mat4oAoGCCqGSM49
|
||||
AwEHoUQDQgAEoC0fxypoNu0kWO2+IuhscGaMK0bnoMyQ/oDgzYf3Nfb9gKDWH1th
|
||||
LtYd31RAPBc7UeEhnNFh5xeHtIb0/gaFFg==
|
||||
-----END EC PRIVATE KEY-----
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIANuF9O5uKvI+R/xLURMOxKxpHfY7Q5qvmDC9ovn04eDoAoGCCqGSM49
|
||||
AwEHoUQDQgAE2QjklM/oPSUXja1vFfX1wTzuHO1RLoVIOga89+JTQKB41Jsj5oV0
|
||||
ojNM/kJAQlK+bbmpTOAO0fujJpBE5Sc2+Q==
|
||||
-----END EC PRIVATE KEY-----
|
||||
|
|
@ -12,7 +12,10 @@ EXTRA_DIST+= \
|
|||
keys/server-key-ecc-521.pem \
|
||||
keys/server-key-rsa.der \
|
||||
keys/server-key-rsa.pem \
|
||||
keys/key-hansel.pem \
|
||||
keys/key-gretel.pem \
|
||||
keys/publickeys.txt \
|
||||
keys/hansel-key-ecc.pem \
|
||||
keys/hansel-key-rsa.pem \
|
||||
keys/gretel-key-ecc.pem \
|
||||
keys/gretel-key-rsa.pem \
|
||||
keys/pubkeys-ecc.txt \
|
||||
keys/pubkeys-rsa.txt \
|
||||
keys/passwd.txt
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNkI5JTP6D0lF42tbxX19cE87hztUS6FSDoGvPfiU0CgeNSbI+aFdKIzTP5CQEJSvm25qUzgDtH7oyaQROUnNvk= hansel
|
||||
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKAtH8cqaDbtJFjtviLobHBmjCtG56DMkP6A4M2H9zX2/YCg1h9bYS7WHd9UQDwXO1HhIZzRYecXh7SG9P4GhRY= gretel
|
||||
374
src/internal.c
374
src/internal.c
|
|
@ -37,6 +37,7 @@
|
|||
#include <wolfssl/wolfcrypt/rsa.h>
|
||||
#include <wolfssl/wolfcrypt/ecc.h>
|
||||
#include <wolfssl/wolfcrypt/hmac.h>
|
||||
#include <wolfssl/wolfcrypt/integer.h>
|
||||
#include <wolfssl/wolfcrypt/signature.h>
|
||||
|
||||
#ifdef NO_INLINE
|
||||
|
|
@ -1310,7 +1311,6 @@ static int GetUint32(word32* v, byte* buf, word32 len, word32* idx)
|
|||
}
|
||||
|
||||
|
||||
#ifndef WOLFSSH_NO_CLIENT
|
||||
/* Gets the size of the mpint, and puts the pointer to the start of
|
||||
* buf's number into *mpint. This function does not copy. */
|
||||
static int GetMpint(word32* mpintSz, byte** mpint,
|
||||
|
|
@ -1332,7 +1332,6 @@ static int GetMpint(word32* mpintSz, byte** mpint,
|
|||
|
||||
return result;
|
||||
}
|
||||
#endif /* WOLFSSH_NO_CLIENT */
|
||||
|
||||
|
||||
/* Gets the size of a string, copies it as much of it as will fit in
|
||||
|
|
@ -2008,7 +2007,6 @@ static int DoKexDhInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
|
|||
}
|
||||
|
||||
|
||||
#ifndef WOLFSSH_NO_CLIENT
|
||||
static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
|
||||
{
|
||||
byte* pubKey;
|
||||
|
|
@ -2316,7 +2314,6 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
|
|||
WLOG(WS_LOG_DEBUG, "Leaving DoKexDhReply(), ret = %d", ret);
|
||||
return ret;
|
||||
}
|
||||
#endif /* WOLFSSH_NO_CLIENT */
|
||||
|
||||
|
||||
static int DoNewKeys(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
|
||||
|
|
@ -2416,7 +2413,6 @@ static int DoKexDhGexRequest(WOLFSSH* ssh,
|
|||
}
|
||||
|
||||
|
||||
#ifndef WOLFSSH_NO_CLIENT
|
||||
static int DoKexDhGexGroup(WOLFSSH* ssh,
|
||||
byte* buf, word32 len, word32* idx)
|
||||
{
|
||||
|
|
@ -2473,7 +2469,6 @@ static int DoKexDhGexGroup(WOLFSSH* ssh,
|
|||
|
||||
return ret;
|
||||
}
|
||||
#endif /* WOLFSSH_NO_CLIENT */
|
||||
|
||||
|
||||
static int DoIgnore(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
|
||||
|
|
@ -2654,7 +2649,6 @@ static int DoServiceRequest(WOLFSSH* ssh,
|
|||
}
|
||||
|
||||
|
||||
#ifndef WOLFSSH_NO_CLIENT
|
||||
static int DoServiceAccept(WOLFSSH* ssh,
|
||||
byte* buf, word32 len, word32* idx)
|
||||
{
|
||||
|
|
@ -2678,7 +2672,6 @@ static int DoServiceAccept(WOLFSSH* ssh,
|
|||
|
||||
return WS_SUCCESS;
|
||||
}
|
||||
#endif /* WOLFSSH_NO_CLIENT */
|
||||
|
||||
|
||||
/* Utility for DoUserAuthRequest() */
|
||||
|
|
@ -2756,9 +2749,11 @@ static int DoUserAuthRequestPassword(WOLFSSH* ssh, WS_UserAuthData* authData,
|
|||
/* Utility for DoUserAuthRequestPublicKey() */
|
||||
/* returns negative for error, positive is size of digest. */
|
||||
static int DoUserAuthRequestRsa(WOLFSSH* ssh, WS_UserAuthData_PublicKey* pk,
|
||||
byte* digest, word32 digestSz)
|
||||
byte hashId, byte* digest, word32 digestSz)
|
||||
{
|
||||
RsaKey key;
|
||||
byte checkDigest[MAX_ENCODED_SIG_SZ];
|
||||
int checkDigestSz;
|
||||
byte* publicKeyType;
|
||||
word32 publicKeyTypeSz = 0;
|
||||
byte* n;
|
||||
|
|
@ -2836,13 +2831,34 @@ static int DoUserAuthRequestRsa(WOLFSSH* ssh, WS_UserAuthData_PublicKey* pk,
|
|||
|
||||
if (ret == WS_SUCCESS) {
|
||||
n = pk->signature + i;
|
||||
ret = wc_RsaSSL_Verify(n, nSz, digest, digestSz, &key);
|
||||
if (ret <= 0) {
|
||||
checkDigestSz = wc_RsaSSL_Verify(n, nSz, checkDigest,
|
||||
sizeof(checkDigest), &key);
|
||||
if (checkDigestSz <= 0) {
|
||||
WLOG(WS_LOG_DEBUG, "Could not verify signature");
|
||||
ret = WS_CRYPTO_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
byte encDigest[MAX_ENCODED_SIG_SZ];
|
||||
word32 encDigestSz;
|
||||
volatile int compare;
|
||||
volatile int sizeCompare;
|
||||
|
||||
encDigestSz = wc_EncodeSignature(encDigest, digest,
|
||||
wc_HashGetDigestSize(hashId),
|
||||
wc_HashGetOID(hashId));
|
||||
|
||||
compare = ConstantCompare(encDigest, checkDigest,
|
||||
encDigestSz);
|
||||
sizeCompare = encDigestSz != (word32)checkDigestSz;
|
||||
|
||||
if ((compare | sizeCompare) == 0)
|
||||
ret = WS_SUCCESS;
|
||||
else
|
||||
ret = WS_RSA_E;
|
||||
}
|
||||
|
||||
wc_FreeRsaKey(&key);
|
||||
|
||||
WLOG(WS_LOG_DEBUG, "Leaving DoUserAuthRequestRsa(), ret = %d", ret);
|
||||
|
|
@ -2850,6 +2866,141 @@ static int DoUserAuthRequestRsa(WOLFSSH* ssh, WS_UserAuthData_PublicKey* pk,
|
|||
}
|
||||
|
||||
|
||||
/* Utility for DoUserAuthRequestPublicKey() */
|
||||
/* returns negative for error, positive is size of digest. */
|
||||
static int DoUserAuthRequestEcc(WOLFSSH* ssh, WS_UserAuthData_PublicKey* pk,
|
||||
byte hashId, byte* digest, word32 digestSz)
|
||||
{
|
||||
ecc_key key;
|
||||
byte* publicKeyType;
|
||||
word32 publicKeyTypeSz = 0;
|
||||
byte* curveName;
|
||||
word32 curveNameSz = 0;
|
||||
mp_int r, s;
|
||||
byte* q;
|
||||
word32 sz, qSz;
|
||||
word32 i = 0;
|
||||
int ret = WS_SUCCESS;
|
||||
|
||||
(void)hashId;
|
||||
|
||||
WLOG(WS_LOG_DEBUG, "Entering DoUserAuthRequestRsa()");
|
||||
|
||||
if (ssh == NULL || pk == NULL || digest == NULL || digestSz == 0)
|
||||
ret = WS_BAD_ARGUMENT;
|
||||
|
||||
/* First check that the public key's type matches the one we are
|
||||
* expecting. */
|
||||
if (ret == WS_SUCCESS)
|
||||
ret = GetUint32(&publicKeyTypeSz, pk->publicKey, pk->publicKeySz, &i);
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
publicKeyType = pk->publicKey + i;
|
||||
i += publicKeyTypeSz;
|
||||
if (publicKeyTypeSz != pk->publicKeyTypeSz &&
|
||||
WMEMCMP(publicKeyType, pk->publicKeyType, publicKeyTypeSz) != 0) {
|
||||
|
||||
WLOG(WS_LOG_DEBUG,
|
||||
"Public Key's type does not match public key type");
|
||||
ret = WS_INVALID_ALGO_ID;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == WS_SUCCESS)
|
||||
ret = GetUint32(&curveNameSz, pk->publicKey, pk->publicKeySz, &i);
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
curveName = pk->publicKey + i;
|
||||
i += curveNameSz;
|
||||
ret = GetUint32(&qSz, pk->publicKey, pk->publicKeySz, &i);
|
||||
}
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
q = pk->publicKey + i;
|
||||
i += qSz;
|
||||
ret = wc_ecc_init_ex(&key, ssh->ctx->heap, INVALID_DEVID);
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
ret = wc_ecc_import_x963(q, qSz, &key);
|
||||
|
||||
if (ret != 0) {
|
||||
WLOG(WS_LOG_DEBUG, "Could not decode public key");
|
||||
ret = WS_CRYPTO_FAILED;
|
||||
}
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
i = 0;
|
||||
/* First check that the signature's public key type matches the one
|
||||
* we are expecting. */
|
||||
ret = GetUint32(&publicKeyTypeSz, pk->signature, pk->signatureSz, &i);
|
||||
}
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
publicKeyType = pk->signature + i;
|
||||
i += publicKeyTypeSz;
|
||||
|
||||
if (publicKeyTypeSz != pk->publicKeyTypeSz &&
|
||||
WMEMCMP(publicKeyType, pk->publicKeyType, publicKeyTypeSz) != 0) {
|
||||
|
||||
WLOG(WS_LOG_DEBUG,
|
||||
"Signature's type does not match public key type");
|
||||
ret = WS_INVALID_ALGO_ID;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
/* Get the size of the signature blob. */
|
||||
ret = GetUint32(&sz, pk->signature, pk->signatureSz, &i);
|
||||
}
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
/* Get R and S. */
|
||||
ret = GetUint32(&sz, pk->signature, pk->signatureSz, &i);
|
||||
}
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
ret = mp_read_unsigned_bin(&r, pk->signature + i, sz);
|
||||
if (ret != 0)
|
||||
ret = WS_PARSE_E;
|
||||
else
|
||||
ret = WS_SUCCESS;
|
||||
}
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
i += sz;
|
||||
ret = GetUint32(&sz, pk->signature, pk->signatureSz, &i);
|
||||
}
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
ret = mp_read_unsigned_bin(&s, pk->signature + i, sz);
|
||||
if (ret != 0)
|
||||
ret = WS_PARSE_E;
|
||||
else
|
||||
ret = WS_SUCCESS;
|
||||
}
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
int status = 0;
|
||||
|
||||
ret = wc_ecc_verify_hash_ex(&r, &s, digest, digestSz, &status, &key);
|
||||
if (ret != 0) {
|
||||
WLOG(WS_LOG_DEBUG, "Could not verify signature");
|
||||
ret = WS_CRYPTO_FAILED;
|
||||
}
|
||||
else
|
||||
ret = status ? WS_SUCCESS : WS_ECC_E;
|
||||
}
|
||||
|
||||
mp_clear(&r);
|
||||
mp_clear(&s);
|
||||
wc_ecc_free(&key);
|
||||
|
||||
WLOG(WS_LOG_DEBUG, "Leaving DoUserAuthRequestEcc(), ret = %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Utility for DoUserAuthRequest() */
|
||||
static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData,
|
||||
byte* buf, word32 len, word32* idx)
|
||||
|
|
@ -2929,80 +3080,73 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData,
|
|||
pk->publicKey, pk->publicKeySz);
|
||||
}
|
||||
else {
|
||||
byte checkDigest[MAX_ENCODED_SIG_SZ];
|
||||
word32 checkDigestSz = sizeof(checkDigest);
|
||||
byte encDigest[MAX_ENCODED_SIG_SZ];
|
||||
word32 encDigestSz;
|
||||
wc_HashAlg hash;
|
||||
byte digest[WC_MAX_DIGEST_SIZE];
|
||||
word32 digestSz;
|
||||
byte hashId = WC_HASH_TYPE_SHA;
|
||||
byte pkTypeId;
|
||||
|
||||
WMEMSET(checkDigest, 0, sizeof(checkDigest));
|
||||
WMEMSET(encDigest, 0, sizeof(encDigest));
|
||||
|
||||
pkTypeId = NameToId((char*)pk->publicKeyType, pk->publicKeyTypeSz);
|
||||
|
||||
if (pkTypeId == ID_SSH_RSA)
|
||||
ret = DoUserAuthRequestRsa(ssh, pk, checkDigest, checkDigestSz);
|
||||
else
|
||||
pkTypeId = NameToId((char*)pk->publicKeyType,
|
||||
pk->publicKeyTypeSz);
|
||||
if (pkTypeId == ID_UNKNOWN)
|
||||
ret = WS_INVALID_ALGO_ID;
|
||||
|
||||
if (ret > 0) {
|
||||
checkDigestSz = (word32)ret;
|
||||
ret = WS_SUCCESS;
|
||||
if (ret == WS_SUCCESS) {
|
||||
hashId = HashForId(pkTypeId);
|
||||
WMEMSET(digest, 0, sizeof(digest));
|
||||
digestSz = wc_HashGetDigestSize(hashId);
|
||||
ret = wc_HashInit(&hash, hashId);
|
||||
}
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
wc_HashAlg hash;
|
||||
byte hashId = WC_HASH_TYPE_SHA;
|
||||
byte digest[WC_MAX_DIGEST_SIZE];
|
||||
volatile int compare;
|
||||
volatile int sizeCompare;
|
||||
if (ret == 0) {
|
||||
c32toa(ssh->sessionIdSz, digest);
|
||||
ret = wc_HashUpdate(&hash, hashId, digest, UINT32_SZ);
|
||||
}
|
||||
|
||||
ret = wc_HashInit(&hash, hashId);
|
||||
if (ret == 0) {
|
||||
c32toa(ssh->sessionIdSz, digest);
|
||||
ret = wc_HashUpdate(&hash, hashId, digest, UINT32_SZ);
|
||||
}
|
||||
if (ret == WS_SUCCESS)
|
||||
ret = wc_HashUpdate(&hash, hashId,
|
||||
ssh->sessionId, ssh->sessionIdSz);
|
||||
if (ret == 0)
|
||||
ret = wc_HashUpdate(&hash, hashId,
|
||||
ssh->sessionId, ssh->sessionIdSz);
|
||||
|
||||
if (ret == 0) {
|
||||
digest[0] = MSGID_USERAUTH_REQUEST;
|
||||
ret = wc_HashUpdate(&hash, hashId, digest, MSG_ID_SZ);
|
||||
}
|
||||
if (ret == 0) {
|
||||
digest[0] = MSGID_USERAUTH_REQUEST;
|
||||
ret = wc_HashUpdate(&hash, hashId, digest, MSG_ID_SZ);
|
||||
}
|
||||
|
||||
/* The rest of the fields in the signature are already
|
||||
* in the buffer. Just need to account for the sizes. */
|
||||
if (ret == 0)
|
||||
ret = wc_HashUpdate(&hash, hashId, pk->dataToSign,
|
||||
authData->usernameSz +
|
||||
authData->serviceNameSz +
|
||||
authData->authNameSz + BOOLEAN_SZ +
|
||||
pk->publicKeyTypeSz + pk->publicKeySz +
|
||||
(UINT32_SZ * 5));
|
||||
if (ret == 0)
|
||||
ret = wc_HashFinal(&hash, hashId, digest);
|
||||
|
||||
encDigestSz = wc_EncodeSignature(encDigest, digest,
|
||||
wc_HashGetDigestSize(hashId),
|
||||
wc_HashGetOID(hashId));
|
||||
/* The rest of the fields in the signature are already
|
||||
* in the buffer. Just need to account for the sizes. */
|
||||
if (ret == 0)
|
||||
ret = wc_HashUpdate(&hash, hashId, pk->dataToSign,
|
||||
authData->usernameSz +
|
||||
authData->serviceNameSz +
|
||||
authData->authNameSz + BOOLEAN_SZ +
|
||||
pk->publicKeyTypeSz + pk->publicKeySz +
|
||||
(UINT32_SZ * 5));
|
||||
if (ret == 0) {
|
||||
ret = wc_HashFinal(&hash, hashId, digest);
|
||||
|
||||
if (ret != 0)
|
||||
ret = WS_CRYPTO_FAILED;
|
||||
else
|
||||
ret = WS_SUCCESS;
|
||||
}
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
compare = ConstantCompare(encDigest, checkDigest,
|
||||
encDigestSz);
|
||||
sizeCompare = encDigestSz != checkDigestSz;
|
||||
if (ret == WS_SUCCESS) {
|
||||
if (pkTypeId == ID_SSH_RSA)
|
||||
ret = DoUserAuthRequestRsa(ssh, pk,
|
||||
hashId, digest, digestSz);
|
||||
else if (pkTypeId == ID_ECDSA_SHA2_NISTP256 ||
|
||||
pkTypeId == ID_ECDSA_SHA2_NISTP384 ||
|
||||
pkTypeId == ID_ECDSA_SHA2_NISTP521)
|
||||
ret = DoUserAuthRequestEcc(ssh, pk,
|
||||
hashId, digest, digestSz);
|
||||
}
|
||||
|
||||
if (compare || sizeCompare || ret < 0) {
|
||||
WLOG(WS_LOG_DEBUG, "DUARPK: signature compare failure");
|
||||
ret = SendUserAuthFailure(ssh, 0);
|
||||
}
|
||||
else {
|
||||
ssh->clientState = CLIENT_USERAUTH_DONE;
|
||||
}
|
||||
}
|
||||
if (ret != WS_SUCCESS) {
|
||||
WLOG(WS_LOG_DEBUG, "DUARPK: signature compare failure");
|
||||
ret = SendUserAuthFailure(ssh, 0);
|
||||
}
|
||||
else {
|
||||
ssh->clientState = CLIENT_USERAUTH_DONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3075,7 +3219,6 @@ static int DoUserAuthRequest(WOLFSSH* ssh,
|
|||
}
|
||||
|
||||
|
||||
#ifndef WOLFSSH_NO_CLIENT
|
||||
static int DoUserAuthFailure(WOLFSSH* ssh,
|
||||
byte* buf, word32 len, word32* idx)
|
||||
{
|
||||
|
|
@ -3152,7 +3295,6 @@ static int DoUserAuthBanner(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
|
|||
WLOG(WS_LOG_DEBUG, "Leaving DoUserAuthBanner(), ret = %d", ret);
|
||||
return ret;
|
||||
}
|
||||
#endif /* WOLFSSH_NO_CLIENT */
|
||||
|
||||
|
||||
static int DoGlobalRequest(WOLFSSH* ssh,
|
||||
|
|
@ -3630,6 +3772,17 @@ static int DoPacket(WOLFSSH* ssh)
|
|||
ret = DoKexDhInit(ssh, buf + idx, payloadSz, &payloadIdx);
|
||||
break;
|
||||
|
||||
case MSGID_KEXDH_REPLY:
|
||||
if (ssh->handshake->kexId == ID_DH_GEX_SHA256) {
|
||||
WLOG(WS_LOG_DEBUG, "Decoding MSGID_KEXDH_GEX_GROUP");
|
||||
ret = DoKexDhGexGroup(ssh, buf + idx, payloadSz, &payloadIdx);
|
||||
}
|
||||
else {
|
||||
WLOG(WS_LOG_DEBUG, "Decoding MSGID_KEXDH_REPLY");
|
||||
ret = DoKexDhReply(ssh, buf + idx, payloadSz, &payloadIdx);
|
||||
}
|
||||
break;
|
||||
|
||||
case MSGID_KEXDH_GEX_REQUEST:
|
||||
WLOG(WS_LOG_DEBUG, "Decoding MSGID_KEXDH_GEX_REQUEST");
|
||||
ret = DoKexDhGexRequest(ssh, buf + idx, payloadSz, &payloadIdx);
|
||||
|
|
@ -3640,16 +3793,41 @@ static int DoPacket(WOLFSSH* ssh)
|
|||
ret = DoKexDhInit(ssh, buf + idx, payloadSz, &payloadIdx);
|
||||
break;
|
||||
|
||||
case MSGID_KEXDH_GEX_REPLY:
|
||||
WLOG(WS_LOG_DEBUG, "Decoding MSGID_KEXDH_GEX_INIT");
|
||||
ret = DoKexDhReply(ssh, buf + idx, payloadSz, &payloadIdx);
|
||||
break;
|
||||
|
||||
case MSGID_SERVICE_REQUEST:
|
||||
WLOG(WS_LOG_DEBUG, "Decoding MSGID_SERVICE_REQUEST");
|
||||
ret = DoServiceRequest(ssh, buf + idx, payloadSz, &payloadIdx);
|
||||
break;
|
||||
|
||||
case MSGID_SERVICE_ACCEPT:
|
||||
WLOG(WS_LOG_DEBUG, "Decoding MSGID_SERVER_ACCEPT");
|
||||
ret = DoServiceAccept(ssh, buf + idx, payloadSz, &payloadIdx);
|
||||
break;
|
||||
|
||||
case MSGID_USERAUTH_REQUEST:
|
||||
WLOG(WS_LOG_DEBUG, "Decoding MSGID_USERAUTH_REQUEST");
|
||||
ret = DoUserAuthRequest(ssh, buf + idx, payloadSz, &payloadIdx);
|
||||
break;
|
||||
|
||||
case MSGID_USERAUTH_FAILURE:
|
||||
WLOG(WS_LOG_DEBUG, "Decoding MSGID_USERAUTH_FAILURE");
|
||||
ret = DoUserAuthFailure(ssh, buf + idx, payloadSz, &payloadIdx);
|
||||
break;
|
||||
|
||||
case MSGID_USERAUTH_SUCCESS:
|
||||
WLOG(WS_LOG_DEBUG, "Decoding MSGID_USERAUTH_SUCCESS");
|
||||
ret = DoUserAuthSuccess(ssh, buf + idx, payloadSz, &payloadIdx);
|
||||
break;
|
||||
|
||||
case MSGID_USERAUTH_BANNER:
|
||||
WLOG(WS_LOG_DEBUG, "Decoding MSGID_USERAUTH_BANNER");
|
||||
ret = DoUserAuthBanner(ssh, buf + idx, payloadSz, &payloadIdx);
|
||||
break;
|
||||
|
||||
case MSGID_GLOBAL_REQUEST:
|
||||
WLOG(WS_LOG_DEBUG, "Decoding MSGID_GLOBAL_REQUEST");
|
||||
ret = DoGlobalRequest(ssh, buf + idx, payloadSz, &payloadIdx);
|
||||
|
|
@ -3705,44 +3883,6 @@ static int DoPacket(WOLFSSH* ssh)
|
|||
ret = DoChannelFailure(ssh, buf + idx, payloadSz, &payloadIdx);
|
||||
break;
|
||||
|
||||
#ifndef WOLFSSH_NO_CLIENT
|
||||
case MSGID_KEXDH_REPLY:
|
||||
if (ssh->handshake->kexId == ID_DH_GEX_SHA256) {
|
||||
WLOG(WS_LOG_DEBUG, "Decoding MSGID_KEXDH_GEX_GROUP");
|
||||
ret = DoKexDhGexGroup(ssh, buf + idx, payloadSz, &payloadIdx);
|
||||
}
|
||||
else {
|
||||
WLOG(WS_LOG_DEBUG, "Decoding MSGID_KEXDH_REPLY");
|
||||
ret = DoKexDhReply(ssh, buf + idx, payloadSz, &payloadIdx);
|
||||
}
|
||||
break;
|
||||
|
||||
case MSGID_KEXDH_GEX_REPLY:
|
||||
WLOG(WS_LOG_DEBUG, "Decoding MSGID_KEXDH_GEX_INIT");
|
||||
ret = DoKexDhReply(ssh, buf + idx, payloadSz, &payloadIdx);
|
||||
break;
|
||||
|
||||
case MSGID_SERVICE_ACCEPT:
|
||||
WLOG(WS_LOG_DEBUG, "Decoding MSGID_SERVER_ACCEPT");
|
||||
ret = DoServiceAccept(ssh, buf + idx, payloadSz, &payloadIdx);
|
||||
break;
|
||||
|
||||
case MSGID_USERAUTH_FAILURE:
|
||||
WLOG(WS_LOG_DEBUG, "Decoding MSGID_USERAUTH_FAILURE");
|
||||
ret = DoUserAuthFailure(ssh, buf + idx, payloadSz, &payloadIdx);
|
||||
break;
|
||||
|
||||
case MSGID_USERAUTH_SUCCESS:
|
||||
WLOG(WS_LOG_DEBUG, "Decoding MSGID_USERAUTH_SUCCESS");
|
||||
ret = DoUserAuthSuccess(ssh, buf + idx, payloadSz, &payloadIdx);
|
||||
break;
|
||||
|
||||
case MSGID_USERAUTH_BANNER:
|
||||
WLOG(WS_LOG_DEBUG, "Decoding MSGID_USERAUTH_BANNER");
|
||||
ret = DoUserAuthBanner(ssh, buf + idx, payloadSz, &payloadIdx);
|
||||
break;
|
||||
#endif /* WOLFSSL_NO_CLIENT */
|
||||
|
||||
default:
|
||||
WLOG(WS_LOG_DEBUG, "Unimplemented message ID (%d)", msg);
|
||||
#ifdef SHOW_UNIMPLEMENTED
|
||||
|
|
@ -5203,7 +5343,6 @@ int SendNewKeys(WOLFSSH* ssh)
|
|||
}
|
||||
|
||||
|
||||
#ifndef WOLFSSH_NO_CLIENT
|
||||
int SendKexDhGexRequest(WOLFSSH* ssh)
|
||||
{
|
||||
byte* output;
|
||||
|
|
@ -5244,7 +5383,6 @@ int SendKexDhGexRequest(WOLFSSH* ssh)
|
|||
WLOG(WS_LOG_DEBUG, "Leaving SendKexDhGexRequest(), ret = %d", ret);
|
||||
return ret;
|
||||
}
|
||||
#endif /* WOLFSSH_NO_CLIENT */
|
||||
|
||||
|
||||
int SendKexDhGexGroup(WOLFSSH* ssh)
|
||||
|
|
@ -5318,7 +5456,6 @@ int SendKexDhGexGroup(WOLFSSH* ssh)
|
|||
}
|
||||
|
||||
|
||||
#ifndef WOLFSSH_NO_CLIENT
|
||||
int SendKexDhInit(WOLFSSH* ssh)
|
||||
{
|
||||
byte* output;
|
||||
|
|
@ -5444,7 +5581,6 @@ int SendKexDhInit(WOLFSSH* ssh)
|
|||
WLOG(WS_LOG_DEBUG, "Leaving SendKexDhInit(), ret = %d", ret);
|
||||
return ret;
|
||||
}
|
||||
#endif /* WOLFSSH_NO_CLIENT */
|
||||
|
||||
|
||||
int SendUnimplemented(WOLFSSH* ssh)
|
||||
|
|
@ -5606,7 +5742,6 @@ int SendDebug(WOLFSSH* ssh, byte alwaysDisplay, const char* msg)
|
|||
}
|
||||
|
||||
|
||||
#ifndef WOLFSSH_NO_CLIENT
|
||||
int SendServiceRequest(WOLFSSH* ssh, byte serviceId)
|
||||
{
|
||||
const char* serviceName;
|
||||
|
|
@ -5648,7 +5783,6 @@ int SendServiceRequest(WOLFSSH* ssh, byte serviceId)
|
|||
WLOG(WS_LOG_DEBUG, "Leaving SendServiceRequest(), ret = %d", ret);
|
||||
return ret;
|
||||
}
|
||||
#endif /* WOLFSSH_NO_CLIENT */
|
||||
|
||||
|
||||
int SendServiceAccept(WOLFSSH* ssh, byte serviceId)
|
||||
|
|
@ -5694,7 +5828,6 @@ static const char cannedAuths[] = "publickey,password";
|
|||
static const word32 cannedAuthsSz = sizeof(cannedAuths) - 1;
|
||||
|
||||
|
||||
#ifndef WOLFSSH_NO_CLIENT
|
||||
int SendUserAuthRequest(WOLFSSH* ssh, byte authId)
|
||||
{
|
||||
byte* output;
|
||||
|
|
@ -5784,7 +5917,6 @@ int SendUserAuthRequest(WOLFSSH* ssh, byte authId)
|
|||
WLOG(WS_LOG_DEBUG, "Leaving SendUserAuthRequest(), ret = %d", ret);
|
||||
return ret;
|
||||
}
|
||||
#endif /* WOLFSSH_NO_CLIENT */
|
||||
|
||||
|
||||
int SendUserAuthFailure(WOLFSSH* ssh, byte partialSuccess)
|
||||
|
|
@ -5983,7 +6115,6 @@ int SendRequestSuccess(WOLFSSH* ssh, int success)
|
|||
}
|
||||
|
||||
|
||||
#ifndef WOLFSSH_NO_CLIENT
|
||||
int SendChannelOpenSession(WOLFSSH* ssh,
|
||||
word32 initialWindowSz, word32 maxPacketSz)
|
||||
{
|
||||
|
|
@ -6044,7 +6175,6 @@ int SendChannelOpenSession(WOLFSSH* ssh,
|
|||
WLOG(WS_LOG_DEBUG, "Leaving SendChannelOpenSession(), ret = %d", ret);
|
||||
return ret;
|
||||
}
|
||||
#endif /* WOLFSSH_NO_CLIENT */
|
||||
|
||||
|
||||
int SendChannelOpenConf(WOLFSSH* ssh)
|
||||
|
|
@ -6295,7 +6425,6 @@ int SendChannelWindowAdjust(WOLFSSH* ssh, word32 peerChannel,
|
|||
}
|
||||
|
||||
|
||||
#ifndef WOLFSSH_NO_CLIENT
|
||||
static const char cannedShellName[] = "shell";
|
||||
static const word32 cannedShellNameSz = sizeof(cannedShellName) - 1;
|
||||
|
||||
|
|
@ -6346,7 +6475,6 @@ int SendChannelRequestShell(WOLFSSH* ssh)
|
|||
WLOG(WS_LOG_DEBUG, "Leaving SendChannelRequestShell(), ret = %d", ret);
|
||||
return ret;
|
||||
}
|
||||
#endif /* WOLFSSH_NO_CLIENT */
|
||||
|
||||
|
||||
int SendChannelSuccess(WOLFSSH* ssh, word32 channelId, int success)
|
||||
|
|
|
|||
216
src/ssh.c
216
src/ssh.c
|
|
@ -371,6 +371,187 @@ int wolfSSH_accept(WOLFSSH* ssh)
|
|||
}
|
||||
|
||||
|
||||
const char connectError[] = "connect error: %s, %d";
|
||||
const char connectState[] = "connect state: %s";
|
||||
|
||||
|
||||
int wolfSSH_connect(WOLFSSH* ssh)
|
||||
{
|
||||
WLOG(WS_LOG_DEBUG, "Entering wolfSSH_connect()");
|
||||
|
||||
if (ssh == NULL)
|
||||
return WS_BAD_ARGUMENT;
|
||||
|
||||
switch (ssh->connectState) {
|
||||
|
||||
case CONNECT_BEGIN:
|
||||
if ( (ssh->error = SendProtoId(ssh)) < WS_SUCCESS) {
|
||||
WLOG(WS_LOG_DEBUG, connectError, "BEGIN", ssh->error);
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
ssh->connectState = CONNECT_CLIENT_VERSION_SENT;
|
||||
WLOG(WS_LOG_DEBUG, connectState, "CLIENT_VERSION_SENT");
|
||||
FALL_THROUGH;
|
||||
|
||||
case CONNECT_CLIENT_VERSION_SENT:
|
||||
while (ssh->serverState < SERVER_VERSION_DONE) {
|
||||
if ( (ssh->error = DoProtoId(ssh)) < WS_SUCCESS) {
|
||||
WLOG(WS_LOG_DEBUG, connectError,
|
||||
"CLIENT_VERSION_SENT", ssh->error);
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
ssh->connectState = CONNECT_SERVER_VERSION_DONE;
|
||||
WLOG(WS_LOG_DEBUG, connectState, "SERVER_VERSION_DONE");
|
||||
FALL_THROUGH;
|
||||
|
||||
case CONNECT_SERVER_VERSION_DONE:
|
||||
if ( (ssh->error = SendKexInit(ssh)) < WS_SUCCESS) {
|
||||
WLOG(WS_LOG_DEBUG, acceptError,
|
||||
"SERVER_VERSION_DONE", ssh->error);
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
ssh->connectState = CONNECT_CLIENT_KEXINIT_SENT;
|
||||
WLOG(WS_LOG_DEBUG, connectState, "CLIENT_KEXINIT_SENT");
|
||||
FALL_THROUGH;
|
||||
|
||||
case CONNECT_CLIENT_KEXINIT_SENT:
|
||||
while (ssh->serverState < SERVER_KEXINIT_DONE) {
|
||||
if ( (ssh->error = DoReceive(ssh)) < WS_SUCCESS) {
|
||||
WLOG(WS_LOG_DEBUG, connectError,
|
||||
"CLIENT_KEXINIT_SENT", ssh->error);
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
ssh->connectState = CONNECT_SERVER_KEXINIT_DONE;
|
||||
WLOG(WS_LOG_DEBUG, connectState, "SERVER_KEXINIT_DONE");
|
||||
FALL_THROUGH;
|
||||
|
||||
case CONNECT_SERVER_KEXINIT_DONE:
|
||||
if (ssh->handshake->kexId == ID_DH_GEX_SHA256)
|
||||
ssh->error = SendKexDhGexRequest(ssh);
|
||||
else
|
||||
ssh->error = SendKexDhInit(ssh);
|
||||
if (ssh->error < WS_SUCCESS) {
|
||||
WLOG(WS_LOG_DEBUG, connectError,
|
||||
"SERVER_KEXINIT_DONE", ssh->error);
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
ssh->connectState = CONNECT_CLIENT_KEXDH_INIT_SENT;
|
||||
WLOG(WS_LOG_DEBUG, connectState, "CLIENT_KEXDH_INIT_SENT");
|
||||
FALL_THROUGH;
|
||||
|
||||
case CONNECT_CLIENT_KEXDH_INIT_SENT:
|
||||
while (ssh->isKeying) {
|
||||
if ( (ssh->error = DoReceive(ssh)) < WS_SUCCESS) {
|
||||
WLOG(WS_LOG_DEBUG, connectError,
|
||||
"CLIENT_KEXDH_INIT_SENT", ssh->error);
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
ssh->connectState = CONNECT_KEYED;
|
||||
WLOG(WS_LOG_DEBUG, connectState, "KEYED");
|
||||
FALL_THROUGH;
|
||||
|
||||
case CONNECT_KEYED:
|
||||
if ( (ssh->error = SendServiceRequest(ssh, ID_SERVICE_USERAUTH)) <
|
||||
WS_SUCCESS) {
|
||||
WLOG(WS_LOG_DEBUG, connectError, "KEYED", ssh->error);
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
ssh->connectState = CONNECT_CLIENT_USERAUTH_REQUEST_SENT;
|
||||
WLOG(WS_LOG_DEBUG, connectState, "CLIENT_USERAUTH_REQUEST_SENT");
|
||||
FALL_THROUGH;
|
||||
|
||||
case CONNECT_CLIENT_USERAUTH_REQUEST_SENT:
|
||||
while (ssh->serverState < SERVER_USERAUTH_REQUEST_DONE) {
|
||||
if ( (ssh->error = DoReceive(ssh)) < WS_SUCCESS) {
|
||||
WLOG(WS_LOG_DEBUG, connectError,
|
||||
"CLIENT_USERAUTH_REQUEST_SENT", ssh->error);
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
ssh->connectState = CONNECT_SERVER_USERAUTH_REQUEST_DONE;
|
||||
WLOG(WS_LOG_DEBUG, connectState, "SERVER_USERAUTH_REQUEST_DONE");
|
||||
FALL_THROUGH;
|
||||
|
||||
case CONNECT_SERVER_USERAUTH_REQUEST_DONE:
|
||||
if ( (ssh->error = SendUserAuthRequest(ssh, ID_NONE)) <
|
||||
WS_SUCCESS) {
|
||||
WLOG(WS_LOG_DEBUG, connectError,
|
||||
"SERVER_USERAUTH_REQUEST_DONE", ssh->error);
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
ssh->connectState = CONNECT_CLIENT_USERAUTH_SENT;
|
||||
WLOG(WS_LOG_DEBUG, connectState, "CLIENT_USERAUTH_SENT");
|
||||
FALL_THROUGH;
|
||||
|
||||
case CONNECT_CLIENT_USERAUTH_SENT:
|
||||
while (ssh->serverState < SERVER_USERAUTH_ACCEPT_DONE) {
|
||||
if ( (ssh->error = DoReceive(ssh)) < WS_SUCCESS) {
|
||||
WLOG(WS_LOG_DEBUG, connectError,
|
||||
"CLIENT_USERAUTH_SENT", ssh->error);
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
ssh->connectState = CONNECT_SERVER_USERAUTH_ACCEPT_DONE;
|
||||
WLOG(WS_LOG_DEBUG, connectState, "SERVER_USERAUTH_ACCEPT_DONE");
|
||||
FALL_THROUGH;
|
||||
|
||||
case CONNECT_SERVER_USERAUTH_ACCEPT_DONE:
|
||||
if ( (ssh->error = SendChannelOpenSession(ssh, DEFAULT_WINDOW_SZ,
|
||||
DEFAULT_MAX_PACKET_SZ)) < WS_SUCCESS) {
|
||||
WLOG(WS_LOG_DEBUG, connectError,
|
||||
"SERVER_USERAUTH_ACCEPT_DONE", ssh->error);
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
ssh->connectState = CONNECT_CLIENT_CHANNEL_OPEN_SESSION_SENT;
|
||||
WLOG(WS_LOG_DEBUG, connectState,
|
||||
"CLIENT_CHANNEL_OPEN_SESSION_SENT");
|
||||
FALL_THROUGH;
|
||||
|
||||
case CONNECT_CLIENT_CHANNEL_OPEN_SESSION_SENT:
|
||||
while (ssh->serverState < SERVER_CHANNEL_OPEN_DONE) {
|
||||
if ( (ssh->error = DoReceive(ssh)) < WS_SUCCESS) {
|
||||
WLOG(WS_LOG_DEBUG, connectError,
|
||||
"CLIENT_CHANNEL_OPEN_SESSION_SENT", ssh->error);
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
ssh->connectState = CONNECT_SERVER_CHANNEL_OPEN_SESSION_DONE;
|
||||
WLOG(WS_LOG_DEBUG, connectState,
|
||||
"SERVER_CHANNEL_OPEN_SESSION_DONE");
|
||||
FALL_THROUGH;
|
||||
|
||||
case CONNECT_SERVER_CHANNEL_OPEN_SESSION_DONE:
|
||||
if ( (ssh->error = SendChannelRequestShell(ssh)) < WS_SUCCESS) {
|
||||
WLOG(WS_LOG_DEBUG, connectError,
|
||||
"SERVER_CHANNEL_OPEN_SESSION_DONE", ssh->error);
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
ssh->connectState = CONNECT_CLIENT_CHANNEL_REQUEST_SHELL_SENT;
|
||||
WLOG(WS_LOG_DEBUG, connectState,
|
||||
"CLIENT_CHANNEL_REQUEST_SHELL_SENT");
|
||||
FALL_THROUGH;
|
||||
|
||||
case CONNECT_CLIENT_CHANNEL_REQUEST_SHELL_SENT:
|
||||
while (ssh->serverState < SERVER_DONE) {
|
||||
if ( (ssh->error = DoReceive(ssh)) < WS_SUCCESS) {
|
||||
WLOG(WS_LOG_DEBUG, connectError,
|
||||
"CLIENT_CHANNEL_REQUEST_SHELL_SENT", ssh->error);
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
ssh->connectState = CONNECT_SERVER_CHANNEL_REQUEST_SHELL_DONE;
|
||||
WLOG(WS_LOG_DEBUG, connectState,
|
||||
"SERVER_CHANNEL_REQUEST_SHELL_DONE");
|
||||
}
|
||||
|
||||
WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_connect()");
|
||||
return WS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int wolfSSH_shutdown(WOLFSSH* ssh)
|
||||
{
|
||||
int ret = WS_SUCCESS;
|
||||
|
|
@ -507,6 +688,41 @@ void* wolfSSH_GetUserAuthCtx(WOLFSSH* ssh)
|
|||
}
|
||||
|
||||
|
||||
int wolfSSH_SetUsername(WOLFSSH* ssh, const char* username)
|
||||
{
|
||||
char* value = NULL;
|
||||
word32 valueSz;
|
||||
int ret = WS_SUCCESS;
|
||||
|
||||
if (ssh == NULL || ssh->handshake == NULL ||
|
||||
ssh->ctx->side == WOLFSSH_ENDPOINT_SERVER ||
|
||||
username == NULL) {
|
||||
|
||||
ret = WS_BAD_ARGUMENT;
|
||||
}
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
valueSz = (word32)WSTRLEN(username);
|
||||
if (valueSz > 0)
|
||||
value = (char*)WMALLOC(valueSz + 1, ssh->ctx->heap, DYNTYPE_STRING);
|
||||
if (value == NULL)
|
||||
ret = WS_MEMORY_E;
|
||||
}
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
WSTRNCPY(value, username, valueSz + 1);
|
||||
if (ssh->userName != NULL) {
|
||||
WFREE(ssh->userName, heap, DYNTYPE_STRING);
|
||||
ssh->userName = NULL;
|
||||
}
|
||||
ssh->userName = value;
|
||||
ssh->userNameSz = valueSz;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int wolfSSH_CTX_SetBanner(WOLFSSH_CTX* ctx,
|
||||
const char* newBanner)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -45,9 +45,6 @@ extern "C" {
|
|||
#define USE_WINDOWS_API
|
||||
#endif
|
||||
|
||||
#define WOLFSSH_NO_CLIENT
|
||||
/* The client code is incomplete. */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -125,11 +125,14 @@ WOLFSSH_API void wolfSSH_SetUserAuth(WOLFSSH_CTX*, WS_CallbackUserAuth);
|
|||
WOLFSSH_API void wolfSSH_SetUserAuthCtx(WOLFSSH*, void*);
|
||||
WOLFSSH_API void* wolfSSH_GetUserAuthCtx(WOLFSSH*);
|
||||
|
||||
WOLFSSH_API int wolfSSH_SetUsername(WOLFSSH*, const char*);
|
||||
|
||||
WOLFSSH_API int wolfSSH_CTX_SetBanner(WOLFSSH_CTX*, const char*);
|
||||
WOLFSSH_API int wolfSSH_CTX_UsePrivateKey_buffer(WOLFSSH_CTX*,
|
||||
const byte*, word32, int);
|
||||
|
||||
WOLFSSH_API int wolfSSH_accept(WOLFSSH*);
|
||||
WOLFSSH_API int wolfSSH_connect(WOLFSSH*);
|
||||
WOLFSSH_API int wolfSSH_shutdown(WOLFSSH*);
|
||||
WOLFSSH_API int wolfSSH_stream_read(WOLFSSH*, byte*, word32);
|
||||
WOLFSSH_API int wolfSSH_stream_send(WOLFSSH*, byte*, word32);
|
||||
|
|
|
|||
Loading…
Reference in New Issue