aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/cifsencrypt.c53
-rw-r--r--fs/cifs/smb2ops.c8
-rw-r--r--fs/cifs/smb2pdu.c84
3 files changed, 126 insertions, 19 deletions
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index aa0dc2573374..afa09fce8151 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -444,6 +444,48 @@ find_domain_name(struct cifs_ses *ses, const struct nls_table *nls_cp)
444 return 0; 444 return 0;
445} 445}
446 446
447/* Server has provided av pairs/target info in the type 2 challenge
448 * packet and we have plucked it and stored within smb session.
449 * We parse that blob here to find the server given timestamp
450 * as part of ntlmv2 authentication (or local current time as
451 * default in case of failure)
452 */
453static __le64
454find_timestamp(struct cifs_ses *ses)
455{
456 unsigned int attrsize;
457 unsigned int type;
458 unsigned int onesize = sizeof(struct ntlmssp2_name);
459 unsigned char *blobptr;
460 unsigned char *blobend;
461 struct ntlmssp2_name *attrptr;
462
463 if (!ses->auth_key.len || !ses->auth_key.response)
464 return 0;
465
466 blobptr = ses->auth_key.response;
467 blobend = blobptr + ses->auth_key.len;
468
469 while (blobptr + onesize < blobend) {
470 attrptr = (struct ntlmssp2_name *) blobptr;
471 type = le16_to_cpu(attrptr->type);
472 if (type == NTLMSSP_AV_EOL)
473 break;
474 blobptr += 2; /* advance attr type */
475 attrsize = le16_to_cpu(attrptr->length);
476 blobptr += 2; /* advance attr size */
477 if (blobptr + attrsize > blobend)
478 break;
479 if (type == NTLMSSP_AV_TIMESTAMP) {
480 if (attrsize == sizeof(u64))
481 return *((__le64 *)blobptr);
482 }
483 blobptr += attrsize; /* advance attr value */
484 }
485
486 return cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
487}
488
447static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash, 489static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
448 const struct nls_table *nls_cp) 490 const struct nls_table *nls_cp)
449{ 491{
@@ -641,6 +683,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
641 struct ntlmv2_resp *ntlmv2; 683 struct ntlmv2_resp *ntlmv2;
642 char ntlmv2_hash[16]; 684 char ntlmv2_hash[16];
643 unsigned char *tiblob = NULL; /* target info blob */ 685 unsigned char *tiblob = NULL; /* target info blob */
686 __le64 rsp_timestamp;
644 687
645 if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED) { 688 if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED) {
646 if (!ses->domainName) { 689 if (!ses->domainName) {
@@ -659,6 +702,12 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
659 } 702 }
660 } 703 }
661 704
705 /* Must be within 5 minutes of the server (or in range +/-2h
706 * in case of Mac OS X), so simply carry over server timestamp
707 * (as Windows 7 does)
708 */
709 rsp_timestamp = find_timestamp(ses);
710
662 baselen = CIFS_SESS_KEY_SIZE + sizeof(struct ntlmv2_resp); 711 baselen = CIFS_SESS_KEY_SIZE + sizeof(struct ntlmv2_resp);
663 tilen = ses->auth_key.len; 712 tilen = ses->auth_key.len;
664 tiblob = ses->auth_key.response; 713 tiblob = ses->auth_key.response;
@@ -675,8 +724,8 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
675 (ses->auth_key.response + CIFS_SESS_KEY_SIZE); 724 (ses->auth_key.response + CIFS_SESS_KEY_SIZE);
676 ntlmv2->blob_signature = cpu_to_le32(0x00000101); 725 ntlmv2->blob_signature = cpu_to_le32(0x00000101);
677 ntlmv2->reserved = 0; 726 ntlmv2->reserved = 0;
678 /* Must be within 5 minutes of the server */ 727 ntlmv2->time = rsp_timestamp;
679 ntlmv2->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); 728
680 get_random_bytes(&ntlmv2->client_chal, sizeof(ntlmv2->client_chal)); 729 get_random_bytes(&ntlmv2->client_chal, sizeof(ntlmv2->client_chal));
681 ntlmv2->reserved2 = 0; 730 ntlmv2->reserved2 = 0;
682 731
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index df91bcf56d67..18da19f4f811 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -50,9 +50,13 @@ change_conf(struct TCP_Server_Info *server)
50 break; 50 break;
51 default: 51 default:
52 server->echoes = true; 52 server->echoes = true;
53 server->oplocks = true; 53 if (enable_oplocks) {
54 server->oplocks = true;
55 server->oplock_credits = 1;
56 } else
57 server->oplocks = false;
58
54 server->echo_credits = 1; 59 server->echo_credits = 1;
55 server->oplock_credits = 1;
56 } 60 }
57 server->credits -= server->echo_credits + server->oplock_credits; 61 server->credits -= server->echo_credits + server->oplock_credits;
58 return 0; 62 return 0;
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 070fb2ad85ce..ce83e2edbe0a 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -46,6 +46,7 @@
46#include "smb2status.h" 46#include "smb2status.h"
47#include "smb2glob.h" 47#include "smb2glob.h"
48#include "cifspdu.h" 48#include "cifspdu.h"
49#include "cifs_spnego.h"
49 50
50/* 51/*
51 * The following table defines the expected "StructureSize" of SMB2 requests 52 * The following table defines the expected "StructureSize" of SMB2 requests
@@ -486,19 +487,15 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
486 cifs_dbg(FYI, "missing security blob on negprot\n"); 487 cifs_dbg(FYI, "missing security blob on negprot\n");
487 488
488 rc = cifs_enable_signing(server, ses->sign); 489 rc = cifs_enable_signing(server, ses->sign);
489#ifdef CONFIG_SMB2_ASN1 /* BB REMOVEME when updated asn1.c ready */
490 if (rc) 490 if (rc)
491 goto neg_exit; 491 goto neg_exit;
492 if (blob_length) 492 if (blob_length) {
493 rc = decode_negTokenInit(security_blob, blob_length, server); 493 rc = decode_negTokenInit(security_blob, blob_length, server);
494 if (rc == 1) 494 if (rc == 1)
495 rc = 0; 495 rc = 0;
496 else if (rc == 0) { 496 else if (rc == 0)
497 rc = -EIO; 497 rc = -EIO;
498 goto neg_exit;
499 } 498 }
500#endif
501
502neg_exit: 499neg_exit:
503 free_rsp_buf(resp_buftype, rsp); 500 free_rsp_buf(resp_buftype, rsp);
504 return rc; 501 return rc;
@@ -592,7 +589,8 @@ SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses,
592 __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */ 589 __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */
593 struct TCP_Server_Info *server = ses->server; 590 struct TCP_Server_Info *server = ses->server;
594 u16 blob_length = 0; 591 u16 blob_length = 0;
595 char *security_blob; 592 struct key *spnego_key = NULL;
593 char *security_blob = NULL;
596 char *ntlmssp_blob = NULL; 594 char *ntlmssp_blob = NULL;
597 bool use_spnego = false; /* else use raw ntlmssp */ 595 bool use_spnego = false; /* else use raw ntlmssp */
598 596
@@ -620,7 +618,8 @@ SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses,
620 ses->ntlmssp->sesskey_per_smbsess = true; 618 ses->ntlmssp->sesskey_per_smbsess = true;
621 619
622 /* FIXME: allow for other auth types besides NTLMSSP (e.g. krb5) */ 620 /* FIXME: allow for other auth types besides NTLMSSP (e.g. krb5) */
623 ses->sectype = RawNTLMSSP; 621 if (ses->sectype != Kerberos && ses->sectype != RawNTLMSSP)
622 ses->sectype = RawNTLMSSP;
624 623
625ssetup_ntlmssp_authenticate: 624ssetup_ntlmssp_authenticate:
626 if (phase == NtLmChallenge) 625 if (phase == NtLmChallenge)
@@ -649,7 +648,48 @@ ssetup_ntlmssp_authenticate:
649 iov[0].iov_base = (char *)req; 648 iov[0].iov_base = (char *)req;
650 /* 4 for rfc1002 length field and 1 for pad */ 649 /* 4 for rfc1002 length field and 1 for pad */
651 iov[0].iov_len = get_rfc1002_length(req) + 4 - 1; 650 iov[0].iov_len = get_rfc1002_length(req) + 4 - 1;
652 if (phase == NtLmNegotiate) { 651
652 if (ses->sectype == Kerberos) {
653#ifdef CONFIG_CIFS_UPCALL
654 struct cifs_spnego_msg *msg;
655
656 spnego_key = cifs_get_spnego_key(ses);
657 if (IS_ERR(spnego_key)) {
658 rc = PTR_ERR(spnego_key);
659 spnego_key = NULL;
660 goto ssetup_exit;
661 }
662
663 msg = spnego_key->payload.data;
664 /*
665 * check version field to make sure that cifs.upcall is
666 * sending us a response in an expected form
667 */
668 if (msg->version != CIFS_SPNEGO_UPCALL_VERSION) {
669 cifs_dbg(VFS,
670 "bad cifs.upcall version. Expected %d got %d",
671 CIFS_SPNEGO_UPCALL_VERSION, msg->version);
672 rc = -EKEYREJECTED;
673 goto ssetup_exit;
674 }
675 ses->auth_key.response = kmemdup(msg->data, msg->sesskey_len,
676 GFP_KERNEL);
677 if (!ses->auth_key.response) {
678 cifs_dbg(VFS,
679 "Kerberos can't allocate (%u bytes) memory",
680 msg->sesskey_len);
681 rc = -ENOMEM;
682 goto ssetup_exit;
683 }
684 ses->auth_key.len = msg->sesskey_len;
685 blob_length = msg->secblob_len;
686 iov[1].iov_base = msg->data + msg->sesskey_len;
687 iov[1].iov_len = blob_length;
688#else
689 rc = -EOPNOTSUPP;
690 goto ssetup_exit;
691#endif /* CONFIG_CIFS_UPCALL */
692 } else if (phase == NtLmNegotiate) { /* if not krb5 must be ntlmssp */
653 ntlmssp_blob = kmalloc(sizeof(struct _NEGOTIATE_MESSAGE), 693 ntlmssp_blob = kmalloc(sizeof(struct _NEGOTIATE_MESSAGE),
654 GFP_KERNEL); 694 GFP_KERNEL);
655 if (ntlmssp_blob == NULL) { 695 if (ntlmssp_blob == NULL) {
@@ -672,6 +712,8 @@ ssetup_ntlmssp_authenticate:
672 /* with raw NTLMSSP we don't encapsulate in SPNEGO */ 712 /* with raw NTLMSSP we don't encapsulate in SPNEGO */
673 security_blob = ntlmssp_blob; 713 security_blob = ntlmssp_blob;
674 } 714 }
715 iov[1].iov_base = security_blob;
716 iov[1].iov_len = blob_length;
675 } else if (phase == NtLmAuthenticate) { 717 } else if (phase == NtLmAuthenticate) {
676 req->hdr.SessionId = ses->Suid; 718 req->hdr.SessionId = ses->Suid;
677 ntlmssp_blob = kzalloc(sizeof(struct _NEGOTIATE_MESSAGE) + 500, 719 ntlmssp_blob = kzalloc(sizeof(struct _NEGOTIATE_MESSAGE) + 500,
@@ -699,6 +741,8 @@ ssetup_ntlmssp_authenticate:
699 } else { 741 } else {
700 security_blob = ntlmssp_blob; 742 security_blob = ntlmssp_blob;
701 } 743 }
744 iov[1].iov_base = security_blob;
745 iov[1].iov_len = blob_length;
702 } else { 746 } else {
703 cifs_dbg(VFS, "illegal ntlmssp phase\n"); 747 cifs_dbg(VFS, "illegal ntlmssp phase\n");
704 rc = -EIO; 748 rc = -EIO;
@@ -710,8 +754,6 @@ ssetup_ntlmssp_authenticate:
710 cpu_to_le16(sizeof(struct smb2_sess_setup_req) - 754 cpu_to_le16(sizeof(struct smb2_sess_setup_req) -
711 1 /* pad */ - 4 /* rfc1001 len */); 755 1 /* pad */ - 4 /* rfc1001 len */);
712 req->SecurityBufferLength = cpu_to_le16(blob_length); 756 req->SecurityBufferLength = cpu_to_le16(blob_length);
713 iov[1].iov_base = security_blob;
714 iov[1].iov_len = blob_length;
715 757
716 inc_rfc1001_len(req, blob_length - 1 /* pad */); 758 inc_rfc1001_len(req, blob_length - 1 /* pad */);
717 759
@@ -722,6 +764,7 @@ ssetup_ntlmssp_authenticate:
722 764
723 kfree(security_blob); 765 kfree(security_blob);
724 rsp = (struct smb2_sess_setup_rsp *)iov[0].iov_base; 766 rsp = (struct smb2_sess_setup_rsp *)iov[0].iov_base;
767 ses->Suid = rsp->hdr.SessionId;
725 if (resp_buftype != CIFS_NO_BUFFER && 768 if (resp_buftype != CIFS_NO_BUFFER &&
726 rsp->hdr.Status == STATUS_MORE_PROCESSING_REQUIRED) { 769 rsp->hdr.Status == STATUS_MORE_PROCESSING_REQUIRED) {
727 if (phase != NtLmNegotiate) { 770 if (phase != NtLmNegotiate) {
@@ -739,7 +782,6 @@ ssetup_ntlmssp_authenticate:
739 /* NTLMSSP Negotiate sent now processing challenge (response) */ 782 /* NTLMSSP Negotiate sent now processing challenge (response) */
740 phase = NtLmChallenge; /* process ntlmssp challenge */ 783 phase = NtLmChallenge; /* process ntlmssp challenge */
741 rc = 0; /* MORE_PROCESSING is not an error here but expected */ 784 rc = 0; /* MORE_PROCESSING is not an error here but expected */
742 ses->Suid = rsp->hdr.SessionId;
743 rc = decode_ntlmssp_challenge(rsp->Buffer, 785 rc = decode_ntlmssp_challenge(rsp->Buffer,
744 le16_to_cpu(rsp->SecurityBufferLength), ses); 786 le16_to_cpu(rsp->SecurityBufferLength), ses);
745 } 787 }
@@ -796,6 +838,10 @@ keygen_exit:
796 kfree(ses->auth_key.response); 838 kfree(ses->auth_key.response);
797 ses->auth_key.response = NULL; 839 ses->auth_key.response = NULL;
798 } 840 }
841 if (spnego_key) {
842 key_invalidate(spnego_key);
843 key_put(spnego_key);
844 }
799 kfree(ses->ntlmssp); 845 kfree(ses->ntlmssp);
800 846
801 return rc; 847 return rc;
@@ -876,6 +922,12 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
876 if (tcon && tcon->bad_network_name) 922 if (tcon && tcon->bad_network_name)
877 return -ENOENT; 923 return -ENOENT;
878 924
925 if ((tcon->seal) &&
926 ((ses->server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION) == 0)) {
927 cifs_dbg(VFS, "encryption requested but no server support");
928 return -EOPNOTSUPP;
929 }
930
879 unc_path = kmalloc(MAX_SHARENAME_LENGTH * 2, GFP_KERNEL); 931 unc_path = kmalloc(MAX_SHARENAME_LENGTH * 2, GFP_KERNEL);
880 if (unc_path == NULL) 932 if (unc_path == NULL)
881 return -ENOMEM; 933 return -ENOMEM;
@@ -955,6 +1007,8 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
955 ((tcon->share_flags & SHI1005_FLAGS_DFS) == 0)) 1007 ((tcon->share_flags & SHI1005_FLAGS_DFS) == 0))
956 cifs_dbg(VFS, "DFS capability contradicts DFS flag\n"); 1008 cifs_dbg(VFS, "DFS capability contradicts DFS flag\n");
957 init_copy_chunk_defaults(tcon); 1009 init_copy_chunk_defaults(tcon);
1010 if (tcon->share_flags & SHI1005_FLAGS_ENCRYPT_DATA)
1011 cifs_dbg(VFS, "Encrypted shares not supported");
958 if (tcon->ses->server->ops->validate_negotiate) 1012 if (tcon->ses->server->ops->validate_negotiate)
959 rc = tcon->ses->server->ops->validate_negotiate(xid, tcon); 1013 rc = tcon->ses->server->ops->validate_negotiate(xid, tcon);
960tcon_exit: 1014tcon_exit: