The Samba-Bugzilla – Attachment 12209 Details for
Bug 11982
Invalid auth_pad_length is not ignored for BIND_* and ALTER_* pdus
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patches for v4-4-test
tmp44.diff.txt (text/plain), 38.43 KB, created by
Stefan Metzmacher
on 2016-06-26 19:22:52 UTC
(
hide
)
Description:
Patches for v4-4-test
Filename:
MIME Type:
Creator:
Stefan Metzmacher
Created:
2016-06-26 19:22:52 UTC
Size:
38.43 KB
patch
obsolete
>From bf1ee4f36fd71b019e0c3a34e4fcbae446f8fe86 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 20 Jun 2016 16:11:37 +0200 >Subject: [PATCH 1/7] s4:rpc_server: parse auth data only for > BIND,ALTER_REQ,AUTH3 > >We should tell dcerpc_pull_auth_trailer() that we only want >auth data. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11982 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit 505a4e68d96e6fb3d8c7493632ecb4b0fc6caa9d) >--- > source4/rpc_server/dcesrv_auth.c | 9 +++------ > 1 file changed, 3 insertions(+), 6 deletions(-) > >diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c >index 2b3f8b0..802876b 100644 >--- a/source4/rpc_server/dcesrv_auth.c >+++ b/source4/rpc_server/dcesrv_auth.c >@@ -44,7 +44,6 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) > struct dcesrv_connection *dce_conn = call->conn; > struct dcesrv_auth *auth = &dce_conn->auth_state; > NTSTATUS status; >- uint32_t auth_length; > > if (pkt->auth_length == 0) { > auth->auth_type = DCERPC_AUTH_TYPE_NONE; >@@ -55,7 +54,7 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) > > status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.bind.auth_info, > &call->in_auth_info, >- &auth_length, false); >+ NULL, true); > if (!NT_STATUS_IS_OK(status)) { > return false; > } >@@ -241,7 +240,6 @@ bool dcesrv_auth_auth3(struct dcesrv_call_state *call) > struct ncacn_packet *pkt = &call->pkt; > struct dcesrv_connection *dce_conn = call->conn; > NTSTATUS status; >- uint32_t auth_length; > > if (pkt->auth_length == 0) { > return false; >@@ -257,7 +255,7 @@ bool dcesrv_auth_auth3(struct dcesrv_call_state *call) > } > > status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.auth3.auth_info, >- &call->in_auth_info, &auth_length, true); >+ &call->in_auth_info, NULL, true); > if (!NT_STATUS_IS_OK(status)) { > return false; > } >@@ -324,7 +322,6 @@ bool dcesrv_auth_alter(struct dcesrv_call_state *call) > struct ncacn_packet *pkt = &call->pkt; > struct dcesrv_connection *dce_conn = call->conn; > NTSTATUS status; >- uint32_t auth_length; > > /* on a pure interface change there is no auth blob */ > if (pkt->auth_length == 0) { >@@ -344,7 +341,7 @@ bool dcesrv_auth_alter(struct dcesrv_call_state *call) > } > > status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.alter.auth_info, >- &call->in_auth_info, &auth_length, true); >+ &call->in_auth_info, NULL, true); > if (!NT_STATUS_IS_OK(status)) { > return false; > } >-- >1.9.1 > > >From b6584d4868a260cdaf57e514a106ced7328e6f87 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 20 Jun 2016 16:16:23 +0200 >Subject: [PATCH 2/7] s4:librpc/rpc: don't ask for auth_length if we ask for > auth data only > >dcerpc_pull_auth_trailer() handles auth_length=NULL just fine. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11982 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit e05c732c6074df2524403ad7bb30eade91443525) >--- > source4/librpc/rpc/dcerpc.c | 8 ++------ > 1 file changed, 2 insertions(+), 6 deletions(-) > >diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c >index 55b4385..479abc0 100644 >--- a/source4/librpc/rpc/dcerpc.c >+++ b/source4/librpc/rpc/dcerpc.c >@@ -1415,12 +1415,10 @@ static void dcerpc_bind_recv_handler(struct rpc_request *subreq, > > /* the bind_ack might contain a reply set of credentials */ > if (pkt->auth_length != 0 && sec->tmp_auth_info.in != NULL) { >- uint32_t auth_length; >- > status = dcerpc_pull_auth_trailer(pkt, sec->tmp_auth_info.mem, > &pkt->u.bind_ack.auth_info, > sec->tmp_auth_info.in, >- &auth_length, true); >+ NULL, true); > if (tevent_req_nterror(req, status)) { > return; > } >@@ -2435,12 +2433,10 @@ static void dcerpc_alter_context_recv_handler(struct rpc_request *subreq, > > /* the alter_resp might contain a reply set of credentials */ > if (pkt->auth_length != 0 && sec->tmp_auth_info.in != NULL) { >- uint32_t auth_length; >- > status = dcerpc_pull_auth_trailer(pkt, sec->tmp_auth_info.mem, > &pkt->u.alter_resp.auth_info, > sec->tmp_auth_info.in, >- &auth_length, true); >+ NULL, true); > if (tevent_req_nterror(req, status)) { > return; > } >-- >1.9.1 > > >From 6be73a03ecd0498e553e3cd5c63f722df0ebf360 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 20 Jun 2016 16:17:45 +0200 >Subject: [PATCH 3/7] librpc/rpc: let dcerpc_pull_auth_trailer() only accept > auth_length!=NULL or auth_data_only=true > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11982 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit f386e81b982cd551313eb9c0f7d2f70d65515d80) >--- > librpc/rpc/dcerpc_util.c | 8 ++++++++ > 1 file changed, 8 insertions(+) > >diff --git a/librpc/rpc/dcerpc_util.c b/librpc/rpc/dcerpc_util.c >index 43e1b7f..4d82e9a5 100644 >--- a/librpc/rpc/dcerpc_util.c >+++ b/librpc/rpc/dcerpc_util.c >@@ -99,6 +99,14 @@ NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt, > ZERO_STRUCTP(auth); > if (_auth_length != NULL) { > *_auth_length = 0; >+ >+ if (auth_data_only) { >+ return NT_STATUS_INTERNAL_ERROR; >+ } >+ } else { >+ if (!auth_data_only) { >+ return NT_STATUS_INTERNAL_ERROR; >+ } > } > > /* Paranoia checks for auth_length. The caller should check this... */ >-- >1.9.1 > > >From 320b8496aeef9fc3f88a07440560b5631e7bb5ee Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 20 Jun 2016 16:25:12 +0200 >Subject: [PATCH 4/7] librpc/rpc: let dcerpc_pull_auth_trailer() check that > auth_pad_length fits within the whole pdu. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11982 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit 3f7e3ed8a276f16aaed87c1f3cd5b9781aa7e1af) >--- > librpc/rpc/dcerpc_util.c | 37 +++++++++++++++++++++++++++++++++++++ > 1 file changed, 37 insertions(+) > >diff --git a/librpc/rpc/dcerpc_util.c b/librpc/rpc/dcerpc_util.c >index 4d82e9a5..ee7b307 100644 >--- a/librpc/rpc/dcerpc_util.c >+++ b/librpc/rpc/dcerpc_util.c >@@ -95,6 +95,7 @@ NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt, > uint16_t data_and_pad; > uint16_t auth_length; > uint32_t tmp_length; >+ uint32_t max_pad_len = 0; > > ZERO_STRUCTP(auth); > if (_auth_length != NULL) { >@@ -157,6 +158,42 @@ NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt, > return ndr_map_error2ntstatus(ndr_err); > } > >+ /* >+ * Make sure the padding would not exceed >+ * the frag_length. >+ * >+ * Here we assume at least 24 bytes for the >+ * payload specific header the value of >+ * DCERPC_{REQUEST,RESPONSE}_LENGTH. >+ * >+ * We use this also for BIND_*, ALTER_* and AUTH3 pdus. >+ * >+ * We need this check before we ignore possible >+ * invalid values. See also bug #11982. >+ * >+ * This check is mainly used to generate the correct >+ * error for BIND_*, ALTER_* and AUTH3 pdus. >+ * >+ * We always have the 'if (data_and_pad < auth->auth_pad_length)' >+ * protection for REQUEST and RESPONSE pdus, where the >+ * auth_pad_length field is actually used by the caller. >+ */ >+ tmp_length = DCERPC_REQUEST_LENGTH; >+ tmp_length += DCERPC_AUTH_TRAILER_LENGTH; >+ tmp_length += pkt->auth_length; >+ if (tmp_length < pkt->frag_length) { >+ max_pad_len = pkt->frag_length - tmp_length; >+ } >+ if (max_pad_len < auth->auth_pad_length) { >+ DEBUG(1, (__location__ ": ERROR: pad length to large. " >+ "max %u got %u\n", >+ (unsigned)max_pad_len, >+ (unsigned)auth->auth_pad_length)); >+ talloc_free(ndr); >+ ZERO_STRUCTP(auth); >+ return NT_STATUS_RPC_PROTOCOL_ERROR; >+ } >+ > if (data_and_pad < auth->auth_pad_length) { > DEBUG(1, (__location__ ": ERROR: pad length mismatch. " > "Calculated %u got %u\n", >-- >1.9.1 > > >From 2db6ef38d137eb78091eb628c2d59099e33ef37a Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 20 Jun 2016 16:26:56 +0200 >Subject: [PATCH 5/7] librpc/rpc: ignore invalid auth_pad_length values in > BIND, ALTER and AUTH3 pdus > >This is a workarround for a bug in old Samba releases. >For BIND_ACK <= 3.5.x and for ALTER_RESP <= 4.2.x (see bug #11061). > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11982 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit aef032302863e5f3a888dbf4c52b21d561a0dff4) >--- > librpc/rpc/dcerpc_util.c | 16 ++++++++++++++++ > 1 file changed, 16 insertions(+) > >diff --git a/librpc/rpc/dcerpc_util.c b/librpc/rpc/dcerpc_util.c >index ee7b307..df14948 100644 >--- a/librpc/rpc/dcerpc_util.c >+++ b/librpc/rpc/dcerpc_util.c >@@ -194,6 +194,22 @@ NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt, > return NT_STATUS_RPC_PROTOCOL_ERROR; > } > >+ /* >+ * This is a workarround for a bug in old >+ * Samba releases. For BIND_ACK <= 3.5.x >+ * and for ALTER_RESP <= 4.2.x (see bug #11061) >+ * >+ * See also bug #11982. >+ */ >+ if (auth_data_only && data_and_pad == 0 && >+ auth->auth_pad_length > 0) { >+ /* >+ * we need to ignore invalid auth_pad_length >+ * values for BIND_*, ALTER_* and AUTH3 pdus. >+ */ >+ auth->auth_pad_length = 0; >+ } >+ > if (data_and_pad < auth->auth_pad_length) { > DEBUG(1, (__location__ ": ERROR: pad length mismatch. " > "Calculated %u got %u\n", >-- >1.9.1 > > >From c833a742a89bb3888eaba47689c324ff193d29e5 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 23 Jun 2016 13:50:39 +0200 >Subject: [PATCH 6/7] s4:rpc_server: generate the correct error when we got an > invalid auth_pad_length on BIND,ALTER,AUTH3 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11982 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit 7d8edcc24148658e92729b3d155e432994e27525) >--- > source4/rpc_server/dcerpc_server.c | 13 ++++++++++--- > source4/rpc_server/dcesrv_auth.c | 18 ++++++++++++++++++ > 2 files changed, 28 insertions(+), 3 deletions(-) > >diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c >index ea29d9d..829d2fe 100644 >--- a/source4/rpc_server/dcerpc_server.c >+++ b/source4/rpc_server/dcerpc_server.c >@@ -804,6 +804,11 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) > > TALLOC_FREE(call->context); > >+ if (call->fault_code == DCERPC_NCA_S_PROTO_ERROR) { >+ return dcesrv_bind_nak(call, >+ DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED); >+ } >+ > if (auth->auth_level != DCERPC_AUTH_LEVEL_NONE) { > /* > * We only give INVALID_AUTH_TYPE if the auth_level was >@@ -936,6 +941,9 @@ static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call) > /* handle the auth3 in the auth code */ > if (!dcesrv_auth_auth3(call)) { > call->conn->auth_state.auth_invalid = true; >+ if (call->fault_code != 0) { >+ return dcesrv_fault_disconnect(call, call->fault_code); >+ } > } > > talloc_free(call); >@@ -1105,9 +1113,8 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) > > auth_ok = dcesrv_auth_alter(call); > if (!auth_ok) { >- if (call->in_auth_info.auth_type == DCERPC_AUTH_TYPE_NONE) { >- return dcesrv_fault_disconnect(call, >- DCERPC_FAULT_ACCESS_DENIED); >+ if (call->fault_code != 0) { >+ return dcesrv_fault_disconnect(call, call->fault_code); > } > } > >diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c >index 802876b..74a62df 100644 >--- a/source4/rpc_server/dcesrv_auth.c >+++ b/source4/rpc_server/dcesrv_auth.c >@@ -56,6 +56,12 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) > &call->in_auth_info, > NULL, true); > if (!NT_STATUS_IS_OK(status)) { >+ /* >+ * This will cause a >+ * DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED >+ * in the caller >+ */ >+ call->fault_code = DCERPC_NCA_S_PROTO_ERROR; > return false; > } > >@@ -257,6 +263,11 @@ bool dcesrv_auth_auth3(struct dcesrv_call_state *call) > status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.auth3.auth_info, > &call->in_auth_info, NULL, true); > if (!NT_STATUS_IS_OK(status)) { >+ /* >+ * Windows returns DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY >+ * instead of DCERPC_NCA_S_PROTO_ERROR. >+ */ >+ call->fault_code = DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY; > return false; > } > >@@ -332,6 +343,7 @@ bool dcesrv_auth_alter(struct dcesrv_call_state *call) > } > > if (dce_conn->auth_state.auth_finished) { >+ call->fault_code = DCERPC_FAULT_ACCESS_DENIED; > return false; > } > >@@ -343,6 +355,12 @@ bool dcesrv_auth_alter(struct dcesrv_call_state *call) > status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.alter.auth_info, > &call->in_auth_info, NULL, true); > if (!NT_STATUS_IS_OK(status)) { >+ call->fault_code = DCERPC_NCA_S_PROTO_ERROR; >+ return false; >+ } >+ >+ if (call->in_auth_info.auth_type == DCERPC_AUTH_TYPE_NONE) { >+ call->fault_code = DCERPC_FAULT_ACCESS_DENIED; > return false; > } > >-- >1.9.1 > > >From 9b56d6ae9fb6dc035bf4746e421a6da636188d7d Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 23 Jun 2016 12:06:40 +0200 >Subject: [PATCH 7/7] python/tests: add auth_pad test for the dcerpc > raw_protocol test > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11982 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> > >Autobuild-User(master): Stefan Metzmacher <metze@samba.org> >Autobuild-Date(master): Fri Jun 24 18:08:44 CEST 2016 on sn-devel-144 > >(cherry picked from commit c49f9abb19adca999d0b1d897d00d91f0ad91bbd) >--- > python/samba/tests/dcerpc/raw_protocol.py | 548 ++++++++++++++++++++++++++++++ > 1 file changed, 548 insertions(+) > >diff --git a/python/samba/tests/dcerpc/raw_protocol.py b/python/samba/tests/dcerpc/raw_protocol.py >index ccd0f6b..8b0bc4e 100755 >--- a/python/samba/tests/dcerpc/raw_protocol.py >+++ b/python/samba/tests/dcerpc/raw_protocol.py >@@ -2616,6 +2616,554 @@ class TestDCERPC_BIND(RawDCERPCTest): > self.assertIsNone(rep) > self.assertNotConnected() > >+ def test_spnego_auth_pad_ok(self): >+ ndr32 = base.transfer_syntax_ndr() >+ >+ tsf1_list = [ndr32] >+ ctx1 = dcerpc.ctx_list() >+ ctx1.context_id = 1 >+ ctx1.num_transfer_syntaxes = len(tsf1_list) >+ ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax() >+ ctx1.transfer_syntaxes = tsf1_list >+ ctx_list = [ctx1] >+ >+ c = Credentials() >+ c.set_anonymous() >+ g = gensec.Security.start_client(self.settings) >+ g.set_credentials(c) >+ g.want_feature(gensec.FEATURE_DCE_STYLE) >+ auth_type = dcerpc.DCERPC_AUTH_TYPE_SPNEGO >+ auth_level = dcerpc.DCERPC_AUTH_LEVEL_CONNECT >+ auth_context_id = 2 >+ g.start_mech_by_authtype(auth_type, auth_level) >+ from_server = "" >+ (finished, to_server) = g.update(from_server) >+ self.assertFalse(finished) >+ >+ auth_info = self.generate_auth(auth_type=auth_type, >+ auth_level=auth_level, >+ auth_context_id=auth_context_id, >+ auth_blob=to_server) >+ >+ req = self.generate_bind(call_id=0, >+ ctx_list=ctx_list, >+ auth_info=auth_info) >+ req_pdu = samba.ndr.ndr_pack(req) >+ >+ auth_pad_ok = len(req_pdu) >+ auth_pad_ok -= dcerpc.DCERPC_REQUEST_LENGTH >+ auth_pad_ok -= dcerpc.DCERPC_AUTH_TRAILER_LENGTH >+ auth_pad_ok -= len(to_server) >+ >+ auth_info = self.generate_auth(auth_type=auth_type, >+ auth_level=auth_level, >+ auth_context_id=auth_context_id, >+ auth_pad_length=auth_pad_ok, >+ auth_blob=to_server) >+ >+ req = self.generate_bind(call_id=0, >+ ctx_list=ctx_list, >+ auth_info=auth_info) >+ self.send_pdu(req) >+ rep = self.recv_pdu() >+ self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id) >+ self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >+ self.assertEquals(rep.u.secondary_address_size, 4) >+ self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEquals(len(rep.u._pad1), 2) >+ #self.assertEquals(rep.u._pad1, '\0' * 2) >+ self.assertEquals(rep.u.num_results, 1) >+ self.assertEquals(rep.u.ctx_list[0].result, >+ dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >+ self.assertEquals(rep.u.ctx_list[0].reason, >+ dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) >+ self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) >+ self.assertNotEquals(len(rep.u.auth_info), 0) >+ a = self.parse_auth(rep.u.auth_info) >+ >+ from_server = a.credentials >+ (finished, to_server) = g.update(from_server) >+ self.assertFalse(finished) >+ >+ auth_info = self.generate_auth(auth_type=auth_type, >+ auth_level=auth_level, >+ auth_context_id=auth_context_id, >+ auth_blob=to_server) >+ req = self.generate_alter(call_id=0, >+ ctx_list=ctx_list, >+ assoc_group_id=rep.u.assoc_group_id, >+ auth_info=auth_info) >+ req_pdu = samba.ndr.ndr_pack(req) >+ >+ auth_pad_ok = len(req_pdu) >+ auth_pad_ok -= dcerpc.DCERPC_REQUEST_LENGTH >+ auth_pad_ok -= dcerpc.DCERPC_AUTH_TRAILER_LENGTH >+ auth_pad_ok -= len(to_server) >+ auth_info = self.generate_auth(auth_type=auth_type, >+ auth_level=auth_level, >+ auth_context_id=auth_context_id, >+ auth_pad_length=auth_pad_ok, >+ auth_blob=to_server) >+ req = self.generate_alter(call_id=0, >+ ctx_list=ctx_list, >+ assoc_group_id=rep.u.assoc_group_id, >+ auth_info=auth_info) >+ self.send_pdu(req) >+ rep = self.recv_pdu() >+ self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id) >+ self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >+ self.assertEquals(rep.u.secondary_address_size, 0) >+ self.assertEquals(len(rep.u._pad1), 2) >+ # Windows sends garbage >+ #self.assertEquals(rep.u._pad1, '\0' * 2) >+ self.assertEquals(rep.u.num_results, 1) >+ self.assertEquals(rep.u.ctx_list[0].result, >+ dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >+ self.assertEquals(rep.u.ctx_list[0].reason, >+ dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) >+ self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) >+ self.assertNotEquals(len(rep.u.auth_info), 0) >+ a = self.parse_auth(rep.u.auth_info) >+ >+ from_server = a.credentials >+ (finished, to_server) = g.update(from_server) >+ self.assertTrue(finished) >+ >+ # And now try a request without auth_info >+ req = self.generate_request(call_id = 2, >+ context_id=ctx1.context_id, >+ opnum=0, >+ stub="") >+ self.send_pdu(req) >+ rep = self.recv_pdu() >+ self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, >+ auth_length=0) >+ self.assertNotEquals(rep.u.alloc_hint, 0) >+ self.assertEquals(rep.u.context_id, req.u.context_id) >+ self.assertEquals(rep.u.cancel_count, 0) >+ self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) >+ >+ # Now a request with auth_info DCERPC_AUTH_LEVEL_CONNECT >+ auth_info = self.generate_auth(auth_type=auth_type, >+ auth_level=auth_level, >+ auth_context_id=auth_context_id, >+ auth_blob="\x01"+"\x00"*15) >+ req = self.generate_request(call_id = 3, >+ context_id=ctx1.context_id, >+ opnum=0, >+ stub="", >+ auth_info=auth_info) >+ self.send_pdu(req) >+ rep = self.recv_pdu() >+ # We don't get an auth_info back >+ self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, >+ auth_length=0) >+ self.assertNotEquals(rep.u.alloc_hint, 0) >+ self.assertEquals(rep.u.context_id, req.u.context_id) >+ self.assertEquals(rep.u.cancel_count, 0) >+ self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) >+ >+ self._disconnect("disconnect") >+ self.assertNotConnected() >+ >+ def test_spnego_auth_pad_fail_bind(self): >+ ndr32 = base.transfer_syntax_ndr() >+ >+ tsf1_list = [ndr32] >+ ctx1 = dcerpc.ctx_list() >+ ctx1.context_id = 1 >+ ctx1.num_transfer_syntaxes = len(tsf1_list) >+ ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax() >+ ctx1.transfer_syntaxes = tsf1_list >+ ctx_list = [ctx1] >+ >+ c = Credentials() >+ c.set_anonymous() >+ g = gensec.Security.start_client(self.settings) >+ g.set_credentials(c) >+ g.want_feature(gensec.FEATURE_DCE_STYLE) >+ auth_type = dcerpc.DCERPC_AUTH_TYPE_SPNEGO >+ auth_level = dcerpc.DCERPC_AUTH_LEVEL_CONNECT >+ auth_context_id = 2 >+ g.start_mech_by_authtype(auth_type, auth_level) >+ from_server = "" >+ (finished, to_server) = g.update(from_server) >+ self.assertFalse(finished) >+ >+ auth_info = self.generate_auth(auth_type=auth_type, >+ auth_level=auth_level, >+ auth_context_id=auth_context_id, >+ auth_blob=to_server) >+ >+ req = self.generate_bind(call_id=0, >+ ctx_list=ctx_list, >+ auth_info=auth_info) >+ req_pdu = samba.ndr.ndr_pack(req) >+ >+ auth_pad_ok = len(req_pdu) >+ auth_pad_ok -= dcerpc.DCERPC_REQUEST_LENGTH >+ auth_pad_ok -= dcerpc.DCERPC_AUTH_TRAILER_LENGTH >+ auth_pad_ok -= len(to_server) >+ auth_pad_bad = auth_pad_ok + 1 >+ auth_info = self.generate_auth(auth_type=auth_type, >+ auth_level=auth_level, >+ auth_context_id=auth_context_id, >+ auth_pad_length=auth_pad_bad, >+ auth_blob=to_server) >+ >+ req = self.generate_bind(call_id=0, >+ ctx_list=ctx_list, >+ auth_info=auth_info) >+ self.send_pdu(req) >+ rep = self.recv_pdu() >+ self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_NAK, req.call_id, >+ auth_length=0) >+ self.assertEquals(rep.u.reject_reason, >+ dcerpc.DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED) >+ self.assertEquals(rep.u.num_versions, 1) >+ self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers) >+ self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) >+ self.assertEquals(len(rep.u._pad), 3) >+ self.assertEquals(rep.u._pad, '\0' * 3) >+ >+ # wait for a disconnect >+ rep = self.recv_pdu() >+ self.assertIsNone(rep) >+ self.assertNotConnected() >+ >+ def test_spnego_auth_pad_fail_alter(self): >+ ndr32 = base.transfer_syntax_ndr() >+ >+ tsf1_list = [ndr32] >+ ctx1 = dcerpc.ctx_list() >+ ctx1.context_id = 1 >+ ctx1.num_transfer_syntaxes = len(tsf1_list) >+ ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax() >+ ctx1.transfer_syntaxes = tsf1_list >+ ctx_list = [ctx1] >+ >+ c = Credentials() >+ c.set_anonymous() >+ g = gensec.Security.start_client(self.settings) >+ g.set_credentials(c) >+ g.want_feature(gensec.FEATURE_DCE_STYLE) >+ auth_type = dcerpc.DCERPC_AUTH_TYPE_SPNEGO >+ auth_level = dcerpc.DCERPC_AUTH_LEVEL_CONNECT >+ auth_context_id = 2 >+ g.start_mech_by_authtype(auth_type, auth_level) >+ from_server = "" >+ (finished, to_server) = g.update(from_server) >+ self.assertFalse(finished) >+ >+ auth_info = self.generate_auth(auth_type=auth_type, >+ auth_level=auth_level, >+ auth_context_id=auth_context_id, >+ auth_blob=to_server) >+ >+ req = self.generate_bind(call_id=0, >+ ctx_list=ctx_list, >+ auth_info=auth_info) >+ req_pdu = samba.ndr.ndr_pack(req) >+ >+ auth_pad_ok = len(req_pdu) >+ auth_pad_ok -= dcerpc.DCERPC_REQUEST_LENGTH >+ auth_pad_ok -= dcerpc.DCERPC_AUTH_TRAILER_LENGTH >+ auth_pad_ok -= len(to_server) >+ >+ auth_info = self.generate_auth(auth_type=auth_type, >+ auth_level=auth_level, >+ auth_context_id=auth_context_id, >+ auth_pad_length=auth_pad_ok, >+ auth_blob=to_server) >+ >+ req = self.generate_bind(call_id=0, >+ ctx_list=ctx_list, >+ auth_info=auth_info) >+ self.send_pdu(req) >+ rep = self.recv_pdu() >+ self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id) >+ self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >+ self.assertEquals(rep.u.secondary_address_size, 4) >+ self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEquals(len(rep.u._pad1), 2) >+ #self.assertEquals(rep.u._pad1, '\0' * 2) >+ self.assertEquals(rep.u.num_results, 1) >+ self.assertEquals(rep.u.ctx_list[0].result, >+ dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >+ self.assertEquals(rep.u.ctx_list[0].reason, >+ dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) >+ self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) >+ self.assertNotEquals(len(rep.u.auth_info), 0) >+ a = self.parse_auth(rep.u.auth_info) >+ >+ from_server = a.credentials >+ (finished, to_server) = g.update(from_server) >+ self.assertFalse(finished) >+ >+ auth_info = self.generate_auth(auth_type=auth_type, >+ auth_level=auth_level, >+ auth_context_id=auth_context_id, >+ auth_blob=to_server) >+ req = self.generate_alter(call_id=0, >+ ctx_list=ctx_list, >+ assoc_group_id=rep.u.assoc_group_id, >+ auth_info=auth_info) >+ req_pdu = samba.ndr.ndr_pack(req) >+ >+ auth_pad_ok = len(req_pdu) >+ auth_pad_ok -= dcerpc.DCERPC_REQUEST_LENGTH >+ auth_pad_ok -= dcerpc.DCERPC_AUTH_TRAILER_LENGTH >+ auth_pad_ok -= len(to_server) >+ auth_pad_bad = auth_pad_ok + 1 >+ auth_info = self.generate_auth(auth_type=auth_type, >+ auth_level=auth_level, >+ auth_context_id=auth_context_id, >+ auth_pad_length=auth_pad_bad, >+ auth_blob=to_server) >+ req = self.generate_alter(call_id=0, >+ ctx_list=ctx_list, >+ assoc_group_id=rep.u.assoc_group_id, >+ auth_info=auth_info) >+ self.send_pdu(req) >+ rep = self.recv_pdu() >+ self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id, >+ pfc_flags=req.pfc_flags | >+ dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE, >+ auth_length=0) >+ self.assertNotEquals(rep.u.alloc_hint, 0) >+ self.assertEquals(rep.u.context_id, 0) >+ self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) >+ self.assertEquals(len(rep.u._pad), 4) >+ self.assertEquals(rep.u._pad, '\0' * 4) >+ >+ # wait for a disconnect >+ rep = self.recv_pdu() >+ self.assertIsNone(rep) >+ self.assertNotConnected() >+ >+ def test_ntlmssp_auth_pad_ok(self): >+ ndr32 = base.transfer_syntax_ndr() >+ >+ tsf1_list = [ndr32] >+ ctx1 = dcerpc.ctx_list() >+ ctx1.context_id = 1 >+ ctx1.num_transfer_syntaxes = len(tsf1_list) >+ ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax() >+ ctx1.transfer_syntaxes = tsf1_list >+ ctx_list = [ctx1] >+ >+ c = Credentials() >+ c.set_anonymous() >+ g = gensec.Security.start_client(self.settings) >+ g.set_credentials(c) >+ g.want_feature(gensec.FEATURE_DCE_STYLE) >+ auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP >+ auth_level = dcerpc.DCERPC_AUTH_LEVEL_CONNECT >+ auth_context_id = 2 >+ g.start_mech_by_authtype(auth_type, auth_level) >+ from_server = "" >+ (finished, to_server) = g.update(from_server) >+ self.assertFalse(finished) >+ >+ auth_info = self.generate_auth(auth_type=auth_type, >+ auth_level=auth_level, >+ auth_context_id=auth_context_id, >+ auth_blob=to_server) >+ >+ req = self.generate_bind(call_id=0, >+ ctx_list=ctx_list, >+ auth_info=auth_info) >+ req_pdu = samba.ndr.ndr_pack(req) >+ >+ auth_pad_ok = len(req_pdu) >+ auth_pad_ok -= dcerpc.DCERPC_REQUEST_LENGTH >+ auth_pad_ok -= dcerpc.DCERPC_AUTH_TRAILER_LENGTH >+ auth_pad_ok -= len(to_server) >+ >+ auth_info = self.generate_auth(auth_type=auth_type, >+ auth_level=auth_level, >+ auth_context_id=auth_context_id, >+ auth_pad_length=auth_pad_ok, >+ auth_blob=to_server) >+ >+ req = self.generate_bind(call_id=0, >+ ctx_list=ctx_list, >+ auth_info=auth_info) >+ self.send_pdu(req) >+ rep = self.recv_pdu() >+ self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id) >+ self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >+ self.assertEquals(rep.u.secondary_address_size, 4) >+ self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEquals(len(rep.u._pad1), 2) >+ #self.assertEquals(rep.u._pad1, '\0' * 2) >+ self.assertEquals(rep.u.num_results, 1) >+ self.assertEquals(rep.u.ctx_list[0].result, >+ dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >+ self.assertEquals(rep.u.ctx_list[0].reason, >+ dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) >+ self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) >+ self.assertNotEquals(len(rep.u.auth_info), 0) >+ a = self.parse_auth(rep.u.auth_info) >+ >+ from_server = a.credentials >+ (finished, to_server) = g.update(from_server) >+ self.assertTrue(finished) >+ >+ auth_pad_ok = 0 >+ auth_info = self.generate_auth(auth_type=auth_type, >+ auth_level=auth_level, >+ auth_context_id=auth_context_id, >+ auth_pad_length=auth_pad_ok, >+ auth_blob=to_server) >+ req = self.generate_auth3(call_id=0, >+ auth_info=auth_info) >+ self.send_pdu(req) >+ self.assertIsConnected() >+ >+ # And now try a request without auth_info >+ req = self.generate_request(call_id = 2, >+ context_id=ctx1.context_id, >+ opnum=0, >+ stub="") >+ self.send_pdu(req) >+ rep = self.recv_pdu() >+ self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, >+ auth_length=0) >+ self.assertNotEquals(rep.u.alloc_hint, 0) >+ self.assertEquals(rep.u.context_id, req.u.context_id) >+ self.assertEquals(rep.u.cancel_count, 0) >+ self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) >+ >+ # Now a request with auth_info DCERPC_AUTH_LEVEL_CONNECT >+ auth_info = self.generate_auth(auth_type=auth_type, >+ auth_level=auth_level, >+ auth_context_id=auth_context_id, >+ auth_blob="\x01"+"\x00"*15) >+ req = self.generate_request(call_id = 3, >+ context_id=ctx1.context_id, >+ opnum=0, >+ stub="", >+ auth_info=auth_info) >+ self.send_pdu(req) >+ rep = self.recv_pdu() >+ # We don't get an auth_info back >+ self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, >+ auth_length=0) >+ self.assertNotEquals(rep.u.alloc_hint, 0) >+ self.assertEquals(rep.u.context_id, req.u.context_id) >+ self.assertEquals(rep.u.cancel_count, 0) >+ self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) >+ >+ self._disconnect("disconnect") >+ self.assertNotConnected() >+ >+ def test_ntlmssp_auth_pad_fail_auth3(self): >+ ndr32 = base.transfer_syntax_ndr() >+ >+ tsf1_list = [ndr32] >+ ctx1 = dcerpc.ctx_list() >+ ctx1.context_id = 1 >+ ctx1.num_transfer_syntaxes = len(tsf1_list) >+ ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax() >+ ctx1.transfer_syntaxes = tsf1_list >+ ctx_list = [ctx1] >+ >+ c = Credentials() >+ c.set_anonymous() >+ g = gensec.Security.start_client(self.settings) >+ g.set_credentials(c) >+ g.want_feature(gensec.FEATURE_DCE_STYLE) >+ auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP >+ auth_level = dcerpc.DCERPC_AUTH_LEVEL_CONNECT >+ auth_context_id = 2 >+ g.start_mech_by_authtype(auth_type, auth_level) >+ from_server = "" >+ (finished, to_server) = g.update(from_server) >+ self.assertFalse(finished) >+ >+ auth_info = self.generate_auth(auth_type=auth_type, >+ auth_level=auth_level, >+ auth_context_id=auth_context_id, >+ auth_blob=to_server) >+ >+ req = self.generate_bind(call_id=0, >+ ctx_list=ctx_list, >+ auth_info=auth_info) >+ req_pdu = samba.ndr.ndr_pack(req) >+ >+ auth_pad_ok = len(req_pdu) >+ auth_pad_ok -= dcerpc.DCERPC_REQUEST_LENGTH >+ auth_pad_ok -= dcerpc.DCERPC_AUTH_TRAILER_LENGTH >+ auth_pad_ok -= len(to_server) >+ >+ auth_info = self.generate_auth(auth_type=auth_type, >+ auth_level=auth_level, >+ auth_context_id=auth_context_id, >+ auth_pad_length=auth_pad_ok, >+ auth_blob=to_server) >+ >+ req = self.generate_bind(call_id=0, >+ ctx_list=ctx_list, >+ auth_info=auth_info) >+ self.send_pdu(req) >+ rep = self.recv_pdu() >+ self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id) >+ self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) >+ self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) >+ self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) >+ self.assertEquals(rep.u.secondary_address_size, 4) >+ self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) >+ self.assertEquals(len(rep.u._pad1), 2) >+ #self.assertEquals(rep.u._pad1, '\0' * 2) >+ self.assertEquals(rep.u.num_results, 1) >+ self.assertEquals(rep.u.ctx_list[0].result, >+ dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) >+ self.assertEquals(rep.u.ctx_list[0].reason, >+ dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) >+ self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) >+ self.assertNotEquals(len(rep.u.auth_info), 0) >+ a = self.parse_auth(rep.u.auth_info) >+ >+ from_server = a.credentials >+ (finished, to_server) = g.update(from_server) >+ self.assertTrue(finished) >+ >+ auth_pad_bad = 1 >+ auth_info = self.generate_auth(auth_type=auth_type, >+ auth_level=auth_level, >+ auth_context_id=auth_context_id, >+ auth_pad_length=auth_pad_bad, >+ auth_blob=to_server) >+ req = self.generate_auth3(call_id=0, >+ auth_info=auth_info) >+ self.send_pdu(req) >+ rep = self.recv_pdu() >+ self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id, >+ pfc_flags=req.pfc_flags | >+ dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE, >+ auth_length=0) >+ self.assertNotEquals(rep.u.alloc_hint, 0) >+ self.assertEquals(rep.u.context_id, 0) >+ self.assertEquals(rep.u.cancel_count, 0) >+ self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY) >+ self.assertEquals(len(rep.u._pad), 4) >+ self.assertEquals(rep.u._pad, '\0' * 4) >+ >+ # wait for a disconnect >+ rep = self.recv_pdu() >+ self.assertIsNone(rep) >+ self.assertNotConnected() >+ > if __name__ == "__main__": > global_ndr_print = True > global_hexdump = True >-- >1.9.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Flags:
gd
:
review+
metze
:
review?
(
abartlet
)
Actions:
View
Attachments on
bug 11982
:
12192
| 12209 |
12211
|
12213
|
12308