From c682472fdf28894858d14eb95b13cb4214847ecd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 12 Sep 2011 09:16:27 +0200 Subject: s3:libsmb: make use of new advanded SMB signing metze --- source3/libsmb/cliconnect.c | 59 +++++++++++++++++++++------------------------ source3/libsmb/clientgen.c | 47 +++++++++++++++++++++++------------- source3/libsmb/clisigning.c | 11 +++------ source3/libsmb/proto.h | 4 +-- 4 files changed, 64 insertions(+), 57 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 4ebabceaa7..54cd669c10 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -944,7 +944,6 @@ static struct tevent_req *cli_session_setup_nt1_send( SMBsesskeygen_ntv1(nt_hash, session_key.data); #endif } - cli_temp_set_signing(cli); } else { /* pre-encrypted password supplied. Only used for security=server, can't do @@ -1444,8 +1443,6 @@ static struct tevent_req *cli_session_setup_kerberos_send( state->cli = cli; state->ads_status = ADS_SUCCESS; - cli_temp_set_signing(cli); - /* * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if * we have to acquire a ticket. To be fixed later :-) @@ -1590,8 +1587,6 @@ static struct tevent_req *cli_session_setup_ntlmssp_send( talloc_set_destructor( state, cli_session_setup_ntlmssp_state_destructor); - cli_temp_set_signing(cli); - status = ntlmssp_client_start(state, lp_netbios_name(), lp_workgroup(), @@ -2643,7 +2638,11 @@ static void cli_negprot_done(struct tevent_req *subreq) if (cli_state_protocol(cli) >= PROTOCOL_NT1) { struct timespec ts; - bool negotiated_smb_signing = false; + const char *client_signing = NULL; + bool server_mandatory; + bool server_allowed; + const char *server_signing = NULL; + bool ok; if (wct != 0x11) { tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); @@ -2678,35 +2677,33 @@ static void cli_negprot_done(struct tevent_req *subreq) } } - /* - * As signing is slow we only turn it on if either the client or - * the server require it. JRA. - */ + client_signing = "disabled"; + if (client_is_signing_allowed(cli)) { + client_signing = "allowed"; + } + if (client_is_signing_mandatory(cli)) { + client_signing = "required"; + } + server_signing = "not supported"; + if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) { + server_signing = "supported"; + server_allowed = true; + } if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) { - /* Fail if server says signing is mandatory and we don't want to support it. */ - if (!client_is_signing_allowed(cli)) { - DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n")); - tevent_req_nterror(req, - NT_STATUS_ACCESS_DENIED); - return; - } - negotiated_smb_signing = true; - } else if (client_is_signing_mandatory(cli) && client_is_signing_allowed(cli)) { - /* Fail if client says signing is mandatory and the server doesn't support it. */ - if (!(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) { - DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n")); - tevent_req_nterror(req, - NT_STATUS_ACCESS_DENIED); - return; - } - negotiated_smb_signing = true; - } else if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) { - negotiated_smb_signing = true; + server_signing = "required"; + server_mandatory = true; } - if (negotiated_smb_signing) { - cli_set_signing_negotiated(cli); + ok = cli_set_signing_negotiated(cli, + server_allowed, + server_mandatory); + if (!ok) { + DEBUG(1,("cli_negprot: SMB signing is required, " + "but client[%s] and server[%s] mismatch\n", + client_signing, server_signing)); + tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); + return; } } else if (cli_state_protocol(cli) >= PROTOCOL_LANMAN1) { diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 15e450a802..c22cd303e5 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -168,8 +168,9 @@ struct cli_state *cli_state_create(TALLOC_CTX *mem_ctx, int signing_state, int flags) { struct cli_state *cli = NULL; - bool allow_smb_signing = false; - bool mandatory_signing = false; + bool allow_smb_signing; + bool desire_smb_signing; + bool mandatory_signing; socklen_t ss_length; int ret; @@ -236,31 +237,43 @@ struct cli_state *cli_state_create(TALLOC_CTX *mem_ctx, cli->use_level_II_oplocks = true; } - if (lp_client_signing()) { - allow_smb_signing = true; - } - - if (lp_client_signing() == Required) { - mandatory_signing = true; - } - - if (signing_state != Undefined) { - allow_smb_signing = true; + if (signing_state == Undefined) { + signing_state = lp_client_signing(); } - if (signing_state == false) { + switch (signing_state) { + case false: + /* never */ allow_smb_signing = false; + desire_smb_signing = false; mandatory_signing = false; - } - - if (signing_state == Required) { + break; + case true: + /* if the server supports it */ + allow_smb_signing = true; + desire_smb_signing = true; + mandatory_signing = false; + break; + default: + case Undefined: + case Auto: + /* if the server requires it */ + allow_smb_signing = true; + desire_smb_signing = false; + mandatory_signing = false; + break; + case Required: + /* always */ + allow_smb_signing = true; + desire_smb_signing = true; mandatory_signing = true; + break; } /* initialise signing */ cli->signing_state = smb_signing_init(cli, allow_smb_signing, - allow_smb_signing, + desire_smb_signing, mandatory_signing); if (!cli->signing_state) { goto error; diff --git a/source3/libsmb/clisigning.c b/source3/libsmb/clisigning.c index 134938fc89..acdc24faeb 100644 --- a/source3/libsmb/clisigning.c +++ b/source3/libsmb/clisigning.c @@ -42,11 +42,6 @@ bool cli_simple_set_signing(struct cli_state *cli, return true; } -bool cli_temp_set_signing(struct cli_state *cli) -{ - return true; -} - void cli_calculate_sign_mac(struct cli_state *cli, char *buf, uint32_t *seqnum) { *seqnum = smb_signing_next_seqnum(cli->signing_state, false); @@ -68,9 +63,11 @@ bool cli_check_sign_mac(struct cli_state *cli, const char *buf, uint32_t seqnum) return true; } -void cli_set_signing_negotiated(struct cli_state *cli) +bool cli_set_signing_negotiated(struct cli_state *cli, + bool allowed, bool mandatory) { - smb_signing_set_negotiated(cli->signing_state, true, false); + return smb_signing_set_negotiated(cli->signing_state, + allowed, mandatory); } bool client_is_signing_on(struct cli_state *cli) diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h index fef7ae0502..4992d95c96 100644 --- a/source3/libsmb/proto.h +++ b/source3/libsmb/proto.h @@ -865,13 +865,13 @@ void cli_free_enc_buffer(struct cli_state *cli, char *buf); bool cli_simple_set_signing(struct cli_state *cli, const DATA_BLOB user_session_key, const DATA_BLOB response); -bool cli_temp_set_signing(struct cli_state *cli); void cli_calculate_sign_mac(struct cli_state *cli, char *buf, uint32_t *seqnum); bool cli_check_sign_mac(struct cli_state *cli, const char *buf, uint32_t seqnum); bool client_is_signing_on(struct cli_state *cli); bool client_is_signing_allowed(struct cli_state *cli); bool client_is_signing_mandatory(struct cli_state *cli); -void cli_set_signing_negotiated(struct cli_state *cli); +bool cli_set_signing_negotiated(struct cli_state *cli, + bool allowed, bool mandatory); /* The following definitions come from libsmb/reparse_symlink.c */ -- cgit