svn commit: samba r13473 - in branches/SAMBA_3_0/source/libsmb: .

jra at samba.org jra at samba.org
Sun Feb 12 16:44:31 GMT 2006


Author: jra
Date: 2006-02-12 16:44:30 +0000 (Sun, 12 Feb 2006)
New Revision: 13473

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=13473

Log:
Back port r13470, r13471, r13472 from Samba4. Thanks Andrew:
-----------------------------------
Thanks to a report from VL:

We were causing mayhem by weakening the keys at the wrong point in time.

I think this is the correct place to do it.  The session key for SMB
signing, and the 'smb session key' (used for encrypting password sets)
is never weakened.

The session key used for bulk data encryption/signing is weakened.

This also makes more sense, when we look at the NTLM2 code.

Andrew Bartlett
-----------------------------------
With more 'try all options' testing, I found this 'simple' but in the
NTLM2 signing code.

Andrew Bartlett
-----------------------------------
After Volker's advise, try every combination of parameters.  This
isn't every parameter on NTLMSSP, but it is most of the important
ones.

This showed up that we had the '128bit && LM_KEY' case messed up.
This isn't supported, so we must look instead at the 56 bit flag.

Andrew Bartlett
-----------------------------------

We should now try retesting with NT4. This should be standalone
enough to port into a SAMBA_3_0_RELEASE branch fix.

Jeremy.

Modified:
   branches/SAMBA_3_0/source/libsmb/ntlmssp.c
   branches/SAMBA_3_0/source/libsmb/ntlmssp_sign.c


Changeset:
Modified: branches/SAMBA_3_0/source/libsmb/ntlmssp.c
===================================================================
--- branches/SAMBA_3_0/source/libsmb/ntlmssp.c	2006-02-12 14:19:31 UTC (rev 13472)
+++ branches/SAMBA_3_0/source/libsmb/ntlmssp.c	2006-02-12 16:44:30 UTC (rev 13473)
@@ -72,6 +72,8 @@
 		DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_SIGN\n"));
 	if (neg_flags & NTLMSSP_NEGOTIATE_SEAL) 
 		DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_SEAL\n"));
+	if (neg_flags & NTLMSSP_NEGOTIATE_DATAGRAM_STYLE)
+		DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_DATAGRAM_STYLE\n"));
 	if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) 
 		DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_LM_KEY\n"));
 	if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE) 
@@ -86,6 +88,10 @@
 		DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n"));
 	if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) 
 		DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n"));
+	if (neg_flags & NTLMSSP_CHAL_ACCEPT_RESPONSE)
+		DEBUGADD(4, ("  NTLMSSP_CHAL_ACCEPT_RESPONSE\n"));
+	if (neg_flags & NTLMSSP_CHAL_NON_NT_SESSION_KEY)
+		DEBUGADD(4, ("  NTLMSSP_CHAL_NON_NT_SESSION_KEY\n"));
 	if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2) 
 		DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_NTLM2\n"));
 	if (neg_flags & NTLMSSP_CHAL_TARGET_INFO) 
@@ -94,6 +100,8 @@
 		DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_128\n"));
 	if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) 
 		DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_KEY_EXCH\n"));
+	if (neg_flags & NTLMSSP_NEGOTIATE_56)
+		DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_56\n"));
 }
 
 /**
@@ -382,11 +390,16 @@
  by the client lanman auth/lanman auth parameters, it isn't too bad.
 */
 
