]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
tests/dcerpc/raw_protocol: test invalid schannel binds
authorStefan Metzmacher <metze@samba.org>
Thu, 12 Nov 2020 10:10:46 +0000 (11:10 +0100)
committerJule Anger <janger@samba.org>
Thu, 7 Nov 2024 08:18:16 +0000 (08:18 +0000)
Note the ad_member will keep these as expected failures,
as it doesn't provide the netlogon service,
while the knownfail for the ADDC is only temporary.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit f7a3827010a859839a3ae7d0cdf297a15610d286)

python/samba/tests/dcerpc/raw_protocol.py
selftest/expectedfail.d/ntlm-auth
selftest/knownfail.d/dcerpc-auth-pad

index 0cc26cf4d5623cec04d36c6bbdba1f849a916dda..815db6d01d13d99ecf2532c01ddc295b553b2dc6 100755 (executable)
@@ -30,6 +30,7 @@ import samba.dcerpc.epmapper
 import samba.dcerpc.mgmt
 import samba.dcerpc.netlogon
 import samba.dcerpc.lsa
+import samba.dcerpc.schannel as schannel
 import struct
 from samba import gensec
 from samba.tests.dcerpc.raw_testcase import RawDCERPCTest
@@ -53,6 +54,7 @@ class TestDCERPC_BIND(RawDCERPCTest):
     @classmethod
     def setUpDynamicTestCases(cls):
         cls._setup_auth_pad_ignored()
+        cls._setup_test_schannel_invalid()
         return
 
     def _test_no_auth_request_bind_pfc_flags(self, req_pfc_flags, rep_pfc_flags):
@@ -8647,6 +8649,156 @@ class TestDCERPC_BIND(RawDCERPCTest):
         self.assertNotConnected()
         return
 
