summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/libsmb/smb_signing.c76
-rw-r--r--source3/smbd/ipc.c6
-rw-r--r--source3/smbd/nttrans.c6
-rw-r--r--source3/smbd/trans2.c6
4 files changed, 82 insertions, 12 deletions
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);
@@ -810,6 +819,49 @@ BOOL srv_is_signing_active(void)
}
/***********************************************************
+ 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.
************************************************************/
diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c
index 85e28f5d17..f0b5c4a92f 100644
--- a/source3/smbd/ipc.c
+++ b/source3/smbd/ipc.c
@@ -428,6 +428,8 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
}
+ srv_signing_trans_start(SVAL(inbuf,smb_mid));
+
if (pscnt < tpscnt || dscnt < tdscnt) {
/* We need to send an interim response then receive the rest
of the parameter/data bytes */
@@ -455,6 +457,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
SAFE_FREE(data);
SAFE_FREE(setup);
END_PROFILE(SMBtrans);
+ srv_signing_trans_stop();
return(ERROR_DOS(ERRSRV,ERRerror));
}
@@ -542,6 +545,8 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
SAFE_FREE(params);
SAFE_FREE(setup);
+ srv_signing_trans_stop();
+
if (close_on_completion)
close_cnum(conn,vuid);
@@ -561,6 +566,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
bad_param:
+ srv_signing_trans_stop();
DEBUG(0,("reply_trans: invalid trans parameters\n"));
SAFE_FREE(data);
SAFE_FREE(params);
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index c574d9d563..1506877aff 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -2321,6 +2321,8 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
dump_data(10, data, data_count);
}
+ srv_signing_trans_start(SVAL(inbuf,smb_mid));
+
if(num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) {
/* We need to send an interim response then receive the rest
of the parameter/data bytes */
@@ -2484,6 +2486,7 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
SAFE_FREE(params);
SAFE_FREE(data);
END_PROFILE(SMBnttrans);
+ srv_signing_trans_stop();
return ERROR_DOS(ERRSRV,ERRerror);
}
@@ -2494,6 +2497,8 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
an error packet.
*/
+ srv_signing_trans_stop();
+
SAFE_FREE(setup);
SAFE_FREE(params);
SAFE_FREE(data);
@@ -2504,6 +2509,7 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
bad_param:
+ srv_signing_trans_stop();
SAFE_FREE(params);
SAFE_FREE(data);
SAFE_FREE(setup);
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 9998887793..86906fa5be 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -3359,6 +3359,8 @@ int reply_trans2(connection_struct *conn,
memcpy( data, smb_base(inbuf) + dsoff, num_data);
}
+ srv_signing_trans_start(SVAL(inbuf,smb_mid));
+
if(num_data_sofar < total_data || num_params_sofar < total_params) {
/* We need to send an interim response then receive the rest
of the parameter/data bytes */
@@ -3531,6 +3533,7 @@ int reply_trans2(connection_struct *conn,
SAFE_FREE(params);
SAFE_FREE(data);
END_PROFILE(SMBtrans2);
+ srv_signing_trans_stop();
return ERROR_DOS(ERRSRV,ERRerror);
}
@@ -3541,6 +3544,8 @@ int reply_trans2(connection_struct *conn,
an error packet.
*/
+ srv_signing_trans_stop();
+
SAFE_FREE(params);
SAFE_FREE(data);
END_PROFILE(SMBtrans2);
@@ -3550,6 +3555,7 @@ int reply_trans2(connection_struct *conn,
bad_param:
+ srv_signing_trans_stop();
SAFE_FREE(params);
SAFE_FREE(data);
END_PROFILE(SMBtrans2);