diff options
author | Jeremy Allison <jra@samba.org> | 2003-08-02 00:29:45 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2003-08-02 00:29:45 +0000 |
commit | 2443f7ffa20a683eabb792182cb0206402ad8059 (patch) | |
tree | 48d0fbd22e7646a4005d799b8210187668aa4a6e /source3/libsmb/smb_signing.c | |
parent | 72a8b313036092d3133c010257218ab60c1ca808 (diff) | |
download | samba-2443f7ffa20a683eabb792182cb0206402ad8059.tar.gz |
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/smb_signing.c')
-rw-r--r-- | source3/libsmb/smb_signing.c | 67 |
1 files changed, 65 insertions, 2 deletions
diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 3feffe4c961..81e25cb67c8 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; |