mirror of
https://github.com/libssh2/libssh2.git
synced 2025-11-23 01:22:37 +03:00
Guard against out-of-bounds reads in userauth.c
This commit is contained in:
174
src/userauth.c
174
src/userauth.c
@@ -1743,28 +1743,58 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
|
|||||||
/* server requested PAM-like conversation */
|
/* server requested PAM-like conversation */
|
||||||
s = session->userauth_kybd_data + 1;
|
s = session->userauth_kybd_data + 1;
|
||||||
|
|
||||||
/* string name (ISO-10646 UTF-8) */
|
if(session->userauth_kybd_data_len >= 5) {
|
||||||
session->userauth_kybd_auth_name_len = _libssh2_ntohu32(s);
|
/* string name (ISO-10646 UTF-8) */
|
||||||
s += 4;
|
session->userauth_kybd_auth_name_len = _libssh2_ntohu32(s);
|
||||||
if(session->userauth_kybd_auth_name_len) {
|
s += 4;
|
||||||
session->userauth_kybd_auth_name =
|
}
|
||||||
LIBSSH2_ALLOC(session,
|
else {
|
||||||
session->userauth_kybd_auth_name_len);
|
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
|
||||||
if(!session->userauth_kybd_auth_name) {
|
"userauth keyboard data buffer too small"
|
||||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
"to get length");
|
||||||
"Unable to allocate memory for "
|
goto cleanup;
|
||||||
"keyboard-interactive 'name' "
|
}
|
||||||
"request field");
|
|
||||||
|
if(session->userauth_kybd_auth_name_len) {
|
||||||
|
session->userauth_kybd_auth_name =
|
||||||
|
LIBSSH2_ALLOC(session,
|
||||||
|
session->userauth_kybd_auth_name_len);
|
||||||
|
if(!session->userauth_kybd_auth_name) {
|
||||||
|
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
|
"Unable to allocate memory for "
|
||||||
|
"keyboard-interactive 'name' "
|
||||||
|
"request field");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (s + session->userauth_list_data_len <=
|
||||||
|
session->userauth_kybd_data +
|
||||||
|
session->userauth_kybd_data_len) {
|
||||||
|
memcpy(session->userauth_kybd_auth_name, s,
|
||||||
|
session->userauth_kybd_auth_name_len);
|
||||||
|
s += session->userauth_kybd_auth_name_len;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
|
||||||
|
"userauth keyboard data buffer too small"
|
||||||
|
"for auth name");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
memcpy(session->userauth_kybd_auth_name, s,
|
}
|
||||||
session->userauth_kybd_auth_name_len);
|
|
||||||
s += session->userauth_kybd_auth_name_len;
|
if (s + 4 <= session->userauth_kybd_data +
|
||||||
|
session->userauth_kybd_data_len) {
|
||||||
|
/* string instruction (ISO-10646 UTF-8) */
|
||||||
|
session->userauth_kybd_auth_instruction_len =
|
||||||
|
_libssh2_ntohu32(s);
|
||||||
|
s += 4;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
|
||||||
|
"userauth keyboard data buffer too small"
|
||||||
|
"for auth instruction length");
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* string instruction (ISO-10646 UTF-8) */
|
|
||||||
session->userauth_kybd_auth_instruction_len = _libssh2_ntohu32(s);
|
|
||||||
s += 4;
|
|
||||||
if(session->userauth_kybd_auth_instruction_len) {
|
if(session->userauth_kybd_auth_instruction_len) {
|
||||||
session->userauth_kybd_auth_instruction =
|
session->userauth_kybd_auth_instruction =
|
||||||
LIBSSH2_ALLOC(session,
|
LIBSSH2_ALLOC(session,
|
||||||
@@ -1776,21 +1806,58 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
|
|||||||
"request field");
|
"request field");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
memcpy(session->userauth_kybd_auth_instruction, s,
|
if(s + session->userauth_kybd_auth_instruction_len <=
|
||||||
session->userauth_kybd_auth_instruction_len);
|
session->userauth_kybd_data +
|
||||||
s += session->userauth_kybd_auth_instruction_len;
|
session->userauth_kybd_data_len) {
|
||||||
|
memcpy(session->userauth_kybd_auth_instruction, s,
|
||||||
|
session->userauth_kybd_auth_instruction_len);
|
||||||
|
s += session->userauth_kybd_auth_instruction_len;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
|
||||||
|
"userauth keyboard data buffer too small"
|
||||||
|
"for auth instruction");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* string language tag (as defined in [RFC-3066]) */
|
if(s + 4 <= session->userauth_kybd_data +
|
||||||
language_tag_len = _libssh2_ntohu32(s);
|
session->userauth_kybd_data_len) {
|
||||||
s += 4;
|
/* string language tag (as defined in [RFC-3066]) */
|
||||||
|
language_tag_len = _libssh2_ntohu32(s);
|
||||||
|
s += 4;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
|
||||||
|
"userauth keyboard data buffer too small"
|
||||||
|
"for auth language tag length");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
/* ignoring this field as deprecated */
|
if(s + language_tag_len <= session->userauth_kybd_data +
|
||||||
s += language_tag_len;
|
session->userauth_kybd_data_len) {
|
||||||
|
/* ignoring this field as deprecated */
|
||||||
|
s += language_tag_len;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
|
||||||
|
"userauth keyboard data buffer too small"
|
||||||
|
"for auth language tag");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
/* int num-prompts */
|
if(s + 4 <= session->userauth_kybd_data +
|
||||||
session->userauth_kybd_num_prompts = _libssh2_ntohu32(s);
|
session->userauth_kybd_data_len) {
|
||||||
s += 4;
|
/* int num-prompts */
|
||||||
|
session->userauth_kybd_num_prompts = _libssh2_ntohu32(s);
|
||||||
|
s += 4;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
|
||||||
|
"userauth keyboard data buffer too small"
|
||||||
|
"for auth num keyboard prompts");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
if(session->userauth_kybd_num_prompts &&
|
if(session->userauth_kybd_num_prompts &&
|
||||||
session->userauth_kybd_num_prompts > 100) {
|
session->userauth_kybd_num_prompts > 100) {
|
||||||
@@ -1824,10 +1891,20 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < session->userauth_kybd_num_prompts; i++) {
|
for(i = 0; i < session->userauth_kybd_num_prompts; i++) {
|
||||||
/* string prompt[1] (ISO-10646 UTF-8) */
|
if(s + 4 <= session->userauth_kybd_data +
|
||||||
session->userauth_kybd_prompts[i].length =
|
session->userauth_kybd_data_len) {
|
||||||
_libssh2_ntohu32(s);
|
/* string prompt[1] (ISO-10646 UTF-8) */
|
||||||
s += 4;
|
session->userauth_kybd_prompts[i].length =
|
||||||
|
_libssh2_ntohu32(s);
|
||||||
|
s += 4;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
|
||||||
|
"userauth keyboard data buffer too small"
|
||||||
|
"for auth keyboard prompt length");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
session->userauth_kybd_prompts[i].text =
|
session->userauth_kybd_prompts[i].text =
|
||||||
LIBSSH2_CALLOC(session,
|
LIBSSH2_CALLOC(session,
|
||||||
session->userauth_kybd_prompts[i].length);
|
session->userauth_kybd_prompts[i].length);
|
||||||
@@ -1837,12 +1914,31 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
|
|||||||
"keyboard-interactive prompt message");
|
"keyboard-interactive prompt message");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
memcpy(session->userauth_kybd_prompts[i].text, s,
|
|
||||||
session->userauth_kybd_prompts[i].length);
|
if(s + session->userauth_kybd_prompts[i].length <=
|
||||||
s += session->userauth_kybd_prompts[i].length;
|
session->userauth_kybd_data +
|
||||||
|
session->userauth_kybd_data_len) {
|
||||||
/* boolean echo[1] */
|
memcpy(session->userauth_kybd_prompts[i].text, s,
|
||||||
session->userauth_kybd_prompts[i].echo = *s++;
|
session->userauth_kybd_prompts[i].length);
|
||||||
|
s += session->userauth_kybd_prompts[i].length;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
|
||||||
|
"userauth keyboard data buffer too small"
|
||||||
|
"for auth keyboard prompt");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if(s < session->userauth_kybd_data +
|
||||||
|
session->userauth_kybd_data_len) {
|
||||||
|
/* boolean echo[1] */
|
||||||
|
session->userauth_kybd_prompts[i].echo = *s++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
|
||||||
|
"userauth keyboard data buffer too small"
|
||||||
|
"for auth keyboard prompt echo");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user