@@ -532,17 +532,67 @@ CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash, struct shash_
532
532
return rc ;
533
533
}
534
534
535
+ /*
536
+ * Set up NTLMv2 response blob with SPN (cifs/<hostname>) appended to the
537
+ * existing list of AV pairs.
538
+ */
539
+ static int set_auth_key_response (struct cifs_ses * ses )
540
+ {
541
+ size_t baselen = CIFS_SESS_KEY_SIZE + sizeof (struct ntlmv2_resp );
542
+ size_t len , spnlen , tilen = 0 , num_avs = 2 /* SPN + EOL */ ;
543
+ struct TCP_Server_Info * server = ses -> server ;
544
+ char * spn __free (kfree ) = NULL ;
545
+ struct ntlmssp2_name * av ;
546
+ char * rsp = NULL ;
547
+ int rc ;
548
+
549
+ spnlen = strlen (server -> hostname );
550
+ len = sizeof ("cifs/" ) + spnlen ;
551
+ spn = kmalloc (len , GFP_KERNEL );
552
+ if (!spn ) {
553
+ rc = - ENOMEM ;
554
+ goto out ;
555
+ }
556
+
557
+ spnlen = scnprintf (spn , len , "cifs/%.*s" ,
558
+ (int )spnlen , server -> hostname );
559
+
560
+ av_for_each_entry (ses , av )
561
+ tilen += sizeof (* av ) + AV_LEN (av );
562
+
563
+ len = baselen + tilen + spnlen * sizeof (__le16 ) + num_avs * sizeof (* av );
564
+ rsp = kmalloc (len , GFP_KERNEL );
565
+ if (!rsp ) {
566
+ rc = - ENOMEM ;
567
+ goto out ;
568
+ }
569
+
570
+ memcpy (rsp + baselen , ses -> auth_key .response , tilen );
571
+ av = (void * )(rsp + baselen + tilen );
572
+ av -> type = cpu_to_le16 (NTLMSSP_AV_TARGET_NAME );
573
+ av -> length = cpu_to_le16 (spnlen * sizeof (__le16 ));
574
+ cifs_strtoUTF16 ((__le16 * )av -> data , spn , spnlen , ses -> local_nls );
575
+ av = (void * )((__u8 * )av + sizeof (* av ) + AV_LEN (av ));
576
+ av -> type = cpu_to_le16 (NTLMSSP_AV_EOL );
577
+ av -> length = 0 ;
578
+
579
+ rc = 0 ;
580
+ ses -> auth_key .len = len ;
581
+ out :
582
+ ses -> auth_key .response = rsp ;
583
+ return rc ;
584
+ }
585
+
535
586
int
536
587
setup_ntlmv2_rsp (struct cifs_ses * ses , const struct nls_table * nls_cp )
537
588
{
538
589
struct shash_desc * hmacmd5 = NULL ;
539
- int rc ;
540
- int baselen ;
541
- unsigned int tilen ;
590
+ unsigned char * tiblob = NULL ; /* target info blob */
542
591
struct ntlmv2_resp * ntlmv2 ;
543
592
char ntlmv2_hash [16 ];
544
- unsigned char * tiblob = NULL ; /* target info blob */
545
593
__le64 rsp_timestamp ;
594
+ __u64 cc ;
595
+ int rc ;
546
596
547
597
if (nls_cp == NULL ) {
548
598
cifs_dbg (VFS , "%s called with nls_cp==NULL\n" , __func__ );
@@ -588,32 +638,25 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
588
638
* (as Windows 7 does)
589
639
*/
590
640
rsp_timestamp = find_timestamp (ses );
641
+ get_random_bytes (& cc , sizeof (cc ));
591
642
592
- baselen = CIFS_SESS_KEY_SIZE + sizeof (struct ntlmv2_resp );
593
- tilen = ses -> auth_key .len ;
594
- tiblob = ses -> auth_key .response ;
643
+ cifs_server_lock (ses -> server );
595
644
596
- ses -> auth_key .response = kmalloc ( baselen + tilen , GFP_KERNEL ) ;
597
- if (! ses -> auth_key . response ) {
598
- rc = - ENOMEM ;
645
+ tiblob = ses -> auth_key .response ;
646
+ rc = set_auth_key_response ( ses );
647
+ if ( rc ) {
599
648
ses -> auth_key .len = 0 ;
600
- goto setup_ntlmv2_rsp_ret ;
649
+ goto unlock ;
601
650
}
602
- ses -> auth_key .len += baselen ;
603
651
604
652
ntlmv2 = (struct ntlmv2_resp * )
605
653
(ses -> auth_key .response + CIFS_SESS_KEY_SIZE );
606
654
ntlmv2 -> blob_signature = cpu_to_le32 (0x00000101 );
607
655
ntlmv2 -> reserved = 0 ;
608
656
ntlmv2 -> time = rsp_timestamp ;
609
-
610
- get_random_bytes (& ntlmv2 -> client_chal , sizeof (ntlmv2 -> client_chal ));
657
+ ntlmv2 -> client_chal = cc ;
611
658
ntlmv2 -> reserved2 = 0 ;
612
659
613
- memcpy (ses -> auth_key .response + baselen , tiblob , tilen );
614
-
615
- cifs_server_lock (ses -> server );
616
-
617
660
rc = cifs_alloc_hash ("hmac(md5)" , & hmacmd5 );
618
661
if (rc ) {
619
662
cifs_dbg (VFS , "Could not allocate HMAC-MD5, rc=%d\n" , rc );
0 commit comments