+    def _test_schannel_invalid_with_args(self,
+                                         pktype,
+                                         tail_padding):
+
+        ndr32 = base.transfer_syntax_ndr()
+        lsarpc_syntax = samba.dcerpc.lsa.abstract_syntax()
+
+        self.epmap_reconnect(lsarpc_syntax)
+
+        if pktype == dcerpc.DCERPC_PKT_AUTH3:
+             max_auth_length=4096
+             max_xmit_frag=self.max_xmit_frag
+        else:
+             max_auth_length=0xffff
+             max_xmit_frag=0xffff
+
+        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]
+
+        auth_type = dcerpc.DCERPC_AUTH_TYPE_SCHANNEL
+        auth_level = dcerpc.DCERPC_AUTH_LEVEL_PRIVACY
+        auth_context_id = 1
+
+        nl_auth = schannel.NL_AUTH_MESSAGE()
+        nl_auth.MessageType = schannel.NL_NEGOTIATE_REQUEST
+        nl_auth.Flags = 0
+
+        nl_auth.Flags |= schannel.NL_FLAG_OEM_NETBIOS_DOMAIN_NAME
+        nl_auth.oem_netbios_domain = "NBDOMAIN"
+
+        nl_auth.Flags |= schannel.NL_FLAG_OEM_NETBIOS_COMPUTER_NAME
+        nl_auth.oem_netbios_computer = "RAWCOMPUTER"
+
+        nl_auth.Flags |= schannel.NL_FLAG_UTF8_DNS_DOMAIN_NAME
+        nl_auth.utf8_dns_domain = "DNS.DOMAIN"
+
+        nl_auth.Flags |= schannel.NL_FLAG_UTF8_NETBIOS_COMPUTER_NAME
+        nl_auth.utf8_netbios_computer = "RAWCOMPUTER"
+
+        to_server = samba.ndr.ndr_pack(nl_auth)
+
+        auth_info = self.generate_auth(auth_type=auth_type,
+                                       auth_level=auth_level,
+                                       auth_context_id=auth_context_id,
+                                       auth_blob=to_server)
+
+        if pktype != dcerpc.DCERPC_PKT_BIND:
+            req = self.generate_bind(call_id=1,
+                                     ctx_list=ctx_list)
+            self.send_pdu(req)
+            rep = self.recv_pdu()
+            self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id,
+                            auth_length=0)
+            self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag)
+            self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag)
+            self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id)
+            sda_str = self.secondary_address
+            sda_len = len(sda_str) + 1
+            mod_len = (2 + sda_len) % 4
+            if mod_len != 0:
+                sda_pad = 4 - mod_len
+            else:
+                sda_pad = 0
+            self.assertEqual(rep.u.secondary_address_size, sda_len)
+            self.assertEqual(rep.u.secondary_address, sda_str)
+            self.assertPadding(rep.u._pad1, sda_pad)
+            self.assertEqual(rep.u.num_results, 1)
+            self.assertEqual(rep.u.ctx_list[0].result,
+                              dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
+            self.assertEqual(rep.u.ctx_list[0].reason,
+                              dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
+            self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
+
+            if pktype == dcerpc.DCERPC_PKT_AUTH3:
+                req = self.generate_auth3(call_id=2,
+                                          auth_info=auth_info)
+                expected_fault = dcerpc.DCERPC_NCA_S_PROTO_ERROR
+            else:
+                req = self.generate_alter(call_id=2,
+                                          ctx_list=ctx_list,
+                                          auth_info=auth_info)
+                expected_fault = dcerpc.DCERPC_FAULT_ACCESS_DENIED
+        else:
+            req = self.generate_bind(call_id=1,
+                                     ctx_list=ctx_list,
+                                     auth_info=auth_info)
+        req_pdu = self._add_auth_padding(req,
+                                         tail_padding=tail_padding,
+                                         max_auth_length=max_auth_length,
+                                         max_xmit_frag=max_xmit_frag)
+        self.send_pdu_blob(req_pdu)
+        rep = self.recv_pdu()
+        if pktype != dcerpc.DCERPC_PKT_BIND:
+            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.assertNotEqual(rep.u.alloc_hint, 0)
+            self.assertEqual(rep.u.context_id, 0)
+            self.assertEqual(rep.u.cancel_count, 0)
+            self.assertEqual(rep.u.flags, 0)
+            self.assertEqual(rep.u.status, expected_fault)
+            self.assertEqual(rep.u.reserved, 0)
+            self.assertEqual(len(rep.u.error_and_verifier), 0)
+        else:
+            self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_NAK, req.call_id,
+                            auth_length=0)
+            self.assertEqual(rep.u.reject_reason,
+                             dcerpc.DCERPC_BIND_NAK_REASON_INVALID_CHECKSUM)
+            self.assertEqual(rep.u.num_versions, 1)
+            self.assertEqual(rep.u.versions[0].rpc_vers, req.rpc_vers)
+            self.assertEqual(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor)
+            self.assertPadding(rep.u._pad, 3)
+
+        # wait for a disconnect
+        rep = self.recv_pdu()
+        self.assertIsNone(rep)
+        self.assertNotConnected()
+
+    @classmethod
+    def _setup_test_schannel_invalid(cls):
+        pktype_methods = {
+            "bind": dcerpc.DCERPC_PKT_BIND,
+            "alter": dcerpc.DCERPC_PKT_ALTER,
+            "auth3": dcerpc.DCERPC_PKT_AUTH3,
+        }
+        paddings = {
+            "no_padding": False,
+            "tail_padding": True,
+        }
+
+        for pktype_method in pktype_methods.keys():
+            for padding in paddings.keys():
+                tname = "%s_%s" % (
+                    pktype_method,
+                    padding,
+                )
+                targs = (
+                    pktype_methods[pktype_method],
+                    paddings[padding],
+                )
+                cls.generate_dynamic_test("test_schannel_invalid",
+                                          tname, *targs)
+        return
+
 
 if __name__ == "__main__":
     global_ndr_print = True
index f4cfd64583342160b1a7e118ea4d03fd18c47625..46561dcdaa3639ce6a6add8d9e43d853867e75dc 100644 (file)
@@ -19,3 +19,7 @@
 ^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_last_only_requests\(ad_member\)
 ^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_mix_requests\(ad_member\)
 ^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_none_only_requests\(ad_member\)
+^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_schannel_invalid_alter_no_padding\(ad_member\)
+^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_schannel_invalid_alter_tail_padding\(ad_member\)
+^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_schannel_invalid_auth3_no_padding\(ad_member\)
+^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_schannel_invalid_auth3_tail_padding\(ad_member\)
index add136710e04a9034eba7f61f2e0714a5944f545..dd407ab54593fc71d6be24383e75a69eb1dd9b14 100644 (file)
@@ -18,3 +18,7 @@
 ^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_auth_tail_pad_spnego_alter
 ^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_auth_tail_pad_spnego_auth3
 ^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_spnego_integrity_bind_auth_align2
+^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_schannel_invalid_alter_no_padding.*chgdcpass
+^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_schannel_invalid_alter_tail_padding.*chgdcpass
+^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_schannel_invalid_bind_no_padding.*chgdcpass
+^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_schannel_invalid_bind_tail_padding.*chgdcpass