1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

smbXcli_base: add hacks to test anonymous signing and encryption

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>
This commit is contained in:
Stefan Metzmacher 2024-05-14 18:21:33 +02:00
parent d6581d213d
commit 14d6e26721
2 changed files with 104 additions and 5 deletions

View 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

View 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,