expanding config parsing

pull/435/head
Jacob Barthelmeh 2022-06-13 13:31:33 -06:00 committed by JacobBarthelmeh
parent 27cf3d31b9
commit 757f3c6b2c
3 changed files with 373 additions and 23 deletions

View File

@ -51,7 +51,7 @@ struct WOLFSSHD_CONFIG {
char* kekAlgos;
char* listenAddress;
char* authKeysFile;
word32 port;
word16 port;
byte passwordAuth:1;
byte pubKeyAuth:1;
byte permitRootLogin:1;
@ -59,7 +59,45 @@ struct WOLFSSHD_CONFIG {
byte usePrivilegeSeparation:1;
};
WOLFSSHD_CONFIG* wolfSSH_NewConfig(void* heap)
/* returns WS_SUCCESS on success */
static int wolfSSHD_CreateString(char** out, const char* in, int inSz,
void* heap)
{
int ret = WS_SUCCESS;
int idx = 0;
/* remove white spaces */
while (idx < inSz && in[idx] == ' ') idx++;
if (idx == inSz) {
ret = WS_BAD_ARGUMENT;
}
/* malloc new string and set it */
if (ret == WS_SUCCESS) {
*out = (char*)WMALLOC((inSz - idx) + 1, heap, DYNTYPE_SSHD);
if (*out == NULL) {
ret = WS_MEMORY_E;
}
else {
XMEMCPY(*out, in + idx, inSz - idx);
*(*out + (inSz - idx)) = '\0';
}
}
return ret;
}
static void wolfSSHD_FreeString(char** in, void* heap)
{
if (*in != NULL) {
WFREE(*in, heap, DYNTYPE_SSHD);
*in = NULL;
}
(void)heap;
}
WOLFSSHD_CONFIG* wolfSSHD_NewConfig(void* heap)
{
WOLFSSHD_CONFIG* ret;
@ -70,24 +108,66 @@ WOLFSSHD_CONFIG* wolfSSH_NewConfig(void* heap)
}
else {
WMEMSET(ret, 0, sizeof(WOLFSSHD_CONFIG));
/* default values */
ret->port = 22;
}
return ret;
}
void wolfSSH_FreeConfig(WOLFSSHD_CONFIG* conf)
void wolfSSHD_FreeConfig(WOLFSSHD_CONFIG* conf)
{
void* heap;
if (conf != NULL) {
heap = conf->heap;
wolfSSHD_FreeString(&conf->authKeysFile, heap);
WFREE(conf, heap, DYNTYPE_SSHD);
}
}
#define MAX_LINE_SIZE 160
int wolfSSH_LoadSSHD(WOLFSSHD_CONFIG* conf, const char* filename)
/* returns WS_SUCCESS on success
* Fails if any option is found that is unknown/unsupported
*/
static int wolfSSHD_ParseConfigLine(WOLFSSHD_CONFIG* conf, const char* l,
int lSz)
{
int ret = WS_BAD_ARGUMENT;
int sz;
/* supported config options */
const char authKeyFile[] = "AuthorizedKeysFile";
sz = (int)XSTRLEN(authKeyFile);
if (lSz > sz && XSTRNCMP(l, authKeyFile, sz) == 0) {
ret = wolfSSHD_CreateString(&conf->authKeysFile, l + sz, lSz - sz,
conf->heap);
}
if (XSTRNCMP(l, "UsePrivilegeSeparation", 18) == 0) {
ret = WS_SUCCESS;
}
if (XSTRNCMP(l, "Subsystem", 9) == 0) {
ret = WS_SUCCESS;
}
if (ret == WS_BAD_ARGUMENT) {
printf("unknown / unsuported config line\n");
}
(void)conf;(void)lSz;
return ret;
}
int wolfSSHD_LoadSSHD(WOLFSSHD_CONFIG* conf, const char* filename)
{
XFILE f;
int ret = WS_SUCCESS;
@ -116,11 +196,28 @@ int wolfSSH_LoadSSHD(WOLFSSHD_CONFIG* conf, const char* filename)
continue; /* commented out line */
}
printf("read config : %s\n", current);
ret = wolfSSHD_ParseConfigLine(conf, current, currentSz);
if (ret != WS_SUCCESS) {
printf("Unable to parse config line : %s\n", current);
break;
}
}
XFCLOSE(f);
return ret;
}
char* wolfSSHD_GetBanner(WOLFSSHD_CONFIG* conf)
{
if (conf != NULL)
return conf->banner;
return NULL;
}
word16 wolfSSHD_GetPort(WOLFSSHD_CONFIG* conf)
{
if (conf != NULL)
return conf->port;
return 0;
}
#endif /* WOLFSSH_SSHD */

