<commit_before>/*
 * NTLM and NTLMv2 authentication mechanism.
 *
 * Copyright (c) 2004 <NAME> <<EMAIL>>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published 
 * by the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#include "common.h"
#include "mech.h"
#include "passdb.h"
#include "str.h"
#include "buffer.h"
#include "hex-binary.h"
#include "safe-memset.h"

#include "ntlm.h"

struct ntlm_auth_request {
	struct auth_request auth_request;

	pool_t pool;

	/* requested: */
	int ntlm2_negotiated;
	int unicode_negotiated;
	const unsigned char *challenge;

	/* received: */
	struct ntlmssp_response *response;
};

static int lm_verify_credentials(struct ntlm_auth_request *request,
				 const char *credentials)
{
	const unsigned char *client_response;
	unsigned char lm_response[LM_RESPONSE_SIZE];
	unsigned char hash[LM_HASH_SIZE];
	unsigned int response_length;
	buffer_t *hash_buffer;

	response_length =
		ntlmssp_buffer_length(request->response, lm_response);
	client_response = ntlmssp_buffer_data(request->response, lm_response);

	if (response_length < LM_RESPONSE_SIZE) {
                auth_request_log_error(&request->auth_request, "ntlm",
			"passdb credentials' length is too small");
		return FALSE;
	}

	hash_buffer = buffer_create_data(request->auth_request.pool,
					 hash, sizeof(hash));
	if (hex_to_binary(credentials, hash_buffer) < 0) {
                auth_request_log_error(&request->auth_request, "ntlm",
				       "passdb credentials are not in hex");
		return FALSE;
	}

	ntlmssp_v1_response(hash, request->challenge, lm_response);
	return memcmp(lm_response, client_response, LM_RESPONSE_SIZE) == 0;
}

static void
lm_credentials_callback(enum passdb_result result,
			const char *credentials,
			struct auth_request *auth_request)
{
	struct ntlm_auth_request *request =
		(struct ntlm_auth_request *)auth_request;

	switch (result) {
	case PASSDB_RESULT_OK:
		if (lm_verify_credentials(request, credentials))
			auth_request_success(auth_request, NULL, 0);
		else
			auth_request_fail(auth_request);
		break;
	case PASSDB_RESULT_INTERNAL_FAILURE:
		auth_request_internal_failure(auth_request);
		break;
	default:
		auth_request_fail(auth_request);
		break;
	}
}

