aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/sess.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/sess.c')
-rw-r--r--fs/cifs/sess.c132
1 files changed, 34 insertions, 98 deletions
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index 795095f4eac6..0a57cb7db5dd 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -383,9 +383,6 @@ static int decode_ascii_ssetup(char **pbcc_area, int bleft,
383static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, 383static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
384 struct cifsSesInfo *ses) 384 struct cifsSesInfo *ses)
385{ 385{
386 unsigned int tioffset; /* challeng message target info area */
387 unsigned int tilen; /* challeng message target info area length */
388
389 CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr; 386 CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr;
390 387
391 if (blob_len < sizeof(CHALLENGE_MESSAGE)) { 388 if (blob_len < sizeof(CHALLENGE_MESSAGE)) {
@@ -408,20 +405,6 @@ static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
408 /* BB spec says that if AvId field of MsvAvTimestamp is populated then 405 /* BB spec says that if AvId field of MsvAvTimestamp is populated then
409 we must set the MIC field of the AUTHENTICATE_MESSAGE */ 406 we must set the MIC field of the AUTHENTICATE_MESSAGE */
410 407
411 ses->server->ntlmssp.server_flags = le32_to_cpu(pblob->NegotiateFlags);
412
413 tioffset = cpu_to_le16(pblob->TargetInfoArray.BufferOffset);
414 tilen = cpu_to_le16(pblob->TargetInfoArray.Length);
415 ses->server->tilen = tilen;
416 if (tilen) {
417 ses->server->tiblob = kmalloc(tilen, GFP_KERNEL);
418 if (!ses->server->tiblob) {
419 cERROR(1, "Challenge target info allocation failure");
420 return -ENOMEM;
421 }
422 memcpy(ses->server->tiblob, bcc_ptr + tioffset, tilen);
423 }
424
425 return 0; 408 return 0;
426} 409}
427 410
@@ -442,13 +425,12 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
442 /* BB is NTLMV2 session security format easier to use here? */ 425 /* BB is NTLMV2 session security format easier to use here? */
443 flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET | 426 flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET |
444 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | 427 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
445 NTLMSSP_NEGOTIATE_NTLM; 428 NTLMSSP_NEGOTIATE_NT_ONLY | NTLMSSP_NEGOTIATE_NTLM;
446 if (ses->server->secMode & 429 if (ses->server->secMode &
447 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { 430 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
448 flags |= NTLMSSP_NEGOTIATE_SIGN | 431 flags |= NTLMSSP_NEGOTIATE_SIGN;
449 NTLMSSP_NEGOTIATE_KEY_XCH | 432 if (ses->server->secMode & SECMODE_SIGN_REQUIRED)
450 NTLMSSP_NEGOTIATE_EXTENDED_SEC; 433 flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
451 }
452 434
453 sec_blob->NegotiateFlags |= cpu_to_le32(flags); 435 sec_blob->NegotiateFlags |= cpu_to_le32(flags);
454 436
@@ -469,12 +451,10 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
469 struct cifsSesInfo *ses, 451 struct cifsSesInfo *ses,
470 const struct nls_table *nls_cp, bool first) 452 const struct nls_table *nls_cp, bool first)
471{ 453{
472 int rc;
473 unsigned int size;
474 AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer; 454 AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer;
475 __u32 flags; 455 __u32 flags;
476 unsigned char *tmp; 456 unsigned char *tmp;
477 struct ntlmv2_resp ntlmv2_response = {}; 457 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
478 458
479 memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8); 459 memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
480 sec_blob->MessageType = NtLmAuthenticate; 460 sec_blob->MessageType = NtLmAuthenticate;
@@ -497,25 +477,19 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
497 sec_blob->LmChallengeResponse.Length = 0; 477 sec_blob->LmChallengeResponse.Length = 0;
498 sec_blob->LmChallengeResponse.MaximumLength = 0; 478 sec_blob->LmChallengeResponse.MaximumLength = 0;
499 479
500 sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer); 480 /* calculate session key, BB what about adding similar ntlmv2 path? */
501 rc = setup_ntlmv2_rsp(ses, (char *)&ntlmv2_response, nls_cp); 481 SMBNTencrypt(ses->password, ses->server->cryptKey, ntlm_session_key);
502 if (rc) { 482 if (first)
503 cERROR(1, "error rc: %d during ntlmssp ntlmv2 setup", rc); 483 cifs_calculate_mac_key(&ses->server->mac_signing_key,
504 goto setup_ntlmv2_ret; 484 ntlm_session_key, ses->password);
505 }
506 size = sizeof(struct ntlmv2_resp);
507 memcpy(tmp, (char *)&ntlmv2_response, size);
508 tmp += size;
509 if (ses->server->tilen > 0) {
510 memcpy(tmp, ses->server->tiblob, ses->server->tilen);
511 tmp += ses->server->tilen;
512 } else
513 ses->server->tilen = 0;
514 485
515 sec_blob->NtChallengeResponse.Length = cpu_to_le16(size + 486 memcpy(tmp, ntlm_session_key, CIFS_SESS_KEY_SIZE);
516 ses->server->tilen); 487 sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer);
488 sec_blob->NtChallengeResponse.Length = cpu_to_le16(CIFS_SESS_KEY_SIZE);
517 sec_blob->NtChallengeResponse.MaximumLength = 489 sec_blob->NtChallengeResponse.MaximumLength =
518 cpu_to_le16(size + ses->server->tilen); 490 cpu_to_le16(CIFS_SESS_KEY_SIZE);
491
492 tmp += CIFS_SESS_KEY_SIZE;
519 493
520 if (ses->domainName == NULL) { 494 if (ses->domainName == NULL) {
521 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer); 495 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
@@ -527,6 +501,7 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
527 len = cifs_strtoUCS((__le16 *)tmp, ses->domainName, 501 len = cifs_strtoUCS((__le16 *)tmp, ses->domainName,
528 MAX_USERNAME_SIZE, nls_cp); 502 MAX_USERNAME_SIZE, nls_cp);
529 len *= 2; /* unicode is 2 bytes each */ 503 len *= 2; /* unicode is 2 bytes each */
504 len += 2; /* trailing null */
530 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer); 505 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
531 sec_blob->DomainName.Length = cpu_to_le16(len); 506 sec_blob->DomainName.Length = cpu_to_le16(len);
532 sec_blob->DomainName.MaximumLength = cpu_to_le16(len); 507 sec_blob->DomainName.MaximumLength = cpu_to_le16(len);
@@ -543,6 +518,7 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
543 len = cifs_strtoUCS((__le16 *)tmp, ses->userName, 518 len = cifs_strtoUCS((__le16 *)tmp, ses->userName,
544 MAX_USERNAME_SIZE, nls_cp); 519 MAX_USERNAME_SIZE, nls_cp);
545 len *= 2; /* unicode is 2 bytes each */ 520 len *= 2; /* unicode is 2 bytes each */
521 len += 2; /* trailing null */
546 sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer); 522 sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
547 sec_blob->UserName.Length = cpu_to_le16(len); 523 sec_blob->UserName.Length = cpu_to_le16(len);
548 sec_blob->UserName.MaximumLength = cpu_to_le16(len); 524 sec_blob->UserName.MaximumLength = cpu_to_le16(len);
@@ -554,26 +530,9 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
554 sec_blob->WorkstationName.MaximumLength = 0; 530 sec_blob->WorkstationName.MaximumLength = 0;
555 tmp += 2; 531 tmp += 2;
556 532
557 if ((ses->server->ntlmssp.server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) && 533 sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
558 !calc_seckey(ses->server)) { 534 sec_blob->SessionKey.Length = 0;
559 memcpy(tmp, ses->server->ntlmssp.ciphertext, CIFS_CPHTXT_SIZE); 535 sec_blob->SessionKey.MaximumLength = 0;
560 sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
561 sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE);
562 sec_blob->SessionKey.MaximumLength =
563 cpu_to_le16(CIFS_CPHTXT_SIZE);
564 tmp += CIFS_CPHTXT_SIZE;
565 } else {
566 sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
567 sec_blob->SessionKey.Length = 0;
568 sec_blob->SessionKey.MaximumLength = 0;
569 }
570
571 ses->server->sequence_number = 0;
572
573setup_ntlmv2_ret:
574 if (ses->server->tilen > 0)
575 kfree(ses->server->tiblob);
576
577 return tmp - pbuffer; 536 return tmp - pbuffer;
578} 537}
579 538
@@ -587,14 +546,15 @@ static void setup_ntlmssp_neg_req(SESSION_SETUP_ANDX *pSMB,
587 return; 546 return;
588} 547}
589 548
590static int setup_ntlmssp_auth_req(char *ntlmsspblob, 549static int setup_ntlmssp_auth_req(SESSION_SETUP_ANDX *pSMB,
591 struct cifsSesInfo *ses, 550 struct cifsSesInfo *ses,
592 const struct nls_table *nls, bool first_time) 551 const struct nls_table *nls, bool first_time)
593{ 552{
594 int bloblen; 553 int bloblen;
595 554
596 bloblen = build_ntlmssp_auth_blob(ntlmsspblob, ses, nls, 555 bloblen = build_ntlmssp_auth_blob(&pSMB->req.SecurityBlob[0], ses, nls,
597 first_time); 556 first_time);
557 pSMB->req.SecurityBlobLength = cpu_to_le16(bloblen);
598 558
599 return bloblen; 559 return bloblen;
600} 560}
@@ -730,7 +690,7 @@ ssetup_ntlmssp_authenticate:
730 690
731 if (first_time) /* should this be moved into common code 691 if (first_time) /* should this be moved into common code
732 with similar ntlmv2 path? */ 692 with similar ntlmv2 path? */
733 cifs_calculate_session_key(&ses->server->session_key, 693 cifs_calculate_mac_key(&ses->server->mac_signing_key,
734 ntlm_session_key, ses->password); 694 ntlm_session_key, ses->password);
735 /* copy session key */ 695 /* copy session key */
736 696
@@ -769,21 +729,12 @@ ssetup_ntlmssp_authenticate:
769 cpu_to_le16(sizeof(struct ntlmv2_resp)); 729 cpu_to_le16(sizeof(struct ntlmv2_resp));
770 730
771 /* calculate session key */ 731 /* calculate session key */
772 rc = setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp); 732 setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp);
773 if (rc) {
774 kfree(v2_sess_key);
775 goto ssetup_exit;
776 }
777 /* FIXME: calculate MAC key */ 733 /* FIXME: calculate MAC key */
778 memcpy(bcc_ptr, (char *)v2_sess_key, 734 memcpy(bcc_ptr, (char *)v2_sess_key,
779 sizeof(struct ntlmv2_resp)); 735 sizeof(struct ntlmv2_resp));
780 bcc_ptr += sizeof(struct ntlmv2_resp); 736 bcc_ptr += sizeof(struct ntlmv2_resp);
781 kfree(v2_sess_key); 737 kfree(v2_sess_key);
782 if (ses->server->tilen > 0) {
783 memcpy(bcc_ptr, ses->server->tiblob,
784 ses->server->tilen);
785 bcc_ptr += ses->server->tilen;
786 }
787 if (ses->capabilities & CAP_UNICODE) { 738 if (ses->capabilities & CAP_UNICODE) {
788 if (iov[0].iov_len % 2) { 739 if (iov[0].iov_len % 2) {
789 *bcc_ptr = 0; 740 *bcc_ptr = 0;
@@ -814,15 +765,15 @@ ssetup_ntlmssp_authenticate:
814 } 765 }
815 /* bail out if key is too long */ 766 /* bail out if key is too long */
816 if (msg->sesskey_len > 767 if (msg->sesskey_len >
817 sizeof(ses->server->session_key.data.krb5)) { 768 sizeof(ses->server->mac_signing_key.data.krb5)) {
818 cERROR(1, "Kerberos signing key too long (%u bytes)", 769 cERROR(1, "Kerberos signing key too long (%u bytes)",
819 msg->sesskey_len); 770 msg->sesskey_len);
820 rc = -EOVERFLOW; 771 rc = -EOVERFLOW;
821 goto ssetup_exit; 772 goto ssetup_exit;
822 } 773 }
823 if (first_time) { 774 if (first_time) {
824 ses->server->session_key.len = msg->sesskey_len; 775 ses->server->mac_signing_key.len = msg->sesskey_len;
825 memcpy(ses->server->session_key.data.krb5, 776 memcpy(ses->server->mac_signing_key.data.krb5,
826 msg->data, msg->sesskey_len); 777 msg->data, msg->sesskey_len);
827 } 778 }
828 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; 779 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
@@ -864,28 +815,12 @@ ssetup_ntlmssp_authenticate:
864 if (phase == NtLmNegotiate) { 815 if (phase == NtLmNegotiate) {
865 setup_ntlmssp_neg_req(pSMB, ses); 816 setup_ntlmssp_neg_req(pSMB, ses);
866 iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE); 817 iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE);
867 iov[1].iov_base = &pSMB->req.SecurityBlob[0];
868 } else if (phase == NtLmAuthenticate) { 818 } else if (phase == NtLmAuthenticate) {
869 int blob_len; 819 int blob_len;
870 char *ntlmsspblob; 820 blob_len = setup_ntlmssp_auth_req(pSMB, ses,
871 821 nls_cp,
872 ntlmsspblob = kmalloc(5 * 822 first_time);
873 sizeof(struct _AUTHENTICATE_MESSAGE),
874 GFP_KERNEL);
875 if (!ntlmsspblob) {
876 cERROR(1, "Can't allocate NTLMSSP");
877 rc = -ENOMEM;
878 goto ssetup_exit;
879 }
880
881 blob_len = setup_ntlmssp_auth_req(ntlmsspblob,
882 ses,
883 nls_cp,
884 first_time);
885 iov[1].iov_len = blob_len; 823 iov[1].iov_len = blob_len;
886 iov[1].iov_base = ntlmsspblob;
887 pSMB->req.SecurityBlobLength =
888 cpu_to_le16(blob_len);
889 /* Make sure that we tell the server that we 824 /* Make sure that we tell the server that we
890 are using the uid that it just gave us back 825 are using the uid that it just gave us back
891 on the response (challenge) */ 826 on the response (challenge) */
@@ -895,6 +830,7 @@ ssetup_ntlmssp_authenticate:
895 rc = -ENOSYS; 830 rc = -ENOSYS;
896 goto ssetup_exit; 831 goto ssetup_exit;
897 } 832 }
833 iov[1].iov_base = &pSMB->req.SecurityBlob[0];
898 /* unicode strings must be word aligned */ 834 /* unicode strings must be word aligned */
899 if ((iov[0].iov_len + iov[1].iov_len) % 2) { 835 if ((iov[0].iov_len + iov[1].iov_len) % 2) {
900 *bcc_ptr = 0; 836 *bcc_ptr = 0;