View File

@ -26,11 +26,13 @@
#include <wolfssh/ssh.h>
#include <wolfssh/internal.h>
#include <wolfssh/test.h>
#include <wolfssh/log.h>
#include <wolfssl/wolfcrypt/wc_port.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#define WOLFSSH_TEST_SERVER
#include <wolfssh/test.h>
#include "wolfsshd.h"
#include <signal.h>
@ -44,6 +46,13 @@
/* catch interrupts and close down gracefully */
static volatile byte quit = 0;
static const char defaultBanner[] = "wolfSSHD\n";
/* Initial connection information to pass on to threads/forks */
typedef struct WOLFSSHD_CONNECTION {
WOLFSSH_CTX* ctx;
int fd;
} WOLFSSHD_CONNECTION;
static void ShowUsage(void)
{
@ -59,18 +68,240 @@ static void interruptCatch(int in)
quit = 1;
}
static int SetupCTX(WOLFSSHD_CONFIG* conf, WOLFSSH_CTX** ctx)
{
int ret = WS_SUCCESS;
const char* banner;
/* create a new WOLFSSH_CTX */
*ctx = wolfSSH_CTX_new(WOLFSSH_ENDPOINT_SERVER, NULL);
if (ctx == NULL) {
fprintf(stderr, "Couldn't allocate SSH CTX data.\n");
ret = WS_MEMORY_E;
}
/* setup authority callback for checking peer connections */
if (ret == WS_SUCCESS) {
// WMEMSET(&pwMapList, 0, sizeof(pwMapList));
// if (serverArgs->user_auth == NULL)
// wolfSSH_SetUserAuth(ctx, wsUserAuth);
// else
// wolfSSH_SetUserAuth(ctx, ((func_args*)args)->user_auth);
}
/* set banner to display on connection */
if (ret == WS_SUCCESS) {
banner = wolfSSHD_GetBanner(conf);
if (banner == NULL) {
banner = defaultBanner;
}
wolfSSH_CTX_SetBanner(*ctx, banner);
}
#ifdef WOLFSSH_AGENT
/* check if using an agent is enabled */
if (ret == WS_SUCCESS) {
wolfSSH_CTX_set_agent_cb(ctx, wolfSSH_AGENT_DefaultActions, NULL);
}
#endif
#ifdef WOLFSSH_FWD
/* check if port forwarding is enabled */
if (ret == WS_SUCCESS) {
wolfSSH_CTX_SetFwdCb(ctx, wolfSSH_FwdDefaultActions, NULL);
}
#endif
/* Load in host private key */
// {
// const char* bufName = NULL;
// #ifndef WOLFSSH_SMALL_STACK
// byte buf[EXAMPLE_KEYLOAD_BUFFER_SZ];
// #endif
// byte* keyLoadBuf;
// word32 bufSz;
//
// #ifdef WOLFSSH_SMALL_STACK
// keyLoadBuf = (byte*)WMALLOC(EXAMPLE_KEYLOAD_BUFFER_SZ,
// NULL, 0);
// if (keyLoadBuf == NULL) {
// WEXIT(EXIT_FAILURE);
// }
// #else
// keyLoadBuf = buf;
// #endif
// bufSz = EXAMPLE_KEYLOAD_BUFFER_SZ;
//
// bufSz = load_key(peerEcc, keyLoadBuf, bufSz);
// if (bufSz == 0) {
// fprintf(stderr, "Couldn't load key file.\n");
// WEXIT(EXIT_FAILURE);
// }
// if (wolfSSH_CTX_UsePrivateKey_buffer(ctx, keyLoadBuf, bufSz,
// WOLFSSH_FORMAT_ASN1) < 0) {
// fprintf(stderr, "Couldn't use key buffer.\n");
// WEXIT(EXIT_FAILURE);
// }
//
// }
/* Load in host public key */
// {
// if (userPubKey) {
// byte* userBuf = NULL;
// word32 userBufSz = 0;
//
// /* get the files size */
// load_file(userPubKey, NULL, &userBufSz);
//
// /* create temp buffer and load in file */
// if (userBufSz == 0) {
// fprintf(stderr, "Couldn't find size of file %s.\n", userPubKey);
// WEXIT(EXIT_FAILURE);
// }
//
// userBuf = (byte*)WMALLOC(userBufSz, NULL, 0);
// if (userBuf == NULL) {
// fprintf(stderr, "WMALLOC failed\n");
// WEXIT(EXIT_FAILURE);
// }
// load_file(userPubKey, userBuf, &userBufSz);
// LoadPublicKeyBuffer(userBuf, userBufSz, &pwMapList);
// }
//
// bufSz = (word32)WSTRLEN(samplePasswordBuffer);
// WMEMCPY(keyLoadBuf, samplePasswordBuffer, bufSz);
// keyLoadBuf[bufSz] = 0;
// LoadPasswordBuffer(keyLoadBuf, bufSz, &pwMapList);
//
// if (userEcc) {
// #ifndef WOLFSSH_NO_ECC
// bufName = samplePublicKeyEccBuffer;
// #endif
// }
// else {
// #ifndef WOLFSSH_NO_RSA
// bufName = samplePublicKeyRsaBuffer;
// #endif
// }
// if (bufName != NULL) {
// bufSz = (word32)WSTRLEN(bufName);
// WMEMCPY(keyLoadBuf, bufName, bufSz);
// keyLoadBuf[bufSz] = 0;
// LoadPublicKeyBuffer(keyLoadBuf, bufSz, &pwMapList);
// }
//
// bufSz = (word32)WSTRLEN(sampleNoneBuffer);
// WMEMCPY(keyLoadBuf, sampleNoneBuffer, bufSz);
// keyLoadBuf[bufSz] = 0;
// LoadNoneBuffer(keyLoadBuf, bufSz, &pwMapList);
//
// #ifdef WOLFSSH_SMALL_STACK
// WFREE(keyLoadBuf, NULL, 0);
// #endif
// }
/* Load in authorized keys */
/* Set allowed connection type, i.e. public key / password */
return ret;
}
#if 0
int SFTP_Subsystem()
{
}
int SCP_Subsystem()
{
}
#endif
//static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh)
//{
// (void)conn;
// (void)ssh;
// return WS_SUCCESS;
//}
/* handle wolfSSH accept and directing to correct subsystem */
static void* wolfSSHD_HandleConnection(void* arg)
{
WOLFSSHD_CONNECTION* conn;
WOLFSSH* ssh;
conn = (WOLFSSHD_CONNECTION*)arg;
ssh = wolfSSH_new(conn->ctx);
wolfSSH_set_fd(ssh, conn->fd);
return NULL;
}
/* returns WS_SUCCESS on success */
static int wolfSSHD_NewConnection(WOLFSSHD_CONNECTION* conn)
{
int pd;
int ret = WS_SUCCESS;
pd = fork();
if (pd < 0) {
printf("issue spawning new process\n");
ret = -1;
}
if (pd == 0) {
/* child process */
(void)wolfSSHD_HandleConnection((void*)&conn);
}
else {
printf("spawned new process %d\n", pd);
}
return ret;
}
int myoptind = 0;
char* myoptarg = NULL;
int main(int argc, char** argv)
{
int ret = WS_SUCCESS;
int ret = WS_SUCCESS;
word16 port = 0;
WS_SOCKET_T listenFd = 0;
int ch;
WOLFSSHD_CONFIG* conf = NULL;
WOLFSSH_CTX* ctx = NULL;
const char* configFile = "/usr/local/etc/ssh/sshd_config";
signal(SIGINT, interruptCatch);
#ifdef DEBUG_WOLFSSH
wolfSSH_Debugging_ON();
#endif
#ifdef DEBUG_WOLFSSL
wolfSSL_Debugging_ON();
#endif
if (ret == WS_SUCCESS) {
wolfSSH_Init();
}
if (ret == WS_SUCCESS) {
conf = wolfSSHD_NewConfig(NULL);
if (conf == NULL) {
ret = WS_MEMORY_E;
}
}
while ((ch = mygetopt(argc, argv, "?f:")) != -1) {
switch (ch) {
case 'f':
@ -88,28 +319,47 @@ int main(int argc, char** argv)
}
if (ret == WS_SUCCESS) {
wolfSSH_Init();
ret = wolfSSHD_LoadSSHD(conf, configFile);
if (ret != WS_SUCCESS)
printf("Error reading in configure file %s\n", configFile);
}
if (ret == WS_SUCCESS) {
conf = wolfSSH_NewConfig(NULL);
if (conf == NULL) {
ret = WS_MEMORY_E;
}
}
if (wolfSSH_LoadSSHD(conf, configFile) != WS_SUCCESS) {
printf("Error reading in configure file %s\n", configFile);
/* port was not overridden with argument, read from config file */
if (port == 0) {
port = wolfSSHD_GetPort(conf);
}
printf("wolfSSH SSHD application\n");
if (ret == WS_SUCCESS) {
ret = SetupCTX(conf, &ctx);
}
tcp_listen(&listenFd, &port, 1);
/* wait for incoming connections and fork them off */
do {
while (ret == WS_SUCCESS && quit == 0) {
WOLFSSHD_CONNECTION conn;
#ifdef WOLFSSL_NUCLEUS
struct addr_struct clientAddr;
#else
SOCKADDR_IN_T clientAddr;
socklen_t clientAddrSz = sizeof(clientAddr);
#endif
} while (ret == WS_SUCCESS && quit == 0);
/* wait for a connection */
conn.ctx = ctx;
#ifdef WOLFSSL_NUCLEUS
conn.fd = NU_Accept(listenFd, &clientAddr, 0);
#else
conn.fd = accept(listenFd, (struct sockaddr*)&clientAddr,
&clientAddrSz);
#endif
wolfSSH_FreeConfig(conf);
ret = wolfSSHD_NewConnection(&conn);
}
wolfSSHD_FreeConfig(conf);
wolfSSH_Cleanup();
return 0;
}

View File

@ -23,9 +23,12 @@
typedef struct WOLFSSHD_CONFIG WOLFSSHD_CONFIG;
WOLFSSHD_CONFIG* wolfSSH_NewConfig(void* heap);
void wolfSSH_FreeConfig(WOLFSSHD_CONFIG* conf);
int wolfSSH_LoadSSHD(WOLFSSHD_CONFIG* con, const char* filename);
WOLFSSHD_CONFIG* wolfSSHD_NewConfig(void* heap);
void wolfSSHD_FreeConfig(WOLFSSHD_CONFIG* conf);
int wolfSSHD_LoadSSHD(WOLFSSHD_CONFIG* conf, const char* filename);
char* wolfSSHD_GetBanner(WOLFSSHD_CONFIG* conf);
word16 wolfSSHD_GetPort(WOLFSSHD_CONFIG* conf);
#endif /* WOLFSSHD_H */