39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch * NTLM message handling.
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch * Copyright (c) 2004 Andrey Panin <pazke@donpac.ru>
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch * This software is released under the MIT license.
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Boschconst char *ntlmssp_t_str_i(const void *message, struct ntlmssp_buffer *buffer,
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch unsigned int len = read_le16(&buffer->length);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch const char *p = ((const char *) message) + read_le32(&buffer->offset);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch while (len-- > 0) {
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Boschstatic unsigned int append_string(buffer_t *buf, const char *str,
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch buffer_append_c(buf, ucase ? i_toupper(*str) : *str);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Boschstatic void ntlmssp_append_string(buffer_t *buf, size_t buffer_offset,
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch length = append_string(buf, str, FALSE, unicode);
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch buffer_write(buf, buffer_offset, &buffer, sizeof(buffer));
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Boschstatic void ntlmssp_append_target_info(buffer_t *buf, size_t buffer_offset, ...)
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch length = append_string(buf, data, FALSE, TRUE) +
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch i_panic("Invalid NTLM target info block type "
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch buffer_write(buf, buffer_offset, &buffer, sizeof(buffer));
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Boschstatic inline uint32_t ntlmssp_flags(uint32_t client_flags)
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch if ((client_flags & NTLMSSP_NEGOTIATE_UNICODE) != 0)
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch if ((client_flags & NTLMSSP_NEGOTIATE_NTLM2) != 0)
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch if ((client_flags & NTLMSSP_REQUEST_TARGET) != 0)
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch flags |= NTLMSSP_REQUEST_TARGET | NTLMSSP_TARGET_TYPE_SERVER;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Boschntlmssp_create_challenge(pool_t pool, const struct ntlmssp_request *request,
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch uint32_t flags = ntlmssp_flags(read_le32(&request->flags));
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch bool unicode = (flags & NTLMSSP_NEGOTIATE_UNICODE) != 0;
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch buf = buffer_create_dynamic(pool, sizeof(struct ntlmssp_challenge));
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch random_fill(c.challenge, sizeof(c.challenge));
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch if ((flags & NTLMSSP_TARGET_TYPE_SERVER) != 0)
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch offsetof(struct ntlmssp_challenge, target_name),
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch ntlmssp_append_target_info(buf, offsetof(struct ntlmssp_challenge,
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Boschstatic bool ntlmssp_check_buffer(const struct ntlmssp_buffer *buffer,
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch /* Empty buffer is ok */
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Boschbool ntlmssp_check_request(const struct ntlmssp_request *request,
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch if (data_size < sizeof(struct ntlmssp_request)) {
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch if (read_le64(&request->magic) != NTLMSSP_MAGIC) {
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch if (read_le32(&request->type) != NTLMSSP_MSG_TYPE1) {
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch *error = "client doesn't advertise NTLM support";
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Boschbool ntlmssp_check_response(const struct ntlmssp_response *response,
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch if (data_size < sizeof(struct ntlmssp_response)) {
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch if (read_le64(&response->magic) != NTLMSSP_MAGIC) {
39bf54004e8ef15baa4c18c7969e87c51b8f197bStephan Bosch if (read_le32(&response->type) != NTLMSSP_MSG_TYPE3) {
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) ||