svn commit: samba r19465 - in branches/SAMBA_4_0/source: auth/gensec librpc/rpc rpc_server

abartlet at samba.org abartlet at samba.org
Mon Oct 23 06:08:26 GMT 2006


Author: abartlet
Date: 2006-10-23 06:08:25 +0000 (Mon, 23 Oct 2006)
New Revision: 19465

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

Log:
Rather than use the non-standard API for determining the signature
length, use the amount the wapped message expanded by.

This works, because GSSAPI doesn't do AEAD (signing of headers), and
so changing the signature length after the fact is valid.

Andrew Bartlett

Modified:
   branches/SAMBA_4_0/source/auth/gensec/gensec_gssapi.c
   branches/SAMBA_4_0/source/librpc/rpc/dcerpc.c
   branches/SAMBA_4_0/source/rpc_server/dcesrv_auth.c


Changeset:
Modified: branches/SAMBA_4_0/source/auth/gensec/gensec_gssapi.c
===================================================================
--- branches/SAMBA_4_0/source/auth/gensec/gensec_gssapi.c	2006-10-23 06:06:35 UTC (rev 19464)
+++ branches/SAMBA_4_0/source/auth/gensec/gensec_gssapi.c	2006-10-23 06:08:25 UTC (rev 19465)
@@ -818,46 +818,6 @@
 	return NT_STATUS_OK;
 }
 
-/* Find out the size of the signature, assuming (incorrectly) that it
- * GSSAPI provides any guarantees as to it's size.
- *
- * This is needed by the DCE/RPC code, which uses AEAD 
- * (signed headers, including signature legnth and a sealed body)
- */
-static size_t gensec_gssapi_sig_size(struct gensec_security *gensec_security, size_t data_size) 
-{
-	struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data;
-	OM_uint32 maj_stat, min_stat;
-	OM_uint32 output_size;
-	if ((gensec_gssapi_state->gss_oid->length != gss_mech_krb5->length)
-	    || (memcmp(gensec_gssapi_state->gss_oid->elements, gss_mech_krb5->elements, 
-		       gensec_gssapi_state->gss_oid->length) != 0)) {
-		DEBUG(1, ("NO sig size available for this mech\n"));
-		return 0;
-	}
-		
-	maj_stat = gsskrb5_wrap_size(&min_stat, 
-				     gensec_gssapi_state->gssapi_context,
-				     gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL),
-				     GSS_C_QOP_DEFAULT,
-				     data_size, 
-				     &output_size);
-	if (GSS_ERROR(maj_stat)) {
-		TALLOC_CTX *mem_ctx = talloc_new(NULL); 
-		DEBUG(1, ("gensec_gssapi_sig_size: determinaing signature size with gsskrb5_wrap_size failed: %s\n", 
-			  gssapi_error_string(mem_ctx, maj_stat, min_stat)));
-		talloc_free(mem_ctx);
-		return 0;
-	}
-
-	if (output_size < data_size) {
-		return 0;
-	}
-
-	/* The difference between the max output and the max input must be the signature */
-	return output_size - data_size;
-}
-
 /* Find out the maximum input size negotiated on this connection */
 
 static size_t gensec_gssapi_max_input_size(struct gensec_security *gensec_security) 
@@ -918,14 +878,12 @@
 		return NT_STATUS_ACCESS_DENIED;
 	}
 
-	sig_length = gensec_gssapi_sig_size(gensec_security, length);
-
-	/* Caller must pad to right boundary */
-	if (output_token.length != (length + sig_length)) {
-		DEBUG(1, ("gensec_gssapi_seal_packet: GSS Wrap length [%ld] does not match caller length [%ld] plus sig size [%ld] = [%ld]\n", 
-			  (long)output_token.length, (long)length, (long)sig_length, (long)(length + sig_length)));
+	if (output_token.length < input_token.length) {
+		DEBUG(1, ("gensec_gssapi_seal_packet: GSS Wrap length [%ld] *less* than caller length [%ld]\n", 
+			  (long)output_token.length, (long)length));
 		return NT_STATUS_INTERNAL_ERROR;
 	}
+	sig_length = output_token.length - input_token.length;
 
 	memcpy(data, ((uint8_t *)output_token.value) + sig_length, length);
 	*sig = data_blob_talloc(mem_ctx, (uint8_t *)output_token.value, sig_length);
@@ -1021,18 +979,14 @@
 		return NT_STATUS_ACCESS_DENIED;
 	}
 
