diff options
-rw-r--r-- | source3/libsmb/clientgen.c | 4 | ||||
-rw-r--r-- | source3/libsmb/clilist.c | 12 | ||||
-rw-r--r-- | source3/libsmb/clitrans.c | 18 | ||||
-rw-r--r-- | source3/libsmb/smb_signing.c | 67 |
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; |