diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-20 04:07:27 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-20 04:07:27 +0000 |
commit | 31bdcfe4b647c8c783efa32da3c333b5f166a42d (patch) | |
tree | 2b868e2a40cde0854fa0f5466ea8990d3d38f93d /libcli/smb/smbXcli_base.c | |
parent | Adding upstream version 2:4.20.1+dfsg. (diff) | |
download | samba-upstream.tar.xz samba-upstream.zip |
Adding upstream version 2:4.20.2+dfsg.upstream/2%4.20.2+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'libcli/smb/smbXcli_base.c')
-rw-r--r-- | libcli/smb/smbXcli_base.c | 104 |
1 files changed, 99 insertions, 5 deletions
diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c index a52a615..87acddf 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; } } @@ -6332,6 +6363,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) { @@ -6432,6 +6480,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, @@ -6441,6 +6493,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, @@ -6459,6 +6520,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, @@ -6468,6 +6533,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); @@ -6477,6 +6544,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) { /* @@ -6492,10 +6571,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); @@ -6527,6 +6602,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 @@ -6698,6 +6782,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 |