-	if (output_token.length < length) {
+	if (output_token.length < input_token.length) {
+		DEBUG(1, ("gensec_gssapi_sign_packet: GSS Wrap length [%ld] *less* than caller length [%ld]\n", 
+			  (long)output_token.length, (long)length));
 		return NT_STATUS_INTERNAL_ERROR;
 	}
 
-	sig_length = gensec_gssapi_sig_size(gensec_security, length);
-
 	/* Caller must pad to right boundary */
-	if (output_token.length != (length + sig_length)) {
-		DEBUG(1, ("gensec_gssapi_sign_packet: GSS Wrap length [%ld] does not match caller length [%ld] plus sig size [%ld] = [%ld]\n", 
-			  (long)output_token.length, (long)length, (long)sig_length, (long)(length + sig_length)));
-		return NT_STATUS_INTERNAL_ERROR;
-	}
+	sig_length = output_token.length - input_token.length;
 
 	*sig = data_blob_talloc(mem_ctx, (uint8_t *)output_token.value, sig_length);
 
@@ -1352,7 +1306,6 @@
 	.update 	= gensec_gssapi_update,
 	.session_key	= gensec_gssapi_session_key,
 	.session_info	= gensec_gssapi_session_info,
-	.sig_size	= gensec_gssapi_sig_size,
 	.sign_packet	= gensec_gssapi_sign_packet,
 	.check_packet	= gensec_gssapi_check_packet,
 	.seal_packet	= gensec_gssapi_seal_packet,

Modified: branches/SAMBA_4_0/source/librpc/rpc/dcerpc.c
===================================================================
--- branches/SAMBA_4_0/source/librpc/rpc/dcerpc.c	2006-10-23 06:06:35 UTC (rev 19464)
+++ branches/SAMBA_4_0/source/librpc/rpc/dcerpc.c	2006-10-23 06:08:25 UTC (rev 19465)
@@ -369,6 +369,9 @@
 	switch (c->security_state.auth_info->auth_level) {
 	case DCERPC_AUTH_LEVEL_PRIVACY:
 	case DCERPC_AUTH_LEVEL_INTEGRITY:
+		/* We hope this length is accruate.  If must be if the
+		 * GENSEC mech does AEAD signing of the packet
+		 * headers */
 		c->security_state.auth_info->credentials
 			= data_blob_talloc(mem_ctx, NULL, gensec_sig_size(c->security_state.generic_state, 
 									  payload_length));
@@ -405,6 +408,8 @@
 	   in these earlier as we don't know the signature length (it
 	   could be variable length) */
 	dcerpc_set_frag_length(blob, blob->length);
+	/* We hope this value is accruate.  If must be if the GENSEC
+	 * mech does AEAD signing of the packet headers */
 	dcerpc_set_auth_length(blob, c->security_state.auth_info->credentials.length);
 
 	/* sign or seal the packet */
@@ -421,7 +426,20 @@
 		if (!NT_STATUS_IS_OK(status)) {
 			return status;
 		}
-		memcpy(blob->data + blob->length - creds2.length, creds2.data, creds2.length);
+		status = data_blob_realloc(mem_ctx, blob,
+					   blob->length - c->security_state.auth_info->credentials.length + 
+					   creds2.length);
+
+		if (!NT_STATUS_IS_OK(status)) {
+			return status;
+		}
+		memcpy(blob->data + blob->length - c->security_state.auth_info->credentials.length,
+		       creds2.data, creds2.length);
+
+		if (!NT_STATUS_IS_OK(status)) {
+			return status;
+		}
+		dcerpc_set_auth_length(blob, creds2.length);
 		break;
 
 	case DCERPC_AUTH_LEVEL_INTEGRITY:
@@ -436,7 +454,20 @@
 		if (!NT_STATUS_IS_OK(status)) {
 			return status;
 		}
-		memcpy(blob->data + blob->length - creds2.length, creds2.data, creds2.length);
+		status = data_blob_realloc(mem_ctx, blob,
+					   blob->length - c->security_state.auth_info->credentials.length + 
+					   creds2.length);
+
+		if (!NT_STATUS_IS_OK(status)) {
+			return status;
+		}
+		memcpy(blob->data + blob->length - c->security_state.auth_info->credentials.length,
+		       creds2.data, creds2.length);
+
+		if (!NT_STATUS_IS_OK(status)) {
+			return status;
+		}
+		dcerpc_set_auth_length(blob, creds2.length);
 		break;
 
 	case DCERPC_AUTH_LEVEL_CONNECT:

Modified: branches/SAMBA_4_0/source/rpc_server/dcesrv_auth.c
===================================================================
--- branches/SAMBA_4_0/source/rpc_server/dcesrv_auth.c	2006-10-23 06:06:35 UTC (rev 19464)
+++ branches/SAMBA_4_0/source/rpc_server/dcesrv_auth.c	2006-10-23 06:08:25 UTC (rev 19465)
@@ -393,6 +393,7 @@
 	NTSTATUS status;
 	struct ndr_push *ndr;
 	uint32_t payload_length;
+	DATA_BLOB creds2;
 
 	/* non-signed packets are simple */
 	if (!dce_conn->auth_state.auth_info || !dce_conn->auth_state.gensec_security) {
@@ -427,14 +428,20 @@
 			return False;
 		}
 	} else {
+
+		/* We hope this length is accruate.  If must be if the
+		 * GENSEC mech does AEAD signing of the packet
+		 * headers */
 		dce_conn->auth_state.auth_info->credentials
 			= data_blob_talloc(call, NULL, 
 					   gensec_sig_size(dce_conn->auth_state.gensec_security, 
 							   payload_length));
+		data_blob_clear(&dce_conn->auth_state.auth_info->credentials);
 	}
 
 	/* add the auth verifier */
