Merge pull request #38 from ejohnstown/client

Client
pull/39/head
dgarske 2017-09-26 11:28:49 -07:00 committed by GitHub
commit 524e56e999
26 changed files with 1855 additions and 515 deletions

1
.gitignore vendored
View File

@ -48,6 +48,7 @@ diff
.vimrc
# examples
examples/client/client
examples/echoserver/echoserver
examples/server/server

View File

@ -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.

View File

@ -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"

View File

@ -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 */

View File

@ -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_ */

View File

@ -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

0
examples/echoserver/echoserver.h 100755 → 100644
View File

View File

@ -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

View File

@ -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 */

View File

@ -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_ */

View File

@ -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>

View File

@ -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>

View File

@ -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

214
ide/winvs/wolfssh.sln 100644 → 100755
View File

@ -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

View File

@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIFWdSB6pL/oYzrP6d0YAxNvTiz6d72/NN0aHIzx3mat4oAoGCCqGSM49
AwEHoUQDQgAEoC0fxypoNu0kWO2+IuhscGaMK0bnoMyQ/oDgzYf3Nfb9gKDWH1th
LtYd31RAPBc7UeEhnNFh5xeHtIb0/gaFFg==
-----END EC PRIVATE KEY-----

View File

@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIANuF9O5uKvI+R/xLURMOxKxpHfY7Q5qvmDC9ovn04eDoAoGCCqGSM49
AwEHoUQDQgAE2QjklM/oPSUXja1vFfX1wTzuHO1RLoVIOga89+JTQKB41Jsj5oV0
ojNM/kJAQlK+bbmpTOAO0fujJpBE5Sc2+Q==
-----END EC PRIVATE KEY-----

View File

@ -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

View File

@ -0,0 +1,2 @@
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNkI5JTP6D0lF42tbxX19cE87hztUS6FSDoGvPfiU0CgeNSbI+aFdKIzTP5CQEJSvm25qUzgDtH7oyaQROUnNvk= hansel
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKAtH8cqaDbtJFjtviLobHBmjCtG56DMkP6A4M2H9zX2/YCg1h9bYS7WHd9UQDwXO1HhIZzRYecXh7SG9P4GhRY= gretel

View File

@ -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
View File

@ -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)
{

View File

@ -45,9 +45,6 @@ extern "C" {
#define USE_WINDOWS_API
#endif
#define WOLFSSH_NO_CLIENT
/* The client code is incomplete. */
#ifdef __cplusplus
}

View File

@ -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);

0
wolfssh/test.h 100755 → 100644
View File