mirror of
https://github.com/samba-team/samba.git
synced 2025-12-12 12:23:50 +03:00
r451: More NTLMSSP work.
The work here is trying to get the LM_KEY option for NLTMSSP operating, however until that functions properly, it is now controlled by some new smb.conf options, defaulting off. Andrew Bartlett
This commit is contained in:
committed by
Gerald (Jerry) Carter
parent
56ebc4275f
commit
c63eb35b45
@@ -330,10 +330,10 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
|
|||||||
ntlmssp_state->unicode = False;
|
ntlmssp_state->unicode = False;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && allow_lm) {
|
if ((neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && allow_lm && !ntlmssp_state->use_ntlmv2) {
|
||||||
/* other end forcing us to use LM */
|
/* other end forcing us to use LM */
|
||||||
ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
|
ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
|
||||||
ntlmssp_state->use_ntlmv2 = False;
|
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
|
||||||
} else {
|
} else {
|
||||||
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
|
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
|
||||||
}
|
}
|
||||||
@@ -348,6 +348,13 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
|
|||||||
|
|
||||||
if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) {
|
if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) {
|
||||||
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;
|
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;
|
||||||
|
if (neg_flags & NTLMSSP_NEGOTIATE_56) {
|
||||||
|
ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(neg_flags & NTLMSSP_NEGOTIATE_56)) {
|
||||||
|
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
|
if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
|
||||||
@@ -360,6 +367,32 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Weaken NTLMSSP keys to cope with down-level clients and servers.
|
||||||
|
|
||||||
|
We probably should have some parameters to control this, but as
|
||||||
|
it only occours for LM_KEY connections, and this is controlled
|
||||||
|
by the client lanman auth/lanman auth parameters, it isn't too bad.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void ntlmssp_weaken_keys(struct ntlmssp_state *ntlmssp_state) {
|
||||||
|
/* Key weakening not performed on the master key for NTLM2
|
||||||
|
and does not occour for NTLM1. Therefore we only need
|
||||||
|
to do this for the LM_KEY.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
|
||||||
|
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) {
|
||||||
|
|
||||||
|
} else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {
|
||||||
|
ntlmssp_state->session_key.data[7] = 0xa0;
|
||||||
|
} else { /* forty bits */
|
||||||
|
ntlmssp_state->session_key.data[5] = 0xe5;
|
||||||
|
ntlmssp_state->session_key.data[6] = 0x38;
|
||||||
|
ntlmssp_state->session_key.data[7] = 0xb0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Next state function for the Negotiate packet
|
* Next state function for the Negotiate packet
|
||||||
@@ -404,7 +437,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
|
|||||||
debug_ntlmssp_flags(neg_flags);
|
debug_ntlmssp_flags(neg_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, lp_lanman_auth());
|
ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, ntlmssp_state->allow_lm_key);
|
||||||
|
|
||||||
/* Ask our caller what challenge they would like in the packet */
|
/* Ask our caller what challenge they would like in the packet */
|
||||||
cryptkey = ntlmssp_state->get_challenge(ntlmssp_state);
|
cryptkey = ntlmssp_state->get_challenge(ntlmssp_state);
|
||||||
@@ -534,8 +567,8 @@ static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state,
|
|||||||
&workstation,
|
&workstation,
|
||||||
&ntlmssp_state->encrypted_session_key,
|
&ntlmssp_state->encrypted_session_key,
|
||||||
&auth_flags)) {
|
&auth_flags)) {
|
||||||
DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n"));
|
DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n"));
|
||||||
dump_data(2, (const char *)request.data, request.length);
|
dump_data(10, (const char *)request.data, request.length);
|
||||||
SAFE_FREE(domain);
|
SAFE_FREE(domain);
|
||||||
SAFE_FREE(user);
|
SAFE_FREE(user);
|
||||||
SAFE_FREE(workstation);
|
SAFE_FREE(workstation);
|
||||||
@@ -569,7 +602,7 @@ static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (auth_flags)
|
if (auth_flags)
|
||||||
ntlmssp_handle_neg_flags(ntlmssp_state, auth_flags, lp_lanman_auth());
|
ntlmssp_handle_neg_flags(ntlmssp_state, auth_flags, ntlmssp_state->allow_lm_key);
|
||||||
|
|
||||||
if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) {
|
if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) {
|
||||||
SAFE_FREE(domain);
|
SAFE_FREE(domain);
|
||||||
@@ -636,6 +669,9 @@ static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state,
|
|||||||
data_blob_free(&ntlmssp_state->encrypted_session_key);
|
data_blob_free(&ntlmssp_state->encrypted_session_key);
|
||||||
return nt_status;
|
return nt_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* LM Key is incompatible... */
|
||||||
|
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NT_STATUS_OK;
|
return NT_STATUS_OK;
|
||||||
@@ -680,7 +716,10 @@ static NTSTATUS ntlmssp_server_postauth(struct ntlmssp_state *ntlmssp_state,
|
|||||||
DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));
|
DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));
|
||||||
session_key = data_blob(NULL, 0);
|
session_key = data_blob(NULL, 0);
|
||||||
}
|
}
|
||||||
} else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
|
} else if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
|
||||||
|
/* Ensure we can never get here on NTLMv2 */
|
||||||
|
&& (ntlmssp_state->nt_resp.length == 0 || ntlmssp_state->nt_resp.length == 24)) {
|
||||||
|
|
||||||
if (lm_session_key && lm_session_key->data && lm_session_key->length >= 8) {
|
if (lm_session_key && lm_session_key->data && lm_session_key->length >= 8) {
|
||||||
if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {
|
if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {
|
||||||
session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
|
session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
|
||||||
@@ -689,26 +728,46 @@ static NTSTATUS ntlmssp_server_postauth(struct ntlmssp_state *ntlmssp_state,
|
|||||||
DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
|
DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
|
||||||
dump_data_pw("LM session key:\n", session_key.data, session_key.length);
|
dump_data_pw("LM session key:\n", session_key.data, session_key.length);
|
||||||
} else {
|
} else {
|
||||||
/* use the key unmodified - it's
|
|
||||||
* probably a NULL key from the guest
|
/* When there is no LM response, just use zeros */
|
||||||
* login */
|
static const uchar zeros[24];
|
||||||
session_key = *lm_session_key;
|
session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
|
||||||
|
SMBsesskeygen_lm_sess_key(zeros, zeros,
|
||||||
|
session_key.data);
|
||||||
|
DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
|
||||||
|
dump_data_pw("LM session key:\n", session_key.data, session_key.length);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
/* LM Key not selected */
|
||||||
|
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
|
||||||
|
|
||||||
DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));
|
DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));
|
||||||
session_key = data_blob(NULL, 0);
|
session_key = data_blob(NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (user_session_key && user_session_key->data) {
|
} else if (user_session_key && user_session_key->data) {
|
||||||
session_key = *user_session_key;
|
session_key = *user_session_key;
|
||||||
DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n"));
|
DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n"));
|
||||||
dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
|
dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
|
||||||
|
|
||||||
|
/* LM Key not selected */
|
||||||
|
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
|
||||||
|
|
||||||
} else if (lm_session_key && lm_session_key->data) {
|
} else if (lm_session_key && lm_session_key->data) {
|
||||||
|
/* Very weird to have LM key, but no user session key, but anyway.. */
|
||||||
session_key = *lm_session_key;
|
session_key = *lm_session_key;
|
||||||
DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n"));
|
DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n"));
|
||||||
dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
|
dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
|
||||||
|
|
||||||
|
/* LM Key not selected */
|
||||||
|
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n"));
|
DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n"));
|
||||||
session_key = data_blob(NULL, 0);
|
session_key = data_blob(NULL, 0);
|
||||||
|
|
||||||
|
/* LM Key not selected */
|
||||||
|
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* With KEY_EXCH, the client supplies the proposed session key,
|
/* With KEY_EXCH, the client supplies the proposed session key,
|
||||||
@@ -741,6 +800,9 @@ static NTSTATUS ntlmssp_server_postauth(struct ntlmssp_state *ntlmssp_state,
|
|||||||
ntlmssp_state->session_key = session_key;
|
ntlmssp_state->session_key = session_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The server might need us to use a partial-strength session key */
|
||||||
|
ntlmssp_weaken_keys(ntlmssp_state);
|
||||||
|
|
||||||
nt_status = ntlmssp_sign_init(ntlmssp_state);
|
nt_status = ntlmssp_sign_init(ntlmssp_state);
|
||||||
|
|
||||||
data_blob_free(&ntlmssp_state->encrypted_session_key);
|
data_blob_free(&ntlmssp_state->encrypted_session_key);
|
||||||
@@ -824,6 +886,9 @@ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state)
|
|||||||
|
|
||||||
(*ntlmssp_state)->expected_state = NTLMSSP_NEGOTIATE;
|
(*ntlmssp_state)->expected_state = NTLMSSP_NEGOTIATE;
|
||||||
|
|
||||||
|
(*ntlmssp_state)->allow_lm_key = (lp_lanman_auth()
|
||||||
|
&& lp_parm_bool(-1, "ntlmssp_server", "allow_lm_key", False));
|
||||||
|
|
||||||
(*ntlmssp_state)->ref_count = 1;
|
(*ntlmssp_state)->ref_count = 1;
|
||||||
|
|
||||||
(*ntlmssp_state)->neg_flags =
|
(*ntlmssp_state)->neg_flags =
|
||||||
@@ -895,9 +960,11 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
|
|||||||
char *server_domain;
|
char *server_domain;
|
||||||
const char *chal_parse_string;
|
const char *chal_parse_string;
|
||||||
const char *auth_gen_string;
|
const char *auth_gen_string;
|
||||||
|
uchar lm_hash[16];
|
||||||
DATA_BLOB lm_response = data_blob(NULL, 0);
|
DATA_BLOB lm_response = data_blob(NULL, 0);
|
||||||
DATA_BLOB nt_response = data_blob(NULL, 0);
|
DATA_BLOB nt_response = data_blob(NULL, 0);
|
||||||
DATA_BLOB session_key = data_blob(NULL, 0);
|
DATA_BLOB session_key = data_blob(NULL, 0);
|
||||||
|
DATA_BLOB lm_session_key = data_blob(NULL, 0);
|
||||||
DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
|
DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
|
||||||
NTSTATUS nt_status;
|
NTSTATUS nt_status;
|
||||||
|
|
||||||
@@ -917,7 +984,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
|
|||||||
DEBUG(3, ("Got challenge flags:\n"));
|
DEBUG(3, ("Got challenge flags:\n"));
|
||||||
debug_ntlmssp_flags(chal_flags);
|
debug_ntlmssp_flags(chal_flags);
|
||||||
|
|
||||||
ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, lp_client_lanman_auth());
|
ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, ntlmssp_state->allow_lm_key);
|
||||||
|
|
||||||
if (ntlmssp_state->unicode) {
|
if (ntlmssp_state->unicode) {
|
||||||
if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
|
if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
|
||||||
@@ -967,6 +1034,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
|
|||||||
|
|
||||||
/* session key is all zeros */
|
/* session key is all zeros */
|
||||||
session_key = data_blob_talloc(ntlmssp_state->mem_ctx, zeros, 16);
|
session_key = data_blob_talloc(ntlmssp_state->mem_ctx, zeros, 16);
|
||||||
|
lm_session_key = data_blob_talloc(ntlmssp_state->mem_ctx, zeros, 16);
|
||||||
|
|
||||||
/* not doing NLTM2 without a password */
|
/* not doing NLTM2 without a password */
|
||||||
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
|
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
|
||||||
@@ -990,6 +1058,10 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
|
|||||||
data_blob_free(&struct_blob);
|
data_blob_free(&struct_blob);
|
||||||
return NT_STATUS_NO_MEMORY;
|
return NT_STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* LM Key is incompatible... */
|
||||||
|
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
|
||||||
|
|
||||||
} else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
|
} else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
|
||||||
struct MD5Context md5_session_nonce_ctx;
|
struct MD5Context md5_session_nonce_ctx;
|
||||||
uchar nt_hash[16];
|
uchar nt_hash[16];
|
||||||
@@ -1024,38 +1096,69 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
|
|||||||
SMBsesskeygen_ntv1(nt_hash, NULL, user_session_key);
|
SMBsesskeygen_ntv1(nt_hash, NULL, user_session_key);
|
||||||
hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data);
|
hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data);
|
||||||
dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
|
dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
|
||||||
|
|
||||||
|
/* LM Key is incompatible... */
|
||||||
|
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
||||||
uchar lm_hash[16];
|
|
||||||
uchar nt_hash[16];
|
uchar nt_hash[16];
|
||||||
E_deshash(ntlmssp_state->password, lm_hash);
|
|
||||||
|
if (ntlmssp_state->use_nt_response) {
|
||||||
|
nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
|
||||||
|
SMBNTencrypt(ntlmssp_state->password,challenge_blob.data,
|
||||||
|
nt_response.data);
|
||||||
E_md4hash(ntlmssp_state->password, nt_hash);
|
E_md4hash(ntlmssp_state->password, nt_hash);
|
||||||
|
session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
|
||||||
|
SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
|
||||||
|
dump_data_pw("NT session key:\n", session_key.data, session_key.length);
|
||||||
|
}
|
||||||
|
|
||||||
/* lanman auth is insecure, it may be disabled */
|
/* lanman auth is insecure, it may be disabled */
|
||||||
if (lp_client_lanman_auth()) {
|
if (lp_client_lanman_auth()) {
|
||||||
lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
|
lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
|
||||||
SMBencrypt(ntlmssp_state->password,challenge_blob.data,
|
if (!SMBencrypt(ntlmssp_state->password,challenge_blob.data,
|
||||||
lm_response.data);
|
lm_response.data)) {
|
||||||
}
|
/* If the LM password was too long (and therefore the LM hash being
|
||||||
|
of the first 14 chars only), don't send it */
|
||||||
|
data_blob_free(&lm_response);
|
||||||
|
|
||||||
nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
|
/* LM Key is incompatible with 'long' passwords */
|
||||||
SMBNTencrypt(ntlmssp_state->password,challenge_blob.data,
|
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
|
||||||
nt_response.data);
|
|
||||||
|
|
||||||
session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
|
|
||||||
if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
|
|
||||||
&& lp_client_lanman_auth()) {
|
|
||||||
SMBsesskeygen_lmv1(lm_hash, lm_response.data,
|
|
||||||
session_key.data);
|
|
||||||
dump_data_pw("LM session key\n", session_key.data, session_key.length);
|
|
||||||
} else {
|
} else {
|
||||||
SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
|
E_deshash(ntlmssp_state->password, lm_hash);
|
||||||
dump_data_pw("NT session key:\n", session_key.data, session_key.length);
|
lm_session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
|
||||||
|
memcpy(lm_session_key.data, lm_hash, 8);
|
||||||
|
memset(&lm_session_key.data[8], '\0', 8);
|
||||||
|
|
||||||
|
if (!ntlmssp_state->use_nt_response) {
|
||||||
|
session_key = lm_session_key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
/* LM Key is incompatible... */
|
||||||
|
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
|
||||||
|
&& lp_client_lanman_auth() && lm_session_key.length == 16) {
|
||||||
|
DATA_BLOB new_session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
|
||||||
|
if (lm_response.length == 24) {
|
||||||
|
SMBsesskeygen_lm_sess_key(lm_session_key.data, lm_response.data,
|
||||||
|
new_session_key.data);
|
||||||
|
} else {
|
||||||
|
static const uchar zeros[24];
|
||||||
|
SMBsesskeygen_lm_sess_key(lm_session_key.data, zeros,
|
||||||
|
new_session_key.data);
|
||||||
|
}
|
||||||
|
new_session_key.length = 16;
|
||||||
|
session_key = new_session_key;
|
||||||
|
dump_data_pw("LM session key\n", session_key.data, session_key.length);
|
||||||
|
}
|
||||||
|
|
||||||
data_blob_free(&struct_blob);
|
data_blob_free(&struct_blob);
|
||||||
|
|
||||||
|
|
||||||
/* Key exchange encryptes a new client-generated session key with
|
/* Key exchange encryptes a new client-generated session key with
|
||||||
the password-derived key */
|
the password-derived key */
|
||||||
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
|
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
|
||||||
@@ -1093,10 +1196,14 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
|
|||||||
|
|
||||||
data_blob_free(&ntlmssp_state->chal);
|
data_blob_free(&ntlmssp_state->chal);
|
||||||
|
|
||||||
|
ntlmssp_state->session_key = session_key;
|
||||||
|
|
||||||
|
/* The client might be using 56 or 40 bit weakened keys */
|
||||||
|
ntlmssp_weaken_keys(ntlmssp_state);
|
||||||
|
|
||||||
ntlmssp_state->chal = challenge_blob;
|
ntlmssp_state->chal = challenge_blob;
|
||||||
ntlmssp_state->lm_resp = lm_response;
|
ntlmssp_state->lm_resp = lm_response;
|
||||||
ntlmssp_state->nt_resp = nt_response;
|
ntlmssp_state->nt_resp = nt_response;
|
||||||
ntlmssp_state->session_key = session_key;
|
|
||||||
|
|
||||||
ntlmssp_state->expected_state = NTLMSSP_UNKNOWN;
|
ntlmssp_state->expected_state = NTLMSSP_UNKNOWN;
|
||||||
|
|
||||||
@@ -1128,7 +1235,12 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state)
|
|||||||
(*ntlmssp_state)->get_global_myname = global_myname;
|
(*ntlmssp_state)->get_global_myname = global_myname;
|
||||||
(*ntlmssp_state)->get_domain = lp_workgroup;
|
(*ntlmssp_state)->get_domain = lp_workgroup;
|
||||||
|
|
||||||
(*ntlmssp_state)->unicode = True;
|
(*ntlmssp_state)->unicode = lp_parm_bool(-1, "ntlmssp_client", "unicode", True);
|
||||||
|
|
||||||
|
(*ntlmssp_state)->use_nt_response = lp_parm_bool(-1, "ntlmssp_client", "send_nt_reponse", True);
|
||||||
|
|
||||||
|
(*ntlmssp_state)->allow_lm_key = (lp_lanman_auth()
|
||||||
|
&& lp_parm_bool(-1, "ntlmssp_client", "allow_lm_key", False));
|
||||||
|
|
||||||
(*ntlmssp_state)->use_ntlmv2 = lp_client_ntlmv2_auth();
|
(*ntlmssp_state)->use_ntlmv2 = lp_client_ntlmv2_auth();
|
||||||
|
|
||||||
@@ -1145,7 +1257,11 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state)
|
|||||||
* We need to set this to allow a later SetPassword
|
* We need to set this to allow a later SetPassword
|
||||||
* via the SAMR pipe to succeed. Strange.... We could
|
* via the SAMR pipe to succeed. Strange.... We could
|
||||||
* also add NTLMSSP_NEGOTIATE_SEAL here. JRA.
|
* also add NTLMSSP_NEGOTIATE_SEAL here. JRA.
|
||||||
* */
|
*
|
||||||
|
* Without this, Windows will not create the master key
|
||||||
|
* that it thinks is only used for NTLMSSP signing and
|
||||||
|
* sealing. (It is actually pulled out and used directly)
|
||||||
|
*/
|
||||||
NTLMSSP_NEGOTIATE_SIGN |
|
NTLMSSP_NEGOTIATE_SIGN |
|
||||||
NTLMSSP_REQUEST_TARGET;
|
NTLMSSP_REQUEST_TARGET;
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ enum NTLM_MESSAGE_TYPE
|
|||||||
#define NTLMSSP_CHAL_TARGET_INFO 0x00800000
|
#define NTLMSSP_CHAL_TARGET_INFO 0x00800000
|
||||||
#define NTLMSSP_NEGOTIATE_128 0x20000000 /* 128-bit encryption */
|
#define NTLMSSP_NEGOTIATE_128 0x20000000 /* 128-bit encryption */
|
||||||
#define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000
|
#define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000
|
||||||
#define NTLMSSP_NEGOTIATE_080000000 0x80000000
|
#define NTLMSSP_NEGOTIATE_56 0x80000000
|
||||||
|
|
||||||
#define NTLMSSP_NAME_TYPE_SERVER 0x01
|
#define NTLMSSP_NAME_TYPE_SERVER 0x01
|
||||||
#define NTLMSSP_NAME_TYPE_DOMAIN 0x02
|
#define NTLMSSP_NAME_TYPE_DOMAIN 0x02
|
||||||
@@ -80,6 +80,9 @@ typedef struct ntlmssp_state
|
|||||||
|
|
||||||
BOOL unicode;
|
BOOL unicode;
|
||||||
BOOL use_ntlmv2;
|
BOOL use_ntlmv2;
|
||||||
|
BOOL use_nt_response; /* Set to 'NO' to debug what happens when the NT response is omited */
|
||||||
|
BOOL allow_lm_key; /* The LM_KEY code is not functional at this point, and it's not
|
||||||
|
very secure anyway */
|
||||||
char *user;
|
char *user;
|
||||||
char *domain;
|
char *domain;
|
||||||
char *workstation;
|
char *workstation;
|
||||||
|
|||||||
@@ -198,25 +198,6 @@ void SMBOWFencrypt(const uchar passwd[16], const uchar *c8, uchar p24[24])
|
|||||||
E_P24(p21, c8, p24);
|
E_P24(p21, c8, p24);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
|
|
||||||
void NTLMSSPOWFencrypt(const uchar passwd[8], const uchar *ntlmchalresp, uchar p24[24])
|
|
||||||
{
|
|
||||||
uchar p21[21];
|
|
||||||
|
|
||||||
memset(p21,'\0',21);
|
|
||||||
memcpy(p21, passwd, 8);
|
|
||||||
memset(p21 + 8, 0xbd, 8);
|
|
||||||
|
|
||||||
E_P24(p21, ntlmchalresp, p24);
|
|
||||||
#ifdef DEBUG_PASSWORD
|
|
||||||
DEBUG(100,("NTLMSSPOWFencrypt: p21, c8, p24\n"));
|
|
||||||
dump_data(100, (char *)p21, 21);
|
|
||||||
dump_data(100, (const char *)ntlmchalresp, 8);
|
|
||||||
dump_data(100, (char *)p24, 24);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Does the NT MD4 hash then des encryption. */
|
/* Does the NT MD4 hash then des encryption. */
|
||||||
|
|
||||||
void SMBNTencrypt(const char *passwd, uchar *c8, uchar *p24)
|
void SMBNTencrypt(const char *passwd, uchar *c8, uchar *p24)
|
||||||
@@ -288,48 +269,25 @@ void SMBsesskeygen_ntv1(const uchar kr[16],
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SMBsesskeygen_lmv1(const uchar lm_hash[16],
|
void SMBsesskeygen_lm_sess_key(const uchar lm_hash[16],
|
||||||
const uchar lm_resp[24], /* only uses 8 */
|
const uchar lm_resp[24], /* only uses 8 */
|
||||||
uint8 sess_key[16])
|
uint8 sess_key[16])
|
||||||
{
|
{
|
||||||
/* Calculate the LM session key (effective length 40 bits,
|
/* Calculate the LM session key (effective length 40 bits,
|
||||||
but changes with each session) */
|
but changes with each session) */
|
||||||
|
|
||||||
uchar p24[24];
|
uchar p24[24];
|
||||||
uchar partial_lm_hash[16];
|
uchar p21[21];
|
||||||
|
|
||||||
memcpy(partial_lm_hash, lm_hash, 8);
|
memset(p21,'\0',21);
|
||||||
memset(partial_lm_hash + 8, 0xbd, 8);
|
memcpy(p21, lm_hash, 8);
|
||||||
|
memset(p21 + 8, 0xbd, 8);
|
||||||
|
|
||||||
SMBOWFencrypt(lm_hash, lm_resp, p24);
|
E_P24(p21, lm_resp, p24);
|
||||||
|
|
||||||
memcpy(sess_key, p24, 16);
|
|
||||||
sess_key[5] = 0xe5;
|
|
||||||
sess_key[6] = 0x38;
|
|
||||||
sess_key[7] = 0xb0;
|
|
||||||
|
|
||||||
#ifdef DEBUG_PASSWORD
|
|
||||||
DEBUG(100, ("SMBsesskeygen_lmv1:\n"));
|
|
||||||
dump_data(100, sess_key, 16);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void SMBsesskeygen_lm_sess_key(const uchar lm_hash[16],
|
|
||||||
const uchar lm_resp[24], /* only uses 8 */
|
|
||||||
uint8 sess_key[16])
|
|
||||||
{
|
|
||||||
uchar p24[24];
|
|
||||||
uchar partial_lm_hash[16];
|
|
||||||
|
|
||||||
memcpy(partial_lm_hash, lm_hash, 8);
|
|
||||||
memset(partial_lm_hash + 8, 0xbd, 8);
|
|
||||||
|
|
||||||
SMBOWFencrypt(partial_lm_hash, lm_resp, p24);
|
|
||||||
|
|
||||||
memcpy(sess_key, p24, 16);
|
memcpy(sess_key, p24, 16);
|
||||||
|
|
||||||
#ifdef DEBUG_PASSWORD
|
#ifdef DEBUG_PASSWORD
|
||||||
DEBUG(100, ("SMBsesskeygen_lmv1_jerry:\n"));
|
DEBUG(100, ("SMBsesskeygen_lm_sess_key: \n"));
|
||||||
dump_data(100, sess_key, 16);
|
dump_data(100, sess_key, 16);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user