1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-28 01:58:17 +03:00

r4566: Fix Samba4 to pass it's own RPC-SAMLOGON torture test.

Include RPC-SAMLOGON in the list of tests expected to pass

Remove silly extra loops from the RPC-SAMLOGON test, which mostly just
slowed htings down.

Andrew Bartlett
This commit is contained in:
Andrew Bartlett 2005-01-06 12:13:31 +00:00 committed by Gerald (Jerry) Carter
parent 5598cda08b
commit 518ca9fb69
3 changed files with 178 additions and 57 deletions

View File

@ -58,11 +58,6 @@ static BOOL smb_pwd_check_ntlmv1(TALLOC_CTX *mem_ctx,
}
SMBOWFencrypt(part_passwd, sec_blob->data, p24);
if (user_sess_key != NULL) {
*user_sess_key = data_blob_talloc(mem_ctx, NULL, 16);
SMBsesskeygen_ntv1(part_passwd, user_sess_key->data);
}
#if DEBUG_PASSWORD
DEBUG(100,("Part password (P16) was |\n"));
@ -74,7 +69,14 @@ static BOOL smb_pwd_check_ntlmv1(TALLOC_CTX *mem_ctx,
DEBUGADD(100,("Value from encryption was |\n"));
dump_data(100, p24, 24);
#endif
return (memcmp(p24, nt_response->data, 24) == 0);
if (memcmp(p24, nt_response->data, 24) == 0) {
if (user_sess_key != NULL) {
*user_sess_key = data_blob_talloc(mem_ctx, NULL, 16);
SMBsesskeygen_ntv1(part_passwd, user_sess_key->data);
}
return True;
}
return False;
}
/****************************************************************************
@ -93,7 +95,6 @@ static BOOL smb_pwd_check_ntlmv2(TALLOC_CTX *mem_ctx,
/* Finish the encryption of part_passwd. */
uint8_t kr[16];
uint8_t value_from_encryption[16];
uint8_t client_response[16];
DATA_BLOB client_key_data;
if (part_passwd == NULL) {
@ -123,17 +124,11 @@ static BOOL smb_pwd_check_ntlmv2(TALLOC_CTX *mem_ctx,
but for NTLMv2 it is meant to contain the current time etc.
*/
memcpy(client_response, ntv2_response->data, sizeof(client_response));
if (!ntv2_owf_gen(part_passwd, user, domain, upper_case_domain, kr)) {
return False;
}
SMBOWFencrypt_ntv2(kr, sec_blob, &client_key_data, value_from_encryption);
if (user_sess_key != NULL) {
*user_sess_key = data_blob_talloc(mem_ctx, NULL, 16);
SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key->data);
}
#if DEBUG_PASSWORD
DEBUG(100,("Part password (P16) was |\n"));
@ -148,7 +143,65 @@ static BOOL smb_pwd_check_ntlmv2(TALLOC_CTX *mem_ctx,
dump_data(100, value_from_encryption, 16);
#endif
data_blob_clear_free(&client_key_data);
return (memcmp(value_from_encryption, client_response, 16) == 0);
if (memcmp(value_from_encryption, ntv2_response->data, 16) == 0) {
if (user_sess_key != NULL) {
*user_sess_key = data_blob_talloc(mem_ctx, NULL, 16);
SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key->data);
}
return True;
}
return False;
}
/****************************************************************************
Core of smb password checking routine. (NTLMv2, LMv2)
Note: The same code works with both NTLMv2 and LMv2.
****************************************************************************/
static BOOL smb_sess_key_ntlmv2(TALLOC_CTX *mem_ctx,
const DATA_BLOB *ntv2_response,
const uint8_t *part_passwd,
const DATA_BLOB *sec_blob,
const char *user, const char *domain,
BOOL upper_case_domain, /* should the domain be transformed into upper case? */
DATA_BLOB *user_sess_key)
{
/* Finish the encryption of part_passwd. */
uint8_t kr[16];
uint8_t value_from_encryption[16];
DATA_BLOB client_key_data;
if (part_passwd == NULL) {
DEBUG(10,("No password set - DISALLOWING access\n"));
/* No password set - always False */
return False;
}
if (sec_blob->length != 8) {
DEBUG(0, ("smb_sess_key_ntlmv2: incorrect challenge size (%lu)\n",
(unsigned long)sec_blob->length));
return False;
}
if (ntv2_response->length < 24) {
/* We MUST have more than 16 bytes, or the stuff below will go
crazy. No known implementation sends less than the 24 bytes
for LMv2, let alone NTLMv2. */
DEBUG(0, ("smb_sess_key_ntlmv2: incorrect password length (%lu)\n",
(unsigned long)ntv2_response->length));
return False;
}
client_key_data = data_blob_talloc(mem_ctx, ntv2_response->data+16, ntv2_response->length-16);
if (!ntv2_owf_gen(part_passwd, user, domain, upper_case_domain, kr)) {
return False;
}
SMBOWFencrypt_ntv2(kr, sec_blob, &client_key_data, value_from_encryption);
*user_sess_key = data_blob_talloc(mem_ctx, NULL, 16);
SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key->data);
return True;
}
/**
@ -182,6 +235,8 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
DATA_BLOB *lm_sess_key)
{
static const uint8_t zeros[8];
DATA_BLOB tmp_sess_key;
if (nt_pw == NULL) {
DEBUG(3,("ntlm_password_check: NO NT password stored for user %s.\n",
username));
@ -299,7 +354,9 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
user_sess_key)) {
if (lm_sess_key) {
*lm_sess_key = *user_sess_key;
lm_sess_key->length = 8;
if (user_sess_key->length) {
lm_sess_key->length = 8;
}
}
return NT_STATUS_OK;
}
@ -314,7 +371,9 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
user_sess_key)) {
if (lm_sess_key) {
*lm_sess_key = *user_sess_key;
lm_sess_key->length = 8;
if (user_sess_key->length) {
lm_sess_key->length = 8;
}
}
return NT_STATUS_OK;
}
@ -329,7 +388,9 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
user_sess_key)) {
if (lm_sess_key) {
*lm_sess_key = *user_sess_key;
lm_sess_key->length = 8;
if (user_sess_key->length) {
lm_sess_key->length = 8;
}
}
return NT_STATUS_OK;
} else {
@ -418,10 +479,28 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
client_username,
client_domain,
False,
user_sess_key)) {
if (lm_sess_key) {
&tmp_sess_key)) {
if (nt_response->length > 24) {
/* If NTLMv2 authentication has preceeded us
* (even if it failed), then use the session
* key from that. See the RPC-SAMLOGON
* torture test */
smb_sess_key_ntlmv2(mem_ctx,
nt_response,
nt_pw, challenge,
client_username,
client_domain,
False,
user_sess_key);
} else if (user_sess_key) {
/* Otherwise, use the LMv2 session key */
*user_sess_key = tmp_sess_key;
}
if (user_sess_key && lm_sess_key) {
*lm_sess_key = *user_sess_key;
lm_sess_key->length = 8;
if (user_sess_key->length) {
lm_sess_key->length = 8;
}
}
return NT_STATUS_OK;
}
@ -433,10 +512,28 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
client_username,
client_domain,
True,
user_sess_key)) {
if (lm_sess_key) {
&tmp_sess_key)) {
if (nt_response->length > 24) {
/* If NTLMv2 authentication has preceeded us
* (even if it failed), then use the session
* key from that. See the RPC-SAMLOGON
* torture test */
smb_sess_key_ntlmv2(mem_ctx,
nt_response,
nt_pw, challenge,
client_username,
client_domain,
True,
user_sess_key);
} else if (user_sess_key) {
/* Otherwise, use the LMv2 session key */
*user_sess_key = tmp_sess_key;
}
if (user_sess_key && lm_sess_key) {
*lm_sess_key = *user_sess_key;
lm_sess_key->length = 8;
if (user_sess_key->length) {
lm_sess_key->length = 8;
}
}
return NT_STATUS_OK;
}
@ -448,10 +545,28 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
client_username,
"",
False,
user_sess_key)) {
if (lm_sess_key) {
&tmp_sess_key)) {
if (nt_response->length > 24) {
/* If NTLMv2 authentication has preceeded us
* (even if it failed), then use the session
* key from that. See the RPC-SAMLOGON
* torture test */
smb_sess_key_ntlmv2(mem_ctx,
nt_response,
nt_pw, challenge,
client_username,
"",
False,
user_sess_key);
} else if (user_sess_key) {
/* Otherwise, use the LMv2 session key */
*user_sess_key = tmp_sess_key;
}
if (user_sess_key && lm_sess_key) {
*lm_sess_key = *user_sess_key;
lm_sess_key->length = 8;
if (user_sess_key->length) {
lm_sess_key->length = 8;
}
}
return NT_STATUS_OK;
}

