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,
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 <http://www.gnu.org/licenses/>.
*/
#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;
-};
-
-/* Store the data for an ongoing trans/trans2/nttrans operation. */
-struct trans_info_context {
uint16 mid;
- uint32 send_seq_num;
uint32 reply_seq_num;
+ BOOL can_delete; /* Set to False in trans state. */
};
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;
};
-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;
- struct outstanding_packet_lookup *tmp;
-
- t = smb_xmalloc(sizeof(*t));
+
+ /* Ensure we only add a mid once. */
+ for (t = *list; t; t = t->next) {
+ if (t->mid == mid) {
+ return False;
+ }
+ }
+
+ t = SMB_XMALLOC_P(struct outstanding_packet_lookup);
ZERO_STRUCTP(t);
- DLIST_ADD_END(*list, t, tmp);
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.
+ * 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 <fran@cis.uab.edu>.
+ */
+
+ 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,
*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;
}
}
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;
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;
}
}
-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 peer\n"
+ "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;
}
}
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.
MD5Init(&md5_ctx);
/* intialise with the key */
- MD5Update(&md5_ctx, data->mac_key.data,
- data->mac_key.length);
+ 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 <nalin@redhat.com> */
+ 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);
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;
+ struct smb_basic_signing_context *data =
+ (struct smb_basic_signing_context *)si->signing_context;
if (!si->doing_signing)
return;
/* 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);
+ 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...*/
- 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++;
+ /* 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;
+ }
}
/***********************************************************
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;
- uint32 saved_seq;
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;
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) ));
+ 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;
}
- saved_seq = reply_seq_number;
- simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac);
+ 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);
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;
- 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;
}
}
} 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, saved_seq);
+ return signing_good(inbuf, si, good, reply_seq_number, must_be_ok);
}
/***********************************************************
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 smb_basic_signing_context *data =
+ (struct smb_basic_signing_context *)si->signing_context;
+ 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)
- SAFE_FREE(data->trans_info);
-
SAFE_FREE(si->signing_context);
return;
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)
{
struct smb_basic_signing_context *data;
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;
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"));
}
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 || !data)
- 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;
-
- 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;
-
- SAFE_FREE(data->trans_info);
- data->trans_info = NULL;
-
- data->send_seq_num += 2;
-}
-
/***********************************************************
SMB signing - TEMP implementation - calculate a MAC to send.
************************************************************/
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;
}
BOOL cli_check_sign_mac(struct cli_state *cli)
{
- if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info)) {
+ if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info, True)) {
free_signing_context(&cli->sign_info);
return False;
}
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 ?
+************************************************************/
+
+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.
************************************************************/
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;
+ 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;
if (!si->doing_signing) {
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);
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);
/* 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;
}
/***********************************************************
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;
+ 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];
unsigned char *server_sent_mac;
- uint mid;
if (!si->doing_signing)
return True;
return False;
}
- 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);
if (!good) {
- DEBUG(5, ("srv_check_incoming_message: BAD SIG: seq %u wanted 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 *)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, (const char *)server_sent_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, server_sent_mac, 8);
+ }
+
#if 1 /* JRATEST */
{
int i;
} 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);
}
- 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;
- }
+ return (signing_good(inbuf, si, good, saved_seq, must_be_ok));
}
/***********************************************************
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)
+ 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);
}
/***********************************************************
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;
+ }
srv_sign_info.sign_outgoing_message(outbuf, &srv_sign_info);
}
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...
+ */
+
+ store_sequence_for_reply(&data->outstanding_packet_list, mid,
+ data->send_seq_num-1);
}
/***********************************************************
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;
}
/***********************************************************
return srv_sign_info.doing_signing;
}
+
/***********************************************************
- Tell server code we are in a multiple trans reply state.
+ Returns whether signing is negotiated. We can't use it unless it was
+ in the negprot.
************************************************************/
-void srv_signing_trans_start(uint16 mid)
+BOOL srv_is_signing_negotiated(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)
- return;
-
- 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;
-
- 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 ));
+ return srv_sign_info.negotiated_smb_signing;
}
/***********************************************************
- Tell server code we are out of a multiple trans reply state.
+ Returns whether signing is actually happening
************************************************************/
-void srv_signing_trans_stop(void)
+BOOL srv_signing_started(void)
{
struct smb_basic_signing_context *data;
- if (!srv_sign_info.doing_signing)
- return;
+ if (!srv_sign_info.doing_signing) {
+ return False;
+ }
data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
- if (!data || !data->trans_info)
- return;
+ if (!data)
+ return False;
- 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 ));
+ if (data->send_seq_num == 0) {
+ return False;
+ }
- SAFE_FREE(data->trans_info);
- data->trans_info = NULL;
+ return True;
}
/***********************************************************
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;