-	status = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, dce_conn->auth_state.auth_info);
+	status = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, 
+				      dce_conn->auth_state.auth_info);
 	if (!NT_STATUS_IS_OK(status)) {
 		return False;
 	}
@@ -446,6 +453,9 @@
 	   in these earlier as we don't know the signature length (it
 	   could be variable length) */
 	dcerpc_set_frag_length(blob, blob->length);
+
+	/* We hope this value is accruate.  If must be if the GENSEC
+	 * mech does AEAD signing of the packet headers */
 	dcerpc_set_auth_length(blob, dce_conn->auth_state.auth_info->credentials.length);
 
 	/* sign or seal the packet */
@@ -457,7 +467,23 @@
 					    payload_length,
 					    blob->data,
 					    blob->length - dce_conn->auth_state.auth_info->credentials.length,
-					    &dce_conn->auth_state.auth_info->credentials);
+					    &creds2);
+
+		if (NT_STATUS_IS_OK(status)) {
+			status = data_blob_realloc(call, blob,
+						   blob->length - dce_conn->auth_state.auth_info->credentials.length + 
+						   creds2.length);
+		}
+
+		if (NT_STATUS_IS_OK(status)) {
+			memcpy(blob->data + blob->length - dce_conn->auth_state.auth_info->credentials.length,
+			       creds2.data, creds2.length);
+		}
+
+		/* If we did AEAD signing of the packet headers, then we hope
+		 * this value didn't change... */
+		dcerpc_set_auth_length(blob, creds2.length);
+		data_blob_free(&creds2);
 		break;
 
 	case DCERPC_AUTH_LEVEL_INTEGRITY:
@@ -467,8 +493,23 @@
 					    payload_length,
 					    blob->data,
 					    blob->length - dce_conn->auth_state.auth_info->credentials.length,
-					    &dce_conn->auth_state.auth_info->credentials);
+					    &creds2);
+		if (NT_STATUS_IS_OK(status)) {
+			status = data_blob_realloc(call, blob,
+						   blob->length - dce_conn->auth_state.auth_info->credentials.length + 
+						   creds2.length);
+		}
 
+		if (NT_STATUS_IS_OK(status)) {
+			memcpy(blob->data + blob->length - dce_conn->auth_state.auth_info->credentials.length,
+			       creds2.data, creds2.length);
+		}
+
+		/* If we did AEAD signing of the packet headers, then we hope
+		 * this value didn't change... */
+		dcerpc_set_auth_length(blob, creds2.length);
+
+		data_blob_free(&creds2);
 		break;
 
 	case DCERPC_AUTH_LEVEL_CONNECT:
@@ -479,14 +520,11 @@
 		break;
 	}
 
+	data_blob_free(&dce_conn->auth_state.auth_info->credentials);
+
 	if (!NT_STATUS_IS_OK(status)) {
 		return False;
 	}	
 
-	memcpy(blob->data + blob->length - dce_conn->auth_state.auth_info->credentials.length, 
-	       dce_conn->auth_state.auth_info->credentials.data, dce_conn->auth_state.auth_info->credentials.length);
-	
-	data_blob_free(&dce_conn->auth_state.auth_info->credentials);
-
 	return True;
 }



More information about the samba-cvs mailing list