[SCM] Samba Shared Repository - branch master updated
Stefan Metzmacher
metze at samba.org
Wed Sep 14 01:42:04 MDT 2011
The branch, master has been updated
via abb24bf s3:smbd: make use of better SMB signing negotiation
via c682472 s3:libsmb: make use of new advanded SMB signing
via 0a6d0f8 s3:smb_signing: add support for easier negotiation of SMB signing
via f205e4c s3:smbd: echo FLAGS2_SMB_SECURITY_SIGNATURES* and the signature field in the reply
from cb064f2 tdb2: remove bogus leftover .orig file.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit abb24bf8e874d525382e994af7ae432212775153
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Sep 12 09:19:06 2011 +0200
s3:smbd: make use of better SMB signing negotiation
metze
Autobuild-User: Stefan Metzmacher <metze at samba.org>
Autobuild-Date: Wed Sep 14 09:41:02 CEST 2011 on sn-devel-104
commit c682472fdf28894858d14eb95b13cb4214847ecd
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Sep 12 09:16:27 2011 +0200
s3:libsmb: make use of new advanded SMB signing
metze
commit 0a6d0f8edaa198898f50f274275efba8de41d843
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Sep 12 09:04:53 2011 +0200
s3:smb_signing: add support for easier negotiation of SMB signing
We don't make use of it yet, but it will follow.
metze
commit f205e4cada0a2e5d1289b5a1482dd670c65b1dfd
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Sep 9 22:44:44 2011 +0200
s3:smbd: echo FLAGS2_SMB_SECURITY_SIGNATURES* and the signature field in the reply
This matches what windows is doing.
metze
-----------------------------------------------------------------------
Summary of changes:
source3/include/smb_signing.h | 5 ++-
source3/libsmb/cliconnect.c | 59 +++++++++++-------------
source3/libsmb/clientgen.c | 46 ++++++++++++-------
source3/libsmb/clisigning.c | 11 ++---
source3/libsmb/proto.h | 4 +-
source3/libsmb/smb_signing.c | 100 ++++++++++++++++++++++++++++-------------
source3/smbd/negprot.c | 1 -
source3/smbd/process.c | 12 ++++-
source3/smbd/proto.h | 3 +-
source3/smbd/sesssetup.c | 18 +++++++
source3/smbd/signing.c | 21 +++++++--
11 files changed, 183 insertions(+), 97 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source3/include/smb_signing.h b/source3/include/smb_signing.h
index d2eda9b..481be1d 100644
--- a/source3/include/smb_signing.h
+++ b/source3/include/smb_signing.h
@@ -26,9 +26,11 @@ struct smb_signing_state;
struct smb_signing_state *smb_signing_init(TALLOC_CTX *mem_ctx,
bool allowed,
+ bool desired,
bool mandatory);
struct smb_signing_state *smb_signing_init_ex(TALLOC_CTX *mem_ctx,
bool allowed,
+ bool desired,
bool mandatory,
void *(*alloc_fn)(TALLOC_CTX *, size_t),
void (*free_fn)(TALLOC_CTX *, void *));
@@ -45,7 +47,8 @@ bool smb_signing_activate(struct smb_signing_state *si,
bool smb_signing_is_active(struct smb_signing_state *si);
bool smb_signing_is_allowed(struct smb_signing_state *si);
bool smb_signing_is_mandatory(struct smb_signing_state *si);
-bool smb_signing_set_negotiated(struct smb_signing_state *si);
+bool smb_signing_set_negotiated(struct smb_signing_state *si,
+ bool allowed, bool mandatory);
bool smb_signing_is_negotiated(struct smb_signing_state *si);
#endif /* _SMB_SIGNING_H_ */
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 4ebabce..54cd669 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 db5e545..c22cd30 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,30 +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,
+ desire_smb_signing,
mandatory_signing);
if (!cli->signing_state) {
goto error;
diff --git a/source3/libsmb/clisigning.c b/source3/libsmb/clisigning.c
index ac4db76..acdc24f 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 smb_signing_set_bsrspyl(cli->signing_state);
-}
-
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);
+ 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 fef7ae0..4992d95 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 */
diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c
index c926b48..ba20723 100644
--- a/source3/libsmb/smb_signing.c
+++ b/source3/libsmb/smb_signing.c
@@ -29,15 +29,15 @@ struct smb_signing_state {
/* is signing localy allowed */
bool allowed;
+ /* is signing localy desired */
+ bool desired;
+
/* is signing localy mandatory */
bool mandatory;
/* is signing negotiated by the peer */
bool negotiated;
- /* send BSRSPYL signatures */
- bool bsrspyl;
-
bool active; /* Have I ever seen a validly signed packet? */
/* mac_key.length > 0 means signing is started */
@@ -54,7 +54,6 @@ struct smb_signing_state {
static void smb_signing_reset_info(struct smb_signing_state *si)
{
si->active = false;
- si->bsrspyl = false;
si->seqnum = 0;
if (si->free_fn) {
@@ -68,6 +67,7 @@ static void smb_signing_reset_info(struct smb_signing_state *si)
struct smb_signing_state *smb_signing_init_ex(TALLOC_CTX *mem_ctx,
bool allowed,
+ bool desired,
bool mandatory,
void *(*alloc_fn)(TALLOC_CTX *, size_t),
void (*free_fn)(TALLOC_CTX *, void *))
@@ -92,10 +92,15 @@ struct smb_signing_state *smb_signing_init_ex(TALLOC_CTX *mem_ctx,
}
if (mandatory) {
+ desired = true;
+ }
+
+ if (desired) {
allowed = true;
}
si->allowed = allowed;
+ si->desired = desired;
si->mandatory = mandatory;
return si;
@@ -103,9 +108,11 @@ struct smb_signing_state *smb_signing_init_ex(TALLOC_CTX *mem_ctx,
struct smb_signing_state *smb_signing_init(TALLOC_CTX *mem_ctx,
bool allowed,
+ bool desired,
bool mandatory)
{
- return smb_signing_init_ex(mem_ctx, allowed, mandatory, NULL, NULL);
+ return smb_signing_init_ex(mem_ctx, allowed, desired, mandatory,
+ NULL, NULL);
}
static bool smb_signing_good(struct smb_signing_state *si,
@@ -210,10 +217,11 @@ void smb_signing_sign_pdu(struct smb_signing_state *si,
uint8_t *outbuf, uint32_t seqnum)
{
uint8_t calc_md5_mac[16];
- uint16_t flags2;
+ uint8_t com;
+ uint8_t flags;
if (si->mac_key.length == 0) {
- if (!si->bsrspyl) {
+ if (!si->negotiated) {
return;
}
}
@@ -226,15 +234,32 @@ void smb_signing_sign_pdu(struct smb_signing_state *si,
abort();
}
- /* mark the packet as signed - BEFORE we sign it...*/
- flags2 = SVAL(outbuf,smb_flg2);
- flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES;
- SSVAL(outbuf, smb_flg2, flags2);
+ com = SVAL(outbuf,smb_com);
+ flags = SVAL(outbuf,smb_flg);
+
+ if (!(flags & FLAG_REPLY)) {
+ uint16_t flags2 = SVAL(outbuf,smb_flg2);
+ /*
+ * If this is a request, specify what is
+ * supported or required by the client
+ */
+ if (si->negotiated && si->desired) {
+ flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES;
+ }
+ if (si->negotiated && si->mandatory) {
+ flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
+ }
+ SSVAL(outbuf, smb_flg2, flags2);
+ }
- if (si->bsrspyl) {
+ if (si->mac_key.length == 0) {
/* I wonder what BSRSPYL stands for - but this is what MS
actually sends! */
- memcpy(calc_md5_mac, "BSRSPYL ", 8);
+ if (com == SMBsesssetupX) {
+ memcpy(calc_md5_mac, "BSRSPYL ", 8);
+ } else {
+ memset(calc_md5_mac, 0, 8);
+ }
} else {
smb_signing_md5(&si->mac_key, outbuf,
seqnum, calc_md5_mac);
@@ -305,21 +330,6 @@ bool smb_signing_check_pdu(struct smb_signing_state *si,
return smb_signing_good(si, good, seqnum);
}
-bool smb_signing_set_bsrspyl(struct smb_signing_state *si)
-{
- if (!si->negotiated) {
- return false;
- }
-
- if (si->active) {
- return false;
- }
-
- si->bsrspyl = true;
-
- return true;
-}
-
bool smb_signing_activate(struct smb_signing_state *si,
const DATA_BLOB user_session_key,
const DATA_BLOB response)
@@ -398,14 +408,42 @@ bool smb_signing_is_mandatory(struct smb_signing_state *si)
return si->mandatory;
}
-bool smb_signing_set_negotiated(struct smb_signing_state *si)
+bool smb_signing_set_negotiated(struct smb_signing_state *si,
+ bool allowed, bool mandatory)
{
- if (!si->allowed) {
+ if (si->active) {
+ return true;
+ }
+
+ if (!si->allowed && mandatory) {
return false;
}
- si->negotiated = true;
+ if (si->mandatory && !allowed) {
+ return false;
+ }
+
+ if (si->mandatory) {
+ si->negotiated = true;
+ return true;
+ }
+
+ if (mandatory) {
+ si->negotiated = true;
+ return true;
+ }
+
+ if (!si->desired) {
+ si->negotiated = false;
+ return true;
+ }
+
+ if (si->desired && allowed) {
+ si->negotiated = true;
+ return true;
+ }
+ si->negotiated = false;
return true;
}
diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c
index 71e0291..89ef52c 100644
--- a/source3/smbd/negprot.c
+++ b/source3/smbd/negprot.c
@@ -375,7 +375,6 @@ static void reply_nt1(struct smb_request *req, uint16 choice)
capabilities &= ~CAP_RAW_MODE;
if (lp_server_signing() == Required)
secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
- srv_set_signing_negotiated(sconn);
} else {
DEBUG(0,("reply_nt1: smb signing is incompatible with share level security !\n"));
if (lp_server_signing() == Required) {
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index c7f0ade..ab0c147 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -1674,15 +1674,21 @@ void remove_from_common_flags2(uint32 v)
static void construct_reply_common(struct smb_request *req, const char *inbuf,
char *outbuf)
{
+ uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
+ uint16_t out_flags2 = common_flags2;
+
+ out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
+ out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
+ out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
+
srv_set_message(outbuf,0,0,false);
SCVAL(outbuf, smb_com, req->cmd);
SIVAL(outbuf,smb_rcls,0);
SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
- SSVAL(outbuf,smb_flg2,
- (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
- common_flags2);
+ SSVAL(outbuf,smb_flg2, out_flags2);
memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
+ memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 8edd695..3d0665d 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -54,7 +54,8 @@ void srv_calculate_sign_mac(struct smbd_server_connection *conn,
char *outbuf, uint32_t seqnum);
void srv_cancel_sign_response(struct smbd_server_connection *conn);
bool srv_init_signing(struct smbd_server_connection *conn);
-void srv_set_signing_negotiated(struct smbd_server_connection *conn);
+void srv_set_signing_negotiated(struct smbd_server_connection *conn,
+ bool allowed, bool mandatory);
bool srv_is_signing_active(struct smbd_server_connection *conn);
bool srv_is_signing_negotiated(struct smbd_server_connection *conn);
void srv_set_signing(struct smbd_server_connection *conn,
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index 6dc8609..28ae24e 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
--
Samba Shared Repository
More information about the samba-cvs
mailing list