aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShirish Pargaonkar <shirishpargaonkar@gmail.com>2010-10-10 14:21:05 -0400
committerSteve French <sfrench@us.ibm.com>2010-10-12 11:14:06 -0400
commit9daa42e22030f0c5c357a5e1f8af658411beda6b (patch)
tree35517e93c8dc79903ed08b86cba8c31b85fb2ca3
parent0dd12c21951e085357046b68c3a108273062d2aa (diff)
CIFS ntlm authentication and signing - Build a proper av/ti pair blob for ntlmv2 without extended security authentication
Build an 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@gmail.com> Reviewed-by: Jeff Layton <jlayton@samba.org> Signed-off-by: Steve French <sfrench@us.ibm.com>
-rw-r--r--fs/cifs/cifsencrypt.c80
1 files changed, 69 insertions, 11 deletions
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index 89fb94fac4b5..e3edd8a6840b 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -263,27 +263,85 @@ void calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
263} 263}
264#endif /* CIFS_WEAK_PW_HASH */ 264#endif /* CIFS_WEAK_PW_HASH */
265 265
266/* This is just a filler for ntlmv2 type of security mechanisms. 266/* Build a proper attribute value/target info pairs blob.
267 * Older servers are not very particular about the contents of av pairs 267 * Fill in netbios and dns domain name and workstation name
268 * in the blob and for sec mechs like ntlmv2, there is no negotiation 268 * and client time (total five av pairs and + one end of fields indicator.
269 * as in ntlmssp, so unless domain and server netbios and dns names 269 * Allocate domain name which gets freed when session struct is deallocated.
270 * are specified, there is no way to obtain name. In case of ntlmssp,
271 * server provides that info in type 2 challenge packet
272 */ 270 */
273static int 271static int
274build_avpair_blob(struct cifsSesInfo *ses) 272build_avpair_blob(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
275{ 273{
274 unsigned int dlen;
275 unsigned int wlen;
276 unsigned int size = 6 * sizeof(struct ntlmssp2_name);
277 __le64 curtime;
278 char *defdmname = "WORKGROUP";
279 unsigned char *blobptr;
276 struct ntlmssp2_name *attrptr; 280 struct ntlmssp2_name *attrptr;
277 281
278 ses->tilen = 2 * sizeof(struct ntlmssp2_name); 282 if (!ses->domainName) {
283 ses->domainName = kstrdup(defdmname, GFP_KERNEL);
284 if (!ses->domainName)
285 return -ENOMEM;
286 }
287
288 dlen = strlen(ses->domainName);
289 wlen = strlen(ses->server->hostname);
290
291 /* The length of this blob is a size which is
292 * six times the size of a structure which holds name/size +
293 * two times the unicode length of a domain name +
294 * two times the unicode length of a server name +
295 * size of a timestamp (which is 8 bytes).
296 */
297 ses->tilen = size + 2 * (2 * dlen) + 2 * (2 * wlen) + 8;
279 ses->tiblob = kzalloc(ses->tilen, GFP_KERNEL); 298 ses->tiblob = kzalloc(ses->tilen, GFP_KERNEL);
280 if (!ses->tiblob) { 299 if (!ses->tiblob) {
281 ses->tilen = 0; 300 ses->tilen = 0;
282 cERROR(1, "Challenge target info allocation failure"); 301 cERROR(1, "Challenge target info allocation failure");
283 return -ENOMEM; 302 return -ENOMEM;
284 } 303 }
285 attrptr = (struct ntlmssp2_name *) ses->tiblob; 304
286 attrptr->type = cpu_to_le16(NTLMSSP_DOMAIN_TYPE); 305 blobptr = ses->tiblob;
306 attrptr = (struct ntlmssp2_name *) blobptr;
307
308 attrptr->type = cpu_to_le16(NTLMSSP_AV_NB_DOMAIN_NAME);
309 attrptr->length = cpu_to_le16(2 * dlen);
310 blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
311 cifs_strtoUCS((__le16 *)blobptr, ses->domainName, dlen, nls_cp);
312
313 blobptr += 2 * dlen;
314 attrptr = (struct ntlmssp2_name *) blobptr;
315
316 attrptr->type = cpu_to_le16(NTLMSSP_AV_NB_COMPUTER_NAME);
317 attrptr->length = cpu_to_le16(2 * wlen);
318 blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
319 cifs_strtoUCS((__le16 *)blobptr, ses->server->hostname, wlen, nls_cp);
320
321 blobptr += 2 * wlen;
322 attrptr = (struct ntlmssp2_name *) blobptr;
323
324 attrptr->type = cpu_to_le16(NTLMSSP_AV_DNS_DOMAIN_NAME);
325 attrptr->length = cpu_to_le16(2 * dlen);
326 blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
327 cifs_strtoUCS((__le16 *)blobptr, ses->domainName, dlen, nls_cp);
328
329 blobptr += 2 * dlen;
330 attrptr = (struct ntlmssp2_name *) blobptr;
331
332 attrptr->type = cpu_to_le16(NTLMSSP_AV_DNS_COMPUTER_NAME);
333 attrptr->length = cpu_to_le16(2 * wlen);
334 blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
335 cifs_strtoUCS((__le16 *)blobptr, ses->server->hostname, wlen, nls_cp);
336
337 blobptr += 2 * wlen;
338 attrptr = (struct ntlmssp2_name *) blobptr;
339
340 attrptr->type = cpu_to_le16(NTLMSSP_AV_TIMESTAMP);
341 attrptr->length = cpu_to_le16(sizeof(__le64));
342 blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
343 curtime = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
344 memcpy(blobptr, &curtime, sizeof(__le64));
287 345
288 return 0; 346 return 0;
289} 347}
@@ -429,7 +487,7 @@ setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf,
429 } 487 }
430 } 488 }
431 } else { 489 } else {
432 rc = build_avpair_blob(ses); 490 rc = build_avpair_blob(ses, nls_cp);
433 if (rc) { 491 if (rc) {
434 cERROR(1, "error %d building av pair blob", rc); 492 cERROR(1, "error %d building av pair blob", rc);
435 return rc; 493 return rc;