On Fri, 10 Dec 2010 15:43:17 -0600 Shirish Pargaonkar <shirishpargaonkar@xxxxxxxxx> wrote: > On Fri, Dec 10, 2010 at 3:13 PM, Jeff Layton <jlayton@xxxxxxxxx> wrote: > > On Fri, 10 Dec 2010 10:30:47 -0600 > > shirishpargaonkar@xxxxxxxxx wrote: > > > >> From: Shirish Pargaonkar <shirishpargaonkar@xxxxxxxxx> > >> > >> > >> 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() and allocate zero'ed buffers > >> to prepare ntlmssp negotiate and authenticat requests. > >> > >> > >> Reported-and-Tested-by: Robbert Kouprie <robbert@xxxxxx> > >> Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@xxxxxxxxx> > >> --- > >> fs/cifs/sess.c | 46 +++++++++++++++++++++++++--------------------- > >> 1 files changed, 25 insertions(+), 21 deletions(-) > >> > >> diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c > >> index 7b01d3f..56e945a 100644 > >> --- a/fs/cifs/sess.c > >> +++ b/fs/cifs/sess.c > >> @@ -425,7 +425,7 @@ static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, > >> > >> /* We do not malloc the blob, it is passed in pbuffer, because > >> it is fixed size, and small, making this approach cleaner */ > >> -static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer, > >> +static void build_ntlmssp_negotiate_blob(char *pbuffer, > >> struct cifsSesInfo *ses) > >> { > >> NEGOTIATE_MESSAGE *sec_blob = (NEGOTIATE_MESSAGE *)pbuffer; > >> @@ -437,7 +437,7 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer, > >> /* BB is NTLMV2 session security format easier to use here? */ > >> flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET | > >> NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | > >> - NTLMSSP_NEGOTIATE_NTLM; > >> + NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC; > >> if (ses->server->secMode & > >> (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { > >> flags |= NTLMSSP_NEGOTIATE_SIGN; > >> @@ -446,7 +446,7 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer, > >> 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.Length = 0; > >> @@ -477,7 +477,7 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, > >> flags = NTLMSSP_NEGOTIATE_56 | > >> NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO | > >> NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | > >> - NTLMSSP_NEGOTIATE_NTLM; > >> + NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC; > >> if (ses->server->secMode & > >> (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) > >> flags |= NTLMSSP_NEGOTIATE_SIGN; > >> @@ -485,7 +485,7 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, > >> flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; > >> > >> tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE); > >> - sec_blob->NegotiateFlags |= cpu_to_le32(flags); > >> + sec_blob->NegotiateFlags = cpu_to_le32(flags); > >> > >> sec_blob->LmChallengeResponse.BufferOffset = > >> cpu_to_le32(sizeof(AUTHENTICATE_MESSAGE)); > >> @@ -544,8 +544,9 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, > >> sec_blob->WorkstationName.MaximumLength = 0; > >> tmp += 2; > >> > >> - if ((ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) && > >> - !calc_seckey(ses)) { > >> + if (((ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) || > >> + (ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_EXTENDED_SEC)) > >> + && !calc_seckey(ses)) { > >> memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE); > >> sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer); > >> sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE); > >> @@ -562,16 +563,6 @@ setup_ntlmv2_ret: > >> *buflen = tmp - pbuffer; > >> 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; > >> -} > > ^^^^^ > > I like that you removed the above function. It was useless indirection. > > > >> #endif > >> > >> int > >> @@ -595,6 +586,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, > >> __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */ > >> u16 blob_len; > >> char *ntlmsspblob = NULL; > >> + char *ntlmsspnblob = NULL; > >> > >> if (ses == NULL) > >> return -EINVAL; > >> @@ -828,16 +820,26 @@ ssetup_ntlmssp_authenticate: > >> capabilities |= CAP_EXTENDED_SECURITY; > >> pSMB->req.Capabilities |= cpu_to_le32(capabilities); > >> if (phase == NtLmNegotiate) { > >> - setup_ntlmssp_neg_req(pSMB, ses); > >> + ntlmsspnblob = kzalloc( > >> + sizeof(struct _NEGOTIATE_MESSAGE), > >> + GFP_KERNEL); > >> + if (!ntlmsspnblob) { > >> + cERROR(1, "Can't allocate NTLMSSPN"); > >> + rc = -ENOMEM; > >> + goto ssetup_exit; > >> + } > >> + build_ntlmssp_negotiate_blob(ntlmsspnblob, ses); > > > > Why did you decide to allocate a new buffer here? Was the SecurityBlob > > not big enough? If not, then I think it would make more sense to just > > memset the existing buffer to 0. > > No the buffer allocated by small_smb_init is sufficient to hold the > ntlmssp negotiate request. I do not need to allocate a new buffer. > And header_assemble memsets that buffer to 0, so no need to redo it again. > > So only ntlmsspblob needs to be kzalloc'ed. > header_assemble does this: memset(temp, 0, 256); /* bigger than MAX_CIFS_HDR_SIZE */ ...is that enough? (I haven't measured it). > > > >> iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE); > >> - iov[1].iov_base = &pSMB->req.SecurityBlob[0]; > >> + iov[1].iov_base = ntlmsspnblob; > >> + pSMB->req.SecurityBlobLength = > >> + cpu_to_le16(sizeof(NEGOTIATE_MESSAGE)); > >> } else if (phase == NtLmAuthenticate) { > >> - /* 5 is an empirical value, large enought to > >> + /* 5 is an empirical value, large enough to > >> * hold authenticate message, max 10 of > >> * av paris, doamin,user,workstation mames, > >> * flags etc.. > >> */ > >> - ntlmsspblob = kmalloc( > >> + ntlmsspblob = kzalloc( > >> 5*sizeof(struct _AUTHENTICATE_MESSAGE), > >> GFP_KERNEL); > >> if (!ntlmsspblob) { > >> @@ -960,6 +962,8 @@ ssetup_exit: > >> key_put(spnego_key); > >> } > >> kfree(str_area); > >> + kfree(ntlmsspnblob); > >> + ntlmsspnblob = NULL; > > > > If we did decide that we needed a new buffer for this, I don't think we > > need a new pointer on the stack for it. ntlmsspblob would suffice in > > that case. > > > >> kfree(ntlmsspblob); > >> ntlmsspblob = NULL; > >> if (resp_buf_type == CIFS_SMALL_BUFFER) { > > > > -- > > Jeff Layton <jlayton@xxxxxxxxx> > > > -- > To unsubscribe from this list: send the line "unsubscribe linux-cifs" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- Jeff Layton <jlayton@xxxxxxxxx> -- To unsubscribe from this list: send the line "unsubscribe linux-cifs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html