diff options
author | Steve French <sfrench@us.ibm.com> | 2010-09-08 17:10:58 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2010-09-08 17:10:58 -0400 |
commit | c8e56f1f4fb9f82f63e4ce6d73a14501d0432c76 (patch) | |
tree | 6d0988317a6eaf4b454c73a1dd95f89184f5b1ed /fs/cifs/sess.c | |
parent | 745e507a9c79c6e1385d3414d5e56f3d4621a375 (diff) |
Revert "[CIFS] Fix ntlmv2 auth with ntlmssp"
This reverts commit 9fbc590860e75785bdaf8b83e48fabfe4d4f7d58.
The change to kernel crypto and fixes to ntlvm2 and ntlmssp
series, introduced a regression. Deferring this patch series
to 2.6.37 after Shirish fixes it.
Signed-off-by: Steve French <sfrench@us.ibm.com>
Acked-by: Jeff Layton <jlayton@redhat.com>
CC: Shirish Pargaonkar <shirishp@us.ibm.com>
Diffstat (limited to 'fs/cifs/sess.c')
-rw-r--r-- | fs/cifs/sess.c | 118 |
1 files changed, 29 insertions, 89 deletions
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index 41fc5328120d..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, | |||
383 | static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, | 383 | static 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,18 +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 | tioffset = cpu_to_le16(pblob->TargetInfoArray.BufferOffset); | ||
412 | tilen = cpu_to_le16(pblob->TargetInfoArray.Length); | ||
413 | ses->server->tilen = tilen; | ||
414 | if (tilen) { | ||
415 | ses->server->tiblob = kmalloc(tilen, GFP_KERNEL); | ||
416 | if (!ses->server->tiblob) { | ||
417 | cERROR(1, "Challenge target info allocation failure"); | ||
418 | return -ENOMEM; | ||
419 | } | ||
420 | memcpy(ses->server->tiblob, bcc_ptr + tioffset, tilen); | ||
421 | } | ||
422 | |||
423 | return 0; | 408 | return 0; |
424 | } | 409 | } |
425 | 410 | ||
@@ -466,12 +451,10 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, | |||
466 | struct cifsSesInfo *ses, | 451 | struct cifsSesInfo *ses, |
467 | const struct nls_table *nls_cp, bool first) | 452 | const struct nls_table *nls_cp, bool first) |
468 | { | 453 | { |
469 | int rc; | ||
470 | unsigned int size; | ||
471 | AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer; | 454 | AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer; |
472 | __u32 flags; | 455 | __u32 flags; |
473 | unsigned char *tmp; | 456 | unsigned char *tmp; |
474 | struct ntlmv2_resp ntlmv2_response = {}; | 457 | char ntlm_session_key[CIFS_SESS_KEY_SIZE]; |
475 | 458 | ||
476 | memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8); | 459 | memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8); |
477 | sec_blob->MessageType = NtLmAuthenticate; | 460 | sec_blob->MessageType = NtLmAuthenticate; |
@@ -494,25 +477,19 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, | |||
494 | sec_blob->LmChallengeResponse.Length = 0; | 477 | sec_blob->LmChallengeResponse.Length = 0; |
495 | sec_blob->LmChallengeResponse.MaximumLength = 0; | 478 | sec_blob->LmChallengeResponse.MaximumLength = 0; |
496 | 479 | ||
497 | sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer); | 480 | /* calculate session key, BB what about adding similar ntlmv2 path? */ |
498 | rc = setup_ntlmv2_rsp(ses, (char *)&ntlmv2_response, nls_cp); | 481 | SMBNTencrypt(ses->password, ses->server->cryptKey, ntlm_session_key); |
499 | if (rc) { | 482 | if (first) |
500 | cERROR(1, "error rc: %d during ntlmssp ntlmv2 setup", rc); | 483 | cifs_calculate_mac_key(&ses->server->mac_signing_key, |
501 | goto setup_ntlmv2_ret; | 484 | ntlm_session_key, ses->password); |
502 | } | ||
503 | size = sizeof(struct ntlmv2_resp); | ||
504 | memcpy(tmp, (char *)&ntlmv2_response, size); | ||
505 | tmp += size; | ||
506 | if (ses->server->tilen > 0) { | ||
507 | memcpy(tmp, ses->server->tiblob, ses->server->tilen); | ||
508 | tmp += ses->server->tilen; | ||
509 | } else | ||
510 | ses->server->tilen = 0; | ||
511 | 485 | ||
512 | sec_blob->NtChallengeResponse.Length = cpu_to_le16(size + | 486 | memcpy(tmp, ntlm_session_key, CIFS_SESS_KEY_SIZE); |
513 | 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); | ||
514 | sec_blob->NtChallengeResponse.MaximumLength = | 489 | sec_blob->NtChallengeResponse.MaximumLength = |
515 | cpu_to_le16(size + ses->server->tilen); | 490 | cpu_to_le16(CIFS_SESS_KEY_SIZE); |
491 | |||
492 | tmp += CIFS_SESS_KEY_SIZE; | ||
516 | 493 | ||
517 | if (ses->domainName == NULL) { | 494 | if (ses->domainName == NULL) { |
518 | sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer); | 495 | sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer); |
@@ -524,6 +501,7 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, | |||
524 | len = cifs_strtoUCS((__le16 *)tmp, ses->domainName, | 501 | len = cifs_strtoUCS((__le16 *)tmp, ses->domainName, |
525 | MAX_USERNAME_SIZE, nls_cp); | 502 | MAX_USERNAME_SIZE, nls_cp); |
526 | len *= 2; /* unicode is 2 bytes each */ | 503 | len *= 2; /* unicode is 2 bytes each */ |
504 | len += 2; /* trailing null */ | ||
527 | sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer); | 505 | sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer); |
528 | sec_blob->DomainName.Length = cpu_to_le16(len); | 506 | sec_blob->DomainName.Length = cpu_to_le16(len); |
529 | sec_blob->DomainName.MaximumLength = cpu_to_le16(len); | 507 | sec_blob->DomainName.MaximumLength = cpu_to_le16(len); |
@@ -540,6 +518,7 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, | |||
540 | len = cifs_strtoUCS((__le16 *)tmp, ses->userName, | 518 | len = cifs_strtoUCS((__le16 *)tmp, ses->userName, |
541 | MAX_USERNAME_SIZE, nls_cp); | 519 | MAX_USERNAME_SIZE, nls_cp); |
542 | len *= 2; /* unicode is 2 bytes each */ | 520 | len *= 2; /* unicode is 2 bytes each */ |
521 | len += 2; /* trailing null */ | ||
543 | sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer); | 522 | sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer); |
544 | sec_blob->UserName.Length = cpu_to_le16(len); | 523 | sec_blob->UserName.Length = cpu_to_le16(len); |
545 | sec_blob->UserName.MaximumLength = cpu_to_le16(len); | 524 | sec_blob->UserName.MaximumLength = cpu_to_le16(len); |
@@ -551,26 +530,9 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, | |||
551 | sec_blob->WorkstationName.MaximumLength = 0; | 530 | sec_blob->WorkstationName.MaximumLength = 0; |
552 | tmp += 2; | 531 | tmp += 2; |
553 | 532 | ||
554 | if ((ses->server->ntlmssp.server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) && | 533 | sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer); |
555 | !calc_seckey(ses->server)) { | 534 | sec_blob->SessionKey.Length = 0; |
556 | memcpy(tmp, ses->server->ntlmssp.ciphertext, CIFS_CPHTXT_SIZE); | 535 | sec_blob->SessionKey.MaximumLength = 0; |
557 | sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer); | ||
558 | sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE); | ||
559 | sec_blob->SessionKey.MaximumLength = | ||
560 | cpu_to_le16(CIFS_CPHTXT_SIZE); | ||
561 | tmp += CIFS_CPHTXT_SIZE; | ||
562 | } else { | ||
563 | sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer); | ||
564 | sec_blob->SessionKey.Length = 0; | ||
565 | sec_blob->SessionKey.MaximumLength = 0; | ||
566 | } | ||
567 | |||
568 | ses->server->sequence_number = 0; | ||
569 | |||
570 | setup_ntlmv2_ret: | ||
571 | if (ses->server->tilen > 0) | ||
572 | kfree(ses->server->tiblob); | ||
573 | |||
574 | return tmp - pbuffer; | 536 | return tmp - pbuffer; |
575 | } | 537 | } |
576 | 538 | ||
@@ -584,14 +546,15 @@ static void setup_ntlmssp_neg_req(SESSION_SETUP_ANDX *pSMB, | |||
584 | return; | 546 | return; |
585 | } | 547 | } |
586 | 548 | ||
587 | static int setup_ntlmssp_auth_req(char *ntlmsspblob, | 549 | static int setup_ntlmssp_auth_req(SESSION_SETUP_ANDX *pSMB, |
588 | struct cifsSesInfo *ses, | 550 | struct cifsSesInfo *ses, |
589 | const struct nls_table *nls, bool first_time) | 551 | const struct nls_table *nls, bool first_time) |
590 | { | 552 | { |
591 | int bloblen; | 553 | int bloblen; |
592 | 554 | ||
593 | bloblen = build_ntlmssp_auth_blob(ntlmsspblob, ses, nls, | 555 | bloblen = build_ntlmssp_auth_blob(&pSMB->req.SecurityBlob[0], ses, nls, |
594 | first_time); | 556 | first_time); |
557 | pSMB->req.SecurityBlobLength = cpu_to_le16(bloblen); | ||
595 | 558 | ||
596 | return bloblen; | 559 | return bloblen; |
597 | } | 560 | } |
@@ -617,7 +580,6 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
617 | struct key *spnego_key = NULL; | 580 | struct key *spnego_key = NULL; |
618 | __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */ | 581 | __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */ |
619 | bool first_time; | 582 | bool first_time; |
620 | char *ntlmsspblob; | ||
621 | 583 | ||
622 | if (ses == NULL) | 584 | if (ses == NULL) |
623 | return -EINVAL; | 585 | return -EINVAL; |
@@ -728,7 +690,7 @@ ssetup_ntlmssp_authenticate: | |||
728 | 690 | ||
729 | if (first_time) /* should this be moved into common code | 691 | if (first_time) /* should this be moved into common code |
730 | with similar ntlmv2 path? */ | 692 | with similar ntlmv2 path? */ |
731 | cifs_calculate_session_key(&ses->server->session_key, | 693 | cifs_calculate_mac_key(&ses->server->mac_signing_key, |
732 | ntlm_session_key, ses->password); | 694 | ntlm_session_key, ses->password); |
733 | /* copy session key */ | 695 | /* copy session key */ |
734 | 696 | ||
@@ -767,21 +729,12 @@ ssetup_ntlmssp_authenticate: | |||
767 | cpu_to_le16(sizeof(struct ntlmv2_resp)); | 729 | cpu_to_le16(sizeof(struct ntlmv2_resp)); |
768 | 730 | ||
769 | /* calculate session key */ | 731 | /* calculate session key */ |
770 | rc = setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp); | 732 | setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp); |
771 | if (rc) { | ||
772 | kfree(v2_sess_key); | ||
773 | goto ssetup_exit; | ||
774 | } | ||
775 | /* FIXME: calculate MAC key */ | 733 | /* FIXME: calculate MAC key */ |
776 | memcpy(bcc_ptr, (char *)v2_sess_key, | 734 | memcpy(bcc_ptr, (char *)v2_sess_key, |
777 | sizeof(struct ntlmv2_resp)); | 735 | sizeof(struct ntlmv2_resp)); |
778 | bcc_ptr += sizeof(struct ntlmv2_resp); | 736 | bcc_ptr += sizeof(struct ntlmv2_resp); |
779 | kfree(v2_sess_key); | 737 | kfree(v2_sess_key); |
780 | if (ses->server->tilen > 0) { | ||
781 | memcpy(bcc_ptr, ses->server->tiblob, | ||
782 | ses->server->tilen); | ||
783 | bcc_ptr += ses->server->tilen; | ||
784 | } | ||
785 | if (ses->capabilities & CAP_UNICODE) { | 738 | if (ses->capabilities & CAP_UNICODE) { |
786 | if (iov[0].iov_len % 2) { | 739 | if (iov[0].iov_len % 2) { |
787 | *bcc_ptr = 0; | 740 | *bcc_ptr = 0; |
@@ -812,15 +765,15 @@ ssetup_ntlmssp_authenticate: | |||
812 | } | 765 | } |
813 | /* bail out if key is too long */ | 766 | /* bail out if key is too long */ |
814 | if (msg->sesskey_len > | 767 | if (msg->sesskey_len > |
815 | sizeof(ses->server->session_key.data.krb5)) { | 768 | sizeof(ses->server->mac_signing_key.data.krb5)) { |
816 | cERROR(1, "Kerberos signing key too long (%u bytes)", | 769 | cERROR(1, "Kerberos signing key too long (%u bytes)", |
817 | msg->sesskey_len); | 770 | msg->sesskey_len); |
818 | rc = -EOVERFLOW; | 771 | rc = -EOVERFLOW; |
819 | goto ssetup_exit; | 772 | goto ssetup_exit; |
820 | } | 773 | } |
821 | if (first_time) { | 774 | if (first_time) { |
822 | ses->server->session_key.len = msg->sesskey_len; | 775 | ses->server->mac_signing_key.len = msg->sesskey_len; |
823 | memcpy(ses->server->session_key.data.krb5, | 776 | memcpy(ses->server->mac_signing_key.data.krb5, |
824 | msg->data, msg->sesskey_len); | 777 | msg->data, msg->sesskey_len); |
825 | } | 778 | } |
826 | pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; | 779 | pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; |
@@ -862,26 +815,12 @@ ssetup_ntlmssp_authenticate: | |||
862 | if (phase == NtLmNegotiate) { | 815 | if (phase == NtLmNegotiate) { |
863 | setup_ntlmssp_neg_req(pSMB, ses); | 816 | setup_ntlmssp_neg_req(pSMB, ses); |
864 | iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE); | 817 | iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE); |
865 | iov[1].iov_base = &pSMB->req.SecurityBlob[0]; | ||
866 | } else if (phase == NtLmAuthenticate) { | 818 | } else if (phase == NtLmAuthenticate) { |
867 | int blob_len; | 819 | int blob_len; |
868 | ntlmsspblob = kmalloc(5 * | 820 | blob_len = setup_ntlmssp_auth_req(pSMB, ses, |
869 | sizeof(struct _AUTHENTICATE_MESSAGE), | 821 | nls_cp, |
870 | GFP_KERNEL); | 822 | first_time); |
871 | if (!ntlmsspblob) { | ||
872 | cERROR(1, "Can't allocate NTLMSSP"); | ||
873 | rc = -ENOMEM; | ||
874 | goto ssetup_exit; | ||
875 | } | ||
876 | |||
877 | blob_len = setup_ntlmssp_auth_req(ntlmsspblob, | ||
878 | ses, | ||
879 | nls_cp, | ||
880 | first_time); | ||
881 | iov[1].iov_len = blob_len; | 823 | iov[1].iov_len = blob_len; |
882 | iov[1].iov_base = ntlmsspblob; | ||
883 | pSMB->req.SecurityBlobLength = | ||
884 | cpu_to_le16(blob_len); | ||
885 | /* Make sure that we tell the server that we | 824 | /* Make sure that we tell the server that we |
886 | are using the uid that it just gave us back | 825 | are using the uid that it just gave us back |
887 | on the response (challenge) */ | 826 | on the response (challenge) */ |
@@ -891,6 +830,7 @@ ssetup_ntlmssp_authenticate: | |||
891 | rc = -ENOSYS; | 830 | rc = -ENOSYS; |
892 | goto ssetup_exit; | 831 | goto ssetup_exit; |
893 | } | 832 | } |
833 | iov[1].iov_base = &pSMB->req.SecurityBlob[0]; | ||
894 | /* unicode strings must be word aligned */ | 834 | /* unicode strings must be word aligned */ |
895 | if ((iov[0].iov_len + iov[1].iov_len) % 2) { | 835 | if ((iov[0].iov_len + iov[1].iov_len) % 2) { |
896 | *bcc_ptr = 0; | 836 | *bcc_ptr = 0; |