samlogon.c

来自「samba最新软件」· C语言 代码 · 共 1,856 行 · 第 1/4 页

C
1,856
字号
			   sizeof(lm_key)) != 0) {			d_printf("LM Key does not match expectations (first 8 session key)!\n");			d_printf("lm_key:\n");			dump_data(1, lm_key, 8);			d_printf("expected:\n");			dump_data(1, session_key.data, 8);			pass = false;		}#endif	}	if (lm_good && memcmp(lm_hash, user_session_key, 8) != 0) {		uint8_t lm_key_expected[16];		memcpy(lm_key_expected, lm_hash, 8);		memset(lm_key_expected+8, '\0', 8);		if (memcmp(lm_key_expected, user_session_key, 			   16) != 0) {			d_printf("NT Session Key does not match expectations (should be first-8 LM hash)!\n");			d_printf("user_session_key:\n");			dump_data(1, user_session_key, sizeof(user_session_key));			d_printf("expected:\n");			dump_data(1, lm_key_expected, sizeof(lm_key_expected));			pass = false;		}	}        return pass;}/*  * Test the NTLM response only, but in the both the NT and LM fields. */static bool test_ntlm_in_both(struct samlogon_state *samlogon_state, char **error_string) {	bool pass = true;	bool lm_good;	NTSTATUS nt_status;	DATA_BLOB nt_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24);	DATA_BLOB session_key = data_blob_talloc(samlogon_state->mem_ctx, NULL, 16);	uint8_t lm_key[8];	uint8_t lm_hash[16];	uint8_t user_session_key[16];	uint8_t nt_hash[16];		ZERO_STRUCT(lm_key);	ZERO_STRUCT(user_session_key);	SMBNTencrypt(samlogon_state->password, samlogon_state->chall.data, 		     nt_response.data);	E_md4hash(samlogon_state->password, nt_hash);	SMBsesskeygen_ntv1(nt_hash, 			   session_key.data);	lm_good = E_deshash(samlogon_state->password, lm_hash); 	if (!lm_good) {		ZERO_STRUCT(lm_hash);	}	nt_status = check_samlogon(samlogon_state,				   BREAK_NONE,				   samlogon_state->parameter_control,				   &samlogon_state->chall,				   NULL, 				   &nt_response,				   lm_key, 				   user_session_key,				   error_string);		if (NT_STATUS_EQUAL(NT_STATUS_WRONG_PASSWORD, nt_status)) {		/* for 'old' passwords, we allow the server to be OK or wrong password */		if (samlogon_state->old_password) {			return true;		}		return false;	} else if (!NT_STATUS_EQUAL(samlogon_state->expected_error, nt_status)) {		SAFE_FREE(*error_string);		asprintf(error_string, "Expected error: %s, got %s", nt_errstr(samlogon_state->expected_error), nt_errstr(nt_status));		return false;	} else if (NT_STATUS_EQUAL(samlogon_state->expected_error, nt_status) && !NT_STATUS_IS_OK(nt_status)) {		return true;	} else if (!NT_STATUS_IS_OK(nt_status)) {		return false;	}	if (!NT_STATUS_IS_OK(nt_status)) {		return false;	}	if (memcmp(lm_hash, lm_key, 		   sizeof(lm_key)) != 0) {		d_printf("LM Key does not match expectations!\n"); 		d_printf("lm_key:\n");		dump_data(1, lm_key, 8);		d_printf("expected:\n");		dump_data(1, lm_hash, 8);		pass = false;	}	if (memcmp(session_key.data, user_session_key, 		   sizeof(user_session_key)) != 0) {		d_printf("NT Session Key does not match expectations!\n"); 		d_printf("user_session_key:\n");		dump_data(1, user_session_key, 16); 		d_printf("expected:\n");		dump_data(1, session_key.data, session_key.length);		pass = false;	}        return pass;}/*  * Test the NTLMv2 and LMv2 responses */enum ntlmv2_domain {	UPPER_DOMAIN,	NO_DOMAIN};static bool test_lmv2_ntlmv2_broken(struct samlogon_state *samlogon_state, 				    enum ntlm_break break_which, 				    enum ntlmv2_domain ntlmv2_domain, 				    char **error_string) {	bool pass = true;	NTSTATUS nt_status;	DATA_BLOB ntlmv2_response = data_blob(NULL, 0);	DATA_BLOB lmv2_response = data_blob(NULL, 0);	DATA_BLOB lmv2_session_key = data_blob(NULL, 0);	DATA_BLOB ntlmv2_session_key = data_blob(NULL, 0);	DATA_BLOB names_blob = NTLMv2_generate_names_blob(samlogon_state->mem_ctx, samlogon_state->iconv_convenience, TEST_MACHINE_NAME, lp_workgroup(global_loadparm));	uint8_t lm_session_key[8];	uint8_t user_session_key[16];	ZERO_STRUCT(lm_session_key);	ZERO_STRUCT(user_session_key);		switch (ntlmv2_domain) {	case UPPER_DOMAIN:		if (!SMBNTLMv2encrypt(samlogon_state->mem_ctx, 				      samlogon_state->account_name, samlogon_state->account_domain, 				      samlogon_state->password, &samlogon_state->chall,				      &names_blob,				      &lmv2_response, &ntlmv2_response, 				      &lmv2_session_key, &ntlmv2_session_key)) {			data_blob_free(&names_blob);			return false;		}		break;	case NO_DOMAIN:		if (!SMBNTLMv2encrypt(samlogon_state->mem_ctx, 				      samlogon_state->account_name, "",				      samlogon_state->password, &samlogon_state->chall,				      &names_blob,				      &lmv2_response, &ntlmv2_response, 				      &lmv2_session_key, &ntlmv2_session_key)) {			data_blob_free(&names_blob);			return false;		}		break;	}	data_blob_free(&names_blob);	nt_status = check_samlogon(samlogon_state,				   break_which,				   samlogon_state->parameter_control,				   &samlogon_state->chall,				   &lmv2_response,				   &ntlmv2_response,				   lm_session_key, 				   user_session_key,				   error_string);		data_blob_free(&lmv2_response);	data_blob_free(&ntlmv2_response);	if (NT_STATUS_EQUAL(NT_STATUS_WRONG_PASSWORD, nt_status)) {		/* for 'old' passwords, we allow the server to be OK or wrong password */		if (samlogon_state->old_password) {			return true;		}		return break_which == BREAK_BOTH;	} else if (NT_STATUS_EQUAL(NT_STATUS_NOT_FOUND, nt_status) && strchr_m(samlogon_state->account_name, '@')) {		return ((break_which == BREAK_NT) || (break_which == BREAK_BOTH) || (break_which == NO_NT));	} else if (!NT_STATUS_EQUAL(samlogon_state->expected_error, nt_status)) {		SAFE_FREE(*error_string);		asprintf(error_string, "Expected error: %s, got %s", nt_errstr(samlogon_state->expected_error), nt_errstr(nt_status));		return false;	} else if (NT_STATUS_EQUAL(samlogon_state->expected_error, nt_status) && !NT_STATUS_IS_OK(nt_status)) {		return true;	} else if (!NT_STATUS_IS_OK(nt_status)) {		return false;	}	switch (break_which) {	case NO_NT:		if (memcmp(lmv2_session_key.data, user_session_key,			   sizeof(user_session_key)) != 0) {			d_printf("USER (LMv2) Session Key does not match expectations!\n");			d_printf("user_session_key:\n");			dump_data(1, user_session_key, 16);			d_printf("expected:\n");			dump_data(1, lmv2_session_key.data, ntlmv2_session_key.length);			pass = false;		}		if (memcmp(lmv2_session_key.data, lm_session_key, 				   sizeof(lm_session_key)) != 0) {			d_printf("LM (LMv2) Session Key does not match expectations!\n");			d_printf("lm_session_key:\n");			dump_data(1, lm_session_key, 8);			d_printf("expected:\n");			dump_data(1, lmv2_session_key.data, 8);			pass = false;		}		break;	default:		if (memcmp(ntlmv2_session_key.data, user_session_key, 			   sizeof(user_session_key)) != 0) {			if (memcmp(lmv2_session_key.data, user_session_key,				   sizeof(user_session_key)) == 0) {				d_printf("USER (NTLMv2) Session Key expected, got LMv2 sessesion key instead:\n");				d_printf("user_session_key:\n");				dump_data(1, user_session_key, 16);				d_printf("expected:\n");				dump_data(1, ntlmv2_session_key.data, ntlmv2_session_key.length);				pass = false;							} else {				d_printf("USER (NTLMv2) Session Key does not match expectations!\n");				d_printf("user_session_key:\n");				dump_data(1, user_session_key, 16);				d_printf("expected:\n");				dump_data(1, ntlmv2_session_key.data, ntlmv2_session_key.length);				pass = false;			}		}		if (memcmp(ntlmv2_session_key.data, lm_session_key, 			   sizeof(lm_session_key)) != 0) {			if (memcmp(lmv2_session_key.data, lm_session_key,				   sizeof(lm_session_key)) == 0) {				d_printf("LM (NTLMv2) Session Key expected, got LMv2 sessesion key instead:\n");				d_printf("user_session_key:\n");				dump_data(1, lm_session_key, 8);				d_printf("expected:\n");				dump_data(1, ntlmv2_session_key.data, 8);				pass = false;			} else {				d_printf("LM (NTLMv2) Session Key does not match expectations!\n");				d_printf("lm_session_key:\n");				dump_data(1, lm_session_key, 8);				d_printf("expected:\n");				dump_data(1, ntlmv2_session_key.data, 8);				pass = false;			}		}	}        return pass;}/*  * Test the NTLM and LMv2 responses */static bool test_lmv2_ntlm_broken(struct samlogon_state *samlogon_state, 				  enum ntlm_break break_which, 				  enum ntlmv2_domain ntlmv2_domain, 				  char **error_string) {	bool pass = true;	NTSTATUS nt_status;	DATA_BLOB ntlmv2_response = data_blob(NULL, 0);	DATA_BLOB lmv2_response = data_blob(NULL, 0);	DATA_BLOB lmv2_session_key = data_blob(NULL, 0);	DATA_BLOB ntlmv2_session_key = data_blob(NULL, 0);	DATA_BLOB names_blob = NTLMv2_generate_names_blob(samlogon_state->mem_ctx, samlogon_state->iconv_convenience, lp_netbios_name(global_loadparm), lp_workgroup(global_loadparm));	DATA_BLOB ntlm_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24);	DATA_BLOB ntlm_session_key = data_blob_talloc(samlogon_state->mem_ctx, NULL, 16);	bool lm_good;	uint8_t lm_hash[16];	uint8_t lm_session_key[8];	uint8_t user_session_key[16];	uint8_t nt_hash[16];	SMBNTencrypt(samlogon_state->password, samlogon_state->chall.data, 		     ntlm_response.data);	E_md4hash(samlogon_state->password, nt_hash);	SMBsesskeygen_ntv1(nt_hash, 			   ntlm_session_key.data);	lm_good = E_deshash(samlogon_state->password, lm_hash); 	if (!lm_good) {		ZERO_STRUCT(lm_hash);	}	ZERO_STRUCT(lm_session_key);	ZERO_STRUCT(user_session_key);	switch (ntlmv2_domain) {	case UPPER_DOMAIN:		/* TODO - test with various domain cases, and without domain */		if (!SMBNTLMv2encrypt(samlogon_state->mem_ctx, 				      samlogon_state->account_name, samlogon_state->account_domain, 				      samlogon_state->password, &samlogon_state->chall,				      &names_blob,				      &lmv2_response, &ntlmv2_response, 				      &lmv2_session_key, &ntlmv2_session_key)) {			data_blob_free(&names_blob);			return false;		}		break;	case NO_DOMAIN:		/* TODO - test with various domain cases, and without domain */		if (!SMBNTLMv2encrypt(samlogon_state->mem_ctx, 				      samlogon_state->account_name, "",				      samlogon_state->password, &samlogon_state->chall,				      &names_blob,				      &lmv2_response, &ntlmv2_response, 				      &lmv2_session_key, &ntlmv2_session_key)) {			data_blob_free(&names_blob);			return false;		}		break;	}	data_blob_free(&names_blob);	nt_status = check_samlogon(samlogon_state,				   break_which,				   samlogon_state->parameter_control,				   &samlogon_state->chall,				   &lmv2_response,				   &ntlm_response,				   lm_session_key, 				   user_session_key,				   error_string);		data_blob_free(&lmv2_response);	data_blob_free(&ntlmv2_response);	if (NT_STATUS_EQUAL(NT_STATUS_WRONG_PASSWORD, nt_status)) {		/* for 'old' passwords, we allow the server to be OK or wrong password */		if (samlogon_state->old_password) {			return true;		}		return ((break_which == BREAK_NT) || (break_which == BREAK_BOTH));	} else if (NT_STATUS_EQUAL(NT_STATUS_NOT_FOUND, nt_status) && strchr_m(samlogon_state->account_name, '@')) {		return ((break_which == BREAK_NT) || (break_which == BREAK_BOTH));	} else if (!NT_STATUS_EQUAL(samlogon_state->expected_error, nt_status)) {		SAFE_FREE(*error_string);		asprintf(error_string, "Expected error: %s, got %s", nt_errstr(samlogon_state->expected_error), nt_errstr(nt_status));		return false;	} else if (NT_STATUS_EQUAL(samlogon_state->expected_error, nt_status) && !NT_STATUS_IS_OK(nt_status)) {		return true;	} else if (!NT_STATUS_IS_OK(nt_status)) {		return false;	}	switch (break_which) {	case NO_NT:		if (memcmp(lmv2_session_key.data, user_session_key, 			   sizeof(user_session_key)) != 0) {			d_printf("USER (LMv2) Session Key does not match expectations!\n");			d_printf("user_session_key:\n");			dump_data(1, user_session_key, 16);			d_printf("expected:\n");			dump_data(1, lmv2_session_key.data, ntlmv2_session_key.length);			pass = false;		}		if (memcmp(lmv2_session_key.data, lm_session_key, 			   sizeof(lm_session_key)) != 0) {			d_printf("LM (LMv2) Session Key does not match expectations!\n");			d_printf("lm_session_key:\n");			dump_data(1, lm_session_key, 8);			d_printf("expected:\n");			dump_data(1, lmv2_session_key.data, 8);			pass = false;		}		break;	case BREAK_LM:		if (memcmp(ntlm_session_key.data, user_session_key, 			   sizeof(user_session_key)) != 0) {			d_printf("USER (NTLMv2) Session Key does not match expectations!\n");			d_printf("user_session_key:\n");			dump_data(1, user_session_key, 16);			d_printf("expected:\n");			dump_data(1, ntlm_session_key.data, ntlm_session_key.length);			pass = false;		}		if (lm_good) {			if (memcmp(lm_hash, lm_session_key, 				   sizeof(lm_session_key)) != 0) {				d_printf("LM Session Key does not match expectations!\n");				d_printf("lm_session_key:\n");				dump_data(1, lm_session_key, 8);				d_printf("expected:\n");				dump_data(1, lm_hash, 8);				pass = false;			}		} else {			static const uint8_t zeros[8];			if (memcmp(zeros, lm_session_key, 				   sizeof(lm_session_key)) != 0) {				d_printf("LM Session Key does not match expectations (zeros)!\n");				d_printf("lm_session_key:\n");				dump_data(1, lm_session_key, 8);				d_printf("expected:\n");				dump_data(1, zeros, 8);				pass = false;			}		}		break;	default:		if (memcmp(ntlm_session_key.data, user_session_key, 			   sizeof(user_session_key)) != 0) {			d_printf("USER (NTLMv2) Session Key does not match expectations!\n");			d_printf("user_session_key:\n");			dump_data(1, user_session_key, 16);			d_printf("expected:\n");			dump_data(1, ntlm_session_key.data, ntlm_session_key.length);			pass = false;		}		if (memcmp(ntlm_session_key.data, lm_session_key, 			   sizeof(lm_session_key)) != 0) {			d_printf("LM (NTLMv2) Session Key does not match expectations!\n");			d_printf("lm_session_key:\n");			dump_data(1, lm_session_key, 8);			d_printf("expected:\n");			dump_data(1, ntlm_session_key.data, 8);			pass = false;		}	}        return pass;}/*  * Test the NTLMv2 and LMv2 responses */static bool test_lmv2_ntlmv2(struct samlogon_state *samlogon_state, char **error_string) {	return test_lmv2_ntlmv2_broken(samlogon_state, BREAK_NONE, UPPER_DOMAIN, error_string);}#if 0static bool test_lmv2_ntlmv2_no_dom(struct samlogon_state *samlogon_state, char **error_string) {	return test_lmv2_ntlmv2_broken(samlogon_state, BREAK_NONE, NO_DOMAIN, error_string);}#endif/*  * Test the LMv2 response only */static bool test_lmv2(struct samlogon_state *samlogon_state, char **error_string) 

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?