summaryrefslogtreecommitdiffstats
path: root/libcli/smb/smbXcli_base.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libcli/smb/smbXcli_base.c104
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