summaryrefslogtreecommitdiff
path: root/source3/libsmb
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libsmb')
-rw-r--r--source3/libsmb/cliconnect.c35
-rw-r--r--source3/libsmb/clientgen.c2
-rw-r--r--source3/libsmb/samlogon_cache.c4
-rw-r--r--source3/libsmb/smb_signing.c120
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.
************************************************************/