summaryrefslogtreecommitdiff
path: root/source3/libsmb
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libsmb')
-rw-r--r--source3/libsmb/clientgen.c4
-rw-r--r--source3/libsmb/clilist.c12
-rw-r--r--source3/libsmb/clitrans.c18
-rw-r--r--source3/libsmb/smb_signing.c67
4 files changed, 97 insertions, 4 deletions
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c
index cdda2eb224..bc5f1462cc 100644
--- a/source3/libsmb/clientgen.c
+++ b/source3/libsmb/clientgen.c
@@ -157,6 +157,10 @@ BOOL cli_send_smb(struct cli_state *cli)
}
nwritten += ret;
}
+ /* Increment the mid so we can tell between responses. */
+ cli->mid++;
+ if (!cli->mid)
+ cli->mid++;
return True;
}
diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c
index 2b56582700..7822987ada 100644
--- a/source3/libsmb/clilist.c
+++ b/source3/libsmb/clilist.c
@@ -145,7 +145,11 @@ static int interpret_long_filename(struct cli_state *cli,
int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
void (*fn)(file_info *, const char *, void *), void *state)
{
+#if 0
int max_matches = 1366; /* Match W2k - was 512. */
+#else
+ int max_matches = 512;
+#endif
int info_level;
char *p, *p2;
pstring mask;
@@ -207,8 +211,12 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
&setup, 1, 0, /* setup, length, max */
param, param_len, 10, /* param, length, max */
NULL, 0,
- MIN(16384,cli->max_xmit) /* data, length, max. W2K server signing
- has a bug unless this matches what W2K uses. */
+#if 0
+ /* w2k value. */
+ MIN(16384,cli->max_xmit) /* data, length, max. */
+#else
+ cli->max_xmit /* data, length, max. */
+#endif
)) {
break;
}
diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c
index 3d3cd427d7..49897d0bb0 100644
--- a/source3/libsmb/clitrans.c
+++ b/source3/libsmb/clitrans.c
@@ -40,6 +40,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans,
char *outdata,*outparam;
char *p;
int pipe_name_len=0;
+ uint16 mid;
this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */
this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam));
@@ -49,6 +50,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans,
SCVAL(cli->outbuf,smb_com,trans);
SSVAL(cli->outbuf,smb_tid, cli->cnum);
cli_setup_packet(cli);
+ mid = cli->mid;
if (pipe_name) {
pipe_name_len = clistr_push(cli, smb_buf(cli->outbuf), pipe_name, -1, STR_TERMINATE);
@@ -84,6 +86,8 @@ BOOL cli_send_trans(struct cli_state *cli, int trans,
cli_setup_bcc(cli, outdata+this_ldata);
show_msg(cli->outbuf);
+
+ cli_signing_trans_start(cli);
if (!cli_send_smb(cli))
return False;
@@ -122,6 +126,10 @@ BOOL cli_send_trans(struct cli_state *cli, int trans,
memcpy(outdata,data+tot_data,this_ldata);
cli_setup_bcc(cli, outdata+this_ldata);
+ /* Ensure this packet has the same MID as
+ * the primary. Important in signing. JRA. */
+ cli->mid = mid;
+
show_msg(cli->outbuf);
if (!cli_send_smb(cli))
return False;
@@ -292,6 +300,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
}
+ cli_signing_trans_stop(cli);
return(True);
}
@@ -309,6 +318,7 @@ BOOL cli_send_nt_trans(struct cli_state *cli,
unsigned int i;
unsigned int this_ldata,this_lparam;
unsigned int tot_data=0,tot_param=0;
+ uint16 mid;
char *outdata,*outparam;
this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */
@@ -319,6 +329,7 @@ BOOL cli_send_nt_trans(struct cli_state *cli,
SCVAL(cli->outbuf,smb_com,SMBnttrans);
SSVAL(cli->outbuf,smb_tid, cli->cnum);
cli_setup_packet(cli);
+ mid = cli->mid;
outparam = smb_buf(cli->outbuf)+3;
outdata = outparam+this_lparam;
@@ -347,6 +358,7 @@ BOOL cli_send_nt_trans(struct cli_state *cli,
cli_setup_bcc(cli, outdata+this_ldata);
show_msg(cli->outbuf);
+ cli_signing_trans_start(cli);
if (!cli_send_smb(cli))
return False;
@@ -384,7 +396,12 @@ BOOL cli_send_nt_trans(struct cli_state *cli,
memcpy(outdata,data+tot_data,this_ldata);
cli_setup_bcc(cli, outdata+this_ldata);
+ /* Ensure this packet has the same MID as
+ * the primary. Important in signing. JRA. */
+ cli->mid = mid;
+
show_msg(cli->outbuf);
+
if (!cli_send_smb(cli))
return False;
@@ -559,5 +576,6 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
break;
}
+ cli_signing_trans_stop(cli);
return(True);
}
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;
@@ -422,6 +448,42 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[
}
/***********************************************************
+ 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;