diff options
-rw-r--r-- | src/ntlm.c | 12 | ||||
-rw-r--r-- | src/ntlm_common.h | 10 |
2 files changed, 21 insertions, 1 deletions
@@ -881,7 +881,8 @@ int ntlm_decode_msg_type(struct ntlm_ctx *ctx, } break; case CHALLENGE_MESSAGE: - if (buffer->length < sizeof(struct wire_chal_msg)) { + if (buffer->length < sizeof(struct wire_chal_msg) && + buffer->length != sizeof(struct wire_chal_msg_old)) { return ERR_DECODE; } break; @@ -1123,6 +1124,15 @@ int ntlm_decode_chal_msg(struct ntlm_ctx *ctx, memcpy(challenge->data, msg->server_challenge, 8); challenge->length = 8; + /* if we allowed a broken short challenge message from an old + * server we must stop here */ + if (buffer->length < sizeof(struct wire_chal_msg)) { + if (flags & NTLMSSP_NEGOTIATE_TARGET_INFO) { + ret = ERR_DECODE; + } + goto done; + } + if (flags & NTLMSSP_NEGOTIATE_TARGET_INFO) { ret = ntlm_decode_field(&msg->target_info, buffer, payload_offs, target_info); diff --git a/src/ntlm_common.h b/src/ntlm_common.h index e3fe56e..24d12fb 100644 --- a/src/ntlm_common.h +++ b/src/ntlm_common.h @@ -98,6 +98,16 @@ struct wire_chal_msg { }; #pragma pack(pop) +/* We have evidence of at least one old broken server + * that send shorter CHALLENGE msgs like this: */ +#pragma pack(push, 1) +struct wire_chal_msg_old { + struct wire_msg_hdr header; + struct wire_field_hdr target_name; + uint32_t neg_flags; + uint8_t server_challenge[8]; +}; +#pragma pack(pop) #pragma pack(push, 1) struct wire_auth_msg { |