]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
smbXcli_base: add hacks to test anonymous signing and encryption
authorStefan Metzmacher <metze@samba.org>
Tue, 14 May 2024 16:21:33 +0000 (18:21 +0200)
committerStefan Metzmacher <metze@samba.org>
Thu, 23 May 2024 12:35:37 +0000 (12:35 +0000)
BUG: 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>
libcli/smb/smbXcli_base.c
libcli/smb/smbXcli_base.h

index 90e343c9d12cda86a5ba371c5a69aa08f2f4f458..f3b534a6c6b1c3dec48f4efe5dc3d20bfedf7961 100644 (file)
@@ -166,6 +166,13 @@ struct smb2cli_session {
        uint16_t channel_sequence;
        bool replay_active;
        bool require_signed_response;
+
+       /*
+        * The following are just for torture tests
+        */
+       bool anonymous_signing;
+       bool anonymous_encryption;
+       bool no_signing_disconnect;
 };
 
 struct smbXcli_session {
@@ -3999,6 +4006,9 @@ static NTSTATUS smb2cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
 
                if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED) ||
                    NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) ||
+                   (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) &&
+                    session != NULL &&
+                    session->smb2->no_signing_disconnect) ||
                    NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
                        /*
                         * if the server returns
@@ -4042,8 +4052,29 @@ static NTSTATUS smb2cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
                                /*
                                 * If the signing check fails, we disconnect
                                 * the connection.
+                                *
+                                * Unless
+                                * smb2cli_session_torture_no_signing_disconnect
+                                * was called in torture tests
                                 */
-                               return signing_status;
+
+                               if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+                                       return signing_status;
+                               }
+
+                               if (!NT_STATUS_EQUAL(status, signing_status)) {
+                                       return signing_status;
+                               }
+
+                               if (session == NULL) {
+                                       return signing_status;
+                               }
+
+                               if (!session->smb2->no_signing_disconnect) {
+                                       return signing_status;
+                               }
+
+                               state->smb2.signing_skipped = true;
                        }
                }
 
@@ -6322,6 +6353,23 @@ void smb2cli_session_require_signed_response(struct smbXcli_session *session,
        session->smb2->require_signed_response = require_signed_response;
 }
 
+void smb2cli_session_torture_anonymous_signing(struct smbXcli_session *session,
+                                              bool anonymous_signing)
+{
+       session->smb2->anonymous_signing = anonymous_signing;
+}
+
+void smb2cli_session_torture_anonymous_encryption(struct smbXcli_session *session,
+                                                 bool anonymous_encryption)
+{
+       session->smb2->anonymous_encryption = anonymous_encryption;
+}
+
+void smb2cli_session_torture_no_signing_disconnect(struct smbXcli_session *session)
+{
+       session->smb2->no_signing_disconnect = true;
+}
+
 NTSTATUS smb2cli_session_update_preauth(struct smbXcli_session *session,
                                        const struct iovec *iov)
 {
@@ -6422,6 +6470,10 @@ NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session,
                                                  conn->protocol,
                                                  preauth_hash);
 
+       if (session->smb2->anonymous_encryption) {
+               goto skip_signing_key;
+       }
+
        status = smb2_signing_key_sign_create(session->smb2,
                                              conn->smb2.server.sign_algo,
                                              &_session_key,
@@ -6431,6 +6483,15 @@ NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session,
                return status;
        }
 
+       if (session->smb2->anonymous_signing) {
+               /*
+                * skip encryption and application keys
+                */
+               goto skip_application_key;
+       }
+
+skip_signing_key:
+
        status = smb2_signing_key_cipher_create(session->smb2,
                                                conn->smb2.server.cipher,
                                                &_session_key,
@@ -6449,6 +6510,10 @@ NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session,
                return status;
        }
 
+       if (session->smb2->anonymous_encryption) {
+               goto skip_application_key;
+       }
+
        status = smb2_signing_key_sign_create(session->smb2,
                                              conn->smb2.server.sign_algo,
                                              &_session_key,
@@ -6458,6 +6523,8 @@ NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session,
                return status;
        }
 
+skip_application_key:
+
        status = smb2_signing_key_copy(session,
                                       session->smb2->signing_key,
                                       &session->smb2_channel.signing_key);
@@ -6467,6 +6534,18 @@ NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session,
 
        check_signature = conn->mandatory_signing;
 
+       if (conn->protocol >= PROTOCOL_SMB3_11) {
+               check_signature = true;
+       }
+
+       if (session->smb2->anonymous_signing) {
+               check_signature = false;
+       }
+
+       if (session->smb2->anonymous_encryption) {
+               check_signature = false;
+       }
+
        hdr_flags = IVAL(recv_iov[0].iov_base, SMB2_HDR_FLAGS);
        if (hdr_flags & SMB2_HDR_FLAG_SIGNED) {
                /*
@@ -6482,10 +6561,6 @@ NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session,
                check_signature = true;
        }
 
-       if (conn->protocol >= PROTOCOL_SMB3_11) {
-               check_signature = true;
-       }
-
        if (check_signature) {
                status = smb2_signing_check_pdu(session->smb2_channel.signing_key,
                                                recv_iov, 3);
@@ -6517,6 +6592,15 @@ NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session,
                session->smb2->should_encrypt = false;
        }
 
+       if (session->smb2->anonymous_signing) {
+               session->smb2->should_sign = true;
+       }
+
+       if (session->smb2->anonymous_encryption) {
+               session->smb2->should_encrypt = true;
+               session->smb2->should_sign = false;
+       }
+
        /*
         * CCM and GCM algorithms must never have their
         * nonce wrap, or the security of the whole
@@ -6688,6 +6772,16 @@ NTSTATUS smb2cli_session_set_channel_key(struct smbXcli_session *session,
 
 NTSTATUS smb2cli_session_encryption_on(struct smbXcli_session *session)
 {
+       if (session->smb2->anonymous_signing) {
+               return NT_STATUS_INVALID_PARAMETER_MIX;
+       }
+
+       if (session->smb2->anonymous_encryption) {
+               SMB_ASSERT(session->smb2->should_encrypt);
+               SMB_ASSERT(!session->smb2->should_sign);
+               return NT_STATUS_OK;
+       }
+
        if (!session->smb2->should_sign) {
                /*
                 * We need required signing on the session
index 25ccd84b33609f4bd05623553b0208713304071c..69fa131a31d66abeaf4cd19160f6fbcc02f67de4 100644 (file)
@@ -535,6 +535,11 @@ void smb2cli_session_start_replay(struct smbXcli_session *session);
 void smb2cli_session_stop_replay(struct smbXcli_session *session);
 void smb2cli_session_require_signed_response(struct smbXcli_session *session,
                                             bool require_signed_response);
+void smb2cli_session_torture_anonymous_signing(struct smbXcli_session *session,
+                                              bool anonymous_signing);
+void smb2cli_session_torture_anonymous_encryption(struct smbXcli_session *session,
+                                                 bool anonymous_encryption);
+void smb2cli_session_torture_no_signing_disconnect(struct smbXcli_session *session);
 NTSTATUS smb2cli_session_update_preauth(struct smbXcli_session *session,
                                        const struct iovec *iov);
 NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session,