summaryrefslogtreecommitdiff
path: root/source3/libsmb/smb_signing.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libsmb/smb_signing.c')
-rw-r--r--source3/libsmb/smb_signing.c120
1 files changed, 76 insertions, 44 deletions
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.
************************************************************/