The Samba-Bugzilla – Attachment 18307 Details for
Bug 15412
anonymous smb3 signing/encryption should be allowed (similar to Windows Server 2022)
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
Patches for v4-19-test
bfixes-tmp419.txt (text/plain), 54.43 KB, created by
Stefan Metzmacher
on 2024-05-29 13:09:39 UTC
(
hide
)
Description:
Patches for v4-19-test
Filename:
MIME Type:
Creator:
Stefan Metzmacher
Created:
2024-05-29 13:09:39 UTC
Size:
54.43 KB
patch
obsolete
>From 14a0d742e33df4cfd2bd312407e86607a2ea6f79 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 14 May 2024 18:21:33 +0200 >Subject: [PATCH 01/10] smbXcli_base: add hacks to test anonymous signing and > encryption >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >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> >(cherry picked from commit 14d6e2672126adee85997dc3d3c64607c987e8b9) >--- > libcli/smb/smbXcli_base.c | 104 ++++++++++++++++++++++++++++++++++++-- > libcli/smb/smbXcli_base.h | 5 ++ > 2 files changed, 104 insertions(+), 5 deletions(-) > >diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c >index fe422eb83fa1..c3960b53381a 100644 >--- a/libcli/smb/smbXcli_base.c >+++ b/libcli/smb/smbXcli_base.c >@@ -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; > } > } > >@@ -6340,6 +6371,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) > { >@@ -6440,6 +6488,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, >@@ -6449,6 +6501,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, >@@ -6467,6 +6528,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, >@@ -6476,6 +6541,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); >@@ -6485,6 +6552,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) { > /* >@@ -6500,10 +6579,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); >@@ -6535,6 +6610,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 >@@ -6699,6 +6783,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 >diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h >index bf8638711ba5..4ce2338b4408 100644 >--- a/libcli/smb/smbXcli_base.h >+++ b/libcli/smb/smbXcli_base.h >@@ -525,6 +525,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, >-- >2.34.1 > > >From 673f5ec3e08e566f604cc85b1e621e65993625e3 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 May 2024 10:51:42 +0200 >Subject: [PATCH 02/10] s4:libcli/smb2: add hack to test anonymous signing and > encryption >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >This will be used in torture tests. > >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> >(cherry picked from commit 6a89615d78119c0bff2fb07bd0c62e4c31ea8441) >--- > source4/libcli/smb2/session.c | 16 +++++++++++----- > source4/libcli/smb2/smb2.h | 2 ++ > 2 files changed, 13 insertions(+), 5 deletions(-) > >diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c >index e94512d3d337..322a7bd6860a 100644 >--- a/source4/libcli/smb2/session.c >+++ b/source4/libcli/smb2/session.c >@@ -385,7 +385,9 @@ static void smb2_session_setup_spnego_both_ready(struct tevent_req *req) > return; > } > >- if (cli_credentials_is_anonymous(state->credentials)) { >+ if (cli_credentials_is_anonymous(state->credentials) && >+ !state->session->anonymous_session_key) >+ { > /* > * Windows server does not set the > * SMB2_SESSION_FLAG_IS_GUEST nor >@@ -399,10 +401,14 @@ static void smb2_session_setup_spnego_both_ready(struct tevent_req *req) > return; > } > >- status = gensec_session_key(session->gensec, state, >- &session_key); >- if (tevent_req_nterror(req, status)) { >- return; >+ if (state->session->forced_session_key.length != 0) { >+ session_key = state->session->forced_session_key; >+ } else { >+ status = gensec_session_key(session->gensec, state, >+ &session_key); >+ if (tevent_req_nterror(req, status)) { >+ return; >+ } > } > > if (state->session_bind) { >diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h >index 4aadab21c4cf..1462e0f9a8d9 100644 >--- a/source4/libcli/smb2/smb2.h >+++ b/source4/libcli/smb2/smb2.h >@@ -128,6 +128,8 @@ struct smb2_session { > struct gensec_security *gensec; > struct smbXcli_session *smbXcli; > bool needs_bind; >+ bool anonymous_session_key; >+ DATA_BLOB forced_session_key; > }; > > >-- >2.34.1 > > >From f0390f64a48f41b3f48191e01e1bdde571dfef03 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 May 2024 10:02:00 +0200 >Subject: [PATCH 03/10] s4:torture/smb2: add > smb2.session.anon-{encryption{1,2,},signing{1,2}} >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >These demonstrate how anonymous encryption and signing work. >They pass against Windows 2022 as ad dc. > >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> >(cherry picked from commit 6c5781b5f154857f1454f41133687fba8c4c9df9) >--- > selftest/knownfail.d/anon-encryption | 1 + > source4/torture/smb2/session.c | 629 +++++++++++++++++++++++++++ > 2 files changed, 630 insertions(+) > create mode 100644 selftest/knownfail.d/anon-encryption > >diff --git a/selftest/knownfail.d/anon-encryption b/selftest/knownfail.d/anon-encryption >new file mode 100644 >index 000000000000..99d833c205a1 >--- /dev/null >+++ b/selftest/knownfail.d/anon-encryption >@@ -0,0 +1 @@ >+^samba3.smb2.session.*.anon-encryption2 >diff --git a/source4/torture/smb2/session.c b/source4/torture/smb2/session.c >index 823304f190f0..2a3d0e6e8536 100644 >--- a/source4/torture/smb2/session.c >+++ b/source4/torture/smb2/session.c >@@ -5527,6 +5527,630 @@ static bool test_session_ntlmssp_bug14932(struct torture_context *tctx, struct s > return ret; > } > >+static bool test_session_anon_encryption1(struct torture_context *tctx, >+ struct smb2_tree *tree0) >+{ >+ const char *host = torture_setting_string(tctx, "host", NULL); >+ const char *share = "IPC$"; >+ char *unc = NULL; >+ struct smb2_transport *transport0 = tree0->session->transport; >+ struct cli_credentials *anon_creds = NULL; >+ struct smbcli_options options; >+ struct smb2_transport *transport = NULL; >+ struct smb2_session *anon_session = NULL; >+ struct smb2_tree *anon_tree = NULL; >+ NTSTATUS status; >+ bool ok = true; >+ struct tevent_req *subreq = NULL; >+ uint32_t timeout_msec; >+ >+ if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_00) { >+ torture_skip(tctx, >+ "Can't test without SMB3 support"); >+ } >+ >+ unc = talloc_asprintf(tctx, "\\\\%s\\%s", host, share); >+ torture_assert(tctx, unc != NULL, "talloc_asprintf"); >+ >+ anon_creds = cli_credentials_init_anon(tctx); >+ torture_assert(tctx, anon_creds != NULL, "cli_credentials_init_anon"); >+ ok = cli_credentials_set_smb_encryption(anon_creds, >+ SMB_ENCRYPTION_REQUIRED, >+ CRED_SPECIFIED); >+ torture_assert(tctx, ok, "cli_credentials_set_smb_encryption"); >+ >+ options = transport0->options; >+ options.client_guid = GUID_random(); >+ options.only_negprot = true; >+ >+ status = smb2_connect(tctx, >+ host, >+ lpcfg_smb_ports(tctx->lp_ctx), >+ share, >+ lpcfg_resolve_context(tctx->lp_ctx), >+ anon_creds, >+ &anon_tree, >+ tctx->ev, >+ &options, >+ lpcfg_socket_options(tctx->lp_ctx), >+ lpcfg_gensec_settings(tctx, tctx->lp_ctx)); >+ torture_assert_ntstatus_ok(tctx, status, "smb2_connect failed"); >+ anon_session = anon_tree->session; >+ transport = anon_session->transport; >+ >+ anon_session->anonymous_session_key = true; >+ smb2cli_session_torture_anonymous_encryption(anon_session->smbXcli, true); >+ >+ status = smb2_session_setup_spnego(anon_session, >+ anon_creds, >+ 0 /* previous_session_id */); >+ torture_assert_ntstatus_ok(tctx, status, >+ "smb2_session_setup_spnego failed"); >+ >+ ok = smbXcli_session_is_authenticated(anon_session->smbXcli); >+ torture_assert(tctx, !ok, "smbXcli_session_is_authenticated(anon) wrong"); >+ >+ /* >+ * The connection is still in ConstrainedConnection state... >+ * >+ * This will use encryption and causes a connection reset >+ */ >+ timeout_msec = transport->options.request_timeout * 1000; >+ subreq = smb2cli_tcon_send(tctx, >+ tctx->ev, >+ transport->conn, >+ timeout_msec, >+ anon_session->smbXcli, >+ anon_tree->smbXcli, >+ 0, /* flags */ >+ unc); >+ torture_assert(tctx, subreq != NULL, "smb2cli_tcon_send"); >+ >+ torture_assert(tctx, >+ tevent_req_poll_ntstatus(subreq, tctx->ev, &status), >+ "tevent_req_poll_ntstatus"); >+ >+ status = smb2cli_tcon_recv(subreq); >+ TALLOC_FREE(subreq); >+ if (NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED)) { >+ status = NT_STATUS_CONNECTION_RESET; >+ } >+ torture_assert_ntstatus_equal(tctx, status, >+ NT_STATUS_CONNECTION_RESET, >+ "smb2cli_tcon_recv"); >+ >+ ok = smbXcli_conn_is_connected(transport->conn); >+ torture_assert(tctx, !ok, "smbXcli_conn_is_connected still connected"); >+ >+ return true; >+} >+ >+static bool test_session_anon_encryption2(struct torture_context *tctx, >+ struct smb2_tree *tree0) >+{ >+ const char *host = torture_setting_string(tctx, "host", NULL); >+ const char *share = "IPC$"; >+ char *unc = NULL; >+ struct smb2_transport *transport0 = tree0->session->transport; >+ struct cli_credentials *_creds = samba_cmdline_get_creds(); >+ struct cli_credentials *user_creds = NULL; >+ struct cli_credentials *anon_creds = NULL; >+ struct smbcli_options options; >+ struct smb2_transport *transport = NULL; >+ struct smb2_session *user_session = NULL; >+ struct smb2_tree *user_tree = NULL; >+ struct smb2_session *anon_session = NULL; >+ struct smb2_tree *anon_tree = NULL; >+ struct smb2_ioctl ioctl = { >+ .level = RAW_IOCTL_SMB2, >+ .in = { >+ .file = { >+ .handle = { >+ .data = { >+ [0] = UINT64_MAX, >+ [1] = UINT64_MAX, >+ }, >+ }, >+ }, >+ .function = FSCTL_QUERY_NETWORK_INTERFACE_INFO, >+ /* Windows client sets this to 64KiB */ >+ .max_output_response = 0x10000, >+ .flags = SMB2_IOCTL_FLAG_IS_FSCTL, >+ }, >+ }; >+ NTSTATUS status; >+ bool ok = true; >+ struct tevent_req *subreq = NULL; >+ uint32_t timeout_msec; >+ uint32_t caps = smb2cli_conn_server_capabilities(transport0->conn); >+ NTSTATUS expected_mc_status; >+ >+ if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_00) { >+ torture_skip(tctx, >+ "Can't test without SMB3 support"); >+ } >+ >+ if (caps & SMB2_CAP_MULTI_CHANNEL) { >+ expected_mc_status = NT_STATUS_OK; >+ } else { >+ expected_mc_status = NT_STATUS_FS_DRIVER_REQUIRED; >+ } >+ >+ unc = talloc_asprintf(tctx, "\\\\%s\\%s", host, share); >+ torture_assert(tctx, unc != NULL, "talloc_asprintf"); >+ >+ user_creds = cli_credentials_shallow_copy(tctx, _creds); >+ torture_assert(tctx, user_creds != NULL, "cli_credentials_shallow_copy"); >+ ok = cli_credentials_set_smb_encryption(user_creds, >+ SMB_ENCRYPTION_REQUIRED, >+ CRED_SPECIFIED); >+ torture_assert(tctx, ok, "cli_credentials_set_smb_encryption"); >+ >+ anon_creds = cli_credentials_init_anon(tctx); >+ torture_assert(tctx, anon_creds != NULL, "cli_credentials_init_anon"); >+ ok = cli_credentials_set_smb_encryption(anon_creds, >+ SMB_ENCRYPTION_REQUIRED, >+ CRED_SPECIFIED); >+ torture_assert(tctx, ok, "cli_credentials_set_smb_encryption"); >+ >+ options = transport0->options; >+ options.client_guid = GUID_random(); >+ >+ status = smb2_connect(tctx, >+ host, >+ lpcfg_smb_ports(tctx->lp_ctx), >+ share, >+ lpcfg_resolve_context(tctx->lp_ctx), >+ user_creds, >+ &user_tree, >+ tctx->ev, >+ &options, >+ lpcfg_socket_options(tctx->lp_ctx), >+ lpcfg_gensec_settings(tctx, tctx->lp_ctx)); >+ torture_assert_ntstatus_ok(tctx, status, "smb2_connect failed"); >+ user_session = user_tree->session; >+ transport = user_session->transport; >+ ok = smb2cli_tcon_is_encryption_on(user_tree->smbXcli); >+ torture_assert(tctx, ok, "smb2cli_tcon_is_encryption_on(user)"); >+ ok = smbXcli_session_is_authenticated(user_session->smbXcli); >+ torture_assert(tctx, ok, "smbXcli_session_is_authenticated(user)"); >+ >+ anon_session = smb2_session_init(transport, >+ lpcfg_gensec_settings(tctx, tctx->lp_ctx), >+ tctx); >+ torture_assert(tctx, anon_session != NULL, "smb2_session_init(anon)"); >+ >+ anon_session->anonymous_session_key = true; >+ smb2cli_session_torture_anonymous_encryption(anon_session->smbXcli, true); >+ >+ status = smb2_session_setup_spnego(anon_session, >+ anon_creds, >+ 0 /* previous_session_id */); >+ torture_assert_ntstatus_ok(tctx, status, >+ "smb2_session_setup_spnego failed"); >+ >+ ok = smb2cli_tcon_is_encryption_on(user_tree->smbXcli); >+ torture_assert(tctx, ok, "smb2cli_tcon_is_encryption_on(anon)"); >+ ok = smbXcli_session_is_authenticated(anon_session->smbXcli); >+ torture_assert(tctx, !ok, "smbXcli_session_is_authenticated(anon) wrong"); >+ >+ anon_tree = smb2_tree_init(anon_session, tctx, false); >+ torture_assert(tctx, anon_tree != NULL, "smb2_tree_init"); >+ >+ timeout_msec = transport->options.request_timeout * 1000; >+ subreq = smb2cli_tcon_send(tctx, >+ tctx->ev, >+ transport->conn, >+ timeout_msec, >+ anon_session->smbXcli, >+ anon_tree->smbXcli, >+ 0, /* flags */ >+ unc); >+ torture_assert(tctx, subreq != NULL, "smb2cli_tcon_send"); >+ >+ torture_assert(tctx, >+ tevent_req_poll_ntstatus(subreq, tctx->ev, &status), >+ "tevent_req_poll_ntstatus"); >+ >+ status = smb2cli_tcon_recv(subreq); >+ TALLOC_FREE(subreq); >+ torture_assert_ntstatus_ok(tctx, status, >+ "smb2cli_tcon_recv(anon)"); >+ >+ ok = smbXcli_conn_is_connected(transport->conn); >+ torture_assert(tctx, ok, "smbXcli_conn_is_connected"); >+ >+ ok = smb2cli_tcon_is_encryption_on(anon_tree->smbXcli); >+ torture_assert(tctx, ok, "smb2cli_tcon_is_encryption_on(anon)"); >+ ok = smbXcli_session_is_authenticated(anon_session->smbXcli); >+ torture_assert(tctx, !ok, "smbXcli_session_is_authenticated(anon) wrong"); >+ >+ status = smb2_ioctl(user_tree, tctx, &ioctl); >+ torture_assert_ntstatus_equal(tctx, status, expected_mc_status, >+ "FSCTL_QUERY_NETWORK_INTERFACE_INFO user"); >+ >+ ok = smbXcli_conn_is_connected(transport->conn); >+ torture_assert(tctx, ok, "smbXcli_conn_is_connected"); >+ >+ status = smb2_ioctl(anon_tree, tctx, &ioctl); >+ torture_assert_ntstatus_equal(tctx, status, expected_mc_status, >+ "FSCTL_QUERY_NETWORK_INTERFACE_INFO anonymous"); >+ >+ ok = smbXcli_conn_is_connected(transport->conn); >+ torture_assert(tctx, ok, "smbXcli_conn_is_connected"); >+ >+ status = smb2_ioctl(user_tree, tctx, &ioctl); >+ torture_assert_ntstatus_equal(tctx, status, expected_mc_status, >+ "FSCTL_QUERY_NETWORK_INTERFACE_INFO user"); >+ >+ ok = smbXcli_conn_is_connected(transport->conn); >+ torture_assert(tctx, ok, "smbXcli_conn_is_connected"); >+ >+ status = smb2_ioctl(anon_tree, tctx, &ioctl); >+ torture_assert_ntstatus_equal(tctx, status, expected_mc_status, >+ "FSCTL_QUERY_NETWORK_INTERFACE_INFO anonymous"); >+ >+ ok = smbXcli_conn_is_connected(transport->conn); >+ torture_assert(tctx, ok, "smbXcli_conn_is_connected"); >+ >+ return true; >+} >+ >+static bool test_session_anon_encryption3(struct torture_context *tctx, >+ struct smb2_tree *tree0) >+{ >+ const char *host = torture_setting_string(tctx, "host", NULL); >+ const char *share = "IPC$"; >+ char *unc = NULL; >+ struct smb2_transport *transport0 = tree0->session->transport; >+ struct cli_credentials *_creds = samba_cmdline_get_creds(); >+ struct cli_credentials *user_creds = NULL; >+ struct cli_credentials *anon_creds = NULL; >+ struct smbcli_options options; >+ struct smb2_transport *transport = NULL; >+ struct smb2_session *user_session = NULL; >+ struct smb2_tree *user_tree = NULL; >+ struct smb2_session *anon_session = NULL; >+ struct smb2_tree *anon_tree = NULL; >+ NTSTATUS status; >+ bool ok = true; >+ struct tevent_req *subreq = NULL; >+ uint32_t timeout_msec; >+ uint8_t wrong_session_key[16] = { 0x1f, 0x2f, 0x3f, }; >+ >+ if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_00) { >+ torture_skip(tctx, >+ "Can't test without SMB3 support"); >+ } >+ >+ unc = talloc_asprintf(tctx, "\\\\%s\\%s", host, share); >+ torture_assert(tctx, unc != NULL, "talloc_asprintf"); >+ >+ user_creds = cli_credentials_shallow_copy(tctx, _creds); >+ torture_assert(tctx, user_creds != NULL, "cli_credentials_shallow_copy"); >+ ok = cli_credentials_set_smb_encryption(user_creds, >+ SMB_ENCRYPTION_REQUIRED, >+ CRED_SPECIFIED); >+ torture_assert(tctx, ok, "cli_credentials_set_smb_encryption"); >+ >+ anon_creds = cli_credentials_init_anon(tctx); >+ torture_assert(tctx, anon_creds != NULL, "cli_credentials_init_anon"); >+ ok = cli_credentials_set_smb_encryption(anon_creds, >+ SMB_ENCRYPTION_REQUIRED, >+ CRED_SPECIFIED); >+ torture_assert(tctx, ok, "cli_credentials_set_smb_encryption"); >+ >+ options = transport0->options; >+ options.client_guid = GUID_random(); >+ >+ status = smb2_connect(tctx, >+ host, >+ lpcfg_smb_ports(tctx->lp_ctx), >+ share, >+ lpcfg_resolve_context(tctx->lp_ctx), >+ user_creds, >+ &user_tree, >+ tctx->ev, >+ &options, >+ lpcfg_socket_options(tctx->lp_ctx), >+ lpcfg_gensec_settings(tctx, tctx->lp_ctx)); >+ torture_assert_ntstatus_ok(tctx, status, "smb2_connect failed"); >+ user_session = user_tree->session; >+ transport = user_session->transport; >+ ok = smb2cli_tcon_is_encryption_on(user_tree->smbXcli); >+ torture_assert(tctx, ok, "smb2cli_tcon_is_encryption_on(user)"); >+ ok = smbXcli_session_is_authenticated(user_session->smbXcli); >+ torture_assert(tctx, ok, "smbXcli_session_is_authenticated(user)"); >+ >+ anon_session = smb2_session_init(transport, >+ lpcfg_gensec_settings(tctx, tctx->lp_ctx), >+ tctx); >+ torture_assert(tctx, anon_session != NULL, "smb2_session_init(anon)"); >+ >+ anon_session->anonymous_session_key = true; >+ anon_session->forced_session_key = data_blob_const(wrong_session_key, >+ ARRAY_SIZE(wrong_session_key)); >+ smb2cli_session_torture_anonymous_encryption(anon_session->smbXcli, true); >+ >+ status = smb2_session_setup_spnego(anon_session, >+ anon_creds, >+ 0 /* previous_session_id */); >+ torture_assert_ntstatus_ok(tctx, status, >+ "smb2_session_setup_spnego failed"); >+ >+ ok = smb2cli_tcon_is_encryption_on(user_tree->smbXcli); >+ torture_assert(tctx, ok, "smb2cli_tcon_is_encryption_on(anon)"); >+ ok = smbXcli_session_is_authenticated(anon_session->smbXcli); >+ torture_assert(tctx, !ok, "smbXcli_session_is_authenticated(anon) wrong"); >+ >+ anon_tree = smb2_tree_init(anon_session, tctx, false); >+ torture_assert(tctx, anon_tree != NULL, "smb2_tree_init"); >+ >+ timeout_msec = transport->options.request_timeout * 1000; >+ subreq = smb2cli_tcon_send(tctx, >+ tctx->ev, >+ transport->conn, >+ timeout_msec, >+ anon_session->smbXcli, >+ anon_tree->smbXcli, >+ 0, /* flags */ >+ unc); >+ torture_assert(tctx, subreq != NULL, "smb2cli_tcon_send"); >+ >+ torture_assert(tctx, >+ tevent_req_poll_ntstatus(subreq, tctx->ev, &status), >+ "tevent_req_poll_ntstatus"); >+ >+ status = smb2cli_tcon_recv(subreq); >+ TALLOC_FREE(subreq); >+ if (NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED)) { >+ status = NT_STATUS_CONNECTION_RESET; >+ } >+ torture_assert_ntstatus_equal(tctx, status, >+ NT_STATUS_CONNECTION_RESET, >+ "smb2cli_tcon_recv"); >+ >+ ok = smbXcli_conn_is_connected(transport->conn); >+ torture_assert(tctx, !ok, "smbXcli_conn_is_connected still connected"); >+ >+ return true; >+} >+ >+static bool test_session_anon_signing1(struct torture_context *tctx, >+ struct smb2_tree *tree0) >+{ >+ const char *host = torture_setting_string(tctx, "host", NULL); >+ const char *share = "IPC$"; >+ char *unc = NULL; >+ struct smb2_transport *transport0 = tree0->session->transport; >+ struct cli_credentials *anon_creds = NULL; >+ struct smbcli_options options; >+ struct smb2_transport *transport = NULL; >+ struct smb2_session *anon_session = NULL; >+ struct smb2_tree *anon_tree = NULL; >+ NTSTATUS status; >+ bool ok = true; >+ struct tevent_req *subreq = NULL; >+ uint32_t timeout_msec; >+ >+ if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_00) { >+ torture_skip(tctx, >+ "Can't test without SMB3 support"); >+ } >+ >+ unc = talloc_asprintf(tctx, "\\\\%s\\%s", host, share); >+ torture_assert(tctx, unc != NULL, "talloc_asprintf"); >+ >+ anon_creds = cli_credentials_init_anon(tctx); >+ torture_assert(tctx, anon_creds != NULL, "cli_credentials_init_anon"); >+ ok = cli_credentials_set_smb_signing(anon_creds, >+ SMB_SIGNING_REQUIRED, >+ CRED_SPECIFIED); >+ torture_assert(tctx, ok, "cli_credentials_set_smb_signing"); >+ ok = cli_credentials_set_smb_ipc_signing(anon_creds, >+ SMB_SIGNING_REQUIRED, >+ CRED_SPECIFIED); >+ torture_assert(tctx, ok, "cli_credentials_set_smb_ipc_signing"); >+ ok = cli_credentials_set_smb_encryption(anon_creds, >+ SMB_ENCRYPTION_OFF, >+ CRED_SPECIFIED); >+ torture_assert(tctx, ok, "cli_credentials_set_smb_encryption"); >+ >+ options = transport0->options; >+ options.client_guid = GUID_random(); >+ options.only_negprot = true; >+ options.signing = SMB_SIGNING_REQUIRED; >+ >+ status = smb2_connect(tctx, >+ host, >+ lpcfg_smb_ports(tctx->lp_ctx), >+ share, >+ lpcfg_resolve_context(tctx->lp_ctx), >+ anon_creds, >+ &anon_tree, >+ tctx->ev, >+ &options, >+ lpcfg_socket_options(tctx->lp_ctx), >+ lpcfg_gensec_settings(tctx, tctx->lp_ctx)); >+ torture_assert_ntstatus_ok(tctx, status, "smb2_connect failed"); >+ anon_session = anon_tree->session; >+ transport = anon_session->transport; >+ >+ anon_session->anonymous_session_key = true; >+ smb2cli_session_torture_anonymous_signing(anon_session->smbXcli, true); >+ >+ status = smb2_session_setup_spnego(anon_session, >+ anon_creds, >+ 0 /* previous_session_id */); >+ torture_assert_ntstatus_ok(tctx, status, >+ "smb2_session_setup_spnego failed"); >+ >+ ok = smbXcli_session_is_authenticated(anon_session->smbXcli); >+ torture_assert(tctx, !ok, "smbXcli_session_is_authenticated(anon) wrong"); >+ >+ timeout_msec = transport->options.request_timeout * 1000; >+ subreq = smb2cli_tcon_send(tctx, >+ tctx->ev, >+ transport->conn, >+ timeout_msec, >+ anon_session->smbXcli, >+ anon_tree->smbXcli, >+ 0, /* flags */ >+ unc); >+ torture_assert(tctx, subreq != NULL, "smb2cli_tcon_send"); >+ >+ torture_assert(tctx, >+ tevent_req_poll_ntstatus(subreq, tctx->ev, &status), >+ "tevent_req_poll_ntstatus"); >+ >+ status = smb2cli_tcon_recv(subreq); >+ TALLOC_FREE(subreq); >+ torture_assert_ntstatus_ok(tctx, status, "smb2cli_tcon_recv"); >+ >+ ok = smbXcli_conn_is_connected(transport->conn); >+ torture_assert(tctx, ok, "smbXcli_conn_is_connected"); >+ >+ return true; >+} >+ >+static bool test_session_anon_signing2(struct torture_context *tctx, >+ struct smb2_tree *tree0) >+{ >+ const char *host = torture_setting_string(tctx, "host", NULL); >+ const char *share = "IPC$"; >+ char *unc = NULL; >+ struct smb2_transport *transport0 = tree0->session->transport; >+ struct cli_credentials *anon_creds = NULL; >+ struct smbcli_options options; >+ struct smb2_transport *transport = NULL; >+ struct smb2_session *anon_session = NULL; >+ struct smb2_session *anon_session_nosign = NULL; >+ struct smb2_tree *anon_tree = NULL; >+ NTSTATUS status; >+ bool ok = true; >+ struct tevent_req *subreq = NULL; >+ uint32_t timeout_msec; >+ uint8_t wrong_session_key[16] = { 0x1f, 0x2f, 0x3f, }; >+ uint64_t session_id; >+ >+ if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_00) { >+ torture_skip(tctx, >+ "Can't test without SMB3 support"); >+ } >+ >+ unc = talloc_asprintf(tctx, "\\\\%s\\%s", host, share); >+ torture_assert(tctx, unc != NULL, "talloc_asprintf"); >+ >+ anon_creds = cli_credentials_init_anon(tctx); >+ torture_assert(tctx, anon_creds != NULL, "cli_credentials_init_anon"); >+ ok = cli_credentials_set_smb_signing(anon_creds, >+ SMB_SIGNING_REQUIRED, >+ CRED_SPECIFIED); >+ torture_assert(tctx, ok, "cli_credentials_set_smb_signing"); >+ ok = cli_credentials_set_smb_ipc_signing(anon_creds, >+ SMB_SIGNING_REQUIRED, >+ CRED_SPECIFIED); >+ torture_assert(tctx, ok, "cli_credentials_set_smb_ipc_signing"); >+ ok = cli_credentials_set_smb_encryption(anon_creds, >+ SMB_ENCRYPTION_OFF, >+ CRED_SPECIFIED); >+ torture_assert(tctx, ok, "cli_credentials_set_smb_encryption"); >+ >+ options = transport0->options; >+ options.client_guid = GUID_random(); >+ options.only_negprot = true; >+ options.signing = SMB_SIGNING_REQUIRED; >+ >+ status = smb2_connect(tctx, >+ host, >+ lpcfg_smb_ports(tctx->lp_ctx), >+ share, >+ lpcfg_resolve_context(tctx->lp_ctx), >+ anon_creds, >+ &anon_tree, >+ tctx->ev, >+ &options, >+ lpcfg_socket_options(tctx->lp_ctx), >+ lpcfg_gensec_settings(tctx, tctx->lp_ctx)); >+ torture_assert_ntstatus_ok(tctx, status, "smb2_connect failed"); >+ anon_session = anon_tree->session; >+ transport = anon_session->transport; >+ >+ anon_session->anonymous_session_key = true; >+ anon_session->forced_session_key = data_blob_const(wrong_session_key, >+ ARRAY_SIZE(wrong_session_key)); >+ smb2cli_session_torture_anonymous_signing(anon_session->smbXcli, true); >+ smb2cli_session_torture_no_signing_disconnect(anon_session->smbXcli); >+ >+ status = smb2_session_setup_spnego(anon_session, >+ anon_creds, >+ 0 /* previous_session_id */); >+ torture_assert_ntstatus_ok(tctx, status, >+ "smb2_session_setup_spnego failed"); >+ >+ ok = smbXcli_session_is_authenticated(anon_session->smbXcli); >+ torture_assert(tctx, !ok, "smbXcli_session_is_authenticated(anon) wrong"); >+ >+ /* >+ * create a new structure for the same session id, >+ * but without smb2.should_sign set. >+ */ >+ session_id = smb2cli_session_current_id(anon_session->smbXcli); >+ anon_session_nosign = smb2_session_init(transport, >+ lpcfg_gensec_settings(tctx, tctx->lp_ctx), >+ tctx); >+ torture_assert(tctx, anon_session_nosign != NULL, "smb2_session_init(anon_nosign)"); >+ smb2cli_session_set_id_and_flags(anon_session_nosign->smbXcli, session_id, 0); >+ smb2cli_session_torture_no_signing_disconnect(anon_session_nosign->smbXcli); >+ >+ timeout_msec = transport->options.request_timeout * 1000; >+ subreq = smb2cli_tcon_send(tctx, >+ tctx->ev, >+ transport->conn, >+ timeout_msec, >+ anon_session->smbXcli, >+ anon_tree->smbXcli, >+ 0, /* flags */ >+ unc); >+ torture_assert(tctx, subreq != NULL, "smb2cli_tcon_send"); >+ >+ torture_assert(tctx, >+ tevent_req_poll_ntstatus(subreq, tctx->ev, &status), >+ "tevent_req_poll_ntstatus"); >+ >+ status = smb2cli_tcon_recv(subreq); >+ TALLOC_FREE(subreq); >+ torture_assert_ntstatus_equal(tctx, status, >+ NT_STATUS_ACCESS_DENIED, >+ "smb2cli_tcon_recv"); >+ >+ ok = smbXcli_conn_is_connected(transport->conn); >+ torture_assert(tctx, ok, "smbXcli_conn_is_connected"); >+ >+ subreq = smb2cli_tcon_send(tctx, >+ tctx->ev, >+ transport->conn, >+ timeout_msec, >+ anon_session_nosign->smbXcli, >+ anon_tree->smbXcli, >+ 0, /* flags */ >+ unc); >+ torture_assert(tctx, subreq != NULL, "smb2cli_tcon_send"); >+ >+ torture_assert(tctx, >+ tevent_req_poll_ntstatus(subreq, tctx->ev, &status), >+ "tevent_req_poll_ntstatus"); >+ >+ status = smb2cli_tcon_recv(subreq); >+ TALLOC_FREE(subreq); >+ torture_assert_ntstatus_ok(tctx, status, "smb2cli_tcon_recv"); >+ >+ ok = smbXcli_conn_is_connected(transport->conn); >+ torture_assert(tctx, ok, "smbXcli_conn_is_connected"); >+ >+ return true; >+} >+ > struct torture_suite *torture_smb2_session_init(TALLOC_CTX *ctx) > { > struct torture_suite *suite = >@@ -5599,6 +6223,11 @@ struct torture_suite *torture_smb2_session_init(TALLOC_CTX *ctx) > torture_suite_add_1smb2_test(suite, "encryption-aes-256-ccm", test_session_encryption_aes_256_ccm); > torture_suite_add_1smb2_test(suite, "encryption-aes-256-gcm", test_session_encryption_aes_256_gcm); > torture_suite_add_1smb2_test(suite, "ntlmssp_bug14932", test_session_ntlmssp_bug14932); >+ torture_suite_add_1smb2_test(suite, "anon-encryption1", test_session_anon_encryption1); >+ torture_suite_add_1smb2_test(suite, "anon-encryption2", test_session_anon_encryption2); >+ torture_suite_add_1smb2_test(suite, "anon-encryption3", test_session_anon_encryption3); >+ torture_suite_add_1smb2_test(suite, "anon-signing1", test_session_anon_signing1); >+ torture_suite_add_1smb2_test(suite, "anon-signing2", test_session_anon_signing2); > > suite->description = talloc_strdup(suite, "SMB2-SESSION tests"); > >-- >2.34.1 > > >From 89f5ac8b64afcccd4625ba809417f2fbcc6fa52e Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 3 Jul 2023 15:05:59 +0200 >Subject: [PATCH 04/10] s3:utils: remove unused signing_flags in > connections_forall() >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >We never use the signing flags from the session, as the tcon >has its own signing flags. > >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> >(cherry picked from commit a9f84593f44f15a19c4cdde1e7ad53cd5e03b4d9) >--- > source3/utils/conn_tdb.c | 2 -- > 1 file changed, 2 deletions(-) > >diff --git a/source3/utils/conn_tdb.c b/source3/utils/conn_tdb.c >index 3724bd424936..2689f71068ae 100644 >--- a/source3/utils/conn_tdb.c >+++ b/source3/utils/conn_tdb.c >@@ -44,7 +44,6 @@ struct connections_forall_session { > uint16_t cipher; > uint16_t dialect; > uint16_t signing; >- uint8_t signing_flags; > }; > > static int collect_sessions_fn(struct smbXsrv_session_global0 *global, >@@ -69,7 +68,6 @@ static int collect_sessions_fn(struct smbXsrv_session_global0 *global, > sess.cipher = global->channels[0].encryption_cipher; > sess.signing = global->channels[0].signing_algo; > sess.dialect = global->connection_dialect; >- sess.signing_flags = global->signing_flags; > > status = dbwrap_store(state->session_by_pid, > make_tdb_data((void*)&id, sizeof(id)), >-- >2.34.1 > > >From cc112bdc4e894ddc0a87fef3aa9aa6b774f52f5c Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 3 Jul 2023 15:08:31 +0200 >Subject: [PATCH 05/10] s3:lib: let sessionid_traverse_read() report if the > session was authenticated >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >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> >(cherry picked from commit 596a10d1079f5c4a954108c81efc862c22a11f28) >--- > source3/include/session.h | 1 + > source3/lib/sessionid_tdb.c | 8 ++++++++ > 2 files changed, 9 insertions(+) > >diff --git a/source3/include/session.h b/source3/include/session.h >index 268c059a8ed2..5a2b24b06a7d 100644 >--- a/source3/include/session.h >+++ b/source3/include/session.h >@@ -39,6 +39,7 @@ struct sessionid { > fstring ip_addr_str; > time_t connect_start; > uint16_t connection_dialect; >+ bool authenticated; > uint8_t encryption_flags; > uint16_t cipher; > uint16_t signing; >diff --git a/source3/lib/sessionid_tdb.c b/source3/lib/sessionid_tdb.c >index 32962253908f..68b178a52331 100644 >--- a/source3/lib/sessionid_tdb.c >+++ b/source3/lib/sessionid_tdb.c >@@ -24,6 +24,7 @@ > #include "session.h" > #include "util_tdb.h" > #include "smbd/globals.h" >+#include "../libcli/security/session.h" > > struct sessionid_traverse_read_state { > int (*fn)(const char *key, struct sessionid *session, >@@ -47,11 +48,18 @@ static int sessionid_traverse_read_fn(struct smbXsrv_session_global0 *global, > }; > > if (session_info != NULL) { >+ enum security_user_level ul; >+ > session.uid = session_info->unix_token->uid; > session.gid = session_info->unix_token->gid; > strncpy(session.username, > session_info->unix_info->unix_name, > sizeof(fstring)-1); >+ >+ ul = security_session_user_level(session_info, NULL); >+ if (ul >= SECURITY_USER) { >+ session.authenticated = true; >+ } > } > > strncpy(session.remote_machine, >-- >2.34.1 > > >From 70b9104d899edd1f633394af61181f20524b2d0a Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 3 Jul 2023 15:10:08 +0200 >Subject: [PATCH 06/10] s3:utils: let connections_forall_read() report if the > session was authenticated >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >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> >(cherry picked from commit 5089d8550640f72b1e0373f8ac321378ccaa8bd5) >--- > source3/utils/conn_tdb.c | 10 ++++++++++ > source3/utils/conn_tdb.h | 1 + > 2 files changed, 11 insertions(+) > >diff --git a/source3/utils/conn_tdb.c b/source3/utils/conn_tdb.c >index 2689f71068ae..3f4ef00ae4f1 100644 >--- a/source3/utils/conn_tdb.c >+++ b/source3/utils/conn_tdb.c >@@ -27,6 +27,7 @@ > #include "conn_tdb.h" > #include "util_tdb.h" > #include "lib/util/string_wrappers.h" >+#include "../libcli/security/session.h" > > struct connections_forall_state { > struct db_context *session_by_pid; >@@ -44,6 +45,7 @@ struct connections_forall_session { > uint16_t cipher; > uint16_t dialect; > uint16_t signing; >+ bool authenticated; > }; > > static int collect_sessions_fn(struct smbXsrv_session_global0 *global, >@@ -55,6 +57,7 @@ static int collect_sessions_fn(struct smbXsrv_session_global0 *global, > > uint32_t id = global->session_global_id; > struct connections_forall_session sess; >+ enum security_user_level ul; > > if (global->auth_session_info == NULL) { > sess.uid = -1; >@@ -68,6 +71,12 @@ static int collect_sessions_fn(struct smbXsrv_session_global0 *global, > sess.cipher = global->channels[0].encryption_cipher; > sess.signing = global->channels[0].signing_algo; > sess.dialect = global->connection_dialect; >+ ul = security_session_user_level(global->auth_session_info, NULL); >+ if (ul >= SECURITY_USER) { >+ sess.authenticated = true; >+ } else { >+ sess.authenticated = false; >+ } > > status = dbwrap_store(state->session_by_pid, > make_tdb_data((void*)&id, sizeof(id)), >@@ -132,6 +141,7 @@ static int traverse_tcon_fn(struct smbXsrv_tcon_global0 *global, > data.dialect = sess.dialect; > data.signing = sess.signing; > data.signing_flags = global->signing_flags; >+ data.authenticated = sess.authenticated; > > state->count++; > >diff --git a/source3/utils/conn_tdb.h b/source3/utils/conn_tdb.h >index 2a6e04e0a820..23a5e214ff2b 100644 >--- a/source3/utils/conn_tdb.h >+++ b/source3/utils/conn_tdb.h >@@ -36,6 +36,7 @@ struct connections_data { > uint16_t dialect; > uint8_t signing_flags; > uint16_t signing; >+ bool authenticated; > }; > > /* The following definitions come from lib/conn_tdb.c */ >-- >2.34.1 > > >From a27ff8f5cdccbb3359457650f2bbf130fae1342d Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 3 Jul 2023 15:12:38 +0200 >Subject: [PATCH 07/10] s3:utils: let smbstatus also report AES-256 encryption > types for tcons >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >We already do that for sessions. > >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> >(cherry picked from commit 8119fd6d6a49b869bd9e8ff653b500e194b070de) >--- > source3/utils/status.c | 6 ++++++ > 1 file changed, 6 insertions(+) > >diff --git a/source3/utils/status.c b/source3/utils/status.c >index cbdb0de67ede..1cb877567ac1 100644 >--- a/source3/utils/status.c >+++ b/source3/utils/status.c >@@ -548,6 +548,12 @@ static int traverse_connections(const struct connections_data *crec, > case SMB2_ENCRYPTION_AES128_GCM: > encryption = "AES-128-GCM"; > break; >+ case SMB2_ENCRYPTION_AES256_CCM: >+ encryption = "AES-256-CCM"; >+ break; >+ case SMB2_ENCRYPTION_AES256_GCM: >+ encryption = "AES-256-GCM"; >+ break; > default: > encryption = "???"; > break; >-- >2.34.1 > > >From cc6b0862e09652a7a3c412ea8c8d7aa236371949 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 3 Jul 2023 15:12:38 +0200 >Subject: [PATCH 08/10] s3:utils: let smbstatus also report partial tcon > signing/encryption >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >We already do that for sessions and also for the json output, >but it was missing in the non-json output for tcons. > >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> >(cherry picked from commit 551756abd2c9e4922075bc3037db645355542363) >--- > source3/utils/status.c | 48 ++++++++++++++++++++++++++++++++++++------ > 1 file changed, 41 insertions(+), 7 deletions(-) > >diff --git a/source3/utils/status.c b/source3/utils/status.c >index 1cb877567ac1..e68fd09f4971 100644 >--- a/source3/utils/status.c >+++ b/source3/utils/status.c >@@ -482,9 +482,29 @@ static int traverse_connections_stdout(struct traverse_state *state, > char *server_id, > const char *machine, > const char *timestr, >- const char *encryption, >- const char *signing) >+ const char *encryption_cipher, >+ enum crypto_degree encryption_degree, >+ const char *signing_cipher, >+ enum crypto_degree signing_degree) > { >+ fstring encryption; >+ fstring signing; >+ >+ if (encryption_degree == CRYPTO_DEGREE_FULL) { >+ fstr_sprintf(encryption, "%s", encryption_cipher); >+ } else if (encryption_degree == CRYPTO_DEGREE_PARTIAL) { >+ fstr_sprintf(encryption, "partial(%s)", encryption_cipher); >+ } else { >+ fstr_sprintf(encryption, "-"); >+ } >+ if (signing_degree == CRYPTO_DEGREE_FULL) { >+ fstr_sprintf(signing, "%s", signing_cipher); >+ } else if (signing_degree == CRYPTO_DEGREE_PARTIAL) { >+ fstr_sprintf(signing, "partial(%s)", signing_cipher); >+ } else { >+ fstr_sprintf(signing, "-"); >+ } >+ > d_printf("%-12s %-7s %-13s %-32s %-12s %-12s\n", > servicename, server_id, machine, timestr, encryption, signing); > >@@ -537,7 +557,9 @@ static int traverse_connections(const struct connections_data *crec, > return -1; > } > >- if (smbXsrv_is_encrypted(crec->encryption_flags)) { >+ if (smbXsrv_is_encrypted(crec->encryption_flags) || >+ smbXsrv_is_partially_encrypted(crec->encryption_flags)) >+ { > switch (crec->cipher) { > case SMB_ENCRYPTION_GSSAPI: > encryption = "GSSAPI"; >@@ -558,10 +580,16 @@ static int traverse_connections(const struct connections_data *crec, > encryption = "???"; > break; > } >- encryption_degree = CRYPTO_DEGREE_FULL; >+ if (smbXsrv_is_encrypted(crec->encryption_flags)) { >+ encryption_degree = CRYPTO_DEGREE_FULL; >+ } else if (smbXsrv_is_partially_encrypted(crec->encryption_flags)) { >+ encryption_degree = CRYPTO_DEGREE_PARTIAL; >+ } > } > >- if (smbXsrv_is_signed(crec->signing_flags)) { >+ if (smbXsrv_is_signed(crec->signing_flags) || >+ smbXsrv_is_partially_signed(crec->signing_flags)) >+ { > switch (crec->signing) { > case SMB2_SIGNING_MD5_SMB1: > signing = "HMAC-MD5"; >@@ -579,7 +607,11 @@ static int traverse_connections(const struct connections_data *crec, > signing = "???"; > break; > } >- signing_degree = CRYPTO_DEGREE_FULL; >+ if (smbXsrv_is_signed(crec->signing_flags)) { >+ signing_degree = CRYPTO_DEGREE_FULL; >+ } else if (smbXsrv_is_partially_signed(crec->signing_flags)) { >+ signing_degree = CRYPTO_DEGREE_PARTIAL; >+ } > } > > if (!state->json_output) { >@@ -589,7 +621,9 @@ static int traverse_connections(const struct connections_data *crec, > crec->machine, > timestr, > encryption, >- signing); >+ encryption_degree, >+ signing, >+ signing_degree); > } else { > result = traverse_connections_json(state, > crec, >-- >2.34.1 > > >From 22adac29adffb2d7080434c8a8a8e8a688149514 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 30 Jun 2023 18:05:51 +0200 >Subject: [PATCH 09/10] s3:smbd: allow anonymous encryption after one > authenticated session setup >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >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> >(cherry picked from commit f3ddfb828e66738ca461c3284c423defb774547c) >--- > selftest/knownfail.d/anon-encryption | 1 - > source3/smbd/globals.h | 5 +++++ > source3/smbd/smb2_server.c | 11 +++++++++++ > source3/smbd/smb2_sesssetup.c | 18 +++++++++++++++++- > source3/smbd/smb2_tcon.c | 4 ++++ > 5 files changed, 37 insertions(+), 2 deletions(-) > delete mode 100644 selftest/knownfail.d/anon-encryption > >diff --git a/selftest/knownfail.d/anon-encryption b/selftest/knownfail.d/anon-encryption >deleted file mode 100644 >index 99d833c205a1..000000000000 >--- a/selftest/knownfail.d/anon-encryption >+++ /dev/null >@@ -1 +0,0 @@ >-^samba3.smb2.session.*.anon-encryption2 >diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h >index 69023fcc50a1..f92721a2c187 100644 >--- a/source3/smbd/globals.h >+++ b/source3/smbd/globals.h >@@ -549,6 +549,11 @@ struct smbXsrv_connection { > } smbtorture; > > bool signing_mandatory; >+ /* >+ * This is ConstrainedConnection in MS-SMB2, >+ * but with reversed value... >+ */ >+ bool got_authenticated_session; > } smb2; > }; > >diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c >index 5a595313cd0f..886e6abced81 100644 >--- a/source3/smbd/smb2_server.c >+++ b/source3/smbd/smb2_server.c >@@ -491,6 +491,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)); >diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c >index e15a83d765a6..47bed6528ad2 100644 >--- a/source3/smbd/smb2_sesssetup.c >+++ b/source3/smbd/smb2_sesssetup.c >@@ -271,6 +271,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)) { >@@ -288,7 +295,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; > } > >@@ -642,6 +652,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; >diff --git a/source3/smbd/smb2_tcon.c b/source3/smbd/smb2_tcon.c >index 5bd01c77e053..1fad6e54e366 100644 >--- a/source3/smbd/smb2_tcon.c >+++ b/source3/smbd/smb2_tcon.c >@@ -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; > } >-- >2.34.1 > > >From a6ace21ed83a83578d2bb6591b603384275c5a0f Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 3 Jul 2023 15:14:38 +0200 >Subject: [PATCH 10/10] s3:utils: let smbstatus report anonymous > signing/encryption explicitly >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >We should mark sessions/tcons with anonymous encryption or signing >in a special way, as the value of it is void, all based on a >session key with 16 zero bytes. > >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> > >Autobuild-User(master): Stefan Metzmacher <metze@samba.org> >Autobuild-Date(master): Thu May 23 13:37:09 UTC 2024 on atb-devel-224 > >(cherry picked from commit 5a54c9b28abb1464c84cb4be15a49718d8ae6795) >--- > source3/utils/status.c | 28 ++++++++++++++++++++++++++++ > source3/utils/status.h | 1 + > source3/utils/status_json.c | 2 ++ > 3 files changed, 31 insertions(+) > >diff --git a/source3/utils/status.c b/source3/utils/status.c >index e68fd09f4971..38a534948c57 100644 >--- a/source3/utils/status.c >+++ b/source3/utils/status.c >@@ -492,6 +492,8 @@ static int traverse_connections_stdout(struct traverse_state *state, > > if (encryption_degree == CRYPTO_DEGREE_FULL) { > fstr_sprintf(encryption, "%s", encryption_cipher); >+ } else if (encryption_degree == CRYPTO_DEGREE_ANONYMOUS) { >+ fstr_sprintf(encryption, "anonymous(%s)", encryption_cipher); > } else if (encryption_degree == CRYPTO_DEGREE_PARTIAL) { > fstr_sprintf(encryption, "partial(%s)", encryption_cipher); > } else { >@@ -499,6 +501,8 @@ static int traverse_connections_stdout(struct traverse_state *state, > } > if (signing_degree == CRYPTO_DEGREE_FULL) { > fstr_sprintf(signing, "%s", signing_cipher); >+ } else if (signing_degree == CRYPTO_DEGREE_ANONYMOUS) { >+ fstr_sprintf(signing, "anonymous(%s)", signing_cipher); > } else if (signing_degree == CRYPTO_DEGREE_PARTIAL) { > fstr_sprintf(signing, "partial(%s)", signing_cipher); > } else { >@@ -585,6 +589,11 @@ static int traverse_connections(const struct connections_data *crec, > } else if (smbXsrv_is_partially_encrypted(crec->encryption_flags)) { > encryption_degree = CRYPTO_DEGREE_PARTIAL; > } >+ if (encryption_degree != CRYPTO_DEGREE_NONE && >+ !crec->authenticated) >+ { >+ encryption_degree = CRYPTO_DEGREE_ANONYMOUS; >+ } > } > > if (smbXsrv_is_signed(crec->signing_flags) || >@@ -612,6 +621,11 @@ static int traverse_connections(const struct connections_data *crec, > } else if (smbXsrv_is_partially_signed(crec->signing_flags)) { > signing_degree = CRYPTO_DEGREE_PARTIAL; > } >+ if (signing_degree != CRYPTO_DEGREE_NONE && >+ !crec->authenticated) >+ { >+ signing_degree = CRYPTO_DEGREE_ANONYMOUS; >+ } > } > > if (!state->json_output) { >@@ -654,6 +668,8 @@ static int traverse_sessionid_stdout(struct traverse_state *state, > > if (encryption_degree == CRYPTO_DEGREE_FULL) { > fstr_sprintf(encryption, "%s", encryption_cipher); >+ } else if (encryption_degree == CRYPTO_DEGREE_ANONYMOUS) { >+ fstr_sprintf(encryption, "anonymous(%s)", encryption_cipher); > } else if (encryption_degree == CRYPTO_DEGREE_PARTIAL) { > fstr_sprintf(encryption, "partial(%s)", encryption_cipher); > } else { >@@ -661,6 +677,8 @@ static int traverse_sessionid_stdout(struct traverse_state *state, > } > if (signing_degree == CRYPTO_DEGREE_FULL) { > fstr_sprintf(signing, "%s", signing_cipher); >+ } else if (signing_degree == CRYPTO_DEGREE_ANONYMOUS) { >+ fstr_sprintf(signing, "anonymous(%s)", signing_cipher); > } else if (signing_degree == CRYPTO_DEGREE_PARTIAL) { > fstr_sprintf(signing, "partial(%s)", signing_cipher); > } else { >@@ -795,6 +813,11 @@ static int traverse_sessionid(const char *key, struct sessionid *session, > } else if (smbXsrv_is_partially_encrypted(session->encryption_flags)) { > encryption_degree = CRYPTO_DEGREE_PARTIAL; > } >+ if (encryption_degree != CRYPTO_DEGREE_NONE && >+ !session->authenticated) >+ { >+ encryption_degree = CRYPTO_DEGREE_ANONYMOUS; >+ } > } > > if (smbXsrv_is_signed(session->signing_flags) || >@@ -822,6 +845,11 @@ static int traverse_sessionid(const char *key, struct sessionid *session, > } else if (smbXsrv_is_partially_signed(session->signing_flags)) { > signing_degree = CRYPTO_DEGREE_PARTIAL; > } >+ if (signing_degree != CRYPTO_DEGREE_NONE && >+ !session->authenticated) >+ { >+ signing_degree = CRYPTO_DEGREE_ANONYMOUS; >+ } > } > > >diff --git a/source3/utils/status.h b/source3/utils/status.h >index c08aba4c2624..6674f0db54fe 100644 >--- a/source3/utils/status.h >+++ b/source3/utils/status.h >@@ -38,6 +38,7 @@ struct traverse_state { > enum crypto_degree { > CRYPTO_DEGREE_NONE, > CRYPTO_DEGREE_PARTIAL, >+ CRYPTO_DEGREE_ANONYMOUS, > CRYPTO_DEGREE_FULL > }; > >diff --git a/source3/utils/status_json.c b/source3/utils/status_json.c >index 79cb1dfe1e41..850fc67e5513 100644 >--- a/source3/utils/status_json.c >+++ b/source3/utils/status_json.c >@@ -257,6 +257,8 @@ static int add_crypto_to_json(struct json_object *parent_json, > > if (degree == CRYPTO_DEGREE_NONE) { > degree_str = "none"; >+ } else if (degree == CRYPTO_DEGREE_ANONYMOUS) { >+ degree_str = "anonymous"; > } else if (degree == CRYPTO_DEGREE_PARTIAL) { > degree_str = "partial"; > } else { >-- >2.34.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Flags:
gd
:
review+
Actions:
View
Attachments on
bug 15412
:
18306
| 18307