Skip to content

Commit 69b2fee

Browse files
authored
Merge pull request #807 from JacobBarthelmeh/keyboardauth
remove keyboard auth callback and use generic auth callback
2 parents 93ddf8f + 8a8ee95 commit 69b2fee

File tree

9 files changed

+201
-123
lines changed

9 files changed

+201
-123
lines changed

apps/wolfsshd/auth.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,10 +1138,9 @@ static int RequestAuthentication(WS_UserAuthData* authData,
11381138
}
11391139

11401140

1141+
#ifdef WOLFSSL_FPKI
11411142
if (ret == WOLFSSH_USERAUTH_SUCCESS &&
11421143
authData->type == WOLFSSH_USERAUTH_PUBLICKEY) {
1143-
1144-
#ifdef WOLFSSL_FPKI
11451144
/* compare user name to UPN in certificate */
11461145
if (authData->sf.publicKey.isCert) {
11471146
DecodedCert* dCert;
@@ -1204,8 +1203,11 @@ static int RequestAuthentication(WS_UserAuthData* authData,
12041203
#endif
12051204
}
12061205
}
1206+
}
12071207
#endif
12081208

1209+
if (ret == WOLFSSH_USERAUTH_SUCCESS &&
1210+
authData->type == WOLFSSH_USERAUTH_PUBLICKEY) {
12091211
/* if this is a certificate and no specific authorized keys file has
12101212
* been set then rely on CA to have verified the cert */
12111213
if (authData->sf.publicKey.isCert &&

examples/echoserver/echoserver.c

Lines changed: 98 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1299,16 +1299,25 @@ static int sftp_worker(thread_ctx_t* threadCtx)
12991299
{
13001300
WOLFSSH* ssh = threadCtx->ssh;
13011301
WS_SOCKET_T s;
1302-
int ret = WS_SUCCESS;
1302+
int ret;
13031303
int error = -1;
13041304
int selected;
13051305
unsigned char peek_buf[1];
13061306
int timeout = TEST_SFTP_TIMEOUT;
13071307

13081308
s = (WS_SOCKET_T)wolfSSH_get_fd(ssh);
1309+
ret = error = wolfSSH_get_error(ssh);
1310+
1311+
/* there is an edge case where the last SFTP handshake message sent got a
1312+
* WANT_WRITE case, keep trying to send it here. */
1313+
while (error == WS_WANT_WRITE) {
1314+
ret = wolfSSH_worker(ssh, NULL);
1315+
error = wolfSSH_get_error(ssh);
1316+
}
13091317

13101318
do {
1311-
if (ret == WS_WANT_WRITE || wolfSSH_SFTP_PendingSend(ssh)) {
1319+
if (ret == WS_WANT_WRITE || ret == WS_CHAN_RXD ||
1320+
wolfSSH_SFTP_PendingSend(ssh)) {
13121321
/* Yes, process the SFTP data. */
13131322
ret = wolfSSH_SFTP_read(ssh);
13141323
error = wolfSSH_get_error(ssh);
@@ -1327,7 +1336,7 @@ static int sftp_worker(thread_ctx_t* threadCtx)
13271336
error == WS_CHAN_RXD || error == WS_REKEYING ||
13281337
error == WS_WINDOW_FULL)
13291338
ret = error;
1330-
if (error == WS_WANT_WRITE && wolfSSH_SFTP_PendingSend(ssh)) {
1339+
if (error == WS_WANT_WRITE || wolfSSH_SFTP_PendingSend(ssh)) {
13311340
continue; /* no need to spend time attempting to pull data
13321341
* if there is still pending sends */
13331342
}
@@ -1362,6 +1371,19 @@ static int sftp_worker(thread_ctx_t* threadCtx)
13621371
break;
13631372
}
13641373
if (ret != WS_SUCCESS && ret != WS_CHAN_RXD) {
1374+
#ifdef WOLFSSH_TEST_BLOCK
1375+
if (error == WS_WANT_READ) {
1376+
while (error == WS_WANT_READ) {
1377+
/* The socket had data but our test nonblocking code
1378+
* returned want read. Loop over wolfSSH_worker here
1379+
* until we get the data off the socket that select
1380+
* indicated was available. */
1381+
ret = wolfSSH_worker(ssh, NULL);
1382+
error = wolfSSH_get_error(ssh);
1383+
}
1384+
continue;
1385+
}
1386+
#endif
13651387
if (ret == WS_WANT_WRITE) {
13661388
/* recall wolfSSH_worker here because is likely our custom
13671389
* highwater callback that returned up a WS_WANT_WRITE */
@@ -1433,20 +1455,45 @@ static int NonBlockSSH_accept(WOLFSSH* ssh)
14331455
printf("... server would read block\n");
14341456
else if (error == WS_WANT_WRITE)
14351457
printf("... server would write block\n");
1458+
else if (error == WS_AUTH_PENDING)
1459+
printf("... server auth pending\n");
14361460

14371461
select_ret = tcp_select(sockfd, 1);
1438-
if (select_ret == WS_SELECT_RECV_READY ||
1439-
select_ret == WS_SELECT_ERROR_READY ||
1440-
error == WS_WANT_WRITE ||
1441-
error == WS_AUTH_PENDING)
1442-
{
1462+
if (select_ret == WS_SELECT_RECV_READY) {
14431463
ret = wolfSSH_accept(ssh);
14441464
error = wolfSSH_get_error(ssh);
1465+
1466+
#ifdef WOLFSSH_TEST_BLOCK
1467+
if (error == WS_WANT_READ) {
1468+
/* The socket had data but our test nonblocking code
1469+
* returned want read. Loop over wolfSSH_accept here until
1470+
* we get the data off the socket that select indicated was
1471+
* available. */
1472+
while (error == WS_WANT_READ) {
1473+
ret = wolfSSH_accept(ssh);
1474+
error = wolfSSH_get_error(ssh);
1475+
}
1476+
}
1477+
#endif
1478+
}
1479+
else if (select_ret == WS_SELECT_TIMEOUT) {
1480+
if (error == WS_WANT_WRITE || error == WS_AUTH_PENDING
1481+
#ifdef WOLFSSH_TEST_BLOCK
1482+
|| error == WS_WANT_READ
1483+
#endif
1484+
) {
1485+
/* For write or auth pending, we need to try again */
1486+
ret = wolfSSH_accept(ssh);
1487+
error = wolfSSH_get_error(ssh);
1488+
}
1489+
else {
1490+
error = WS_WANT_READ;
1491+
}
1492+
}
1493+
else {
1494+
ret = WS_FATAL_ERROR;
1495+
break;
14451496
}
1446-
else if (select_ret == WS_SELECT_TIMEOUT)
1447-
error = WS_WANT_READ;
1448-
else
1449-
error = WS_FATAL_ERROR;
14501497
}
14511498

14521499
return ret;
@@ -1709,14 +1756,17 @@ static void StrListFree(StrList* list)
17091756
}
17101757

17111758

1712-
/* Map user names to passwords */
1759+
/* Map user names to passwords and keyboard auth prompts */
17131760
/* Use arrays for username and p. The password or public key can
17141761
* be hashed and the hash stored here. Then I won't need the type. */
17151762
typedef struct PwMap {
17161763
byte type;
17171764
byte username[32];
17181765
word32 usernameSz;
17191766
byte p[WC_SHA256_DIGEST_SIZE];
1767+
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
1768+
WS_UserAuthData_Keyboard* keyboard;
1769+
#endif
17201770
struct PwMap* next;
17211771
} PwMap;
17221772

@@ -1752,6 +1802,24 @@ static PwMap* PwMapNew(PwMapList* list, byte type, const byte* username,
17521802
}
17531803

17541804

1805+
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
1806+
/* Create new node for list of auths, adding keyboard auth prompts */
1807+
static PwMap* PwMapKeyboardNew(PwMapList* list, byte type, const byte* username,
1808+
word32 usernameSz, const byte* p, word32 pSz,
1809+
WS_UserAuthData_Keyboard* keyboard)
1810+
{
1811+
PwMap* map;
1812+
1813+
map = PwMapNew(list, type, username, usernameSz, p, pSz);
1814+
if (map) {
1815+
map->keyboard = keyboard;
1816+
}
1817+
1818+
return map;
1819+
}
1820+
#endif
1821+
1822+
17551823
static void PwMapListDelete(PwMapList* list)
17561824
{
17571825
if (list != NULL) {
@@ -2013,7 +2081,8 @@ static int LoadPasswdList(StrList* strList, PwMapList* mapList)
20132081
return count;
20142082
}
20152083
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
2016-
static int LoadKeyboardList(StrList* strList, PwMapList* mapList)
2084+
static int LoadKeyboardList(StrList* strList, PwMapList* mapList,
2085+
WS_UserAuthData_Keyboard* kbAuthData)
20172086
{
20182087
char names[256];
20192088
char* passwd;
@@ -2026,9 +2095,10 @@ static int LoadKeyboardList(StrList* strList, PwMapList* mapList)
20262095
*passwd = 0;
20272096
passwd++;
20282097

2029-
PwMapNew(mapList, WOLFSSH_USERAUTH_KEYBOARD,
2098+
PwMapKeyboardNew(mapList, WOLFSSH_USERAUTH_KEYBOARD,
20302099
(byte*)names, (word32)WSTRLEN(names),
2031-
(byte*)passwd, (word32)WSTRLEN(passwd));
2100+
(byte*)passwd, (word32)WSTRLEN(passwd),
2101+
kbAuthData);
20322102
}
20332103
else {
20342104
fprintf(stderr, "Ignoring password: %s\n", names);
@@ -2192,6 +2262,7 @@ static int wsUserAuth(byte authType,
21922262
#endif
21932263
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
21942264
authType != WOLFSSH_USERAUTH_KEYBOARD &&
2265+
authType != WOLFSSH_USERAUTH_KEYBOARD_SETUP &&
21952266
#endif
21962267
authType != WOLFSSH_USERAUTH_PUBLICKEY) {
21972268

@@ -2315,6 +2386,14 @@ static int wsUserAuth(byte authType,
23152386
}
23162387
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
23172388
else if (authData->type == WOLFSSH_USERAUTH_KEYBOARD) {
2389+
if (authType == WOLFSSH_USERAUTH_KEYBOARD_SETUP) {
2390+
/* setup the keyboard auth prompts */
2391+
WMEMCPY(&authData->sf.keyboard, map->keyboard,
2392+
sizeof(WS_UserAuthData_Keyboard));
2393+
return WS_SUCCESS;
2394+
}
2395+
2396+
/* do keyboard auth prompts */
23182397
if (WMEMCMP(map->p, authHash, WC_SHA256_DIGEST_SIZE) == 0) {
23192398
return WOLFSSH_USERAUTH_SUCCESS;
23202399
}
@@ -2338,15 +2417,6 @@ static int wsUserAuth(byte authType,
23382417
return WOLFSSH_USERAUTH_INVALID_USER;
23392418
}
23402419

2341-
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
2342-
static int keyboardCallback(WS_UserAuthData_Keyboard *kbAuth, void *ctx)
2343-
{
2344-
WS_UserAuthData_Keyboard *kbAuthData = (WS_UserAuthData_Keyboard*) ctx;
2345-
WMEMCPY(kbAuth, kbAuthData, sizeof(WS_UserAuthData_Keyboard));
2346-
2347-
return WS_SUCCESS;
2348-
}
2349-
#endif
23502420

23512421
#ifdef WOLFSSH_SFTP
23522422
/*
@@ -2800,9 +2870,6 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
28002870

28012871
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
28022872
if (keyboardList) {
2803-
LoadKeyboardList(keyboardList, &pwMapList);
2804-
StrListFree(keyboardList);
2805-
keyboardList = NULL;
28062873
kbAuthData.promptCount = 1;
28072874
kbAuthData.promptName = NULL;
28082875
kbAuthData.promptNameSz = 0;
@@ -2825,7 +2892,9 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
28252892
ES_ERROR("Error allocating promptEcho");
28262893
}
28272894
kbAuthData.promptEcho[0] = 0;
2828-
wolfSSH_SetKeyboardAuthPrompts(ctx, keyboardCallback);
2895+
LoadKeyboardList(keyboardList, &pwMapList, &kbAuthData);
2896+
StrListFree(keyboardList);
2897+
keyboardList = NULL;
28292898
}
28302899
#endif
28312900

@@ -3035,9 +3104,6 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
30353104
#endif
30363105
wolfSSH_SetUserAuthCtx(ssh, &pwMapList);
30373106
wolfSSH_SetKeyingCompletionCbCtx(ssh, (void*)ssh);
3038-
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
3039-
wolfSSH_SetKeyboardAuthCtx(ssh, &kbAuthData);
3040-
#endif
30413107

30423108
/* Use the session object for its own highwater callback ctx */
30433109
if (defaultHighwater > 0) {

examples/sftpclient/sftpclient.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,8 @@ static int NonBlockSSH_connect(void)
205205
sockfd = (SOCKET_T)wolfSSH_get_fd(ssh);
206206

207207
while (ret != WS_SUCCESS &&
208-
(error == WS_WANT_READ || error == WS_WANT_WRITE))
208+
(error == WS_WANT_READ || error == WS_WANT_WRITE ||
209+
error == WS_REKEYING || error == WS_AUTH_PENDING))
209210
{
210211
if (error == WS_WANT_READ)
211212
printf("... client would read block\n");
@@ -219,6 +220,19 @@ static int NonBlockSSH_connect(void)
219220
{
220221
ret = wolfSSH_SFTP_connect(ssh);
221222
error = wolfSSH_get_error(ssh);
223+
224+
#ifdef WOLFSSH_TEST_BLOCK
225+
if (select_ret == WS_SELECT_RECV_READY && error == WS_WANT_READ) {
226+
/* The socket has data to be read but the non blocking test
227+
* code returned want read. Loop over wolfSSH_SFTP_connect here
228+
* until we get the data off the socket that select indicated
229+
* was available. */
230+
while (error == WS_WANT_READ) {
231+
ret = wolfSSH_SFTP_connect(ssh);
232+
error = wolfSSH_get_error(ssh);
233+
}
234+
}
235+
#endif
222236
}
223237
else if (select_ret == WS_SELECT_TIMEOUT)
224238
error = WS_WANT_READ;
@@ -1150,7 +1164,8 @@ static int doAutopilot(int cmd, char* local, char* remote)
11501164
}
11511165
err = wolfSSH_get_error(ssh);
11521166
} while ((err == WS_WANT_READ || err == WS_WANT_WRITE ||
1153-
err == WS_CHAN_RXD) && ret == WS_FATAL_ERROR);
1167+
err == WS_CHAN_RXD || err == WS_REKEYING) &&
1168+
ret == WS_FATAL_ERROR);
11541169

11551170
if (ret != WS_SUCCESS) {
11561171
if (cmd == AUTOPILOT_PUT) {

0 commit comments

Comments
 (0)