static int ntlm_verify_credentials(struct ntlm_auth_request *request,
				   const char *credentials)
{
        struct auth_request *auth_request = &request->auth_request;
	const unsigned char *client_response;
	unsigned char hash[NTLMSSP_HASH_SIZE];
	unsigned int response_length;
	buffer_t *hash_buffer;

	response_length =
		ntlmssp_buffer_length(request->response, ntlm_response);
	client_response = ntlmssp_buffer_data(request->response, ntlm_response);

	if (response_length == 0) {
		/* try LM authentication unless NTLM2 was negotiated */
		return request->ntlm2_negotiated ? -1 : 0;
	}

	hash_buffer = buffer_create_data(auth_request->pool,
					 hash, sizeof(hash));
	hex_to_binary(credentials, hash_buffer);


	if (response_length > NTLMSSP_RESPONSE_SIZE) {
		unsigned char ntlm_v2_response[NTLMSSP_V2_RESPONSE_SIZE];
		const unsigned char *blob =
			client_response + NTLMSSP_V2_RESPONSE_SIZE;

		/*
		 * Authentication target == NULL because we are acting
		 * as a standalone server, not as NT domain member.
		 */
		ntlmssp_v2_response(auth_request->user, NULL,
				    hash, request->challenge, blob,
				    response_length - NTLMSSP_V2_RESPONSE_SIZE,
				    ntlm_v2_response);

		return memcmp(ntlm_v2_response, client_response,
			      NTLMSSP_V2_RESPONSE_SIZE) == 0 ? 1 : -1;
	} else {
		unsigned char ntlm_response[NTLMSSP_RESPONSE_SIZE];
		const unsigned char *client_lm_response =
			ntlmssp_buffer_data(request->response, lm_response);

		if (request->ntlm2_negotiated)
			ntlmssp2_response(hash, request->challenge,
					  client_lm_response,
					  ntlm_response);<commit_msg>Fixes incorrect error message and adds missing hex_to_binary() return value check. Patch by <NAME>.<commit_after>/*
 * NTLM and NTLMv2 authentication mechanism.
 *
 * Copyright (c) 2004 <NAME> <<EMAIL>>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published 
 * by the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#include "common.h"
#include "mech.h"
#include "passdb.h"
#include "str.h"
#include "buffer.h"
#include "hex-binary.h"
#include "safe-memset.h"

#include "ntlm.h"

struct ntlm_auth_request {
	struct auth_request auth_request;

	pool_t pool;

	/* requested: */
	int ntlm2_negotiated;
	int unicode_negotiated;
	const unsigned char *challenge;

	/* received: */
	struct ntlmssp_response *response;
};

static int lm_verify_credentials(struct ntlm_auth_request *request,
				 const char *credentials)
{
	const unsigned char *client_response;
	unsigned char lm_response[LM_RESPONSE_SIZE];
	unsigned char hash[LM_HASH_SIZE];
	unsigned int response_length;
	buffer_t *hash_buffer;

	response_length =
		ntlmssp_buffer_length(request->response, lm_response);
	client_response = ntlmssp_buffer_data(request->response, lm_response);

	if (response_length < LM_RESPONSE_SIZE) {
                auth_request_log_error(&request->auth_request, "ntlm",
			"LM response length is too small");
		return FALSE;
	}

	hash_buffer = buffer_create_data(request->auth_request.pool,
					 hash, sizeof(hash));
	if (hex_to_binary(credentials, hash_buffer) < 0) {
                auth_request_log_error(&request->auth_request, "ntlm",
				       "passdb credentials are not in hex");
		return FALSE;
	}

	ntlmssp_v1_response(hash, request->challenge, lm_response);
	return memcmp(lm_response, client_response, LM_RESPONSE_SIZE) == 0;
}

static void
lm_credentials_callback(enum passdb_result result,
			const char *credentials,
			struct auth_request *auth_request)
{
	struct ntlm_auth_request *request =
		(struct ntlm_auth_request *)auth_request;

	switch (result) {
	case PASSDB_RESULT_OK:
		if (lm_verify_credentials(request, credentials))
			auth_request_success(auth_request, NULL, 0);
		else
			auth_request_fail(auth_request);
		break;
	case PASSDB_RESULT_INTERNAL_FAILURE:
		auth_request_internal_failure(auth_request);
		break;
	default:
		auth_request_fail(auth_request);
		break;
	}
}

static int ntlm_verify_credentials(struct ntlm_auth_request *request,
				   const char *credentials)
{
        struct auth_request *auth_request = &request->auth_request;
	const unsigned char *client_response;
	unsigned char hash[NTLMSSP_HASH_SIZE];
	unsigned int response_length;
	buffer_t *hash_buffer;

	response_length =
		ntlmssp_buffer_length(request->response, ntlm_response);
	client_response = ntlmssp_buffer_data(request->response, ntlm_response);

	if (response_length == 0) {
		/* try LM authentication unless NTLM2 was negotiated */
		return request->ntlm2_negotiated ? -1 : 0;
	}

	hash_buffer = buffer_create_data(auth_request->pool,
					 hash, sizeof(hash));
	if (hex_to_binary(credentials, hash_buffer) < 0) {
                auth_request_log_error(&request->auth_request, "ntlm",
				       "passdb credentials are not in hex");
		return 0;
	}

	if (response_length > NTLMSSP_RESPONSE_SIZE) {
		unsigned char ntlm_v2_response[NTLMSSP_V2_RESPONSE_SIZE];
		const unsigned char *blob =
			client_response + NTLMSSP_V2_RESPONSE_SIZE;

		/*
		 * Authentication target == NULL because we are acting
		 * as a standalone server, not as NT domain member.
		 */
		ntlmssp_v2_response(auth_request->user, NULL,
				    hash, request->challenge, blob,
				    response_length - NTLMSSP_V2_RESPONSE_SIZE,
				    ntlm_v2_response);

		return memcmp(ntlm_v2_response, client_response,
			      NTLMSSP_V2_RESPONSE_SIZE) == 0 ? 1 : -1;
	} else {
		unsigned char ntlm_response[NTLMSSP_RESPONSE_SIZE];
		const unsigned char *client_lm_response =
			ntlmssp_buffer_data(request->response, lm_response);

		if (request->ntlm2_negotiated)
			ntlmssp2_response(hash, request->challenge,
					  client_lm_response,
					  ntlm_response);
{'fraction_non_alphanumeric': 0.09119960668633235, 'fraction_numerical': 0.007374631268436578, 'mean_word_length': 4.750530035335689, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6572056', 'n_tokens_mistral': 3038, 'n_tokens_neox': 2741, 'n_words': 630}