s3:smbd: allow anonymous encryption after one authenticated session setup
authorStefan Metzmacher <metze@samba.org>
Fri, 30 Jun 2023 16:05:51 +0000 (18:05 +0200)
committerStefan Metzmacher <metze@samba.org>
Thu, 23 May 2024 12:35:37 +0000 (12:35 +0000)
I have captures where a client tries smb3 encryption on an anonymous session,
we used to allow that before commit da7dcc443f45d07d9963df9daae458fbdd991a47
was released with samba-4.15.0rc1.

Testing against Windows Server 2022 revealed that anonymous signing is always
allowed (with the session key derived from 16 zero bytes) and
anonymous encryption is allowed after one authenticated session setup on
the tcp connection.

https://bugzilla.samba.org/show_bug.cgi?id=15412

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Günther Deschner <gd@samba.org>
selftest/knownfail.d/anon-encryption [deleted file]
source3/smbd/globals.h
source3/smbd/smb2_server.c
source3/smbd/smb2_sesssetup.c
source3/smbd/smb2_tcon.c

diff --git a/selftest/knownfail.d/anon-encryption b/selftest/knownfail.d/anon-encryption
deleted file mode 100644 (file)
index 99d833c..0000000
+++ /dev/null
@@ -1 +0,0 @@
-^samba3.smb2.session.*.anon-encryption2
index bfa3b124d73ea10b26231583b8fff2a4ded1e477..7d0d924dd7394a151d1a461fc76d091c2276b450 100644 (file)
@@ -522,6 +522,11 @@ struct smbXsrv_connection {
                } smbtorture;
 
                bool signing_mandatory;
+               /*
+                * This is ConstrainedConnection in MS-SMB2,
+                * but with reversed value...
+                */
+               bool got_authenticated_session;
        } smb2;
 };
 
index 642b530134b9e2334167564f52a55f8622dcd185..a32044d9357fdfa9d8d0222ef435544f3dede897 100644 (file)
@@ -495,6 +495,17 @@ static NTSTATUS smbd_smb2_inbuf_parse_compound(struct smbXsrv_connection *xconn,
                                goto inval;
                        }
 
+                       if (!xconn->smb2.got_authenticated_session) {
+                               D_INFO("Got SMB2_TRANSFORM header, "
+                                      "but not no authenticated session yet "
+                                      "client[%s] server[%s]\n",
+                                      tsocket_address_string(
+                                       xconn->remote_address, talloc_tos()),
+                                      tsocket_address_string(
+                                       xconn->local_address, talloc_tos()));
+                               goto inval;
+                       }
+
                        if (len < SMB2_TF_HDR_SIZE) {
                                DEBUG(1, ("%d bytes left, expected at least %d\n",
                                           (int)len, SMB2_TF_HDR_SIZE));
index 3005385ac9ceeb391762cb0c2b9d7a3b231baf08..d4140af2f1f3776ed70c4074a5f708c999983ed4 100644 (file)
@@ -272,6 +272,13 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session,
                x->global->signing_flags &= ~SMBXSRV_SIGNING_REQUIRED;
                /* we map anonymous to guest internally */
                guest = true;
+       } else {
+               /*
+                * Remember we got one authenticated session on the connection
+                * in order to allow SMB3 decryption to happen
+                * (sadly even for future anonymous connections).
+                */
+               xconn->smb2.got_authenticated_session = true;
        }
 
        if (guest && (x->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED)) {
@@ -289,7 +296,10 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session,
        }
        x->global->signing_algo = xconn->smb2.server.sign_algo;
        x->global->encryption_cipher = xconn->smb2.server.cipher;
-       if (guest) {
+       if (*out_session_flags & SMB2_SESSION_FLAG_IS_GUEST) {
+               /*
+                * A fallback to guest can't do any encryption
+                */
                x->global->encryption_cipher = SMB2_ENCRYPTION_NONE;
        }
 
@@ -643,6 +653,12 @@ static NTSTATUS smbd_smb2_bind_auth_return(struct smbXsrv_session *session,
                return NT_STATUS_LOGON_FAILURE;
        }
 
+       /*
+        * Remember we got one authenticated session on the connection
+        * in order to allow SMB3 decryption to happen
+        */
+       xconn->smb2.got_authenticated_session = true;
+
        *out_session_id = session->global->session_wire_id;
 
        return NT_STATUS_OK;
index b228036510aa6f233a28e06d96e7963912b91471..20d89670df18a01b3628fdce103addac2a2dba26 100644 (file)
@@ -331,6 +331,10 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
                }
        }
 
+       if (guest_session) {
+               /* make sure we don't ask for optional encryption */
+               encryption_desired = false;
+       }
        if (encryption_desired) {
                encryption_flags |= SMBXSRV_ENCRYPTION_DESIRED;
        }