1
0
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:
Andrew Bartlett
2004-05-02 12:42:01 +00:00
committed by Gerald (Jerry) Carter
parent 56ebc4275f
commit c63eb35b45
3 changed files with 171 additions and 94 deletions

View File

@@ -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);
@@ -688,27 +727,47 @@ static NTSTATUS ntlmssp_server_postauth(struct ntlmssp_state *ntlmssp_state,
session_key.data); session_key.data);
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);
E_md4hash(ntlmssp_state->password, nt_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);
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); } else {
E_deshash(ntlmssp_state->password, lm_hash);
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);
session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); if (!ntlmssp_state->use_nt_response) {
if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) session_key = lm_session_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); /* LM Key is incompatible... */
dump_data_pw("NT session key:\n", session_key.data, session_key.length); 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;

View File

@@ -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;

View File

@@ -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
} }