On Wed, 29 Sep 2010 09:39:04 -0500
[email protected] wrote:
> From: Shirish Pargaonkar <[email protected]>
>
>
> 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 <[email protected]>
> ---
> fs/cifs/cifsencrypt.c | 83 ++++++++++++++++++++++++++++++++++++++++++------
> 1 files changed, 72 insertions(+), 11 deletions(-)
>
> diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
> index 730038a..7ca9c80 100644
> --- a/fs/cifs/cifsencrypt.c
> +++ b/fs/cifs/cifsencrypt.c
> @@ -263,27 +263,88 @@ 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)
> + dlen = strlen(ses->domainName);
> + else {
> + dlen = strlen(defdmname);
> + ses->domainName = kmalloc(dlen + 1, GFP_KERNEL);
> + if (!ses->domainName)
> + return -ENOMEM;
> + strcpy(ses->domainName, defdmname);
> + }
> +
> + wlen = strlen(ses->server->hostname);
> +
> + ses->tilen = size + 2 * (2 * dlen) + 2 * (2 * wlen) + 8;
^^^^
A comment explaining the above calculation would be nice.
> 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);
> + if (ses->domainName)
> + cifs_strtoUCS((__le16 *)blobptr, ses->domainName, dlen, nls_cp);
> + else
> + cifs_strtoUCS((__le16 *)blobptr, defdmname, 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;
> +
> + 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);
> + if (ses->domainName)
> + cifs_strtoUCS((__le16 *)blobptr, ses->domainName, dlen, nls_cp);
> + else
> + cifs_strtoUCS((__le16 *)blobptr, defdmname, 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 +487,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;
The rest looks reasonable.
--
Jeff Layton <[email protected]>
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html