mirror of https://github.com/wolfSSL/wolfssh.git
Merge 62eafadf01
into 0e5d1fcc1b
commit
57ee2cc0bc
|
@ -1138,10 +1138,9 @@ static int RequestAuthentication(WS_UserAuthData* authData,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_FPKI
|
||||||
if (ret == WOLFSSH_USERAUTH_SUCCESS &&
|
if (ret == WOLFSSH_USERAUTH_SUCCESS &&
|
||||||
authData->type == WOLFSSH_USERAUTH_PUBLICKEY) {
|
authData->type == WOLFSSH_USERAUTH_PUBLICKEY) {
|
||||||
|
|
||||||
#ifdef WOLFSSL_FPKI
|
|
||||||
/* compare user name to UPN in certificate */
|
/* compare user name to UPN in certificate */
|
||||||
if (authData->sf.publicKey.isCert) {
|
if (authData->sf.publicKey.isCert) {
|
||||||
DecodedCert* dCert;
|
DecodedCert* dCert;
|
||||||
|
@ -1204,8 +1203,11 @@ static int RequestAuthentication(WS_UserAuthData* authData,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (ret == WOLFSSH_USERAUTH_SUCCESS &&
|
||||||
|
authData->type == WOLFSSH_USERAUTH_PUBLICKEY) {
|
||||||
/* if this is a certificate and no specific authorized keys file has
|
/* if this is a certificate and no specific authorized keys file has
|
||||||
* been set then rely on CA to have verified the cert */
|
* been set then rely on CA to have verified the cert */
|
||||||
if (authData->sf.publicKey.isCert &&
|
if (authData->sf.publicKey.isCert &&
|
||||||
|
|
|
@ -1299,16 +1299,25 @@ static int sftp_worker(thread_ctx_t* threadCtx)
|
||||||
{
|
{
|
||||||
WOLFSSH* ssh = threadCtx->ssh;
|
WOLFSSH* ssh = threadCtx->ssh;
|
||||||
WS_SOCKET_T s;
|
WS_SOCKET_T s;
|
||||||
int ret = WS_SUCCESS;
|
int ret;
|
||||||
int error = -1;
|
int error = -1;
|
||||||
int selected;
|
int selected;
|
||||||
unsigned char peek_buf[1];
|
unsigned char peek_buf[1];
|
||||||
int timeout = TEST_SFTP_TIMEOUT;
|
int timeout = TEST_SFTP_TIMEOUT;
|
||||||
|
|
||||||
s = (WS_SOCKET_T)wolfSSH_get_fd(ssh);
|
s = (WS_SOCKET_T)wolfSSH_get_fd(ssh);
|
||||||
|
ret = error = wolfSSH_get_error(ssh);
|
||||||
|
|
||||||
|
/* there is an edge case where the last SFTP handshake message sent got a
|
||||||
|
* WANT_WRITE case, keep trying to send it here. */
|
||||||
|
while (error == WS_WANT_WRITE) {
|
||||||
|
ret = wolfSSH_worker(ssh, NULL);
|
||||||
|
error = wolfSSH_get_error(ssh);
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (ret == WS_WANT_WRITE || wolfSSH_SFTP_PendingSend(ssh)) {
|
if (ret == WS_WANT_WRITE || ret == WS_CHAN_RXD ||
|
||||||
|
wolfSSH_SFTP_PendingSend(ssh)) {
|
||||||
/* Yes, process the SFTP data. */
|
/* Yes, process the SFTP data. */
|
||||||
ret = wolfSSH_SFTP_read(ssh);
|
ret = wolfSSH_SFTP_read(ssh);
|
||||||
error = wolfSSH_get_error(ssh);
|
error = wolfSSH_get_error(ssh);
|
||||||
|
@ -1362,6 +1371,19 @@ static int sftp_worker(thread_ctx_t* threadCtx)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ret != WS_SUCCESS && ret != WS_CHAN_RXD) {
|
if (ret != WS_SUCCESS && ret != WS_CHAN_RXD) {
|
||||||
|
#ifdef WOLFSSH_TEST_BLOCK
|
||||||
|
if (error == WS_WANT_READ) {
|
||||||
|
while (error == WS_WANT_READ) {
|
||||||
|
/* The socket had data but our test nonblocking code
|
||||||
|
* returned want read. Loop over wolfSSH_worker here
|
||||||
|
* until we get the data off the socket that select
|
||||||
|
* indicated was available. */
|
||||||
|
ret = wolfSSH_worker(ssh, NULL);
|
||||||
|
error = wolfSSH_get_error(ssh);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (ret == WS_WANT_WRITE) {
|
if (ret == WS_WANT_WRITE) {
|
||||||
/* recall wolfSSH_worker here because is likely our custom
|
/* recall wolfSSH_worker here because is likely our custom
|
||||||
* highwater callback that returned up a WS_WANT_WRITE */
|
* highwater callback that returned up a WS_WANT_WRITE */
|
||||||
|
@ -1433,20 +1455,45 @@ static int NonBlockSSH_accept(WOLFSSH* ssh)
|
||||||
printf("... server would read block\n");
|
printf("... server would read block\n");
|
||||||
else if (error == WS_WANT_WRITE)
|
else if (error == WS_WANT_WRITE)
|
||||||
printf("... server would write block\n");
|
printf("... server would write block\n");
|
||||||
|
else if (error == WS_AUTH_PENDING)
|
||||||
|
printf("... server auth pending\n");
|
||||||
|
|
||||||
select_ret = tcp_select(sockfd, 1);
|
select_ret = tcp_select(sockfd, 1);
|
||||||
if (select_ret == WS_SELECT_RECV_READY ||
|
if (select_ret == WS_SELECT_RECV_READY) {
|
||||||
select_ret == WS_SELECT_ERROR_READY ||
|
ret = wolfSSH_accept(ssh);
|
||||||
error == WS_WANT_WRITE ||
|
error = wolfSSH_get_error(ssh);
|
||||||
error == WS_AUTH_PENDING)
|
|
||||||
{
|
#ifdef WOLFSSH_TEST_BLOCK
|
||||||
|
if (error == WS_WANT_READ) {
|
||||||
|
/* The socket had data but our test nonblocking code
|
||||||
|
* returned want read. Loop over wolfSSH_accept here until
|
||||||
|
* we get the data off the socket that select indicated was
|
||||||
|
* available. */
|
||||||
|
while (error == WS_WANT_READ) {
|
||||||
ret = wolfSSH_accept(ssh);
|
ret = wolfSSH_accept(ssh);
|
||||||
error = wolfSSH_get_error(ssh);
|
error = wolfSSH_get_error(ssh);
|
||||||
}
|
}
|
||||||
else if (select_ret == WS_SELECT_TIMEOUT)
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if (select_ret == WS_SELECT_TIMEOUT) {
|
||||||
|
if (error == WS_WANT_WRITE || error == WS_AUTH_PENDING
|
||||||
|
#ifdef WOLFSSH_TEST_BLOCK
|
||||||
|
|| error == WS_WANT_READ
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
/* For write or auth pending, we need to try again */
|
||||||
|
ret = wolfSSH_accept(ssh);
|
||||||
|
error = wolfSSH_get_error(ssh);
|
||||||
|
}
|
||||||
|
else {
|
||||||
error = WS_WANT_READ;
|
error = WS_WANT_READ;
|
||||||
else
|
}
|
||||||
error = WS_FATAL_ERROR;
|
}
|
||||||
|
else {
|
||||||
|
ret = WS_FATAL_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1709,7 +1756,7 @@ static void StrListFree(StrList* list)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Map user names to passwords */
|
/* Map user names to passwords and keyboard auth prompts */
|
||||||
/* Use arrays for username and p. The password or public key can
|
/* Use arrays for username and p. The password or public key can
|
||||||
* be hashed and the hash stored here. Then I won't need the type. */
|
* be hashed and the hash stored here. Then I won't need the type. */
|
||||||
typedef struct PwMap {
|
typedef struct PwMap {
|
||||||
|
@ -1717,6 +1764,9 @@ typedef struct PwMap {
|
||||||
byte username[32];
|
byte username[32];
|
||||||
word32 usernameSz;
|
word32 usernameSz;
|
||||||
byte p[WC_SHA256_DIGEST_SIZE];
|
byte p[WC_SHA256_DIGEST_SIZE];
|
||||||
|
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
|
||||||
|
WS_UserAuthData_Keyboard* keyboard;
|
||||||
|
#endif
|
||||||
struct PwMap* next;
|
struct PwMap* next;
|
||||||
} PwMap;
|
} PwMap;
|
||||||
|
|
||||||
|
@ -1752,6 +1802,24 @@ static PwMap* PwMapNew(PwMapList* list, byte type, const byte* username,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
|
||||||
|
/* Create new node for list of auths, adding keyboard auth prompts */
|
||||||
|
static PwMap* PwMapKeyboardNew(PwMapList* list, byte type, const byte* username,
|
||||||
|
word32 usernameSz, const byte* p, word32 pSz,
|
||||||
|
WS_UserAuthData_Keyboard* keyboard)
|
||||||
|
{
|
||||||
|
PwMap* map;
|
||||||
|
|
||||||
|
map = PwMapNew(list, type, username, usernameSz, p, pSz);
|
||||||
|
if (map) {
|
||||||
|
map->keyboard = keyboard;
|
||||||
|
}
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static void PwMapListDelete(PwMapList* list)
|
static void PwMapListDelete(PwMapList* list)
|
||||||
{
|
{
|
||||||
if (list != NULL) {
|
if (list != NULL) {
|
||||||
|
@ -2013,7 +2081,8 @@ static int LoadPasswdList(StrList* strList, PwMapList* mapList)
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
|
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
|
||||||
static int LoadKeyboardList(StrList* strList, PwMapList* mapList)
|
static int LoadKeyboardList(StrList* strList, PwMapList* mapList,
|
||||||
|
WS_UserAuthData_Keyboard* kbAuthData)
|
||||||
{
|
{
|
||||||
char names[256];
|
char names[256];
|
||||||
char* passwd;
|
char* passwd;
|
||||||
|
@ -2026,9 +2095,10 @@ static int LoadKeyboardList(StrList* strList, PwMapList* mapList)
|
||||||
*passwd = 0;
|
*passwd = 0;
|
||||||
passwd++;
|
passwd++;
|
||||||
|
|
||||||
PwMapNew(mapList, WOLFSSH_USERAUTH_KEYBOARD,
|
PwMapKeyboardNew(mapList, WOLFSSH_USERAUTH_KEYBOARD,
|
||||||
(byte*)names, (word32)WSTRLEN(names),
|
(byte*)names, (word32)WSTRLEN(names),
|
||||||
(byte*)passwd, (word32)WSTRLEN(passwd));
|
(byte*)passwd, (word32)WSTRLEN(passwd),
|
||||||
|
kbAuthData);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "Ignoring password: %s\n", names);
|
fprintf(stderr, "Ignoring password: %s\n", names);
|
||||||
|
@ -2192,6 +2262,7 @@ static int wsUserAuth(byte authType,
|
||||||
#endif
|
#endif
|
||||||
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
|
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
|
||||||
authType != WOLFSSH_USERAUTH_KEYBOARD &&
|
authType != WOLFSSH_USERAUTH_KEYBOARD &&
|
||||||
|
authType != WOLFSSH_USERAUTH_KEYBOARD_SETUP &&
|
||||||
#endif
|
#endif
|
||||||
authType != WOLFSSH_USERAUTH_PUBLICKEY) {
|
authType != WOLFSSH_USERAUTH_PUBLICKEY) {
|
||||||
|
|
||||||
|
@ -2315,6 +2386,14 @@ static int wsUserAuth(byte authType,
|
||||||
}
|
}
|
||||||
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
|
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
|
||||||
else if (authData->type == WOLFSSH_USERAUTH_KEYBOARD) {
|
else if (authData->type == WOLFSSH_USERAUTH_KEYBOARD) {
|
||||||
|
if (authType == WOLFSSH_USERAUTH_KEYBOARD_SETUP) {
|
||||||
|
/* setup the keyboard auth prompts */
|
||||||
|
WMEMCPY(&authData->sf.keyboard, map->keyboard,
|
||||||
|
sizeof(WS_UserAuthData_Keyboard));
|
||||||
|
return WS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do keyboard auth prompts */
|
||||||
if (WMEMCMP(map->p, authHash, WC_SHA256_DIGEST_SIZE) == 0) {
|
if (WMEMCMP(map->p, authHash, WC_SHA256_DIGEST_SIZE) == 0) {
|
||||||
return WOLFSSH_USERAUTH_SUCCESS;
|
return WOLFSSH_USERAUTH_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -2338,15 +2417,6 @@ static int wsUserAuth(byte authType,
|
||||||
return WOLFSSH_USERAUTH_INVALID_USER;
|
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
|
#ifdef WOLFSSH_SFTP
|
||||||
/*
|
/*
|
||||||
|
@ -2800,9 +2870,6 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
|
||||||
|
|
||||||
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
|
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
|
||||||
if (keyboardList) {
|
if (keyboardList) {
|
||||||
LoadKeyboardList(keyboardList, &pwMapList);
|
|
||||||
StrListFree(keyboardList);
|
|
||||||
keyboardList = NULL;
|
|
||||||
kbAuthData.promptCount = 1;
|
kbAuthData.promptCount = 1;
|
||||||
kbAuthData.promptName = NULL;
|
kbAuthData.promptName = NULL;
|
||||||
kbAuthData.promptNameSz = 0;
|
kbAuthData.promptNameSz = 0;
|
||||||
|
@ -2825,7 +2892,9 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
|
||||||
ES_ERROR("Error allocating promptEcho");
|
ES_ERROR("Error allocating promptEcho");
|
||||||
}
|
}
|
||||||
kbAuthData.promptEcho[0] = 0;
|
kbAuthData.promptEcho[0] = 0;
|
||||||
wolfSSH_SetKeyboardAuthPrompts(ctx, keyboardCallback);
|
LoadKeyboardList(keyboardList, &pwMapList, &kbAuthData);
|
||||||
|
StrListFree(keyboardList);
|
||||||
|
keyboardList = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -3035,9 +3104,6 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
|
||||||
#endif
|
#endif
|
||||||
wolfSSH_SetUserAuthCtx(ssh, &pwMapList);
|
wolfSSH_SetUserAuthCtx(ssh, &pwMapList);
|
||||||
wolfSSH_SetKeyingCompletionCbCtx(ssh, (void*)ssh);
|
wolfSSH_SetKeyingCompletionCbCtx(ssh, (void*)ssh);
|
||||||
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
|
|
||||||
wolfSSH_SetKeyboardAuthCtx(ssh, &kbAuthData);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Use the session object for its own highwater callback ctx */
|
/* Use the session object for its own highwater callback ctx */
|
||||||
if (defaultHighwater > 0) {
|
if (defaultHighwater > 0) {
|
||||||
|
|
|
@ -205,7 +205,8 @@ static int NonBlockSSH_connect(void)
|
||||||
sockfd = (SOCKET_T)wolfSSH_get_fd(ssh);
|
sockfd = (SOCKET_T)wolfSSH_get_fd(ssh);
|
||||||
|
|
||||||
while (ret != WS_SUCCESS &&
|
while (ret != WS_SUCCESS &&
|
||||||
(error == WS_WANT_READ || error == WS_WANT_WRITE))
|
(error == WS_WANT_READ || error == WS_WANT_WRITE ||
|
||||||
|
error == WS_REKEYING || error == WS_AUTH_PENDING))
|
||||||
{
|
{
|
||||||
if (error == WS_WANT_READ)
|
if (error == WS_WANT_READ)
|
||||||
printf("... client would read block\n");
|
printf("... client would read block\n");
|
||||||
|
@ -219,6 +220,19 @@ static int NonBlockSSH_connect(void)
|
||||||
{
|
{
|
||||||
ret = wolfSSH_SFTP_connect(ssh);
|
ret = wolfSSH_SFTP_connect(ssh);
|
||||||
error = wolfSSH_get_error(ssh);
|
error = wolfSSH_get_error(ssh);
|
||||||
|
|
||||||
|
#ifdef WOLFSSH_TEST_BLOCK
|
||||||
|
if (select_ret == WS_SELECT_RECV_READY && error == WS_WANT_READ) {
|
||||||
|
/* The socket has data to be read but the non blocking test
|
||||||
|
* code returned want read. Loop over wolfSSH_SFTP_connect here
|
||||||
|
* until we get the data off the socket that select indicated
|
||||||
|
* was available. */
|
||||||
|
while (error == WS_WANT_READ) {
|
||||||
|
ret = wolfSSH_SFTP_connect(ssh);
|
||||||
|
error = wolfSSH_get_error(ssh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else if (select_ret == WS_SELECT_TIMEOUT)
|
else if (select_ret == WS_SELECT_TIMEOUT)
|
||||||
error = WS_WANT_READ;
|
error = WS_WANT_READ;
|
||||||
|
@ -1146,7 +1160,8 @@ static int doAutopilot(int cmd, char* local, char* remote)
|
||||||
}
|
}
|
||||||
err = wolfSSH_get_error(ssh);
|
err = wolfSSH_get_error(ssh);
|
||||||
} while ((err == WS_WANT_READ || err == WS_WANT_WRITE ||
|
} while ((err == WS_WANT_READ || err == WS_WANT_WRITE ||
|
||||||
err == WS_CHAN_RXD) && ret == WS_FATAL_ERROR);
|
err == WS_CHAN_RXD || err == WS_REKEYING) &&
|
||||||
|
ret == WS_FATAL_ERROR);
|
||||||
|
|
||||||
if (ret != WS_SUCCESS) {
|
if (ret != WS_SUCCESS) {
|
||||||
if (cmd == AUTOPILOT_PUT) {
|
if (cmd == AUTOPILOT_PUT) {
|
||||||
|
@ -1409,6 +1424,7 @@ THREAD_RETURN WOLFSSH_THREAD sftpclient_test(void* args)
|
||||||
ret = wolfSSH_get_error(ssh);
|
ret = wolfSSH_get_error(ssh);
|
||||||
} while (ret == WS_WANT_READ || ret == WS_WANT_WRITE);
|
} while (ret == WS_WANT_READ || ret == WS_WANT_WRITE);
|
||||||
if (n == NULL) {
|
if (n == NULL) {
|
||||||
|
printf("Error [%d] when getting real path\n", ret);
|
||||||
err_sys("Unable to get real path for working directory");
|
err_sys("Unable to get real path for working directory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -877,9 +877,6 @@ WOLFSSH_CTX* CtxInit(WOLFSSH_CTX* ctx, byte side, void* heap)
|
||||||
ctx->algoListCipher = cannedEncAlgoNames;
|
ctx->algoListCipher = cannedEncAlgoNames;
|
||||||
ctx->algoListMac = cannedMacAlgoNames;
|
ctx->algoListMac = cannedMacAlgoNames;
|
||||||
ctx->algoListKeyAccepted = cannedKeyAlgoNames;
|
ctx->algoListKeyAccepted = cannedKeyAlgoNames;
|
||||||
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
|
|
||||||
ctx->keyboardAuthCb = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
count = (word32)(sizeof(ctx->privateKey)
|
count = (word32)(sizeof(ctx->privateKey)
|
||||||
/ sizeof(ctx->privateKey[0]));
|
/ sizeof(ctx->privateKey[0]));
|
||||||
|
@ -7881,7 +7878,10 @@ static int DoUserAuthFailure(WOLFSSH* ssh,
|
||||||
break;
|
break;
|
||||||
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
|
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
|
||||||
case ID_USERAUTH_KEYBOARD:
|
case ID_USERAUTH_KEYBOARD:
|
||||||
|
/* try a different auth method if failing */
|
||||||
|
if (ssh->kbAuthAttempts < 3) {
|
||||||
authType |= WOLFSSH_USERAUTH_KEYBOARD;
|
authType |= WOLFSSH_USERAUTH_KEYBOARD;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if !defined(WOLFSSH_NO_RSA) || !defined(WOLFSSH_NO_ECDSA)
|
#if !defined(WOLFSSH_NO_RSA) || !defined(WOLFSSH_NO_ECDSA)
|
||||||
|
@ -13369,19 +13369,27 @@ int SendUserAuthKeyboardRequest(WOLFSSH* ssh, WS_UserAuthData* authData)
|
||||||
|
|
||||||
WLOG(WS_LOG_DEBUG, "Entering SendUserAuthKeyboardRequest()");
|
WLOG(WS_LOG_DEBUG, "Entering SendUserAuthKeyboardRequest()");
|
||||||
|
|
||||||
|
|
||||||
if (ssh == NULL || authData == NULL) {
|
if (ssh == NULL || authData == NULL) {
|
||||||
ret = WS_BAD_ARGUMENT;
|
ret = WS_BAD_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ssh->ctx->keyboardAuthCb == NULL) {
|
if (ssh->ctx->userAuthCb == NULL) {
|
||||||
WLOG(WS_LOG_DEBUG, "SendUserAuthKeyboardRequest called with no Cb set");
|
WLOG(WS_LOG_DEBUG, "SendUserAuthKeyboardRequest called with no Cb set");
|
||||||
ret = WS_BAD_USAGE;
|
ret = WS_BAD_USAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == WS_SUCCESS) {
|
if (ret == WS_SUCCESS) {
|
||||||
ret = ssh->ctx->keyboardAuthCb(&authData->sf.keyboard,
|
authData->type = WOLFSSH_USERAUTH_KEYBOARD;
|
||||||
ssh->keyboardAuthCtx);
|
ret = ssh->ctx->userAuthCb(WOLFSSH_USERAUTH_KEYBOARD_SETUP, authData,
|
||||||
|
ssh->userAuthCtx);
|
||||||
|
if (ret == WOLFSSH_USERAUTH_SUCCESS) {
|
||||||
|
ret = WS_SUCCESS;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WLOG(WS_LOG_DEBUG, "Issue with keyboard auth setup, try another "
|
||||||
|
"auth type");
|
||||||
|
return SendUserAuthFailure(ssh, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (authData->sf.keyboard.promptCount > 0 &&
|
if (authData->sf.keyboard.promptCount > 0 &&
|
||||||
|
@ -13407,10 +13415,12 @@ int SendUserAuthKeyboardRequest(WOLFSSH* ssh, WS_UserAuthData* authData)
|
||||||
ret = PreparePacket(ssh, payloadSz);
|
ret = PreparePacket(ssh, payloadSz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ret == WS_SUCCESS) {
|
||||||
output = ssh->outputBuffer.buffer;
|
output = ssh->outputBuffer.buffer;
|
||||||
idx = ssh->outputBuffer.length;
|
idx = ssh->outputBuffer.length;
|
||||||
|
|
||||||
output[idx++] = MSGID_USERAUTH_INFO_REQUEST;
|
output[idx++] = MSGID_USERAUTH_INFO_REQUEST;
|
||||||
|
}
|
||||||
|
|
||||||
if (ret == WS_SUCCESS) {
|
if (ret == WS_SUCCESS) {
|
||||||
ret = BuildUserAuthRequestKeyboard(ssh, output, &idx, authData);
|
ret = BuildUserAuthRequestKeyboard(ssh, output, &idx, authData);
|
||||||
|
@ -14946,6 +14956,7 @@ int SendUserAuthRequest(WOLFSSH* ssh, byte authType, int addSig)
|
||||||
WMEMSET(keySig_ptr, 0, sizeof(WS_KeySignature));
|
WMEMSET(keySig_ptr, 0, sizeof(WS_KeySignature));
|
||||||
keySig_ptr->keySigId = ID_NONE;
|
keySig_ptr->keySigId = ID_NONE;
|
||||||
keySig_ptr->heap = ssh->ctx->heap;
|
keySig_ptr->heap = ssh->ctx->heap;
|
||||||
|
|
||||||
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
|
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
|
||||||
/* Callback happens later for keyboard auth */
|
/* Callback happens later for keyboard auth */
|
||||||
if (authType & WOLFSSH_USERAUTH_KEYBOARD) {
|
if (authType & WOLFSSH_USERAUTH_KEYBOARD) {
|
||||||
|
@ -15074,6 +15085,7 @@ int SendUserAuthRequest(WOLFSSH* ssh, byte authType, int addSig)
|
||||||
/* submethods */
|
/* submethods */
|
||||||
c32toa(0, output + idx);
|
c32toa(0, output + idx);
|
||||||
idx += LENGTH_SZ;
|
idx += LENGTH_SZ;
|
||||||
|
ssh->kbAuthAttempts++;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (authId == ID_USERAUTH_PUBLICKEY)
|
else if (authId == ID_USERAUTH_PUBLICKEY)
|
||||||
|
@ -15117,9 +15129,7 @@ static int GetAllowedAuth(WOLFSSH* ssh, char* authStr)
|
||||||
|
|
||||||
typeAllowed |= WOLFSSH_USERAUTH_PASSWORD;
|
typeAllowed |= WOLFSSH_USERAUTH_PASSWORD;
|
||||||
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
|
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
|
||||||
if (ssh->ctx->keyboardAuthCb != NULL) {
|
|
||||||
typeAllowed |= WOLFSSH_USERAUTH_KEYBOARD;
|
typeAllowed |= WOLFSSH_USERAUTH_KEYBOARD;
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
#if !defined(WOLFSSH_NO_RSA) || !defined(WOLFSSH_NO_ECDSA)
|
#if !defined(WOLFSSH_NO_RSA) || !defined(WOLFSSH_NO_ECDSA)
|
||||||
typeAllowed |= WOLFSSH_USERAUTH_PUBLICKEY;
|
typeAllowed |= WOLFSSH_USERAUTH_PUBLICKEY;
|
||||||
|
|
21
src/ssh.c
21
src/ssh.c
|
@ -1046,6 +1046,10 @@ int wolfSSH_shutdown(WOLFSSH* ssh)
|
||||||
* response to SendChannelClose */
|
* response to SendChannelClose */
|
||||||
if (channel != NULL && ret == WS_SUCCESS) {
|
if (channel != NULL && ret == WS_SUCCESS) {
|
||||||
ret = wolfSSH_worker(ssh, NULL);
|
ret = wolfSSH_worker(ssh, NULL);
|
||||||
|
if (ret == WS_CHAN_RXD) {
|
||||||
|
/* received response */
|
||||||
|
ret = WS_SUCCESS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ssh != NULL && ssh->channelList == NULL) {
|
if (ssh != NULL && ssh->channelList == NULL) {
|
||||||
|
@ -1338,23 +1342,6 @@ int wolfSSH_SendDisconnect(WOLFSSH *ssh, word32 reason)
|
||||||
return SendDisconnect(ssh, reason);
|
return SendDisconnect(ssh, reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
|
|
||||||
void wolfSSH_SetKeyboardAuthPrompts(WOLFSSH_CTX* ctx,
|
|
||||||
WS_CallbackKeyboardAuthPrompts cb)
|
|
||||||
{
|
|
||||||
if (ctx != NULL) {
|
|
||||||
ctx->keyboardAuthCb = cb;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void wolfSSH_SetKeyboardAuthCtx(WOLFSSH* ssh, void* keyboardAuthCtx)
|
|
||||||
{
|
|
||||||
if (ssh != NULL) {
|
|
||||||
ssh->keyboardAuthCtx = keyboardAuthCtx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void wolfSSH_SetUserAuth(WOLFSSH_CTX* ctx, WS_CallbackUserAuth cb)
|
void wolfSSH_SetUserAuth(WOLFSSH_CTX* ctx, WS_CallbackUserAuth cb)
|
||||||
{
|
{
|
||||||
if (ctx != NULL) {
|
if (ctx != NULL) {
|
||||||
|
|
|
@ -515,6 +515,7 @@ static void wolfSSH_SFTP_buffer_rewind(WS_SFTP_BUFFER* buffer)
|
||||||
static int wolfSSH_SFTP_buffer_send(WOLFSSH* ssh, WS_SFTP_BUFFER* buffer)
|
static int wolfSSH_SFTP_buffer_send(WOLFSSH* ssh, WS_SFTP_BUFFER* buffer)
|
||||||
{
|
{
|
||||||
int ret = WS_SUCCESS;
|
int ret = WS_SUCCESS;
|
||||||
|
int err;
|
||||||
|
|
||||||
if (buffer == NULL) {
|
if (buffer == NULL) {
|
||||||
return WS_BAD_ARGUMENT;
|
return WS_BAD_ARGUMENT;
|
||||||
|
@ -524,6 +525,12 @@ static int wolfSSH_SFTP_buffer_send(WOLFSSH* ssh, WS_SFTP_BUFFER* buffer)
|
||||||
return WS_BUFFER_E;
|
return WS_BUFFER_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Call wolfSSH worker if rekeying or adjusting window size */
|
||||||
|
err = wolfSSH_get_error(ssh);
|
||||||
|
if (err == WS_WINDOW_FULL || err == WS_REKEYING) {
|
||||||
|
(void)wolfSSH_worker(ssh, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if (buffer->idx < buffer->sz) {
|
if (buffer->idx < buffer->sz) {
|
||||||
ret = wolfSSH_stream_send(ssh, buffer->data + buffer->idx,
|
ret = wolfSSH_stream_send(ssh, buffer->data + buffer->idx,
|
||||||
buffer->sz - buffer->idx);
|
buffer->sz - buffer->idx);
|
||||||
|
@ -543,6 +550,7 @@ static int wolfSSH_SFTP_buffer_read(WOLFSSH* ssh, WS_SFTP_BUFFER* buffer,
|
||||||
int readSz)
|
int readSz)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
byte peekBuf[1];
|
||||||
|
|
||||||
if (buffer == NULL || ssh == NULL) {
|
if (buffer == NULL || ssh == NULL) {
|
||||||
return WS_FATAL_ERROR;
|
return WS_FATAL_ERROR;
|
||||||
|
@ -563,8 +571,18 @@ static int wolfSSH_SFTP_buffer_read(WOLFSSH* ssh, WS_SFTP_BUFFER* buffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
if (!wolfSSH_stream_peek(ssh, peekBuf, 1)) {
|
||||||
|
/* poll more data off the wire */
|
||||||
|
ret = wolfSSH_worker(ssh, NULL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = WS_CHAN_RXD; /* existing data found with peek */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == WS_CHAN_RXD) {
|
||||||
ret = wolfSSH_stream_read(ssh, buffer->data + buffer->idx,
|
ret = wolfSSH_stream_read(ssh, buffer->data + buffer->idx,
|
||||||
buffer->sz - buffer->idx);
|
buffer->sz - buffer->idx);
|
||||||
|
}
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return WS_FATAL_ERROR;
|
return WS_FATAL_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -1400,8 +1418,9 @@ int wolfSSH_SFTP_read(WOLFSSH* ssh)
|
||||||
ret = wolfSSH_SFTP_buffer_read(ssh, &state->buffer,
|
ret = wolfSSH_SFTP_buffer_read(ssh, &state->buffer,
|
||||||
state->buffer.sz);
|
state->buffer.sz);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (ssh->error != WS_WANT_READ && ssh->error != WS_WANT_WRITE)
|
if (!NoticeError(ssh)) {
|
||||||
wolfSSH_SFTP_ClearState(ssh, STATE_ID_RECV);
|
wolfSSH_SFTP_ClearState(ssh, STATE_ID_RECV);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5661,7 +5680,7 @@ int wolfSSH_SFTP_RecvFSetSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
|
||||||
* returns WS_SUCCESS on success
|
* returns WS_SUCCESS on success
|
||||||
*/
|
*/
|
||||||
static int SFTP_ClientRecvInit(WOLFSSH* ssh) {
|
static int SFTP_ClientRecvInit(WOLFSSH* ssh) {
|
||||||
int len;
|
int len, ret;
|
||||||
byte id;
|
byte id;
|
||||||
word32 sz = 0;
|
word32 sz = 0;
|
||||||
word32 version = 0;
|
word32 version = 0;
|
||||||
|
@ -5669,6 +5688,11 @@ static int SFTP_ClientRecvInit(WOLFSSH* ssh) {
|
||||||
|
|
||||||
switch (ssh->sftpState) {
|
switch (ssh->sftpState) {
|
||||||
case SFTP_RECV:
|
case SFTP_RECV:
|
||||||
|
ret = wolfSSH_worker(ssh,NULL);
|
||||||
|
if (ret != WS_CHAN_RXD) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if ((len = wolfSSH_stream_read(ssh, buf, sizeof(buf)))
|
if ((len = wolfSSH_stream_read(ssh, buf, sizeof(buf)))
|
||||||
!= sizeof(buf)) {
|
!= sizeof(buf)) {
|
||||||
/* @TODO partial read on small packet */
|
/* @TODO partial read on small packet */
|
||||||
|
@ -5780,7 +5804,7 @@ int wolfSSH_SFTP_connect(WOLFSSH* ssh)
|
||||||
|
|
||||||
switch (ssh->sftpState) {
|
switch (ssh->sftpState) {
|
||||||
case SFTP_BEGIN:
|
case SFTP_BEGIN:
|
||||||
if ((ssh->error = SFTP_ClientSendInit(ssh)) != WS_SUCCESS) {
|
if (SFTP_ClientSendInit(ssh) != WS_SUCCESS) {
|
||||||
return WS_FATAL_ERROR;
|
return WS_FATAL_ERROR;
|
||||||
}
|
}
|
||||||
ssh->sftpState = SFTP_RECV;
|
ssh->sftpState = SFTP_RECV;
|
||||||
|
@ -5903,14 +5927,7 @@ int SendPacketType(WOLFSSH* ssh, byte type, byte* buf, word32 bufSz)
|
||||||
* because channel could have restrictions on how much
|
* because channel could have restrictions on how much
|
||||||
* state->data can be sent at one time */
|
* state->data can be sent at one time */
|
||||||
do {
|
do {
|
||||||
int err;
|
|
||||||
ret = wolfSSH_SFTP_buffer_send(ssh, &state->buffer);
|
ret = wolfSSH_SFTP_buffer_send(ssh, &state->buffer);
|
||||||
|
|
||||||
/* check for adjust window packet */
|
|
||||||
err = wolfSSH_get_error(ssh);
|
|
||||||
if (err == WS_WINDOW_FULL || err == WS_REKEYING)
|
|
||||||
ret = wolfSSH_worker(ssh, NULL);
|
|
||||||
ssh->error = err; /* don't save potential want read here */
|
|
||||||
} while (ret > 0 &&
|
} while (ret > 0 &&
|
||||||
wolfSSH_SFTP_buffer_idx(&state->buffer) <
|
wolfSSH_SFTP_buffer_idx(&state->buffer) <
|
||||||
wolfSSH_SFTP_buffer_size(&state->buffer));
|
wolfSSH_SFTP_buffer_size(&state->buffer));
|
||||||
|
@ -6544,8 +6561,7 @@ static int wolfSSH_SFTP_GetHandle(WOLFSSH* ssh, byte* handle, word32* handleSz)
|
||||||
WLOG(WS_LOG_SFTP, "SFTP GET HANDLE STATE: GET_HEADER");
|
WLOG(WS_LOG_SFTP, "SFTP GET HANDLE STATE: GET_HEADER");
|
||||||
ret = SFTP_GetHeader(ssh, &state->reqId, &type, &state->buffer);
|
ret = SFTP_GetHeader(ssh, &state->reqId, &type, &state->buffer);
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
if (ssh->error == WS_WANT_READ ||
|
if (NoticeError(ssh)) {
|
||||||
ssh->error == WS_WANT_WRITE) {
|
|
||||||
return WS_FATAL_ERROR;
|
return WS_FATAL_ERROR;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -8066,9 +8082,8 @@ int wolfSSH_SFTP_Close(WOLFSSH* ssh, byte* handle, word32 handleSz)
|
||||||
case STATE_CLOSE_SEND:
|
case STATE_CLOSE_SEND:
|
||||||
WLOG(WS_LOG_SFTP, "SFTP CLOSE STATE: SEND");
|
WLOG(WS_LOG_SFTP, "SFTP CLOSE STATE: SEND");
|
||||||
ret = SendPacketType(ssh, WOLFSSH_FTP_CLOSE, handle, handleSz);
|
ret = SendPacketType(ssh, WOLFSSH_FTP_CLOSE, handle, handleSz);
|
||||||
if (ssh->error == WS_WANT_WRITE || ssh->error == WS_WANT_READ)
|
if (NoticeError(ssh)) {
|
||||||
{
|
return WS_FATAL_ERROR;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret != WS_SUCCESS) {
|
if (ret != WS_SUCCESS) {
|
||||||
|
@ -8081,10 +8096,9 @@ int wolfSSH_SFTP_Close(WOLFSSH* ssh, byte* handle, word32 handleSz)
|
||||||
case STATE_CLOSE_GET_HEADER:
|
case STATE_CLOSE_GET_HEADER:
|
||||||
WLOG(WS_LOG_SFTP, "SFTP CLOSE STATE: GET_HEADER");
|
WLOG(WS_LOG_SFTP, "SFTP CLOSE STATE: GET_HEADER");
|
||||||
ret = SFTP_GetHeader(ssh, &state->reqId, &type, &state->buffer);
|
ret = SFTP_GetHeader(ssh, &state->reqId, &type, &state->buffer);
|
||||||
if (ret <= 0 &&
|
if (ret <= 0 && NoticeError(ssh)) {
|
||||||
(ssh->error == WS_WANT_WRITE ||
|
return WS_FATAL_ERROR;
|
||||||
ssh->error == WS_WANT_READ))
|
}
|
||||||
return ret;
|
|
||||||
|
|
||||||
if (type != WOLFSSH_FTP_STATUS || ret <= 0) {
|
if (type != WOLFSSH_FTP_STATUS || ret <= 0) {
|
||||||
WLOG(WS_LOG_SFTP, "Unexpected packet type");
|
WLOG(WS_LOG_SFTP, "Unexpected packet type");
|
||||||
|
@ -8169,7 +8183,7 @@ WS_SFTPNAME* wolfSSH_SFTP_RealPath(WOLFSSH* ssh, char* dir)
|
||||||
case SFTP_REAL_GET_PACKET:
|
case SFTP_REAL_GET_PACKET:
|
||||||
/* read name response from Real Path packet */
|
/* read name response from Real Path packet */
|
||||||
ret = wolfSSH_SFTP_DoName(ssh);
|
ret = wolfSSH_SFTP_DoName(ssh);
|
||||||
if (ret != NULL || (ret == NULL && ssh->error != WS_WANT_READ)) {
|
if (ret != NULL || (ret == NULL && !NoticeError(ssh))) {
|
||||||
wolfSSH_SFTP_ClearState(ssh, STATE_ID_NAME);
|
wolfSSH_SFTP_ClearState(ssh, STATE_ID_NAME);
|
||||||
ssh->realState = SFTP_REAL_SEND_PACKET;
|
ssh->realState = SFTP_REAL_SEND_PACKET;
|
||||||
}
|
}
|
||||||
|
@ -9188,9 +9202,7 @@ int wolfSSH_SFTP_Put(WOLFSSH* ssh, char* from, char* to, byte resume,
|
||||||
ret = wolfSSH_SFTP_Close(ssh, state->handle,
|
ret = wolfSSH_SFTP_Close(ssh, state->handle,
|
||||||
state->handleSz);
|
state->handleSz);
|
||||||
if (ret != WS_SUCCESS) {
|
if (ret != WS_SUCCESS) {
|
||||||
if (ssh->error == WS_WANT_READ ||
|
if (NoticeError(ssh)) {
|
||||||
ssh->error == WS_WANT_WRITE ||
|
|
||||||
ssh->error == WS_REKEYING) {
|
|
||||||
return WS_FATAL_ERROR;
|
return WS_FATAL_ERROR;
|
||||||
}
|
}
|
||||||
WLOG(WS_LOG_SFTP, "Error closing handle");
|
WLOG(WS_LOG_SFTP, "Error closing handle");
|
||||||
|
|
31
tests/auth.c
31
tests/auth.c
|
@ -222,11 +222,23 @@ static int load_key(byte isEcc, byte* buf, word32 bufSz)
|
||||||
|
|
||||||
static int serverUserAuth(byte authType, WS_UserAuthData* authData, void* ctx)
|
static int serverUserAuth(byte authType, WS_UserAuthData* authData, void* ctx)
|
||||||
{
|
{
|
||||||
(void) ctx;
|
WS_UserAuthData_Keyboard* prompts = (WS_UserAuthData_Keyboard*)ctx;
|
||||||
if (authType != WOLFSSH_USERAUTH_KEYBOARD) {
|
|
||||||
|
if (ctx == NULL) {
|
||||||
return WOLFSSH_USERAUTH_FAILURE;
|
return WOLFSSH_USERAUTH_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (authType != WOLFSSH_USERAUTH_KEYBOARD &&
|
||||||
|
authType != WOLFSSH_USERAUTH_KEYBOARD_SETUP) {
|
||||||
|
return WOLFSSH_USERAUTH_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (authType == WOLFSSH_USERAUTH_KEYBOARD_SETUP) {
|
||||||
|
WMEMCPY(&authData->sf.keyboard, prompts,
|
||||||
|
sizeof(WS_UserAuthData_Keyboard));
|
||||||
|
return WS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
if (authData->sf.keyboard.responseCount != kbResponseCount) {
|
if (authData->sf.keyboard.responseCount != kbResponseCount) {
|
||||||
return WOLFSSH_USERAUTH_FAILURE;
|
return WOLFSSH_USERAUTH_FAILURE;
|
||||||
}
|
}
|
||||||
|
@ -237,8 +249,9 @@ static int serverUserAuth(byte authType, WS_UserAuthData* authData, void* ctx)
|
||||||
return WOLFSSH_USERAUTH_FAILURE;
|
return WOLFSSH_USERAUTH_FAILURE;
|
||||||
|
|
||||||
}
|
}
|
||||||
if (WSTRCMP((const char*)authData->sf.keyboard.responses[resp],
|
if (WSTRNCMP((const char*)authData->sf.keyboard.responses[resp],
|
||||||
(const char*)kbResponses[resp]) != 0) {
|
(const char*)kbResponses[resp],
|
||||||
|
kbResponseLengths[resp]) != 0) {
|
||||||
return WOLFSSH_USERAUTH_FAILURE;
|
return WOLFSSH_USERAUTH_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -251,14 +264,6 @@ static int serverUserAuth(byte authType, WS_UserAuthData* authData, void* ctx)
|
||||||
return WOLFSSH_USERAUTH_SUCCESS;
|
return WOLFSSH_USERAUTH_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int serverKeyboardCallback(WS_UserAuthData_Keyboard *kbAuth, void *ctx)
|
|
||||||
{
|
|
||||||
(void) ctx;
|
|
||||||
WMEMCPY(kbAuth, &promptData, sizeof(WS_UserAuthData_Keyboard));
|
|
||||||
|
|
||||||
return WS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void SignalTcpReady(tcp_ready* ready, word16 port)
|
static INLINE void SignalTcpReady(tcp_ready* ready, word16 port)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&ready->mutex);
|
pthread_mutex_lock(&ready->mutex);
|
||||||
|
@ -332,13 +337,13 @@ static THREAD_RETURN WOLFSSH_THREAD server_thread(void* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
wolfSSH_SetUserAuth(ctx, serverUserAuth);
|
wolfSSH_SetUserAuth(ctx, serverUserAuth);
|
||||||
wolfSSH_SetKeyboardAuthPrompts(ctx, serverKeyboardCallback);
|
|
||||||
ssh = wolfSSH_new(ctx);
|
ssh = wolfSSH_new(ctx);
|
||||||
if (ssh == NULL) {
|
if (ssh == NULL) {
|
||||||
ES_ERROR("Couldn't allocate SSH data.\n");
|
ES_ERROR("Couldn't allocate SSH data.\n");
|
||||||
}
|
}
|
||||||
keyLoadBuf = buf;
|
keyLoadBuf = buf;
|
||||||
bufSz = EXAMPLE_KEYLOAD_BUFFER_SZ;
|
bufSz = EXAMPLE_KEYLOAD_BUFFER_SZ;
|
||||||
|
wolfSSH_SetUserAuthCtx(ssh, &promptData);
|
||||||
|
|
||||||
bufSz = load_key(peerEcc, keyLoadBuf, bufSz);
|
bufSz = load_key(peerEcc, keyLoadBuf, bufSz);
|
||||||
if (bufSz == 0) {
|
if (bufSz == 0) {
|
||||||
|
|
|
@ -529,9 +529,6 @@ struct WOLFSSH_CTX {
|
||||||
WS_CallbackUserAuth userAuthCb; /* User Authentication Callback */
|
WS_CallbackUserAuth userAuthCb; /* User Authentication Callback */
|
||||||
WS_CallbackUserAuthTypes userAuthTypesCb; /* Authentication Types Allowed */
|
WS_CallbackUserAuthTypes userAuthTypesCb; /* Authentication Types Allowed */
|
||||||
WS_CallbackUserAuthResult userAuthResultCb; /* User Authentication Result */
|
WS_CallbackUserAuthResult userAuthResultCb; /* User Authentication Result */
|
||||||
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
|
|
||||||
WS_CallbackKeyboardAuthPrompts keyboardAuthCb; /* Keyboard auth prompts */
|
|
||||||
#endif
|
|
||||||
WS_CallbackHighwater highwaterCb; /* Data Highwater Mark Callback */
|
WS_CallbackHighwater highwaterCb; /* Data Highwater Mark Callback */
|
||||||
WS_CallbackGlobalReq globalReqCb; /* Global Request Callback */
|
WS_CallbackGlobalReq globalReqCb; /* Global Request Callback */
|
||||||
WS_CallbackReqSuccess reqSuccessCb; /* Global Request Success Callback */
|
WS_CallbackReqSuccess reqSuccessCb; /* Global Request Success Callback */
|
||||||
|
@ -922,6 +919,7 @@ struct WOLFSSH {
|
||||||
void* keyingCompletionCtx;
|
void* keyingCompletionCtx;
|
||||||
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
|
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
|
||||||
WS_UserAuthData_Keyboard kbAuth;
|
WS_UserAuthData_Keyboard kbAuth;
|
||||||
|
byte kbAuthAttempts;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -368,13 +368,6 @@ WOLFSSH_API void wolfSSH_SetUserAuthTypes(WOLFSSH_CTX*,
|
||||||
WOLFSSH_API void wolfSSH_SetUserAuthCtx(WOLFSSH*, void*);
|
WOLFSSH_API void wolfSSH_SetUserAuthCtx(WOLFSSH*, void*);
|
||||||
WOLFSSH_API void* wolfSSH_GetUserAuthCtx(WOLFSSH*);
|
WOLFSSH_API void* wolfSSH_GetUserAuthCtx(WOLFSSH*);
|
||||||
|
|
||||||
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
|
|
||||||
typedef int (*WS_CallbackKeyboardAuthPrompts)(WS_UserAuthData_Keyboard*, void*);
|
|
||||||
WOLFSSH_API void wolfSSH_SetKeyboardAuthPrompts(WOLFSSH_CTX*,
|
|
||||||
WS_CallbackKeyboardAuthPrompts);
|
|
||||||
WOLFSSH_API void wolfSSH_SetKeyboardAuthCtx(WOLFSSH*, void*);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef int (*WS_CallbackUserAuthResult)(byte result,
|
typedef int (*WS_CallbackUserAuthResult)(byte result,
|
||||||
WS_UserAuthData* authData, void* userAuthResultCtx);
|
WS_UserAuthData* authData, void* userAuthResultCtx);
|
||||||
WOLFSSH_API void wolfSSH_SetUserAuthResult(WOLFSSH_CTX* ctx,
|
WOLFSSH_API void wolfSSH_SetUserAuthResult(WOLFSSH_CTX* ctx,
|
||||||
|
@ -474,6 +467,7 @@ enum WS_FormatTypes {
|
||||||
#define WOLFSSH_USERAUTH_PUBLICKEY 0x02
|
#define WOLFSSH_USERAUTH_PUBLICKEY 0x02
|
||||||
#define WOLFSSH_USERAUTH_KEYBOARD 0x04
|
#define WOLFSSH_USERAUTH_KEYBOARD 0x04
|
||||||
#define WOLFSSH_USERAUTH_NONE 0x08
|
#define WOLFSSH_USERAUTH_NONE 0x08
|
||||||
|
#define WOLFSSH_USERAUTH_KEYBOARD_SETUP 0x10
|
||||||
|
|
||||||
enum WS_UserAuthResults
|
enum WS_UserAuthResults
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue