diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/include/client.h | 1 | ||||
-rw-r--r-- | source3/libsmb/cliconnect.c | 41 | ||||
-rw-r--r-- | source3/libsmb/clientgen.c | 3 | ||||
-rw-r--r-- | source3/libsmb/clireadwrite.c | 11 | ||||
-rw-r--r-- | source3/libsmb/smbencrypt.c | 10 |
5 files changed, 47 insertions, 19 deletions
diff --git a/source3/include/client.h b/source3/include/client.h index e2eda54948..69c74200c1 100644 --- a/source3/include/client.h +++ b/source3/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/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 33e2b28609..135238b9a7 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/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/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index e7e88687b8..c9500ead5d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/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/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 6fce1c039b..756a6cce2f 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/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/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 29e168f7bf..9ae6da0ced 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/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. |