bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/*
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch * NTLM message handling.
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch *
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch * Copyright (c) 2004 Andrey Panin <pazke@donpac.ru>
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch *
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch * This software is released under the MIT license.
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch */
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch#include "lib.h"
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch#include "str.h"
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch#include "buffer.h"
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch#include "hostpid.h"
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch#include "randgen.h"
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch#include "ntlm.h"
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch#include "ntlm-message.h"
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch#include <stdarg.h>
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch#include <ctype.h>
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Boschconst char *ntlmssp_t_str_i(const void *message, struct ntlmssp_buffer *buffer,
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch bool unicode)
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch{
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch unsigned int len = read_le16(&buffer->length);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch const char *p = ((const char *) message) + read_le32(&buffer->offset);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch string_t *str;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch if (unicode)
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch len /= sizeof(ucs2le_t);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch str = t_str_new(len);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch while (len-- > 0) {
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch str_append_c(str, *p & 0x7f);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch p += unicode ? sizeof(ucs2le_t) : 1;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch }
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch return str_c(str);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch}
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Boschstatic unsigned int append_string(buffer_t *buf, const char *str,
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch bool ucase, bool unicode)
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch{
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch unsigned int length = 0;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch for ( ; *str != '\0'; str++) {
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch buffer_append_c(buf, ucase ? i_toupper(*str) : *str);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch if (unicode) {
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch buffer_append_c(buf, 0);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch length++;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch }
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch length++;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch }
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch return length;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch}
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Boschstatic void ntlmssp_append_string(buffer_t *buf, size_t buffer_offset,
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch const char *str, bool unicode)
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch{
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch struct ntlmssp_buffer buffer;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch unsigned int length;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch write_le32(&buffer.offset, buf->used);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch length = append_string(buf, str, FALSE, unicode);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch write_le16(&buffer.length, length);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch write_le16(&buffer.space, length);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch buffer_write(buf, buffer_offset, &buffer, sizeof(buffer));
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch}
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Boschstatic void ntlmssp_append_target_info(buffer_t *buf, size_t buffer_offset, ...)
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch{
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch struct ntlmssp_v2_target_info info;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch struct ntlmssp_buffer buffer;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch va_list args;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch unsigned int length, total_length = 0;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch int type;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch write_le32(&buffer.offset, buf->used);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch va_start(args, buffer_offset);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch do {
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch const char *data;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch type = va_arg(args, int);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch i_zero(&info);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch write_le16(&info.type, type);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch switch (type) {
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch case NTPLMSSP_V2_TARGET_END:
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch buffer_append(buf, &info, sizeof(info));
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch length = sizeof(info);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch break;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch case NTPLMSSP_V2_TARGET_SERVER:
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch case NTPLMSSP_V2_TARGET_DOMAIN:
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch case NTPLMSSP_V2_TARGET_FQDN:
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch case NTPLMSSP_V2_TARGET_DNS:
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch data = va_arg(args, const char *);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch write_le16(&info.length,
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch strlen(data) * sizeof(ucs2le_t));
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch buffer_append(buf, &info, sizeof(info));
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch length = append_string(buf, data, FALSE, TRUE) +
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch sizeof(info);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch break;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch default:
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch i_panic("Invalid NTLM target info block type "
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch "%u", type);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch }
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch total_length += length;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch } while (type != NTPLMSSP_V2_TARGET_END);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch va_end(args);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch write_le16(&buffer.length, total_length);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch write_le16(&buffer.space, total_length);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch buffer_write(buf, buffer_offset, &buffer, sizeof(buffer));
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch}
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Boschstatic inline uint32_t ntlmssp_flags(uint32_t client_flags)
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch{
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch uint32_t flags = NTLMSSP_NEGOTIATE_NTLM |
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch NTLMSSP_NEGOTIATE_TARGET_INFO;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch if ((client_flags & NTLMSSP_NEGOTIATE_UNICODE) != 0)
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch flags |= NTLMSSP_NEGOTIATE_UNICODE;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch else
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch flags |= NTLMSSP_NEGOTIATE_OEM;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch if ((client_flags & NTLMSSP_NEGOTIATE_NTLM2) != 0)
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch flags |= NTLMSSP_NEGOTIATE_NTLM2;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch if ((client_flags & NTLMSSP_REQUEST_TARGET) != 0)
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch flags |= NTLMSSP_REQUEST_TARGET | NTLMSSP_TARGET_TYPE_SERVER;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch return flags;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch}
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Boschconst struct ntlmssp_challenge *
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Boschntlmssp_create_challenge(pool_t pool, const struct ntlmssp_request *request,
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch size_t *size)
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch{
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch buffer_t *buf;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch uint32_t flags = ntlmssp_flags(read_le32(&request->flags));
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch bool unicode = (flags & NTLMSSP_NEGOTIATE_UNICODE) != 0;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch struct ntlmssp_challenge c;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch buf = buffer_create_dynamic(pool, sizeof(struct ntlmssp_challenge));
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch i_zero(&c);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch write_le64(&c.magic, NTLMSSP_MAGIC);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch write_le32(&c.type, NTLMSSP_MSG_TYPE2);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch write_le32(&c.flags, flags);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch random_fill(c.challenge, sizeof(c.challenge));
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch buffer_write(buf, 0, &c, sizeof(c));
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch if ((flags & NTLMSSP_TARGET_TYPE_SERVER) != 0)
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch ntlmssp_append_string(buf,
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch offsetof(struct ntlmssp_challenge, target_name),
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch my_hostname, unicode);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch ntlmssp_append_target_info(buf, offsetof(struct ntlmssp_challenge,
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch target_info),
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch NTPLMSSP_V2_TARGET_FQDN, my_hostname,
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch NTPLMSSP_V2_TARGET_END);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch *size = buf->used;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch return buffer_free_without_data(&buf);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch}
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Boschstatic bool ntlmssp_check_buffer(const struct ntlmssp_buffer *buffer,
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch size_t data_size, const char **error)
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch{
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch uint32_t offset = read_le32(&buffer->offset);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch uint16_t length = read_le16(&buffer->length);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch uint16_t space = read_le16(&buffer->space);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch /* Empty buffer is ok */
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch if (length == 0 && space == 0)
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch return TRUE;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch if (offset >= data_size) {
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch *error = "buffer offset out of bounds";
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch return FALSE;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch }
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch if (offset + space > data_size) {
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch *error = "buffer end out of bounds";
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch return FALSE;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch }
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch return TRUE;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch}
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Boschbool ntlmssp_check_request(const struct ntlmssp_request *request,
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch size_t data_size, const char **error)
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch{
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch uint32_t flags;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch if (data_size < sizeof(struct ntlmssp_request)) {
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch *error = "request too short";
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch return FALSE;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch }
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch if (read_le64(&request->magic) != NTLMSSP_MAGIC) {
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch *error = "signature mismatch";
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch return FALSE;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch }
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch if (read_le32(&request->type) != NTLMSSP_MSG_TYPE1) {
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch *error = "message type mismatch";
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch return FALSE;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch }
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch flags = read_le32(&request->flags);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch if ((flags & NTLMSSP_NEGOTIATE_NTLM) == 0) {
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch *error = "client doesn't advertise NTLM support";
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch return FALSE;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch }
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch return TRUE;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch}
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Boschbool ntlmssp_check_response(const struct ntlmssp_response *response,
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch size_t data_size, const char **error)
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch{
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch if (data_size < sizeof(struct ntlmssp_response)) {
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch *error = "response too short";
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch return FALSE;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch }
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch if (read_le64(&response->magic) != NTLMSSP_MAGIC) {
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch *error = "signature mismatch";
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch return FALSE;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch }
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch if (read_le32(&response->type) != NTLMSSP_MSG_TYPE3) {
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch *error = "message type mismatch";
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch return FALSE;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch }
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch if (!ntlmssp_check_buffer(&response->lm_response, data_size, error) ||
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch !ntlmssp_check_buffer(&response->ntlm_response, data_size, error) ||
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch !ntlmssp_check_buffer(&response->domain, data_size, error) ||
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch !ntlmssp_check_buffer(&response->user, data_size, error) ||
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch !ntlmssp_check_buffer(&response->workstation, data_size, error))
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch return FALSE;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch return TRUE;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch}
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch