Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/os-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ jobs:
'--enable-all',
'--enable-sftp',
'--enable-scp',
'--enable-keyboard-interactive',
'--enable-shell',
]
name: Build wolfssh
Expand Down
11 changes: 10 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,11 @@ AC_ARG_ENABLE([keygen],
[AS_HELP_STRING([--enable-keygen],[Enable key generation (default: disabled)])],
[ENABLED_KEYGEN=$enableval],[ENABLED_KEYGEN=no])

# Keyboard Interactive
AC_ARG_ENABLE([keyboard-interactive],
[AS_HELP_STRING([--enable-keyboard-interactive],[Enable keyboard interactive authentication (default: disabled)])],
[ENABLED_KEYBOARD_INTERACTIVE=$enableval],[ENABLED_KEYBOARD_INTERACTIVE=no])

# SCP
AC_ARG_ENABLE([scp],
[AS_HELP_STRING([--enable-scp],[Enable scp support (default: disabled)])],
Expand Down Expand Up @@ -206,7 +211,7 @@ AC_ARG_ENABLE([distro],
AS_IF([test "x$ENABLED_DISTRO" = "xyes"],
[ENABLED_ALL=yes; enable_shared=yes; enable_static=yes])
AS_IF([test "x$ENABLED_ALL" = "xyes"],
[ENABLED_KEYGEN=yes; ENABLED_SCP=yes; ENABLED_SFTP=yes; ENABLED_FWD=yes; ENABLED_SHELL=yes; ENABLED_AGENT=yes; ENABLED_SSHD=yes; ENABLED_SSHCLIENT=yes; ENABLED_CERTS=yes])
[ENABLED_KEYGEN=yes; ENABLED_SCP=yes; ENABLED_SFTP=yes; ENABLED_FWD=yes; ENABLED_SHELL=yes; ENABLED_AGENT=yes; ENABLED_SSHD=yes; ENABLED_SSHCLIENT=yes; ENABLED_CERTS=yes; ENABLED_KEYBOARD_INTERACTIVE=yes])
AS_IF([test "x$ENABLED_SSHD" = "xyes"],
[ENABLED_SHELL=yes])

Expand All @@ -215,6 +220,8 @@ AS_IF([test "x$ENABLED_INLINE" = "xno"],
[AM_CPPFLAGS="$AM_CPPFLAGS -DNO_INLINE"])
AS_IF([test "x$ENABLED_KEYGEN" = "xyes"],
[AM_CPPFLAGS="$AM_CPPFLAGS -DWOLFSSH_KEYGEN"])
AS_IF([test "x$ENABLED_KEYBOARD_INTERACTIVE" = "xyes"],
[AM_CPPFLAGS="$AM_CPPFLAGS -DWOLFSSH_KEYBOARD_INTERACTIVE"])
AS_IF([test "x$ENABLED_SCP" = "xyes"],
[AM_CPPFLAGS="$AM_CPPFLAGS -DWOLFSSH_SCP"])
AS_IF([test "x$ENABLED_SFTP" = "xyes"],
Expand Down Expand Up @@ -292,6 +299,7 @@ AM_CONDITIONAL([BUILD_SSHD],[test "x$ENABLED_SSHD" = "xyes"])
AM_CONDITIONAL([BUILD_SSHCLIENT],[test "x$ENABLED_SSHCLIENT" = "xyes"])
AM_CONDITIONAL([BUILD_CERTS],[test "x$ENABLED_CERTS" = "xyes"])
AM_CONDITIONAL([BUILD_TPM],[test "x$ENABLED_TPM" = "xyes"])
AM_CONDITIONAL([BUILD_KEYBOARD_INTERACTIVE],[test "x$ENABLED_KEYBOARD_INTERACTIVE" = "xyes"])

AX_HARDEN_CC_COMPILER_FLAGS

Expand Down Expand Up @@ -328,6 +336,7 @@ AS_ECHO([" Features"])
AS_ECHO([" * Inline Code: $ENABLED_INLINE"])
AS_ECHO([" * Small stack: $ENABLED_SMALLSTACK"])
AS_ECHO([" * keygen: $ENABLED_KEYGEN"])
AS_ECHO([" * keyboard interactive: $ENABLED_KEYBOARD_INTERACTIVE"])
AS_ECHO([" * psuedo-terminal: $ENABLED_TERM"])
AS_ECHO([" * echoserver shell support: $ENABLED_SHELL"])
AS_ECHO([" * scp: $ENABLED_SCP"])
Expand Down
13 changes: 10 additions & 3 deletions examples/client/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,11 @@ static word32 userPrivateKeySz = 0;
static word32 userPrivateKeyTypeSz = 0;
static byte isPrivate = 0;

#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
static word32 keyboardResponseCount = 0;
static byte** keyboardResponses;
static word32* keyboardResponseLengths;

#endif

#ifdef WOLFSSH_CERTS
#if 0
Expand Down Expand Up @@ -460,7 +461,7 @@ int ClientUserAuth(byte authType,
{
const char* defaultPassword = (const char*)ctx;
word32 passwordSz = 0;
#ifdef WOLFSSH_TERM
#if defined(WOLFSSH_TERM) && defined(WOLFSSH_KEYBOARD_INTERACTIVE)
word32 entry;
#endif
int ret = WOLFSSH_USERAUTH_SUCCESS;
Expand All @@ -474,9 +475,11 @@ int ClientUserAuth(byte authType,
if (authData->type & WOLFSSH_USERAUTH_PUBLICKEY) {
printf(" - publickey\n");
}
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
if (authData->type & WOLFSSH_USERAUTH_KEYBOARD) {
printf(" - keyboard\n");
}
#endif
printf("wolfSSH requesting to use type %d\n", authType);
#endif

Expand Down Expand Up @@ -544,7 +547,7 @@ int ClientUserAuth(byte authType,
authData->sf.password.passwordSz = passwordSz;
}
}
#ifdef WOLFSSH_TERM
#if defined(WOLFSSH_TERM) && defined(WOLFSSH_KEYBOARD_INTERACTIVE)
else if (authType == WOLFSSH_USERAUTH_KEYBOARD) {
if (authData->sf.keyboard.promptName &&
authData->sf.keyboard.promptName[0] != '\0') {
Expand Down Expand Up @@ -1112,7 +1115,9 @@ int ClientLoadCA(WOLFSSH_CTX* ctx, const char* caCert)
void ClientFreeBuffers(const char* pubKeyName, const char* privKeyName,
void* heap)
{
#if defined(WOLFSSH_TERM) && defined(WOLFSSH_KEYBOARD_INTERACTIVE)
word32 entry;
#endif
#ifdef WOLFSSH_TPM
wolfSSH_TPM_Cleanup(&tpmDev, &tpmKey);
#endif
Expand All @@ -1126,9 +1131,11 @@ void ClientFreeBuffers(const char* pubKeyName, const char* privKeyName,
WFREE(userPrivateKey, heap, DYNTYPE_PRIVKEY);
}

#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
for (entry = 0; entry < keyboardResponseCount; entry++) {
WFREE(keyboardResponses[entry], NULL, 0);
}
WFREE(keyboardResponses, NULL, 0);
WFREE(keyboardResponseLengths, NULL, 0);
#endif
}
29 changes: 26 additions & 3 deletions examples/echoserver/echoserver.c
Original file line number Diff line number Diff line change
Expand Up @@ -2006,7 +2006,7 @@ static int LoadPasswdList(StrList* strList, PwMapList* mapList)

return count;
}

#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
static int LoadKeyboardList(StrList* strList, PwMapList* mapList)
{
char names[256];
Expand Down Expand Up @@ -2034,6 +2034,7 @@ static int LoadKeyboardList(StrList* strList, PwMapList* mapList)

return count;
}
#endif

#ifndef NO_FILESYSTEM
static int LoadPubKeyList(StrList* strList, int format, PwMapList* mapList)
Expand Down Expand Up @@ -2183,8 +2184,10 @@ static int wsUserAuth(byte authType,
#ifdef WOLFSSH_ALLOW_USERAUTH_NONE
authType != WOLFSSH_USERAUTH_NONE &&
#endif
authType != WOLFSSH_USERAUTH_PUBLICKEY &&
authType != WOLFSSH_USERAUTH_KEYBOARD) {
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
authType != WOLFSSH_USERAUTH_KEYBOARD &&
#endif
authType != WOLFSSH_USERAUTH_PUBLICKEY) {

return WOLFSSH_USERAUTH_FAILURE;
}
Expand All @@ -2194,6 +2197,7 @@ static int wsUserAuth(byte authType,
authData->sf.password.passwordSz,
authHash);
}
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
else if (authType == WOLFSSH_USERAUTH_KEYBOARD) {
if (authData->sf.keyboard.responseCount != 1) {
return WOLFSSH_USERAUTH_FAILURE;
Expand All @@ -2202,6 +2206,7 @@ static int wsUserAuth(byte authType,
authData->sf.keyboard.responseLengths[0],
authHash);
}
#endif
else if (authType == WOLFSSH_USERAUTH_PUBLICKEY) {
wc_Sha256Hash(authData->sf.publicKey.publicKey,
authData->sf.publicKey.publicKeySz,
Expand Down Expand Up @@ -2302,6 +2307,7 @@ static int wsUserAuth(byte authType,
WOLFSSH_USERAUTH_REJECTED;
}
}
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
else if (authData->type == WOLFSSH_USERAUTH_KEYBOARD) {
if (WMEMCMP(map->p, authHash, WC_SHA256_DIGEST_SIZE) == 0) {
return WOLFSSH_USERAUTH_SUCCESS;
Expand All @@ -2310,6 +2316,7 @@ static int wsUserAuth(byte authType,
return WOLFSSH_USERAUTH_INVALID_PASSWORD;
}
}
#endif
#ifdef WOLFSSH_ALLOW_USERAUTH_NONE
else if (authData->type == WOLFSSH_USERAUTH_NONE) {
return WOLFSSH_USERAUTH_SUCCESS;
Expand All @@ -2325,13 +2332,15 @@ static int wsUserAuth(byte authType,
return WOLFSSH_USERAUTH_INVALID_USER;
}

#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
static int keyboardCallback(WS_UserAuthData_Keyboard *kbAuth, void *ctx)
{
WS_UserAuthData_Keyboard *kbAuthData = (WS_UserAuthData_Keyboard*) ctx;
WMEMCPY(kbAuth, kbAuthData, sizeof(WS_UserAuthData_Keyboard));

return WS_SUCCESS;
}
#endif

#ifdef WOLFSSH_SFTP
/*
Expand Down Expand Up @@ -2417,9 +2426,11 @@ static void ShowUsage(void)
" load in an X.509 DER cert to accept from peer\n");
printf(" -P <name>:<password>\n"
" add password to accept from peer\n");
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
printf(" -i <name>:<password>\n"
" add passowrd to accept via keyboard-interactive "
"from peer\n");
#endif
#ifdef WOLFSSH_CERTS
printf(" -a <file> load in a root CA certificate file\n");
#endif
Expand Down Expand Up @@ -2463,8 +2474,10 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
StrList* derPubKeyList = NULL;
#endif
StrList* passwdList = NULL;
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
StrList* keyboardList = NULL;
WS_UserAuthData_Keyboard kbAuthData;
#endif
WS_SOCKET_T listenFd = WOLFSSH_SOCKET_INVALID;
word32 defaultHighwater = EXAMPLE_HIGHWATER_MARK;
word32 threadCount = 0;
Expand Down Expand Up @@ -2495,7 +2508,9 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
int argc = serverArgs->argc;
char** argv = serverArgs->argv;
serverArgs->return_code = EXIT_SUCCESS;
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
kbAuthData.promptCount = 0;
#endif

if (argc > 0) {
const char* optlist = "?1a:d:efEp:R:Ni:j:i:I:J:K:P:k:b:x:m:c:s:";
Expand Down Expand Up @@ -2582,9 +2597,11 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
passwdList = StrListAdd(passwdList, myoptarg);
break;

#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
case 'i':
keyboardList = StrListAdd(keyboardList, myoptarg);
break;
#endif

case 'b':
userAuthWouldBlock = atoi(myoptarg);
Expand Down Expand Up @@ -2739,6 +2756,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
passwdList = NULL;
}

#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
if (keyboardList) {
LoadKeyboardList(keyboardList, &pwMapList);
StrListFree(keyboardList);
Expand Down Expand Up @@ -2767,6 +2785,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
kbAuthData.promptEcho[0] = 0;
wolfSSH_SetKeyboardAuthPrompts(ctx, keyboardCallback);
}
#endif

{
const char* bufName = NULL;
Expand Down Expand Up @@ -2973,7 +2992,9 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
#endif
wolfSSH_SetUserAuthCtx(ssh, &pwMapList);
wolfSSH_SetKeyingCompletionCbCtx(ssh, (void*)ssh);
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
wolfSSH_SetKeyboardAuthCtx(ssh, &kbAuthData);
#endif
/* Use the session object for its own highwater callback ctx */
if (defaultHighwater > 0) {
wolfSSH_SetHighwaterCtx(ssh, (void*)ssh);
Expand Down Expand Up @@ -3046,11 +3067,13 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
if (listenFd != WOLFSSH_SOCKET_INVALID) {
WCLOSESOCKET(listenFd);
}
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
if (kbAuthData.promptCount > 0) {
WFREE(kbAuthData.promptLengths, NULL, 0);
WFREE(kbAuthData.prompts, NULL, 0);
WFREE(kbAuthData.promptEcho, NULL, 0);
}
#endif
wc_FreeMutex(&doneLock);
PwMapListDelete(&pwMapList);
wolfSSH_CTX_free(ctx);
Expand Down
Loading