The branch, v4-2-test has been updated via 67859d0 python/tests: add auth_pad test for the dcerpc raw_protocol test via 00b06bc s4:rpc_server: generate the correct error when we got an invalid auth_pad_length on BIND,ALTER,AUTH3 via 90c2a94 librpc/rpc: ignore invalid auth_pad_length values in BIND, ALTER and AUTH3 pdus via 30b5b9f librpc/rpc: let dcerpc_pull_auth_trailer() check that auth_pad_length fits within the whole pdu. via 93e8b4e librpc/rpc: let dcerpc_pull_auth_trailer() only accept auth_length!=NULL or auth_data_only=true via d950d0f s4:librpc/rpc: don't ask for auth_length if we ask for auth data only via 7d76653 s4:rpc_server: parse auth data only for BIND,ALTER_REQ,AUTH3 from 996ee07 VERSION: Bump version up to 4.2.15...
https://git.samba.org/?p=samba.git;a=shortlog;h=v4-2-test - Log ----------------------------------------------------------------- commit 67859d0f316aaf62ef662d9b9ff80381a07bfed8 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Jun 23 12:06:40 2016 +0200 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 <me...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> Autobuild-User(master): Stefan Metzmacher <me...@samba.org> Autobuild-Date(master): Fri Jun 24 18:08:44 CEST 2016 on sn-devel-144 (cherry picked from commit c49f9abb19adca999d0b1d897d00d91f0ad91bbd) Autobuild-User(v4-2-test): Karolin Seeger <ksee...@samba.org> Autobuild-Date(v4-2-test): Thu Aug 4 13:43:46 CEST 2016 on sn-devel-104 commit 00b06bccde173d8b9613d34c1f3e9c4e4788ca12 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Jun 23 13:50:39 2016 +0200 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 <me...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> (cherry picked from commit 7d8edcc24148658e92729b3d155e432994e27525) commit 90c2a94b9686d86457d74767310b4b72f90d8c82 Author: Stefan Metzmacher <me...@samba.org> Date: Mon Jun 20 16:26:56 2016 +0200 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 <me...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> (cherry picked from commit aef032302863e5f3a888dbf4c52b21d561a0dff4) commit 30b5b9fd97ee68d0c78f1f820b552afa33f065f4 Author: Stefan Metzmacher <me...@samba.org> Date: Mon Jun 20 16:25:12 2016 +0200 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 <me...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> (cherry picked from commit 3f7e3ed8a276f16aaed87c1f3cd5b9781aa7e1af) commit 93e8b4e0f9d59a04551df47b438f5ebd55f568a5 Author: Stefan Metzmacher <me...@samba.org> Date: Mon Jun 20 16:17:45 2016 +0200 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 <me...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> (cherry picked from commit f386e81b982cd551313eb9c0f7d2f70d65515d80) commit d950d0f6b50b93ef8b96490c7f353336c161f12d Author: Stefan Metzmacher <me...@samba.org> Date: Mon Jun 20 16:16:23 2016 +0200 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 <me...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> (cherry picked from commit e05c732c6074df2524403ad7bb30eade91443525) commit 7d7665355029bd8079e258623776708a70ec32e8 Author: Stefan Metzmacher <me...@samba.org> Date: Mon Jun 20 16:11:37 2016 +0200 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 <me...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> (cherry picked from commit 505a4e68d96e6fb3d8c7493632ecb4b0fc6caa9d) ----------------------------------------------------------------------- Summary of changes: librpc/rpc/dcerpc_util.c | 61 ++++ python/samba/tests/dcerpc/raw_protocol.py | 548 ++++++++++++++++++++++++++++++ source4/librpc/rpc/dcerpc.c | 8 +- source4/rpc_server/dcerpc_server.c | 13 +- source4/rpc_server/dcesrv_auth.c | 27 +- 5 files changed, 642 insertions(+), 15 deletions(-) Changeset truncated at 500 lines: diff --git a/librpc/rpc/dcerpc_util.c b/librpc/rpc/dcerpc_util.c index 43e1b7f..df14948 100644 --- a/librpc/rpc/dcerpc_util.c +++ b/librpc/rpc/dcerpc_util.c @@ -95,10 +95,19 @@ 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) { *_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... */ @@ -149,6 +158,58 @@ 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; + } + + /* + * 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", 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) -- Samba Shared Repository