View File

@ -2,9 +2,9 @@
# add tests to this list as they start passing, so we test
# that they stay passing
ncacn_np_tests="RPC-SCHANNEL RPC-ECHO RPC-DSSETUP"
ncalrpc_tests="RPC-SCHANNEL RPC-ECHO RPC-DSSETUP"
ncacn_ip_tcp_tests="RPC-SCHANNEL RPC-ECHO"
ncacn_np_tests="RPC-SCHANNEL RPC-ECHO RPC-DSSETUP RPC-SAMLOGON"
ncalrpc_tests="RPC-SCHANNEL RPC-ECHO RPC-DSSETUP RPC-SAMLOGON"
ncacn_ip_tcp_tests="RPC-SCHANNEL RPC-ECHO RPC-SAMLOGON"
if [ $# -lt 4 ]; then
cat <<EOF

View File

@ -582,7 +582,7 @@ static BOOL test_lmv2_ntlmv2_broken(struct samlogon_state *samlogon_state, enum
switch (break_which) {
case NO_NT:
if (memcmp(lmv2_session_key.data, user_session_key,
if (memcmp(lmv2_session_key.data, user_session_key,
sizeof(user_session_key)) != 0) {
printf("USER (LMv2) Session Key does not match expectations!\n");
printf("user_session_key:\n");
@ -604,21 +604,42 @@ static BOOL test_lmv2_ntlmv2_broken(struct samlogon_state *samlogon_state, enum
default:
if (memcmp(ntlmv2_session_key.data, user_session_key,
sizeof(user_session_key)) != 0) {
printf("USER (NTLMv2) Session Key does not match expectations!\n");
printf("user_session_key:\n");
dump_data(1, user_session_key, 16);
printf("expected:\n");
dump_data(1, ntlmv2_session_key.data, ntlmv2_session_key.length);
pass = False;
if (memcmp(lmv2_session_key.data, user_session_key,
sizeof(user_session_key)) == 0) {
printf("USER (NTLMv2) Session Key expected, got LMv2 sessesion key instead:\n");
printf("user_session_key:\n");
dump_data(1, user_session_key, 16);
printf("expected:\n");
dump_data(1, ntlmv2_session_key.data, ntlmv2_session_key.length);
pass = False;
} else {
printf("USER (NTLMv2) Session Key does not match expectations!\n");
printf("user_session_key:\n");
dump_data(1, user_session_key, 16);
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) {
printf("LM (NTLMv2) Session Key does not match expectations!\n");
printf("lm_session_key:\n");
dump_data(1, lm_session_key, 8);
printf("expected:\n");
dump_data(1, ntlmv2_session_key.data, 8);
pass = False;
if (memcmp(lmv2_session_key.data, lm_session_key,
sizeof(lm_session_key)) == 0) {
printf("LM (NTLMv2) Session Key expected, got LMv2 sessesion key instead:\n");
printf("user_session_key:\n");
dump_data(1, lm_session_key, 8);
printf("expected:\n");
dump_data(1, ntlmv2_session_key.data, 8);
pass = False;
} else {
printf("LM (NTLMv2) Session Key does not match expectations!\n");
printf("lm_session_key:\n");
dump_data(1, lm_session_key, 8);
printf("expected:\n");
dump_data(1, ntlmv2_session_key.data, 8);
pass = False;
}
}
}
@ -1267,21 +1288,6 @@ BOOL torture_rpc_samlogon(void)
}
}
for (i=0; i < 32; i++) {
if (!test_SetupCredentials2(p, mem_ctx, 1 << i,
TEST_MACHINE_NAME, machine_password, creds)) {
return False;
}
if (!test_InteractiveLogon(p, mem_ctx, creds)) {
ret = False;
}
if (!test_SamLogon(p, mem_ctx, creds)) {
ret = False;
}
}
failed:
talloc_destroy(mem_ctx);