mirror of https://github.com/wolfSSL/wolfssh.git
Adding code
parent
997013f210
commit
eb82d2bf28
|
@ -20,12 +20,234 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#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 <stdio.h>
|
||||||
#include <wolfssh/ssh.h>
|
#include <wolfssh/ssh.h>
|
||||||
|
|
||||||
|
|
||||||
|
typedef unsigned short word16;
|
||||||
|
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
|
||||||
|
|
||||||
|
#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* ACCEPT_THIRD_T;
|
||||||
|
#else
|
||||||
|
#if defined _XOPEN_SOURCE_EXTENDED
|
||||||
|
typedef socklen_t* ACCEPT_THIRD_T;
|
||||||
|
#else
|
||||||
|
typedef int* ACCEPT_THIRD_T;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static WINLINE void err_sys(const char* msg)
|
||||||
|
{
|
||||||
|
printf("server error: %s\n", msg);
|
||||||
|
if (msg)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static WINLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer,
|
||||||
|
word16 port)
|
||||||
|
{
|
||||||
|
int useLookup = 0;
|
||||||
|
(void)useLookup;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
err_sys("no entry for host");
|
||||||
|
}
|
||||||
|
#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 WINLINE 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 WINLINE void tcp_listen(SOCKET_T* sockfd, word16* 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");
|
||||||
|
if (listen(*sockfd, 5) != 0)
|
||||||
|
err_sys("tcp listen failed");
|
||||||
|
#if !defined(USE_WINDOWS_API)
|
||||||
|
if (*port == 0) {
|
||||||
|
socklen_t len = sizeof(addr);
|
||||||
|
if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) {
|
||||||
|
#ifndef TEST_IPV6
|
||||||
|
*port = ntohs(addr.sin_port);
|
||||||
|
#else
|
||||||
|
*port = ntohs(addr.sin6_port);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static WINLINE void tcp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd, word16 port)
|
||||||
|
{
|
||||||
|
SOCKADDR_IN_T client;
|
||||||
|
socklen_t client_len = sizeof(client);
|
||||||
|
|
||||||
|
tcp_listen(sockfd, &port, 1);
|
||||||
|
|
||||||
|
*clientfd = accept(*sockfd, (struct sockaddr*)&client,
|
||||||
|
(ACCEPT_THIRD_T)&client_len);
|
||||||
|
|
||||||
|
if (*clientfd == -1)
|
||||||
|
err_sys("tcp accept failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
SOCKET_T sockfd = 0;
|
||||||
|
SOCKET_T clientfd = 0;
|
||||||
|
|
||||||
#ifdef DEBUG_WOLFSSH
|
#ifdef DEBUG_WOLFSSH
|
||||||
wolfSSH_Debugging_ON();
|
wolfSSH_Debugging_ON();
|
||||||
#endif
|
#endif
|
||||||
|
@ -34,9 +256,13 @@ int main(void)
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tcp_accept(&sockfd, &clientfd, 22222);
|
||||||
|
|
||||||
if (wolfSSH_Cleanup() != WS_SUCCESS) {
|
if (wolfSSH_Cleanup() != WS_SUCCESS) {
|
||||||
fprintf(stderr, "Couldn't clean up wolfSSH.\n");
|
fprintf(stderr, "Couldn't clean up wolfSSH.\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
271
src/ssh.c
271
src/ssh.c
|
@ -44,3 +44,274 @@ int wolfSSH_Cleanup(void)
|
||||||
return WS_SUCCESS;
|
return WS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static WOLFSSH_CTX* CtxInit(WOLFSSH_CTX* ctx, void* heap)
|
||||||
|
{
|
||||||
|
WLOG(WS_LOG_DEBUG, "Enter CtxInit()");
|
||||||
|
|
||||||
|
if (ctx == NULL)
|
||||||
|
return ctx;
|
||||||
|
|
||||||
|
WMEMSET(ctx, 0, sizeof(WOLFSSH_CTX));
|
||||||
|
|
||||||
|
if (heap)
|
||||||
|
ctx->heap = heap;
|
||||||
|
|
||||||
|
#ifndef WOLFSSH_USER_IO
|
||||||
|
ctx->ioRecvCb = wsEmbedRecv;
|
||||||
|
ctx->ioSendCb = wsEmbedSend;
|
||||||
|
#endif /* WOLFSSH_USER_IO */
|
||||||
|
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WOLFSSH_CTX* wolfSSH_CTX_new(void* heap)
|
||||||
|
{
|
||||||
|
WOLFSSH_CTX* ctx;
|
||||||
|
|
||||||
|
WLOG(WS_LOG_DEBUG, "Enter wolfSSH_CTX_new()");
|
||||||
|
|
||||||
|
ctx = (WOLFSSH_CTX*)WMALLOC(sizeof(WOLFSSH_CTX), heap, WOLFSSH_CTX_TYPE);
|
||||||
|
ctx = CtxInit(ctx, heap);
|
||||||
|
|
||||||
|
WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_CTX_new(), ctx = %p", ctx);
|
||||||
|
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void CtxResourceFree(WOLFSSH_CTX* ctx)
|
||||||
|
{
|
||||||
|
/* when context holds resources, free here */
|
||||||
|
(void)ctx;
|
||||||
|
|
||||||
|
WLOG(WS_LOG_DEBUG, "Enter CtxResourceFree()");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void wolfSSH_CTX_free(WOLFSSH_CTX* ctx)
|
||||||
|
{
|
||||||
|
WLOG(WS_LOG_DEBUG, "Enter wolfSSH_CTX_free()");
|
||||||
|
|
||||||
|
if (ctx) {
|
||||||
|
CtxResourceFree(ctx);
|
||||||
|
WFREE(ctx, ctx->heap, WOLFSSH_CTX_TYPE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static WOLFSSH* SshInit(WOLFSSH* ssh, WOLFSSH_CTX* ctx)
|
||||||
|
{
|
||||||
|
WLOG(WS_LOG_DEBUG, "Enter SshInit()");
|
||||||
|
|
||||||
|
if (ssh == NULL)
|
||||||
|
return ssh;
|
||||||
|
|
||||||
|
WMEMSET(ssh, 0, sizeof(WOLFSSH)); /* default init to zeros */
|
||||||
|
|
||||||
|
if (ctx)
|
||||||
|
ssh->ctx = ctx;
|
||||||
|
else {
|
||||||
|
WLOG(WS_LOG_ERROR, "Trying to init a wolfSSH w/o wolfSSH_CTX");
|
||||||
|
wolfSSH_free(ssh);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssh->rfd = -1; /* set to invalid */
|
||||||
|
ssh->wfd = -1; /* set to invalid */
|
||||||
|
ssh->ioReadCtx = &ssh->rfd; /* prevent invalid access if not correctly */
|
||||||
|
ssh->ioWriteCtx = &ssh->wfd; /* set */
|
||||||
|
|
||||||
|
return ssh;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WOLFSSH* wolfSSH_new(WOLFSSH_CTX* ctx)
|
||||||
|
{
|
||||||
|
WOLFSSH* ssh;
|
||||||
|
void* heap = NULL;
|
||||||
|
|
||||||
|
if (ctx)
|
||||||
|
heap = ctx->heap;
|
||||||
|
|
||||||
|
WLOG(WS_LOG_DEBUG, "Enter wolfSSH_new()");
|
||||||
|
|
||||||
|
ssh = (WOLFSSH*)WMALLOC(sizeof(WOLFSSH), heap, WOLFSSH_TYPE);
|
||||||
|
ssh = SshInit(ssh, ctx);
|
||||||
|
|
||||||
|
WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_new(), ssh = %p", ssh);
|
||||||
|
|
||||||
|
return ssh;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void SshResourceFree(WOLFSSH* ssh)
|
||||||
|
{
|
||||||
|
/* when ssh holds resources, free here */
|
||||||
|
(void)ssh;
|
||||||
|
|
||||||
|
WLOG(WS_LOG_DEBUG, "Enter sshResourceFree()");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void wolfSSH_free(WOLFSSH* ssh)
|
||||||
|
{
|
||||||
|
WLOG(WS_LOG_DEBUG, "Enter wolfSSH_free()");
|
||||||
|
|
||||||
|
if (ssh) {
|
||||||
|
SshResourceFree(ssh);
|
||||||
|
WFREE(ssh, ssh->ctx ? ssh->ctx->heap : NULL, WOLFSSH_TYPE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static WOLFSSH_CHAN* SshChanInit(WOLFSSH_CHAN* chan, WOLFSSH* ssh)
|
||||||
|
{
|
||||||
|
WLOG(WS_LOG_DEBUG, "Enter SshChanInit()");
|
||||||
|
|
||||||
|
if (chan == NULL)
|
||||||
|
return chan;
|
||||||
|
|
||||||
|
WMEMSET(chan, 0, sizeof(WOLFSSH_CHAN)); /* default init to zeros */
|
||||||
|
|
||||||
|
if (ssh) {
|
||||||
|
chan->ssh = ssh;
|
||||||
|
chan->ctx = ssh->ctx;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WLOG(WS_LOG_ERROR, "Trying to init a wolfSSH_CHAN w/o wolfSSH");
|
||||||
|
wolfSSH_CHAN_free(chan);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return chan;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WOLFSSH_CHAN* wolfSSH_CHAN_new(WOLFSSH* ssh)
|
||||||
|
{
|
||||||
|
WOLFSSH_CHAN* chan;
|
||||||
|
void* heap = NULL;
|
||||||
|
|
||||||
|
WLOG(WS_LOG_DEBUG, "Enter wolfSSH_CHAN_new()");
|
||||||
|
|
||||||
|
if (ssh != NULL && ssh->ctx != NULL)
|
||||||
|
heap = ssh->ctx->heap;
|
||||||
|
|
||||||
|
chan = (WOLFSSH_CHAN*)WMALLOC(sizeof(WOLFSSH_CHAN),
|
||||||
|
heap, WOLFSSH_CHAN_TYPE);
|
||||||
|
|
||||||
|
chan = SshChanInit(chan, ssh);
|
||||||
|
|
||||||
|
WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_CHAN_new(), chan = %p", chan);
|
||||||
|
|
||||||
|
return chan;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void SshChanResourceFree(WOLFSSH_CHAN* chan)
|
||||||
|
{
|
||||||
|
/* when ssh channel holds resources, free here */
|
||||||
|
(void)chan;
|
||||||
|
|
||||||
|
WLOG(WS_LOG_DEBUG, "Enter SshChanResourceFree()");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void wolfSSH_CHAN_free(WOLFSSH_CHAN* chan)
|
||||||
|
{
|
||||||
|
WLOG(WS_LOG_DEBUG, "Enter wolfSCEP_free()");
|
||||||
|
|
||||||
|
if (chan) {
|
||||||
|
SshChanResourceFree(chan);
|
||||||
|
WFREE(chan, chan->ctx ? chan->ctx->heap : NULL, WOLFSCEP_TYPE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int wolfSSH_set_fd(WOLFSSH* ssh, int fd)
|
||||||
|
{
|
||||||
|
WLOG(WS_LOG_DEBUG, "Enter wolfSSH_set_fd()");
|
||||||
|
|
||||||
|
if (ssh) {
|
||||||
|
ssh->rfd = fd;
|
||||||
|
ssh->wfd = fd;
|
||||||
|
|
||||||
|
ssh->ioReadCtx = &ssh->rfd;
|
||||||
|
ssh->ioWriteCtx = &ssh->wfd;
|
||||||
|
|
||||||
|
return WS_SUCCESS;
|
||||||
|
}
|
||||||
|
return WS_BAD_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int wolfSSH_get_fd(const WOLFSSH* ssh)
|
||||||
|
{
|
||||||
|
WLOG(WS_LOG_DEBUG, "Enter wolfSSH_get_fd()");
|
||||||
|
|
||||||
|
if (ssh)
|
||||||
|
return ssh->rfd;
|
||||||
|
|
||||||
|
return WS_BAD_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enum {
|
||||||
|
doProcessInit
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int ProcessReply(WOLFSSH* ssh)
|
||||||
|
{
|
||||||
|
int ret = WS_FATAL_ERROR;
|
||||||
|
int readSz;
|
||||||
|
|
||||||
|
(void)readSz;
|
||||||
|
for (;;) {
|
||||||
|
switch (ssh->processReply) {
|
||||||
|
case doProcessInit:
|
||||||
|
readSz = ssh->blockSz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int wolfSSH_accept(WOLFSSH* ssh)
|
||||||
|
{
|
||||||
|
switch (ssh->acceptState) {
|
||||||
|
case ACCEPT_BEGIN:
|
||||||
|
if ( (ssh->error = ProcessReply(ssh)) < 0) {
|
||||||
|
WLOG(WS_LOG_DEBUG, "accept reply error: %d", ssh->error);
|
||||||
|
return WS_FATAL_ERROR;
|
||||||
|
}
|
||||||
|
ssh->acceptState = CLIENT_VERSION_DONE;
|
||||||
|
WLOG(WS_LOG_DEBUG, "accept state CLIENT_VERSION_DONE");
|
||||||
|
|
||||||
|
case CLIENT_VERSION_DONE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SERVER_VERSION_SENT:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return WS_FATAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int SendServerVersion(WOLFSSH* ssh)
|
||||||
|
{
|
||||||
|
(void)ssh;
|
||||||
|
return WS_FATAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int DoClientVersion(WOLFSSH* ssh)
|
||||||
|
{
|
||||||
|
(void)ssh;
|
||||||
|
return WS_FATAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,21 +29,65 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
enum {
|
||||||
|
/* Any of the items can be none. */
|
||||||
|
ID_NONE,
|
||||||
|
|
||||||
|
/* Encryption IDs */
|
||||||
|
ID_AES128_CBC,
|
||||||
|
ID_AES128_CTR,
|
||||||
|
ID_AES128_GCM_WOLF,
|
||||||
|
|
||||||
|
/* Integrity IDs */
|
||||||
|
ID_HMAC_SHA1,
|
||||||
|
ID_HMAC_SHA1_96,
|
||||||
|
|
||||||
|
/* Key Exchange IDs */
|
||||||
|
ID_DH_GROUP1_SHA1,
|
||||||
|
ID_DH_GROUP14_SHA1,
|
||||||
|
|
||||||
|
/* Public Key IDs */
|
||||||
|
ID_SSH_RSA,
|
||||||
|
|
||||||
|
ID_UNKNOWN
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
WOLFSSH_LOCAL uint8_t NameToId(const char*);
|
||||||
|
WOLFSSH_LOCAL const char* IdToName(uint8_t);
|
||||||
|
|
||||||
|
|
||||||
/* our wolfSSH Context */
|
/* our wolfSSH Context */
|
||||||
struct WOLFSSH_CTX {
|
struct WOLFSSH_CTX {
|
||||||
void* heap; /* heap hint */
|
void* heap; /* heap hint */
|
||||||
WS_CallbackIORecv ioRecvCb; /* I/O Receive Callback */
|
WS_CallbackIORecv ioRecvCb; /* I/O Receive Callback */
|
||||||
WS_CallbackIOSend ioSendCb; /* I/O Send Callback */
|
WS_CallbackIOSend ioSendCb; /* I/O Send Callback */
|
||||||
|
uint8_t compression;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* our wolfSSH session */
|
/* our wolfSSH session */
|
||||||
struct WOLFSSH {
|
struct WOLFSSH {
|
||||||
WOLFSSH_CTX* ctx; /* owner context */
|
WOLFSSH_CTX* ctx; /* owner context */
|
||||||
|
int error;
|
||||||
|
int rfd;
|
||||||
|
int wfd;
|
||||||
void* ioReadCtx; /* I/O Read Context handle */
|
void* ioReadCtx; /* I/O Read Context handle */
|
||||||
void* ioWriteCtx; /* I/O Write Context handle */
|
void* ioWriteCtx; /* I/O Write Context handle */
|
||||||
int rflags; /* optional read flags */
|
int rflags; /* optional read flags */
|
||||||
int wflags; /* optional write flags */
|
int wflags; /* optional write flags */
|
||||||
|
WOLFSSH_CHAN *channel; /* single data channel */
|
||||||
|
uint8_t blockSz;
|
||||||
|
uint8_t acceptState;
|
||||||
|
uint8_t processReply;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* wolfSSH channel */
|
||||||
|
struct WOLFSSH_CHAN {
|
||||||
|
WOLFSSH_CTX* ctx;
|
||||||
|
WOLFSSH* ssh;
|
||||||
|
int id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,6 +99,19 @@ WOLFSSH_LOCAL int wsEmbedSend(WOLFSSH* ssh, void*, uint32_t sz, void* ctx);
|
||||||
|
|
||||||
#endif /* WOLFSSH_USER_IO */
|
#endif /* WOLFSSH_USER_IO */
|
||||||
|
|
||||||
|
|
||||||
|
WOLFSSH_LOCAL int ProcessReply(WOLFSSH*);
|
||||||
|
WOLFSSH_LOCAL int SendServerVersion(WOLFSSH*);
|
||||||
|
WOLFSSH_LOCAL int DoClientVersion(WOLFSSH*);
|
||||||
|
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ACCEPT_BEGIN = 0,
|
||||||
|
CLIENT_VERSION_DONE,
|
||||||
|
SERVER_VERSION_SENT,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -42,12 +42,31 @@ WOLFSSH_API int wolfSSH_Cleanup(void);
|
||||||
WOLFSSH_API int wolfSSH_Debugging_ON(void);
|
WOLFSSH_API int wolfSSH_Debugging_ON(void);
|
||||||
WOLFSSH_API void wolfSSH_Debugging_OFF(void);
|
WOLFSSH_API void wolfSSH_Debugging_OFF(void);
|
||||||
|
|
||||||
|
/* context functions */
|
||||||
|
WOLFSSH_API WOLFSSH_CTX* wolfSSH_CTX_new(void*);
|
||||||
|
WOLFSSH_API void wolfSSH_CTX_free(WOLFSSH_CTX*);
|
||||||
|
|
||||||
|
/* ssh session functions */
|
||||||
|
WOLFSSH_API WOLFSSH* wolfSSH_new(WOLFSSH_CTX*);
|
||||||
|
WOLFSSH_API void wolfSSH_free(WOLFSSH*);
|
||||||
|
|
||||||
|
/* ssh channel functions */
|
||||||
|
WOLFSSH_API WOLFSSH_CHAN* wolfSSH_CHAN_new(WOLFSSH*);
|
||||||
|
WOLFSSH_API void wolfSSH_CHAN_free(WOLFSSH_CHAN*);
|
||||||
|
|
||||||
|
WOLFSSH_API int wolfSSH_set_fd(WOLFSSH*, int);
|
||||||
|
WOLFSSH_API int wolfSSH_get_fd(const WOLFSSH*);
|
||||||
|
|
||||||
WOLFSSH_API const char* wolfSSH_get_error(int);
|
WOLFSSH_API const char* wolfSSH_get_error(int);
|
||||||
|
|
||||||
/* I/O callbacks */
|
/* I/O callbacks */
|
||||||
typedef int (*WS_CallbackIORecv)(WOLFSSH*, void* buf, uint32_t sz, void* ctx);
|
typedef int (*WS_CallbackIORecv)(WOLFSSH*, void* buf, uint32_t sz, void* ctx);
|
||||||
typedef int (*WS_CallbackIOSend)(WOLFSSH*, void* buf, uint32_t sz, void* ctx);
|
typedef int (*WS_CallbackIOSend)(WOLFSSH*, void* buf, uint32_t sz, void* ctx);
|
||||||
|
|
||||||
|
/* Channel I/O callbacks */
|
||||||
|
typedef int (*WSH_CallbackChanRecv)();
|
||||||
|
typedef int (*WSH_CallbackChanSend)();
|
||||||
|
|
||||||
WOLFSSH_API void wolfSSH_SetIORecv(WOLFSSH_CTX*, WS_CallbackIORecv);
|
WOLFSSH_API void wolfSSH_SetIORecv(WOLFSSH_CTX*, WS_CallbackIORecv);
|
||||||
WOLFSSH_API void wolfSSH_SetIOSend(WOLFSSH_CTX*, WS_CallbackIOSend);
|
WOLFSSH_API void wolfSSH_SetIOSend(WOLFSSH_CTX*, WS_CallbackIOSend);
|
||||||
|
|
||||||
|
@ -57,6 +76,7 @@ WOLFSSH_API void wolfSSH_SetIOWriteCtx(WOLFSSH* ssh, void *ctx);
|
||||||
WOLFSSH_API void* wolfSSH_GetIOReadCtx(WOLFSSH* ssh);
|
WOLFSSH_API void* wolfSSH_GetIOReadCtx(WOLFSSH* ssh);
|
||||||
WOLFSSH_API void* wolfSSH_GetIOWriteCtx(WOLFSSH* ssh);
|
WOLFSSH_API void* wolfSSH_GetIOWriteCtx(WOLFSSH* ssh);
|
||||||
|
|
||||||
|
WOLFSSH_API int wolfSSH_accept(WOLFSSH* ssh);
|
||||||
|
|
||||||
|
|
||||||
/* dynamic memory types */
|
/* dynamic memory types */
|
||||||
|
|
Loading…
Reference in New Issue