From 2ed7730f2d498a446dc7281e652d02a9dd2d94cf Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 9 Mar 2003 09:23:09 +0000 Subject: Change the way we sign SMB packets, to a function pointer interface. The intention is to allow for NTLMSSP and kerberos signing of packets, but for now it's just what I call 'simple' signing. (aka SMB signing per the SNIA spec) Andrew Bartlett (This used to be commit b9cf95c3dc04a45de71fb16e85c1bfbae50e6d8f) --- source3/libsmb/smb_signing.c | 329 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 329 insertions(+) create mode 100644 source3/libsmb/smb_signing.c (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c new file mode 100644 index 0000000000..b3a6351893 --- /dev/null +++ b/source3/libsmb/smb_signing.c @@ -0,0 +1,329 @@ +/* + Unix SMB/CIFS implementation. + SMB Signing Code + Copyright (C) Jeremy Allison 2002. + Copyright (C) Andrew Bartlett 2002-2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +struct smb_basic_signing_context { + DATA_BLOB mac_key; + uint32 send_seq_num; + uint32 reply_seq_num; +}; + +/*********************************************************** + SMB signing - Common code before we set a new signing implementation +************************************************************/ + +static BOOL set_smb_signing_common(struct cli_state *cli) +{ + if (cli->sign_info.doing_signing) { + return False; + } + + if (cli->sign_info.free_signing_context) + cli->sign_info.free_signing_context(cli); + + /* These calls are INCONPATIBLE with SMB signing */ + cli->readbraw_supported = False; + cli->writebraw_supported = False; + + return True; +} + +/*********************************************************** + SMB signing - Common code for 'real' implementations +************************************************************/ + +static BOOL set_smb_signing_real_common(struct cli_state *cli) +{ + if (cli->sign_info.mandetory_signing) { + DEBUG(5, ("Mandetory SMB signing enabled!\n")); + cli->sign_info.doing_signing = True; + } + + DEBUG(5, ("SMB signing enabled!\n")); + + return True; +} + +static void mark_packet_signed(struct cli_state *cli) +{ + uint16 flags2; + flags2 = SVAL(cli->outbuf,smb_flg2); + flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; + SSVAL(cli->outbuf,smb_flg2, flags2); +} + +/*********************************************************** + SMB signing - Simple implementation - calculate a MAC to send. +************************************************************/ + +static void cli_simple_sign_outgoing_message(struct cli_state *cli) +{ + unsigned char calc_md5_mac[16]; + struct MD5Context md5_ctx; + struct smb_basic_signing_context *data = cli->sign_info.signing_context; + + /* + * Firstly put the sequence number into the first 4 bytes. + * and zero out the next 4 bytes. + */ + SIVAL(cli->outbuf, smb_ss_field, + data->send_seq_num); + SIVAL(cli->outbuf, smb_ss_field + 4, 0); + + /* mark the packet as signed - BEFORE we sign it...*/ + mark_packet_signed(cli); + + /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ + MD5Init(&md5_ctx); + MD5Update(&md5_ctx, data->mac_key.data, + data->mac_key.length); + MD5Update(&md5_ctx, cli->outbuf + 4, smb_len(cli->outbuf)); + MD5Final(calc_md5_mac, &md5_ctx); + + DEBUG(10, ("sent SMB signiture of\n")); + dump_data(10, calc_md5_mac, 8); + + memcpy(&cli->outbuf[smb_ss_field], calc_md5_mac, 8); + +/* cli->outbuf[smb_ss_field+2]=0; + Uncomment this to test if the remote server actually verifies signitures...*/ + data->send_seq_num++; + data->reply_seq_num = data->send_seq_num; + data->send_seq_num++; +} + +/*********************************************************** + SMB signing - Simple implementation - check a MAC sent by server. +************************************************************/ + +static BOOL cli_simple_check_incoming_message(struct cli_state *cli) +{ + BOOL good; + unsigned char calc_md5_mac[16]; + unsigned char server_sent_mac[8]; + struct MD5Context md5_ctx; + struct smb_basic_signing_context *data = cli->sign_info.signing_context; + + /* + * Firstly put the sequence number into the first 4 bytes. + * and zero out the next 4 bytes. + */ + + memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac)); + + DEBUG(10, ("got SMB signiture of\n")); + dump_data(10, server_sent_mac, 8); + + SIVAL(cli->inbuf, smb_ss_field, data->reply_seq_num); + SIVAL(cli->inbuf, smb_ss_field + 4, 0); + + /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ + MD5Init(&md5_ctx); + MD5Update(&md5_ctx, data->mac_key.data, + data->mac_key.length); + MD5Update(&md5_ctx, cli->inbuf + 4, smb_len(cli->inbuf)); + MD5Final(calc_md5_mac, &md5_ctx); + + good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); + + if (good && !cli->sign_info.doing_signing) { + cli->sign_info.doing_signing = True; + } + + if (!good) { + DEBUG(1, ("SMB signiture check failed!\n")); + } + + return good; +} + +/*********************************************************** + SMB signing - Simple implementation - free signing context +************************************************************/ + +static void cli_simple_free_signing_context(struct cli_state *cli) +{ + struct smb_basic_signing_context *data = cli->sign_info.signing_context; + + data_blob_free(&data->mac_key); + SAFE_FREE(cli->sign_info.signing_context); + + return; +} + +/*********************************************************** + SMB signing - Simple implementation - setup the MAC key. +************************************************************/ + +void cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[16], const DATA_BLOB response) +{ + struct smb_basic_signing_context *data; + + if (!set_smb_signing_common(cli)) { + return; + } + + if (!set_smb_signing_real_common(cli)) { + return; + } + + data = smb_xmalloc(sizeof(*data)); + cli->sign_info.signing_context = data; + + data->mac_key = data_blob(NULL, MIN(response.length + 16, 40)); + + memcpy(&data->mac_key.data[0], user_session_key, 16); + memcpy(&data->mac_key.data[16],response.data, MIN(response.length, 40 - 16)); + + /* Initialise the sequence number */ + data->send_seq_num = 0; + + cli->sign_info.sign_outgoing_message = cli_simple_sign_outgoing_message; + cli->sign_info.check_incoming_message = cli_simple_check_incoming_message; + cli->sign_info.free_signing_context = cli_simple_free_signing_context; +} + +/*********************************************************** + SMB signing - NULL implementation - calculate a MAC to send. +************************************************************/ + +static void cli_null_sign_outgoing_message(struct cli_state *cli) +{ + static uchar zeros[8]; + memcpy(&cli->outbuf[smb_ss_field], zeros, sizeof(zeros)); +} + +/*********************************************************** + SMB signing - NULL implementation - check a MAC sent by server. +************************************************************/ + +static BOOL cli_null_check_incoming_message(struct cli_state *cli) +{ + return True; +} + +/*********************************************************** + SMB signing - NULL implementation - free signing context +************************************************************/ + +static void cli_null_free_signing_context(struct cli_state *cli) +{ + return; +} + +/*********************************************************** + SMB signing - NULL implementation - setup the MAC key. +************************************************************/ + +void cli_null_set_signing(struct cli_state *cli) +{ + struct smb_basic_sign_data *data; + + if (!set_smb_signing_common(cli)) { + return; + } + + cli->sign_info.signing_context = NULL; + + cli->sign_info.sign_outgoing_message = cli_null_sign_outgoing_message; + cli->sign_info.check_incoming_message = cli_null_check_incoming_message; + cli->sign_info.free_signing_context = cli_null_free_signing_context; +} + +/*********************************************************** + SMB signing - TEMP implementation - calculate a MAC to send. +************************************************************/ + +static void cli_temp_sign_outgoing_message(struct cli_state *cli) +{ + memcpy(&cli->outbuf[smb_ss_field], "SignRequest", 8); + return; +} + +/*********************************************************** + SMB signing - TEMP implementation - check a MAC sent by server. +************************************************************/ + +static BOOL cli_temp_check_incoming_message(struct cli_state *cli) +{ + return True; +} + +/*********************************************************** + SMB signing - TEMP implementation - free signing context +************************************************************/ + +static void cli_temp_free_signing_context(struct cli_state *cli) +{ + return; +} + +/*********************************************************** + SMB signing - NULL implementation - setup the MAC key. +************************************************************/ + +void cli_temp_set_signing(struct cli_state *cli) +{ + if (!set_smb_signing_common(cli)) { + return; + } + + cli->sign_info.signing_context = NULL; + + cli->sign_info.sign_outgoing_message = cli_temp_sign_outgoing_message; + cli->sign_info.check_incoming_message = cli_temp_check_incoming_message; + cli->sign_info.free_signing_context = cli_temp_free_signing_context; +} + +/** + * Free the singing context + */ + +void cli_free_signing_context(struct cli_state *cli) +{ + if (cli->sign_info.free_signing_context) + cli->sign_info.free_signing_context(cli); + + cli_null_set_signing(cli); +} + +void cli_caclulate_sign_mac(struct cli_state *cli) +{ + cli->sign_info.sign_outgoing_message(cli); +} + +BOOL cli_check_sign_mac(struct cli_state *cli) +{ + BOOL good; + good = cli->sign_info.check_incoming_message(cli); + + if (!good) { + if (cli->sign_info.doing_signing) { + return False; + } else { + cli_free_signing_context(cli); + } + } + + return True; +} + -- cgit From 2b6a6df0f65caccb31c78008539d24f8c4a2f72a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 9 Mar 2003 21:09:28 +0000 Subject: Try not to clobber the session request. (This used to be commit 05cffbee56f0556f550b4d14f3111bd7db972621) --- source3/libsmb/smb_signing.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index b3a6351893..581d18fef7 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -208,8 +208,10 @@ void cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ static void cli_null_sign_outgoing_message(struct cli_state *cli) { - static uchar zeros[8]; - memcpy(&cli->outbuf[smb_ss_field], zeros, sizeof(zeros)); + /* we can't zero out the sig, as we might be trying to send a + session request - which is NBT-level, not SMB level and doesn't + have the feild */ + return; } /*********************************************************** @@ -295,7 +297,7 @@ void cli_temp_set_signing(struct cli_state *cli) } /** - * Free the singing context + * Free the singing context */ void cli_free_signing_context(struct cli_state *cli) @@ -306,11 +308,21 @@ void cli_free_signing_context(struct cli_state *cli) cli_null_set_signing(cli); } +/** + * Sign a packet with the current mechinism + */ + void cli_caclulate_sign_mac(struct cli_state *cli) { cli->sign_info.sign_outgoing_message(cli); } +/** + * Check a packet with the current mechinism + * @return False if we had an established signing connection + * which had a back checksum, True otherwise + */ + BOOL cli_check_sign_mac(struct cli_state *cli) { BOOL good; -- cgit From e9a94cd2c9cab4518603620259dae44b40d9049e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 10 Mar 2003 02:14:35 +0000 Subject: Further work on NTLMSSP-based SMB signing. Current status is that I cannnot get Win2k to send a valid signiture in it's session setup reply - which it will give to win2k clients. So, I need to look at becoming 'more like MS', but for now I'll get this code into the tree. It's actually based on the TNG cli_pipe_ntlmssp.c, as it was slightly easier to understand than our own (but only the utility functions remain in any way intact...). This includes the mysical 'NTLM2' code - I have no idea if it actually works. (I couldn't get TNG to use it for its pipes either). Andrew Bartlett (This used to be commit a034a5e381ba5612be21e2ba640d11f82cd945da) --- source3/libsmb/smb_signing.c | 180 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 150 insertions(+), 30 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 581d18fef7..40359c5c8c 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -33,6 +33,11 @@ struct smb_basic_signing_context { static BOOL set_smb_signing_common(struct cli_state *cli) { + if (!cli->sign_info.negotiated_smb_signing + && !cli->sign_info.mandetory_signing) { + return False; + } + if (cli->sign_info.doing_signing) { return False; } @@ -40,7 +45,7 @@ static BOOL set_smb_signing_common(struct cli_state *cli) if (cli->sign_info.free_signing_context) cli->sign_info.free_signing_context(cli); - /* These calls are INCONPATIBLE with SMB signing */ + /* These calls are INCOMPATIBLE with SMB signing */ cli->readbraw_supported = False; cli->writebraw_supported = False; @@ -54,7 +59,7 @@ static BOOL set_smb_signing_common(struct cli_state *cli) static BOOL set_smb_signing_real_common(struct cli_state *cli) { if (cli->sign_info.mandetory_signing) { - DEBUG(5, ("Mandetory SMB signing enabled!\n")); + DEBUG(5, ("Mandatory SMB signing enabled!\n")); cli->sign_info.doing_signing = True; } @@ -71,6 +76,28 @@ static void mark_packet_signed(struct cli_state *cli) SSVAL(cli->outbuf,smb_flg2, flags2); } +static BOOL signing_good(struct cli_state *cli, BOOL good) +{ + DEBUG(10, ("got SMB signature of\n")); + dump_data(10,&cli->outbuf[smb_ss_field] , 8); + + if (good && !cli->sign_info.doing_signing) { + cli->sign_info.doing_signing = True; + } + + if (!good) { + if (cli->sign_info.doing_signing) { + DEBUG(1, ("SMB signature check failed!\n")); + return False; + } else { + DEBUG(3, ("Server did not sign reply correctly\n")); + cli_free_signing_context(cli); + return False; + } + } + return True; +} + /*********************************************************** SMB signing - Simple implementation - calculate a MAC to send. ************************************************************/ @@ -99,7 +126,7 @@ static void cli_simple_sign_outgoing_message(struct cli_state *cli) MD5Update(&md5_ctx, cli->outbuf + 4, smb_len(cli->outbuf)); MD5Final(calc_md5_mac, &md5_ctx); - DEBUG(10, ("sent SMB signiture of\n")); + DEBUG(10, ("sent SMB signature of\n")); dump_data(10, calc_md5_mac, 8); memcpy(&cli->outbuf[smb_ss_field], calc_md5_mac, 8); @@ -130,7 +157,7 @@ static BOOL cli_simple_check_incoming_message(struct cli_state *cli) memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac)); - DEBUG(10, ("got SMB signiture of\n")); + DEBUG(10, ("got SMB signature of\n")); dump_data(10, server_sent_mac, 8); SIVAL(cli->inbuf, smb_ss_field, data->reply_seq_num); @@ -145,15 +172,7 @@ static BOOL cli_simple_check_incoming_message(struct cli_state *cli) good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); - if (good && !cli->sign_info.doing_signing) { - cli->sign_info.doing_signing = True; - } - - if (!good) { - DEBUG(1, ("SMB signiture check failed!\n")); - } - - return good; + return signing_good(cli, good); } /*********************************************************** @@ -174,16 +193,16 @@ static void cli_simple_free_signing_context(struct cli_state *cli) SMB signing - Simple implementation - setup the MAC key. ************************************************************/ -void cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[16], const DATA_BLOB response) +BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[16], const DATA_BLOB response) { struct smb_basic_signing_context *data; if (!set_smb_signing_common(cli)) { - return; + return False; } if (!set_smb_signing_real_common(cli)) { - return; + return False; } data = smb_xmalloc(sizeof(*data)); @@ -194,12 +213,105 @@ void cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ memcpy(&data->mac_key.data[0], user_session_key, 16); memcpy(&data->mac_key.data[16],response.data, MIN(response.length, 40 - 16)); - /* Initialise the sequence number */ + /* Initialize the sequence number */ data->send_seq_num = 0; cli->sign_info.sign_outgoing_message = cli_simple_sign_outgoing_message; cli->sign_info.check_incoming_message = cli_simple_check_incoming_message; cli->sign_info.free_signing_context = cli_simple_free_signing_context; + + return True; +} + +/*********************************************************** + SMB signing - NTLMSSP implementation - calculate a MAC to send. +************************************************************/ + +static void cli_ntlmssp_sign_outgoing_message(struct cli_state *cli) +{ + NTSTATUS nt_status; + DATA_BLOB sig; + NTLMSSP_CLIENT_STATE *ntlmssp_state = cli->sign_info.signing_context; + + /* mark the packet as signed - BEFORE we sign it...*/ + mark_packet_signed(cli); + + nt_status = ntlmssp_client_sign_packet(ntlmssp_state, cli->outbuf + 4, + smb_len(cli->outbuf), &sig); + + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(0, ("NTLMSSP signing failed with %s\n", nt_errstr(nt_status))); + return; + } + + DEBUG(10, ("sent SMB signature of\n")); + dump_data(10, sig.data, MIN(sig.length, 8)); + memcpy(&cli->outbuf[smb_ss_field], sig.data, MIN(sig.length, 8)); + + data_blob_free(&sig); +} + +/*********************************************************** + SMB signing - NTLMSSP implementation - check a MAC sent by server. +************************************************************/ + +static BOOL cli_ntlmssp_check_incoming_message(struct cli_state *cli) +{ + BOOL good; + NTSTATUS nt_status; + DATA_BLOB sig = data_blob(&cli->outbuf[smb_ss_field], 8); + + NTLMSSP_CLIENT_STATE *ntlmssp_state = cli->sign_info.signing_context; + + nt_status = ntlmssp_client_check_packet(ntlmssp_state, cli->outbuf + 4, + smb_len(cli->outbuf), &sig); + + data_blob_free(&sig); + + good = NT_STATUS_IS_OK(nt_status); + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(5, ("NTLMSSP signing failed with %s\n", nt_errstr(nt_status))); + } + + return signing_good(cli, good); +} + +/*********************************************************** + SMB signing - NTLMSSP implementation - free signing context +************************************************************/ + +static void cli_ntlmssp_free_signing_context(struct cli_state *cli) +{ + ntlmssp_client_end((NTLMSSP_CLIENT_STATE **)&cli->sign_info.signing_context); +} + +/*********************************************************** + SMB signing - NTLMSSP implementation - setup the MAC key. +************************************************************/ + +BOOL cli_ntlmssp_set_signing(struct cli_state *cli, + NTLMSSP_CLIENT_STATE *ntlmssp_state) +{ + if (!set_smb_signing_common(cli)) { + return False; + } + + if (!NT_STATUS_IS_OK(ntlmssp_client_sign_init(ntlmssp_state))) { + return False; + } + + if (!set_smb_signing_real_common(cli)) { + return False; + } + + cli->sign_info.signing_context = ntlmssp_state; + ntlmssp_state->ref_count++; + + cli->sign_info.sign_outgoing_message = cli_ntlmssp_sign_outgoing_message; + cli->sign_info.check_incoming_message = cli_ntlmssp_check_incoming_message; + cli->sign_info.free_signing_context = cli_ntlmssp_free_signing_context; + + return True; } /*********************************************************** @@ -210,7 +322,7 @@ static void cli_null_sign_outgoing_message(struct cli_state *cli) { /* we can't zero out the sig, as we might be trying to send a session request - which is NBT-level, not SMB level and doesn't - have the feild */ + have the field */ return; } @@ -232,23 +344,24 @@ static void cli_null_free_signing_context(struct cli_state *cli) return; } -/*********************************************************** +/** SMB signing - NULL implementation - setup the MAC key. -************************************************************/ -void cli_null_set_signing(struct cli_state *cli) + @note Used as an initialisation only - it will not correctly + shut down a real signing mechinism +*/ + +BOOL cli_null_set_signing(struct cli_state *cli) { struct smb_basic_sign_data *data; - if (!set_smb_signing_common(cli)) { - return; - } - cli->sign_info.signing_context = NULL; cli->sign_info.sign_outgoing_message = cli_null_sign_outgoing_message; cli->sign_info.check_incoming_message = cli_null_check_incoming_message; cli->sign_info.free_signing_context = cli_null_free_signing_context; + + return True; } /*********************************************************** @@ -257,7 +370,12 @@ void cli_null_set_signing(struct cli_state *cli) static void cli_temp_sign_outgoing_message(struct cli_state *cli) { - memcpy(&cli->outbuf[smb_ss_field], "SignRequest", 8); + /* mark the packet as signed - BEFORE we sign it...*/ + mark_packet_signed(cli); + + /* I wonder what BSRSPYL stands for - but this is what MS + actually sends! */ + memcpy(&cli->outbuf[smb_ss_field], "BSRSPYL ", 8); return; } @@ -283,10 +401,10 @@ static void cli_temp_free_signing_context(struct cli_state *cli) SMB signing - NULL implementation - setup the MAC key. ************************************************************/ -void cli_temp_set_signing(struct cli_state *cli) +BOOL cli_temp_set_signing(struct cli_state *cli) { if (!set_smb_signing_common(cli)) { - return; + return False; } cli->sign_info.signing_context = NULL; @@ -294,6 +412,8 @@ void cli_temp_set_signing(struct cli_state *cli) cli->sign_info.sign_outgoing_message = cli_temp_sign_outgoing_message; cli->sign_info.check_incoming_message = cli_temp_check_incoming_message; cli->sign_info.free_signing_context = cli_temp_free_signing_context; + + return True; } /** @@ -309,7 +429,7 @@ void cli_free_signing_context(struct cli_state *cli) } /** - * Sign a packet with the current mechinism + * Sign a packet with the current mechanism */ void cli_caclulate_sign_mac(struct cli_state *cli) @@ -318,7 +438,7 @@ void cli_caclulate_sign_mac(struct cli_state *cli) } /** - * Check a packet with the current mechinism + * Check a packet with the current mechanism * @return False if we had an established signing connection * which had a back checksum, True otherwise */ -- cgit From 9db9982cd34d36d8b23e94a4063761c8b6aa9e17 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Fri, 14 Mar 2003 17:20:13 +0000 Subject: We haven't implemented The Singing Contexts so far. Who knows what .NET server brings, though ...? ;-) Rafal (This used to be commit d81b0d26903004be6a99ac029dd531fd18947268) --- source3/libsmb/smb_signing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 40359c5c8c..c3538ee9fd 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -417,7 +417,7 @@ BOOL cli_temp_set_signing(struct cli_state *cli) } /** - * Free the singing context + * Free the signing context */ void cli_free_signing_context(struct cli_state *cli) -- cgit From 72b0c07eae391c796c09161416baa34cd852dc03 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Mar 2003 21:25:35 +0000 Subject: Removed unused var. Jeremy. (This used to be commit f93c64b5ca1bc21f5fa89200034cd82dcbc0910b) --- source3/libsmb/smb_signing.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index c3538ee9fd..c713418e82 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -353,8 +353,6 @@ static void cli_null_free_signing_context(struct cli_state *cli) BOOL cli_null_set_signing(struct cli_state *cli) { - struct smb_basic_sign_data *data; - cli->sign_info.signing_context = NULL; cli->sign_info.sign_outgoing_message = cli_null_sign_outgoing_message; -- cgit From 873284d90bb7f6f0862acf27544eadeee853972a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 30 Mar 2003 02:58:33 +0000 Subject: Merge from HEAD - leave the SMB buffer untouched when checking it's SMB sig. Andrew Bartlett (This used to be commit 3d4c4b6cb3f4850f0801f140ea3dad2c8423ee52) --- source3/libsmb/smb_signing.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index c713418e82..9bbf7ef91c 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -79,7 +79,7 @@ static void mark_packet_signed(struct cli_state *cli) static BOOL signing_good(struct cli_state *cli, BOOL good) { DEBUG(10, ("got SMB signature of\n")); - dump_data(10,&cli->outbuf[smb_ss_field] , 8); + dump_data(10,&cli->inbuf[smb_ss_field] , 8); if (good && !cli->sign_info.doing_signing) { cli->sign_info.doing_signing = True; @@ -147,31 +147,47 @@ static BOOL cli_simple_check_incoming_message(struct cli_state *cli) BOOL good; unsigned char calc_md5_mac[16]; unsigned char server_sent_mac[8]; + unsigned char sequence_buf[8]; struct MD5Context md5_ctx; struct smb_basic_signing_context *data = cli->sign_info.signing_context; + const size_t offset_end_of_sig = (smb_ss_field + 8); /* * Firstly put the sequence number into the first 4 bytes. * and zero out the next 4 bytes. */ - memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac)); - - DEBUG(10, ("got SMB signature of\n")); - dump_data(10, server_sent_mac, 8); + SIVAL(sequence_buf, 0, data->reply_seq_num); + SIVAL(sequence_buf, 4, 0); - SIVAL(cli->inbuf, smb_ss_field, data->reply_seq_num); - SIVAL(cli->inbuf, smb_ss_field + 4, 0); + if (smb_len(cli->inbuf) < (offset_end_of_sig - 4)) { + DEBUG(1, ("Can't check signature on short packet! smb_len = %u\n", smb_len(cli->inbuf))); + return False; + } + /* get a copy of the server-sent mac */ + memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac)); + /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ MD5Init(&md5_ctx); MD5Update(&md5_ctx, data->mac_key.data, data->mac_key.length); - MD5Update(&md5_ctx, cli->inbuf + 4, smb_len(cli->inbuf)); + MD5Update(&md5_ctx, cli->inbuf + 4, smb_ss_field - 4); + MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf)); + + MD5Update(&md5_ctx, cli->inbuf + offset_end_of_sig, + smb_len(cli->inbuf) - (offset_end_of_sig - 4)); MD5Final(calc_md5_mac, &md5_ctx); good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); + if (!good) { + DEBUG(5, ("BAD SIG: wanted SMB signature of\n")); + dump_data(5, calc_md5_mac, 8); + + DEBUG(5, ("BAD SIG: got SMB signature of\n")); + dump_data(5, server_sent_mac, 8); + } return signing_good(cli, good); } @@ -213,7 +229,7 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ memcpy(&data->mac_key.data[0], user_session_key, 16); memcpy(&data->mac_key.data[16],response.data, MIN(response.length, 40 - 16)); - /* Initialize the sequence number */ + /* Initialise the sequence number */ data->send_seq_num = 0; cli->sign_info.sign_outgoing_message = cli_simple_sign_outgoing_message; @@ -348,7 +364,7 @@ static void cli_null_free_signing_context(struct cli_state *cli) SMB signing - NULL implementation - setup the MAC key. @note Used as an initialisation only - it will not correctly - shut down a real signing mechinism + shut down a real signing mechanism */ BOOL cli_null_set_signing(struct cli_state *cli) -- cgit From 8aa04b531e261dfc5f3ee4fa398ff5623376d843 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Apr 2003 08:13:29 +0000 Subject: Merge a trivial fix across from HEAD. Not that this would work now... Volker (This used to be commit 8c70f657cfb2f2b32fbaa31112d7953a3a6dc775) --- source3/libsmb/smb_signing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 9bbf7ef91c..9b473fa736 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -275,7 +275,7 @@ static BOOL cli_ntlmssp_check_incoming_message(struct cli_state *cli) { BOOL good; NTSTATUS nt_status; - DATA_BLOB sig = data_blob(&cli->outbuf[smb_ss_field], 8); + DATA_BLOB sig = data_blob(&cli->inbuf[smb_ss_field], 8); NTLMSSP_CLIENT_STATE *ntlmssp_state = cli->sign_info.signing_context; -- cgit From 1e2147fc0f677914fb2e3168b4fd4d7ddb4b9867 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 21 Apr 2003 13:00:39 +0000 Subject: Merge SMB signing, cli buffer clobber and NTLMSSP signing tweaks from HEAD. (This used to be commit c6c4f69b8ddc500890a65829e1b9fb7a3e9839e9) --- source3/libsmb/smb_signing.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 9b473fa736..4e9b895a1b 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -160,11 +160,6 @@ static BOOL cli_simple_check_incoming_message(struct cli_state *cli) SIVAL(sequence_buf, 0, data->reply_seq_num); SIVAL(sequence_buf, 4, 0); - if (smb_len(cli->inbuf) < (offset_end_of_sig - 4)) { - DEBUG(1, ("Can't check signature on short packet! smb_len = %u\n", smb_len(cli->inbuf))); - return False; - } - /* get a copy of the server-sent mac */ memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac)); @@ -460,8 +455,14 @@ void cli_caclulate_sign_mac(struct cli_state *cli) BOOL cli_check_sign_mac(struct cli_state *cli) { BOOL good; - good = cli->sign_info.check_incoming_message(cli); - + + if (smb_len(cli->inbuf) < (smb_ss_field + 8 - 4)) { + DEBUG(cli->sign_info.doing_signing ? 1 : 10, ("Can't check signature on short packet! smb_len = %u\n", smb_len(cli->inbuf))); + good = False; + } else { + good = cli->sign_info.check_incoming_message(cli); + } + if (!good) { if (cli->sign_info.doing_signing) { return False; -- cgit From 8b69f163359b7f917b13838cf7e88e7afb591bb0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 4 May 2003 01:05:39 +0000 Subject: Add doco to our SMB signing code. This should make it clearer what magic numbers refer to the magic numbers in the CIFS spec, and what bits and peices are being appended into the MD5 calculation where. Andrew Bartlett (This used to be commit 7f1c271cfb04f621e36f1acf60979652e82dc6f4) --- source3/libsmb/smb_signing.c | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 4e9b895a1b..76e3eb8988 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -21,6 +21,15 @@ #include "includes.h" +/* the SNIA Technical Reference tells us that this is '40 or 44' bytes + long, but NTLM only uses 40, and we don't know what value to use for + NTLMv2 */ + +/* my guess is 64, and other evidence indicates we don't setup the + session key correctly, so that's why it's failing */ + +#define SIMPLE_SMB_SIGNING_MAC_KEY_LEN 64 + struct smb_basic_signing_context { DATA_BLOB mac_key; uint32 send_seq_num; @@ -111,6 +120,9 @@ static void cli_simple_sign_outgoing_message(struct cli_state *cli) /* * Firstly put the sequence number into the first 4 bytes. * and zero out the next 4 bytes. + * + * We put the sequence into the packet, becouse we are going + * to copy over it anyway. */ SIVAL(cli->outbuf, smb_ss_field, data->send_seq_num); @@ -132,7 +144,7 @@ static void cli_simple_sign_outgoing_message(struct cli_state *cli) memcpy(&cli->outbuf[smb_ss_field], calc_md5_mac, 8); /* cli->outbuf[smb_ss_field+2]=0; - Uncomment this to test if the remote server actually verifies signitures...*/ + Uncomment this to test if the remote server actually verifies signatures...*/ data->send_seq_num++; data->reply_seq_num = data->send_seq_num; data->send_seq_num++; @@ -155,6 +167,8 @@ static BOOL cli_simple_check_incoming_message(struct cli_state *cli) /* * Firstly put the sequence number into the first 4 bytes. * and zero out the next 4 bytes. + * + * We do this here, to avoid modifying the packet. */ SIVAL(sequence_buf, 0, data->reply_seq_num); @@ -163,15 +177,28 @@ static BOOL cli_simple_check_incoming_message(struct cli_state *cli) /* get a copy of the server-sent mac */ memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac)); - /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ + /* Calculate the 16 byte MAC - but don't alter the data in the + incoming packet. + + This makes for a bit for fussing about, but it's not too bad. + */ MD5Init(&md5_ctx); + + /* intialise with the key */ MD5Update(&md5_ctx, data->mac_key.data, data->mac_key.length); + + /* copy in the first bit of the SMB header */ MD5Update(&md5_ctx, cli->inbuf + 4, smb_ss_field - 4); + + /* copy in the sequence number, instead of the signature */ MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf)); - + + /* copy in the rest of the packet in, skipping the signature */ MD5Update(&md5_ctx, cli->inbuf + offset_end_of_sig, smb_len(cli->inbuf) - (offset_end_of_sig - 4)); + + /* caclulate the MD5 sig */ MD5Final(calc_md5_mac, &md5_ctx); good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); @@ -219,10 +246,10 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ data = smb_xmalloc(sizeof(*data)); cli->sign_info.signing_context = data; - data->mac_key = data_blob(NULL, MIN(response.length + 16, 40)); + data->mac_key = data_blob(NULL, MIN(response.length + 16, SIMPLE_SMB_SIGNING_MAC_KEY_LEN)); memcpy(&data->mac_key.data[0], user_session_key, 16); - memcpy(&data->mac_key.data[16],response.data, MIN(response.length, 40 - 16)); + memcpy(&data->mac_key.data[16],response.data, MIN(response.length, SIMPLE_SMB_SIGNING_MAC_KEY_LEN - 16)); /* Initialise the sequence number */ data->send_seq_num = 0; -- cgit From 2752f4a533a5546df794aa7c02f6765185ccc4cc Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 7 May 2003 12:58:59 +0000 Subject: SMB Signing with NTLMv2 works! (well, under certain conditions :-) There is no length limit on the size of the authentication response added into the MD5 hash. (We had previously limited this to lengths like 40, 44 or 64 in attempts to make sense of what the SNIA spec tells us). Instead, the entire authentication response is added in. Currently, this only works on a Win2k domain members with a Samba PDC, becouse our NTLMv2 code currently fails against an Win2k PDC. However, this splits the problem in half - particularly as the NTLMv2 format is known, and even has an ethereal disector! (thanks tpot). Andrew Bartlett (This used to be commit 7645d3d28afbb8eea502c0e063df3afb3aa812f4) --- source3/libsmb/smb_signing.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 76e3eb8988..0f56cd15d9 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -21,15 +21,6 @@ #include "includes.h" -/* the SNIA Technical Reference tells us that this is '40 or 44' bytes - long, but NTLM only uses 40, and we don't know what value to use for - NTLMv2 */ - -/* my guess is 64, and other evidence indicates we don't setup the - session key correctly, so that's why it's failing */ - -#define SIMPLE_SMB_SIGNING_MAC_KEY_LEN 64 - struct smb_basic_signing_context { DATA_BLOB mac_key; uint32 send_seq_num; @@ -246,10 +237,10 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ data = smb_xmalloc(sizeof(*data)); cli->sign_info.signing_context = data; - data->mac_key = data_blob(NULL, MIN(response.length + 16, SIMPLE_SMB_SIGNING_MAC_KEY_LEN)); + data->mac_key = data_blob(NULL, response.length + 16); memcpy(&data->mac_key.data[0], user_session_key, 16); - memcpy(&data->mac_key.data[16],response.data, MIN(response.length, SIMPLE_SMB_SIGNING_MAC_KEY_LEN - 16)); + memcpy(&data->mac_key.data[16],response.data, response.length); /* Initialise the sequence number */ data->send_seq_num = 0; -- cgit From 402fbc518a5489b33f1c5eafb8e6acb9ee5addbd Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 14 May 2003 00:46:43 +0000 Subject: spelling (This used to be commit 865c11275685c85124b506c9bbd2a8bde2e760b9) --- source3/libsmb/smb_signing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 0f56cd15d9..eedf7f401f 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -112,7 +112,7 @@ static void cli_simple_sign_outgoing_message(struct cli_state *cli) * Firstly put the sequence number into the first 4 bytes. * and zero out the next 4 bytes. * - * We put the sequence into the packet, becouse we are going + * We put the sequence into the packet, because we are going * to copy over it anyway. */ SIVAL(cli->outbuf, smb_ss_field, -- cgit From 54f7cde1eb58921ca3fb08782bc72adaf5e93082 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Jun 2003 03:49:35 +0000 Subject: Rework our smb signing code again, this factors out some of the common MAC calcuation code, and now supports multiple outstanding packets. Fixes bug #40 Andrew Bartlett (This used to be commit dd33212f1ec08f46223d6de8e5ff3140ce367a9a) --- source3/libsmb/smb_signing.c | 163 +++++++++++++++++++++++++++++-------------- 1 file changed, 109 insertions(+), 54 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index eedf7f401f..fee2b66670 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -21,12 +21,50 @@ #include "includes.h" +/* Lookup a packet's MID (multiplex id) and figure out it's sequence number */ +struct outstanding_packet_lookup { + uint16 mid; + uint32 reply_seq_num; + struct outstanding_packet_lookup *prev, *next; +}; + struct smb_basic_signing_context { DATA_BLOB mac_key; uint32 send_seq_num; - uint32 reply_seq_num; + struct outstanding_packet_lookup *outstanding_packet_list; }; +static void store_sequence_for_reply(struct outstanding_packet_lookup **list, + uint16 mid, uint32 reply_seq_num) +{ + struct outstanding_packet_lookup *t; + struct outstanding_packet_lookup *tmp; + + t = smb_xmalloc(sizeof(*t)); + ZERO_STRUCTP(t); + + DLIST_ADD_END(*list, t, tmp); + t->mid = mid; + t->reply_seq_num = reply_seq_num; +} + +static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, + uint16 mid, uint32 *reply_seq_num) +{ + struct outstanding_packet_lookup *t; + + for (t = *list; t; t = t->next) { + if (t->mid == mid) { + *reply_seq_num = t->reply_seq_num; + DLIST_REMOVE(*list, t); + return True; + } + } + DEBUG(0, ("Unexpected incoming packet, it's MID (%u) does not match" + " a MID in our outstanding list!\n", mid)); + return False; +} + /*********************************************************** SMB signing - Common code before we set a new signing implementation ************************************************************/ @@ -99,35 +137,67 @@ static BOOL signing_good(struct cli_state *cli, BOOL good) } /*********************************************************** - SMB signing - Simple implementation - calculate a MAC to send. + SMB signing - Simple implementation - calculate a MAC on the packet ************************************************************/ -static void cli_simple_sign_outgoing_message(struct cli_state *cli) +static void simple_packet_signature(struct smb_basic_signing_context *data, + const uchar *buf, uint32 seq_number, + unsigned char calc_md5_mac[16]) { - unsigned char calc_md5_mac[16]; + const size_t offset_end_of_sig = (smb_ss_field + 8); + unsigned char sequence_buf[8]; struct MD5Context md5_ctx; - struct smb_basic_signing_context *data = cli->sign_info.signing_context; /* * Firstly put the sequence number into the first 4 bytes. * and zero out the next 4 bytes. * - * We put the sequence into the packet, because we are going - * to copy over it anyway. + * We do this here, to avoid modifying the packet. */ - SIVAL(cli->outbuf, smb_ss_field, - data->send_seq_num); - SIVAL(cli->outbuf, smb_ss_field + 4, 0); - /* mark the packet as signed - BEFORE we sign it...*/ - mark_packet_signed(cli); + SIVAL(sequence_buf, 0, seq_number); + SIVAL(sequence_buf, 4, 0); - /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ + /* Calculate the 16 byte MAC - but don't alter the data in the + incoming packet. + + This makes for a bit for fussing about, but it's not too bad. + */ MD5Init(&md5_ctx); + + /* intialise with the key */ MD5Update(&md5_ctx, data->mac_key.data, data->mac_key.length); - MD5Update(&md5_ctx, cli->outbuf + 4, smb_len(cli->outbuf)); + + /* copy in the first bit of the SMB header */ + MD5Update(&md5_ctx, buf + 4, smb_ss_field - 4); + + /* copy in the sequence number, instead of the signature */ + MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf)); + + /* copy in the rest of the packet in, skipping the signature */ + MD5Update(&md5_ctx, buf + offset_end_of_sig, + smb_len(buf) - (offset_end_of_sig - 4)); + + /* caclulate the MD5 sig */ MD5Final(calc_md5_mac, &md5_ctx); +} + + +/*********************************************************** + SMB signing - Simple implementation - send the MAC. +************************************************************/ + +static void cli_simple_sign_outgoing_message(struct cli_state *cli) +{ + unsigned char calc_md5_mac[16]; + struct smb_basic_signing_context *data = cli->sign_info.signing_context; + + /* mark the packet as signed - BEFORE we sign it...*/ + mark_packet_signed(cli); + + simple_packet_signature(data, cli->outbuf, data->send_seq_num, + calc_md5_mac); DEBUG(10, ("sent SMB signature of\n")); dump_data(10, calc_md5_mac, 8); @@ -136,8 +206,11 @@ static void cli_simple_sign_outgoing_message(struct cli_state *cli) /* cli->outbuf[smb_ss_field+2]=0; Uncomment this to test if the remote server actually verifies signatures...*/ + data->send_seq_num++; - data->reply_seq_num = data->send_seq_num; + store_sequence_for_reply(&data->outstanding_packet_list, + cli->mid, + data->send_seq_num); data->send_seq_num++; } @@ -148,50 +221,21 @@ static void cli_simple_sign_outgoing_message(struct cli_state *cli) static BOOL cli_simple_check_incoming_message(struct cli_state *cli) { BOOL good; + uint32 reply_seq_number; unsigned char calc_md5_mac[16]; - unsigned char server_sent_mac[8]; - unsigned char sequence_buf[8]; - struct MD5Context md5_ctx; - struct smb_basic_signing_context *data = cli->sign_info.signing_context; - const size_t offset_end_of_sig = (smb_ss_field + 8); + unsigned char *server_sent_mac; - /* - * Firstly put the sequence number into the first 4 bytes. - * and zero out the next 4 bytes. - * - * We do this here, to avoid modifying the packet. - */ - - SIVAL(sequence_buf, 0, data->reply_seq_num); - SIVAL(sequence_buf, 4, 0); - - /* get a copy of the server-sent mac */ - memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac)); - - /* Calculate the 16 byte MAC - but don't alter the data in the - incoming packet. - - This makes for a bit for fussing about, but it's not too bad. - */ - MD5Init(&md5_ctx); - - /* intialise with the key */ - MD5Update(&md5_ctx, data->mac_key.data, - data->mac_key.length); - - /* copy in the first bit of the SMB header */ - MD5Update(&md5_ctx, cli->inbuf + 4, smb_ss_field - 4); - - /* copy in the sequence number, instead of the signature */ - MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf)); + struct smb_basic_signing_context *data = cli->sign_info.signing_context; - /* copy in the rest of the packet in, skipping the signature */ - MD5Update(&md5_ctx, cli->inbuf + offset_end_of_sig, - smb_len(cli->inbuf) - (offset_end_of_sig - 4)); + if (!get_sequence_for_reply(&data->outstanding_packet_list, + SVAL(cli->inbuf, smb_mid), + &reply_seq_number)) { + return False; + } - /* caclulate the MD5 sig */ - MD5Final(calc_md5_mac, &md5_ctx); + simple_packet_signature(data, cli->inbuf, reply_seq_number, calc_md5_mac); + server_sent_mac = &cli->inbuf[smb_ss_field]; good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); if (!good) { @@ -211,6 +255,13 @@ static BOOL cli_simple_check_incoming_message(struct cli_state *cli) static void cli_simple_free_signing_context(struct cli_state *cli) { struct smb_basic_signing_context *data = cli->sign_info.signing_context; + struct outstanding_packet_lookup *list = data->outstanding_packet_list; + + while (list) { + struct outstanding_packet_lookup *old_head = list; + DLIST_REMOVE(list, list); + SAFE_FREE(old_head); + } data_blob_free(&data->mac_key); SAFE_FREE(cli->sign_info.signing_context); @@ -235,6 +286,7 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ } data = smb_xmalloc(sizeof(*data)); + cli->sign_info.signing_context = data; data->mac_key = data_blob(NULL, response.length + 16); @@ -245,6 +297,9 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ /* Initialise the sequence number */ data->send_seq_num = 0; + /* Initialise the list of outstanding packets */ + data->outstanding_packet_list = NULL; + cli->sign_info.sign_outgoing_message = cli_simple_sign_outgoing_message; cli->sign_info.check_incoming_message = cli_simple_check_incoming_message; cli->sign_info.free_signing_context = cli_simple_free_signing_context; -- cgit From 236702e15c26432fd09888658fd66f318d03e3f5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 14 Jul 2003 10:38:23 +0000 Subject: Fix SMB signing when using NTLMSSP... It's so simple now I know how it works - and it has nothing to do with NTLMSSP (it's just a slightly different use of the old algorithm). :-). Note: This is actually less secure then the non-NTLMSSP code, as there is no per-session random data included for NTLM logins. (NTLMv2 is better, fortunetly). Andrew Bartlett (This used to be commit 95ec8317d4c6817d192bcd52eec44a22286e10ee) --- source3/libsmb/smb_signing.c | 94 ++------------------------------------------ 1 file changed, 3 insertions(+), 91 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index fee2b66670..c15604c91c 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -277,6 +277,9 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ { struct smb_basic_signing_context *data; + if (!user_session_key) + return False; + if (!set_smb_signing_common(cli)) { return False; } @@ -307,97 +310,6 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ return True; } -/*********************************************************** - SMB signing - NTLMSSP implementation - calculate a MAC to send. -************************************************************/ - -static void cli_ntlmssp_sign_outgoing_message(struct cli_state *cli) -{ - NTSTATUS nt_status; - DATA_BLOB sig; - NTLMSSP_CLIENT_STATE *ntlmssp_state = cli->sign_info.signing_context; - - /* mark the packet as signed - BEFORE we sign it...*/ - mark_packet_signed(cli); - - nt_status = ntlmssp_client_sign_packet(ntlmssp_state, cli->outbuf + 4, - smb_len(cli->outbuf), &sig); - - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(0, ("NTLMSSP signing failed with %s\n", nt_errstr(nt_status))); - return; - } - - DEBUG(10, ("sent SMB signature of\n")); - dump_data(10, sig.data, MIN(sig.length, 8)); - memcpy(&cli->outbuf[smb_ss_field], sig.data, MIN(sig.length, 8)); - - data_blob_free(&sig); -} - -/*********************************************************** - SMB signing - NTLMSSP implementation - check a MAC sent by server. -************************************************************/ - -static BOOL cli_ntlmssp_check_incoming_message(struct cli_state *cli) -{ - BOOL good; - NTSTATUS nt_status; - DATA_BLOB sig = data_blob(&cli->inbuf[smb_ss_field], 8); - - NTLMSSP_CLIENT_STATE *ntlmssp_state = cli->sign_info.signing_context; - - nt_status = ntlmssp_client_check_packet(ntlmssp_state, cli->outbuf + 4, - smb_len(cli->outbuf), &sig); - - data_blob_free(&sig); - - good = NT_STATUS_IS_OK(nt_status); - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(5, ("NTLMSSP signing failed with %s\n", nt_errstr(nt_status))); - } - - return signing_good(cli, good); -} - -/*********************************************************** - SMB signing - NTLMSSP implementation - free signing context -************************************************************/ - -static void cli_ntlmssp_free_signing_context(struct cli_state *cli) -{ - ntlmssp_client_end((NTLMSSP_CLIENT_STATE **)&cli->sign_info.signing_context); -} - -/*********************************************************** - SMB signing - NTLMSSP implementation - setup the MAC key. -************************************************************/ - -BOOL cli_ntlmssp_set_signing(struct cli_state *cli, - NTLMSSP_CLIENT_STATE *ntlmssp_state) -{ - if (!set_smb_signing_common(cli)) { - return False; - } - - if (!NT_STATUS_IS_OK(ntlmssp_client_sign_init(ntlmssp_state))) { - return False; - } - - if (!set_smb_signing_real_common(cli)) { - return False; - } - - cli->sign_info.signing_context = ntlmssp_state; - ntlmssp_state->ref_count++; - - cli->sign_info.sign_outgoing_message = cli_ntlmssp_sign_outgoing_message; - cli->sign_info.check_incoming_message = cli_ntlmssp_check_incoming_message; - cli->sign_info.free_signing_context = cli_ntlmssp_free_signing_context; - - return True; -} - /*********************************************************** SMB signing - NULL implementation - calculate a MAC to send. ************************************************************/ -- cgit From 39de3249b0676a65cfbce23484d964f1e3334baa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 15 Jul 2003 22:26:47 +0000 Subject: Add a cli_ prefix to a few functions to ensure everything that takes a struct cli_state is so marked. Jeremy (This used to be commit 0b8724ed65799f94f2af5d1dbb9ba20f1bac53a7) --- source3/libsmb/smb_signing.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index c15604c91c..466f32cb92 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -69,7 +69,7 @@ static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, SMB signing - Common code before we set a new signing implementation ************************************************************/ -static BOOL set_smb_signing_common(struct cli_state *cli) +static BOOL cli_set_smb_signing_common(struct cli_state *cli) { if (!cli->sign_info.negotiated_smb_signing && !cli->sign_info.mandetory_signing) { @@ -94,7 +94,7 @@ static BOOL set_smb_signing_common(struct cli_state *cli) SMB signing - Common code for 'real' implementations ************************************************************/ -static BOOL set_smb_signing_real_common(struct cli_state *cli) +static BOOL cli_set_smb_signing_real_common(struct cli_state *cli) { if (cli->sign_info.mandetory_signing) { DEBUG(5, ("Mandatory SMB signing enabled!\n")); @@ -106,7 +106,7 @@ static BOOL set_smb_signing_real_common(struct cli_state *cli) return True; } -static void mark_packet_signed(struct cli_state *cli) +static void cli_mark_packet_signed(struct cli_state *cli) { uint16 flags2; flags2 = SVAL(cli->outbuf,smb_flg2); @@ -114,7 +114,7 @@ static void mark_packet_signed(struct cli_state *cli) SSVAL(cli->outbuf,smb_flg2, flags2); } -static BOOL signing_good(struct cli_state *cli, BOOL good) +static BOOL cli_signing_good(struct cli_state *cli, BOOL good) { DEBUG(10, ("got SMB signature of\n")); dump_data(10,&cli->inbuf[smb_ss_field] , 8); @@ -194,7 +194,7 @@ static void cli_simple_sign_outgoing_message(struct cli_state *cli) struct smb_basic_signing_context *data = cli->sign_info.signing_context; /* mark the packet as signed - BEFORE we sign it...*/ - mark_packet_signed(cli); + cli_mark_packet_signed(cli); simple_packet_signature(data, cli->outbuf, data->send_seq_num, calc_md5_mac); @@ -245,7 +245,7 @@ static BOOL cli_simple_check_incoming_message(struct cli_state *cli) DEBUG(5, ("BAD SIG: got SMB signature of\n")); dump_data(5, server_sent_mac, 8); } - return signing_good(cli, good); + return cli_signing_good(cli, good); } /*********************************************************** @@ -280,11 +280,11 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ if (!user_session_key) return False; - if (!set_smb_signing_common(cli)) { + if (!cli_set_smb_signing_common(cli)) { return False; } - if (!set_smb_signing_real_common(cli)) { + if (!cli_set_smb_signing_real_common(cli)) { return False; } @@ -365,7 +365,7 @@ BOOL cli_null_set_signing(struct cli_state *cli) static void cli_temp_sign_outgoing_message(struct cli_state *cli) { /* mark the packet as signed - BEFORE we sign it...*/ - mark_packet_signed(cli); + cli_mark_packet_signed(cli); /* I wonder what BSRSPYL stands for - but this is what MS actually sends! */ @@ -397,7 +397,7 @@ static void cli_temp_free_signing_context(struct cli_state *cli) BOOL cli_temp_set_signing(struct cli_state *cli) { - if (!set_smb_signing_common(cli)) { + if (!cli_set_smb_signing_common(cli)) { return False; } -- cgit From c44a9d25a2bfff9d5ebede80f30e13e41aca797c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 15 Jul 2003 23:05:57 +0000 Subject: Added the "required" keyword to the "client signing" parameter to force it on. Fail if missmatch. Small format tidyups in smbd/sesssetup.c. Preparing to add signing on server side. Jeremy. (This used to be commit c390b3e4cd68cfc233ddf14d139e25d40f050f27) --- source3/libsmb/smb_signing.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 466f32cb92..d4f77bf07c 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -72,7 +72,7 @@ static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, static BOOL cli_set_smb_signing_common(struct cli_state *cli) { if (!cli->sign_info.negotiated_smb_signing - && !cli->sign_info.mandetory_signing) { + && !cli->sign_info.mandatory_signing) { return False; } @@ -96,7 +96,7 @@ static BOOL cli_set_smb_signing_common(struct cli_state *cli) static BOOL cli_set_smb_signing_real_common(struct cli_state *cli) { - if (cli->sign_info.mandetory_signing) { + if (cli->sign_info.mandatory_signing) { DEBUG(5, ("Mandatory SMB signing enabled!\n")); cli->sign_info.doing_signing = True; } @@ -458,4 +458,3 @@ BOOL cli_check_sign_mac(struct cli_state *cli) return True; } - -- cgit From aed434ea9baf430bf7513ca3fb1f7b2f01792341 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 16 Jul 2003 05:51:10 +0000 Subject: Spelling. (This used to be commit 2750418752e491c5e87f0f2adf253291e31ee4c2) --- source3/libsmb/smb_signing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index d4f77bf07c..df17362f08 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -179,7 +179,7 @@ static void simple_packet_signature(struct smb_basic_signing_context *data, MD5Update(&md5_ctx, buf + offset_end_of_sig, smb_len(buf) - (offset_end_of_sig - 4)); - /* caclulate the MD5 sig */ + /* calculate the MD5 sig */ MD5Final(calc_md5_mac, &md5_ctx); } @@ -426,7 +426,7 @@ void cli_free_signing_context(struct cli_state *cli) * Sign a packet with the current mechanism */ -void cli_caclulate_sign_mac(struct cli_state *cli) +void cli_calculate_sign_mac(struct cli_state *cli) { cli->sign_info.sign_outgoing_message(cli); } -- cgit From 8c38bb75b74ef7a4f40a5490102c77ab7d5fa0ac Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 Jul 2003 19:17:33 +0000 Subject: Add krb5_princ_component to Heimdal. Remove cli_ from mark packet signed. Jeremy. (This used to be commit dd46f8b22d6e8411081a1279e1cd32929e40370b) --- source3/libsmb/smb_signing.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index df17362f08..f4ee6c00e0 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -106,12 +106,12 @@ static BOOL cli_set_smb_signing_real_common(struct cli_state *cli) return True; } -static void cli_mark_packet_signed(struct cli_state *cli) +static void mark_packet_signed(char *outbuf) { uint16 flags2; - flags2 = SVAL(cli->outbuf,smb_flg2); + flags2 = SVAL(outbuf,smb_flg2); flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; - SSVAL(cli->outbuf,smb_flg2, flags2); + SSVAL(outbuf,smb_flg2, flags2); } static BOOL cli_signing_good(struct cli_state *cli, BOOL good) @@ -194,7 +194,7 @@ static void cli_simple_sign_outgoing_message(struct cli_state *cli) struct smb_basic_signing_context *data = cli->sign_info.signing_context; /* mark the packet as signed - BEFORE we sign it...*/ - cli_mark_packet_signed(cli); + mark_packet_signed(cli->outbuf); simple_packet_signature(data, cli->outbuf, data->send_seq_num, calc_md5_mac); @@ -365,7 +365,7 @@ BOOL cli_null_set_signing(struct cli_state *cli) static void cli_temp_sign_outgoing_message(struct cli_state *cli) { /* mark the packet as signed - BEFORE we sign it...*/ - cli_mark_packet_signed(cli); + mark_packet_signed(cli->outbuf); /* I wonder what BSRSPYL stands for - but this is what MS actually sends! */ -- cgit From 4fbbaff415dbb8f1d06b6213e394860bf07a6b6d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 Jul 2003 21:06:21 +0000 Subject: Add API framework for server SMB signing. Jeremy. (This used to be commit 61fc9a7b2eafdf8cbed1f8d9aae016b828c91a08) --- source3/libsmb/smb_signing.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index f4ee6c00e0..e18d1ed42a 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -458,3 +458,24 @@ BOOL cli_check_sign_mac(struct cli_state *cli) return True; } + +/*********************************************************** + SMB signing - server API's. +************************************************************/ + +void srv_enable_signing(void) +{ +} + +void srv_disable_signing(void) +{ +} + +BOOL srv_check_sign_mac(char *buf) +{ + return True; +} + +void srv_calculate_sign_mac(char *buf) +{ +} -- cgit From 6ab5e14494ed6b579658f4fe3410759582d909cd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 Jul 2003 22:57:56 +0000 Subject: Refactor signing code to remove most dependencies on 'struct cli'. Ensure a server can't do a downgrade attack if client signing is mandatory. Add a lp_server_signing() function and a 'server signing' parameter that will act as the client one does. Jeremy (This used to be commit 203e4bf0bfb66fd9239e9a0656438a71280113cb) --- source3/libsmb/smb_signing.c | 205 ++++++++++++++++++++++++------------------- 1 file changed, 113 insertions(+), 92 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index e18d1ed42a..683a382369 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -81,7 +81,7 @@ static BOOL cli_set_smb_signing_common(struct cli_state *cli) } if (cli->sign_info.free_signing_context) - cli->sign_info.free_signing_context(cli); + cli->sign_info.free_signing_context(&cli->sign_info); /* These calls are INCOMPATIBLE with SMB signing */ cli->readbraw_supported = False; @@ -94,11 +94,11 @@ static BOOL cli_set_smb_signing_common(struct cli_state *cli) SMB signing - Common code for 'real' implementations ************************************************************/ -static BOOL cli_set_smb_signing_real_common(struct cli_state *cli) +static BOOL set_smb_signing_real_common(struct smb_sign_info *si) { - if (cli->sign_info.mandatory_signing) { + if (si->mandatory_signing) { DEBUG(5, ("Mandatory SMB signing enabled!\n")); - cli->sign_info.doing_signing = True; + si->doing_signing = True; } DEBUG(5, ("SMB signing enabled!\n")); @@ -114,22 +114,85 @@ static void mark_packet_signed(char *outbuf) SSVAL(outbuf,smb_flg2, flags2); } -static BOOL cli_signing_good(struct cli_state *cli, BOOL good) +/*********************************************************** + SMB signing - NULL implementation - calculate a MAC to send. +************************************************************/ + +static void null_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) +{ + /* we can't zero out the sig, as we might be trying to send a + session request - which is NBT-level, not SMB level and doesn't + have the field */ + return; +} + +/*********************************************************** + SMB signing - NULL implementation - check a MAC sent by server. +************************************************************/ + +static BOOL null_check_incoming_message(char *inbuf, struct smb_sign_info *si) +{ + return True; +} + +/*********************************************************** + SMB signing - NULL implementation - free signing context +************************************************************/ + +static void null_free_signing_context(struct smb_sign_info *si) +{ + return; +} + +/** + SMB signing - NULL implementation - setup the MAC key. + + @note Used as an initialisation only - it will not correctly + shut down a real signing mechanism +*/ + +static BOOL null_set_signing(struct smb_sign_info *si) +{ + si->signing_context = NULL; + + si->sign_outgoing_message = null_sign_outgoing_message; + si->check_incoming_message = null_check_incoming_message; + si->free_signing_context = null_free_signing_context; + + return True; +} + +/** + * Free the signing context + */ + +static void free_signing_context(struct smb_sign_info *si) +{ + if (si->free_signing_context) { + si->free_signing_context(si); + si->signing_context = NULL; + } + + null_set_signing(si); +} + + +static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good) { DEBUG(10, ("got SMB signature of\n")); - dump_data(10,&cli->inbuf[smb_ss_field] , 8); + dump_data(10,&inbuf[smb_ss_field] , 8); - if (good && !cli->sign_info.doing_signing) { - cli->sign_info.doing_signing = True; + if (good && !si->doing_signing) { + si->doing_signing = True; } if (!good) { - if (cli->sign_info.doing_signing) { + if (si->doing_signing) { DEBUG(1, ("SMB signature check failed!\n")); return False; } else { DEBUG(3, ("Server did not sign reply correctly\n")); - cli_free_signing_context(cli); + free_signing_context(si); return False; } } @@ -188,28 +251,27 @@ static void simple_packet_signature(struct smb_basic_signing_context *data, SMB signing - Simple implementation - send the MAC. ************************************************************/ -static void cli_simple_sign_outgoing_message(struct cli_state *cli) +static void cli_simple_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) { unsigned char calc_md5_mac[16]; - struct smb_basic_signing_context *data = cli->sign_info.signing_context; + struct smb_basic_signing_context *data = si->signing_context; /* mark the packet as signed - BEFORE we sign it...*/ - mark_packet_signed(cli->outbuf); + mark_packet_signed(outbuf); - simple_packet_signature(data, cli->outbuf, data->send_seq_num, - calc_md5_mac); + simple_packet_signature(data, outbuf, data->send_seq_num, calc_md5_mac); DEBUG(10, ("sent SMB signature of\n")); dump_data(10, calc_md5_mac, 8); - memcpy(&cli->outbuf[smb_ss_field], calc_md5_mac, 8); + memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); /* cli->outbuf[smb_ss_field+2]=0; Uncomment this to test if the remote server actually verifies signatures...*/ data->send_seq_num++; store_sequence_for_reply(&data->outstanding_packet_list, - cli->mid, + SVAL(outbuf,smb_mid), data->send_seq_num); data->send_seq_num++; } @@ -218,24 +280,24 @@ static void cli_simple_sign_outgoing_message(struct cli_state *cli) SMB signing - Simple implementation - check a MAC sent by server. ************************************************************/ -static BOOL cli_simple_check_incoming_message(struct cli_state *cli) +static BOOL cli_simple_check_incoming_message(char *inbuf, struct smb_sign_info *si) { BOOL good; uint32 reply_seq_number; unsigned char calc_md5_mac[16]; unsigned char *server_sent_mac; - struct smb_basic_signing_context *data = cli->sign_info.signing_context; + struct smb_basic_signing_context *data = si->signing_context; if (!get_sequence_for_reply(&data->outstanding_packet_list, - SVAL(cli->inbuf, smb_mid), + SVAL(inbuf, smb_mid), &reply_seq_number)) { return False; } - simple_packet_signature(data, cli->inbuf, reply_seq_number, calc_md5_mac); + simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); - server_sent_mac = &cli->inbuf[smb_ss_field]; + server_sent_mac = &inbuf[smb_ss_field]; good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); if (!good) { @@ -245,16 +307,16 @@ static BOOL cli_simple_check_incoming_message(struct cli_state *cli) DEBUG(5, ("BAD SIG: got SMB signature of\n")); dump_data(5, server_sent_mac, 8); } - return cli_signing_good(cli, good); + return signing_good(inbuf, si, good); } /*********************************************************** SMB signing - Simple implementation - free signing context ************************************************************/ -static void cli_simple_free_signing_context(struct cli_state *cli) +static void cli_simple_free_signing_context(struct smb_sign_info *si) { - struct smb_basic_signing_context *data = cli->sign_info.signing_context; + struct smb_basic_signing_context *data = si->signing_context; struct outstanding_packet_lookup *list = data->outstanding_packet_list; while (list) { @@ -264,7 +326,7 @@ static void cli_simple_free_signing_context(struct cli_state *cli) } data_blob_free(&data->mac_key); - SAFE_FREE(cli->sign_info.signing_context); + SAFE_FREE(si->signing_context); return; } @@ -284,7 +346,7 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ return False; } - if (!cli_set_smb_signing_real_common(cli)) { + if (!set_smb_signing_real_common(&cli->sign_info)) { return False; } @@ -310,66 +372,18 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ return True; } -/*********************************************************** - SMB signing - NULL implementation - calculate a MAC to send. -************************************************************/ - -static void cli_null_sign_outgoing_message(struct cli_state *cli) -{ - /* we can't zero out the sig, as we might be trying to send a - session request - which is NBT-level, not SMB level and doesn't - have the field */ - return; -} - -/*********************************************************** - SMB signing - NULL implementation - check a MAC sent by server. -************************************************************/ - -static BOOL cli_null_check_incoming_message(struct cli_state *cli) -{ - return True; -} - -/*********************************************************** - SMB signing - NULL implementation - free signing context -************************************************************/ - -static void cli_null_free_signing_context(struct cli_state *cli) -{ - return; -} - -/** - SMB signing - NULL implementation - setup the MAC key. - - @note Used as an initialisation only - it will not correctly - shut down a real signing mechanism -*/ - -BOOL cli_null_set_signing(struct cli_state *cli) -{ - cli->sign_info.signing_context = NULL; - - cli->sign_info.sign_outgoing_message = cli_null_sign_outgoing_message; - cli->sign_info.check_incoming_message = cli_null_check_incoming_message; - cli->sign_info.free_signing_context = cli_null_free_signing_context; - - return True; -} - /*********************************************************** SMB signing - TEMP implementation - calculate a MAC to send. ************************************************************/ -static void cli_temp_sign_outgoing_message(struct cli_state *cli) +static void cli_temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) { /* mark the packet as signed - BEFORE we sign it...*/ - mark_packet_signed(cli->outbuf); + mark_packet_signed(outbuf); /* I wonder what BSRSPYL stands for - but this is what MS actually sends! */ - memcpy(&cli->outbuf[smb_ss_field], "BSRSPYL ", 8); + memcpy(&outbuf[smb_ss_field], "BSRSPYL ", 8); return; } @@ -377,7 +391,7 @@ static void cli_temp_sign_outgoing_message(struct cli_state *cli) SMB signing - TEMP implementation - check a MAC sent by server. ************************************************************/ -static BOOL cli_temp_check_incoming_message(struct cli_state *cli) +static BOOL cli_temp_check_incoming_message(char *inbuf, struct smb_sign_info *si) { return True; } @@ -386,7 +400,7 @@ static BOOL cli_temp_check_incoming_message(struct cli_state *cli) SMB signing - TEMP implementation - free signing context ************************************************************/ -static void cli_temp_free_signing_context(struct cli_state *cli) +static void cli_temp_free_signing_context(struct smb_sign_info *si) { return; } @@ -395,6 +409,15 @@ static void cli_temp_free_signing_context(struct cli_state *cli) SMB signing - NULL implementation - setup the MAC key. ************************************************************/ +BOOL cli_null_set_signing(struct cli_state *cli) +{ + return null_set_signing(&cli->sign_info); +} + +/*********************************************************** + SMB signing - temp implementation - setup the MAC key. +************************************************************/ + BOOL cli_temp_set_signing(struct cli_state *cli) { if (!cli_set_smb_signing_common(cli)) { @@ -410,16 +433,9 @@ BOOL cli_temp_set_signing(struct cli_state *cli) return True; } -/** - * Free the signing context - */ - -void cli_free_signing_context(struct cli_state *cli) +void cli_free_signing_context(struct cli_state *cli) { - if (cli->sign_info.free_signing_context) - cli->sign_info.free_signing_context(cli); - - cli_null_set_signing(cli); + free_signing_context(&cli->sign_info); } /** @@ -428,7 +444,7 @@ void cli_free_signing_context(struct cli_state *cli) void cli_calculate_sign_mac(struct cli_state *cli) { - cli->sign_info.sign_outgoing_message(cli); + cli->sign_info.sign_outgoing_message(cli->outbuf, &cli->sign_info); } /** @@ -445,14 +461,14 @@ BOOL cli_check_sign_mac(struct cli_state *cli) DEBUG(cli->sign_info.doing_signing ? 1 : 10, ("Can't check signature on short packet! smb_len = %u\n", smb_len(cli->inbuf))); good = False; } else { - good = cli->sign_info.check_incoming_message(cli); + good = cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info); } if (!good) { if (cli->sign_info.doing_signing) { return False; } else { - cli_free_signing_context(cli); + free_signing_context(&cli->sign_info); } } @@ -479,3 +495,8 @@ BOOL srv_check_sign_mac(char *buf) void srv_calculate_sign_mac(char *buf) { } + +BOOL allow_sendfile(void) +{ + return True; +} -- cgit From f1b6cd794dd5de853c4b068361a326160a3d0384 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 17 Jul 2003 00:48:21 +0000 Subject: Putting the framework for server signing in place. Ensure we don't use sendfile when signing (I need to add this for readbraw/writebraw too...). Jeremy. (This used to be commit f2e84f1ba67b13ff29e24a38099b559d9033a680) --- source3/libsmb/smb_signing.c | 72 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 5 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 683a382369..8e3a4ff8d8 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -479,24 +479,86 @@ BOOL cli_check_sign_mac(struct cli_state *cli) SMB signing - server API's. ************************************************************/ +static struct smb_sign_info srv_sign_info = { + null_sign_outgoing_message, + null_check_incoming_message, + null_free_signing_context, + NULL, + False, + False, + False, + False +}; + +/*********************************************************** + Turn on signing after sending an oplock break. +************************************************************/ + void srv_enable_signing(void) { + srv_sign_info.doing_signing = True; } +/*********************************************************** + Turn off signing before sending an oplock break. +************************************************************/ + void srv_disable_signing(void) { + srv_sign_info.doing_signing = False; } -BOOL srv_check_sign_mac(char *buf) +/*********************************************************** + Called to validate an incoming packet from the client. +************************************************************/ + +BOOL srv_check_sign_mac(char *inbuf) { - return True; + if (!srv_sign_info.doing_signing) + return True; + + /* Check if it's a session keepalive. */ + if(CVAL(inbuf,0) == SMBkeepalive) + return True; + + if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) { + DEBUG(1, ("srv_check_sign_mac: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf) )); + return False; + } + + return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info); } -void srv_calculate_sign_mac(char *buf) +/*********************************************************** + Called to sign an outgoing packet to the client. +************************************************************/ + +void srv_calculate_sign_mac(char *outbuf) { + if (!srv_sign_info.doing_signing) + return; + + /* Check if it's a session keepalive. */ + /* JRA Paranioa test - do we ever generate these in the server ? */ + if(CVAL(outbuf,0) == SMBkeepalive) + return; + + /* JRA Paranioa test - we should be able to get rid of this... */ + if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) { + DEBUG(1, ("srv_calculate_sign_mac: Logic error. Can't check signature on short packet! smb_len = %u\n", + smb_len(outbuf) )); + abort(); + } + + srv_sign_info.sign_outgoing_message(outbuf, &srv_sign_info); } -BOOL allow_sendfile(void) +/*********************************************************** + Returns whether signing is active. We can't use sendfile or raw + reads/writes if it is. +************************************************************/ + +BOOL srv_signing_active(void) { - return True; + return srv_sign_info.doing_signing; } -- cgit From 583fc850781148b15f8fe20d9567ca840fb722d2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 17 Jul 2003 00:58:14 +0000 Subject: Correctly toggle the signing state to what it was previosly when sending an oplock break. Jeremy. (This used to be commit 9515de83a864250c417cf490b7be714c8e1e127e) --- source3/libsmb/smb_signing.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 8e3a4ff8d8..23611f3e3b 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -491,21 +491,14 @@ static struct smb_sign_info srv_sign_info = { }; /*********************************************************** - Turn on signing after sending an oplock break. + Turn signing off or on for oplock break code. ************************************************************/ -void srv_enable_signing(void) +BOOL srv_oplock_set_signing(BOOL onoff) { - srv_sign_info.doing_signing = True; -} - -/*********************************************************** - Turn off signing before sending an oplock break. -************************************************************/ - -void srv_disable_signing(void) -{ - srv_sign_info.doing_signing = False; + BOOL ret = srv_sign_info.doing_signing; + srv_sign_info.doing_signing = onoff; + return ret; } /*********************************************************** -- cgit From 814e987c6241601fb03335b2ba9a633d65cc5e23 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 18 Jul 2003 00:53:34 +0000 Subject: Signing so far... the client code fails on a SMBtrans2 secondary transaction I think (my changes haven't affected this I believe). Initial support on the server side for smbclient. Still doesn't work for w2k clients I think... Work in progress..... (don't change). Jeremy. (This used to be commit e5714edc233424c2f74edb6d658f32f8e0ec9275) --- source3/libsmb/smb_signing.c | 164 ++++++++++++++++++++++++++++++------------- 1 file changed, 114 insertions(+), 50 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 23611f3e3b..2612ed2367 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -57,6 +57,7 @@ static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, if (t->mid == mid) { *reply_seq_num = t->reply_seq_num; DLIST_REMOVE(*list, t); + SAFE_FREE(t); return True; } } @@ -179,7 +180,7 @@ static void free_signing_context(struct smb_sign_info *si) static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good) { - DEBUG(10, ("got SMB signature of\n")); + DEBUG(10, ("signing_good: got SMB signature of\n")); dump_data(10,&inbuf[smb_ss_field] , 8); if (good && !si->doing_signing) { @@ -251,17 +252,27 @@ static void simple_packet_signature(struct smb_basic_signing_context *data, SMB signing - Simple implementation - send the MAC. ************************************************************/ -static void cli_simple_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) +static void simple_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) { unsigned char calc_md5_mac[16]; struct smb_basic_signing_context *data = si->signing_context; + if (!si->doing_signing) + return; + + /* JRA Paranioa test - we should be able to get rid of this... */ + if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) { + DEBUG(1, ("simple_sign_outgoing_message: Logic error. Can't check signature on short packet! smb_len = %u\n", + smb_len(outbuf) )); + abort(); + } + /* mark the packet as signed - BEFORE we sign it...*/ mark_packet_signed(outbuf); simple_packet_signature(data, outbuf, data->send_seq_num, calc_md5_mac); - DEBUG(10, ("sent SMB signature of\n")); + DEBUG(10, ("simple_sign_outgoing_message: sent SMB signature of\n")); dump_data(10, calc_md5_mac, 8); memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); @@ -270,17 +281,19 @@ static void cli_simple_sign_outgoing_message(char *outbuf, struct smb_sign_info Uncomment this to test if the remote server actually verifies signatures...*/ data->send_seq_num++; +#if 1 /* JRATEST */ store_sequence_for_reply(&data->outstanding_packet_list, SVAL(outbuf,smb_mid), data->send_seq_num); data->send_seq_num++; +#endif /* JRATEST */ } /*********************************************************** SMB signing - Simple implementation - check a MAC sent by server. ************************************************************/ -static BOOL cli_simple_check_incoming_message(char *inbuf, struct smb_sign_info *si) +static BOOL simple_check_incoming_message(char *inbuf, struct smb_sign_info *si) { BOOL good; uint32 reply_seq_number; @@ -289,11 +302,24 @@ static BOOL cli_simple_check_incoming_message(char *inbuf, struct smb_sign_info struct smb_basic_signing_context *data = si->signing_context; + if (!si->doing_signing) + return True; + + if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) { + DEBUG(1, ("simple_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf))); + return False; + } + +#if 1 /* JRATEST */ if (!get_sequence_for_reply(&data->outstanding_packet_list, SVAL(inbuf, smb_mid), &reply_seq_number)) { return False; } +#else /* JRATEST */ + reply_seq_number = data->send_seq_num; + data->send_seq_num++; +#endif /* JRATEST */ simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); @@ -301,10 +327,10 @@ static BOOL cli_simple_check_incoming_message(char *inbuf, struct smb_sign_info good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); if (!good) { - DEBUG(5, ("BAD SIG: wanted SMB signature of\n")); + DEBUG(5, ("simple_check_incoming_message: BAD SIG: wanted SMB signature of\n")); dump_data(5, calc_md5_mac, 8); - DEBUG(5, ("BAD SIG: got SMB signature of\n")); + DEBUG(5, ("simple_check_incoming_message: BAD SIG: got SMB signature of\n")); dump_data(5, server_sent_mac, 8); } return signing_good(inbuf, si, good); @@ -314,7 +340,7 @@ static BOOL cli_simple_check_incoming_message(char *inbuf, struct smb_sign_info SMB signing - Simple implementation - free signing context ************************************************************/ -static void cli_simple_free_signing_context(struct smb_sign_info *si) +static void simple_free_signing_context(struct smb_sign_info *si) { struct smb_basic_signing_context *data = si->signing_context; struct outstanding_packet_lookup *list = data->outstanding_packet_list; @@ -357,7 +383,8 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ data->mac_key = data_blob(NULL, response.length + 16); memcpy(&data->mac_key.data[0], user_session_key, 16); - memcpy(&data->mac_key.data[16],response.data, response.length); + if (response.length) + memcpy(&data->mac_key.data[16],response.data, response.length); /* Initialise the sequence number */ data->send_seq_num = 0; @@ -365,9 +392,9 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ /* Initialise the list of outstanding packets */ data->outstanding_packet_list = NULL; - cli->sign_info.sign_outgoing_message = cli_simple_sign_outgoing_message; - cli->sign_info.check_incoming_message = cli_simple_check_incoming_message; - cli->sign_info.free_signing_context = cli_simple_free_signing_context; + cli->sign_info.sign_outgoing_message = simple_sign_outgoing_message; + cli->sign_info.check_incoming_message = simple_check_incoming_message; + cli->sign_info.free_signing_context = simple_free_signing_context; return True; } @@ -376,7 +403,7 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ SMB signing - TEMP implementation - calculate a MAC to send. ************************************************************/ -static void cli_temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) +static void temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) { /* mark the packet as signed - BEFORE we sign it...*/ mark_packet_signed(outbuf); @@ -391,7 +418,7 @@ static void cli_temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *s SMB signing - TEMP implementation - check a MAC sent by server. ************************************************************/ -static BOOL cli_temp_check_incoming_message(char *inbuf, struct smb_sign_info *si) +static BOOL temp_check_incoming_message(char *inbuf, struct smb_sign_info *si) { return True; } @@ -400,7 +427,7 @@ static BOOL cli_temp_check_incoming_message(char *inbuf, struct smb_sign_info *s SMB signing - TEMP implementation - free signing context ************************************************************/ -static void cli_temp_free_signing_context(struct smb_sign_info *si) +static void temp_free_signing_context(struct smb_sign_info *si) { return; } @@ -426,9 +453,9 @@ BOOL cli_temp_set_signing(struct cli_state *cli) cli->sign_info.signing_context = NULL; - cli->sign_info.sign_outgoing_message = cli_temp_sign_outgoing_message; - cli->sign_info.check_incoming_message = cli_temp_check_incoming_message; - cli->sign_info.free_signing_context = cli_temp_free_signing_context; + cli->sign_info.sign_outgoing_message = temp_sign_outgoing_message; + cli->sign_info.check_incoming_message = temp_check_incoming_message; + cli->sign_info.free_signing_context = temp_free_signing_context; return True; } @@ -450,28 +477,15 @@ void cli_calculate_sign_mac(struct cli_state *cli) /** * Check a packet with the current mechanism * @return False if we had an established signing connection - * which had a back checksum, True otherwise + * which had a bad checksum, True otherwise. */ BOOL cli_check_sign_mac(struct cli_state *cli) { - BOOL good; - - if (smb_len(cli->inbuf) < (smb_ss_field + 8 - 4)) { - DEBUG(cli->sign_info.doing_signing ? 1 : 10, ("Can't check signature on short packet! smb_len = %u\n", smb_len(cli->inbuf))); - good = False; - } else { - good = cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info); - } - - if (!good) { - if (cli->sign_info.doing_signing) { - return False; - } else { - free_signing_context(&cli->sign_info); - } + if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info)) { + free_signing_context(&cli->sign_info); + return False; } - return True; } @@ -507,18 +521,10 @@ BOOL srv_oplock_set_signing(BOOL onoff) BOOL srv_check_sign_mac(char *inbuf) { - if (!srv_sign_info.doing_signing) - return True; - /* Check if it's a session keepalive. */ if(CVAL(inbuf,0) == SMBkeepalive) return True; - if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) { - DEBUG(1, ("srv_check_sign_mac: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf) )); - return False; - } - return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info); } @@ -536,22 +542,80 @@ void srv_calculate_sign_mac(char *outbuf) if(CVAL(outbuf,0) == SMBkeepalive) return; - /* JRA Paranioa test - we should be able to get rid of this... */ - if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) { - DEBUG(1, ("srv_calculate_sign_mac: Logic error. Can't check signature on short packet! smb_len = %u\n", - smb_len(outbuf) )); - abort(); - } - srv_sign_info.sign_outgoing_message(outbuf, &srv_sign_info); } +/*********************************************************** + Called by server negprot when signing has been negotiated. +************************************************************/ + +void srv_set_signing_negotiated(void) +{ + srv_sign_info.allow_smb_signing = True; + srv_sign_info.negotiated_smb_signing = True; + if (lp_server_signing() == Required) + srv_sign_info.mandatory_signing = True; + + srv_sign_info.sign_outgoing_message = temp_sign_outgoing_message; + srv_sign_info.check_incoming_message = temp_check_incoming_message; + srv_sign_info.free_signing_context = temp_free_signing_context; +} + /*********************************************************** Returns whether signing is active. We can't use sendfile or raw reads/writes if it is. ************************************************************/ -BOOL srv_signing_active(void) +BOOL srv_is_signing_active(void) { return srv_sign_info.doing_signing; } + +/*********************************************************** + Turn on signing from this packet onwards. +************************************************************/ + +void srv_set_signing(const uchar user_session_key[16], const DATA_BLOB response) +{ + struct smb_basic_signing_context *data; + + if (!user_session_key) + return; + + if (!srv_sign_info.negotiated_smb_signing && !srv_sign_info.mandatory_signing) { + DEBUG(5,("srv_set_signing: signing negotiated = %u, mandatory_signing = %u. Not allowing smb signing.\n", + (unsigned int)srv_sign_info.negotiated_smb_signing, + (unsigned int)srv_sign_info.mandatory_signing )); + return; + } + + /* Once we've turned on, ignore any more sessionsetups. */ + if (srv_sign_info.doing_signing) { + return; + } + + if (srv_sign_info.free_signing_context) + srv_sign_info.free_signing_context(&srv_sign_info); + + srv_sign_info.doing_signing = True; + + data = smb_xmalloc(sizeof(*data)); + + srv_sign_info.signing_context = data; + + data->mac_key = data_blob(NULL, response.length + 16); + + memcpy(&data->mac_key.data[0], user_session_key, 16); + if (response.length) + memcpy(&data->mac_key.data[16],response.data, response.length); + + /* Initialise the sequence number */ + data->send_seq_num = 0; + + /* Initialise the list of outstanding packets */ + data->outstanding_packet_list = NULL; + + srv_sign_info.sign_outgoing_message = simple_sign_outgoing_message; + srv_sign_info.check_incoming_message = simple_check_incoming_message; + srv_sign_info.free_signing_context = simple_free_signing_context; +} -- cgit From e79e26eb0002cc664ceaff62bc587ac4f3d62073 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 23 Jul 2003 06:04:20 +0000 Subject: Don't check in two places for signing turned off... Jeremy. (This used to be commit f4b02e52e25556e5b101d493e2e6404563bf96dd) --- source3/libsmb/smb_signing.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 2612ed2367..19450a9536 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -534,9 +534,6 @@ BOOL srv_check_sign_mac(char *inbuf) void srv_calculate_sign_mac(char *outbuf) { - if (!srv_sign_info.doing_signing) - return; - /* Check if it's a session keepalive. */ /* JRA Paranioa test - do we ever generate these in the server ? */ if(CVAL(outbuf,0) == SMBkeepalive) -- cgit From 79e2d7c24ebc06a485d8a26c1e58c684237ef533 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Jul 2003 04:25:37 +0000 Subject: Server side NTLM signing works - until the first async packet. Working on this next.... Jeremy. (This used to be commit eff74a1fcc597497a4c70589a44c1b70e93ab549) --- source3/libsmb/smb_signing.c | 136 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 114 insertions(+), 22 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 19450a9536..36c4147af8 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. SMB Signing Code - Copyright (C) Jeremy Allison 2002. + Copyright (C) Jeremy Allison 2003. Copyright (C) Andrew Bartlett 2002-2003 This program is free software; you can redistribute it and/or modify @@ -219,6 +219,8 @@ static void simple_packet_signature(struct smb_basic_signing_context *data, * We do this here, to avoid modifying the packet. */ + DEBUG(10,("simple_packet_signature: sequence number %u\n", seq_number )); + SIVAL(sequence_buf, 0, seq_number); SIVAL(sequence_buf, 4, 0); @@ -249,10 +251,10 @@ static void simple_packet_signature(struct smb_basic_signing_context *data, /*********************************************************** - SMB signing - Simple implementation - send the MAC. + SMB signing - Client implementation - send the MAC. ************************************************************/ -static void simple_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) +static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) { unsigned char calc_md5_mac[16]; struct smb_basic_signing_context *data = si->signing_context; @@ -262,7 +264,7 @@ static void simple_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) /* JRA Paranioa test - we should be able to get rid of this... */ if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) { - DEBUG(1, ("simple_sign_outgoing_message: Logic error. Can't check signature on short packet! smb_len = %u\n", + DEBUG(1, ("client_sign_outgoing_message: Logic error. Can't check signature on short packet! smb_len = %u\n", smb_len(outbuf) )); abort(); } @@ -272,7 +274,7 @@ static void simple_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) simple_packet_signature(data, outbuf, data->send_seq_num, calc_md5_mac); - DEBUG(10, ("simple_sign_outgoing_message: sent SMB signature of\n")); + DEBUG(10, ("client_sign_outgoing_message: sent SMB signature of\n")); dump_data(10, calc_md5_mac, 8); memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); @@ -281,19 +283,17 @@ static void simple_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) Uncomment this to test if the remote server actually verifies signatures...*/ data->send_seq_num++; -#if 1 /* JRATEST */ store_sequence_for_reply(&data->outstanding_packet_list, SVAL(outbuf,smb_mid), data->send_seq_num); data->send_seq_num++; -#endif /* JRATEST */ } /*********************************************************** - SMB signing - Simple implementation - check a MAC sent by server. + SMB signing - Client implementation - check a MAC sent by server. ************************************************************/ -static BOOL simple_check_incoming_message(char *inbuf, struct smb_sign_info *si) +static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) { BOOL good; uint32 reply_seq_number; @@ -306,20 +306,15 @@ static BOOL simple_check_incoming_message(char *inbuf, struct smb_sign_info *si) return True; if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) { - DEBUG(1, ("simple_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf))); + DEBUG(1, ("client_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf))); return False; } -#if 1 /* JRATEST */ if (!get_sequence_for_reply(&data->outstanding_packet_list, SVAL(inbuf, smb_mid), &reply_seq_number)) { return False; } -#else /* JRATEST */ - reply_seq_number = data->send_seq_num; - data->send_seq_num++; -#endif /* JRATEST */ simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); @@ -327,10 +322,10 @@ static BOOL simple_check_incoming_message(char *inbuf, struct smb_sign_info *si) good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); if (!good) { - DEBUG(5, ("simple_check_incoming_message: BAD SIG: wanted SMB signature of\n")); + DEBUG(5, ("client_check_incoming_message: BAD SIG: wanted SMB signature of\n")); dump_data(5, calc_md5_mac, 8); - DEBUG(5, ("simple_check_incoming_message: BAD SIG: got SMB signature of\n")); + DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n")); dump_data(5, server_sent_mac, 8); } return signing_good(inbuf, si, good); @@ -383,8 +378,17 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ data->mac_key = data_blob(NULL, response.length + 16); memcpy(&data->mac_key.data[0], user_session_key, 16); - if (response.length) + + DEBUG(10, ("cli_simple_set_signing: user_session_key\n")); + dump_data(10, user_session_key, 16); + + if (response.length) { memcpy(&data->mac_key.data[16],response.data, response.length); + DEBUG(10, ("cli_simple_set_signing: response_data\n")); + dump_data(10, response.data, response.length); + } else { + DEBUG(10, ("cli_simple_set_signing: NULL response_data\n")); + } /* Initialise the sequence number */ data->send_seq_num = 0; @@ -392,8 +396,8 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ /* Initialise the list of outstanding packets */ data->outstanding_packet_list = NULL; - cli->sign_info.sign_outgoing_message = simple_sign_outgoing_message; - cli->sign_info.check_incoming_message = simple_check_incoming_message; + cli->sign_info.sign_outgoing_message = client_sign_outgoing_message; + cli->sign_info.check_incoming_message = client_check_incoming_message; cli->sign_info.free_signing_context = simple_free_signing_context; return True; @@ -489,6 +493,94 @@ BOOL cli_check_sign_mac(struct cli_state *cli) return True; } +/*********************************************************** + SMB signing - Server implementation - send the MAC. +************************************************************/ + +static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) +{ + unsigned char calc_md5_mac[16]; + struct smb_basic_signing_context *data = si->signing_context; + + if (!si->doing_signing) + return; + + /* JRA Paranioa test - we should be able to get rid of this... */ + if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) { + DEBUG(1, ("srv_sign_outgoing_message: Logic error. Can't check signature on short packet! smb_len = %u\n", + smb_len(outbuf) )); + abort(); + } + + /* mark the packet as signed - BEFORE we sign it...*/ + mark_packet_signed(outbuf); + + simple_packet_signature(data, outbuf, data->send_seq_num, calc_md5_mac); + + DEBUG(10, ("srv_sign_outgoing_message: sent SMB signature of\n")); + dump_data(10, calc_md5_mac, 8); + + memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); + +/* cli->outbuf[smb_ss_field+2]=0; + Uncomment this to test if the remote server actually verifies signatures...*/ + + data->send_seq_num++; +#if 0 /* JRATEST */ + store_sequence_for_reply(&data->outstanding_packet_list, + SVAL(outbuf,smb_mid), + data->send_seq_num); + data->send_seq_num++; +#endif /* JRATEST */ +} + +/*********************************************************** + SMB signing - Server implementation - check a MAC sent by server. +************************************************************/ + +static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) +{ + BOOL good; + uint32 reply_seq_number; + unsigned char calc_md5_mac[16]; + unsigned char *server_sent_mac; + + struct smb_basic_signing_context *data = si->signing_context; + + if (!si->doing_signing) + return True; + + if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) { + DEBUG(1, ("srv_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf))); + return False; + } + +#if 0 /* JRATEST */ + if (!get_sequence_for_reply(&data->outstanding_packet_list, + SVAL(inbuf, smb_mid), + &reply_seq_number)) { + return False; + } +#else /* JRATEST */ + reply_seq_number = data->send_seq_num; + data->send_seq_num++; +#endif /* JRATEST */ + + simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); + + server_sent_mac = &inbuf[smb_ss_field]; + good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); + + if (!good) { + DEBUG(5, ("srv_check_incoming_message: BAD SIG: wanted SMB signature of\n")); + dump_data(5, calc_md5_mac, 8); + + DEBUG(5, ("srv_check_incoming_message: BAD SIG: got SMB signature of\n")); + dump_data(5, server_sent_mac, 8); + } + return signing_good(inbuf, si, good); +} + /*********************************************************** SMB signing - server API's. ************************************************************/ @@ -612,7 +704,7 @@ void srv_set_signing(const uchar user_session_key[16], const DATA_BLOB response) /* Initialise the list of outstanding packets */ data->outstanding_packet_list = NULL; - srv_sign_info.sign_outgoing_message = simple_sign_outgoing_message; - srv_sign_info.check_incoming_message = simple_check_incoming_message; + srv_sign_info.sign_outgoing_message = srv_sign_outgoing_message; + srv_sign_info.check_incoming_message = srv_check_incoming_message; srv_sign_info.free_signing_context = simple_free_signing_context; } -- cgit From 08634e26e45d3dd935727e43587a137c72417cd3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Jul 2003 06:19:37 +0000 Subject: SMB signing is now working with change notify. Need to fix the disconnect when bad signature received, plus check the oplock breaks.... Jermey. (This used to be commit dd83931a00ec0a2c4b78b939c54bc101ec82312f) --- source3/libsmb/smb_signing.c | 46 +++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 18 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 36c4147af8..1fe3f99c8a 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -61,8 +61,6 @@ static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, return True; } } - DEBUG(0, ("Unexpected incoming packet, it's MID (%u) does not match" - " a MID in our outstanding list!\n", mid)); return False; } @@ -501,6 +499,8 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) { unsigned char calc_md5_mac[16]; struct smb_basic_signing_context *data = si->signing_context; + uint32 send_seq_number = data->send_seq_num; + BOOL was_deferred_packet; if (!si->doing_signing) return; @@ -515,7 +515,12 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) /* mark the packet as signed - BEFORE we sign it...*/ mark_packet_signed(outbuf); - simple_packet_signature(data, outbuf, data->send_seq_num, calc_md5_mac); + /* See if this is a reply for a deferred packet. */ + was_deferred_packet = get_sequence_for_reply(&data->outstanding_packet_list, + SVAL(outbuf, smb_mid), + &send_seq_number); + + simple_packet_signature(data, outbuf, send_seq_number, calc_md5_mac); DEBUG(10, ("srv_sign_outgoing_message: sent SMB signature of\n")); dump_data(10, calc_md5_mac, 8); @@ -525,13 +530,8 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) /* cli->outbuf[smb_ss_field+2]=0; Uncomment this to test if the remote server actually verifies signatures...*/ - data->send_seq_num++; -#if 0 /* JRATEST */ - store_sequence_for_reply(&data->outstanding_packet_list, - SVAL(outbuf,smb_mid), - data->send_seq_num); - data->send_seq_num++; -#endif /* JRATEST */ + if (!was_deferred_packet) + data->send_seq_num++; } /*********************************************************** @@ -555,16 +555,8 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) return False; } -#if 0 /* JRATEST */ - if (!get_sequence_for_reply(&data->outstanding_packet_list, - SVAL(inbuf, smb_mid), - &reply_seq_number)) { - return False; - } -#else /* JRATEST */ reply_seq_number = data->send_seq_num; data->send_seq_num++; -#endif /* JRATEST */ simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); @@ -634,6 +626,24 @@ void srv_calculate_sign_mac(char *outbuf) srv_sign_info.sign_outgoing_message(outbuf, &srv_sign_info); } +/*********************************************************** + Called by server to defer an outgoing packet. +************************************************************/ + +void srv_defer_sign_response(uint16 mid) +{ + struct smb_basic_signing_context *data; + + if (!srv_sign_info.doing_signing) + return; + + data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; + + store_sequence_for_reply(&data->outstanding_packet_list, + mid, data->send_seq_num); + data->send_seq_num++; +} + /*********************************************************** Called by server negprot when signing has been negotiated. ************************************************************/ -- cgit From ceb68ee051e97afb1cb08e6f458e23e8f475504e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Jul 2003 19:05:32 +0000 Subject: Fix packet signing with asynchronous oplock breaks. Removed bad error message due to w2k bug. I think this code is now working.... Need more testing of course but works on all the obvious cases I can think of. Jeremy. (This used to be commit a6e537f6611cc1357fffea0b69901fba7c9ad6ea) --- source3/libsmb/smb_signing.c | 72 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 5 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 1fe3f99c8a..4a98b84826 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -187,7 +187,12 @@ static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good) if (!good) { if (si->doing_signing) { - DEBUG(1, ("SMB signature check failed!\n")); + struct smb_basic_signing_context *data = si->signing_context; + + /* W2K sends a bad first signature but the sign engine is on.... JRA. */ + if (data->send_seq_num > 1) + DEBUG(1, ("SMB signature check failed!\n")); + return False; } else { DEBUG(3, ("Server did not sign reply correctly\n")); @@ -491,6 +496,21 @@ BOOL cli_check_sign_mac(struct cli_state *cli) return True; } +static BOOL outgoing_packet_is_oplock_break(char *outbuf) +{ + if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) { + return False; + } + + if (CVAL(outbuf,smb_com) != SMBlockingX) + return False; + + if (CVAL(outbuf,smb_vwv3) != LOCKING_ANDX_OPLOCK_RELEASE) + return False; + + return True; +} + /*********************************************************** SMB signing - Server implementation - send the MAC. ************************************************************/ @@ -502,12 +522,32 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) uint32 send_seq_number = data->send_seq_num; BOOL was_deferred_packet; - if (!si->doing_signing) + if (!si->doing_signing) { + if (si->allow_smb_signing && si->negotiated_smb_signing) { + uint16 mid = SVAL(outbuf, smb_mid); + + was_deferred_packet = get_sequence_for_reply(&data->outstanding_packet_list, + mid, &send_seq_number); + if (!was_deferred_packet) { + /* + * Is this an outgoing oplock break ? If so, store the + * mid in the outstanding list. + */ + + if (outgoing_packet_is_oplock_break(outbuf)) { + store_sequence_for_reply(&data->outstanding_packet_list, + mid, data->send_seq_num); + } + + data->send_seq_num++; + } + } return; + } /* JRA Paranioa test - we should be able to get rid of this... */ if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) { - DEBUG(1, ("srv_sign_outgoing_message: Logic error. Can't check signature on short packet! smb_len = %u\n", + DEBUG(1, ("srv_sign_outgoing_message: Logic error. Can't send signature on short packet! smb_len = %u\n", smb_len(outbuf) )); abort(); } @@ -555,8 +595,13 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) return False; } - reply_seq_number = data->send_seq_num; - data->send_seq_num++; + /* Oplock break requests store an outgoing mid in the packet list. */ + if (!get_sequence_for_reply(&data->outstanding_packet_list, + SVAL(inbuf, smb_mid), + &reply_seq_number)) { + reply_seq_number = data->send_seq_num; + data->send_seq_num++; + } simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); @@ -564,11 +609,28 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); if (!good) { + DEBUG(5, ("srv_check_incoming_message: BAD SIG: wanted SMB signature of\n")); dump_data(5, calc_md5_mac, 8); DEBUG(5, ("srv_check_incoming_message: BAD SIG: got SMB signature of\n")); dump_data(5, server_sent_mac, 8); + +#if 0 /* JRATEST */ + { + int i; + reply_seq_number -= 5; + for (i = 0; i < 10; i++, reply_seq_number++) { + simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); + if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) { + DEBUG(0,("srv_check_incoming_message: out of seq. seq num %u matches.\n", + reply_seq_number )); + break; + } + } + } +#endif /* JRATEST */ + } return signing_good(inbuf, si, good); } -- cgit From 4632786cfb193dd80ce04206912297186e871814 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 25 Jul 2003 23:15:30 +0000 Subject: W00t! Client smb signing is now working correctly with krb5 and w2k server. Server code *should* also work (I'll check shortly). May be the odd memory leak. Problem was we (a) weren't setting signing on in the client krb5 sessionsetup code (b) we need to ask for a subkey... (c). The client and server need to ask for local and remote subkeys respectively. Thanks to Paul Nelson @ Thursby for some sage advice on this :-). Jeremy. (This used to be commit 3f9e3b60709df5ab755045a093e642510d4cde00) --- source3/libsmb/smb_signing.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 4a98b84826..977d5e3905 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -330,6 +330,21 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n")); dump_data(5, server_sent_mac, 8); +#if 0 /* JRATEST */ + { + int i; + reply_seq_number -= 5; + for (i = 0; i < 10; i++, reply_seq_number++) { + simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); + if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) { + DEBUG(0,("client_check_incoming_message: out of seq. seq num %u matches.\n", + reply_seq_number )); + break; + } + } + } +#endif /* JRATEST */ + } return signing_good(inbuf, si, good); } -- cgit From 5e2235843ed98afafc9309067dea651196a62b5f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 27 Jul 2003 10:25:44 +0000 Subject: Fix comment (This used to be commit 2c395a3904395c2743df9c3035459c6f3866232d) --- source3/libsmb/smb_signing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 977d5e3905..305a741ef1 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -230,7 +230,7 @@ static void simple_packet_signature(struct smb_basic_signing_context *data, /* Calculate the 16 byte MAC - but don't alter the data in the incoming packet. - This makes for a bit for fussing about, but it's not too bad. + This makes for a bit of fussing about, but it's not too bad. */ MD5Init(&md5_ctx); -- cgit From aa7f82c5cc751915192a8641dc87c837a61e29fb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 31 Jul 2003 00:30:01 +0000 Subject: Turn the 'doing_signing' variable on - fix bug where it was only being set on when signing was mandatory. Jeremy. (This used to be commit 7c58673a103195435ca75ebb2684880d1f7242d3) --- source3/libsmb/smb_signing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 305a741ef1..3feffe4c96 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -97,9 +97,9 @@ static BOOL set_smb_signing_real_common(struct smb_sign_info *si) { if (si->mandatory_signing) { DEBUG(5, ("Mandatory SMB signing enabled!\n")); - si->doing_signing = True; } + si->doing_signing = True; DEBUG(5, ("SMB signing enabled!\n")); return True; -- cgit From 2443f7ffa20a683eabb792182cb0206402ad8059 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Aug 2003 00:29:45 +0000 Subject: Correct fix (removed the earlier band-aid) for what I thought was a signing bug with w2k. Turns out that when we're doing a trans/trans2/nttrans call the MID and send_sequence_number and reply_sequence_number must remain constant. This was something we got very wrong in earlier versions of Samba. I can now get a directory listing from WINNT\SYSTEM32 with the older earlier parameters for clilist.c This still needs to be fixed for the server side of Samba, client appears to be working happily now (I'm doing a signed smbtar download of an entire W2K3 image to test this :-). Jeremy. (This used to be commit 2093a3130d4087d0659b497eebd580e7a66e5aa3) --- source3/libsmb/smb_signing.c | 67 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 3feffe4c96..81e25cb67c 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -28,9 +28,17 @@ struct outstanding_packet_lookup { struct outstanding_packet_lookup *prev, *next; }; +/* Store the data for an ongoing trans/trans2/nttrans operation. */ +struct trans_info_context { + uint16 mid; + uint32 send_seq_num; + uint32 reply_seq_num; +}; + struct smb_basic_signing_context { DATA_BLOB mac_key; uint32 send_seq_num; + struct trans_info_context *trans_info; struct outstanding_packet_lookup *outstanding_packet_list; }; @@ -261,6 +269,7 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) { unsigned char calc_md5_mac[16]; struct smb_basic_signing_context *data = si->signing_context; + uint32 send_seq_num; if (!si->doing_signing) return; @@ -275,7 +284,12 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) /* mark the packet as signed - BEFORE we sign it...*/ mark_packet_signed(outbuf); - simple_packet_signature(data, outbuf, data->send_seq_num, calc_md5_mac); + if (data->trans_info) + send_seq_num = data->trans_info->send_seq_num; + else + send_seq_num = data->send_seq_num; + + simple_packet_signature(data, outbuf, send_seq_num, calc_md5_mac); DEBUG(10, ("client_sign_outgoing_message: sent SMB signature of\n")); dump_data(10, calc_md5_mac, 8); @@ -285,6 +299,9 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) /* cli->outbuf[smb_ss_field+2]=0; Uncomment this to test if the remote server actually verifies signatures...*/ + if (data->trans_info) + return; + data->send_seq_num++; store_sequence_for_reply(&data->outstanding_packet_list, SVAL(outbuf,smb_mid), @@ -313,9 +330,13 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) return False; } - if (!get_sequence_for_reply(&data->outstanding_packet_list, + if (data->trans_info) { + reply_seq_number = data->trans_info->reply_seq_num; + } else if (!get_sequence_for_reply(&data->outstanding_packet_list, SVAL(inbuf, smb_mid), &reply_seq_number)) { + DEBUG(1, ("client_check_incoming_message: failed to get sequence number %u for reply.\n", + (unsigned int) SVAL(inbuf, smb_mid) )); return False; } @@ -365,6 +386,10 @@ static void simple_free_signing_context(struct smb_sign_info *si) } data_blob_free(&data->mac_key); + + if (data->trans_info) + SAFE_FREE(data->trans_info); + SAFE_FREE(si->signing_context); return; @@ -390,6 +415,7 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ } data = smb_xmalloc(sizeof(*data)); + memset(data, '\0', sizeof(*data)); cli->sign_info.signing_context = data; @@ -421,6 +447,42 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ return True; } +/*********************************************************** + Tell client code we are in a multiple trans reply state. +************************************************************/ + +void cli_signing_trans_start(struct cli_state *cli) +{ + struct smb_basic_signing_context *data = cli->sign_info.signing_context; + + if (!cli->sign_info.doing_signing) + return; + + data->trans_info = smb_xmalloc(sizeof(struct trans_info_context)); + ZERO_STRUCTP(data->trans_info); + + data->trans_info->send_seq_num = data->send_seq_num; + data->trans_info->mid = SVAL(cli->outbuf,smb_mid); + data->trans_info->reply_seq_num = data->send_seq_num+1; +} + +/*********************************************************** + Tell client code we are out of a multiple trans reply state. +************************************************************/ + +void cli_signing_trans_stop(struct cli_state *cli) +{ + struct smb_basic_signing_context *data = cli->sign_info.signing_context; + + if (!cli->sign_info.doing_signing) + return; + + if (data->trans_info) + SAFE_FREE(data->trans_info); + + data->send_seq_num += 2; +} + /*********************************************************** SMB signing - TEMP implementation - calculate a MAC to send. ************************************************************/ @@ -776,6 +838,7 @@ void srv_set_signing(const uchar user_session_key[16], const DATA_BLOB response) srv_sign_info.doing_signing = True; data = smb_xmalloc(sizeof(*data)); + memset(data, '\0', sizeof(*data)); srv_sign_info.signing_context = data; -- cgit From 760e58cf807e099b450c83fbdb8d393d53b9dca3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Aug 2003 03:06:07 +0000 Subject: Add the same signing code to the server. Ensure we use identical session numbers and MIDs when in trans/trans2/nttrans code. Jeremy. (This used to be commit 901544b29b4d815709b3dbad3012f1d2c419d904) --- source3/libsmb/smb_signing.c | 76 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 64 insertions(+), 12 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 81e25cb67c..d4c50a71f0 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -477,8 +477,8 @@ void cli_signing_trans_stop(struct cli_state *cli) if (!cli->sign_info.doing_signing) return; - if (data->trans_info) - SAFE_FREE(data->trans_info); + SAFE_FREE(data->trans_info); + data->trans_info = NULL; data->send_seq_num += 2; } @@ -598,10 +598,11 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) struct smb_basic_signing_context *data = si->signing_context; uint32 send_seq_number = data->send_seq_num; BOOL was_deferred_packet; + uint16 mid; if (!si->doing_signing) { if (si->allow_smb_signing && si->negotiated_smb_signing) { - uint16 mid = SVAL(outbuf, smb_mid); + mid = SVAL(outbuf, smb_mid); was_deferred_packet = get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number); @@ -632,10 +633,13 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) /* mark the packet as signed - BEFORE we sign it...*/ mark_packet_signed(outbuf); + mid = SVAL(outbuf, smb_mid); + /* See if this is a reply for a deferred packet. */ - was_deferred_packet = get_sequence_for_reply(&data->outstanding_packet_list, - SVAL(outbuf, smb_mid), - &send_seq_number); + was_deferred_packet = get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number); + + if (data->trans_info && (data->trans_info->mid == mid)) + send_seq_number = data->trans_info->send_seq_num; simple_packet_signature(data, outbuf, send_seq_number, calc_md5_mac); @@ -647,7 +651,7 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) /* cli->outbuf[smb_ss_field+2]=0; Uncomment this to test if the remote server actually verifies signatures...*/ - if (!was_deferred_packet) + if (!was_deferred_packet && !data->trans_info) data->send_seq_num++; } @@ -661,6 +665,7 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) uint32 reply_seq_number; unsigned char calc_md5_mac[16]; unsigned char *server_sent_mac; + uint mid; struct smb_basic_signing_context *data = si->signing_context; @@ -672,12 +677,16 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) return False; } + mid = SVAL(inbuf, smb_mid); + /* Oplock break requests store an outgoing mid in the packet list. */ - if (!get_sequence_for_reply(&data->outstanding_packet_list, - SVAL(inbuf, smb_mid), - &reply_seq_number)) { - reply_seq_number = data->send_seq_num; - data->send_seq_num++; + if (!get_sequence_for_reply(&data->outstanding_packet_list, mid, &reply_seq_number)) { + if (data->trans_info && (data->trans_info->mid == mid)) { + reply_seq_number = data->trans_info->reply_seq_num; + } else { + reply_seq_number = data->send_seq_num; + data->send_seq_num++; + } } simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); @@ -809,6 +818,49 @@ BOOL srv_is_signing_active(void) return srv_sign_info.doing_signing; } +/*********************************************************** + Tell server code we are in a multiple trans reply state. +************************************************************/ + +void srv_signing_trans_start(uint16 mid) +{ + struct smb_basic_signing_context *data; + + if (!srv_sign_info.doing_signing) + return; + + data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; + + data->trans_info = smb_xmalloc(sizeof(struct trans_info_context)); + ZERO_STRUCTP(data->trans_info); + + data->trans_info->reply_seq_num = data->send_seq_num-1; + data->trans_info->mid = mid; + data->trans_info->send_seq_num = data->send_seq_num; + + /* Increment now in case we need to send a non-trans + * reply in the middle of the trans stream. */ + data->send_seq_num++; +} + +/*********************************************************** + Tell server code we are out of a multiple trans reply state. +************************************************************/ + +void srv_signing_trans_stop(void) +{ + struct smb_basic_signing_context *data; + + if (!srv_sign_info.doing_signing) + return; + + data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; + + SAFE_FREE(data->trans_info); + data->trans_info = NULL; +} + + /*********************************************************** Turn on signing from this packet onwards. ************************************************************/ -- cgit From a202afb881e3f9db5f79d7cd93c64a49f128ba70 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Aug 2003 03:12:39 +0000 Subject: Leave the packet sequence checkers enabled whilst I track down a smbclient -> smbd sequence number problem. Jeremy. (This used to be commit 844898dbd8e99837ef1621aa73024714aa819ce4) --- source3/libsmb/smb_signing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index d4c50a71f0..5fc44eb953 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -351,7 +351,7 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n")); dump_data(5, server_sent_mac, 8); -#if 0 /* JRATEST */ +#if 1 /* JRATEST */ { int i; reply_seq_number -= 5; @@ -702,7 +702,7 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) DEBUG(5, ("srv_check_incoming_message: BAD SIG: got SMB signature of\n")); dump_data(5, server_sent_mac, 8); -#if 0 /* JRATEST */ +#if 1 /* JRATEST */ { int i; reply_seq_number -= 5; -- cgit From 099bd33a9999718e6cfe6cb387c8845805b67284 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Aug 2003 07:07:38 +0000 Subject: More fixes for client and server side signing. Ensure sequence numbers are updated correctly on returning an error for server trans streams. Ensure we turn off client trans streams on error. Jeremy. (This used to be commit 3a789cb7f01115c37404e5a696de363287cb0e5f) --- source3/libsmb/smb_signing.c | 57 ++++++++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 15 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 5fc44eb953..a62b5a4cdf 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -186,9 +186,6 @@ static void free_signing_context(struct smb_sign_info *si) static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good) { - DEBUG(10, ("signing_good: got SMB signature of\n")); - dump_data(10,&inbuf[smb_ss_field] , 8); - if (good && !si->doing_signing) { si->doing_signing = True; } @@ -199,11 +196,11 @@ static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good) /* W2K sends a bad first signature but the sign engine is on.... JRA. */ if (data->send_seq_num > 1) - DEBUG(1, ("SMB signature check failed!\n")); + DEBUG(1, ("signing_good: SMB signature check failed!\n")); return False; } else { - DEBUG(3, ("Server did not sign reply correctly\n")); + DEBUG(3, ("signing_good: Peer did not sign reply correctly\n")); free_signing_context(si); return False; } @@ -366,6 +363,9 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) } #endif /* JRATEST */ + } else { + DEBUG(10, ("client_check_incoming_message:: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); + dump_data(10, server_sent_mac, 8); } return signing_good(inbuf, si, good); } @@ -455,7 +455,7 @@ void cli_signing_trans_start(struct cli_state *cli) { struct smb_basic_signing_context *data = cli->sign_info.signing_context; - if (!cli->sign_info.doing_signing) + if (!cli->sign_info.doing_signing || !data) return; data->trans_info = smb_xmalloc(sizeof(struct trans_info_context)); @@ -464,6 +464,13 @@ void cli_signing_trans_start(struct cli_state *cli) data->trans_info->send_seq_num = data->send_seq_num; data->trans_info->mid = SVAL(cli->outbuf,smb_mid); data->trans_info->reply_seq_num = data->send_seq_num+1; + + DEBUG(10,("cli_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \ +data->send_seq_num = %u\n", + (unsigned int)data->trans_info->mid, + (unsigned int)data->trans_info->reply_seq_num, + (unsigned int)data->trans_info->send_seq_num, + (unsigned int)data->send_seq_num )); } /*********************************************************** @@ -474,7 +481,7 @@ void cli_signing_trans_stop(struct cli_state *cli) { struct smb_basic_signing_context *data = cli->sign_info.signing_context; - if (!cli->sign_info.doing_signing) + if (!cli->sign_info.doing_signing || !data) return; SAFE_FREE(data->trans_info); @@ -638,12 +645,15 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) /* See if this is a reply for a deferred packet. */ was_deferred_packet = get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number); - if (data->trans_info && (data->trans_info->mid == mid)) + if (data->trans_info && (data->trans_info->mid == mid)) { + /* This is a reply in a trans stream. Use the sequence + * number associated with the stream mid. */ send_seq_number = data->trans_info->send_seq_num; + } simple_packet_signature(data, outbuf, send_seq_number, calc_md5_mac); - DEBUG(10, ("srv_sign_outgoing_message: sent SMB signature of\n")); + DEBUG(10, ("srv_sign_outgoing_message: seq %u: sent SMB signature of\n", (unsigned int)send_seq_number)); dump_data(10, calc_md5_mac, 8); memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); @@ -651,8 +661,16 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) /* cli->outbuf[smb_ss_field+2]=0; Uncomment this to test if the remote server actually verifies signatures...*/ - if (!was_deferred_packet && !data->trans_info) - data->send_seq_num++; + if (!was_deferred_packet) { + if (!data->trans_info) { + /* Always increment if not in a trans stream. */ + data->send_seq_num++; + } else if ((data->trans_info->send_seq_num == data->send_seq_num) || (data->trans_info->mid != mid)) { + /* Increment if this is the first reply in a trans stream or a + * packet that doesn't belong to this stream (different mid). */ + data->send_seq_num++; + } + } } /*********************************************************** @@ -717,6 +735,9 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) } #endif /* JRATEST */ + } else { + DEBUG(10, ("srv_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); + dump_data(10, server_sent_mac, 8); } return signing_good(inbuf, si, good); } @@ -830,6 +851,8 @@ void srv_signing_trans_start(uint16 mid) return; data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; + if (!data) + return; data->trans_info = smb_xmalloc(sizeof(struct trans_info_context)); ZERO_STRUCTP(data->trans_info); @@ -838,9 +861,12 @@ void srv_signing_trans_start(uint16 mid) data->trans_info->mid = mid; data->trans_info->send_seq_num = data->send_seq_num; - /* Increment now in case we need to send a non-trans - * reply in the middle of the trans stream. */ - data->send_seq_num++; + DEBUG(10,("srv_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \ +data->send_seq_num = %u\n", + (unsigned int)mid, + (unsigned int)data->trans_info->reply_seq_num, + (unsigned int)data->trans_info->send_seq_num, + (unsigned int)data->send_seq_num )); } /*********************************************************** @@ -855,12 +881,13 @@ void srv_signing_trans_stop(void) return; data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; + if (!data || !data->trans_info) + return; SAFE_FREE(data->trans_info); data->trans_info = NULL; } - /*********************************************************** Turn on signing from this packet onwards. ************************************************************/ -- cgit From 9482f14b2cb6df0672853c1ba758152ff634ecea Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Aug 2003 08:38:34 +0000 Subject: Only look for mid sign records on incoming packets for oplock break replies. Otherwise we find spurious mid sign records on reply_ntcancel calls (they cancel by mid). That took a *lot* of tracking down. I still need to remove the mid records from the sign state on reply_ntcancel to avoid leaking memory.... Jeremy. (This used to be commit 270bf20fe3e226ab5cfc689bd20ed4c22b2fa7e6) --- source3/libsmb/smb_signing.c | 48 ++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 20 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index a62b5a4cdf..c3fc3306fe 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -54,6 +54,8 @@ static void store_sequence_for_reply(struct outstanding_packet_lookup **list, DLIST_ADD_END(*list, t, tmp); t->mid = mid; t->reply_seq_num = reply_seq_num; + DEBUG(10,("store_sequence_for_reply: stored seq = %u mid = %u\n", + (unsigned int)reply_seq_num, (unsigned int)mid )); } static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, @@ -64,6 +66,8 @@ static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, for (t = *list; t; t = t->next) { if (t->mid == mid) { *reply_seq_num = t->reply_seq_num; + DEBUG(10,("get_sequence_for_reply: found seq = %u mid = %u\n", + (unsigned int)t->reply_seq_num, (unsigned int)t->mid )); DLIST_REMOVE(*list, t); SAFE_FREE(t); return True; @@ -580,16 +584,12 @@ BOOL cli_check_sign_mac(struct cli_state *cli) return True; } -static BOOL outgoing_packet_is_oplock_break(char *outbuf) +static BOOL packet_is_oplock_break(char *buf) { - if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) { + if (CVAL(buf,smb_com) != SMBlockingX) return False; - } - if (CVAL(outbuf,smb_com) != SMBlockingX) - return False; - - if (CVAL(outbuf,smb_vwv3) != LOCKING_ANDX_OPLOCK_RELEASE) + if (CVAL(buf,smb_vwv3) != LOCKING_ANDX_OPLOCK_RELEASE) return False; return True; @@ -604,7 +604,7 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) unsigned char calc_md5_mac[16]; struct smb_basic_signing_context *data = si->signing_context; uint32 send_seq_number = data->send_seq_num; - BOOL was_deferred_packet; + BOOL was_deferred_packet = False; uint16 mid; if (!si->doing_signing) { @@ -619,7 +619,7 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) * mid in the outstanding list. */ - if (outgoing_packet_is_oplock_break(outbuf)) { + if (packet_is_oplock_break(outbuf)) { store_sequence_for_reply(&data->outstanding_packet_list, mid, data->send_seq_num); } @@ -680,13 +680,12 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) { BOOL good; - uint32 reply_seq_number; + struct smb_basic_signing_context *data = si->signing_context; + uint32 reply_seq_number = data->send_seq_num; unsigned char calc_md5_mac[16]; unsigned char *server_sent_mac; uint mid; - struct smb_basic_signing_context *data = si->signing_context; - if (!si->doing_signing) return True; @@ -697,14 +696,16 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) mid = SVAL(inbuf, smb_mid); - /* Oplock break requests store an outgoing mid in the packet list. */ - if (!get_sequence_for_reply(&data->outstanding_packet_list, mid, &reply_seq_number)) { - if (data->trans_info && (data->trans_info->mid == mid)) { - reply_seq_number = data->trans_info->reply_seq_num; - } else { - reply_seq_number = data->send_seq_num; - data->send_seq_num++; - } + /* Is this part of a trans stream ? */ + if (data->trans_info && (data->trans_info->mid == mid)) { + /* If so we don't increment the sequence. */ + reply_seq_number = data->trans_info->reply_seq_num; + } else { + /* We always increment the sequence number. */ + data->send_seq_num++; + /* Oplock break requests store an outgoing mid in the packet list. */ + if (packet_is_oplock_break(inbuf)) + get_sequence_for_reply(&data->outstanding_packet_list, mid, &reply_seq_number); } simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); @@ -884,6 +885,13 @@ void srv_signing_trans_stop(void) if (!data || !data->trans_info) return; + DEBUG(10,("srv_signing_trans_stop: removing mid = %u, reply_seq_num = %u, send_seq_num = %u \ +data->send_seq_num = %u\n", + (unsigned int)data->trans_info->mid, + (unsigned int)data->trans_info->reply_seq_num, + (unsigned int)data->trans_info->send_seq_num, + (unsigned int)data->send_seq_num )); + SAFE_FREE(data->trans_info); data->trans_info = NULL; } -- cgit From b925d197f5c1829f7bb8c18de2557c0ccc2d94a9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Aug 2003 08:48:01 +0000 Subject: Ensure we don't leak any sign records on cancel of pending requests. Jeremy. (This used to be commit 9a8ffc239c0f1aada713de7e9e007066738d8874) --- source3/libsmb/smb_signing.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index c3fc3306fe..4167452953 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -809,11 +809,38 @@ void srv_defer_sign_response(uint16 mid) data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; + if (!data) + return; + store_sequence_for_reply(&data->outstanding_packet_list, mid, data->send_seq_num); data->send_seq_num++; } +/*********************************************************** + Called to remove sequence records when a deferred packet is + cancelled by mid. This should never find one.... +************************************************************/ + +void srv_cancel_sign_response(uint16 mid) +{ + struct smb_basic_signing_context *data; + uint32 dummy_seq; + + if (!srv_sign_info.doing_signing) + return; + + data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; + + if (!data) + return; + + DEBUG(10,("srv_cancel_sign_response: for mid %u\n", (unsigned int)mid )); + + while (get_sequence_for_reply(&data->outstanding_packet_list, mid, &dummy_seq)) + ; +} + /*********************************************************** Called by server negprot when signing has been negotiated. ************************************************************/ -- cgit From a8646708e3b5bfe7838db7fe1f9f9974170d1f9e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 3 Aug 2003 07:12:46 +0000 Subject: Fix oplock break detection code on incoming oplock break responses. This fixes signing for oplocks. Jeremy. (This used to be commit 69c56ee8bce122839a8fec4e59198f84b0757166) --- source3/libsmb/smb_signing.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 4167452953..174e29fa52 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -188,7 +188,7 @@ static void free_signing_context(struct smb_sign_info *si) } -static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good) +static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good, uint32 seq) { if (good && !si->doing_signing) { si->doing_signing = True; @@ -200,7 +200,8 @@ static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good) /* W2K sends a bad first signature but the sign engine is on.... JRA. */ if (data->send_seq_num > 1) - DEBUG(1, ("signing_good: SMB signature check failed!\n")); + DEBUG(1, ("signing_good: SMB signature check failed on seq %u!\n", + (unsigned int)seq )); return False; } else { @@ -318,6 +319,7 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) { BOOL good; uint32 reply_seq_number; + uint32 saved_seq; unsigned char calc_md5_mac[16]; unsigned char *server_sent_mac; @@ -341,6 +343,7 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) return False; } + saved_seq = reply_seq_number; simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); server_sent_mac = &inbuf[smb_ss_field]; @@ -371,7 +374,7 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) DEBUG(10, ("client_check_incoming_message:: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); dump_data(10, server_sent_mac, 8); } - return signing_good(inbuf, si, good); + return signing_good(inbuf, si, good, saved_seq); } /*********************************************************** @@ -589,9 +592,10 @@ static BOOL packet_is_oplock_break(char *buf) if (CVAL(buf,smb_com) != SMBlockingX) return False; - if (CVAL(buf,smb_vwv3) != LOCKING_ANDX_OPLOCK_RELEASE) + if (!(CVAL(buf,smb_vwv3) & LOCKING_ANDX_OPLOCK_RELEASE)) return False; + DEBUG(10,("packet_is_oplock_break = True !\n")); return True; } @@ -682,6 +686,7 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) BOOL good; struct smb_basic_signing_context *data = si->signing_context; uint32 reply_seq_number = data->send_seq_num; + uint32 saved_seq; unsigned char calc_md5_mac[16]; unsigned char *server_sent_mac; uint mid; @@ -708,6 +713,7 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) get_sequence_for_reply(&data->outstanding_packet_list, mid, &reply_seq_number); } + saved_seq = reply_seq_number; simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); server_sent_mac = &inbuf[smb_ss_field]; @@ -715,10 +721,12 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) if (!good) { - DEBUG(5, ("srv_check_incoming_message: BAD SIG: wanted SMB signature of\n")); + DEBUG(5, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n", + (unsigned int)saved_seq)); dump_data(5, calc_md5_mac, 8); - DEBUG(5, ("srv_check_incoming_message: BAD SIG: got SMB signature of\n")); + DEBUG(5, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n", + (unsigned int)saved_seq)); dump_data(5, server_sent_mac, 8); #if 1 /* JRATEST */ @@ -740,7 +748,7 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) DEBUG(10, ("srv_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); dump_data(10, server_sent_mac, 8); } - return signing_good(inbuf, si, good); + return signing_good(inbuf, si, good, saved_seq); } /*********************************************************** -- cgit From 110abf10d208769bf6bcfc0604874cb1bed0406a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 7 Aug 2003 02:59:52 +0000 Subject: Turns out I had my packet sequences wrong for oplock break code. I was storing the mid of the oplock break - I should have been storing the mid from the open. There are thus 2 types of deferred packet sequence returns - ones that increment the sequence number (returns from oplock causing opens) and ones that don't (change notify returns etc). Running with signing forced on does lead to some interesting tests :-). Jeremy. (This used to be commit 85907f02cec566502d9e4adabbd414020a26064d) --- source3/libsmb/smb_signing.c | 65 +++++++++++++------------------------------- 1 file changed, 19 insertions(+), 46 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 174e29fa52..4b12f36eba 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -25,6 +25,7 @@ struct outstanding_packet_lookup { uint16 mid; uint32 reply_seq_num; + BOOL deferred_packet; struct outstanding_packet_lookup *prev, *next; }; @@ -43,7 +44,7 @@ struct smb_basic_signing_context { }; static void store_sequence_for_reply(struct outstanding_packet_lookup **list, - uint16 mid, uint32 reply_seq_num) + uint16 mid, uint32 reply_seq_num, BOOL deferred_pkt) { struct outstanding_packet_lookup *t; struct outstanding_packet_lookup *tmp; @@ -54,19 +55,25 @@ static void store_sequence_for_reply(struct outstanding_packet_lookup **list, DLIST_ADD_END(*list, t, tmp); t->mid = mid; t->reply_seq_num = reply_seq_num; - DEBUG(10,("store_sequence_for_reply: stored seq = %u mid = %u\n", + t->deferred_packet = deferred_pkt; + + DEBUG(10,("store_sequence_for_reply: stored %sseq = %u mid = %u\n", + deferred_pkt ? "deferred " : "", (unsigned int)reply_seq_num, (unsigned int)mid )); } static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, - uint16 mid, uint32 *reply_seq_num) + uint16 mid, uint32 *reply_seq_num, BOOL *def) { struct outstanding_packet_lookup *t; for (t = *list; t; t = t->next) { if (t->mid == mid) { *reply_seq_num = t->reply_seq_num; - DEBUG(10,("get_sequence_for_reply: found seq = %u mid = %u\n", + if (def) + *def = t->deferred_packet; + DEBUG(10,("get_sequence_for_reply: found %sseq = %u mid = %u\n", + (t->deferred_packet) ? "deferred " : "", (unsigned int)t->reply_seq_num, (unsigned int)t->mid )); DLIST_REMOVE(*list, t); SAFE_FREE(t); @@ -307,7 +314,7 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) data->send_seq_num++; store_sequence_for_reply(&data->outstanding_packet_list, SVAL(outbuf,smb_mid), - data->send_seq_num); + data->send_seq_num, False); data->send_seq_num++; } @@ -337,7 +344,7 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) reply_seq_number = data->trans_info->reply_seq_num; } else if (!get_sequence_for_reply(&data->outstanding_packet_list, SVAL(inbuf, smb_mid), - &reply_seq_number)) { + &reply_seq_number, NULL)) { DEBUG(1, ("client_check_incoming_message: failed to get sequence number %u for reply.\n", (unsigned int) SVAL(inbuf, smb_mid) )); return False; @@ -587,18 +594,6 @@ BOOL cli_check_sign_mac(struct cli_state *cli) return True; } -static BOOL packet_is_oplock_break(char *buf) -{ - if (CVAL(buf,smb_com) != SMBlockingX) - return False; - - if (!(CVAL(buf,smb_vwv3) & LOCKING_ANDX_OPLOCK_RELEASE)) - return False; - - DEBUG(10,("packet_is_oplock_break = True !\n")); - return True; -} - /*********************************************************** SMB signing - Server implementation - send the MAC. ************************************************************/ @@ -612,25 +607,6 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) uint16 mid; if (!si->doing_signing) { - if (si->allow_smb_signing && si->negotiated_smb_signing) { - mid = SVAL(outbuf, smb_mid); - - was_deferred_packet = get_sequence_for_reply(&data->outstanding_packet_list, - mid, &send_seq_number); - if (!was_deferred_packet) { - /* - * Is this an outgoing oplock break ? If so, store the - * mid in the outstanding list. - */ - - if (packet_is_oplock_break(outbuf)) { - store_sequence_for_reply(&data->outstanding_packet_list, - mid, data->send_seq_num); - } - - data->send_seq_num++; - } - } return; } @@ -647,7 +623,7 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) mid = SVAL(outbuf, smb_mid); /* See if this is a reply for a deferred packet. */ - was_deferred_packet = get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number); + get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number, &was_deferred_packet); if (data->trans_info && (data->trans_info->mid == mid)) { /* This is a reply in a trans stream. Use the sequence @@ -666,7 +642,7 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) Uncomment this to test if the remote server actually verifies signatures...*/ if (!was_deferred_packet) { - if (!data->trans_info) { + if (!data->trans_info) { /* Always increment if not in a trans stream. */ data->send_seq_num++; } else if ((data->trans_info->send_seq_num == data->send_seq_num) || (data->trans_info->mid != mid)) { @@ -674,7 +650,7 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) * packet that doesn't belong to this stream (different mid). */ data->send_seq_num++; } - } + } } /*********************************************************** @@ -708,9 +684,6 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) } else { /* We always increment the sequence number. */ data->send_seq_num++; - /* Oplock break requests store an outgoing mid in the packet list. */ - if (packet_is_oplock_break(inbuf)) - get_sequence_for_reply(&data->outstanding_packet_list, mid, &reply_seq_number); } saved_seq = reply_seq_number; @@ -808,7 +781,7 @@ void srv_calculate_sign_mac(char *outbuf) Called by server to defer an outgoing packet. ************************************************************/ -void srv_defer_sign_response(uint16 mid) +void srv_defer_sign_response(uint16 mid, BOOL deferred_packet) { struct smb_basic_signing_context *data; @@ -821,7 +794,7 @@ void srv_defer_sign_response(uint16 mid) return; store_sequence_for_reply(&data->outstanding_packet_list, - mid, data->send_seq_num); + mid, data->send_seq_num, deferred_packet); data->send_seq_num++; } @@ -845,7 +818,7 @@ void srv_cancel_sign_response(uint16 mid) DEBUG(10,("srv_cancel_sign_response: for mid %u\n", (unsigned int)mid )); - while (get_sequence_for_reply(&data->outstanding_packet_list, mid, &dummy_seq)) + while (get_sequence_for_reply(&data->outstanding_packet_list, mid, &dummy_seq,NULL)) ; } -- cgit From 3bbe9c0869ea8653f684afa9a1345f6fa2f80b4b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 7 Aug 2003 05:36:08 +0000 Subject: An oplock break reply from the client causes the sequence number to be updated by 2 if there is no open reply outstanding, else by one.... Yes - this makes no sense.... Jeremy. (This used to be commit b43ce1ff6109f6422a621329ceb713b42df40040) --- source3/libsmb/smb_signing.c | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 4b12f36eba..afacfc7a93 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -83,6 +83,22 @@ static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, return False; } +/*********************************************************** + A reply is pending if there is a non-deferred packet on the queue. +************************************************************/ + +static BOOL is_reply_pending(struct outstanding_packet_lookup *list) +{ + for (; list; list = list->next) { + if (!list->deferred_packet) { + DEBUG(10,("is_reply_pending: True.\n")); + return True; + } + } + DEBUG(10,("is_reply_pending: False.\n")); + return False; +} + /*********************************************************** SMB signing - Common code before we set a new signing implementation ************************************************************/ @@ -653,6 +669,22 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) } } +/*********************************************************** + Is an incoming packet an oplock break reply ? +************************************************************/ + +static BOOL is_oplock_break(char *inbuf) +{ + if (CVAL(inbuf,smb_com) != SMBlockingX) + return False; + + if (!(CVAL(inbuf,smb_vwv3) & LOCKING_ANDX_OPLOCK_RELEASE)) + return False; + + DEBUG(10,("is_oplock_break: Packet is oplock break\n")); + return True; +} + /*********************************************************** SMB signing - Server implementation - check a MAC sent by server. ************************************************************/ @@ -684,6 +716,13 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) } else { /* We always increment the sequence number. */ data->send_seq_num++; + + /* If we get an asynchronous oplock break reply and there + * isn't a reply pending we need to re-sync the sequence + * number. + */ + if (is_oplock_break(inbuf) && !is_reply_pending(data->outstanding_packet_list)) + data->send_seq_num++; } saved_seq = reply_seq_number; @@ -718,7 +757,7 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) #endif /* JRATEST */ } else { - DEBUG(10, ("srv_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); + DEBUG(10, ("srv_check_incoming_message: seq %u: (current is %u) got good SMB signature of\n", (unsigned int)reply_seq_number, (unsigned int)data->send_seq_num)); dump_data(10, server_sent_mac, 8); } return signing_good(inbuf, si, good, saved_seq); -- cgit From aa39cc37dab9c4f8c3295d872bb8cc143890b378 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Fri, 15 Aug 2003 04:42:05 +0000 Subject: get rid of more compiler warnings (This used to be commit 398bd14fc6e2f8ab2f34211270e179b8928a6669) --- source3/libsmb/smb_signing.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index afacfc7a93..08ff655a3f 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -314,10 +314,10 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) else send_seq_num = data->send_seq_num; - simple_packet_signature(data, outbuf, send_seq_num, calc_md5_mac); + simple_packet_signature(data, (const unsigned char *)outbuf, send_seq_num, calc_md5_mac); DEBUG(10, ("client_sign_outgoing_message: sent SMB signature of\n")); - dump_data(10, calc_md5_mac, 8); + dump_data(10, (const char *)calc_md5_mac, 8); memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); @@ -367,23 +367,23 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) } saved_seq = reply_seq_number; - simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); + simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); - server_sent_mac = &inbuf[smb_ss_field]; + server_sent_mac = (unsigned char *)&inbuf[smb_ss_field]; good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); if (!good) { DEBUG(5, ("client_check_incoming_message: BAD SIG: wanted SMB signature of\n")); - dump_data(5, calc_md5_mac, 8); + dump_data(5, (const char *)calc_md5_mac, 8); DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n")); - dump_data(5, server_sent_mac, 8); + dump_data(5, (const char *)server_sent_mac, 8); #if 1 /* JRATEST */ { int i; reply_seq_number -= 5; for (i = 0; i < 10; i++, reply_seq_number++) { - simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); + simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) { DEBUG(0,("client_check_incoming_message: out of seq. seq num %u matches.\n", reply_seq_number )); @@ -395,7 +395,7 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) } else { DEBUG(10, ("client_check_incoming_message:: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); - dump_data(10, server_sent_mac, 8); + dump_data(10, (const char *)server_sent_mac, 8); } return signing_good(inbuf, si, good, saved_seq); } @@ -454,12 +454,12 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ memcpy(&data->mac_key.data[0], user_session_key, 16); DEBUG(10, ("cli_simple_set_signing: user_session_key\n")); - dump_data(10, user_session_key, 16); + dump_data(10, (const char *)user_session_key, 16); if (response.length) { memcpy(&data->mac_key.data[16],response.data, response.length); DEBUG(10, ("cli_simple_set_signing: response_data\n")); - dump_data(10, response.data, response.length); + dump_data(10, (const char *)response.data, response.length); } else { DEBUG(10, ("cli_simple_set_signing: NULL response_data\n")); } @@ -647,10 +647,10 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) send_seq_number = data->trans_info->send_seq_num; } - simple_packet_signature(data, outbuf, send_seq_number, calc_md5_mac); + simple_packet_signature(data, (const unsigned char *)outbuf, send_seq_number, calc_md5_mac); DEBUG(10, ("srv_sign_outgoing_message: seq %u: sent SMB signature of\n", (unsigned int)send_seq_number)); - dump_data(10, calc_md5_mac, 8); + dump_data(10, (const char *)calc_md5_mac, 8); memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); @@ -726,27 +726,27 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) } saved_seq = reply_seq_number; - simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); + simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); - server_sent_mac = &inbuf[smb_ss_field]; + server_sent_mac = (unsigned char *)&inbuf[smb_ss_field]; good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); if (!good) { DEBUG(5, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n", (unsigned int)saved_seq)); - dump_data(5, calc_md5_mac, 8); + dump_data(5, (const char *)calc_md5_mac, 8); DEBUG(5, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n", (unsigned int)saved_seq)); - dump_data(5, server_sent_mac, 8); + dump_data(5, (const char *)server_sent_mac, 8); #if 1 /* JRATEST */ { int i; reply_seq_number -= 5; for (i = 0; i < 10; i++, reply_seq_number++) { - simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); + simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) { DEBUG(0,("srv_check_incoming_message: out of seq. seq num %u matches.\n", reply_seq_number )); @@ -758,7 +758,7 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) } else { DEBUG(10, ("srv_check_incoming_message: seq %u: (current is %u) got good SMB signature of\n", (unsigned int)reply_seq_number, (unsigned int)data->send_seq_num)); - dump_data(10, server_sent_mac, 8); + dump_data(10, (const char *)server_sent_mac, 8); } return signing_good(inbuf, si, good, saved_seq); } -- cgit From 1269d231132b414958a16b9a3544917e15b81f57 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 14 Oct 2003 17:01:03 +0000 Subject: Enable us to see what sequence number we were expecting when we fail a sign (should help track down out of sequence bugs). Jeremy. (This used to be commit 6e21261fe40698b2ee46c802bd1c044a909f8e5d) --- source3/libsmb/smb_signing.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 08ff655a3f..8a4401ef19 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -385,8 +385,8 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) for (i = 0; i < 10; i++, reply_seq_number++) { simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) { - DEBUG(0,("client_check_incoming_message: out of seq. seq num %u matches.\n", - reply_seq_number )); + DEBUG(0,("client_check_incoming_message: out of seq. seq num %u matches. \ +We were expecting seq %u\n", reply_seq_number, saved_seq )); break; } } @@ -748,8 +748,8 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) for (i = 0; i < 10; i++, reply_seq_number++) { simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) { - DEBUG(0,("srv_check_incoming_message: out of seq. seq num %u matches.\n", - reply_seq_number )); + DEBUG(0,("srv_check_incoming_message: out of seq. seq num %u matches. \ +We were expecting seq %u\n", reply_seq_number, saved_seq )); break; } } -- cgit From 3fe18a46a33cc1c0a0ecfefc61618356d7746a15 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 21 Oct 2003 17:40:58 +0000 Subject: Fix signing miss-sequence noticed by Stefan Metzmacher Jeremy. (This used to be commit 63f331564396e7a4f16dce95bb98d3b6c4b75351) --- source3/libsmb/smb_signing.c | 73 ++++++++++++++++---------------------------- 1 file changed, 27 insertions(+), 46 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 8a4401ef19..91509f0fb8 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -25,7 +25,6 @@ struct outstanding_packet_lookup { uint16 mid; uint32 reply_seq_num; - BOOL deferred_packet; struct outstanding_packet_lookup *prev, *next; }; @@ -44,7 +43,7 @@ struct smb_basic_signing_context { }; static void store_sequence_for_reply(struct outstanding_packet_lookup **list, - uint16 mid, uint32 reply_seq_num, BOOL deferred_pkt) + uint16 mid, uint32 reply_seq_num) { struct outstanding_packet_lookup *t; struct outstanding_packet_lookup *tmp; @@ -55,25 +54,20 @@ static void store_sequence_for_reply(struct outstanding_packet_lookup **list, DLIST_ADD_END(*list, t, tmp); t->mid = mid; t->reply_seq_num = reply_seq_num; - t->deferred_packet = deferred_pkt; - DEBUG(10,("store_sequence_for_reply: stored %sseq = %u mid = %u\n", - deferred_pkt ? "deferred " : "", + DEBUG(10,("store_sequence_for_reply: stored seq = %u mid = %u\n", (unsigned int)reply_seq_num, (unsigned int)mid )); } static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, - uint16 mid, uint32 *reply_seq_num, BOOL *def) + uint16 mid, uint32 *reply_seq_num) { struct outstanding_packet_lookup *t; for (t = *list; t; t = t->next) { if (t->mid == mid) { *reply_seq_num = t->reply_seq_num; - if (def) - *def = t->deferred_packet; - DEBUG(10,("get_sequence_for_reply: found %sseq = %u mid = %u\n", - (t->deferred_packet) ? "deferred " : "", + DEBUG(10,("get_sequence_for_reply: found seq = %u mid = %u\n", (unsigned int)t->reply_seq_num, (unsigned int)t->mid )); DLIST_REMOVE(*list, t); SAFE_FREE(t); @@ -83,22 +77,6 @@ static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, return False; } -/*********************************************************** - A reply is pending if there is a non-deferred packet on the queue. -************************************************************/ - -static BOOL is_reply_pending(struct outstanding_packet_lookup *list) -{ - for (; list; list = list->next) { - if (!list->deferred_packet) { - DEBUG(10,("is_reply_pending: True.\n")); - return True; - } - } - DEBUG(10,("is_reply_pending: False.\n")); - return False; -} - /*********************************************************** SMB signing - Common code before we set a new signing implementation ************************************************************/ @@ -329,8 +307,7 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) data->send_seq_num++; store_sequence_for_reply(&data->outstanding_packet_list, - SVAL(outbuf,smb_mid), - data->send_seq_num, False); + SVAL(outbuf,smb_mid), data->send_seq_num); data->send_seq_num++; } @@ -359,8 +336,7 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) if (data->trans_info) { reply_seq_number = data->trans_info->reply_seq_num; } else if (!get_sequence_for_reply(&data->outstanding_packet_list, - SVAL(inbuf, smb_mid), - &reply_seq_number, NULL)) { + SVAL(inbuf, smb_mid), &reply_seq_number)) { DEBUG(1, ("client_check_incoming_message: failed to get sequence number %u for reply.\n", (unsigned int) SVAL(inbuf, smb_mid) )); return False; @@ -639,7 +615,7 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) mid = SVAL(outbuf, smb_mid); /* See if this is a reply for a deferred packet. */ - get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number, &was_deferred_packet); + was_deferred_packet = get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number); if (data->trans_info && (data->trans_info->mid == mid)) { /* This is a reply in a trans stream. Use the sequence @@ -655,18 +631,21 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); /* cli->outbuf[smb_ss_field+2]=0; - Uncomment this to test if the remote server actually verifies signatures...*/ + Uncomment this to test if the remote client actually verifies signatures...*/ - if (!was_deferred_packet) { - if (!data->trans_info) { - /* Always increment if not in a trans stream. */ - data->send_seq_num++; - } else if ((data->trans_info->send_seq_num == data->send_seq_num) || (data->trans_info->mid != mid)) { - /* Increment if this is the first reply in a trans stream or a - * packet that doesn't belong to this stream (different mid). */ - data->send_seq_num++; - } - } + /* Don't mess with the sequence number for a deferred packet. */ + if (was_deferred_packet) { + return; + } + + if (!data->trans_info) { + /* Always increment if not in a trans stream. */ + data->send_seq_num++; + } else if ((data->trans_info->send_seq_num == data->send_seq_num) || (data->trans_info->mid != mid)) { + /* Increment if this is the first reply in a trans stream or a + * packet that doesn't belong to this stream (different mid). */ + data->send_seq_num++; + } } /*********************************************************** @@ -721,8 +700,10 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) * isn't a reply pending we need to re-sync the sequence * number. */ - if (is_oplock_break(inbuf) && !is_reply_pending(data->outstanding_packet_list)) + if (is_oplock_break(inbuf)) { + DEBUG(10,("srv_check_incoming_message: oplock break at seq num %u\n", data->send_seq_num)); data->send_seq_num++; + } } saved_seq = reply_seq_number; @@ -820,7 +801,7 @@ void srv_calculate_sign_mac(char *outbuf) Called by server to defer an outgoing packet. ************************************************************/ -void srv_defer_sign_response(uint16 mid, BOOL deferred_packet) +void srv_defer_sign_response(uint16 mid) { struct smb_basic_signing_context *data; @@ -833,7 +814,7 @@ void srv_defer_sign_response(uint16 mid, BOOL deferred_packet) return; store_sequence_for_reply(&data->outstanding_packet_list, - mid, data->send_seq_num, deferred_packet); + mid, data->send_seq_num); data->send_seq_num++; } @@ -857,7 +838,7 @@ void srv_cancel_sign_response(uint16 mid) DEBUG(10,("srv_cancel_sign_response: for mid %u\n", (unsigned int)mid )); - while (get_sequence_for_reply(&data->outstanding_packet_list, mid, &dummy_seq,NULL)) + while (get_sequence_for_reply(&data->outstanding_packet_list, mid, &dummy_seq)) ; } -- cgit From fcbfc7ad0669009957c65fa61bb20df75a9701b4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 22 Nov 2003 13:19:38 +0000 Subject: Changes all over the shop, but all towards: - NTLM2 support in the server - KEY_EXCH support in the server - variable length session keys. In detail: - NTLM2 is an extension of NTLMv1, that is compatible with existing domain controllers (unlike NTLMv2, which requires a DC upgrade). * This is known as 'NTLMv2 session security' * (This is not yet implemented on the RPC pipes however, so there may well still be issues for PDC setups, particuarly around password changes. We do not fully understand the sign/seal implications of NTLM2 on RPC pipes.) This requires modifications to our authentication subsystem, as we must handle the 'challege' input into the challenge-response algorithm being changed. This also needs to be turned off for 'security=server', which does not support this. - KEY_EXCH is another 'security' mechanism, whereby the session key actually used by the server is sent by the client, rather than being the shared-secret directly or indirectly. - As both these methods change the session key, the auth subsystem needed to be changed, to 'override' session keys provided by the backend. - There has also been a major overhaul of the NTLMSSP subsystem, to merge the 'client' and 'server' functions, so they both operate on a single structure. This should help the SPNEGO implementation. - The 'names blob' in NTLMSSP is always in unicode - never in ascii. Don't make an ascii version ever. - The other big change is to allow variable length session keys. We have always assumed that session keys are 16 bytes long - and padded to this length if shorter. However, Kerberos session keys are 8 bytes long, when the krb5 login uses DES. * This fix allows SMB signging on machines not yet running MIT KRB5 1.3.1. * - Add better DEBUG() messages to ntlm_auth, warning administrators of misconfigurations that prevent access to the privileged pipe. This should help reduce some of the 'it just doesn't work' issues. - Fix data_blob_talloc() to behave the same way data_blob() does when passed a NULL data pointer. (just allocate) REMEMBER to make clean after this commit - I have changed plenty of data structures... (This used to be commit f3bbc87b0dac63426cda6fac7a295d3aad810ecc) --- source3/libsmb/smb_signing.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 91509f0fb8..eec991072d 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -405,11 +405,11 @@ static void simple_free_signing_context(struct smb_sign_info *si) SMB signing - Simple implementation - setup the MAC key. ************************************************************/ -BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[16], const DATA_BLOB response) +BOOL cli_simple_set_signing(struct cli_state *cli, const DATA_BLOB user_session_key, const DATA_BLOB response) { struct smb_basic_signing_context *data; - if (!user_session_key) + if (!user_session_key.length) return False; if (!cli_set_smb_signing_common(cli)) { @@ -425,21 +425,23 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ cli->sign_info.signing_context = data; - data->mac_key = data_blob(NULL, response.length + 16); + data->mac_key = data_blob(NULL, response.length + user_session_key.length); - memcpy(&data->mac_key.data[0], user_session_key, 16); + memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length); DEBUG(10, ("cli_simple_set_signing: user_session_key\n")); - dump_data(10, (const char *)user_session_key, 16); + dump_data(10, (const char *)user_session_key.data, user_session_key.length); if (response.length) { - memcpy(&data->mac_key.data[16],response.data, response.length); + memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length); DEBUG(10, ("cli_simple_set_signing: response_data\n")); dump_data(10, (const char *)response.data, response.length); } else { DEBUG(10, ("cli_simple_set_signing: NULL response_data\n")); } + dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length); + /* Initialise the sequence number */ data->send_seq_num = 0; @@ -928,11 +930,11 @@ data->send_seq_num = %u\n", Turn on signing from this packet onwards. ************************************************************/ -void srv_set_signing(const uchar user_session_key[16], const DATA_BLOB response) +void srv_set_signing(const DATA_BLOB user_session_key, const DATA_BLOB response) { struct smb_basic_signing_context *data; - if (!user_session_key) + if (!user_session_key.length) return; if (!srv_sign_info.negotiated_smb_signing && !srv_sign_info.mandatory_signing) { @@ -957,11 +959,13 @@ void srv_set_signing(const uchar user_session_key[16], const DATA_BLOB response) srv_sign_info.signing_context = data; - data->mac_key = data_blob(NULL, response.length + 16); + data->mac_key = data_blob(NULL, response.length + user_session_key.length); - memcpy(&data->mac_key.data[0], user_session_key, 16); + memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length); if (response.length) - memcpy(&data->mac_key.data[16],response.data, response.length); + memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length); + + dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length); /* Initialise the sequence number */ data->send_seq_num = 0; -- cgit From efdd1ea572b1e05c3bf169a1a93dffcdabe600b5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 25 Nov 2003 00:32:51 +0000 Subject: When server signing is set to "auto", if the client doesn't sign just ignore it. Only fail if signing is set to "required". Jeremy. (This used to be commit 8916ddfc39c3e70265188926f24034152f0e7b6b) --- source3/libsmb/smb_signing.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index eec991072d..2a53638d17 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -370,7 +370,7 @@ We were expecting seq %u\n", reply_seq_number, saved_seq )); #endif /* JRATEST */ } else { - DEBUG(10, ("client_check_incoming_message:: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); + DEBUG(10, ("client_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); dump_data(10, (const char *)server_sent_mac, 8); } return signing_good(inbuf, si, good, saved_seq); @@ -743,7 +743,24 @@ We were expecting seq %u\n", reply_seq_number, saved_seq )); DEBUG(10, ("srv_check_incoming_message: seq %u: (current is %u) got good SMB signature of\n", (unsigned int)reply_seq_number, (unsigned int)data->send_seq_num)); dump_data(10, (const char *)server_sent_mac, 8); } - return signing_good(inbuf, si, good, saved_seq); + + if (!signing_good(inbuf, si, good, saved_seq)) { + if (si->mandatory_signing) { + /* Mandatory signing - fail and disconnect. */ + return False; + } else { + /* Non-mandatory signing - just turn off. */ + DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and client \ +isn't sending correct signatures. Turning off.\n")); + si->negotiated_smb_signing = False; + si->allow_smb_signing = False; + si->doing_signing = False; + free_signing_context(si); + return True; + } + } else { + return True; + } } /*********************************************************** @@ -967,6 +984,10 @@ void srv_set_signing(const DATA_BLOB user_session_key, const DATA_BLOB response) dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length); + DEBUG(3,("srv_set_signing: turning on SMB signing: signing negotiated = %s, mandatory_signing = %s.\n", + BOOLSTR(srv_sign_info.negotiated_smb_signing), + BOOLSTR(srv_sign_info.mandatory_signing) )); + /* Initialise the sequence number */ data->send_seq_num = 0; -- cgit From 6ce882ef292b1e785b8b859b48256da11091c0d1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 25 Nov 2003 18:15:52 +0000 Subject: If signing starts successfully, don't just turn it off automatically if it fails later. Only turn it off automatically if it fails at the start. Jeremy. (This used to be commit 4a145531c2b6353291cd25f14f5572aa31e86594) --- source3/libsmb/smb_signing.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 2a53638d17..755a1548eb 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -745,11 +745,8 @@ We were expecting seq %u\n", reply_seq_number, saved_seq )); } if (!signing_good(inbuf, si, good, saved_seq)) { - if (si->mandatory_signing) { - /* Mandatory signing - fail and disconnect. */ - return False; - } else { - /* Non-mandatory signing - just turn off. */ + if (!si->mandatory_signing && (data->send_seq_num < 3)){ + /* Non-mandatory signing - just turn off if this is the first bad packet.. */ DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and client \ isn't sending correct signatures. Turning off.\n")); si->negotiated_smb_signing = False; @@ -757,6 +754,9 @@ isn't sending correct signatures. Turning off.\n")); si->doing_signing = False; free_signing_context(si); return True; + } else { + /* Mandatory signing or bad packet after signing started - fail and disconnect. */ + return False; } } else { return True; -- cgit From 12d3246a6c0fe2d6241d7f7ec8573b263a559390 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 1 Dec 2003 01:04:04 +0000 Subject: Better fix for client signing bug. Ensure we don't malloc/free trans signing state info each packet. Jeremy. (This used to be commit 818cf32d6330f7e7855ce662326003e75d4a1d46) --- source3/libsmb/smb_signing.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 755a1548eb..cb35fda220 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -457,9 +457,12 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const DATA_BLOB user_session_ /*********************************************************** Tell client code we are in a multiple trans reply state. + We call this after the last outgoing trans2 packet (which + has incremented the sequence numbers), so we must save the + current mid and sequence number -2. ************************************************************/ -void cli_signing_trans_start(struct cli_state *cli) +void cli_signing_trans_start(struct cli_state *cli, uint16 mid) { struct smb_basic_signing_context *data = cli->sign_info.signing_context; @@ -469,9 +472,9 @@ void cli_signing_trans_start(struct cli_state *cli) data->trans_info = smb_xmalloc(sizeof(struct trans_info_context)); ZERO_STRUCTP(data->trans_info); - data->trans_info->send_seq_num = data->send_seq_num; - data->trans_info->mid = SVAL(cli->outbuf,smb_mid); - data->trans_info->reply_seq_num = data->send_seq_num+1; + data->trans_info->send_seq_num = data->send_seq_num-2; + data->trans_info->mid = mid; + data->trans_info->reply_seq_num = data->send_seq_num-1; DEBUG(10,("cli_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \ data->send_seq_num = %u\n", @@ -492,10 +495,15 @@ void cli_signing_trans_stop(struct cli_state *cli) if (!cli->sign_info.doing_signing || !data) return; + DEBUG(10,("cli_signing_trans_stop: freeing mid = %u, reply_seq_num = %u, send_seq_num = %u \ +data->send_seq_num = %u\n", + (unsigned int)data->trans_info->mid, + (unsigned int)data->trans_info->reply_seq_num, + (unsigned int)data->trans_info->send_seq_num, + (unsigned int)data->send_seq_num )); + SAFE_FREE(data->trans_info); data->trans_info = NULL; - - data->send_seq_num += 2; } /*********************************************************** -- cgit From f7dfa789c1601d92a76fe0804b095f6931a93246 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 1 Dec 2003 06:59:54 +0000 Subject: Fix spurious error msg. when seq=0. Jeremy (This used to be commit 4912ad8f18041c9c3abe2cfa67dd26a324c9c31e) --- source3/libsmb/smb_signing.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index cb35fda220..6b2abb9ccc 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -764,6 +764,8 @@ isn't sending correct signatures. Turning off.\n")); return True; } else { /* Mandatory signing or bad packet after signing started - fail and disconnect. */ + if (saved_seq) + DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u\n", (unsigned int)saved_seq)); return False; } } else { -- cgit From 82027c1ea2e44f51fa3a622af54736bac2e754a3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 27 Dec 2003 10:11:26 +0000 Subject: Preliminary fix for our signing problem with failed NTLMSSP logins. This patch solves the problem for me here, I can still successfully set up signing using NTLMSSP against w2k3 and it does not show a signing error anymoe when the password was wrong. Jeremy, you might want to take a further look at it as this is not particularly elegant. Volker (This used to be commit f5afaafd61dc7bd191225ffa8eee184125dd97c3) --- source3/libsmb/smb_signing.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 6b2abb9ccc..8a056f659f 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -405,7 +405,9 @@ static void simple_free_signing_context(struct smb_sign_info *si) SMB signing - Simple implementation - setup the MAC key. ************************************************************/ -BOOL cli_simple_set_signing(struct cli_state *cli, const DATA_BLOB user_session_key, const DATA_BLOB response) +BOOL cli_simple_set_signing(struct cli_state *cli, + const DATA_BLOB user_session_key, + const DATA_BLOB response, int initial_send_seq_num) { struct smb_basic_signing_context *data; @@ -443,7 +445,7 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const DATA_BLOB user_session_ dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length); /* Initialise the sequence number */ - data->send_seq_num = 0; + data->send_seq_num = initial_send_seq_num; /* Initialise the list of outstanding packets */ data->outstanding_packet_list = NULL; -- cgit From bb1119acca3f0735ca57871015d499d2358c9fb2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 17 Jan 2004 00:30:35 +0000 Subject: Fix for a signing bug when the mid wraps. Found by Fran Fabrizio . Add to the *start* of the list not the end of the list. This ensures that the *last* send sequence with this mid is returned by preference. This can happen if the mid wraps and one of the early mid numbers didn't get a reply and is still lurking on the list. Jeremy. (This used to be commit 25d739978fe9081ba0946c36901492127248e3e0) --- source3/libsmb/smb_signing.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 8a056f659f..9010dbf5cb 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -46,15 +46,23 @@ static void store_sequence_for_reply(struct outstanding_packet_lookup **list, uint16 mid, uint32 reply_seq_num) { struct outstanding_packet_lookup *t; - struct outstanding_packet_lookup *tmp; - + t = smb_xmalloc(sizeof(*t)); ZERO_STRUCTP(t); - DLIST_ADD_END(*list, t, tmp); t->mid = mid; t->reply_seq_num = reply_seq_num; + /* + * Add to the *start* of the list not the end of the list. + * This ensures that the *last* send sequence with this mid + * is returned by preference. + * This can happen if the mid wraps and one of the early + * mid numbers didn't get a reply and is still lurking on + * the list. JRA. Found by Fran Fabrizio . + */ + + DLIST_ADD(*list, t); DEBUG(10,("store_sequence_for_reply: stored seq = %u mid = %u\n", (unsigned int)reply_seq_num, (unsigned int)mid )); } -- cgit From e9a7e67e01c115328f95690cbf63ca1ef0b4d408 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 27 Mar 2004 07:33:59 +0000 Subject: Merge from HEAD the SMB signing patch that I developed a couple of weeks ago. This patch re-adds support for 'optional' SMB signing. It also ensures that we are much more careful about when we enable signing, particularly with on-the-fly smb.conf reloads. The client code will now attempt to use smb signing by default, and disable it if the server doesn't correctly support it. Andrew Bartlett (This used to be commit e27b5cbe75d89ec839dafd52dd33101885a4c263) --- source3/libsmb/smb_signing.c | 120 +++++++++++++++++++++++++++---------------- 1 file changed, 76 insertions(+), 44 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 9010dbf5cb..c71543959d 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -150,7 +150,7 @@ static void null_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) SMB signing - NULL implementation - check a MAC sent by server. ************************************************************/ -static BOOL null_check_incoming_message(char *inbuf, struct smb_sign_info *si) +static BOOL null_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL must_be_ok) { return True; } @@ -197,25 +197,39 @@ static void free_signing_context(struct smb_sign_info *si) } -static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good, uint32 seq) +static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good, uint32 seq, BOOL must_be_ok) { - if (good && !si->doing_signing) { - si->doing_signing = True; - } + if (good) { - if (!good) { - if (si->doing_signing) { - struct smb_basic_signing_context *data = si->signing_context; + if (!si->doing_signing) { + si->doing_signing = True; + } + + if (!si->seen_valid) { + si->seen_valid = True; + } - /* W2K sends a bad first signature but the sign engine is on.... JRA. */ - if (data->send_seq_num > 1) - DEBUG(1, ("signing_good: SMB signature check failed on seq %u!\n", - (unsigned int)seq )); + } else { + if (!si->mandatory_signing && !si->seen_valid) { - return False; - } else { - DEBUG(3, ("signing_good: Peer did not sign reply correctly\n")); + if (!must_be_ok) { + return True; + } + /* Non-mandatory signing - just turn off if this is the first bad packet.. */ + DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and client \ +isn't sending correct signatures. Turning off.\n")); + si->negotiated_smb_signing = False; + si->allow_smb_signing = False; + si->doing_signing = False; free_signing_context(si); + return True; + } else if (!must_be_ok) { + /* This packet is known to be unsigned */ + return True; + } else { + /* Mandatory signing or bad packet after signing started - fail and disconnect. */ + if (seq) + DEBUG(0, ("signing_good: BAD SIG: seq %u\n", (unsigned int)seq)); return False; } } @@ -323,7 +337,7 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) SMB signing - Client implementation - check a MAC sent by server. ************************************************************/ -static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) +static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL must_be_ok) { BOOL good; uint32 reply_seq_number; @@ -381,7 +395,7 @@ We were expecting seq %u\n", reply_seq_number, saved_seq )); DEBUG(10, ("client_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); dump_data(10, (const char *)server_sent_mac, 8); } - return signing_good(inbuf, si, good, saved_seq); + return signing_good(inbuf, si, good, saved_seq, must_be_ok); } /*********************************************************** @@ -415,7 +429,7 @@ static void simple_free_signing_context(struct smb_sign_info *si) BOOL cli_simple_set_signing(struct cli_state *cli, const DATA_BLOB user_session_key, - const DATA_BLOB response, int initial_send_seq_num) + const DATA_BLOB response) { struct smb_basic_signing_context *data; @@ -453,7 +467,7 @@ BOOL cli_simple_set_signing(struct cli_state *cli, dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length); /* Initialise the sequence number */ - data->send_seq_num = initial_send_seq_num; + data->send_seq_num = 0; /* Initialise the list of outstanding packets */ data->outstanding_packet_list = NULL; @@ -535,7 +549,7 @@ static void temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) SMB signing - TEMP implementation - check a MAC sent by server. ************************************************************/ -static BOOL temp_check_incoming_message(char *inbuf, struct smb_sign_info *si) +static BOOL temp_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL foo) { return True; } @@ -597,9 +611,9 @@ void cli_calculate_sign_mac(struct cli_state *cli) * which had a bad checksum, True otherwise. */ -BOOL cli_check_sign_mac(struct cli_state *cli) +BOOL cli_check_sign_mac(struct cli_state *cli, BOOL must_be_ok) { - if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info)) { + if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info, must_be_ok)) { free_signing_context(&cli->sign_info); return False; } @@ -688,7 +702,7 @@ static BOOL is_oplock_break(char *inbuf) SMB signing - Server implementation - check a MAC sent by server. ************************************************************/ -static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) +static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL must_be_ok) { BOOL good; struct smb_basic_signing_context *data = si->signing_context; @@ -762,25 +776,7 @@ We were expecting seq %u\n", reply_seq_number, saved_seq )); dump_data(10, (const char *)server_sent_mac, 8); } - if (!signing_good(inbuf, si, good, saved_seq)) { - if (!si->mandatory_signing && (data->send_seq_num < 3)){ - /* Non-mandatory signing - just turn off if this is the first bad packet.. */ - DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and client \ -isn't sending correct signatures. Turning off.\n")); - si->negotiated_smb_signing = False; - si->allow_smb_signing = False; - si->doing_signing = False; - free_signing_context(si); - return True; - } else { - /* Mandatory signing or bad packet after signing started - fail and disconnect. */ - if (saved_seq) - DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u\n", (unsigned int)saved_seq)); - return False; - } - } else { - return True; - } + return (signing_good(inbuf, si, good, saved_seq, must_be_ok)); } /*********************************************************** @@ -813,13 +809,13 @@ BOOL srv_oplock_set_signing(BOOL onoff) Called to validate an incoming packet from the client. ************************************************************/ -BOOL srv_check_sign_mac(char *inbuf) +BOOL srv_check_sign_mac(char *inbuf, BOOL must_be_ok) { /* Check if it's a session keepalive. */ if(CVAL(inbuf,0) == SMBkeepalive) return True; - return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info); + return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info, must_be_ok); } /*********************************************************** @@ -907,6 +903,42 @@ BOOL srv_is_signing_active(void) return srv_sign_info.doing_signing; } + +/*********************************************************** + Returns whether signing is negotiated. We can't use it unless it was + in the negprot. +************************************************************/ + +BOOL srv_is_signing_negotiated(void) +{ + return srv_sign_info.negotiated_smb_signing; +} + +/*********************************************************** + Returns whether signing is negotiated. We can't use it unless it was + in the negprot. +************************************************************/ + +BOOL srv_signing_started(void) +{ + struct smb_basic_signing_context *data; + + if (!srv_sign_info.doing_signing) { + return False; + } + + data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; + if (!data) + return False; + + if (data->send_seq_num == 0) { + return False; + } + + return True; +} + + /*********************************************************** Tell server code we are in a multiple trans reply state. ************************************************************/ -- cgit From 6dbd02d056750de48dd09c2a222a36e74079d044 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 27 Mar 2004 07:51:31 +0000 Subject: Make it clearer that this error refers to the peer, as this code is in both the client and server. Andrew Bartlett (This used to be commit 414d3fdc753b44262e9a281170d1058608d01bdf) --- source3/libsmb/smb_signing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index c71543959d..7a90e645b3 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -216,8 +216,8 @@ static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good, uint3 return True; } /* Non-mandatory signing - just turn off if this is the first bad packet.. */ - DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and client \ -isn't sending correct signatures. Turning off.\n")); + DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and peer\n" + "isn't sending correct signatures. Turning off.\n")); si->negotiated_smb_signing = False; si->allow_smb_signing = False; si->doing_signing = False; -- cgit From 7c2b0d536b5b76aeec60a5c1d4be8316d19099d9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 27 Mar 2004 10:32:59 +0000 Subject: Let the comment match the function... Andrew Bartlett (This used to be commit 43c71b3202e909cca7c41c54d0b340aea1323db6) --- source3/libsmb/smb_signing.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 7a90e645b3..7130453c0c 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -915,8 +915,7 @@ BOOL srv_is_signing_negotiated(void) } /*********************************************************** - Returns whether signing is negotiated. We can't use it unless it was - in the negprot. + Returns whether signing is actually happening ************************************************************/ BOOL srv_signing_started(void) -- cgit From fddef6fc201ed127eaac737e725d1c2dd8c6926e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 11 Jun 2004 17:54:23 +0000 Subject: r1115: Fix for #1427. Catch bad path errors at the right point. Ensure all our pathname parsing is consistent. Jeremy. (This used to be commit 5e8237e306f0bb0e492f10fb6487938132899384) --- source3/libsmb/smb_signing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 7130453c0c..63838e6933 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -748,11 +748,11 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si, BO if (!good) { - DEBUG(5, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n", + DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n", (unsigned int)saved_seq)); dump_data(5, (const char *)calc_md5_mac, 8); - DEBUG(5, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n", + DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n", (unsigned int)saved_seq)); dump_data(5, (const char *)server_sent_mac, 8); -- cgit From 58686e844f30e0c1712ec87d7f1b3e743d09be96 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 11 Jun 2004 23:54:52 +0000 Subject: r1117: Doh ! Remember to turn off signing when sending a "break to level II" oplock message, or we mess up the signing sequence number.... Also improve sign error reporting. Also when deferring an open that had been deferred due to an oplock break, don't re-add the mid to the pending sign queue or we increment the sequence number twice and mess up signing again... I can now bounce between 2 WinXP/Win2003 boxes opening Excel spreadsheets with signing turned on and get correct "file in use" messages. Jeremy. (This used to be commit 1745ce4e2cf7fcb4c27c077973258d157cd241b1) --- source3/libsmb/smb_signing.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 63838e6933..868c991c16 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -42,11 +42,18 @@ struct smb_basic_signing_context { struct outstanding_packet_lookup *outstanding_packet_list; }; -static void store_sequence_for_reply(struct outstanding_packet_lookup **list, +static BOOL store_sequence_for_reply(struct outstanding_packet_lookup **list, uint16 mid, uint32 reply_seq_num) { struct outstanding_packet_lookup *t; + /* Ensure we only add a mid once. */ + for (t = *list; t; t = t->next) { + if (t->mid == mid) { + return False; + } + } + t = smb_xmalloc(sizeof(*t)); ZERO_STRUCTP(t); @@ -65,6 +72,7 @@ static void store_sequence_for_reply(struct outstanding_packet_lookup **list, DLIST_ADD(*list, t); DEBUG(10,("store_sequence_for_reply: stored seq = %u mid = %u\n", (unsigned int)reply_seq_num, (unsigned int)mid )); + return True; } static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, @@ -748,14 +756,16 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si, BO if (!good) { - DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n", - (unsigned int)saved_seq)); - dump_data(5, (const char *)calc_md5_mac, 8); - - DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n", + if (saved_seq) { + DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n", (unsigned int)saved_seq)); - dump_data(5, (const char *)server_sent_mac, 8); + dump_data(5, (const char *)calc_md5_mac, 8); + DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n", + (unsigned int)reply_seq_number)); + dump_data(5, (const char *)server_sent_mac, 8); + } + #if 1 /* JRATEST */ { int i; @@ -848,9 +858,13 @@ void srv_defer_sign_response(uint16 mid) if (!data) return; - store_sequence_for_reply(&data->outstanding_packet_list, - mid, data->send_seq_num); - data->send_seq_num++; + /* + * Ensure we only store this mid reply once... + */ + + if (store_sequence_for_reply(&data->outstanding_packet_list, mid, data->send_seq_num)) { + data->send_seq_num++; + } } /*********************************************************** -- cgit From e27895d54fa487d28a87e1d31f172e6e468100e2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 13 Jun 2004 23:08:47 +0000 Subject: r1121: Fix memory leak in the trans2 signing code. We would start the trans2 state, which is fine, but never pull the expected reply off the packet queue. I'm not sure if this is still a major problem after jra's recent 'no duplicate mids on the list' change, but I think this is correct anyway. (This used to be commit ee23a4237d427ce72d6a8c5f180ef48d6454cddc) --- source3/libsmb/smb_signing.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 868c991c16..8c59e49ebb 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -497,6 +497,7 @@ BOOL cli_simple_set_signing(struct cli_state *cli, void cli_signing_trans_start(struct cli_state *cli, uint16 mid) { struct smb_basic_signing_context *data = cli->sign_info.signing_context; + uint32 reply_seq_num; if (!cli->sign_info.doing_signing || !data) return; @@ -504,9 +505,16 @@ void cli_signing_trans_start(struct cli_state *cli, uint16 mid) data->trans_info = smb_xmalloc(sizeof(struct trans_info_context)); ZERO_STRUCTP(data->trans_info); - data->trans_info->send_seq_num = data->send_seq_num-2; + /* This ensures the sequence is pulled off the outstanding packet list */ + if (!get_sequence_for_reply(&data->outstanding_packet_list, + mid, &reply_seq_num)) { + DEBUG(1, ("get_sequence_for_reply failed - did we enter the trans signing state without sending a packet?\n")); + return; + } + + data->trans_info->send_seq_num = reply_seq_num - 1; data->trans_info->mid = mid; - data->trans_info->reply_seq_num = data->send_seq_num-1; + data->trans_info->reply_seq_num = reply_seq_num; DEBUG(10,("cli_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \ data->send_seq_num = %u\n", -- cgit From 8f93b500320d7d4341dfea37fd1f82d02b1ce980 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 14 Jul 2004 01:20:50 +0000 Subject: r1487: Remove unused parameter for the client-side signing functions. Andrew Bartlett (This used to be commit 6d594d5bb119b6bc3f4c7699752666ac24d04745) --- source3/libsmb/smb_signing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 8c59e49ebb..39131debf5 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -627,9 +627,9 @@ void cli_calculate_sign_mac(struct cli_state *cli) * which had a bad checksum, True otherwise. */ -BOOL cli_check_sign_mac(struct cli_state *cli, BOOL must_be_ok) +BOOL cli_check_sign_mac(struct cli_state *cli) { - if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info, must_be_ok)) { + if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info, True)) { free_signing_context(&cli->sign_info); return False; } -- cgit From e798a6b9fee3874ea7bb2589e1ecc66b3c012353 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 27 Oct 2004 17:40:28 +0000 Subject: r3294: Fix for SMB signing with 56-bit DES session keys. From Nalin Dahyabhai . Jeremy. (This used to be commit 55d23cb253d869e58bd51cf179c6dc0f3cfab9d2) --- source3/libsmb/smb_signing.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 39131debf5..b02a13c73e 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -255,6 +255,7 @@ static void simple_packet_signature(struct smb_basic_signing_context *data, const size_t offset_end_of_sig = (smb_ss_field + 8); unsigned char sequence_buf[8]; struct MD5Context md5_ctx; + unsigned char key_buf[16]; /* * Firstly put the sequence number into the first 4 bytes. @@ -276,8 +277,14 @@ static void simple_packet_signature(struct smb_basic_signing_context *data, MD5Init(&md5_ctx); /* intialise with the key */ - MD5Update(&md5_ctx, data->mac_key.data, - data->mac_key.length); + /* NB. When making and verifying SMB signatures, Windows apparently + zero-pads the key to 128 bits if it isn't long enough. + From Nalin Dahyabhai */ + MD5Update(&md5_ctx, data->mac_key.data, data->mac_key.length); + if (data->mac_key.length < sizeof(key_buf)) { + memset(key_buf, 0, sizeof(key_buf)); + MD5Update(&md5_ctx, key_buf, sizeof(key_buf) - data->mac_key.length); + } /* copy in the first bit of the SMB header */ MD5Update(&md5_ctx, buf + 4, smb_ss_field - 4); -- cgit From acf9d61421faa6c0055d57fdee7db300dc5431aa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 7 Dec 2004 18:25:53 +0000 Subject: r4088: Get medieval on our ass about malloc.... :-). Take control of all our allocation functions so we can funnel through some well known functions. Should help greatly with malloc checking. HEAD patch to follow. Jeremy. (This used to be commit 620f2e608f70ba92f032720c031283d295c5c06a) --- source3/libsmb/smb_signing.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index b02a13c73e..df69ff3e41 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -54,7 +54,7 @@ static BOOL store_sequence_for_reply(struct outstanding_packet_lookup **list, } } - t = smb_xmalloc(sizeof(*t)); + t = SMB_XMALLOC_P(struct outstanding_packet_lookup); ZERO_STRUCTP(t); t->mid = mid; @@ -459,7 +459,7 @@ BOOL cli_simple_set_signing(struct cli_state *cli, return False; } - data = smb_xmalloc(sizeof(*data)); + data = SMB_XMALLOC_P(struct smb_basic_signing_context); memset(data, '\0', sizeof(*data)); cli->sign_info.signing_context = data; @@ -509,7 +509,7 @@ void cli_signing_trans_start(struct cli_state *cli, uint16 mid) if (!cli->sign_info.doing_signing || !data) return; - data->trans_info = smb_xmalloc(sizeof(struct trans_info_context)); + data->trans_info = SMB_XMALLOC_P(struct trans_info_context); ZERO_STRUCTP(data->trans_info); /* This ensures the sequence is pulled off the outstanding packet list */ @@ -982,7 +982,7 @@ void srv_signing_trans_start(uint16 mid) if (!data) return; - data->trans_info = smb_xmalloc(sizeof(struct trans_info_context)); + data->trans_info = SMB_XMALLOC_P(struct trans_info_context); ZERO_STRUCTP(data->trans_info); data->trans_info->reply_seq_num = data->send_seq_num-1; @@ -1051,7 +1051,7 @@ void srv_set_signing(const DATA_BLOB user_session_key, const DATA_BLOB response) srv_sign_info.doing_signing = True; - data = smb_xmalloc(sizeof(*data)); + data = SMB_XMALLOC_P(struct smb_basic_signing_context); memset(data, '\0', sizeof(*data)); srv_sign_info.signing_context = data; -- cgit From 3b7dccf076628114d4fb1f67ab7aa05457de367d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 15 Mar 2005 18:21:35 +0000 Subject: r5804: Revert the signing change by Nalin Dahyabhai . Seems to be incorrect (several user reports). Jeremy. (This used to be commit 0abfb67c79dde280b3dae14a7c7bcdb5f4d58e44) --- source3/libsmb/smb_signing.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index df69ff3e41..500ff7cc6e 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -277,14 +277,17 @@ static void simple_packet_signature(struct smb_basic_signing_context *data, MD5Init(&md5_ctx); /* intialise with the key */ + MD5Update(&md5_ctx, data->mac_key.data, data->mac_key.length); +#if 0 + /* JRA - apparently this is incorrect. */ /* NB. When making and verifying SMB signatures, Windows apparently zero-pads the key to 128 bits if it isn't long enough. From Nalin Dahyabhai */ - MD5Update(&md5_ctx, data->mac_key.data, data->mac_key.length); if (data->mac_key.length < sizeof(key_buf)) { memset(key_buf, 0, sizeof(key_buf)); MD5Update(&md5_ctx, key_buf, sizeof(key_buf) - data->mac_key.length); } +#endif /* copy in the first bit of the SMB header */ MD5Update(&md5_ctx, buf + 4, smb_ss_field - 4); -- cgit From d177f1bc8f0cb5ad91c9146871ba2e93eb2988d2 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 15 Mar 2005 20:12:51 +0000 Subject: r5806: * fix a couple more segvs in spoolss * comment out unused variable after jra's change to revert the 56bit des smb signing changes (This used to be commit 13ed08cd2a1097021cc44f4109859ba89db7df81) --- source3/libsmb/smb_signing.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 500ff7cc6e..f0f2024e7b 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -255,7 +255,10 @@ static void simple_packet_signature(struct smb_basic_signing_context *data, const size_t offset_end_of_sig = (smb_ss_field + 8); unsigned char sequence_buf[8]; struct MD5Context md5_ctx; +#if 0 + /* JRA - apparently this is incorrect. */ unsigned char key_buf[16]; +#endif /* * Firstly put the sequence number into the first 4 bytes. -- cgit From 846c4520ce102883825e3d2e1adba79a0b45a7d5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 13 Mar 2006 23:48:13 +0000 Subject: r14355: Try and fix Coverity #158 by making the pointer aliasing clearer. This isn't a bug but a code clarification. Jeremy. (This used to be commit 7ada96a1cfb1e928b7dfde101ca250b20024243f) --- source3/libsmb/smb_signing.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index f0f2024e7b..52e4b1d04c 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -426,18 +426,20 @@ We were expecting seq %u\n", reply_seq_number, saved_seq )); static void simple_free_signing_context(struct smb_sign_info *si) { struct smb_basic_signing_context *data = si->signing_context; - struct outstanding_packet_lookup *list = data->outstanding_packet_list; + struct outstanding_packet_lookup *list; + struct outstanding_packet_lookup *next; - while (list) { - struct outstanding_packet_lookup *old_head = list; - DLIST_REMOVE(list, list); - SAFE_FREE(old_head); + for (list = data->outstanding_packet_list; list; list = next) { + next = list->next; + DLIST_REMOVE(data->outstanding_packet_list, list); + SAFE_FREE(list); } data_blob_free(&data->mac_key); - if (data->trans_info) + if (data->trans_info) { SAFE_FREE(data->trans_info); + } SAFE_FREE(si->signing_context); -- cgit From 22dbd67708f1651a2341d70ce576fac360affccf Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 10 Apr 2006 15:33:04 +0000 Subject: r15018: Merge Volker's ipc/trans2/nttrans changes over into 3.0. Also merge the new POSIX lock code - this is not enabled unless -DDEVELOPER is defined. This doesn't yet map onto underlying system POSIX locks. Updates vfs to allow lock queries. Jeremy. (This used to be commit 08e52ead03304ff04229e1bfe544ff40e2564fc7) --- source3/libsmb/smb_signing.c | 234 +++---------------------------------------- 1 file changed, 16 insertions(+), 218 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 52e4b1d04c..4ff74ca464 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -28,17 +28,9 @@ struct outstanding_packet_lookup { struct outstanding_packet_lookup *prev, *next; }; -/* Store the data for an ongoing trans/trans2/nttrans operation. */ -struct trans_info_context { - uint16 mid; - uint32 send_seq_num; - uint32 reply_seq_num; -}; - struct smb_basic_signing_context { DATA_BLOB mac_key; uint32 send_seq_num; - struct trans_info_context *trans_info; struct outstanding_packet_lookup *outstanding_packet_list; }; @@ -315,7 +307,6 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) { unsigned char calc_md5_mac[16]; struct smb_basic_signing_context *data = si->signing_context; - uint32 send_seq_num; if (!si->doing_signing) return; @@ -330,12 +321,8 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) /* mark the packet as signed - BEFORE we sign it...*/ mark_packet_signed(outbuf); - if (data->trans_info) - send_seq_num = data->trans_info->send_seq_num; - else - send_seq_num = data->send_seq_num; - - simple_packet_signature(data, (const unsigned char *)outbuf, send_seq_num, calc_md5_mac); + simple_packet_signature(data, (const unsigned char *)outbuf, + data->send_seq_num, calc_md5_mac); DEBUG(10, ("client_sign_outgoing_message: sent SMB signature of\n")); dump_data(10, (const char *)calc_md5_mac, 8); @@ -345,13 +332,7 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) /* cli->outbuf[smb_ss_field+2]=0; Uncomment this to test if the remote server actually verifies signatures...*/ - if (data->trans_info) - return; - - data->send_seq_num++; - store_sequence_for_reply(&data->outstanding_packet_list, - SVAL(outbuf,smb_mid), data->send_seq_num); - data->send_seq_num++; + data->send_seq_num += 2; } /*********************************************************** @@ -362,7 +343,6 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si, { BOOL good; uint32 reply_seq_number; - uint32 saved_seq; unsigned char calc_md5_mac[16]; unsigned char *server_sent_mac; @@ -376,17 +356,9 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si, return False; } - if (data->trans_info) { - reply_seq_number = data->trans_info->reply_seq_num; - } else if (!get_sequence_for_reply(&data->outstanding_packet_list, - SVAL(inbuf, smb_mid), &reply_seq_number)) { - DEBUG(1, ("client_check_incoming_message: failed to get sequence number %u for reply.\n", - (unsigned int) SVAL(inbuf, smb_mid) )); - return False; - } - - saved_seq = reply_seq_number; - simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); + reply_seq_number = data->send_seq_num - 1; + simple_packet_signature(data, (const unsigned char *)inbuf, + reply_seq_number, calc_md5_mac); server_sent_mac = (unsigned char *)&inbuf[smb_ss_field]; good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); @@ -400,12 +372,11 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si, #if 1 /* JRATEST */ { int i; - reply_seq_number -= 5; - for (i = 0; i < 10; i++, reply_seq_number++) { - simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); + for (i = -5; i < 5; i++) { + simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number+i, calc_md5_mac); if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) { DEBUG(0,("client_check_incoming_message: out of seq. seq num %u matches. \ -We were expecting seq %u\n", reply_seq_number, saved_seq )); +We were expecting seq %u\n", reply_seq_number+i, reply_seq_number )); break; } } @@ -416,7 +387,7 @@ We were expecting seq %u\n", reply_seq_number, saved_seq )); DEBUG(10, ("client_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); dump_data(10, (const char *)server_sent_mac, 8); } - return signing_good(inbuf, si, good, saved_seq, must_be_ok); + return signing_good(inbuf, si, good, reply_seq_number, must_be_ok); } /*********************************************************** @@ -437,10 +408,6 @@ static void simple_free_signing_context(struct smb_sign_info *si) data_blob_free(&data->mac_key); - if (data->trans_info) { - SAFE_FREE(data->trans_info); - } - SAFE_FREE(si->signing_context); return; @@ -502,65 +469,6 @@ BOOL cli_simple_set_signing(struct cli_state *cli, return True; } -/*********************************************************** - Tell client code we are in a multiple trans reply state. - We call this after the last outgoing trans2 packet (which - has incremented the sequence numbers), so we must save the - current mid and sequence number -2. -************************************************************/ - -void cli_signing_trans_start(struct cli_state *cli, uint16 mid) -{ - struct smb_basic_signing_context *data = cli->sign_info.signing_context; - uint32 reply_seq_num; - - if (!cli->sign_info.doing_signing || !data) - return; - - data->trans_info = SMB_XMALLOC_P(struct trans_info_context); - ZERO_STRUCTP(data->trans_info); - - /* This ensures the sequence is pulled off the outstanding packet list */ - if (!get_sequence_for_reply(&data->outstanding_packet_list, - mid, &reply_seq_num)) { - DEBUG(1, ("get_sequence_for_reply failed - did we enter the trans signing state without sending a packet?\n")); - return; - } - - data->trans_info->send_seq_num = reply_seq_num - 1; - data->trans_info->mid = mid; - data->trans_info->reply_seq_num = reply_seq_num; - - DEBUG(10,("cli_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \ -data->send_seq_num = %u\n", - (unsigned int)data->trans_info->mid, - (unsigned int)data->trans_info->reply_seq_num, - (unsigned int)data->trans_info->send_seq_num, - (unsigned int)data->send_seq_num )); -} - -/*********************************************************** - Tell client code we are out of a multiple trans reply state. -************************************************************/ - -void cli_signing_trans_stop(struct cli_state *cli) -{ - struct smb_basic_signing_context *data = cli->sign_info.signing_context; - - if (!cli->sign_info.doing_signing || !data) - return; - - DEBUG(10,("cli_signing_trans_stop: freeing mid = %u, reply_seq_num = %u, send_seq_num = %u \ -data->send_seq_num = %u\n", - (unsigned int)data->trans_info->mid, - (unsigned int)data->trans_info->reply_seq_num, - (unsigned int)data->trans_info->send_seq_num, - (unsigned int)data->send_seq_num )); - - SAFE_FREE(data->trans_info); - data->trans_info = NULL; -} - /*********************************************************** SMB signing - TEMP implementation - calculate a MAC to send. ************************************************************/ @@ -659,8 +567,7 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) { unsigned char calc_md5_mac[16]; struct smb_basic_signing_context *data = si->signing_context; - uint32 send_seq_number = data->send_seq_num; - BOOL was_deferred_packet = False; + uint32 send_seq_number = data->send_seq_num-1; uint16 mid; if (!si->doing_signing) { @@ -680,13 +587,7 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) mid = SVAL(outbuf, smb_mid); /* See if this is a reply for a deferred packet. */ - was_deferred_packet = get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number); - - if (data->trans_info && (data->trans_info->mid == mid)) { - /* This is a reply in a trans stream. Use the sequence - * number associated with the stream mid. */ - send_seq_number = data->trans_info->send_seq_num; - } + get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number); simple_packet_signature(data, (const unsigned char *)outbuf, send_seq_number, calc_md5_mac); @@ -697,36 +598,6 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) /* cli->outbuf[smb_ss_field+2]=0; Uncomment this to test if the remote client actually verifies signatures...*/ - - /* Don't mess with the sequence number for a deferred packet. */ - if (was_deferred_packet) { - return; - } - - if (!data->trans_info) { - /* Always increment if not in a trans stream. */ - data->send_seq_num++; - } else if ((data->trans_info->send_seq_num == data->send_seq_num) || (data->trans_info->mid != mid)) { - /* Increment if this is the first reply in a trans stream or a - * packet that doesn't belong to this stream (different mid). */ - data->send_seq_num++; - } -} - -/*********************************************************** - Is an incoming packet an oplock break reply ? -************************************************************/ - -static BOOL is_oplock_break(char *inbuf) -{ - if (CVAL(inbuf,smb_com) != SMBlockingX) - return False; - - if (!(CVAL(inbuf,smb_vwv3) & LOCKING_ANDX_OPLOCK_RELEASE)) - return False; - - DEBUG(10,("is_oplock_break: Packet is oplock break\n")); - return True; } /*********************************************************** @@ -753,23 +624,8 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si, BO mid = SVAL(inbuf, smb_mid); - /* Is this part of a trans stream ? */ - if (data->trans_info && (data->trans_info->mid == mid)) { - /* If so we don't increment the sequence. */ - reply_seq_number = data->trans_info->reply_seq_num; - } else { - /* We always increment the sequence number. */ - data->send_seq_num++; - - /* If we get an asynchronous oplock break reply and there - * isn't a reply pending we need to re-sync the sequence - * number. - */ - if (is_oplock_break(inbuf)) { - DEBUG(10,("srv_check_incoming_message: oplock break at seq num %u\n", data->send_seq_num)); - data->send_seq_num++; - } - } + /* We always increment the sequence number. */ + data->send_seq_num += 2; saved_seq = reply_seq_number; simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); @@ -885,9 +741,8 @@ void srv_defer_sign_response(uint16 mid) * Ensure we only store this mid reply once... */ - if (store_sequence_for_reply(&data->outstanding_packet_list, mid, data->send_seq_num)) { - data->send_seq_num++; - } + store_sequence_for_reply(&data->outstanding_packet_list, mid, + data->send_seq_num-1); } /*********************************************************** @@ -974,63 +829,6 @@ BOOL srv_signing_started(void) return True; } - -/*********************************************************** - Tell server code we are in a multiple trans reply state. -************************************************************/ - -void srv_signing_trans_start(uint16 mid) -{ - struct smb_basic_signing_context *data; - - if (!srv_sign_info.doing_signing) - return; - - data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; - if (!data) - return; - - data->trans_info = SMB_XMALLOC_P(struct trans_info_context); - ZERO_STRUCTP(data->trans_info); - - data->trans_info->reply_seq_num = data->send_seq_num-1; - data->trans_info->mid = mid; - data->trans_info->send_seq_num = data->send_seq_num; - - DEBUG(10,("srv_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \ -data->send_seq_num = %u\n", - (unsigned int)mid, - (unsigned int)data->trans_info->reply_seq_num, - (unsigned int)data->trans_info->send_seq_num, - (unsigned int)data->send_seq_num )); -} - -/*********************************************************** - Tell server code we are out of a multiple trans reply state. -************************************************************/ - -void srv_signing_trans_stop(void) -{ - struct smb_basic_signing_context *data; - - if (!srv_sign_info.doing_signing) - return; - - data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; - if (!data || !data->trans_info) - return; - - DEBUG(10,("srv_signing_trans_stop: removing mid = %u, reply_seq_num = %u, send_seq_num = %u \ -data->send_seq_num = %u\n", - (unsigned int)data->trans_info->mid, - (unsigned int)data->trans_info->reply_seq_num, - (unsigned int)data->trans_info->send_seq_num, - (unsigned int)data->send_seq_num )); - - SAFE_FREE(data->trans_info); - data->trans_info = NULL; -} - /*********************************************************** Turn on signing from this packet onwards. ************************************************************/ -- cgit From 9e13d35092a9b2caee3448bd9f11c1b82dd9d6d2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 28 Jun 2006 17:58:47 +0000 Subject: r16630: Fix bug #3881, reported by jason@ncac.gwu.edu. Jeremy. (This used to be commit ec0a47b94c12b64d351ca8e6bdd467578528f3da) --- source3/libsmb/smb_signing.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 4ff74ca464..d68f161e23 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -612,7 +612,6 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si, BO uint32 saved_seq; unsigned char calc_md5_mac[16]; unsigned char *server_sent_mac; - uint mid; if (!si->doing_signing) return True; @@ -622,8 +621,6 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si, BO return False; } - mid = SVAL(inbuf, smb_mid); - /* We always increment the sequence number. */ data->send_seq_num += 2; -- cgit From d0b0ed90ebc0ed5d4b8c07c8362753df34a00ef9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 29 Jun 2006 21:30:58 +0000 Subject: r16696: Fix the multiple-outstanding write and trans client signing bug. Jeremy. (This used to be commit 3b7fbe856cea7cbb5bf91844f94f221be0a2c627) --- source3/libsmb/smb_signing.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index d68f161e23..68c259ba03 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -332,7 +332,22 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) /* cli->outbuf[smb_ss_field+2]=0; Uncomment this to test if the remote server actually verifies signatures...*/ - data->send_seq_num += 2; + /* Instead of re-introducing the trans_info_conect we + used to have here, we use the fact that during a + SMBtrans/SMBtrans2/SMBnttrans send that the mid stays + constant. This means that calling store_sequence_for_reply() + will return False for all trans secondaries, as the mid is already + on the stored sequence list. As the send_seqence_number must + remain constant for all primary+secondary trans sends, we + only increment the send sequence number when we successfully + add a new entry to the outstanding sequence list. This means + I can isolate the fix here rather than re-adding the trans + signing on/off calls in libsmb/clitrans2.c JRA. + */ + + if (store_sequence_for_reply(&data->outstanding_packet_list, SVAL(outbuf,smb_mid), data->send_seq_num + 1)) { + data->send_seq_num += 2; + } } /*********************************************************** @@ -356,7 +371,12 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si, return False; } - reply_seq_number = data->send_seq_num - 1; + if (!get_sequence_for_reply(&data->outstanding_packet_list, SVAL(inbuf, smb_mid), &reply_seq_number)) { + DEBUG(1, ("client_check_incoming_message: received message " + "with mid %u with no matching send record.\n", (unsigned int)SVAL(inbuf, smb_mid) )); + return False; + } + simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); -- cgit From 321b0a3a63b40f779c71d476fdc5a840d2ced665 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 28 Jul 2006 21:23:53 +0000 Subject: r17292: Try and fix bug #3967 - signing problems on trans calls introduced by signing code simplification. Please test if you've seen signing problems with 3.0.23a. Jeremy. (This used to be commit f462daf02c12cfba634f92e681eb23a09e7d0acf) --- source3/libsmb/smb_signing.c | 69 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 68c259ba03..fd5d8bf06f 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -23,9 +23,10 @@ /* Lookup a packet's MID (multiplex id) and figure out it's sequence number */ struct outstanding_packet_lookup { + struct outstanding_packet_lookup *prev, *next; uint16 mid; uint32 reply_seq_num; - struct outstanding_packet_lookup *prev, *next; + BOOL can_delete; /* Set to False in trans state. */ }; struct smb_basic_signing_context { @@ -51,6 +52,7 @@ static BOOL store_sequence_for_reply(struct outstanding_packet_lookup **list, t->mid = mid; t->reply_seq_num = reply_seq_num; + t->can_delete = True; /* * Add to the *start* of the list not the end of the list. @@ -77,8 +79,23 @@ static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, *reply_seq_num = t->reply_seq_num; DEBUG(10,("get_sequence_for_reply: found seq = %u mid = %u\n", (unsigned int)t->reply_seq_num, (unsigned int)t->mid )); - DLIST_REMOVE(*list, t); - SAFE_FREE(t); + if (t->can_delete) { + DLIST_REMOVE(*list, t); + SAFE_FREE(t); + } + return True; + } + } + return False; +} + +static BOOL set_sequence_can_delete_flag(struct outstanding_packet_lookup **list, uint16 mid, BOOL can_delete_entry) +{ + struct outstanding_packet_lookup *t; + + for (t = *list; t; t = t->next) { + if (t->mid == mid) { + t->can_delete = can_delete_entry; return True; } } @@ -579,6 +596,52 @@ BOOL cli_check_sign_mac(struct cli_state *cli) return True; } +/*********************************************************** + Enter trans/trans2/nttrans state. +************************************************************/ + +BOOL client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid) +{ + struct smb_sign_info *si = &cli->sign_info; + struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; + + if (!si->doing_signing) { + return True; + } + + if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, False)) { + return False; + } + + return True; +} + +/*********************************************************** + Leave trans/trans2/nttrans state. +************************************************************/ + +BOOL client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid) +{ + uint32 reply_seq_num; + struct smb_sign_info *si = &cli->sign_info; + struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; + + if (!si->doing_signing) { + return True; + } + + if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, True)) { + return False; + } + + /* Now delete the stored mid entry. */ + if (!get_sequence_for_reply(&data->outstanding_packet_list, mid, &reply_seq_num)) { + return False; + } + + return True; +} + /*********************************************************** SMB signing - Server implementation - send the MAC. ************************************************************/ -- cgit From 02eea79624c85fb5ce6c3ffefe2d27e40c5ff97f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 31 Jul 2006 03:53:39 +0000 Subject: r17333: Some C++ warnings (This used to be commit be9aaffdaccae06c8c035eaf31862e34b7cfbe38) --- source3/libsmb/smb_signing.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index fd5d8bf06f..e000d539b4 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -323,7 +323,8 @@ static void simple_packet_signature(struct smb_basic_signing_context *data, static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) { unsigned char calc_md5_mac[16]; - struct smb_basic_signing_context *data = si->signing_context; + struct smb_basic_signing_context *data = + (struct smb_basic_signing_context *)si->signing_context; if (!si->doing_signing) return; @@ -378,7 +379,8 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si, unsigned char calc_md5_mac[16]; unsigned char *server_sent_mac; - struct smb_basic_signing_context *data = si->signing_context; + struct smb_basic_signing_context *data = + (struct smb_basic_signing_context *)si->signing_context; if (!si->doing_signing) return True; @@ -433,7 +435,8 @@ We were expecting seq %u\n", reply_seq_number+i, reply_seq_number )); static void simple_free_signing_context(struct smb_sign_info *si) { - struct smb_basic_signing_context *data = si->signing_context; + struct smb_basic_signing_context *data = + (struct smb_basic_signing_context *)si->signing_context; struct outstanding_packet_lookup *list; struct outstanding_packet_lookup *next; @@ -649,7 +652,8 @@ BOOL client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid) static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) { unsigned char calc_md5_mac[16]; - struct smb_basic_signing_context *data = si->signing_context; + struct smb_basic_signing_context *data = + (struct smb_basic_signing_context *)si->signing_context; uint32 send_seq_number = data->send_seq_num-1; uint16 mid; @@ -690,7 +694,8 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL must_be_ok) { BOOL good; - struct smb_basic_signing_context *data = si->signing_context; + struct smb_basic_signing_context *data = + (struct smb_basic_signing_context *)si->signing_context; uint32 reply_seq_number = data->send_seq_num; uint32 saved_seq; unsigned char calc_md5_mac[16]; -- cgit From a8627a857630033cca700916d90456c837726ff4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 5 Aug 2006 20:05:37 +0000 Subject: r17431: Fix bug #4003, reported by dale-keyword-samba.c7b741@codefu.org. NTcancel doesn't send a reply, so in this case the signing sequence number is only incremented by 1, not 2. Jeremy. (This used to be commit 85841a01987e653a085af00c7c437145686a332b) --- source3/libsmb/smb_signing.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index e000d539b4..e277137e9b 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -852,6 +852,9 @@ void srv_cancel_sign_response(uint16 mid) while (get_sequence_for_reply(&data->outstanding_packet_list, mid, &dummy_seq)) ; + + /* cancel doesn't send a reply so doesn't burn a sequence number. */ + data->send_seq_num -= 1; } /*********************************************************** -- cgit From b4f39f4a9ed432d7bd687527b36d5ec93397d2b2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 17 Aug 2006 19:49:54 +0000 Subject: r17595: Fix from Ben Winslow to allow client smb signing to be correctly turned off. Jeremy. (This used to be commit 61f052b0a67b8a05b5d925bf8bbad73369ac03bd) --- source3/libsmb/smb_signing.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index e277137e9b..a2df0cc38a 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -108,6 +108,10 @@ static BOOL set_sequence_can_delete_flag(struct outstanding_packet_lookup **list static BOOL cli_set_smb_signing_common(struct cli_state *cli) { + if (!cli->sign_info.allow_smb_signing) { + return False; + } + if (!cli->sign_info.negotiated_smb_signing && !cli->sign_info.mandatory_signing) { return False; -- cgit From 58406b0d1c1d2d95e559d188450af79d44a1f2f3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 11 Nov 2006 00:23:44 +0000 Subject: r19659: Fix bug #4187. Possible crash in signing on/off code. Jeremy. (This used to be commit 78c1c43523d787825bdb6d52e128bf0af5eccaae) --- source3/libsmb/smb_signing.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index a2df0cc38a..df74b2db36 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -616,6 +616,10 @@ BOOL client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid) return True; } + if (!data) { + return False; + } + if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, False)) { return False; } @@ -637,6 +641,10 @@ BOOL client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid) return True; } + if (!data) { + return False; + } + if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, True)) { return False; } -- cgit From 071db6fdbff694681fa1793ee678a9a0af3e266a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 21 Mar 2007 00:25:08 +0000 Subject: r21897: Add in a basic raw NTLM encrypt request. Now for testing. Jeremy. (This used to be commit 783a7b3085a155d9652cd725bf2960cd272cb554) --- source3/libsmb/smb_signing.c | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index df74b2db36..66a15e9408 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -585,7 +585,9 @@ void cli_free_signing_context(struct cli_state *cli) void cli_calculate_sign_mac(struct cli_state *cli) { - cli->sign_info.sign_outgoing_message(cli->outbuf, &cli->sign_info); + if (!cli_encryption_on(cli)) { + cli->sign_info.sign_outgoing_message(cli->outbuf, &cli->sign_info); + } } /** @@ -596,6 +598,9 @@ void cli_calculate_sign_mac(struct cli_state *cli) BOOL cli_check_sign_mac(struct cli_state *cli) { + if (cli_encryption_on(cli)) { + return True; + } if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info, True)) { free_signing_context(&cli->sign_info); return False; @@ -612,6 +617,9 @@ BOOL client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid) struct smb_sign_info *si = &cli->sign_info; struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; + if (cli_encryption_on(cli)) { + return True; + } if (!si->doing_signing) { return True; } @@ -637,6 +645,9 @@ BOOL client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid) struct smb_sign_info *si = &cli->sign_info; struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; + if (cli_encryption_on(cli)) { + return True; + } if (!si->doing_signing) { return True; } @@ -798,8 +809,18 @@ BOOL srv_oplock_set_signing(BOOL onoff) BOOL srv_check_sign_mac(char *inbuf, BOOL must_be_ok) { /* Check if it's a session keepalive. */ - if(CVAL(inbuf,0) == SMBkeepalive) + if(CVAL(inbuf,0) == SMBkeepalive) { return True; + } + + /* + * If we have an encrypted transport + * don't sign - we're already doing that. + */ + + if (srv_encryption_on()) { + return True; + } return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info, must_be_ok); } @@ -811,9 +832,18 @@ BOOL srv_check_sign_mac(char *inbuf, BOOL must_be_ok) void srv_calculate_sign_mac(char *outbuf) { /* Check if it's a session keepalive. */ - /* JRA Paranioa test - do we ever generate these in the server ? */ - if(CVAL(outbuf,0) == SMBkeepalive) + if(CVAL(outbuf,0) == SMBkeepalive) { return; + } + + /* + * If we have an encrypted transport + * don't check sign - we're already doing that. + */ + + if (srv_encryption_on()) { + return; + } srv_sign_info.sign_outgoing_message(outbuf, &srv_sign_info); } -- cgit From 8c395be5e514a28f13608a462c0c0e8417e21160 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 21 Mar 2007 23:49:57 +0000 Subject: r21922: Fixed the build by rather horrid means. I really need to restructure libsmb/smb_signing.c so it isn't in the base libs path but lives in libsmb instead (like smb_seal.c does). Jeremy. (This used to be commit 1b828f051d0782201f697de15ff973bd6b097d5b) --- source3/libsmb/smb_signing.c | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 66a15e9408..0395208986 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -585,9 +585,7 @@ void cli_free_signing_context(struct cli_state *cli) void cli_calculate_sign_mac(struct cli_state *cli) { - if (!cli_encryption_on(cli)) { - cli->sign_info.sign_outgoing_message(cli->outbuf, &cli->sign_info); - } + cli->sign_info.sign_outgoing_message(cli->outbuf, &cli->sign_info); } /** @@ -598,9 +596,6 @@ void cli_calculate_sign_mac(struct cli_state *cli) BOOL cli_check_sign_mac(struct cli_state *cli) { - if (cli_encryption_on(cli)) { - return True; - } if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info, True)) { free_signing_context(&cli->sign_info); return False; @@ -617,9 +612,6 @@ BOOL client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid) struct smb_sign_info *si = &cli->sign_info; struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; - if (cli_encryption_on(cli)) { - return True; - } if (!si->doing_signing) { return True; } @@ -645,9 +637,6 @@ BOOL client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid) struct smb_sign_info *si = &cli->sign_info; struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; - if (cli_encryption_on(cli)) { - return True; - } if (!si->doing_signing) { return True; } @@ -813,15 +802,6 @@ BOOL srv_check_sign_mac(char *inbuf, BOOL must_be_ok) return True; } - /* - * If we have an encrypted transport - * don't sign - we're already doing that. - */ - - if (srv_encryption_on()) { - return True; - } - return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info, must_be_ok); } @@ -836,15 +816,6 @@ void srv_calculate_sign_mac(char *outbuf) return; } - /* - * If we have an encrypted transport - * don't check sign - we're already doing that. - */ - - if (srv_encryption_on()) { - return; - } - srv_sign_info.sign_outgoing_message(outbuf, &srv_sign_info); } -- cgit From 56ba44766854ed7cda265bdaf85913f2a1008282 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 28 Mar 2007 13:34:59 +0000 Subject: r22001: change prototype of dump_data(), so that it takes unsigned char * now, which matches what samba4 has. also fix all the callers to prevent compiler warnings metze (This used to be commit fa322f0cc9c26a9537ba3f0a7d4e4a25941317e7) --- source3/libsmb/smb_signing.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 0395208986..d3384ce365 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -347,7 +347,7 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) data->send_seq_num, calc_md5_mac); DEBUG(10, ("client_sign_outgoing_message: sent SMB signature of\n")); - dump_data(10, (const char *)calc_md5_mac, 8); + dump_data(10, calc_md5_mac, 8); memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); @@ -408,10 +408,10 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si, if (!good) { DEBUG(5, ("client_check_incoming_message: BAD SIG: wanted SMB signature of\n")); - dump_data(5, (const char *)calc_md5_mac, 8); + dump_data(5, calc_md5_mac, 8); DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n")); - dump_data(5, (const char *)server_sent_mac, 8); + dump_data(5, server_sent_mac, 8); #if 1 /* JRATEST */ { int i; @@ -428,7 +428,7 @@ We were expecting seq %u\n", reply_seq_number+i, reply_seq_number )); } else { DEBUG(10, ("client_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); - dump_data(10, (const char *)server_sent_mac, 8); + dump_data(10, server_sent_mac, 8); } return signing_good(inbuf, si, good, reply_seq_number, must_be_ok); } @@ -488,12 +488,12 @@ BOOL cli_simple_set_signing(struct cli_state *cli, memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length); DEBUG(10, ("cli_simple_set_signing: user_session_key\n")); - dump_data(10, (const char *)user_session_key.data, user_session_key.length); + dump_data(10, user_session_key.data, user_session_key.length); if (response.length) { memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length); DEBUG(10, ("cli_simple_set_signing: response_data\n")); - dump_data(10, (const char *)response.data, response.length); + dump_data(10, response.data, response.length); } else { DEBUG(10, ("cli_simple_set_signing: NULL response_data\n")); } @@ -691,7 +691,7 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) simple_packet_signature(data, (const unsigned char *)outbuf, send_seq_number, calc_md5_mac); DEBUG(10, ("srv_sign_outgoing_message: seq %u: sent SMB signature of\n", (unsigned int)send_seq_number)); - dump_data(10, (const char *)calc_md5_mac, 8); + dump_data(10, calc_md5_mac, 8); memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); @@ -735,11 +735,11 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si, BO if (saved_seq) { DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n", (unsigned int)saved_seq)); - dump_data(5, (const char *)calc_md5_mac, 8); + dump_data(5, calc_md5_mac, 8); DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n", (unsigned int)reply_seq_number)); - dump_data(5, (const char *)server_sent_mac, 8); + dump_data(5, server_sent_mac, 8); } #if 1 /* JRATEST */ @@ -759,7 +759,7 @@ We were expecting seq %u\n", reply_seq_number, saved_seq )); } else { DEBUG(10, ("srv_check_incoming_message: seq %u: (current is %u) got good SMB signature of\n", (unsigned int)reply_seq_number, (unsigned int)data->send_seq_num)); - dump_data(10, (const char *)server_sent_mac, 8); + dump_data(10, server_sent_mac, 8); } return (signing_good(inbuf, si, good, saved_seq, must_be_ok)); -- cgit From 32106b23951e01fb17f814584ebbcc8d7288cb75 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 May 2007 00:07:38 +0000 Subject: r22920: Add in the UNIX capability for 24-bit readX, as discussed with the Apple guys and Linux kernel guys. Still looking at how to do writeX as there's no recvfile(). Jeremy. (This used to be commit a53268fb2082de586e2df250d8ddfcff53379102) --- source3/libsmb/smb_signing.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index d3384ce365..30f41476e3 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -657,6 +657,16 @@ BOOL client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid) return True; } +/*********************************************************** + Is client signing on ? +************************************************************/ + +BOOL client_is_signing_on(struct cli_state *cli) +{ + struct smb_sign_info *si = &cli->sign_info; + return si->doing_signing; +} + /*********************************************************** SMB signing - Server implementation - send the MAC. ************************************************************/ -- cgit From d824b98f80ba186030cbb70b3a1e5daf80469ecd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Jul 2007 19:25:36 +0000 Subject: r23779: Change from v2 or later to v3 or later. Jeremy. (This used to be commit 407e6e695b8366369b7c76af1ff76869b45347b3) --- source3/libsmb/smb_signing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 30f41476e3..039edecf72 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -6,7 +6,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, -- cgit From 5e54558c6dea67b56bbfaba5698f3a434d3dffb6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 00:52:41 +0000 Subject: r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text (This used to be commit b0132e94fc5fef936aa766fb99a306b3628e9f07) --- source3/libsmb/smb_signing.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 039edecf72..3964bfa534 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -15,8 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" -- cgit From 25a3427ef16f261cbfcf65abc367f55165676aaa Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 21 Jul 2007 21:56:33 +0000 Subject: r23986: Some const (This used to be commit dc6f4bdb7f5fc0fd4cd9f687c47af3719985da8b) --- source3/libsmb/smb_signing.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 3964bfa534..d893af54f8 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -170,7 +170,9 @@ static void null_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) SMB signing - NULL implementation - check a MAC sent by server. ************************************************************/ -static BOOL null_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL must_be_ok) +static BOOL null_check_incoming_message(const char *inbuf, + struct smb_sign_info *si, + BOOL must_be_ok) { return True; } @@ -217,7 +219,8 @@ static void free_signing_context(struct smb_sign_info *si) } -static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good, uint32 seq, BOOL must_be_ok) +static BOOL signing_good(const char *inbuf, struct smb_sign_info *si, + BOOL good, uint32 seq, BOOL must_be_ok) { if (good) { @@ -375,7 +378,9 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) SMB signing - Client implementation - check a MAC sent by server. ************************************************************/ -static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL must_be_ok) +static BOOL client_check_incoming_message(const char *inbuf, + struct smb_sign_info *si, + BOOL must_be_ok) { BOOL good; uint32 reply_seq_number; @@ -531,7 +536,8 @@ static void temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) SMB signing - TEMP implementation - check a MAC sent by server. ************************************************************/ -static BOOL temp_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL foo) +static BOOL temp_check_incoming_message(const char *inbuf, + struct smb_sign_info *si, BOOL foo) { return True; } @@ -712,7 +718,9 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) SMB signing - Server implementation - check a MAC sent by server. ************************************************************/ -static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL must_be_ok) +static BOOL srv_check_incoming_message(const char *inbuf, + struct smb_sign_info *si, + BOOL must_be_ok) { BOOL good; struct smb_basic_signing_context *data = -- cgit From ece86db24cd82b086de69e9681de4fb1f391cc2e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Jul 2007 13:51:39 +0000 Subject: r23991: Some const (This used to be commit 804be77e4695eb923048948dbc6e223967fdef94) --- source3/libsmb/smb_signing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index d893af54f8..c5b1d44586 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -812,7 +812,7 @@ BOOL srv_oplock_set_signing(BOOL onoff) Called to validate an incoming packet from the client. ************************************************************/ -BOOL srv_check_sign_mac(char *inbuf, BOOL must_be_ok) +BOOL srv_check_sign_mac(const char *inbuf, BOOL must_be_ok) { /* Check if it's a session keepalive. */ if(CVAL(inbuf,0) == SMBkeepalive) { -- cgit From 30191d1a5704ad2b158386b511558972d539ce47 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2007 17:40:25 -0700 Subject: RIP BOOL. Convert BOOL -> bool. I found a few interesting bugs in various places whilst doing this (places that assumed BOOL == int). I also need to fix the Samba4 pidl generation (next checkin). Jeremy. (This used to be commit f35a266b3cbb3e5fa6a86be60f34fe340a3ca71f) --- source3/libsmb/smb_signing.c | 64 ++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 32 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index c5b1d44586..1e150525ba 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -25,7 +25,7 @@ struct outstanding_packet_lookup { struct outstanding_packet_lookup *prev, *next; uint16 mid; uint32 reply_seq_num; - BOOL can_delete; /* Set to False in trans state. */ + bool can_delete; /* Set to False in trans state. */ }; struct smb_basic_signing_context { @@ -34,7 +34,7 @@ struct smb_basic_signing_context { struct outstanding_packet_lookup *outstanding_packet_list; }; -static BOOL store_sequence_for_reply(struct outstanding_packet_lookup **list, +static bool store_sequence_for_reply(struct outstanding_packet_lookup **list, uint16 mid, uint32 reply_seq_num) { struct outstanding_packet_lookup *t; @@ -68,7 +68,7 @@ static BOOL store_sequence_for_reply(struct outstanding_packet_lookup **list, return True; } -static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, +static bool get_sequence_for_reply(struct outstanding_packet_lookup **list, uint16 mid, uint32 *reply_seq_num) { struct outstanding_packet_lookup *t; @@ -88,7 +88,7 @@ static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, return False; } -static BOOL set_sequence_can_delete_flag(struct outstanding_packet_lookup **list, uint16 mid, BOOL can_delete_entry) +static bool set_sequence_can_delete_flag(struct outstanding_packet_lookup **list, uint16 mid, bool can_delete_entry) { struct outstanding_packet_lookup *t; @@ -105,7 +105,7 @@ static BOOL set_sequence_can_delete_flag(struct outstanding_packet_lookup **list SMB signing - Common code before we set a new signing implementation ************************************************************/ -static BOOL cli_set_smb_signing_common(struct cli_state *cli) +static bool cli_set_smb_signing_common(struct cli_state *cli) { if (!cli->sign_info.allow_smb_signing) { return False; @@ -134,7 +134,7 @@ static BOOL cli_set_smb_signing_common(struct cli_state *cli) SMB signing - Common code for 'real' implementations ************************************************************/ -static BOOL set_smb_signing_real_common(struct smb_sign_info *si) +static bool set_smb_signing_real_common(struct smb_sign_info *si) { if (si->mandatory_signing) { DEBUG(5, ("Mandatory SMB signing enabled!\n")); @@ -170,9 +170,9 @@ static void null_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) SMB signing - NULL implementation - check a MAC sent by server. ************************************************************/ -static BOOL null_check_incoming_message(const char *inbuf, +static bool null_check_incoming_message(const char *inbuf, struct smb_sign_info *si, - BOOL must_be_ok) + bool must_be_ok) { return True; } @@ -193,7 +193,7 @@ static void null_free_signing_context(struct smb_sign_info *si) shut down a real signing mechanism */ -static BOOL null_set_signing(struct smb_sign_info *si) +static bool null_set_signing(struct smb_sign_info *si) { si->signing_context = NULL; @@ -219,8 +219,8 @@ static void free_signing_context(struct smb_sign_info *si) } -static BOOL signing_good(const char *inbuf, struct smb_sign_info *si, - BOOL good, uint32 seq, BOOL must_be_ok) +static bool signing_good(const char *inbuf, struct smb_sign_info *si, + bool good, uint32 seq, bool must_be_ok) { if (good) { @@ -378,11 +378,11 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) SMB signing - Client implementation - check a MAC sent by server. ************************************************************/ -static BOOL client_check_incoming_message(const char *inbuf, +static bool client_check_incoming_message(const char *inbuf, struct smb_sign_info *si, - BOOL must_be_ok) + bool must_be_ok) { - BOOL good; + bool good; uint32 reply_seq_number; unsigned char calc_md5_mac[16]; unsigned char *server_sent_mac; @@ -465,7 +465,7 @@ static void simple_free_signing_context(struct smb_sign_info *si) SMB signing - Simple implementation - setup the MAC key. ************************************************************/ -BOOL cli_simple_set_signing(struct cli_state *cli, +bool cli_simple_set_signing(struct cli_state *cli, const DATA_BLOB user_session_key, const DATA_BLOB response) { @@ -536,8 +536,8 @@ static void temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) SMB signing - TEMP implementation - check a MAC sent by server. ************************************************************/ -static BOOL temp_check_incoming_message(const char *inbuf, - struct smb_sign_info *si, BOOL foo) +static bool temp_check_incoming_message(const char *inbuf, + struct smb_sign_info *si, bool foo) { return True; } @@ -555,7 +555,7 @@ static void temp_free_signing_context(struct smb_sign_info *si) SMB signing - NULL implementation - setup the MAC key. ************************************************************/ -BOOL cli_null_set_signing(struct cli_state *cli) +bool cli_null_set_signing(struct cli_state *cli) { return null_set_signing(&cli->sign_info); } @@ -564,7 +564,7 @@ BOOL cli_null_set_signing(struct cli_state *cli) SMB signing - temp implementation - setup the MAC key. ************************************************************/ -BOOL cli_temp_set_signing(struct cli_state *cli) +bool cli_temp_set_signing(struct cli_state *cli) { if (!cli_set_smb_signing_common(cli)) { return False; @@ -599,7 +599,7 @@ void cli_calculate_sign_mac(struct cli_state *cli) * which had a bad checksum, True otherwise. */ -BOOL cli_check_sign_mac(struct cli_state *cli) +bool cli_check_sign_mac(struct cli_state *cli) { if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info, True)) { free_signing_context(&cli->sign_info); @@ -612,7 +612,7 @@ BOOL cli_check_sign_mac(struct cli_state *cli) Enter trans/trans2/nttrans state. ************************************************************/ -BOOL client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid) +bool client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid) { struct smb_sign_info *si = &cli->sign_info; struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; @@ -636,7 +636,7 @@ BOOL client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid) Leave trans/trans2/nttrans state. ************************************************************/ -BOOL client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid) +bool client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid) { uint32 reply_seq_num; struct smb_sign_info *si = &cli->sign_info; @@ -666,7 +666,7 @@ BOOL client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid) Is client signing on ? ************************************************************/ -BOOL client_is_signing_on(struct cli_state *cli) +bool client_is_signing_on(struct cli_state *cli) { struct smb_sign_info *si = &cli->sign_info; return si->doing_signing; @@ -718,11 +718,11 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) SMB signing - Server implementation - check a MAC sent by server. ************************************************************/ -static BOOL srv_check_incoming_message(const char *inbuf, +static bool srv_check_incoming_message(const char *inbuf, struct smb_sign_info *si, - BOOL must_be_ok) + bool must_be_ok) { - BOOL good; + bool good; struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; uint32 reply_seq_number = data->send_seq_num; @@ -801,9 +801,9 @@ static struct smb_sign_info srv_sign_info = { Turn signing off or on for oplock break code. ************************************************************/ -BOOL srv_oplock_set_signing(BOOL onoff) +bool srv_oplock_set_signing(bool onoff) { - BOOL ret = srv_sign_info.doing_signing; + bool ret = srv_sign_info.doing_signing; srv_sign_info.doing_signing = onoff; return ret; } @@ -812,7 +812,7 @@ BOOL srv_oplock_set_signing(BOOL onoff) Called to validate an incoming packet from the client. ************************************************************/ -BOOL srv_check_sign_mac(const char *inbuf, BOOL must_be_ok) +bool srv_check_sign_mac(const char *inbuf, bool must_be_ok) { /* Check if it's a session keepalive. */ if(CVAL(inbuf,0) == SMBkeepalive) { @@ -908,7 +908,7 @@ void srv_set_signing_negotiated(void) reads/writes if it is. ************************************************************/ -BOOL srv_is_signing_active(void) +bool srv_is_signing_active(void) { return srv_sign_info.doing_signing; } @@ -919,7 +919,7 @@ BOOL srv_is_signing_active(void) in the negprot. ************************************************************/ -BOOL srv_is_signing_negotiated(void) +bool srv_is_signing_negotiated(void) { return srv_sign_info.negotiated_smb_signing; } @@ -928,7 +928,7 @@ BOOL srv_is_signing_negotiated(void) Returns whether signing is actually happening ************************************************************/ -BOOL srv_signing_started(void) +bool srv_signing_started(void) { struct smb_basic_signing_context *data; -- cgit From 774a30989af4879cc6c3f5a270a20a645983edfa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 4 Dec 2007 13:30:22 -0800 Subject: Fix signing bug found by Volker. That one was *subtle*. Jeremy (This used to be commit 816aea6c1a426eb2450061b847729e22bdac33a0) --- source3/libsmb/smb_signing.c | 79 +++----------------------------------------- 1 file changed, 5 insertions(+), 74 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 1e150525ba..d5cbe3b125 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -25,7 +25,6 @@ struct outstanding_packet_lookup { struct outstanding_packet_lookup *prev, *next; uint16 mid; uint32 reply_seq_num; - bool can_delete; /* Set to False in trans state. */ }; struct smb_basic_signing_context { @@ -42,7 +41,9 @@ static bool store_sequence_for_reply(struct outstanding_packet_lookup **list, /* Ensure we only add a mid once. */ for (t = *list; t; t = t->next) { if (t->mid == mid) { - return False; + DLIST_REMOVE(*list, t); + SAFE_FREE(t); + break; } } @@ -51,7 +52,6 @@ static bool store_sequence_for_reply(struct outstanding_packet_lookup **list, t->mid = mid; t->reply_seq_num = reply_seq_num; - t->can_delete = True; /* * Add to the *start* of the list not the end of the list. @@ -78,23 +78,8 @@ static bool get_sequence_for_reply(struct outstanding_packet_lookup **list, *reply_seq_num = t->reply_seq_num; DEBUG(10,("get_sequence_for_reply: found seq = %u mid = %u\n", (unsigned int)t->reply_seq_num, (unsigned int)t->mid )); - if (t->can_delete) { - DLIST_REMOVE(*list, t); - SAFE_FREE(t); - } - return True; - } - } - return False; -} - -static bool set_sequence_can_delete_flag(struct outstanding_packet_lookup **list, uint16 mid, bool can_delete_entry) -{ - struct outstanding_packet_lookup *t; - - for (t = *list; t; t = t->next) { - if (t->mid == mid) { - t->can_delete = can_delete_entry; + DLIST_REMOVE(*list, t); + SAFE_FREE(t); return True; } } @@ -608,60 +593,6 @@ bool cli_check_sign_mac(struct cli_state *cli) return True; } -/*********************************************************** - Enter trans/trans2/nttrans state. -************************************************************/ - -bool client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid) -{ - struct smb_sign_info *si = &cli->sign_info; - struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; - - if (!si->doing_signing) { - return True; - } - - if (!data) { - return False; - } - - if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, False)) { - return False; - } - - return True; -} - -/*********************************************************** - Leave trans/trans2/nttrans state. -************************************************************/ - -bool client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid) -{ - uint32 reply_seq_num; - struct smb_sign_info *si = &cli->sign_info; - struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; - - if (!si->doing_signing) { - return True; - } - - if (!data) { - return False; - } - - if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, True)) { - return False; - } - - /* Now delete the stored mid entry. */ - if (!get_sequence_for_reply(&data->outstanding_packet_list, mid, &reply_seq_num)) { - return False; - } - - return True; -} - /*********************************************************** Is client signing on ? ************************************************************/ -- cgit From 9254bb4ef1c3c3a52ea8e935edb0e7a86ec3ea7a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 4 Jan 2008 12:56:23 -0800 Subject: Refactor the crypto code after a very helpful conversation with Volker. Mostly making sure we have data on the incoming packet type, not stored in the smb header. Jeremy. (This used to be commit c4e5a505043965eec77b5bb9bc60957e8f3b97c8) --- source3/libsmb/smb_signing.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index d5cbe3b125..f03c21bd0e 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -745,8 +745,8 @@ bool srv_oplock_set_signing(bool onoff) bool srv_check_sign_mac(const char *inbuf, bool must_be_ok) { - /* Check if it's a session keepalive. */ - if(CVAL(inbuf,0) == SMBkeepalive) { + /* Check if it's a non-session message. */ + if(CVAL(inbuf,0)) { return True; } @@ -759,8 +759,8 @@ bool srv_check_sign_mac(const char *inbuf, bool must_be_ok) void srv_calculate_sign_mac(char *outbuf) { - /* Check if it's a session keepalive. */ - if(CVAL(outbuf,0) == SMBkeepalive) { + /* Check if it's a non-session message. */ + if(CVAL(outbuf,0)) { return; } -- cgit From 4b5169f590425334d9ae3f2b7be2201e2e0b747e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 12 Feb 2008 11:54:37 +0100 Subject: Add explicit buf arg to cli_encrypt_message and cli_calculate_sign_mac (This used to be commit db6ae9ed2326e6cd68475375d049084cf1d5a98c) --- source3/libsmb/smb_signing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index f03c21bd0e..eeaf28c3d1 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -573,9 +573,9 @@ void cli_free_signing_context(struct cli_state *cli) * Sign a packet with the current mechanism */ -void cli_calculate_sign_mac(struct cli_state *cli) +void cli_calculate_sign_mac(struct cli_state *cli, char *buf) { - cli->sign_info.sign_outgoing_message(cli->outbuf, &cli->sign_info); + cli->sign_info.sign_outgoing_message(buf, &cli->sign_info); } /** -- cgit From b9f7dd2909487f8e306774ee0475f8b20331a866 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 12 Feb 2008 23:16:37 +0100 Subject: Add explicit buf arg to cli_check_sign_mac (This used to be commit ffc1c8cc03e6bad40ed2be91392074b4f038a1bf) --- source3/libsmb/smb_signing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index eeaf28c3d1..bd6d97123d 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -584,9 +584,9 @@ void cli_calculate_sign_mac(struct cli_state *cli, char *buf) * which had a bad checksum, True otherwise. */ -bool cli_check_sign_mac(struct cli_state *cli) +bool cli_check_sign_mac(struct cli_state *cli, char *buf) { - if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info, True)) { + if (!cli->sign_info.check_incoming_message(buf, &cli->sign_info, True)) { free_signing_context(&cli->sign_info); return False; } -- cgit From 8ef2ada0ef36f946c79e5523db90f8d1d03d6607 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 13 May 2008 15:19:46 +0200 Subject: Revert "Fix signing bug found by Volker. That one was *subtle*." This reverts commit 816aea6c1a426eb2450061b847729e22bdac33a0. (This used to be commit e402e6508ca0806deef4c4044cfa6461b682850a) --- source3/libsmb/smb_signing.c | 79 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 74 insertions(+), 5 deletions(-) (limited to 'source3/libsmb/smb_signing.c') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index bd6d97123d..ea1eb05cfb 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -25,6 +25,7 @@ struct outstanding_packet_lookup { struct outstanding_packet_lookup *prev, *next; uint16 mid; uint32 reply_seq_num; + bool can_delete; /* Set to False in trans state. */ }; struct smb_basic_signing_context { @@ -41,9 +42,7 @@ static bool store_sequence_for_reply(struct outstanding_packet_lookup **list, /* Ensure we only add a mid once. */ for (t = *list; t; t = t->next) { if (t->mid == mid) { - DLIST_REMOVE(*list, t); - SAFE_FREE(t); - break; + return False; } } @@ -52,6 +51,7 @@ static bool store_sequence_for_reply(struct outstanding_packet_lookup **list, t->mid = mid; t->reply_seq_num = reply_seq_num; + t->can_delete = True; /* * Add to the *start* of the list not the end of the list. @@ -78,8 +78,23 @@ static bool get_sequence_for_reply(struct outstanding_packet_lookup **list, *reply_seq_num = t->reply_seq_num; DEBUG(10,("get_sequence_for_reply: found seq = %u mid = %u\n", (unsigned int)t->reply_seq_num, (unsigned int)t->mid )); - DLIST_REMOVE(*list, t); - SAFE_FREE(t); + if (t->can_delete) { + DLIST_REMOVE(*list, t); + SAFE_FREE(t); + } + return True; + } + } + return False; +} + +static bool set_sequence_can_delete_flag(struct outstanding_packet_lookup **list, uint16 mid, bool can_delete_entry) +{ + struct outstanding_packet_lookup *t; + + for (t = *list; t; t = t->next) { + if (t->mid == mid) { + t->can_delete = can_delete_entry; return True; } } @@ -593,6 +608,60 @@ bool cli_check_sign_mac(struct cli_state *cli, char *buf) return True; } +/*********************************************************** + Enter trans/trans2/nttrans state. +************************************************************/ + +bool client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid) +{ + struct smb_sign_info *si = &cli->sign_info; + struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; + + if (!si->doing_signing) { + return True; + } + + if (!data) { + return False; + } + + if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, False)) { + return False; + } + + return True; +} + +/*********************************************************** + Leave trans/trans2/nttrans state. +************************************************************/ + +bool client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid) +{ + uint32 reply_seq_num; + struct smb_sign_info *si = &cli->sign_info; + struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; + + if (!si->doing_signing) { + return True; + } + + if (!data) { + return False; + } + + if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, True)) { + return False; + } + + /* Now delete the stored mid entry. */ + if (!get_sequence_for_reply(&data->outstanding_packet_list, mid, &reply_seq_num)) { + return False; + } + + return True; +} + /*********************************************************** Is client signing on ? ************************************************************/ -- cgit