Skip to content

Commit 9de0737

Browse files
Paulo Alcantarasmfrench
authored andcommitted
cifs: fix ntlmssp auth when there is no key exchange
Warn on the lack of key exchange during NTLMSSP authentication rather than aborting it as there are some servers that do not set it in CHALLENGE message. Signed-off-by: Paulo Alcantara (SUSE) <[email protected]> Acked-by: Ronnie Sahlberg <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 51a08bd commit 9de0737

File tree

1 file changed

+36
-18
lines changed

1 file changed

+36
-18
lines changed

fs/cifs/sess.c

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -590,8 +590,8 @@ int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
590590
{
591591
unsigned int tioffset; /* challenge message target info area */
592592
unsigned int tilen; /* challenge message target info area length */
593-
594593
CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr;
594+
__u32 server_flags;
595595

596596
if (blob_len < sizeof(CHALLENGE_MESSAGE)) {
597597
cifs_dbg(VFS, "challenge blob len %d too small\n", blob_len);
@@ -609,12 +609,37 @@ int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
609609
return -EINVAL;
610610
}
611611

612+
server_flags = le32_to_cpu(pblob->NegotiateFlags);
613+
cifs_dbg(FYI, "%s: negotiate=0x%08x challenge=0x%08x\n", __func__,
614+
ses->ntlmssp->client_flags, server_flags);
615+
616+
if ((ses->ntlmssp->client_flags & (NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN)) &&
617+
(!(server_flags & NTLMSSP_NEGOTIATE_56) && !(server_flags & NTLMSSP_NEGOTIATE_128))) {
618+
cifs_dbg(VFS, "%s: requested signing/encryption but server did not return either 56-bit or 128-bit session key size\n",
619+
__func__);
620+
return -EINVAL;
621+
}
622+
if (!(server_flags & NTLMSSP_NEGOTIATE_NTLM) && !(server_flags & NTLMSSP_NEGOTIATE_EXTENDED_SEC)) {
623+
cifs_dbg(VFS, "%s: server does not seem to support either NTLMv1 or NTLMv2\n", __func__);
624+
return -EINVAL;
625+
}
626+
if (ses->server->sign && !(server_flags & NTLMSSP_NEGOTIATE_SIGN)) {
627+
cifs_dbg(VFS, "%s: forced packet signing but server does not seem to support it\n",
628+
__func__);
629+
return -EOPNOTSUPP;
630+
}
631+
if ((ses->ntlmssp->client_flags & NTLMSSP_NEGOTIATE_KEY_XCH) &&
632+
!(server_flags & NTLMSSP_NEGOTIATE_KEY_XCH))
633+
pr_warn_once("%s: authentication has been weakened as server does not support key exchange\n",
634+
__func__);
635+
636+
ses->ntlmssp->server_flags = server_flags;
637+
612638
memcpy(ses->ntlmssp->cryptkey, pblob->Challenge, CIFS_CRYPTO_KEY_SIZE);
613-
/* BB we could decode pblob->NegotiateFlags; some may be useful */
614639
/* In particular we can examine sign flags */
615640
/* BB spec says that if AvId field of MsvAvTimestamp is populated then
616641
we must set the MIC field of the AUTHENTICATE_MESSAGE */
617-
ses->ntlmssp->server_flags = le32_to_cpu(pblob->NegotiateFlags);
642+
618643
tioffset = le32_to_cpu(pblob->TargetInfoArray.BufferOffset);
619644
tilen = le16_to_cpu(pblob->TargetInfoArray.Length);
620645
if (tioffset > blob_len || tioffset + tilen > blob_len) {
@@ -721,13 +746,13 @@ int build_ntlmssp_negotiate_blob(unsigned char **pbuffer,
721746
flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET |
722747
NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
723748
NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC |
724-
NTLMSSP_NEGOTIATE_SEAL;
725-
if (server->sign)
726-
flags |= NTLMSSP_NEGOTIATE_SIGN;
749+
NTLMSSP_NEGOTIATE_ALWAYS_SIGN | NTLMSSP_NEGOTIATE_SEAL |
750+
NTLMSSP_NEGOTIATE_SIGN;
727751
if (!server->session_estab || ses->ntlmssp->sesskey_per_smbsess)
728752
flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
729753

730754
tmp = *pbuffer + sizeof(NEGOTIATE_MESSAGE);
755+
ses->ntlmssp->client_flags = flags;
731756
sec_blob->NegotiateFlags = cpu_to_le32(flags);
732757

733758
/* these fields should be null in negotiate phase MS-NLMP 3.1.5.1.1 */
@@ -779,15 +804,8 @@ int build_ntlmssp_auth_blob(unsigned char **pbuffer,
779804
memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
780805
sec_blob->MessageType = NtLmAuthenticate;
781806

782-
flags = NTLMSSP_NEGOTIATE_56 |
783-
NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO |
784-
NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
785-
NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC |
786-
NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED;
787-
if (ses->server->sign)
788-
flags |= NTLMSSP_NEGOTIATE_SIGN;
789-
if (!ses->server->session_estab || ses->ntlmssp->sesskey_per_smbsess)
790-
flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
807+
flags = ses->ntlmssp->server_flags | NTLMSSP_REQUEST_TARGET |
808+
NTLMSSP_NEGOTIATE_TARGET_INFO | NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED;
791809

792810
tmp = *pbuffer + sizeof(AUTHENTICATE_MESSAGE);
793811
sec_blob->NegotiateFlags = cpu_to_le32(flags);
@@ -834,9 +852,9 @@ int build_ntlmssp_auth_blob(unsigned char **pbuffer,
834852
*pbuffer, &tmp,
835853
nls_cp);
836854

837-
if (((ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) ||
838-
(ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
839-
&& !calc_seckey(ses)) {
855+
if ((ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) &&
856+
(!ses->server->session_estab || ses->ntlmssp->sesskey_per_smbsess) &&
857+
!calc_seckey(ses)) {
840858
memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
841859
sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - *pbuffer);
842860
sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE);

0 commit comments

Comments
 (0)