initial openssh-style certificate parsing

pull/453/head
Hayden Roche 2022-08-22 14:59:32 -07:00 committed by JacobBarthelmeh
parent 543e5c89e3
commit 7c486e518a
5 changed files with 313 additions and 127 deletions

View File

@ -61,9 +61,9 @@
#endif
struct WOLFSSHD_AUTH {
CallbackCheckUser CheckUserCb;
CallbackCheckPassword CheckPasswordCb;
CallbackCheckPublicKey CheckPublicKeyCb;
CallbackCheckUser checkUserCb;
CallbackCheckPassword checkPasswordCb;
CallbackCheckPublicKey checkPublicKeyCb;
const WOLFSSHD_CONFIG* conf;
int gid;
int uid;
@ -75,7 +75,7 @@ struct WOLFSSHD_AUTH {
#define WOLFSSHD_MAX_PASSWORD_ATTEMPTS 3
#endif
#ifndef MAX_LEN_SZ
#ifndef MAX_LINE_SZ
#define MAX_LINE_SZ 500
#endif
#ifndef MAX_PATH_SZ
@ -132,6 +132,7 @@ enum {
WSSHD_AUTH_SUCCESS = 1
};
/* TODO: Can use wolfSSH_ReadKey_buffer? */
static int CheckAuthKeysLine(char* line, word32 lineSz, const byte* key,
word32 keySz)
{
@ -465,7 +466,9 @@ static int ResolveAuthKeysPath(const char* homeDir, char* resolved)
return ret;
}
static int CheckPublicKeyUnix(const char* name, const byte* key, word32 keySz)
static int CheckPublicKeyUnix(const char* name,
const WS_UserAuthData_PublicKey* pubKeyCtx,
const char* usrCaKeysFile)
{
int ret = WSSHD_AUTH_SUCCESS;
int rc;
@ -478,67 +481,132 @@ static int CheckPublicKeyUnix(const char* name, const byte* key, word32 keySz)
int foundKey = 0;
char authKeysPath[MAX_PATH_SZ];
errno = 0;
pwInfo = getpwnam((const char*)name);
if (pwInfo == NULL) {
if (errno != 0) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error calling getpwnam for user "
"%s.", name);
}
ret = WS_FATAL_ERROR;
}
#ifdef WOLFSSH_OSSH_CERTS
if (pubKeyCtx->isOsshCert) {
byte* caKey = NULL;
word32 caKeySz;
const byte* caKeyType = NULL;
word32 caKeyTypeSz;
byte fingerprint[WC_SHA256_DIGEST_SIZE];
if (ret == WSSHD_AUTH_SUCCESS) {
WMEMSET(authKeysPath, 0, sizeof(authKeysPath));
rc = ResolveAuthKeysPath(pwInfo->pw_dir, authKeysPath);
if (rc != WS_SUCCESS) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Failed to resolve authorized keys"
" file path.");
ret = rc;
}
}
if (ret == WSSHD_AUTH_SUCCESS) {
f = XFOPEN(authKeysPath, "rb");
if (f == XBADFILE) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Unable to open %s",
authKeysPath);
ret = WS_BAD_FILE_E;
}
}
if (ret == WSSHD_AUTH_SUCCESS) {
lineBuf = (char*)WMALLOC(MAX_LINE_SZ, NULL, DYNTYPE_BUFFER);
if (lineBuf == NULL) {
ret = WS_MEMORY_E;
}
}
while (ret == WSSHD_AUTH_SUCCESS &&
(current = XFGETS(lineBuf, MAX_LINE_SZ, f)) != NULL) {
currentSz = (word32)XSTRLEN(current);
/* remove leading spaces */
while (currentSz > 0 && current[0] == ' ') {
currentSz = currentSz - 1;
current = current + 1;
if (pubKeyCtx->caKey == NULL ||
pubKeyCtx->caKeySz != WC_SHA256_DIGEST_SIZE) {
ret = WS_FATAL_ERROR;
}
if (currentSz <= 1) {
continue; /* empty line */
if (ret == WSSHD_AUTH_SUCCESS) {
f = XFOPEN(usrCaKeysFile, "rb");
if (f == XBADFILE) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Unable to open %s",
usrCaKeysFile);
ret = WS_BAD_FILE_E;
}
}
if (ret == WSSHD_AUTH_SUCCESS) {
lineBuf = (char*)WMALLOC(MAX_LINE_SZ, NULL, DYNTYPE_BUFFER);
if (lineBuf == NULL) {
ret = WS_MEMORY_E;
}
}
while (ret == WSSHD_AUTH_SUCCESS &&
(current = XFGETS(lineBuf, MAX_LINE_SZ, f)) != NULL) {
currentSz = (word32)XSTRLEN(current);
if (current[0] == '#') {
continue; /* commented out line */
}
/* remove leading spaces */
while (currentSz > 0 && current[0] == ' ') {
currentSz = currentSz - 1;
current = current + 1;
}
rc = CheckAuthKeysLine(current, currentSz, key, keySz);
if (rc == WSSHD_AUTH_SUCCESS) {
foundKey = 1;
break;
}
else if (rc < 0) {
ret = rc;
break;
if (currentSz <= 1) {
continue; /* empty line */
}
if (current[0] == '#') {
continue; /* commented out line */
}
rc = wolfSSH_ReadKey_buffer((const byte*)current, currentSz,
WOLFSSH_FORMAT_SSH, &caKey, &caKeySz,
&caKeyType, &caKeyTypeSz, NULL);
if (rc == WS_SUCCESS) {
rc = wc_Hash(WC_HASH_TYPE_SHA256, caKey, caKeySz, fingerprint,
WC_SHA256_DIGEST_SIZE);
if (rc == 0 && WMEMCMP(fingerprint, pubKeyCtx->caKey,
WC_SHA256_DIGEST_SIZE) == 0) {
foundKey = 1;
break;
}
}
}
}
else
#endif /* WOLFSSH_OSSH_CERTS */
{
errno = 0;
pwInfo = getpwnam((const char*)name);
if (pwInfo == NULL) {
if (errno != 0) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error calling getpwnam for user "
"%s.", name);
}
ret = WS_FATAL_ERROR;
}
if (ret == WSSHD_AUTH_SUCCESS) {
WMEMSET(authKeysPath, 0, sizeof(authKeysPath));
rc = ResolveAuthKeysPath(pwInfo->pw_dir, authKeysPath);
if (rc != WS_SUCCESS) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Failed to resolve authorized keys"
" file path.");
ret = rc;
}
}
if (ret == WSSHD_AUTH_SUCCESS) {
f = XFOPEN(authKeysPath, "rb");
if (f == XBADFILE) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Unable to open %s",
authKeysPath);
ret = WS_BAD_FILE_E;
}
}
if (ret == WSSHD_AUTH_SUCCESS) {
lineBuf = (char*)WMALLOC(MAX_LINE_SZ, NULL, DYNTYPE_BUFFER);
if (lineBuf == NULL) {
ret = WS_MEMORY_E;
}
}
while (ret == WSSHD_AUTH_SUCCESS &&
(current = XFGETS(lineBuf, MAX_LINE_SZ, f)) != NULL) {
currentSz = (word32)XSTRLEN(current);
/* remove leading spaces */
while (currentSz > 0 && current[0] == ' ') {
currentSz = currentSz - 1;
current = current + 1;
}
if (currentSz <= 1) {
continue; /* empty line */
}
if (current[0] == '#') {
continue; /* commented out line */
}
rc = CheckAuthKeysLine(current, currentSz, pubKeyCtx->publicKey,
pubKeyCtx->publicKeySz);
if (rc == WSSHD_AUTH_SUCCESS) {
foundKey = 1;
break;
}
else if (rc < 0) {
ret = rc;
break;
}
}
}
if (f != XBADFILE) {
XFCLOSE(f);
}
@ -554,6 +622,7 @@ static int CheckPublicKeyUnix(const char* name, const byte* key, word32 keySz)
WFREE(authKeysFile, NULL, DYNTYPE_STRING);
}
(void)usrCaKeysFile;
return ret;
}
#endif /* !_WIN32*/
@ -562,71 +631,80 @@ static int CheckPublicKeyUnix(const char* name, const byte* key, word32 keySz)
/* return WOLFSSH_USERAUTH_SUCCESS on success */
static int DoCheckUser(const char* usr, WOLFSSHD_AUTH* auth)
{
int ret = WOLFSSH_USERAUTH_FAILURE;
int ret = WOLFSSH_USERAUTH_SUCCESS;
int rc;
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Checking user name %s", usr);
rc = auth->CheckUserCb(usr);
if (rc == WSSHD_AUTH_SUCCESS) {
wolfSSH_Log(WS_LOG_INFO, "[SSHD] User ok.");
ret = WOLFSSH_USERAUTH_SUCCESS;
if (wolfSSHD_ConfigGetPermitRoot(auth->conf) == 0) {
if (XSTRCMP(usr, "root") == 0) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Login as root not permited");
ret = WOLFSSH_USERAUTH_FAILURE;
}
}
else if (ret == WSSHD_AUTH_FAILURE) {
wolfSSH_Log(WS_LOG_INFO, "[SSHD] User %s doesn't exist.", usr);
ret = WOLFSSH_USERAUTH_INVALID_USER;
}
else {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error looking up user %s.", usr);
ret = WOLFSSH_USERAUTH_FAILURE;
if (ret == WOLFSSH_USERAUTH_SUCCESS) {
rc = auth->checkUserCb(usr);
if (rc == WSSHD_AUTH_SUCCESS) {
wolfSSH_Log(WS_LOG_INFO, "[SSHD] User ok.");
ret = WOLFSSH_USERAUTH_SUCCESS;
}
else if (ret == WSSHD_AUTH_FAILURE) {
wolfSSH_Log(WS_LOG_INFO, "[SSHD] User %s doesn't exist.", usr);
ret = WOLFSSH_USERAUTH_INVALID_USER;
}
else {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error looking up user %s.", usr);
ret = WOLFSSH_USERAUTH_FAILURE;
}
}
return ret;
}
/* @TODO this will take in a pipe or equivalent to talk to a privileged thread
* rathar than having WOLFSSHD_AUTH directly with privilege separation */
static int RequestAuthentication(const char* usr, int type, const byte* data,
int dataSz, WOLFSSHD_AUTH* auth)
static int RequestAuthentication(WS_UserAuthData* authData,
WOLFSSHD_AUTH* authCtx)
{
int ret;
int rc;
const char* usr;
if (auth == NULL)
if (authData == NULL || authCtx == NULL) {
return WOLFSSH_USERAUTH_FAILURE;
if (wolfSSHD_ConfigGetPermitRoot(auth->conf) == 0) {
if (XSTRCMP(usr, "root") == 0) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Login as root not permited");
return WOLFSSH_USERAUTH_FAILURE;
}
}
ret = DoCheckUser(usr, auth);
usr = (const char*)authData->username;
ret = DoCheckUser(usr, authCtx);
/* temporarily elevate permissions */
if (ret == WOLFSSH_USERAUTH_SUCCESS &&
wolfSSHD_AuthRaisePermissions(auth) != WS_SUCCESS) {
wolfSSHD_AuthRaisePermissions(authCtx) != WS_SUCCESS) {
wolfSSH_Log(WS_LOG_ERROR,
"[SSHD] Failure to raise permissions for auth");
ret = WOLFSSH_USERAUTH_FAILURE;
}
if (ret == WOLFSSH_USERAUTH_SUCCESS && type == WOLFSSH_USERAUTH_PASSWORD) {
int rc;
if (ret == WOLFSSH_USERAUTH_SUCCESS &&
authData->type == WOLFSSH_USERAUTH_PASSWORD) {
if (wolfSSHD_ConfigGetPwAuth(auth->conf) != 1) {
if (wolfSSHD_ConfigGetPwAuth(authCtx->conf) != 1) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Password authentication not "
"allowed by configuration!");
ret = WOLFSSH_USERAUTH_FAILURE;
}
/* Check if password is valid for this user. */
/* first handle empty password cases */
else if (dataSz == 0 && wolfSSHD_ConfigGetPermitEmptyPw(auth->conf)
!= 1) {
else if (authData->sf.password.passwordSz == 0 &&
wolfSSHD_ConfigGetPermitEmptyPw(authCtx->conf) != 1) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Empty passwords not allowed by "
"configuration!");
ret = WOLFSSH_USERAUTH_FAILURE;
}
else {
rc = auth->CheckPasswordCb(usr, data, dataSz);
rc = authCtx->checkPasswordCb(usr, authData->sf.password.password,
authData->sf.password.passwordSz);
if (rc == WSSHD_AUTH_SUCCESS) {
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Password ok.");
}
@ -634,8 +712,8 @@ static int RequestAuthentication(const char* usr, int type, const byte* data,
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Password incorrect.");
ret = WOLFSSH_USERAUTH_INVALID_PASSWORD;
auth->attempts--;
if (auth->attempts == 0) {
authCtx->attempts--;
if (authCtx->attempts == 0) {
wolfSSH_Log(WS_LOG_ERROR,
"[SSHD] Too many bad password attempts!");
ret = WOLFSSH_USERAUTH_REJECTED;
@ -649,10 +727,11 @@ static int RequestAuthentication(const char* usr, int type, const byte* data,
}
if (ret == WOLFSSH_USERAUTH_SUCCESS && type == WOLFSSH_USERAUTH_PUBLICKEY) {
int rc;
if (ret == WOLFSSH_USERAUTH_SUCCESS &&
authData->type == WOLFSSH_USERAUTH_PUBLICKEY) {
rc = auth->CheckPublicKeyCb(usr, data, dataSz);
rc = authCtx->checkPublicKeyCb(usr, &authData->sf.publicKey,
wolfSSHD_ConfigGetUserCAKeysFile(authCtx->conf));
if (rc == WSSHD_AUTH_SUCCESS) {
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Public key ok.");
ret = WOLFSSH_USERAUTH_SUCCESS;
@ -668,10 +747,11 @@ static int RequestAuthentication(const char* usr, int type, const byte* data,
}
if (wolfSSHD_AuthReducePermissions(auth) != WS_SUCCESS) {
if (wolfSSHD_AuthReducePermissions(authCtx) != WS_SUCCESS) {
/* stop everything if not able to reduce permissions level */
exit(1);
}
return ret;
}
@ -680,15 +760,15 @@ static int RequestAuthentication(const char* usr, int type, const byte* data,
int DefaultUserAuth(byte authType, WS_UserAuthData* authData, void* ctx)
{
int ret = WOLFSSH_USERAUTH_SUCCESS;
WOLFSSHD_AUTH* auth;
WOLFSSHD_AUTH* authCtx;
if (ctx == NULL) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] No auth callbacks passed in");
return WOLFSSH_USERAUTH_FAILURE;
}
else {
auth = (WOLFSSHD_AUTH*)ctx;
if (auth->CheckUserCb == NULL) {
authCtx = (WOLFSSHD_AUTH*)ctx;
if (authCtx->checkUserCb == NULL) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] No way to check the user is set");
return WOLFSSH_USERAUTH_FAILURE;
}
@ -708,22 +788,9 @@ int DefaultUserAuth(byte authType, WS_UserAuthData* authData, void* ctx)
ret = WOLFSSH_USERAUTH_INVALID_AUTHTYPE;
}
/* call to possibly privilaged authentecator for password check */
if (ret == WOLFSSH_USERAUTH_SUCCESS &&
authData->type == WOLFSSH_USERAUTH_PASSWORD) {
ret = RequestAuthentication((const char*)authData->username,
authData->type,
authData->sf.password.password,
authData->sf.password.passwordSz, auth);
}
/* call to possibly privilaged authentecator for public key check */
if (ret == WOLFSSH_USERAUTH_SUCCESS &&
authData->type == WOLFSSH_USERAUTH_PUBLICKEY) {
ret = RequestAuthentication((const char*)authData->username,
authData->type,
authData->sf.publicKey.publicKey,
authData->sf.publicKey.publicKeySz, auth);
/* call to possibly privileged authenticator for password check */
if (ret == WOLFSSH_USERAUTH_SUCCESS) {
ret = RequestAuthentication(authData, authCtx);
}
return ret;
@ -738,7 +805,7 @@ static int SetDefaultUserCheck(WOLFSSHD_AUTH* auth)
/* TODO: Implement for Windows. */
#else
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Setting default Unix user name check");
auth->CheckUserCb = CheckUserUnix;
auth->checkUserCb = CheckUserUnix;
ret = WS_SUCCESS;
#endif
@ -754,11 +821,11 @@ static int SetDefaultPasswordCheck(WOLFSSHD_AUTH* auth)
/* TODO: Add CheckPasswordWin. */
#elif defined(WOLFSSH_USE_PAM)
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Setting PAM password check");
auth->CheckPasswordCb = CheckPasswordPAM;
auth->checkPasswordCb = CheckPasswordPAM;
ret = WS_SUCCESS;
#else
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Setting Unix password check");
auth->CheckPasswordCb = CheckPasswordUnix;
auth->checkPasswordCb = CheckPasswordUnix;
ret = WS_SUCCESS;
#endif
return ret;
@ -773,7 +840,7 @@ static int SetDefaultPublicKeyCheck(WOLFSSHD_AUTH* auth)
/* TODO: Implement for Windows. */
#else
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Setting Unix public key check");
auth->CheckPublicKeyCb = CheckPublicKeyUnix;
auth->checkPublicKeyCb = CheckPublicKeyUnix;
ret = WS_SUCCESS;
#endif
return ret;

View File

@ -51,8 +51,9 @@ typedef int (*CallbackCheckPassword)(const char* usr, const byte* psw,
* Returns WSSHD_AUTH_SUCCESS if public key ok, WSSHD_AUTH_FAILURE if key not
* ok, and negative values if an error occurs during checking.
*/
typedef int (*CallbackCheckPublicKey)(const char* usr, const byte* key,
word32 keySz);
typedef int (*CallbackCheckPublicKey)(const char* usr,
const WS_UserAuthData_PublicKey* pubKey,
const char* usrCaKeysFile);
WOLFSSHD_AUTH* wolfSSHD_AuthCreateUser(void* heap, const WOLFSSHD_CONFIG* conf);
int wolfSSHD_AuthFreeUser(WOLFSSHD_AUTH* auth);

View File

@ -57,6 +57,8 @@ struct WOLFSSHD_CONFIG {
char* chrootDir;
char* ciphers;
char* hostKeyFile;
char* hostCertFile;
char* userCAKeysFile;
char* hostKeyAlgos;
char* kekAlgos;
char* listenAddress;
@ -290,6 +292,7 @@ void wolfSSHD_ConfigFree(WOLFSSHD_CONFIG* conf)
FreeString(&current->listenAddress, heap);
FreeString(&current->authKeysFile, heap);
FreeString(&current->hostKeyFile, heap);
FreeString(&current->hostCertFile, heap);
WFREE(current, heap, DYNTYPE_SSHD);
current = next;
@ -324,9 +327,11 @@ enum {
OPT_CHROOT_DIR = 17,
OPT_MATCH = 18,
OPT_FORCE_CMD = 19,
OPT_HOST_CERT = 20,
OPT_TRUSTED_USER_CA_KEYS = 21,
};
enum {
NUM_OPTIONS = 20
NUM_OPTIONS = 22
};
static const CONFIG_OPTION options[NUM_OPTIONS] = {
@ -350,6 +355,8 @@ static const CONFIG_OPTION options[NUM_OPTIONS] = {
{OPT_CHROOT_DIR, "ChrootDirectory"},
{OPT_MATCH, "Match"},
{OPT_FORCE_CMD, "ForceCommand"},
{OPT_HOST_CERT, "HostCertificate"},
{OPT_TRUSTED_USER_CA_KEYS, "TrustedUserCAKeys"},
};
/* returns WS_SUCCESS on success */
@ -955,6 +962,10 @@ static int HandleConfigOption(WOLFSSHD_CONFIG** conf, int opt,
/* TODO: Add logic to check if file exists? */
ret = wolfSSHD_ConfigSetHostKeyFile(*conf, value);
break;
case OPT_HOST_CERT:
/* TODO: Add logic to check if file exists? */
ret = wolfSSHD_ConfigSetHostCertFile(*conf, value);
break;
case OPT_PASSWORD_AUTH:
ret = HandlePwAuth(*conf, value);
break;
@ -981,6 +992,10 @@ static int HandleConfigOption(WOLFSSHD_CONFIG** conf, int opt,
case OPT_FORCE_CMD:
ret = HandleForcedCommand(*conf, full, fullSz);
break;
case OPT_TRUSTED_USER_CA_KEYS:
/* TODO: Add logic to check if file exists? */
ret = wolfSSHD_ConfigSetUserCAKeysFile(*conf, value);
break;
default:
break;
}
@ -1234,6 +1249,50 @@ char* wolfSSHD_ConfigGetHostKeyFile(const WOLFSSHD_CONFIG* conf)
return ret;
}
char* wolfSSHD_ConfigGetHostCertFile(const WOLFSSHD_CONFIG* conf)
{
char* ret = NULL;
if (conf != NULL) {
ret = conf->hostCertFile;
}
return ret;
}
char* wolfSSHD_ConfigGetUserCAKeysFile(const WOLFSSHD_CONFIG* conf)
{
char* ret = NULL;
if (conf != NULL) {
ret = conf->userCAKeysFile;
}
return ret;
}
static int SetFileString(char** dst, const char* src, void* heap)
{
int ret = WS_SUCCESS;
if (dst == NULL) {
ret = WS_BAD_ARGUMENT;
}
if (ret == WS_SUCCESS) {
if (*dst != NULL) {
FreeString(dst, heap);
*dst = NULL;
}
if (src != NULL) {
ret = CreateString(dst, src, (int)WSTRLEN(src), heap);
}
}
return ret;
}
int wolfSSHD_ConfigSetHostKeyFile(WOLFSSHD_CONFIG* conf, const char* file)
{
int ret = WS_SUCCESS;
@ -1243,15 +1302,37 @@ int wolfSSHD_ConfigSetHostKeyFile(WOLFSSHD_CONFIG* conf, const char* file)
}
if (ret == WS_SUCCESS) {
if (conf->hostKeyFile != NULL) {
FreeString(&conf->hostKeyFile, conf->heap);
conf->hostKeyFile = NULL;
}
ret = SetFileString(&conf->hostKeyFile, file, conf->heap);
}
if (file != NULL) {
ret = CreateString(&conf->hostKeyFile, file,
(int)WSTRLEN(file), conf->heap);
}
return ret;
}
int wolfSSHD_ConfigSetHostCertFile(WOLFSSHD_CONFIG* conf, const char* file)
{
int ret = WS_SUCCESS;
if (conf == NULL) {
ret = WS_BAD_ARGUMENT;
}
if (ret == WS_SUCCESS) {
ret = SetFileString(&conf->hostCertFile, file, conf->heap);
}
return ret;
}
int wolfSSHD_ConfigSetUserCAKeysFile(WOLFSSHD_CONFIG* conf, const char* file)
{
int ret = WS_SUCCESS;
if (conf == NULL) {
ret = WS_BAD_ARGUMENT;
}
if (ret == WS_SUCCESS) {
ret = SetFileString(&conf->userCAKeysFile, file, conf->heap);
}
return ret;

View File

@ -38,7 +38,11 @@ char* wolfSSHD_ConfigGetForcedCmd(const WOLFSSHD_CONFIG* conf);
char* wolfSSHD_ConfigGetBanner(const WOLFSSHD_CONFIG* conf);
char* wolfSSHD_ConfigGetChroot(const WOLFSSHD_CONFIG* conf);
char* wolfSSHD_ConfigGetHostKeyFile(const WOLFSSHD_CONFIG* conf);
char* wolfSSHD_ConfigGetHostCertFile(const WOLFSSHD_CONFIG* conf);
char* wolfSSHD_ConfigGetUserCAKeysFile(const WOLFSSHD_CONFIG* conf);
int wolfSSHD_ConfigSetHostKeyFile(WOLFSSHD_CONFIG* conf, const char* file);
int wolfSSHD_ConfigSetHostCertFile(WOLFSSHD_CONFIG* conf, const char* file);
int wolfSSHD_ConfigSetUserCAKeysFile(WOLFSSHD_CONFIG* conf, const char* file);
word16 wolfSSHD_ConfigGetPort(const WOLFSSHD_CONFIG* conf);
char* wolfSSHD_ConfigGetAuthKeysFile(const WOLFSSHD_CONFIG* conf);
int wolfSSHD_ConfigSetAuthKeysFile(WOLFSSHD_CONFIG* conf, const char* file);

View File

@ -272,7 +272,40 @@ static int SetupCTX(WOLFSSHD_CONFIG* conf, WOLFSSH_CTX** ctx)
}
}
}
#ifdef WOLFSSH_OSSH_CERTS
if (ret == WS_SUCCESS) {
/* TODO: Create a helper function that uses a file instead. */
char* hostCert = wolfSSHD_ConfigGetHostCertFile(conf);
if (hostCert != NULL) {
FILE* f;
f = XFOPEN(hostCert, "rb");
if (f == NULL) {
wolfSSH_Log(WS_LOG_ERROR,
"[SSHD] Unable to open host certificate.");
ret = WS_BAD_ARGUMENT;
}
else {
byte* data;
int dataSz = 4096;
data = (byte*)WMALLOC(dataSz, NULL, 0);
dataSz = (int)XFREAD(data, 1, dataSz, f);
XFCLOSE(f);
if (wolfSSH_CTX_UseOsshCert_buffer(*ctx, data, dataSz) < 0) {
wolfSSH_Log(WS_LOG_ERROR,
"[SSHD] Failed to use host certificate.");
ret = WS_BAD_ARGUMENT;
}
WFREE(data, NULL, 0);
}
}
}
#endif /* WOLFSSH_OSSH_CERTS */
/* @TODO Load in host public key */
/* Set allowed connection type, i.e. public key / password */