From e67b7e5f88ea29670009eef6a69e3f60ebed3517 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow@samba.org>
Date: Tue, 20 Jun 2023 12:46:31 +0200
Subject: [PATCH 18/28] CVE-2023-3347: CI: add a test for server-side mandatory
 signing

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

Signed-off-by: Ralph Boehme <slow@samba.org>

Conflict: NA
Reference: https://download.samba.org/pub/samba/patches/security/samba-4.17.10-security-2023-07-19.patch
---
 .../samba3.smb2.session-require-signing       |  1 +
 selftest/target/Samba3.pm                     |  1 +
 source3/selftest/tests.py                     |  2 +
 source4/torture/smb2/session.c                | 64 +++++++++++++++++++
 source4/torture/smb2/smb2.c                   |  1 +
 5 files changed, 69 insertions(+)
 create mode 100644 selftest/knownfail.d/samba3.smb2.session-require-signing

diff --git a/selftest/knownfail.d/samba3.smb2.session-require-signing b/selftest/knownfail.d/samba3.smb2.session-require-signing
new file mode 100644
index 00000000000..53b7a7022a8
--- /dev/null
+++ b/selftest/knownfail.d/samba3.smb2.session-require-signing
@@ -0,0 +1 @@
+^samba3.smb2.session-require-signing.bug15397
diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index 9c590547c94..3336c5b8e97 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -1294,6 +1294,7 @@ sub setup_ad_member_idmap_rid
 	# values required for tests to succeed
 	create krb5 conf = no
         map to guest = bad user
+	server signing = required
 ";
 
 	my $ret = $self->provision(
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index 04349c1f1f7..887bf6d5293 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -938,6 +938,8 @@ for t in tests:
         # Certain tests fail when run against ad_member with MIT kerberos because the private krb5.conf overrides the provisioned lib/krb5.conf,
         # ad_member_idmap_rid sets "create krb5.conf = no"
         plansmbtorture4testsuite(t, "ad_member_idmap_rid", '//$SERVER/tmp -k yes -U$DC_USERNAME@$REALM%$DC_PASSWORD', 'krb5')
+    elif t == "smb2.session-require-signing":
+        plansmbtorture4testsuite(t, "ad_member_idmap_rid", '//$SERVER_IP/tmp -U$DC_USERNAME@$REALM%$DC_PASSWORD')
     elif t == "rpc.lsa":
         plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD', 'over ncacn_np ')
         plansmbtorture4testsuite(t, "nt4_dc", 'ncacn_ip_tcp:$SERVER_IP -U$USERNAME%$PASSWORD', 'over ncacn_ip_tcp ')
diff --git a/source4/torture/smb2/session.c b/source4/torture/smb2/session.c
index 92f9e638ff4..e417008cad7 100644
--- a/source4/torture/smb2/session.c
+++ b/source4/torture/smb2/session.c
@@ -5498,3 +5498,67 @@ struct torture_suite *torture_smb2_session_init(TALLOC_CTX *ctx)
 
 	return suite;
 }
+
+static bool test_session_require_sign_bug15397(struct torture_context *tctx,
+					       struct smb2_tree *_tree)
+{
+	const char *host = torture_setting_string(tctx, "host", NULL);
+	const char *share = torture_setting_string(tctx, "share", NULL);
+	struct cli_credentials *_creds = samba_cmdline_get_creds();
+	struct cli_credentials *creds = NULL;
+	struct smbcli_options options;
+	struct smb2_tree *tree = NULL;
+	uint8_t security_mode;
+	NTSTATUS status;
+	bool ok = true;
+
+	/*
+	 * Setup our own connection so we can control the signing flags
+	 */
+
+	creds = cli_credentials_shallow_copy(tctx, _creds);
+	torture_assert(tctx, creds != NULL, "cli_credentials_shallow_copy");
+
+	options = _tree->session->transport->options;
+	options.client_guid = GUID_random();
+	options.signing = SMB_SIGNING_IF_REQUIRED;
+
+	status = smb2_connect(tctx,
+			      host,
+			      lpcfg_smb_ports(tctx->lp_ctx),
+			      share,
+			      lpcfg_resolve_context(tctx->lp_ctx),
+			      creds,
+			      &tree,
+			      tctx->ev,
+			      &options,
+			      lpcfg_socket_options(tctx->lp_ctx),
+			      lpcfg_gensec_settings(tctx, tctx->lp_ctx));
+	torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
+					"smb2_connect failed");
+
+	security_mode = smb2cli_session_security_mode(tree->session->smbXcli);
+
+	torture_assert_int_equal_goto(
+		tctx,
+		security_mode,
+		SMB2_NEGOTIATE_SIGNING_REQUIRED | SMB2_NEGOTIATE_SIGNING_ENABLED,
+		ok,
+		done,
+		"Signing not required");
+
+done:
+	return ok;
+}
+
+struct torture_suite *torture_smb2_session_req_sign_init(TALLOC_CTX *ctx)
+{
+	struct torture_suite *suite =
+	    torture_suite_create(ctx, "session-require-signing");
+
+	torture_suite_add_1smb2_test(suite, "bug15397",
+				     test_session_require_sign_bug15397);
+
+	suite->description = talloc_strdup(suite, "SMB2-SESSION require signing tests");
+	return suite;
+}
diff --git a/source4/torture/smb2/smb2.c b/source4/torture/smb2/smb2.c
index c717db50b70..8621f09d820 100644
--- a/source4/torture/smb2/smb2.c
+++ b/source4/torture/smb2/smb2.c
@@ -189,6 +189,7 @@ NTSTATUS torture_smb2_init(TALLOC_CTX *ctx)
 	torture_suite_add_suite(suite, torture_smb2_sharemode_init(suite));
 	torture_suite_add_1smb2_test(suite, "hold-oplock", test_smb2_hold_oplock);
 	torture_suite_add_suite(suite, torture_smb2_session_init(suite));
+	torture_suite_add_suite(suite, torture_smb2_session_req_sign_init(suite));
 	torture_suite_add_suite(suite, torture_smb2_replay_init(suite));
 	torture_suite_add_simple_test(suite, "dosmode", torture_smb2_dosmode);
 	torture_suite_add_simple_test(suite, "async_dosmode", torture_smb2_async_dosmode);
-- 
2.34.1
