mirror of https://github.com/wolfSSL/wolfssh.git
expanding config parsing
parent
27cf3d31b9
commit
757f3c6b2c
|
@ -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 */
|
||||
|
|
280
apps/wolfsshd.c
280
apps/wolfsshd.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
Loading…
Reference in New Issue