-void ntlmssp_weaken_keys(NTLMSSP_STATE *ntlmssp_state)
+DATA_BLOB ntlmssp_weaken_keys(NTLMSSP_STATE *ntlmssp_state, TALLOC_CTX *mem_ctx)
 {
+	DATA_BLOB weakened_key = data_blob_talloc(mem_ctx,
+					ntlmssp_state->session_key.data,
+					ntlmssp_state->session_key.length);
+
 	/* Nothing to weaken.  We certainly don't want to 'extend' the length... */
-	if (ntlmssp_state->session_key.length < 8) {
-		return;
+	if (weakened_key.length < 16) {
+		/* perhaps there was no key? */
+		return weakened_key;
 	}
 
 	/* Key weakening not performed on the master key for NTLM2
@@ -395,17 +408,19 @@
 	*/
 
 	if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
-		if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) {
-			;
-		} else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {
-			ntlmssp_state->session_key.data[7] = 0xa0;
+		/* LM key doesn't support 128 bit crypto, so this is
+		 * the best we can do.  If you negotiate 128 bit, but
+		 * not 56, you end up with 40 bit... */
+		if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {
+			weakened_key.data[7] = 0xa0;
 		} else { /* forty bits */
-			ntlmssp_state->session_key.data[5] = 0xe5;
-			ntlmssp_state->session_key.data[6] = 0x38;
-			ntlmssp_state->session_key.data[7] = 0xb0;
+			weakened_key.data[5] = 0xe5;
+			weakened_key.data[6] = 0x38;
+			weakened_key.data[7] = 0xb0;
 		}
-		ntlmssp_state->session_key.length = 8;
+		weakened_key.length = 8;
 	}
+	return weakened_key;
 }
 
 /**
@@ -775,9 +790,6 @@
 		ntlmssp_state->session_key = session_key;
 	}
 
-	/* The client might need us to use a partial-strength session key */
-	ntlmssp_weaken_keys(ntlmssp_state);
-
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		ntlmssp_state->session_key = data_blob(NULL, 0);
 	} else if (ntlmssp_state->session_key.length) {
@@ -1093,9 +1105,6 @@
 
 	ntlmssp_state->session_key = session_key;
 
-	/* The client might be using 56 or 40 bit weakened keys */
-	ntlmssp_weaken_keys(ntlmssp_state);
-
 	ntlmssp_state->chal = challenge_blob;
 	ntlmssp_state->lm_resp = lm_response;
 	ntlmssp_state->nt_resp = nt_response;

Modified: branches/SAMBA_3_0/source/libsmb/ntlmssp_sign.c
===================================================================
--- branches/SAMBA_3_0/source/libsmb/ntlmssp_sign.c	2006-02-12 14:19:31 UTC (rev 13472)
+++ branches/SAMBA_3_0/source/libsmb/ntlmssp_sign.c	2006-02-12 16:44:30 UTC (rev 13473)
@@ -328,17 +328,22 @@
 {
 	unsigned char p24[24];
 	ZERO_STRUCT(p24);
+	TALLOC_CTX *mem_ctx = talloc_init("weak_keys");
 
+	if (!mem_ctx) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
 	DEBUG(3, ("NTLMSSP Sign/Seal - Initialising with flags:\n"));
 	debug_ntlmssp_flags(ntlmssp_state->neg_flags);
 
-	if (!ntlmssp_state->session_key.length) {
+	if (ntlmssp_state->session_key.length < 8) {
+		talloc_free(mem_ctx);
 		DEBUG(3, ("NO session key, cannot intialise signing\n"));
 		return NT_STATUS_NO_USER_SESSION_KEY;
 	}
 
-	if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2)
-	{
+	if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
 		DATA_BLOB weak_session_key = ntlmssp_state->session_key;
 		const char *send_sign_const;
 		const char *send_seal_const;
@@ -359,11 +364,8 @@
 			recv_seal_const = CLI_SEAL;
 			break;
 		default:
-			send_sign_const = "unknown role";
-			send_seal_const = "unknown role";
-			recv_sign_const = "unknown role";
-			recv_seal_const = "unknown role";
-			break;
+			talloc_free(mem_ctx);
+			return NT_STATUS_INTERNAL_ERROR;
 		}
 
 		/**
@@ -374,7 +376,7 @@
 		if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) {
 			;
 		} else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {
-			weak_session_key.length = 6;
+			weak_session_key.length = 7;
 		} else { /* forty bits */
 			weak_session_key.length = 5;
 		}
@@ -383,12 +385,13 @@
 				weak_session_key.data,
 				weak_session_key.length);
 
-		/* SEND */
+		/* SEND: sign key */
 		calc_ntlmv2_key(ntlmssp_state->send_sign_key,
 				ntlmssp_state->session_key, send_sign_const);
 		dump_data_pw("NTLMSSP send sign key:\n",
 				ntlmssp_state->send_sign_key, 16);
 
+		/* SEND: seal ARCFOUR pad */
 		calc_ntlmv2_key(ntlmssp_state->send_seal_key,
 				weak_session_key, send_seal_const);
 		dump_data_pw("NTLMSSP send seal key:\n",
@@ -401,12 +404,13 @@
 			     ntlmssp_state->send_seal_arc4_state, 
 			     sizeof(ntlmssp_state->send_seal_arc4_state));
 
-		/* RECV */
+		/* RECV: sign key */
 		calc_ntlmv2_key(ntlmssp_state->recv_sign_key,
 				ntlmssp_state->session_key, recv_sign_const);
 		dump_data_pw("NTLMSSP recv send sign key:\n",
 				ntlmssp_state->recv_sign_key, 16);
 
+		/* RECV: seal ARCFOUR pad */
 		calc_ntlmv2_key(ntlmssp_state->recv_seal_key,
 				weak_session_key, recv_seal_const);
 		
@@ -446,10 +450,12 @@
 				weak_session_key.length);
 #endif
 
+		DATA_BLOB weak_session_key = ntlmssp_weaken_keys(ntlmssp_state, mem_ctx);
+
 		DEBUG(5, ("NTLMSSP Sign/Seal - using NTLM1\n"));
 
 		smb_arc4_init(ntlmssp_state->ntlmv1_arc4_state,
-                             ntlmssp_state->session_key.data, ntlmssp_state->session_key.length);
+                             weak_session_key.data, weak_session_key.length);
 
                 dump_data_pw("NTLMv1 arc4 state:\n", ntlmssp_state->ntlmv1_arc4_state,
 				sizeof(ntlmssp_state->ntlmv1_arc4_state));
@@ -457,5 +463,6 @@
 		ntlmssp_state->ntlmv1_seq_num = 0;
 	}
 
+	talloc_free(mem_ctx);
 	return NT_STATUS_OK;
 }



More information about the samba-cvs mailing list