Commit df8fbc24 authored by Shirish Pargaonkar's avatar Shirish Pargaonkar Committed by Steve French

cifs: Support NTLM2 session security during NTLMSSP authentication [try #5]

Indicate to the server a capability of NTLM2 session security (NTLM2 Key)
during ntlmssp protocol exchange in one of the bits of the flags field.
If server supports this capability, send NTLM2 key even if signing is not
required on the server.

If the server requires signing, the session keys exchanged for NTLMv2
and NTLM2 session security in auth packet of the nlmssp exchange are same.

Send the same flags in authenticate message (type 3) that client sent in
negotiate message (type 1).

Remove function setup_ntlmssp_neg_req

Make sure ntlmssp negotiate and authenticate messages are zero'ed
before they are built.
Reported-and-Tested-by: default avatarRobbert Kouprie <robbert@exx.nl>
Signed-off-by: default avatarShirish Pargaonkar <shirishpargaonkar@gmail.com>
Acked-by: default avatarJeff Layton <jlayton@redhat.com>
Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
parent 262f86ad
...@@ -431,13 +431,14 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer, ...@@ -431,13 +431,14 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
NEGOTIATE_MESSAGE *sec_blob = (NEGOTIATE_MESSAGE *)pbuffer; NEGOTIATE_MESSAGE *sec_blob = (NEGOTIATE_MESSAGE *)pbuffer;
__u32 flags; __u32 flags;
memset(pbuffer, 0, sizeof(NEGOTIATE_MESSAGE));
memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8); memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
sec_blob->MessageType = NtLmNegotiate; sec_blob->MessageType = NtLmNegotiate;
/* BB is NTLMV2 session security format easier to use here? */ /* BB is NTLMV2 session security format easier to use here? */
flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET | flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET |
NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
NTLMSSP_NEGOTIATE_NTLM; NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
if (ses->server->secMode & if (ses->server->secMode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
flags |= NTLMSSP_NEGOTIATE_SIGN; flags |= NTLMSSP_NEGOTIATE_SIGN;
...@@ -446,7 +447,7 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer, ...@@ -446,7 +447,7 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
NTLMSSP_NEGOTIATE_EXTENDED_SEC; NTLMSSP_NEGOTIATE_EXTENDED_SEC;
} }
sec_blob->NegotiateFlags |= cpu_to_le32(flags); sec_blob->NegotiateFlags = cpu_to_le32(flags);
sec_blob->WorkstationName.BufferOffset = 0; sec_blob->WorkstationName.BufferOffset = 0;
sec_blob->WorkstationName.Length = 0; sec_blob->WorkstationName.Length = 0;
...@@ -477,7 +478,7 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, ...@@ -477,7 +478,7 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
flags = NTLMSSP_NEGOTIATE_56 | flags = NTLMSSP_NEGOTIATE_56 |
NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO | NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO |
NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
NTLMSSP_NEGOTIATE_NTLM; NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
if (ses->server->secMode & if (ses->server->secMode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
flags |= NTLMSSP_NEGOTIATE_SIGN; flags |= NTLMSSP_NEGOTIATE_SIGN;
...@@ -485,7 +486,7 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, ...@@ -485,7 +486,7 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE); tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE);
sec_blob->NegotiateFlags |= cpu_to_le32(flags); sec_blob->NegotiateFlags = cpu_to_le32(flags);
sec_blob->LmChallengeResponse.BufferOffset = sec_blob->LmChallengeResponse.BufferOffset =
cpu_to_le32(sizeof(AUTHENTICATE_MESSAGE)); cpu_to_le32(sizeof(AUTHENTICATE_MESSAGE));
...@@ -544,8 +545,9 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, ...@@ -544,8 +545,9 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
sec_blob->WorkstationName.MaximumLength = 0; sec_blob->WorkstationName.MaximumLength = 0;
tmp += 2; tmp += 2;
if ((ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) && if (((ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) ||
!calc_seckey(ses)) { (ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
&& !calc_seckey(ses)) {
memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE); memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer); sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE); sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE);
...@@ -562,16 +564,6 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, ...@@ -562,16 +564,6 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
*buflen = tmp - pbuffer; *buflen = tmp - pbuffer;
return rc; return rc;
} }
static void setup_ntlmssp_neg_req(SESSION_SETUP_ANDX *pSMB,
struct cifsSesInfo *ses)
{
build_ntlmssp_negotiate_blob(&pSMB->req.SecurityBlob[0], ses);
pSMB->req.SecurityBlobLength = cpu_to_le16(sizeof(NEGOTIATE_MESSAGE));
return;
}
#endif #endif
int int
...@@ -828,16 +820,19 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -828,16 +820,19 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
capabilities |= CAP_EXTENDED_SECURITY; capabilities |= CAP_EXTENDED_SECURITY;
pSMB->req.Capabilities |= cpu_to_le32(capabilities); pSMB->req.Capabilities |= cpu_to_le32(capabilities);
if (phase == NtLmNegotiate) { if (phase == NtLmNegotiate) {
setup_ntlmssp_neg_req(pSMB, ses); build_ntlmssp_negotiate_blob(
pSMB->req.SecurityBlob, ses);
iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE); iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE);
iov[1].iov_base = &pSMB->req.SecurityBlob[0]; iov[1].iov_base = pSMB->req.SecurityBlob;
pSMB->req.SecurityBlobLength =
cpu_to_le16(sizeof(NEGOTIATE_MESSAGE));
} else if (phase == NtLmAuthenticate) { } else if (phase == NtLmAuthenticate) {
/* 5 is an empirical value, large enought to /* 5 is an empirical value, large enought to
* hold authenticate message, max 10 of * hold authenticate message, max 10 of
* av paris, doamin,user,workstation mames, * av paris, doamin,user,workstation mames,
* flags etc.. * flags etc..
*/ */
ntlmsspblob = kmalloc( ntlmsspblob = kzalloc(
5*sizeof(struct _AUTHENTICATE_MESSAGE), 5*sizeof(struct _AUTHENTICATE_MESSAGE),
GFP_KERNEL); GFP_KERNEL);
if (!ntlmsspblob) { if (!ntlmsspblob) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment