diff options
Diffstat (limited to 'source3/libsmb')
-rw-r--r-- | source3/libsmb/cliconnect.c | 35 | ||||
-rw-r--r-- | source3/libsmb/clientgen.c | 2 | ||||
-rw-r--r-- | source3/libsmb/samlogon_cache.c | 4 | ||||
-rw-r--r-- | source3/libsmb/smb_signing.c | 120 |
4 files changed, 62 insertions, 99 deletions
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 8093d79452..e75a361e25 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -325,7 +325,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, session_key = data_blob(NULL, 16); SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); } - cli_simple_set_signing(cli, session_key, nt_response); + cli_simple_set_signing(cli, session_key, nt_response, 0); } else { /* pre-encrypted password supplied. Only used for security=server, can't do @@ -521,7 +521,7 @@ static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char * file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length); #endif - cli_simple_set_signing(cli, session_key_krb5, null_blob); + cli_simple_set_signing(cli, session_key_krb5, null_blob, 0); blob2 = cli_session_setup_blob(cli, negTokenTarg); @@ -643,16 +643,13 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use fstrcpy(cli->server_domain, ntlmssp_state->server_domain); cli_set_session_key(cli, ntlmssp_state->session_key); - if (cli_simple_set_signing(cli, key, null_blob)) { - - /* 'resign' the last message, so we get the right sequence numbers - for checking the first reply from the server */ - cli_calculate_sign_mac(cli); - - if (!cli_check_sign_mac(cli, True)) { - nt_status = NT_STATUS_ACCESS_DENIED; - } - } + /* Using NTLMSSP session setup, signing on the net only starts + * after a successful authentication and the session key has + * been determined, but with a sequence number of 2. This + * assumes that NTLMSSP needs exactly 2 roundtrips, for any + * other SPNEGO mechanism it needs adapting. */ + + cli_simple_set_signing(cli, key, null_blob, 2); } /* we have a reference conter on ntlmssp_state, if we are signing @@ -1091,8 +1088,6 @@ BOOL cli_negprot(struct cli_state *cli) } cli->sign_info.negotiated_smb_signing = True; cli->sign_info.mandatory_signing = True; - } else if (cli->sign_info.allow_smb_signing && cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) { - cli->sign_info.negotiated_smb_signing = True; } } else if (cli->protocol >= PROTOCOL_LANMAN1) { @@ -1610,8 +1605,8 @@ struct cli_state *get_ipc_connect(char *server, struct in_addr *server_ip, struct cli_state *get_ipc_connect_master_ip(struct ip_service * mb_ip, pstring workgroup, struct user_auth_info *user_info) { static fstring name; - struct cli_state *cli; - struct in_addr server_ip; + struct cli_state *cli; + struct in_addr server_ip; DEBUG(99, ("Looking up name of master browser %s\n", inet_ntoa(mb_ip->ip))); @@ -1640,14 +1635,14 @@ struct cli_state *get_ipc_connect_master_ip(struct ip_service * mb_ip, pstring w return NULL; } - pstrcpy(workgroup, name); + pstrcpy(workgroup, name); - DEBUG(4, ("found master browser %s, %s\n", + DEBUG(4, ("found master browser %s, %s\n", name, inet_ntoa(mb_ip->ip))); - cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info); + cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info); - return cli; + return cli; } diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 66edc3ce38..8542eea064 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -117,7 +117,7 @@ BOOL cli_receive_smb(struct cli_state *cli) return ret; } - if (!cli_check_sign_mac(cli, True)) { + if (!cli_check_sign_mac(cli)) { DEBUG(0, ("SMB Signature verification failed on incoming packet!\n")); cli->smb_rw_error = READ_BAD_SIG; close(cli->fd); diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index 4cd642c4e3..72c10007bf 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -157,7 +157,7 @@ BOOL netsamlogon_cache_store(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user) free the user_info struct (malloc()'d memory) ***********************************************************************/ -NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, const DOM_SID *user_sid) +NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, DOM_SID *user_sid) { NET_USER_INFO_3 *user = NULL; TDB_DATA data, key; @@ -218,7 +218,7 @@ NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, const DOM_SID *user return user; } -BOOL netsamlogon_cache_have(const DOM_SID *user_sid) +BOOL netsamlogon_cache_have(DOM_SID *user_sid) { TALLOC_CTX *mem_ctx = talloc_init("netsamlogon_cache_have"); NET_USER_INFO_3 *user = NULL; diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 28ff0e0c2e..9010dbf5cb 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -150,7 +150,7 @@ static void null_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) SMB signing - NULL implementation - check a MAC sent by server. ************************************************************/ -static BOOL null_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL expected_ok) +static BOOL null_check_incoming_message(char *inbuf, struct smb_sign_info *si) { return True; } @@ -197,39 +197,25 @@ static void free_signing_context(struct smb_sign_info *si) } -static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good, uint32 seq, BOOL expected_ok) +static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good, uint32 seq) { - if (good) { + if (good && !si->doing_signing) { + si->doing_signing = True; + } - if (!si->doing_signing) { - si->doing_signing = True; - } - - if (!si->seen_valid) { - si->seen_valid = True; - } + if (!good) { + if (si->doing_signing) { + struct smb_basic_signing_context *data = si->signing_context; - } else { - if (!si->mandatory_signing && !si->seen_valid) { + /* W2K sends a bad first signature but the sign engine is on.... JRA. */ + if (data->send_seq_num > 1) + DEBUG(1, ("signing_good: SMB signature check failed on seq %u!\n", + (unsigned int)seq )); - if (!expected_ok) { - return True; - } - /* Non-mandatory signing - just turn off if this is the first bad packet.. */ - DEBUG(5, ("signing_good: signing negotiated but not required and the other side \ -isn't sending correct signatures. Turning signatures off.\n")); - si->negotiated_smb_signing = False; - si->allow_smb_signing = False; - si->doing_signing = False; - free_signing_context(si); - return True; - } else if (!expected_ok) { - /* This packet is known to be unsigned */ - return True; + return False; } else { - /* Mandatory signing or bad packet after signing started - fail and disconnect. */ - if (seq) - DEBUG(0, ("signing_good: BAD SIG: seq %u\n", (unsigned int)seq)); + DEBUG(3, ("signing_good: Peer did not sign reply correctly\n")); + free_signing_context(si); return False; } } @@ -337,7 +323,7 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) SMB signing - Client implementation - check a MAC sent by server. ************************************************************/ -static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL expected_ok) +static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) { BOOL good; uint32 reply_seq_number; @@ -395,7 +381,7 @@ We were expecting seq %u\n", reply_seq_number, saved_seq )); DEBUG(10, ("client_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); dump_data(10, (const char *)server_sent_mac, 8); } - return signing_good(inbuf, si, good, saved_seq, expected_ok); + return signing_good(inbuf, si, good, saved_seq); } /*********************************************************** @@ -429,7 +415,7 @@ static void simple_free_signing_context(struct smb_sign_info *si) BOOL cli_simple_set_signing(struct cli_state *cli, const DATA_BLOB user_session_key, - const DATA_BLOB response) + const DATA_BLOB response, int initial_send_seq_num) { struct smb_basic_signing_context *data; @@ -467,7 +453,7 @@ BOOL cli_simple_set_signing(struct cli_state *cli, dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length); /* Initialise the sequence number */ - data->send_seq_num = 0; + data->send_seq_num = initial_send_seq_num; /* Initialise the list of outstanding packets */ data->outstanding_packet_list = NULL; @@ -549,7 +535,7 @@ static void temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) SMB signing - TEMP implementation - check a MAC sent by server. ************************************************************/ -static BOOL temp_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL expected_ok) +static BOOL temp_check_incoming_message(char *inbuf, struct smb_sign_info *si) { return True; } @@ -611,9 +597,9 @@ void cli_calculate_sign_mac(struct cli_state *cli) * which had a bad checksum, True otherwise. */ -BOOL cli_check_sign_mac(struct cli_state *cli, BOOL expected_ok) +BOOL cli_check_sign_mac(struct cli_state *cli) { - if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info, expected_ok)) { + if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info)) { free_signing_context(&cli->sign_info); return False; } @@ -702,7 +688,7 @@ static BOOL is_oplock_break(char *inbuf) SMB signing - Server implementation - check a MAC sent by server. ************************************************************/ -static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL expected_ok) +static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) { BOOL good; struct smb_basic_signing_context *data = si->signing_context; @@ -776,7 +762,25 @@ We were expecting seq %u\n", reply_seq_number, saved_seq )); dump_data(10, (const char *)server_sent_mac, 8); } - return (signing_good(inbuf, si, good, saved_seq, expected_ok)); + if (!signing_good(inbuf, si, good, saved_seq)) { + if (!si->mandatory_signing && (data->send_seq_num < 3)){ + /* Non-mandatory signing - just turn off if this is the first bad packet.. */ + DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and client \ +isn't sending correct signatures. Turning off.\n")); + si->negotiated_smb_signing = False; + si->allow_smb_signing = False; + si->doing_signing = False; + free_signing_context(si); + return True; + } else { + /* Mandatory signing or bad packet after signing started - fail and disconnect. */ + if (saved_seq) + DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u\n", (unsigned int)saved_seq)); + return False; + } + } else { + return True; + } } /*********************************************************** @@ -809,13 +813,13 @@ BOOL srv_oplock_set_signing(BOOL onoff) Called to validate an incoming packet from the client. ************************************************************/ -BOOL srv_check_sign_mac(char *inbuf, BOOL expected_ok) +BOOL srv_check_sign_mac(char *inbuf) { /* Check if it's a session keepalive. */ if(CVAL(inbuf,0) == SMBkeepalive) return True; - return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info, expected_ok); + return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info); } /*********************************************************** @@ -903,42 +907,6 @@ BOOL srv_is_signing_active(void) return srv_sign_info.doing_signing; } - -/*********************************************************** - Returns whether signing is negotiated. We can't use it unless it was - in the negprot. -************************************************************/ - -BOOL srv_is_signing_negotiated(void) -{ - return srv_sign_info.negotiated_smb_signing; -} - -/*********************************************************** - Returns whether signing is negotiated. We can't use it unless it was - in the negprot. -************************************************************/ - -BOOL srv_signing_started(void) -{ - struct smb_basic_signing_context *data; - - if (!srv_sign_info.doing_signing) { - return False; - } - - data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; - if (!data) - return False; - - if (data->send_seq_num == 0) { - return False; - } - - return True; -} - - /*********************************************************** Tell server code we are in a multiple trans reply state. ************************************************************/ |