Re: [PATCH 2/7 cifs] ntlm authentication and signing - Build a proper av/ti pair blob for ntlmv2 without extended security authentication

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, 9 Oct 2010 15:10:38 -0500
Shirish Pargaonkar <shirishpargaonkar@xxxxxxxxx> wrote:

> On Sat, Oct 9, 2010 at 3:02 PM, Jeff Layton <jlayton@xxxxxxxxxx> wrote:
> > On Thu,  7 Oct 2010 07:45:28 -0500
> > shirishpargaonkar@xxxxxxxxx wrote:
> >
> >> From: Shirish Pargaonkar <shirishpargaonkar@xxxxxxxxx>
> >>
> >> Build a av pair blob as part of ntlmv2 (without extended security) auth
> >> request.  Include netbios and dns names for domain and server and
> >> a timestamp in the blob.
> >>
> >>
> >> Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@xxxxxxxxx>
> >> ---
> >>  fs/cifs/cifsencrypt.c |   77 ++++++++++++++++++++++++++++++++++++++++++-------
> >>  1 files changed, 66 insertions(+), 11 deletions(-)
> >>
> >> diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
> >> index 730038a..6a1e50c 100644
> >> --- a/fs/cifs/cifsencrypt.c
> >> +++ b/fs/cifs/cifsencrypt.c
> >> @@ -263,27 +263,82 @@ void calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
> >>  }
> >>  #endif /* CIFS_WEAK_PW_HASH */
> >>
> >> -/* This is just a filler for ntlmv2 type of security mechanisms.
> >> - * Older servers are not very particular about the contents of av pairs
> >> - * in the blob and for sec mechs like ntlmv2, there is no negotiation
> >> - * as in ntlmssp, so unless domain and server  netbios and dns names
> >> - * are specified, there is no way to obtain name.  In case of ntlmssp,
> >> - * server provides that info in type 2 challenge packet
> >> +/* Build a proper attribute value/target info pairs blob.
> >> + * Fill in netbios and dns domain name and workstation name
> >> + * and client time (total five av pairs and + one end of fields indicator.
> >> + * Allocate domain name which gets freed when session struct is deallocated.
> >>   */
> >>  static int
> >> -build_avpair_blob(struct cifsSesInfo *ses)
> >> +build_avpair_blob(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
> >>  {
> >> +     unsigned int dlen;
> >> +     unsigned int wlen;
> >> +     unsigned int size = 6 * sizeof(struct ntlmssp2_name);
> >> +     __le64  curtime;
> >> +     char *defdmname = "WORKGROUP";
> >> +     unsigned char *blobptr;
> >>       struct ntlmssp2_name *attrptr;
> >>
> >> -     ses->tilen = 2 * sizeof(struct ntlmssp2_name);
> >> +     if (!ses->domainName)
> >> +             ses->domainName = kstrdup(defdmname, GFP_KERNEL);
> >> +
> >        ^^^^
> > kstrdup can return NULL if memory can't be allocated. I think you need
> > to check for that here.
> 
> yes, will make/add the change/check.
> 
> >
> >> +     dlen = strlen(ses->domainName);
> >> +     wlen = strlen(ses->server->hostname);
> >> +
> >> +     /* The length of this blob is a size which is
> >> +      * six times the size of a structure which holds name/size +
> >> +      * two times the unicode length of a domain name +
> >> +      * two times the unicode length of a server name +
> >> +      * size of a timestamp (which is 8 bytes).
> >> +      */
> >> +     ses->tilen = size + 2 * (2 * dlen) + 2 * (2 * wlen) + 8;
> >>       ses->tiblob = kzalloc(ses->tilen, GFP_KERNEL);
> >>       if (!ses->tiblob) {
> >>               ses->tilen = 0;
> >>               cERROR(1, "Challenge target info allocation failure");
> >>               return -ENOMEM;
> >>       }
> >> -     attrptr = (struct ntlmssp2_name *) ses->tiblob;
> >> -     attrptr->type = cpu_to_le16(NTLMSSP_DOMAIN_TYPE);
> >> +
> >> +     blobptr = ses->tiblob;
> >> +     attrptr = (struct ntlmssp2_name *) blobptr;
> >> +
> >> +     attrptr->type = cpu_to_le16(NTLMSSP_AV_NB_DOMAIN_NAME);
> >> +     attrptr->length = cpu_to_le16(2 * dlen);
> >> +     blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
> >> +     cifs_strtoUCS((__le16 *)blobptr, ses->domainName, dlen, nls_cp);
> >> +
> >> +     blobptr += 2 * dlen;
> >> +     attrptr = (struct ntlmssp2_name *) blobptr;
> >> +
> >> +     attrptr->type = cpu_to_le16(NTLMSSP_AV_NB_COMPUTER_NAME);
> >> +     attrptr->length = cpu_to_le16(2 * wlen);
> >> +     blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
> >> +     cifs_strtoUCS((__le16 *)blobptr, ses->server->hostname, wlen, nls_cp);
> >> +
> >> +     blobptr += 2 * wlen;
> >> +     attrptr = (struct ntlmssp2_name *) blobptr;
> >> +
> >
> >        ^^^^^^^^^^
> > Seems odd that we populate the NB and DNS AV pairs with the same
> > values. Are you sure that's correct? I haven't read the spec as closely
> > as you probably have, but intuitively I'd expect the NB name to be a
> > shortname and the DNS name to be a FQDN....
> 
> yes, but how do we obtain them?  In case of NTLMSSP, the server itself
> provides them in type 2 messge but in case of NTLMv2 auth, how does
> a client come up with them unless already supplied?
> 

I suppose you could just use the stuff before the first '.' for the NB
name...

But that said, I'm in favor of going with whatever works here. If it
works like this, I don't think you should worry about it too much until
someone finds that it doesn't.

> >
> >> +     attrptr->type = cpu_to_le16(NTLMSSP_AV_DNS_DOMAIN_NAME);
> >> +     attrptr->length = cpu_to_le16(2 * dlen);
> >> +     blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
> >> +     cifs_strtoUCS((__le16 *)blobptr, ses->domainName, dlen, nls_cp);
> >> +
> >> +     blobptr += 2 * dlen;
> >> +     attrptr = (struct ntlmssp2_name *) blobptr;
> >> +
> >> +     attrptr->type = cpu_to_le16(NTLMSSP_AV_DNS_COMPUTER_NAME);
> >> +     attrptr->length = cpu_to_le16(2 * wlen);
> >> +     blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
> >> +     cifs_strtoUCS((__le16 *)blobptr, ses->server->hostname, wlen, nls_cp);
> >> +
> >> +     blobptr += 2 * wlen;
> >> +     attrptr = (struct ntlmssp2_name *) blobptr;
> >> +
> >> +     attrptr->type = cpu_to_le16(NTLMSSP_AV_TIMESTAMP);
> >> +     attrptr->length = cpu_to_le16(sizeof(__le64));
> >> +     blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
> >> +     curtime = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
> >> +     memcpy(blobptr, &curtime, sizeof(__le64));
> >>
> >>       return 0;
> >>  }
> >> @@ -426,7 +481,7 @@ setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf,
> >>                       }
> >>               }
> >>       } else {
> >> -             rc = build_avpair_blob(ses);
> >> +             rc = build_avpair_blob(ses, nls_cp);
> >>               if (rc) {
> >>                       cERROR(1, "error %d building av pair blob", rc);
> >>                       return rc;
> >
> >
> --
> 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@xxxxxxxxxx>
--
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


[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux