import sys
import os
+import time
sys.path.insert(0, "bin/python")
os.environ["PYTHONUNBUFFERED"] = "1"
import samba.dcerpc.mgmt
import samba.dcerpc.netlogon
import struct
-from samba.credentials import Credentials
from samba import gensec
-from samba.tests import RawDCERPCTest
+from samba.tests.dcerpc.raw_testcase import RawDCERPCTest
global_ndr_print = False
global_hexdump = False
dcerpc.DCERPC_PFC_FLAG_FIRST |
dcerpc.DCERPC_PFC_FLAG_LAST)
- # TODO: doesn't announce DCERPC_PFC_FLAG_CONC_MPX
- # by default
- def _test_no_auth_request_bind_pfc_CONC_MPX(self):
+ def test_no_auth_request_bind_pfc_CONC_MPX(self):
return self._test_no_auth_request_bind_pfc_flags(
req_pfc_flags=0 |
dcerpc.DCERPC_PFC_FLAG_CONC_MPX |
self.assertIsNone(rep)
self.assertNotConnected()
- def _test_auth_none_level_bind(self, auth_level,
+ def test_no_auth_bind_time_keep_on_orphan_simple(self):
+ features = dcerpc.DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN
+ btf = base.bind_time_features_syntax(features)
+
+ zero_syntax = misc.ndr_syntax_id()
+
+ tsf1_list = [btf]
+ ctx1 = dcerpc.ctx_list()
+ ctx1.context_id = 1
+ ctx1.num_transfer_syntaxes = len(tsf1_list)
+ ctx1.abstract_syntax = zero_syntax
+ ctx1.transfer_syntaxes = tsf1_list
+
+ req = self.generate_bind(call_id=0, ctx_list=[ctx1])
+ self.send_pdu(req)
+ rep = self.recv_pdu()
+ self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id,
+ auth_length=0)
+ 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_NEGOTIATE_ACK)
+ self.assertEquals(rep.u.ctx_list[0].reason, features)
+ self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, zero_syntax)
+ self.assertEquals(rep.u.auth_info, '\0' * 0)
+
+ def test_no_auth_bind_time_keep_on_orphan_ignore_additional(self):
+ features1 = dcerpc.DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN
+ btf1 = base.bind_time_features_syntax(features1)
+
+ features2 = dcerpc.DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING
+ btf2 = base.bind_time_features_syntax(features2)
+
+ zero_syntax = misc.ndr_syntax_id()
+ ndr64 = base.transfer_syntax_ndr64()
+
+ tsf1_list = [btf1,btf2,zero_syntax]
+ ctx1 = dcerpc.ctx_list()
+ ctx1.context_id = 1
+ ctx1.num_transfer_syntaxes = len(tsf1_list)
+ ctx1.abstract_syntax = ndr64
+ ctx1.transfer_syntaxes = tsf1_list
+
+ req = self.generate_bind(call_id=0, ctx_list=[ctx1])
+ self.send_pdu(req)
+ rep = self.recv_pdu()
+ self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id,
+ auth_length=0)
+ 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_NEGOTIATE_ACK)
+ self.assertEquals(rep.u.ctx_list[0].reason, features1)
+ self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, zero_syntax)
+ self.assertEquals(rep.u.auth_info, '\0' * 0)
+
+ def _test_auth_type_level_bind_nak(self, auth_type, auth_level, creds=None,
reason=dcerpc.DCERPC_BIND_NAK_REASON_INVALID_AUTH_TYPE):
ndr32 = base.transfer_syntax_ndr()
ctx1.transfer_syntaxes = tsf1_list
ctx_list = [ctx1]
- auth_type = dcerpc.DCERPC_AUTH_TYPE_NONE
auth_context_id = 0
- auth_info = self.generate_auth(auth_type=auth_type,
- auth_level=auth_level,
- auth_context_id=auth_context_id,
- auth_blob="none")
+ if creds is not None:
+ # We always start with DCERPC_AUTH_LEVEL_INTEGRITY
+ auth_context = self.get_auth_context_creds(creds,
+ auth_type=auth_type,
+ auth_level=auth_level,
+ auth_context_id=auth_context_id,
+ g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY)
+ from_server = ""
+ (finished, to_server) = auth_context["gensec"].update(from_server)
+ self.assertFalse(finished)
+
+ auth_info = self.generate_auth(auth_type=auth_context["auth_type"],
+ auth_level=auth_context["auth_level"],
+ auth_context_id=auth_context["auth_context_id"],
+ auth_blob=to_server)
+ else:
+ to_server = "none"
+ 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,
self.assertIsNone(rep)
self.assertNotConnected()
+ def _test_auth_none_level_bind(self, auth_level,
+ reason=dcerpc.DCERPC_BIND_NAK_REASON_INVALID_AUTH_TYPE):
+ return self._test_auth_type_level_bind_nak(auth_type=dcerpc.DCERPC_AUTH_LEVEL_NONE,
+ auth_level=auth_level, reason=reason)
+
def test_auth_none_none_bind(self):
return self._test_auth_none_level_bind(dcerpc.DCERPC_AUTH_LEVEL_NONE,
reason=dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED)
def _get_netlogon_ctx(self):
abstract = samba.dcerpc.netlogon.abstract_syntax()
- self.epmap_reconnect(abstract)
-
ndr32 = base.transfer_syntax_ndr()
- tsf1_list = [ndr32]
- ctx = dcerpc.ctx_list()
- ctx.context_id = 0
- ctx.num_transfer_syntaxes = len(tsf1_list)
- ctx.abstract_syntax = abstract
- ctx.transfer_syntaxes = tsf1_list
-
- req = self.generate_bind(call_id=0,
- ctx_list=[ctx])
- self.send_pdu(req)
- rep = self.recv_pdu()
- self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id,
- auth_length=0)
- 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)
- port_str = "%d" % self.tcp_port
- port_len = len(port_str) + 1
- mod_len = (2 + port_len) % 4
- if mod_len != 0:
- port_pad = 4 - mod_len
- else:
- port_pad = 0
- self.assertEquals(rep.u.secondary_address_size, port_len)
- self.assertEquals(rep.u.secondary_address, port_str)
- self.assertEquals(len(rep.u._pad1), port_pad)
- self.assertEquals(rep.u._pad1, '\0' * port_pad)
- 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.assertEquals(rep.u.auth_info, '\0' * 0)
+ (ctx, ack) = self.prepare_presentation(abstract, ndr32, context_id=0,
+ epmap=True, return_ack=True)
- server = '\\\\' + self.host
+ server = '\\\\' + self.target_hostname
server_utf16 = unicode(server, 'utf-8').encode('utf-16-le')
computer = 'UNKNOWNCOMPUTER'
computer_utf16 = unicode(computer, 'utf-8').encode('utf-16-le')
real_stub += computer_utf16 + '\x00\x00'
real_stub += '\x11\x22\x33\x44\x55\x66\x77\x88'
- return (ctx, rep, real_stub)
+ return (ctx, ack, real_stub)
def _test_fragmented_requests(self, remaining=None, alloc_hint=None,
fault_first=None, fault_last=None):
# And now try a request without auth_info
# netr_ServerReqChallenge()
- req = self.generate_request(call_id = 2,
+ req = self.generate_request(call_id = 0x21234,
pfc_flags=pfc_flags,
context_id=ctx.context_id,
opnum=4,
self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, 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.context_id, 0)
self.assertEquals(rep.u.cancel_count, 0)
self.assertEquals(rep.u.flags, 0)
self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR)
# netr_ServerReqChallenge with given flags
req = self.generate_request(call_id = 2,
pfc_flags=dcerpc.DCERPC_PFC_FLAG_FIRST |
- dcerpc.DCERPC_PFC_FLAG_PENDING_CANCEL,
+ dcerpc.DCERPC_PFC_FLAG_PENDING_CANCEL,
context_id=ctx.context_id,
opnum=4,
stub=real_stub)
dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
auth_length=0)
self.assertNotEquals(rep.u.alloc_hint, 0)
- self.assertEquals(rep.u.context_id, req.u.context_id)
+ self.assertEquals(rep.u.context_id, 0)
self.assertEquals(rep.u.cancel_count, 0)
self.assertEquals(rep.u.flags, 0)
self.assertEquals(rep.u.status, dcerpc.DCERPC_FAULT_NO_CALL_ACTIVE)
self.assertEquals(rep.u.reserved, 0)
self.assertEquals(len(rep.u.error_and_verifier), 0)
- def test_spnego_connect_request(self):
+ def test_co_cancel_no_request(self):
ndr32 = base.transfer_syntax_ndr()
+ abstract = samba.dcerpc.mgmt.abstract_syntax()
+ ctx = self.prepare_presentation(abstract, ndr32, context_id=0xff)
- 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 = self.generate_co_cancel(call_id = 3)
+ self.send_pdu(req)
+ rep = self.recv_pdu(timeout=0.01)
+ self.assertIsNone(rep)
+ self.assertIsConnected()
+ # And now try a request
+ req = self.generate_request(call_id = 1,
+ context_id=ctx.context_id,
+ opnum=0,
+ stub="")
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)
+ 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)
- req = self.generate_alter(call_id=0,
- ctx_list=ctx_list,
- assoc_group_id=rep.u.assoc_group_id,
- auth_info=auth_info)
+ def test_co_cancel_request_after_first(self):
+ ndr32 = base.transfer_syntax_ndr()
+ abstract = samba.dcerpc.mgmt.abstract_syntax()
+ ctx = self.prepare_presentation(abstract, ndr32, context_id=0xff)
+ req = self.generate_request(call_id = 1,
+ pfc_flags=dcerpc.DCERPC_PFC_FLAG_FIRST,
+ context_id=ctx.context_id,
+ opnum=0,
+ stub="")
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)
+ rep = self.recv_pdu(timeout=0.01)
+ self.assertIsNone(rep)
+ self.assertIsConnected()
- from_server = a.credentials
- (finished, to_server) = g.update(from_server)
- self.assertTrue(finished)
+ req = self.generate_co_cancel(call_id = 1)
+ self.send_pdu(req)
+ rep = self.recv_pdu(timeout=0.01)
+ self.assertIsNone(rep)
+ self.assertIsConnected()
- # And now try a request without auth_info
- req = self.generate_request(call_id = 2,
- context_id=ctx1.context_id,
+ req = self.generate_request(call_id = 1,
+ pfc_flags=dcerpc.DCERPC_PFC_FLAG_LAST,
+ context_id=ctx.context_id,
opnum=0,
stub="")
self.send_pdu(req)
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,
+ # And now try a request
+ req = self.generate_request(call_id = 2,
+ context_id=ctx.context_id,
opnum=0,
- stub="",
- auth_info=auth_info)
+ stub="")
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.cancel_count, 0)
self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
- # Now a request with auth_info DCERPC_AUTH_LEVEL_INTEGRITY
- auth_info = self.generate_auth(auth_type=auth_type,
- auth_level=dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY,
- auth_context_id=auth_context_id,
- auth_blob="\x01"+"\x00"*15)
- req = self.generate_request(call_id = 4,
- context_id=ctx1.context_id,
+ def test_orphaned_no_request(self):
+ ndr32 = base.transfer_syntax_ndr()
+ abstract = samba.dcerpc.mgmt.abstract_syntax()
+ ctx = self.prepare_presentation(abstract, ndr32)
+
+ req = self.generate_orphaned(call_id = 3)
+ self.send_pdu(req)
+ rep = self.recv_pdu(timeout=0.01)
+ self.assertIsNone(rep)
+ self.assertIsConnected()
+
+ # And now try a request
+ req = self.generate_request(call_id = 1,
+ context_id=ctx.context_id,
opnum=0,
- stub="",
- auth_info=auth_info)
+ stub="")
self.send_pdu(req)
rep = self.recv_pdu()
- # We get a fault back
- self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
+ 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.context_id, req.u.context_id & 0xff)
self.assertEquals(rep.u.cancel_count, 0)
- self.assertEquals(rep.u.flags, 0)
- self.assertEquals(rep.u.status, dcerpc.DCERPC_FAULT_ACCESS_DENIED)
- self.assertEquals(rep.u.reserved, 0)
- self.assertEquals(len(rep.u.error_and_verifier), 0)
+ self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
+
+ def test_orphaned_request_after_first_last(self):
+ ndr32 = base.transfer_syntax_ndr()
+ abstract = samba.dcerpc.mgmt.abstract_syntax()
+ ctx = self.prepare_presentation(abstract, ndr32)
+
+ req = self.generate_request(call_id = 1,
+ pfc_flags=dcerpc.DCERPC_PFC_FLAG_FIRST,
+ context_id=ctx.context_id,
+ opnum=0,
+ stub="")
+ self.send_pdu(req)
+ rep = self.recv_pdu(timeout=0.1)
+ self.assertIsNone(rep)
+ self.assertIsConnected()
+
+ req = self.generate_orphaned(call_id = 1)
+ self.send_pdu(req)
+ rep = self.recv_pdu(timeout=0.1)
+ self.assertIsNone(rep)
+ self.assertIsConnected()
+
+ req = self.generate_request(call_id = 1,
+ pfc_flags=dcerpc.DCERPC_PFC_FLAG_LAST,
+ context_id=ctx.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 & 0xff)
+ self.assertEquals(rep.u.cancel_count, 0)
+ self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
+
+ # And now try a request
+ req = self.generate_request(call_id = 2,
+ context_id=ctx.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 & 0xff)
+ self.assertEquals(rep.u.cancel_count, 0)
+ self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
+
+ def test_orphaned_request_after_first_mpx_last(self):
+ ndr32 = base.transfer_syntax_ndr()
+ abstract = samba.dcerpc.mgmt.abstract_syntax()
+
+ pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST
+ pfc_flags |= samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST
+ pfc_flags |= samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_CONC_MPX
+ ctx = self.prepare_presentation(abstract, ndr32, pfc_flags=pfc_flags)
+
+ req = self.generate_request(call_id = 1,
+ pfc_flags=dcerpc.DCERPC_PFC_FLAG_FIRST,
+ context_id=ctx.context_id,
+ opnum=0,
+ stub="")
+ self.send_pdu(req)
+ rep = self.recv_pdu(timeout=0.1)
+ self.assertIsNone(rep)
+ self.assertIsConnected()
+
+ req = self.generate_orphaned(call_id = 1)
+ self.send_pdu(req)
+ rep = self.recv_pdu(timeout=0.1)
+ self.assertIsNone(rep)
+ self.assertIsConnected()
+
+ req = self.generate_request(call_id = 1,
+ pfc_flags=dcerpc.DCERPC_PFC_FLAG_LAST,
+ context_id=ctx.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 & 0xff)
+ self.assertEquals(rep.u.cancel_count, 0)
+ self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
+
+ # And now try a request
+ req = self.generate_request(call_id = 2,
+ context_id=ctx.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 & 0xff)
+ self.assertEquals(rep.u.cancel_count, 0)
+ self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
+
+ def test_orphaned_request_after_first_no_last(self):
+ ndr32 = base.transfer_syntax_ndr()
+ abstract = samba.dcerpc.mgmt.abstract_syntax()
+ ctx = self.prepare_presentation(abstract, ndr32)
+
+ req1 = self.generate_request(call_id = 1,
+ pfc_flags=dcerpc.DCERPC_PFC_FLAG_FIRST,
+ context_id=ctx.context_id,
+ opnum=0,
+ stub="")
+ self.send_pdu(req1)
+ rep = self.recv_pdu(timeout=0.1)
+ self.assertIsNone(rep)
+ self.assertIsConnected()
+
+ req = self.generate_orphaned(call_id = 1)
+ self.send_pdu(req)
+ rep = self.recv_pdu(timeout=0.1)
+ self.assertIsNone(rep)
+ self.assertIsConnected()
+
+ # And now try a new request
+ req2 = self.generate_request(call_id = 2,
+ context_id=ctx.context_id,
+ opnum=0,
+ stub="")
+ self.send_pdu(req2)
+ rep = self.recv_pdu()
+ self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req1.call_id,
+ auth_length=0)
+ self.assertNotEquals(rep.u.alloc_hint, 0)
+ self.assertEquals(rep.u.context_id, req1.u.context_id)
+ self.assertEquals(rep.u.cancel_count, 0)
+ self.assertEquals(rep.u.flags, 0)
+ self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR)
+ self.assertEquals(rep.u.reserved, 0)
+ self.assertEquals(len(rep.u.error_and_verifier), 0)
+
+ # wait for a disconnect
+ rep = self.recv_pdu()
+ self.assertIsNone(rep)
+ self.assertNotConnected()
+
+ def test_orphaned_request_after_first_mpx_no_last(self):
+ ndr32 = base.transfer_syntax_ndr()
+ abstract = samba.dcerpc.mgmt.abstract_syntax()
+
+ pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST
+ pfc_flags |= samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST
+ pfc_flags |= samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_CONC_MPX
+ ctx = self.prepare_presentation(abstract, ndr32,
+ pfc_flags=pfc_flags)
+
+ req1 = self.generate_request(call_id = 1,
+ pfc_flags=dcerpc.DCERPC_PFC_FLAG_FIRST,
+ context_id=ctx.context_id,
+ opnum=0,
+ stub="")
+ self.send_pdu(req1)
+ rep = self.recv_pdu(timeout=0.1)
+ self.assertIsNone(rep)
+ self.assertIsConnected()
+
+ req = self.generate_orphaned(call_id = 1)
+ self.send_pdu(req)
+ rep = self.recv_pdu(timeout=0.1)
+ self.assertIsNone(rep)
+ self.assertIsConnected()
+
+ # And now try a new request
+ req2 = self.generate_request(call_id = 2,
+ context_id=ctx.context_id-1,
+ opnum=0,
+ stub="")
+ self.send_pdu(req2)
+ rep = self.recv_pdu()
+ self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req2.call_id,
+ 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.flags, 0)
+ self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR)
+ self.assertEquals(rep.u.reserved, 0)
+ self.assertEquals(len(rep.u.error_and_verifier), 0)
+
+ # wait for a disconnect
+ rep = self.recv_pdu()
+ self.assertIsNone(rep)
+ self.assertNotConnected()
+
+ def test_spnego_connect_request(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 = self.get_anon_creds()
+ 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)
+
+ 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)
+
+ 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 & 0xff)
+ 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 & 0xff)
+ 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_INTEGRITY
+ auth_info = self.generate_auth(auth_type=auth_type,
+ auth_level=dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY,
+ auth_context_id=auth_context_id,
+ auth_blob="\x01"+"\x00"*15)
+ req = self.generate_request(call_id = 4,
+ context_id=ctx1.context_id,
+ opnum=0,
+ stub="",
+ auth_info=auth_info)
+ self.send_pdu(req)
+ rep = self.recv_pdu()
+ # We get a fault back
+ self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, 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.assertEquals(rep.u.flags, 0)
+ self.assertEquals(rep.u.status, dcerpc.DCERPC_FAULT_ACCESS_DENIED)
+ self.assertEquals(rep.u.reserved, 0)
+ self.assertEquals(len(rep.u.error_and_verifier), 0)
# wait for a disconnect
rep = self.recv_pdu()
ctx1.transfer_syntaxes = tsf1_list
ctx_list = [ctx1]
- c = Credentials()
- c.set_anonymous()
+ c = self.get_anon_creds()
g = gensec.Security.start_client(self.settings)
g.set_credentials(c)
g.want_feature(gensec.FEATURE_DCE_STYLE)
ctx1.transfer_syntaxes = tsf1_list
ctx_list = [ctx1]
- c = Credentials()
- c.set_anonymous()
+ c = self.get_anon_creds()
g = gensec.Security.start_client(self.settings)
g.set_credentials(c)
g.want_feature(gensec.FEATURE_DCE_STYLE)
ctx1.transfer_syntaxes = tsf1_list
ctx_list = [ctx1]
- c = Credentials()
- c.set_anonymous()
+ c = self.get_anon_creds()
g = gensec.Security.start_client(self.settings)
g.set_credentials(c)
g.want_feature(gensec.FEATURE_DCE_STYLE)
ctx1.transfer_syntaxes = tsf1_list
ctx_list = [ctx1]
- c = Credentials()
- c.set_anonymous()
+ c = self.get_anon_creds()
g = gensec.Security.start_client(self.settings)
g.set_credentials(c)
g.want_feature(gensec.FEATURE_DCE_STYLE)
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.context_id, req.u.context_id & 0xff)
self.assertEquals(rep.u.cancel_count, 0)
self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
ctx1.transfer_syntaxes = tsf1_list
ctx_list = [ctx1]
- c = Credentials()
- c.set_anonymous()
+ c = self.get_anon_creds()
g = gensec.Security.start_client(self.settings)
g.set_credentials(c)
g.want_feature(gensec.FEATURE_DCE_STYLE)
ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
ctx1.transfer_syntaxes = tsf1_list
- c = Credentials()
- c.set_anonymous()
+ c = self.get_anon_creds()
g = gensec.Security.start_client(self.settings)
g.set_credentials(c)
g.want_feature(gensec.FEATURE_DCE_STYLE)
ctx1b.abstract_syntax = samba.dcerpc.epmapper.abstract_syntax()
ctx1b.transfer_syntaxes = tsf1_list
- c = Credentials()
- c.set_anonymous()
+ c = self.get_anon_creds()
g = gensec.Security.start_client(self.settings)
g.set_credentials(c)
g.want_feature(gensec.FEATURE_DCE_STYLE)
ctx1b.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
ctx1b.transfer_syntaxes = tsf1b_list
- c = Credentials()
- c.set_anonymous()
+ c = self.get_anon_creds()
g = gensec.Security.start_client(self.settings)
g.set_credentials(c)
g.want_feature(gensec.FEATURE_DCE_STYLE)
ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
ctx1.transfer_syntaxes = tsf1_list
- c = Credentials()
- c.set_anonymous()
+ c = self.get_anon_creds()
g = gensec.Security.start_client(self.settings)
g.set_credentials(c)
g.want_feature(gensec.FEATURE_DCE_STYLE)
ctx1b.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
ctx1b.transfer_syntaxes = tsf1b_list
- c = Credentials()
- c.set_anonymous()
+ c = self.get_anon_creds()
g = gensec.Security.start_client(self.settings)
g.set_credentials(c)
g.want_feature(gensec.FEATURE_DCE_STYLE)
ctx1b.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
ctx1b.transfer_syntaxes = tsf1b_list
- c = Credentials()
- c.set_anonymous()
+ c = self.get_anon_creds()
g = gensec.Security.start_client(self.settings)
g.set_credentials(c)
g.want_feature(gensec.FEATURE_DCE_STYLE)
ctx1.transfer_syntaxes = tsf1_list
ctx_list = [ctx1]
- c = Credentials()
- c.set_anonymous()
+ c = self.get_anon_creds()
g = gensec.Security.start_client(self.settings)
g.set_credentials(c)
g.want_feature(gensec.FEATURE_DCE_STYLE)
ctx1.transfer_syntaxes = tsf1_list
ctx_list = [ctx1]
- c = Credentials()
- c.set_anonymous()
+ c = self.get_anon_creds()
g = gensec.Security.start_client(self.settings)
g.set_credentials(c)
g.want_feature(gensec.FEATURE_DCE_STYLE)
ctx1.transfer_syntaxes = tsf1_list
ctx_list = [ctx1]
- c = Credentials()
- c.set_anonymous()
+ c = self.get_anon_creds()
g = gensec.Security.start_client(self.settings)
g.set_credentials(c)
g.want_feature(gensec.FEATURE_DCE_STYLE)
ctx1.transfer_syntaxes = tsf1_list
ctx_list = [ctx1]
- c = Credentials()
- c.set_anonymous()
+ c = self.get_anon_creds()
g = gensec.Security.start_client(self.settings)
g.set_credentials(c)
g.want_feature(gensec.FEATURE_DCE_STYLE)
ctx1.transfer_syntaxes = tsf1_list
ctx_list = [ctx1]
- c = Credentials()
- c.set_anonymous()
+ c = self.get_anon_creds()
g = gensec.Security.start_client(self.settings)
g.set_credentials(c)
g.want_feature(gensec.FEATURE_DCE_STYLE)
self.assertIsNone(rep)
self.assertNotConnected()
+ def _test_spnego_bind_auth_level(self, auth_level, auth_context_id, ctx,
+ g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY,
+ alter_fault=None):
+ creds = self.get_user_creds()
+ auth_context = self.get_auth_context_creds(creds=creds,
+ auth_type=dcerpc.DCERPC_AUTH_TYPE_SPNEGO,
+ auth_level=auth_level,
+ auth_context_id=auth_context_id,
+ g_auth_level=g_auth_level)
+ if auth_context is None:
+ return None
+ ack = self.do_generic_bind(ctx=ctx,
+ auth_context=auth_context,
+ alter_fault=alter_fault)
+ if ack is None:
+ return None
+ return auth_context["gensec"]
+
+ def _test_spnego_level_bind_nak(self, auth_level,
+ reason=dcerpc.DCERPC_BIND_NAK_REASON_INVALID_CHECKSUM):
+ c = self.get_user_creds()
+ return self._test_auth_type_level_bind_nak(auth_type=dcerpc.DCERPC_AUTH_TYPE_SPNEGO,
+ auth_level=auth_level, creds=c, reason=reason)
+
+ def _test_spnego_level_bind(self, auth_level,
+ g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY,
+ alter_fault=None,
+ request_fault=None,
+ response_fault_flags=0):
+ ndr32 = base.transfer_syntax_ndr()
+
+ tsf1_list = [ndr32]
+ ctx1 = dcerpc.ctx_list()
+ ctx1.context_id = 0x1001
+ ctx1.num_transfer_syntaxes = len(tsf1_list)
+ ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
+ ctx1.transfer_syntaxes = tsf1_list
+
+ auth_type = dcerpc.DCERPC_AUTH_TYPE_SPNEGO
+ auth_context_id = 2
+
+ g = self._test_spnego_bind_auth_level(auth_level=auth_level,
+ auth_context_id=auth_context_id,
+ ctx=ctx1,
+ g_auth_level=g_auth_level,
+ alter_fault=alter_fault)
+
+ if request_fault is None:
+ return
+
+ self.assertIsNotNone(g)
+
+ stub_bin = '\x00' * 17
+ mod_len = len(stub_bin) % dcerpc.DCERPC_AUTH_PAD_ALIGNMENT
+ auth_pad_length = 0
+ if mod_len > 0:
+ auth_pad_length = dcerpc.DCERPC_AUTH_PAD_ALIGNMENT - mod_len
+ stub_bin += '\x00' * auth_pad_length
+
+ if g_auth_level >= dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY:
+ sig_size = g.sig_size(len(stub_bin))
+ else:
+ sig_size = 16
+ zero_sig = "\x00"*sig_size
+
+ auth_info = self.generate_auth(auth_type=auth_type,
+ auth_level=auth_level,
+ auth_pad_length=auth_pad_length,
+ auth_context_id=auth_context_id,
+ auth_blob=zero_sig)
+ req = self.generate_request(call_id = 4,
+ context_id=ctx1.context_id,
+ opnum=0xffff,
+ stub=stub_bin,
+ auth_info=auth_info)
+ if g_auth_level >= dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY:
+ req_blob = samba.ndr.ndr_pack(req)
+ ofs_stub = dcerpc.DCERPC_REQUEST_LENGTH
+ ofs_sig = len(req_blob) - req.auth_length
+ ofs_trailer = ofs_sig - dcerpc.DCERPC_AUTH_TRAILER_LENGTH
+ req_data = req_blob[ofs_stub:ofs_trailer]
+ req_whole = req_blob[0:ofs_sig]
+ sig = g.sign_packet(req_data, req_whole)
+ auth_info = self.generate_auth(auth_type=auth_type,
+ auth_level=auth_level,
+ auth_pad_length=auth_pad_length,
+ auth_context_id=auth_context_id,
+ auth_blob=sig)
+ req = self.generate_request(call_id = 4,
+ context_id=ctx1.context_id,
+ opnum=0xffff,
+ stub=stub_bin,
+ 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 | response_fault_flags,
+ auth_length=0)
+ self.assertNotEquals(rep.u.alloc_hint, 0)
+ self.assertEquals(rep.u.context_id, ctx1.context_id)
+ self.assertEquals(rep.u.cancel_count, 0)
+ self.assertEquals(rep.u.flags, 0)
+ self.assertEquals(rep.u.status, request_fault)
+ self.assertEquals(rep.u.reserved, 0)
+ self.assertEquals(len(rep.u.error_and_verifier), 0)
+
+ if response_fault_flags & dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE:
+ return
+
+ # wait for a disconnect
+ rep = self.recv_pdu()
+ self.assertIsNone(rep)
+ self.assertNotConnected()
+
+ def test_spnego_none_bind(self):
+ return self._test_spnego_level_bind_nak(dcerpc.DCERPC_AUTH_LEVEL_NONE,
+ reason=dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED)
+
+ def test_spnego_call_bind(self):
+ return self._test_spnego_level_bind_nak(dcerpc.DCERPC_AUTH_LEVEL_CALL,
+ reason=dcerpc.DCERPC_BIND_NAK_REASON_INVALID_CHECKSUM)
+
+ def test_spnego_0_bind(self):
+ return self._test_spnego_level_bind_nak(0,
+ reason=dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED)
+
+ def test_spnego_7_bind(self):
+ return self._test_spnego_level_bind_nak(7,
+ reason=dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED)
+
+ def test_spnego_255_bind(self):
+ return self._test_spnego_level_bind_nak(255,
+ reason=dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED)
+
+ def test_spnego_connect_bind_none(self):
+ return self._test_spnego_level_bind(auth_level=dcerpc.DCERPC_AUTH_LEVEL_CONNECT,
+ g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_CONNECT)
+
+ def test_spnego_connect_bind_sign(self):
+ return self._test_spnego_level_bind(auth_level=dcerpc.DCERPC_AUTH_LEVEL_CONNECT,
+ g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY)
+
+ def test_spnego_connect_bind_seal(self):
+ return self._test_spnego_level_bind(auth_level=dcerpc.DCERPC_AUTH_LEVEL_CONNECT,
+ g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_PRIVACY)
+
+ def test_spnego_packet_bind_none(self):
+ # DCERPC_AUTH_LEVEL_PACKET is handled as alias of
+ # DCERPC_AUTH_LEVEL_INTEGRITY
+ return self._test_spnego_level_bind(auth_level=dcerpc.DCERPC_AUTH_LEVEL_PACKET,
+ g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_CONNECT,
+ request_fault=dcerpc.DCERPC_FAULT_SEC_PKG_ERROR)
+
+ def test_spnego_packet_bind_sign(self):
+ # DCERPC_AUTH_LEVEL_PACKET is handled as alias of
+ # DCERPC_AUTH_LEVEL_INTEGRITY
+ return self._test_spnego_level_bind(auth_level=dcerpc.DCERPC_AUTH_LEVEL_PACKET,
+ g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY,
+ request_fault=dcerpc.DCERPC_NCA_S_OP_RNG_ERROR,
+ response_fault_flags=dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE)
+
+ def test_spnego_packet_bind_sign(self):
+ # DCERPC_AUTH_LEVEL_PACKET is handled as alias of
+ # DCERPC_AUTH_LEVEL_INTEGRITY
+ return self._test_spnego_level_bind(auth_level=dcerpc.DCERPC_AUTH_LEVEL_PACKET,
+ g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_PRIVACY,
+ request_fault=dcerpc.DCERPC_NCA_S_OP_RNG_ERROR,
+ response_fault_flags=dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE)
+
+ def test_spnego_integrity_bind_none(self):
+ return self._test_spnego_level_bind(auth_level=dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY,
+ g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_CONNECT,
+ request_fault=dcerpc.DCERPC_FAULT_SEC_PKG_ERROR)
+
+ def test_spnego_integrity_bind_sign(self):
+ return self._test_spnego_level_bind(auth_level=dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY,
+ g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY,
+ request_fault=dcerpc.DCERPC_NCA_S_OP_RNG_ERROR,
+ response_fault_flags=dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE)
+
+ def test_spnego_integrity_bind_seal(self):
+ return self._test_spnego_level_bind(auth_level=dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY,
+ g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_PRIVACY,
+ request_fault=dcerpc.DCERPC_NCA_S_OP_RNG_ERROR,
+ response_fault_flags=dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE)
+
+ def test_spnego_privacy_bind_none(self):
+ # This fails...
+ return self._test_spnego_level_bind(auth_level=dcerpc.DCERPC_AUTH_LEVEL_PRIVACY,
+ g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_CONNECT,
+ alter_fault=dcerpc.DCERPC_FAULT_SEC_PKG_ERROR)
+
+ def test_spnego_privacy_bind_sign(self):
+ # This fails...
+ return self._test_spnego_level_bind(auth_level=dcerpc.DCERPC_AUTH_LEVEL_PRIVACY,
+ g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY,
+ alter_fault=dcerpc.DCERPC_FAULT_SEC_PKG_ERROR)
+
+ def test_spnego_privacy_bind_seal(self):
+ return self._test_spnego_level_bind(auth_level=dcerpc.DCERPC_AUTH_LEVEL_PRIVACY,
+ g_auth_level=dcerpc.DCERPC_AUTH_LEVEL_PRIVACY)
+
+
+
+ def _test_spnego_signing_auth_level_request(self, auth_level):
+ ndr32 = base.transfer_syntax_ndr()
+
+ tsf1_list = [ndr32]
+ ctx1 = dcerpc.ctx_list()
+ ctx1.context_id = 0x1001
+ ctx1.num_transfer_syntaxes = len(tsf1_list)
+ ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
+ ctx1.transfer_syntaxes = tsf1_list
+ ctx_list = [ctx1]
+
+ auth_type = dcerpc.DCERPC_AUTH_TYPE_SPNEGO
+ auth_context_id = 2
+
+ g = self._test_spnego_bind_auth_level(auth_level=auth_level,
+ auth_context_id=auth_context_id,
+ ctx=ctx1)
+
+ stub_bin = '\x00' * 0
+ mod_len = len(stub_bin) % dcerpc.DCERPC_AUTH_PAD_ALIGNMENT
+ auth_pad_length = 0
+ if mod_len > 0:
+ auth_pad_length = dcerpc.DCERPC_AUTH_PAD_ALIGNMENT - mod_len
+ stub_bin += '\x00' * auth_pad_length
+
+ sig_size = g.sig_size(len(stub_bin))
+ zero_sig = "\x00"*sig_size
+
+ auth_info = self.generate_auth(auth_type=auth_type,
+ auth_level=auth_level,
+ auth_pad_length=auth_pad_length,
+ auth_context_id=auth_context_id,
+ auth_blob=zero_sig)
+ req = self.generate_request(call_id = 3,
+ context_id=ctx1.context_id,
+ opnum=0,
+ stub=stub_bin,
+ auth_info=auth_info)
+ req_blob = samba.ndr.ndr_pack(req)
+ ofs_stub = dcerpc.DCERPC_REQUEST_LENGTH
+ ofs_sig = len(req_blob) - req.auth_length
+ ofs_trailer = ofs_sig - dcerpc.DCERPC_AUTH_TRAILER_LENGTH
+ req_data = req_blob[ofs_stub:ofs_trailer]
+ req_whole = req_blob[0:ofs_sig]
+ sig = g.sign_packet(req_data, req_whole)
+ auth_info = self.generate_auth(auth_type=auth_type,
+ auth_level=auth_level,
+ auth_pad_length=auth_pad_length,
+ auth_context_id=auth_context_id,
+ auth_blob=sig)
+ req = self.generate_request(call_id = 3,
+ context_id=ctx1.context_id,
+ opnum=0,
+ stub=stub_bin,
+ auth_info=auth_info)
+ self.send_pdu(req)
+ (rep, rep_blob) = self.recv_pdu_raw()
+ self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
+ auth_length=sig_size)
+ self.assertNotEquals(rep.u.alloc_hint, 0)
+ self.assertEquals(rep.u.context_id, req.u.context_id & 0xff)
+ self.assertEquals(rep.u.cancel_count, 0)
+ self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
+ self.assertEquals(rep.auth_length, sig_size)
+
+ ofs_stub = dcerpc.DCERPC_REQUEST_LENGTH
+ ofs_sig = rep.frag_length - rep.auth_length
+ ofs_trailer = ofs_sig - dcerpc.DCERPC_AUTH_TRAILER_LENGTH
+ rep_data = rep_blob[ofs_stub:ofs_trailer]
+ rep_whole = rep_blob[0:ofs_sig]
+ rep_sig = rep_blob[ofs_sig:]
+ rep_auth_info_blob = rep_blob[ofs_trailer:]
+
+ rep_auth_info = self.parse_auth(rep_auth_info_blob)
+ self.assertEquals(rep_auth_info.auth_type, auth_type)
+ self.assertEquals(rep_auth_info.auth_level, auth_level)
+ # mgmt_inq_if_ids() returns no fixed size results
+ #self.assertEquals(rep_auth_info.auth_pad_length, 0)
+ self.assertEquals(rep_auth_info.auth_reserved, 0)
+ self.assertEquals(rep_auth_info.auth_context_id, auth_context_id)
+ self.assertEquals(rep_auth_info.credentials, rep_sig)
+
+ g.check_packet(rep_data, rep_whole, rep_sig)
+
+ stub_bin = '\x00' * 17
+ mod_len = len(stub_bin) % dcerpc.DCERPC_AUTH_PAD_ALIGNMENT
+ auth_pad_length = 0
+ if mod_len > 0:
+ auth_pad_length = dcerpc.DCERPC_AUTH_PAD_ALIGNMENT - mod_len
+ stub_bin += '\x00' * auth_pad_length
+
+ sig_size = g.sig_size(len(stub_bin))
+ zero_sig = "\x00"*sig_size
+
+ auth_info = self.generate_auth(auth_type=auth_type,
+ auth_level=auth_level,
+ auth_pad_length=auth_pad_length,
+ auth_context_id=auth_context_id,
+ auth_blob=zero_sig)
+ req = self.generate_request(call_id = 4,
+ context_id=ctx1.context_id,
+ opnum=0xffff,
+ stub=stub_bin,
+ auth_info=auth_info)
+ req_blob = samba.ndr.ndr_pack(req)
+ ofs_stub = dcerpc.DCERPC_REQUEST_LENGTH
+ ofs_sig = len(req_blob) - req.auth_length
+ ofs_trailer = ofs_sig - dcerpc.DCERPC_AUTH_TRAILER_LENGTH
+ req_data = req_blob[ofs_stub:ofs_trailer]
+ req_whole = req_blob[0:ofs_sig]
+ sig = g.sign_packet(req_data, req_whole)
+ auth_info = self.generate_auth(auth_type=auth_type,
+ auth_level=auth_level,
+ auth_pad_length=auth_pad_length,
+ auth_context_id=auth_context_id,
+ auth_blob=sig)
+ req = self.generate_request(call_id = 4,
+ context_id=ctx1.context_id,
+ opnum=0xffff,
+ stub=stub_bin,
+ 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, ctx1.context_id)
+ self.assertEquals(rep.u.cancel_count, 0)
+ self.assertEquals(rep.u.flags, 0)
+ self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_OP_RNG_ERROR)
+ self.assertEquals(rep.u.reserved, 0)
+ self.assertEquals(len(rep.u.error_and_verifier), 0)
+
+ stub_bin = '\x00' * 8
+ mod_len = len(stub_bin) % dcerpc.DCERPC_AUTH_PAD_ALIGNMENT
+ auth_pad_length = 0
+ if mod_len > 0:
+ auth_pad_length = dcerpc.DCERPC_AUTH_PAD_ALIGNMENT - mod_len
+ stub_bin += '\x00' * auth_pad_length
+
+ sig_size = g.sig_size(len(stub_bin))
+ zero_sig = "\x00"*sig_size
+
+ auth_info = self.generate_auth(auth_type=auth_type,
+ auth_level=auth_level,
+ auth_pad_length=auth_pad_length,
+ auth_context_id=auth_context_id,
+ auth_blob=zero_sig)
+ req = self.generate_request(call_id = 5,
+ context_id=ctx1.context_id,
+ opnum=1,
+ stub=stub_bin,
+ auth_info=auth_info)
+ req_blob = samba.ndr.ndr_pack(req)
+ ofs_stub = dcerpc.DCERPC_REQUEST_LENGTH
+ ofs_sig = len(req_blob) - req.auth_length
+ ofs_trailer = ofs_sig - dcerpc.DCERPC_AUTH_TRAILER_LENGTH
+ req_data = req_blob[ofs_stub:ofs_trailer]
+ req_whole = req_blob[0:ofs_sig]
+ sig = g.sign_packet(req_data, req_whole)
+ auth_info = self.generate_auth(auth_type=auth_type,
+ auth_level=auth_level,
+ auth_pad_length=auth_pad_length,
+ auth_context_id=auth_context_id,
+ auth_blob=sig)
+ req = self.generate_request(call_id = 5,
+ context_id=ctx1.context_id,
+ opnum=1,
+ stub=stub_bin,
+ auth_info=auth_info)
+ self.send_pdu(req)
+ (rep, rep_blob) = self.recv_pdu_raw()
+ self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
+ auth_length=sig_size)
+ self.assertNotEquals(rep.u.alloc_hint, 0)
+ self.assertEquals(rep.u.context_id, req.u.context_id & 0xff)
+ self.assertEquals(rep.u.cancel_count, 0)
+ self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
+ self.assertEquals(rep.auth_length, sig_size)
+
+ ofs_stub = dcerpc.DCERPC_REQUEST_LENGTH
+ ofs_sig = rep.frag_length - rep.auth_length
+ ofs_trailer = ofs_sig - dcerpc.DCERPC_AUTH_TRAILER_LENGTH
+ rep_data = rep_blob[ofs_stub:ofs_trailer]
+ rep_whole = rep_blob[0:ofs_sig]
+ rep_sig = rep_blob[ofs_sig:]
+ rep_auth_info_blob = rep_blob[ofs_trailer:]
+
+ rep_auth_info = self.parse_auth(rep_auth_info_blob)
+ self.assertEquals(rep_auth_info.auth_type, auth_type)
+ self.assertEquals(rep_auth_info.auth_level, auth_level)
+ self.assertEquals(rep_auth_info.auth_pad_length, 4)
+ self.assertEquals(rep_auth_info.auth_reserved, 0)
+ self.assertEquals(rep_auth_info.auth_context_id, auth_context_id)
+ self.assertEquals(rep_auth_info.credentials, rep_sig)
+
+ g.check_packet(rep_data, rep_whole, rep_sig)
+
+ stub_bin = '\x00' * 8
+ mod_len = len(stub_bin) % dcerpc.DCERPC_AUTH_PAD_ALIGNMENT
+ auth_pad_length = 0
+ if mod_len > 0:
+ auth_pad_length = dcerpc.DCERPC_AUTH_PAD_ALIGNMENT - mod_len
+ stub_bin += '\x00' * auth_pad_length
+
+ sig_size = g.sig_size(len(stub_bin))
+ zero_sig = "\x00"*sig_size
+
+ auth_info = self.generate_auth(auth_type=auth_type,
+ auth_level=auth_level,
+ auth_pad_length=auth_pad_length,
+ auth_context_id=auth_context_id,
+ auth_blob=zero_sig)
+ req = self.generate_request(call_id = 6,
+ context_id=ctx1.context_id,
+ opnum=3,
+ stub=stub_bin,
+ auth_info=auth_info)
+ req_blob = samba.ndr.ndr_pack(req)
+ ofs_stub = dcerpc.DCERPC_REQUEST_LENGTH
+ ofs_sig = len(req_blob) - req.auth_length
+ ofs_trailer = ofs_sig - dcerpc.DCERPC_AUTH_TRAILER_LENGTH
+ req_data = req_blob[ofs_stub:ofs_trailer]
+ req_whole = req_blob[0:ofs_sig]
+ sig = g.sign_packet(req_data, req_whole)
+ auth_info = self.generate_auth(auth_type=auth_type,
+ auth_level=auth_level,
+ auth_pad_length=auth_pad_length,
+ auth_context_id=auth_context_id,
+ auth_blob=sig)
+ req = self.generate_request(call_id = 6,
+ context_id=ctx1.context_id,
+ opnum=3,
+ stub=stub_bin,
+ auth_info=auth_info)
+ self.send_pdu(req)
+ (rep, rep_blob) = self.recv_pdu_raw()
+ self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
+ auth_length=sig_size)
+ self.assertNotEquals(rep.u.alloc_hint, 0)
+ self.assertEquals(rep.u.context_id, req.u.context_id & 0xff)
+ self.assertEquals(rep.u.cancel_count, 0)
+ self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
+ self.assertEquals(rep.auth_length, sig_size)
+
+ ofs_stub = dcerpc.DCERPC_REQUEST_LENGTH
+ ofs_sig = rep.frag_length - rep.auth_length
+ ofs_trailer = ofs_sig - dcerpc.DCERPC_AUTH_TRAILER_LENGTH
+ rep_data = rep_blob[ofs_stub:ofs_trailer]
+ rep_whole = rep_blob[0:ofs_sig]
+ rep_sig = rep_blob[ofs_sig:]
+ rep_auth_info_blob = rep_blob[ofs_trailer:]
+
+ rep_auth_info = self.parse_auth(rep_auth_info_blob)
+ self.assertEquals(rep_auth_info.auth_type, auth_type)
+ self.assertEquals(rep_auth_info.auth_level, auth_level)
+ self.assertEquals(rep_auth_info.auth_pad_length, 12)
+ self.assertEquals(rep_auth_info.auth_reserved, 0)
+ self.assertEquals(rep_auth_info.auth_context_id, auth_context_id)
+ self.assertEquals(rep_auth_info.credentials, rep_sig)
+
+ g.check_packet(rep_data, rep_whole, rep_sig)
+
+ def test_spnego_signing_packet(self):
+ # DCERPC_AUTH_LEVEL_PACKET is handled as alias of
+ # DCERPC_AUTH_LEVEL_INTEGRITY
+ return self._test_spnego_signing_auth_level_request(dcerpc.DCERPC_AUTH_LEVEL_PACKET)
+
+ def test_spnego_signing_integrity(self):
+ return self._test_spnego_signing_auth_level_request(dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY)
+
+
+ def test_assoc_group_fail1(self):
+ abstract = samba.dcerpc.mgmt.abstract_syntax()
+ transfer = base.transfer_syntax_ndr()
+
+ tsf1_list = [transfer]
+ ctx = samba.dcerpc.dcerpc.ctx_list()
+ ctx.context_id = 1
+ ctx.num_transfer_syntaxes = len(tsf1_list)
+ ctx.abstract_syntax = abstract
+ ctx.transfer_syntaxes = tsf1_list
+
+ ack = self.do_generic_bind(ctx=ctx, assoc_group_id=1,
+ nak_reason=dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED)
+ return
+
+ def test_assoc_group_fail2(self):
+ abstract = samba.dcerpc.mgmt.abstract_syntax()
+ transfer = base.transfer_syntax_ndr()
+
+ tsf1_list = [transfer]
+ ctx = samba.dcerpc.dcerpc.ctx_list()
+ ctx.context_id = 1
+ ctx.num_transfer_syntaxes = len(tsf1_list)
+ ctx.abstract_syntax = abstract
+ ctx.transfer_syntaxes = tsf1_list
+
+ ack = self.do_generic_bind(ctx=ctx)
+
+ self._disconnect("test_assoc_group_fail2")
+ self.assertNotConnected()
+ time.sleep(0.5)
+ self.connect()
+
+ ack2 = self.do_generic_bind(ctx=ctx,assoc_group_id=ack.u.assoc_group_id,
+ nak_reason=dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED)
+ return
+
+ def test_assoc_group_diff1(self):
+ abstract = samba.dcerpc.mgmt.abstract_syntax()
+ transfer = base.transfer_syntax_ndr()
+
+ (ctx1, ack1) = self.prepare_presentation(abstract, transfer,
+ context_id=1, return_ack=True)
+
+ conn2 = self.second_connection()
+ (ctx2, ack2) = conn2.prepare_presentation(abstract, transfer,
+ context_id=2, return_ack=True)
+ self.assertNotEqual(ack2.u.assoc_group_id, ack1.u.assoc_group_id)
+
+ return
+
+ def test_assoc_group_ok1(self):
+ abstract = samba.dcerpc.mgmt.abstract_syntax()
+ transfer = base.transfer_syntax_ndr()
+
+ (ctx1, ack1) = self.prepare_presentation(abstract, transfer,
+ context_id=1, return_ack=True)
+
+ conn2 = self.second_connection()
+ (ctx2, ack2) = conn2.prepare_presentation(abstract, transfer,
+ assoc_group_id=ack1.u.assoc_group_id,
+ context_id=2, return_ack=True)
+
+ inq_if_ids = samba.dcerpc.mgmt.inq_if_ids()
+ self.do_single_request(call_id = 1, ctx=ctx1, io=inq_if_ids)
+ conn2.do_single_request(call_id = 1, ctx=ctx2, io=inq_if_ids)
+
+ conn2.do_single_request(call_id = 1, ctx=ctx1, io=inq_if_ids,
+ fault_pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST |
+ samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST |
+ samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
+ fault_status=dcerpc.DCERPC_NCA_S_UNKNOWN_IF,
+ fault_context_id=0)
+
+ self.do_single_request(call_id = 1, ctx=ctx1, io=inq_if_ids)
+ conn2.do_single_request(call_id = 1, ctx=ctx2, io=inq_if_ids)
+ return
+
if __name__ == "__main__":
global_ndr_print = True
global_hexdump = True