userauth_keyboard_interactive: fix buffer overflow

Partly reverse 566894494b4972ae12 which was simplifying the code far too
much and ended up overflowing a buffer within the LIBSSH2_SESSION
struct. Back to allocating the buffer properly like it used to do.

Bug: http://www.libssh2.org/mail/libssh2-devel-archive-2011-06/0032.shtml
Reported by: Alfred Gebert
This commit is contained in:
Daniel Stenberg 2011-06-29 21:30:22 +02:00
parent dadc05fdfd
commit 45ffdcfe3c
2 changed files with 15 additions and 6 deletions

View File

@ -683,7 +683,6 @@ struct _LIBSSH2_SESSION
/* State variables used in libssh2_userauth_keyboard_interactive_ex() */
libssh2_nonblocking_states userauth_kybd_state;
unsigned char userauth_buf[5];
unsigned char *userauth_kybd_data;
size_t userauth_kybd_data_len;
unsigned char *userauth_kybd_packet;

View File

@ -1563,6 +1563,11 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
"Keyboard-interactive response callback function"
" invoked");
session->userauth_kybd_packet_len =
1 /* byte SSH_MSG_USERAUTH_INFO_RESPONSE */
+ 4 /* int num-responses */
;
for(i = 0; i != session->userauth_kybd_num_prompts; ++i) {
/* string response[1] (ISO-10646 UTF-8) */
session->userauth_kybd_packet_len +=
@ -1572,10 +1577,15 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
/* A new userauth_kybd_data area is to be allocated, free the
former one. */
LIBSSH2_FREE(session, session->userauth_kybd_data);
session->userauth_kybd_data = NULL;
/* get a pointer to the storage buffer that fits 5 bytes */
s = &session->userauth_buf[0];
session->userauth_kybd_data = s =
LIBSSH2_ALLOC(session, session->userauth_kybd_packet_len);
if (!s) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for keyboard-"
"interactive response packet");
goto cleanup;
}
*s = SSH_MSG_USERAUTH_INFO_RESPONSE;
s++;
@ -1591,8 +1601,8 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
}
if (session->userauth_kybd_state == libssh2_NB_state_sent1) {
rc = _libssh2_transport_send(session, session->userauth_buf,
sizeof(session->userauth_buf),
rc = _libssh2_transport_send(session, session->userauth_kybd_data,
session->userauth_kybd_packet_len,
NULL, 0);
if (rc == LIBSSH2_ERROR_EAGAIN)
return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,