From 982bdcf427008138a1c7c8d3f2756de1c5126d6b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 13 Jul 2021 21:26:19 +0200 Subject: [PATCH] libcli/smb: actually make use of "client/server smb3 signing algorithms" Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- libcli/smb/smb2_negotiate_context.h | 2 ++ libcli/smb/smbXcli_base.c | 1 + libcli/smb/util.c | 33 ++++++++++++++++++++++++++++- source3/libsmb/clientgen.c | 1 + source3/smbd/smb2_negprot.c | 2 ++ source4/param/loadparm.c | 1 + 6 files changed, 39 insertions(+), 1 deletion(-) diff --git a/libcli/smb/smb2_negotiate_context.h b/libcli/smb/smb2_negotiate_context.h index 47ed6c94e8c..e08bf424d95 100644 --- a/libcli/smb/smb2_negotiate_context.h +++ b/libcli/smb/smb2_negotiate_context.h @@ -77,6 +77,7 @@ const char *smb3_signing_algorithm_name(uint16_t algo); const char *smb3_encryption_algorithm_name(uint16_t algo); struct smb311_capabilities smb311_capabilities_parse(const char *role, + const char * const *signing_algos, const char * const *encryption_algos); NTSTATUS smb311_capabilities_check(const struct smb311_capabilities *c, @@ -85,6 +86,7 @@ NTSTATUS smb311_capabilities_check(const struct smb311_capabilities *c, NTSTATUS error_status, const char *role, enum protocol_types protocol, + uint16_t sign_algo, uint16_t cipher_algo); #endif /* _LIBCLI_SMB_SMB2_NEGOTIATE_BLOB_H_ */ diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c index c2d70ee016d..341a371d8b8 100644 --- a/libcli/smb/smbXcli_base.c +++ b/libcli/smb/smbXcli_base.c @@ -5415,6 +5415,7 @@ static NTSTATUS smbXcli_negprot_smb3_check_capabilities(struct tevent_req *req) NT_STATUS_ACCESS_DENIED, "client", conn->protocol, + conn->smb2.server.sign_algo, conn->smb2.server.cipher); } diff --git a/libcli/smb/util.c b/libcli/smb/util.c index 362486375a9..4cb47aafd07 100644 --- a/libcli/smb/util.c +++ b/libcli/smb/util.c @@ -531,9 +531,9 @@ static int32_t parse_enum_val(const struct enum_list *e, } struct smb311_capabilities smb311_capabilities_parse(const char *role, + const char * const *signing_algos, const char * const *encryption_algos) { - const char * const *signing_algos = NULL; struct smb311_capabilities c = { .signing = { .num_algos = 0, @@ -638,13 +638,27 @@ NTSTATUS smb311_capabilities_check(const struct smb311_capabilities *c, NTSTATUS error_status, const char *role, enum protocol_types protocol, + uint16_t sign_algo, uint16_t cipher_algo) { + const struct smb3_signing_capabilities *sign_algos = + &c->signing; const struct smb3_encryption_capabilities *ciphers = &c->encryption; + bool found_signing = false; bool found_encryption = false; size_t i; + for (i = 0; i < sign_algos->num_algos; i++) { + if (sign_algo == sign_algos->algos[i]) { + /* + * We found a match + */ + found_signing = true; + break; + } + } + for (i = 0; i < ciphers->num_algos; i++) { if (cipher_algo == SMB2_ENCRYPTION_NONE) { /* @@ -663,6 +677,23 @@ NTSTATUS smb311_capabilities_check(const struct smb311_capabilities *c, } } + if (!found_signing) { + /* + * We negotiated a signing algo we don't allow, + * most likely for SMB < 3.1.1 + */ + DEBUG(debug_lvl,("%s: " + "SMB3 signing algorithm[%u][%s] on dialect[%s] " + "not allowed by '%s smb3 signing algorithms' - %s.\n", + debug_prefix, + sign_algo, + smb3_signing_algorithm_name(sign_algo), + smb_protocol_types_string(protocol), + role, + nt_errstr(error_status))); + return error_status; + } + if (!found_encryption) { /* * We negotiated a cipher we don't allow, diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index c81625c9a9b..b9b2bacaa76 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -72,6 +72,7 @@ struct cli_state *cli_state_create(TALLOC_CTX *mem_ctx, uint32_t smb2_capabilities = 0; struct smb311_capabilities smb3_capabilities = smb311_capabilities_parse("client", + lp_client_smb3_signing_algorithms(), lp_client_smb3_encryption_algorithms()); struct GUID client_guid; diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c index a9014ae3439..c6c9e50e32a 100644 --- a/source3/smbd/smb2_negprot.c +++ b/source3/smbd/smb2_negprot.c @@ -160,6 +160,7 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req) struct smb2_negotiate_contexts out_c = { .num_contexts = 0, }; const struct smb311_capabilities default_smb3_capabilities = smb311_capabilities_parse("server", + lp_server_smb3_signing_algorithms(), lp_server_smb3_encryption_algorithms()); DATA_BLOB out_negotiate_context_blob = data_blob_null; uint32_t out_negotiate_context_offset = 0; @@ -621,6 +622,7 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req) NT_STATUS_INVALID_PARAMETER, "server", protocol, + xconn->smb2.server.sign_algo, xconn->smb2.server.cipher); if (!NT_STATUS_IS_OK(status)) { return smbd_smb2_request_error(req, status); diff --git a/source4/param/loadparm.c b/source4/param/loadparm.c index 9a040e2913e..81892d540ef 100644 --- a/source4/param/loadparm.c +++ b/source4/param/loadparm.c @@ -51,6 +51,7 @@ void lpcfg_smbcli_options(struct loadparm_context *lp_ctx, .client_guid = GUID_random(), .max_credits = WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK, .smb3_capabilities = smb311_capabilities_parse("client", + lpcfg_client_smb3_signing_algorithms(lp_ctx), lpcfg_client_smb3_encryption_algorithms(lp_ctx)), }; }