summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/include/client.h1
-rw-r--r--source/libsmb/cliconnect.c41
-rw-r--r--source/libsmb/clientgen.c3
-rw-r--r--source/libsmb/clireadwrite.c11
-rw-r--r--source/libsmb/smbencrypt.c10
5 files changed, 47 insertions, 19 deletions
diff --git a/source/include/client.h b/source/include/client.h
index e2eda54948f..69c74200c10 100644
--- a/source/include/client.h
+++ b/source/include/client.h
@@ -59,6 +59,7 @@ struct print_job_info
typedef struct smb_sign_info {
BOOL use_smb_signing;
+ BOOL negotiated_smb_signing;
size_t mac_key_len;
uint8 mac_key[44];
uint32 send_seq_num;
diff --git a/source/libsmb/cliconnect.c b/source/libsmb/cliconnect.c
index 33e2b286095..135238b9a7f 100644
--- a/source/libsmb/cliconnect.c
+++ b/source/libsmb/cliconnect.c
@@ -144,9 +144,6 @@ static BOOL cli_session_setup_guest(struct cli_state *cli)
char *p;
uint32 capabilities = cli_session_setup_capabilities(cli);
- /* Guest cannot use SMB signing. */
- cli->sign_info.use_smb_signing = False;
-
set_message(cli->outbuf,13,0,True);
SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
cli_setup_packet(cli);
@@ -202,9 +199,6 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user,
passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE|STR_ASCII);
- /* Plaintext password cannot use SMB signing. */
- cli->sign_info.use_smb_signing = False;
-
set_message(cli->outbuf,13,0,True);
SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
cli_setup_packet(cli);
@@ -275,12 +269,15 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user,
ntpasslen = 24;
SMBencrypt((uchar *)pass,cli->secblob.data,(uchar *)pword);
SMBNTencrypt((uchar *)pass,cli->secblob.data,(uchar *)ntpword);
- cli_calculate_mac_key(cli, (uchar *)pass, (uchar *)ntpword);
} else {
memcpy(pword, pass, passlen);
memcpy(ntpword, ntpass, ntpasslen);
}
+ if (cli->sign_info.negotiated_smb_signing) {
+ cli_calculate_mac_key(cli, (uchar *)pass, (uchar *)ntpword);
+ }
+
/* send a session setup command */
memset(cli->outbuf,'\0',smb_size);
@@ -311,10 +308,15 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user,
show_msg(cli->inbuf);
+ if (cli_is_error(cli) || SVAL(cli->inbuf,smb_vwv2) /* guest */) {
+ /* We only use it if we have a successful non-guest connect */
+ cli->sign_info.use_smb_signing = False;
+ }
+
if (cli_is_error(cli)) {
return False;
}
-
+
/* use the returned vuid from now on */
cli->vuid = SVAL(cli->inbuf,smb_uid);
@@ -346,9 +348,6 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob)
/* send a session setup command */
memset(cli->outbuf,'\0',smb_size);
- /* Extended security cannot use SMB signing (for now). */
- cli->sign_info.use_smb_signing = False;
-
set_message(cli->outbuf,12,0,True);
SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
cli_setup_packet(cli);
@@ -813,6 +812,11 @@ BOOL cli_negprot(struct cli_state *cli)
int numprots;
int plength;
+ if (cli->sign_info.use_smb_signing) {
+ DEBUG(0, ("Cannot send negprot again, particularly after setting up SMB Signing\n"));
+ return False;
+ }
+
if (cli->protocol < PROTOCOL_NT1) {
cli->use_spnego = False;
}
@@ -879,10 +883,10 @@ BOOL cli_negprot(struct cli_state *cli)
/* A way to attempt to force SMB signing */
if (getenv("CLI_FORCE_SMB_SIGNING"))
- cli->sign_info.use_smb_signing = True;
-
- if (cli->sign_info.use_smb_signing && !(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED))
- cli->sign_info.use_smb_signing = False;
+ cli->sign_info.negotiated_smb_signing = True;
+
+ if (cli->sign_info.negotiated_smb_signing && !(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED))
+ cli->sign_info.negotiated_smb_signing = False;
} else if (cli->protocol >= PROTOCOL_LANMAN1) {
cli->use_spnego = False;
@@ -896,13 +900,11 @@ BOOL cli_negprot(struct cli_state *cli)
cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0);
cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0);
cli->secblob = data_blob(smb_buf(cli->inbuf),smb_buflen(cli->inbuf));
- cli->sign_info.use_smb_signing = False;
} else {
/* the old core protocol */
cli->use_spnego = False;
cli->sec_mode = 0;
cli->serverzone = TimeDiff(time(NULL));
- cli->sign_info.use_smb_signing = False;
}
cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE);
@@ -929,6 +931,11 @@ BOOL cli_session_request(struct cli_state *cli,
/* 445 doesn't have session request */
if (cli->port == 445) return True;
+ if (cli->sign_info.use_smb_signing) {
+ DEBUG(0, ("Cannot send session resquest again, particularly after setting up SMB Signing\n"));
+ return False;
+ }
+
/* send a session request (RFC 1002) */
memcpy(&(cli->calling), calling, sizeof(*calling));
memcpy(&(cli->called ), called , sizeof(*called ));
diff --git a/source/libsmb/clientgen.c b/source/libsmb/clientgen.c
index e7e88687b85..c9500ead5d2 100644
--- a/source/libsmb/clientgen.c
+++ b/source/libsmb/clientgen.c
@@ -120,8 +120,7 @@ BOOL cli_send_smb(struct cli_state *cli)
if (cli->fd == -1)
return False;
- if (SVAL(cli->outbuf,smb_flg2) & FLAGS2_SMB_SECURITY_SIGNATURES)
- cli_caclulate_sign_mac(cli);
+ cli_caclulate_sign_mac(cli);
len = smb_len(cli->outbuf) + 4;
diff --git a/source/libsmb/clireadwrite.c b/source/libsmb/clireadwrite.c
index 6fce1c039b5..756a6cce2f9 100644
--- a/source/libsmb/clireadwrite.c
+++ b/source/libsmb/clireadwrite.c
@@ -128,6 +128,11 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_
}
#if 0 /* relies on client_recieve_smb(), now a static in libsmb/clientgen.c */
+
+/* This call is INCOMPATIBLE with SMB signing. If you remove the #if 0
+ you must fix ensure you don't attempt to sign the packets - data
+ *will* be currupted */
+
/****************************************************************************
Issue a single SMBreadraw and don't wait for a reply.
****************************************************************************/
@@ -135,6 +140,12 @@ Issue a single SMBreadraw and don't wait for a reply.
static BOOL cli_issue_readraw(struct cli_state *cli, int fnum, off_t offset,
size_t size, int i)
{
+
+ if (!cli->sign_info.use_smb_signing) {
+ DEBUG(0, ("Cannot use readraw and SMB Signing\n"));
+ return False;
+ }
+
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
diff --git a/source/libsmb/smbencrypt.c b/source/libsmb/smbencrypt.c
index 29e168f7bf4..9ae6da0ced9 100644
--- a/source/libsmb/smbencrypt.c
+++ b/source/libsmb/smbencrypt.c
@@ -343,6 +343,8 @@ void cli_calculate_mac_key(struct cli_state *cli, const unsigned char *ntpasswd,
E_md4hash(ntpasswd,&cli->sign_info.mac_key[0]);
memcpy(&cli->sign_info.mac_key[16],resp,24);
cli->sign_info.mac_key_len = 40;
+ cli->sign_info.use_smb_signing = True;
+
}
/***********************************************************
@@ -354,6 +356,14 @@ void cli_caclulate_sign_mac(struct cli_state *cli)
unsigned char calc_md5_mac[16];
struct MD5Context md5_ctx;
+ if (!cli->sign_info.use_smb_signing) {
+ return;
+ }
+
+ /* These calls are INCONPATIBLE with SMB signing */
+ cli->readbraw_supported = False;
+ cli->writebraw_supported = False;
+
/*
* Firstly put the sequence number into the first 4 bytes.
* and zero out the next 4 bytes.