mirror of https://github.com/wolfSSL/wolfssh.git
commit
524e56e999
|
@ -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