From 259129e8f4bc8cacd1850eba3f6551134835d079 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 14 Feb 2010 11:56:28 +1100 Subject: a4-dcerpc: another attempt at dcerpc auth padding The last change broke net vampire against w2k8r2 --- source4/librpc/rpc/dcerpc.c | 19 +++++++++++-------- source4/librpc/rpc/dcerpc_util.c | 8 +++++--- source4/rpc_server/dcesrv_auth.c | 8 ++++---- 3 files changed, 20 insertions(+), 15 deletions(-) (limited to 'source4') diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index e7b181c50b..ccafe070ab 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -318,6 +318,7 @@ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c, size_t payload_length; enum ndr_err_code ndr_err; size_t hdr_size = DCERPC_REQUEST_LENGTH; + uint32_t offset; /* non-signed packets are simpler */ if (sig_size == 0) { @@ -362,17 +363,15 @@ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c, if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return ndr_map_error2ntstatus(ndr_err); } - status = NT_STATUS_OK; /* pad to 16 byte multiple in the payload portion of the packet. This matches what w2k3 does */ - c->security_state.auth_info->auth_pad_length = - (16 - (pkt->u.request.stub_and_verifier.length & 15)) & 15; - ndr_err = ndr_push_zero(ndr, c->security_state.auth_info->auth_pad_length); + offset = ndr->offset; + ndr_err = ndr_push_align(ndr, 16); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return ndr_map_error2ntstatus(ndr_err); } - status = NT_STATUS_OK; + c->security_state.auth_info->auth_pad_length = ndr->offset - offset; payload_length = pkt->u.request.stub_and_verifier.length + c->security_state.auth_info->auth_pad_length; @@ -385,7 +384,6 @@ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c, if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return ndr_map_error2ntstatus(ndr_err); } - status = NT_STATUS_OK; /* extract the whole packet as a blob */ *blob = ndr_push_blob(ndr); @@ -433,12 +431,17 @@ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c, } if (creds2.length != sig_size) { - DEBUG(0,("ncacn_push_request_sign: creds2.length[%u] != sig_size[%u] pad[%u] stub[%u]\n", + /* this means the sig_size estimate for the signature + was incorrect. We have to correct the packet + sizes. That means we could go over the max fragment + length */ + DEBUG(3,("ncacn_push_request_sign: creds2.length[%u] != sig_size[%u] pad[%u] stub[%u]\n", (unsigned) creds2.length, (unsigned) sig_size, (unsigned) c->security_state.auth_info->auth_pad_length, (unsigned) pkt->u.request.stub_and_verifier.length)); - return NT_STATUS_INTERNAL_ERROR; + dcerpc_set_frag_length(blob, blob->length + creds2.length); + dcerpc_set_auth_length(blob, creds2.length); } if (!data_blob_append(mem_ctx, blob, creds2.data, creds2.length)) { diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c index 1985cb9e18..f41236148a 100644 --- a/source4/librpc/rpc/dcerpc_util.c +++ b/source4/librpc/rpc/dcerpc_util.c @@ -52,8 +52,8 @@ const struct ndr_interface_call *dcerpc_iface_find_call(const struct ndr_interfa */ NTSTATUS ncacn_push_auth(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, - struct ncacn_packet *pkt, - struct dcerpc_auth *auth_info) + struct ncacn_packet *pkt, + struct dcerpc_auth *auth_info) { struct ndr_push *ndr; enum ndr_err_code ndr_err; @@ -83,10 +83,12 @@ NTSTATUS ncacn_push_auth(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, } if (auth_info) { - ndr_err = ndr_push_zero(ndr, auth_info->auth_pad_length); + uint32_t offset = ndr->offset; + ndr_err = ndr_push_align(ndr, 16); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return ndr_map_error2ntstatus(ndr_err); } + auth_info->auth_pad_length = ndr->offset - offset; ndr_err = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, auth_info); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return ndr_map_error2ntstatus(ndr_err); diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index d56dd12ac5..4d708e4dff 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -378,7 +378,7 @@ bool dcesrv_auth_response(struct dcesrv_call_state *call, NTSTATUS status; enum ndr_err_code ndr_err; struct ndr_push *ndr; - uint32_t payload_length; + uint32_t payload_length, offset; DATA_BLOB creds2; /* non-signed packets are simple */ @@ -423,12 +423,12 @@ bool dcesrv_auth_response(struct dcesrv_call_state *call, } /* pad to 16 byte multiple, match win2k3 */ - dce_conn->auth_state.auth_info->auth_pad_length = - (16 - (pkt->u.response.stub_and_verifier.length & 15)) & 15; - ndr_err = ndr_push_zero(ndr, dce_conn->auth_state.auth_info->auth_pad_length); + offset = ndr->offset; + ndr_err = ndr_push_align(ndr, 16); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return false; } + dce_conn->auth_state.auth_info->auth_pad_length = ndr->offset - offset; payload_length = pkt->u.response.stub_and_verifier.length + dce_conn->auth_state.auth_info->auth_pad_length; -- cgit