summaryrefslogtreecommitdiff
path: root/source3/libsmb
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2003-08-02 00:29:45 +0000
committerJeremy Allison <jra@samba.org>2003-08-02 00:29:45 +0000
commit2443f7ffa20a683eabb792182cb0206402ad8059 (patch)
tree48d0fbd22e7646a4005d799b8210187668aa4a6e /source3/libsmb
parent72a8b313036092d3133c010257218ab60c1ca808 (diff)
downloadsamba-2443f7ffa20a683eabb792182cb0206402ad8059.tar.gz
samba-2443f7ffa20a683eabb792182cb0206402ad8059.tar.bz2
samba-2443f7ffa20a683eabb792182cb0206402ad8059.zip
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)
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;