[SCM] Samba Shared Repository - branch master updated
Andrew Bartlett
abartlet at samba.org
Thu Jun 6 03:19:02 UTC 2024
The branch, master has been updated
via ed61c57e023 s4:dns_server: no-op dns updates with ACCESS_DENIED should be ignored
via 76fec2668e7 s4:dns_server: correctly sign dns update responses with gss-tsig like Windows
via db350bc573b s4:dns_server: dns_verify_tsig should return REFUSED on error
via 5906ed94f2c s4:dns_server: also search DNS_QTYPE_TKEY in the answers section if it's the last section
via ae7538af044 s4:dns_server: use tkey->algorithm if available in dns_sign_tsig()
via bd0235cd515 s4:dns_server: use the client provided algorithm for the fake TSIG structure
via 3467d149149 s4:dns_server: only allow gss-tsig and gss.microsoft.com for TSIG
via fa0f23e69ea s4:dns_server: only allow gss-tsig and gss.microsoft.com for TKEY
via a56627b0d12 s4:dns_server: failed dns updates should result in REFUSED for ACCESS_DENIED
via 708a6fae697 python:tests/dns_tkey: add test_update_tsig_record_access_denied()
via 753428a3b6c s4:selftest/tests: pass USERNAME_UNPRIV=$DOMAIN_USER to samba.tests.dns_tkey
via 88457da00d4 python:tests/dns_base: add get_unpriv_creds() helper
via 848318338b2 python:tests/dns_tkey: let test_update_tsig_windows() actually pass against windows 2022
via 8324d0739df python:tests/dns_base: let verify_packet() work against Windows
via de4ed363d37 python:tests/dns_tkey: test bad and changing tsig algorithms
via b9b03ca503c python:tests/dns_tkey: add gss.microsoft.com tsig updates
via 3c7cb85eaf8 python:tests/dns_tkey: let us have test_update_gss_tsig_tkey_req_{additional,answers}()
via 740bda87a80 python:tests/dns_tkey: test TKEY with gss-tsig, gss.microsoft.com and invalid algorithms
via b0af60e7850 python:tests/dns_base: maintain a dict with tkey related state
via 1b1e7e06cf6 python:tests/dns_base: let dns_transaction_udp() take allow_{remaining,truncated}=True
via 27d92fa808c python:tests/dns_base: pass tkey_trans(expected_rcode)
via cd747307d84 python:tests/dns_base: let tkey_trans() take tkey_req_in_answers
via f8dfa9b33bd python:tests/dns_base: let tkey_trans() and sign_packet() take algorithm_name as argument
via 6e997f93d53 python:tests/dns_tkey: make use of self.assert_echoed_dns_error()
via ce591464cb1 python:tests/dns_base: add self.assert_echoed_dns_error()
via c741d0f3969 python:tests/dns_base: let dns_transaction_tcp() handle short receives
via c594cbad4af python:tests/dns_base: use ndr_deepcopy() and ndr_pack() in verify_packet()
via ae23d512a72 python:tests/dns_base: generate a real signature in bad_sign_packet()
via 319836ce9e6 lib/addns: remove unused kerberos/gssapi includes in dns.h
from 096d3807b05 build: Make "samba4" public libraries provided (mostly) for OpenChange private
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit ed61c57e02309b738e73fb12877a0a565b627724
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu May 30 14:52:22 2024 +0200
s4:dns_server: no-op dns updates with ACCESS_DENIED should be ignored
If the client does not have permissions to update the record,
but the record already has the data the update tries to apply,
it's a no-op that should result in success instead of failing.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13019
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
Autobuild-Date(master): Thu Jun 6 03:18:16 UTC 2024 on atb-devel-224
commit 76fec2668e73b9d15447abee551d5c04148aaf27
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu May 30 14:39:28 2024 +0200
s4:dns_server: correctly sign dns update responses with gss-tsig like Windows
This means we no longer generate strange errors/warnings
in the Windows event log nor in the nsupdate -g output.
Note: this is a only difference between gss-tsig and
the legacy gss.microsoft.com algorithms.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13019
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit db350bc573b378fb0615bdd8592cc9c62f6db146
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu May 30 14:42:53 2024 +0200
s4:dns_server: dns_verify_tsig should return REFUSED on error
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13019
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 5906ed94f2c5c68e83c63e7c201534eeb323cfe7
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu May 30 14:41:21 2024 +0200
s4:dns_server: also search DNS_QTYPE_TKEY in the answers section if it's the last section
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13019
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit ae7538af04435658d2ba6dcab109beecb6c5f13e
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri May 31 08:38:24 2024 +0200
s4:dns_server: use tkey->algorithm if available in dns_sign_tsig()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13019
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit bd0235cd515d5602ed9501bfc810a2487364ea10
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri May 31 08:38:24 2024 +0200
s4:dns_server: use the client provided algorithm for the fake TSIG structure
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13019
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 3467d1491490830d61d16cb6278051daf48466fc
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri May 31 08:38:24 2024 +0200
s4:dns_server: only allow gss-tsig and gss.microsoft.com for TSIG
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13019
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit fa0f23e69eaf4f475bc9dc9aa0e23c7bd5208250
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri May 31 08:38:24 2024 +0200
s4:dns_server: only allow gss-tsig and gss.microsoft.com for TKEY
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13019
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit a56627b0d125ef7b456bebe307087f324f1f0422
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri May 31 08:36:40 2024 +0200
s4:dns_server: failed dns updates should result in REFUSED for ACCESS_DENIED
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13019
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 708a6fae6978e1462e1a53f4ee08f11b51a5637a
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed May 29 11:40:51 2024 +0200
python:tests/dns_tkey: add test_update_tsig_record_access_denied()
This demonstrates that access_denied is only generated if the client
really generates a change in the database.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13019
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 753428a3b6c488c4aacea04d2ddb9ea73244695a
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed May 29 11:39:56 2024 +0200
s4:selftest/tests: pass USERNAME_UNPRIV=$DOMAIN_USER to samba.tests.dns_tkey
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13019
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 88457da00d4110b419f7a7ccabcd542fa77e463f
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed May 29 11:39:56 2024 +0200
python:tests/dns_base: add get_unpriv_creds() helper
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13019
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 848318338b2972f331e067bf1c8d6c7dac0748c8
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed May 29 13:17:54 2024 +0200
python:tests/dns_tkey: let test_update_tsig_windows() actually pass against windows 2022
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13019
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 8324d0739dfdd0a081c403e298a9038ee7df681f
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed May 29 13:17:54 2024 +0200
python:tests/dns_base: let verify_packet() work against Windows
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13019
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit de4ed363d378f2065a4634f94af80ea0e3965c96
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed May 29 17:26:39 2024 +0200
python:tests/dns_tkey: test bad and changing tsig algorithms
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13019
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit b9b03ca503c43c7ee06df6c331839bd47f9eac8c
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed May 29 17:18:34 2024 +0200
python:tests/dns_tkey: add gss.microsoft.com tsig updates
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13019
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 3c7cb85eaf8371be55a371601cc354440dab7a94
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed May 29 14:15:45 2024 +0200
python:tests/dns_tkey: let us have test_update_gss_tsig_tkey_req_{additional,answers}()
Also test using the additional record in the answers section.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13019
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 740bda87a80b97816d892e8f7aae28759f6916ec
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed May 29 16:41:12 2024 +0200
python:tests/dns_tkey: test TKEY with gss-tsig, gss.microsoft.com and invalid algorithms
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13019
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit b0af60e7850e656ef98edeac657c66b853080dab
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed May 29 14:10:52 2024 +0200
python:tests/dns_base: maintain a dict with tkey related state
This will allow tests to backup the whole state
and mix them.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13019
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 1b1e7e06cf6ebd283de73c351267d53b42663d2f
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed May 29 14:14:11 2024 +0200
python:tests/dns_base: let dns_transaction_udp() take allow_{remaining,truncated}=True
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13019
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 27d92fa808c6617353c36fdb230504e880f4925b
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed May 29 16:07:53 2024 +0200
python:tests/dns_base: pass tkey_trans(expected_rcode)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13019
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit cd747307d845f3cff723a7916aeeb31458f19202
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed May 29 14:08:13 2024 +0200
python:tests/dns_base: let tkey_trans() take tkey_req_in_answers
It's possible to put the additional into the answers section,
so we should be able to test that.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13019
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit f8dfa9b33bdedffbe2e3b6e229ffae4beb3c712e
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed May 29 13:17:54 2024 +0200
python:tests/dns_base: let tkey_trans() and sign_packet() take algorithm_name as argument
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13019
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 6e997f93d53ac45af79aec030bad73f51bdc5629
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed May 29 13:35:58 2024 +0200
python:tests/dns_tkey: make use of self.assert_echoed_dns_error()
Failed DNS updates just echo the request flaged as response,
all other elements are unchanged.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13019
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit ce591464cb12ab00a5d5752a7cea5f909c3c3f1b
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed May 29 13:35:58 2024 +0200
python:tests/dns_base: add self.assert_echoed_dns_error()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13019
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit c741d0f3969abe821e8ee2a10f848159eb2749fe
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri May 31 08:07:24 2024 +0200
python:tests/dns_base: let dns_transaction_tcp() handle short receives
With socket_wrapper we only get 1500 byte chunks...
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13019
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit c594cbad4af97031bb7b5b0eb2fb228b00acf646
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed May 29 13:16:40 2024 +0200
python:tests/dns_base: use ndr_deepcopy() and ndr_pack() in verify_packet()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13019
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit ae23d512a724650ae2de1178ac43deff8266aa56
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed May 29 13:11:24 2024 +0200
python:tests/dns_base: generate a real signature in bad_sign_packet()
We just destroy the signature bytes but keep the header unchanged.
This makes it easier to look at it in wireshark.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13019
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 319836ce9e65d68aa98696f387c0d3e6d99e57b8
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed Jun 5 17:46:53 2024 +0200
lib/addns: remove unused kerberos/gssapi includes in dns.h
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
-----------------------------------------------------------------------
Summary of changes:
lib/addns/dns.h | 2 -
python/samba/tests/dns_base.py | 213 +++++++++++++++-------
python/samba/tests/dns_tkey.py | 325 ++++++++++++++++++++++++++++++----
python/samba/tests/join.py | 2 +-
source4/dns_server/dns_crypto.c | 49 ++++-
source4/dns_server/dns_query.c | 27 ++-
source4/dns_server/dns_update.c | 11 ++
source4/dns_server/dnsserver_common.c | 2 +
source4/selftest/tests.py | 6 +-
9 files changed, 526 insertions(+), 111 deletions(-)
Changeset truncated at 500 lines:
diff --git a/lib/addns/dns.h b/lib/addns/dns.h
index abf0906fdab..6e605cbec2e 100644
--- a/lib/addns/dns.h
+++ b/lib/addns/dns.h
@@ -27,8 +27,6 @@
#include "../replace/replace.h"
#include "system/network.h"
-#include "system/kerberos.h"
-#include "system/gssapi.h"
/* make sure we have included the correct config.h */
#ifndef NO_CONFIG_H /* for some tests */
diff --git a/python/samba/tests/dns_base.py b/python/samba/tests/dns_base.py
index d320a0e9183..43a62b1ac57 100644
--- a/python/samba/tests/dns_base.py
+++ b/python/samba/tests/dns_base.py
@@ -20,6 +20,7 @@ from samba.tests import TestCaseInTempDir
from samba.dcerpc import dns, dnsp
from samba import gensec, tests
from samba import credentials
+from samba import NTSTATUSError
import struct
import samba.ndr as ndr
import random
@@ -76,6 +77,24 @@ class DNSTest(TestCaseInTempDir):
self.assertEqual(p_opcode, opcode, "Expected OPCODE %s, got %s" %
(opcode, p_opcode))
+ def assert_dns_flags_equals(self, packet, flags):
+ "Helper function to check opcode"
+ p_flags = packet.operation & (~(dns.DNS_OPCODE|dns.DNS_RCODE))
+ self.assertEqual(p_flags, flags, "Expected FLAGS %02x, got %02x" %
+ (flags, p_flags))
+
+ def assert_echoed_dns_error(self, request, response, response_p, rcode):
+
+ request_p = ndr.ndr_pack(request)
+
+ self.assertEqual(response.id, request.id)
+ self.assert_dns_rcode_equals(response, rcode)
+ self.assert_dns_opcode_equals(response, request.operation & dns.DNS_OPCODE)
+ self.assert_dns_flags_equals(response,
+ (request.operation | dns.DNS_FLAG_REPLY) & (~(dns.DNS_OPCODE|dns.DNS_RCODE)))
+ self.assertEqual(len(response_p), len(request_p))
+ self.assertEqual(response_p[4:], request_p[4:])
+
def make_name_packet(self, opcode, qid=None):
"Helper creating a dns.name_packet"
p = dns.name_packet()
@@ -112,6 +131,8 @@ class DNSTest(TestCaseInTempDir):
return self.creds.get_realm().lower()
def dns_transaction_udp(self, packet, host,
+ allow_remaining=False,
+ allow_truncated=False,
dump=False, timeout=None):
"send a DNS query and read the reply"
s = None
@@ -128,8 +149,22 @@ class DNSTest(TestCaseInTempDir):
recv_packet = s.recv(2048, 0)
if dump:
print(self.hexdump(recv_packet))
- response = ndr.ndr_unpack(dns.name_packet, recv_packet)
+ if allow_truncated:
+ # with allow_remaining
+ # we add some zero bytes
+ # in order to also parse truncated
+ # responses
+ recv_packet_p = recv_packet + 32*b"\x00"
+ allow_remaining = True
+ else:
+ recv_packet_p = recv_packet
+ response = ndr.ndr_unpack(dns.name_packet, recv_packet_p,
+ allow_remaining=allow_remaining)
return (response, recv_packet)
+ except RuntimeError as re:
+ if s is not None:
+ s.close()
+ raise AssertionError(re)
finally:
if s is not None:
s.close()
@@ -151,11 +186,26 @@ class DNSTest(TestCaseInTempDir):
tcp_packet += send_packet
s.sendall(tcp_packet)
- recv_packet = s.recv(0xffff + 2, 0)
+ recv_packet = b''
+ length = None
+ for i in range(0, 2 + 0xffff):
+ if len(recv_packet) >= 2:
+ length, = struct.unpack('!H', recv_packet[0:2])
+ remaining = 2 + length
+ else:
+ remaining = 2 + 12
+ remaining -= len(recv_packet)
+ if remaining == 0:
+ break
+ recv_packet += s.recv(remaining, 0)
if dump:
print(self.hexdump(recv_packet))
response = ndr.ndr_unpack(dns.name_packet, recv_packet[2:])
+ except RuntimeError as re:
+ if s is not None:
+ s.close()
+ raise AssertionError(re)
finally:
if s is not None:
s.close()
@@ -217,18 +267,41 @@ class DNSTKeyTest(DNSTest):
self.creds.set_username(tests.env_get_var_value('USERNAME'))
self.creds.set_password(tests.env_get_var_value('PASSWORD'))
self.creds.set_kerberos_state(credentials.MUST_USE_KERBEROS)
+
+ self.unpriv_creds = None
+
self.newrecname = "tkeytsig.%s" % self.get_dns_domain()
- def tkey_trans(self, creds=None):
+ def get_unpriv_creds(self):
+ if self.unpriv_creds is not None:
+ return self.unpriv_creds
+
+ self.unpriv_creds = credentials.Credentials()
+ self.unpriv_creds.guess(self.lp_ctx)
+ self.unpriv_creds.set_username(tests.env_get_var_value('USERNAME_UNPRIV'))
+ self.unpriv_creds.set_password(tests.env_get_var_value('PASSWORD_UNPRIV'))
+ self.unpriv_creds.set_kerberos_state(credentials.MUST_USE_KERBEROS)
+
+ return self.unpriv_creds
+
+ def tkey_trans(self, creds=None, algorithm_name="gss-tsig",
+ tkey_req_in_answers=False,
+ expected_rcode=dns.DNS_RCODE_OK):
"Do a TKEY transaction and establish a gensec context"
if creds is None:
creds = self.creds
- self.key_name = "%s.%s" % (uuid.uuid4(), self.get_dns_domain())
+ mech = 'spnego'
+
+ tkey = {}
+ tkey['name'] = "%s.%s" % (uuid.uuid4(), self.get_dns_domain())
+ tkey['creds'] = creds
+ tkey['mech'] = mech
+ tkey['algorithm'] = algorithm_name
p = self.make_name_packet(dns.DNS_OPCODE_QUERY)
- q = self.make_name_question(self.key_name,
+ q = self.make_name_question(tkey['name'],
dns.DNS_QTYPE_TKEY,
dns.DNS_QCLASS_IN)
questions = []
@@ -236,30 +309,30 @@ class DNSTKeyTest(DNSTest):
self.finish_name_packet(p, questions)
r = dns.res_rec()
- r.name = self.key_name
+ r.name = tkey['name']
r.rr_type = dns.DNS_QTYPE_TKEY
r.rr_class = dns.DNS_QCLASS_IN
r.ttl = 0
r.length = 0xffff
rdata = dns.tkey_record()
- rdata.algorithm = "gss-tsig"
+ rdata.algorithm = algorithm_name
rdata.inception = int(time.time())
rdata.expiration = int(time.time()) + 60 * 60
rdata.mode = dns.DNS_TKEY_MODE_GSSAPI
rdata.error = 0
rdata.other_size = 0
- self.g = gensec.Security.start_client(self.settings)
- self.g.set_credentials(creds)
- self.g.set_target_service("dns")
- self.g.set_target_hostname(self.server)
- self.g.want_feature(gensec.FEATURE_SIGN)
- self.g.start_mech_by_name("spnego")
+ tkey['gensec'] = gensec.Security.start_client(self.settings)
+ tkey['gensec'].set_credentials(creds)
+ tkey['gensec'].set_target_service("dns")
+ tkey['gensec'].set_target_hostname(self.server)
+ tkey['gensec'].want_feature(gensec.FEATURE_SIGN)
+ tkey['gensec'].start_mech_by_name(tkey['mech'])
finished = False
client_to_server = b""
- (finished, server_to_client) = self.g.update(client_to_server)
+ (finished, server_to_client) = tkey['gensec'].update(client_to_server)
self.assertFalse(finished)
data = [x if isinstance(x, int) else ord(x) for x in list(server_to_client)]
@@ -268,56 +341,76 @@ class DNSTKeyTest(DNSTest):
r.rdata = rdata
additional = [r]
- p.arcount = 1
- p.additional = additional
+ if tkey_req_in_answers:
+ p.ancount = 1
+ p.answers = additional
+ else:
+ p.arcount = 1
+ p.additional = additional
(response, response_packet) =\
self.dns_transaction_tcp(p, self.server_ip)
+ if expected_rcode != dns.DNS_RCODE_OK:
+ self.assert_echoed_dns_error(p, response, response_packet, expected_rcode)
+ return
self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK)
tkey_record = response.answers[0].rdata
server_to_client = bytes(tkey_record.key_data)
- (finished, client_to_server) = self.g.update(server_to_client)
+ (finished, client_to_server) = tkey['gensec'].update(server_to_client)
self.assertTrue(finished)
+ self.tkey = tkey
+
self.verify_packet(response, response_packet)
def verify_packet(self, response, response_packet, request_mac=b""):
+ self.assertEqual(response.arcount, 1)
self.assertEqual(response.additional[0].rr_type, dns.DNS_QTYPE_TSIG)
+ if self.tkey['algorithm'] == "gss-tsig":
+ gss_tsig = True
+ else:
+ gss_tsig = False
+
+ request_mac_len = b""
+ if len(request_mac) > 0 and gss_tsig:
+ request_mac_len = struct.pack('!H', len(request_mac))
+
tsig_record = response.additional[0].rdata
mac = bytes(tsig_record.mac)
+ self.assertEqual(tsig_record.original_id, response.id)
+ self.assertEqual(tsig_record.mac_size, len(mac))
+
# Cut off tsig record from dns response packet for MAC verification
# and reset additional record count.
- key_name_len = len(self.key_name) + 2
- tsig_record_len = len(ndr.ndr_pack(tsig_record)) + key_name_len + 10
-
- # convert str/bytes to a list (of string char or int)
- # so it can be modified
- response_packet_list = [x if isinstance(x, int) else ord(x) for x in response_packet]
- del response_packet_list[-tsig_record_len:]
- response_packet_list[11] = 0
-
- # convert modified list (of string char or int) to str/bytes
- response_packet_wo_tsig = bytes(response_packet_list)
+ response_copy = ndr.ndr_deepcopy(response)
+ response_copy.arcount = 0
+ response_packet_wo_tsig = ndr.ndr_pack(response_copy)
fake_tsig = dns.fake_tsig_rec()
- fake_tsig.name = self.key_name
+ fake_tsig.name = self.tkey['name']
fake_tsig.rr_class = dns.DNS_QCLASS_ANY
fake_tsig.ttl = 0
fake_tsig.time_prefix = tsig_record.time_prefix
fake_tsig.time = tsig_record.time
fake_tsig.algorithm_name = tsig_record.algorithm_name
fake_tsig.fudge = tsig_record.fudge
- fake_tsig.error = 0
- fake_tsig.other_size = 0
+ fake_tsig.error = tsig_record.error
+ fake_tsig.other_size = tsig_record.other_size
+ fake_tsig.other_data = tsig_record.other_data
fake_tsig_packet = ndr.ndr_pack(fake_tsig)
- data = request_mac + response_packet_wo_tsig + fake_tsig_packet
- self.g.check_packet(data, data, mac)
+ data = request_mac_len + request_mac + response_packet_wo_tsig + fake_tsig_packet
+ try:
+ self.tkey['gensec'].check_packet(data, data, mac)
+ except NTSTATUSError as nt:
+ raise AssertionError(nt)
- def sign_packet(self, packet, key_name):
+ def sign_packet(self, packet, key_name,
+ algorithm_name="gss-tsig",
+ bad_sig=False):
"Sign a packet, calculate a MAC and add TSIG record"
packet_data = ndr.ndr_pack(packet)
@@ -327,18 +420,35 @@ class DNSTKeyTest(DNSTest):
fake_tsig.ttl = 0
fake_tsig.time_prefix = 0
fake_tsig.time = int(time.time())
- fake_tsig.algorithm_name = "gss-tsig"
+ fake_tsig.algorithm_name = algorithm_name
fake_tsig.fudge = 300
fake_tsig.error = 0
fake_tsig.other_size = 0
fake_tsig_packet = ndr.ndr_pack(fake_tsig)
data = packet_data + fake_tsig_packet
- mac = self.g.sign_packet(data, data)
+ mac = self.tkey['gensec'].sign_packet(data, data)
mac_list = [x if isinstance(x, int) else ord(x) for x in list(mac)]
+ if bad_sig:
+ if len(mac) > 8:
+ mac_list[-8] = mac_list[-8] ^ 0xff
+ if len(mac) > 7:
+ mac_list[-7] = ord('b')
+ if len(mac) > 6:
+ mac_list[-6] = ord('a')
+ if len(mac) > 5:
+ mac_list[-5] = ord('d')
+ if len(mac) > 4:
+ mac_list[-4] = ord('m')
+ if len(mac) > 3:
+ mac_list[-3] = ord('a')
+ if len(mac) > 2:
+ mac_list[-2] = ord('c')
+ if len(mac) > 1:
+ mac_list[-1] = mac_list[-1] ^ 0xff
rdata = dns.tsig_record()
- rdata.algorithm_name = "gss-tsig"
+ rdata.algorithm_name = algorithm_name
rdata.time_prefix = 0
rdata.time = fake_tsig.time
rdata.fudge = 300
@@ -363,33 +473,10 @@ class DNSTKeyTest(DNSTest):
return mac
def bad_sign_packet(self, packet, key_name):
- """Add bad signature for a packet by bitflipping
- the final byte in the MAC"""
-
- mac_list = [x if isinstance(x, int) else ord(x) for x in list("badmac")]
-
- rdata = dns.tsig_record()
- rdata.algorithm_name = "gss-tsig"
- rdata.time_prefix = 0
- rdata.time = int(time.time())
- rdata.fudge = 300
- rdata.original_id = packet.id
- rdata.error = 0
- rdata.other_size = 0
- rdata.mac = mac_list
- rdata.mac_size = len(mac_list)
+ """Add bad signature for a packet by
+ bitflipping and hardcoding bytes at the end of the MAC"""
- r = dns.res_rec()
- r.name = key_name
- r.rr_type = dns.DNS_QTYPE_TSIG
- r.rr_class = dns.DNS_QCLASS_ANY
- r.ttl = 0
- r.length = 0xffff
- r.rdata = rdata
-
- additional = [r]
- packet.additional = additional
- packet.arcount = 1
+ return self.sign_packet(packet, key_name, bad_sig=True)
def search_record(self, name):
p = self.make_name_packet(dns.DNS_OPCODE_QUERY)
diff --git a/python/samba/tests/dns_tkey.py b/python/samba/tests/dns_tkey.py
index 69af14d6f10..f8417ea119d 100644
--- a/python/samba/tests/dns_tkey.py
+++ b/python/samba/tests/dns_tkey.py
@@ -19,6 +19,7 @@
import sys
import optparse
import samba.getopt as options
+import samba.ndr as ndr
from samba.dcerpc import dns
from samba.tests.subunitrun import SubunitOptions, TestProgram
from samba.tests.dns_base import DNSTKeyTest
@@ -55,17 +56,34 @@ class TestDNSUpdates(DNSTKeyTest):
self.server_ip = server_ip
super().setUp()
- def test_tkey(self):
- "test DNS TKEY handshake"
+ def test_tkey_gss_tsig(self):
+ "test DNS TKEY handshake with gss-tsig"
self.tkey_trans()
+ def test_tkey_gss_microsoft_com(self):
+ "test DNS TKEY handshake with gss.microsoft.com"
+
+ self.tkey_trans(algorithm_name="gss.microsoft.com")
+
+ def test_tkey_invalid_gss_TSIG(self):
+ "test DNS TKEY handshake with invalid gss-TSIG"
+
+ self.tkey_trans(algorithm_name="gss-TSIG",
+ expected_rcode=dns.DNS_RCODE_REFUSED)
+
+ def test_tkey_invalid_gss_MICROSOFT_com(self):
+ "test DNS TKEY handshake with invalid gss.MICROSOFT.com"
+
+ self.tkey_trans(algorithm_name="gss.MICROSOFT.com",
+ expected_rcode=dns.DNS_RCODE_REFUSED)
+
def test_update_wo_tsig(self):
"test DNS update without TSIG record"
p = self.make_update_request()
(response, response_p) = self.dns_transaction_udp(p, self.server_ip)
- self.assert_dns_rcode_equals(response, dns.DNS_RCODE_REFUSED)
+ self.assert_echoed_dns_error(p, response, response_p, dns.DNS_RCODE_REFUSED)
rcode = self.search_record(self.newrecname)
self.assert_rcode_equals(rcode, dns.DNS_RCODE_NXDOMAIN)
@@ -78,10 +96,7 @@ class TestDNSUpdates(DNSTKeyTest):
p = self.make_update_request()
self.sign_packet(p, "badkey")
(response, response_p) = self.dns_transaction_udp(p, self.server_ip)
- self.assert_dns_rcode_equals(response, dns.DNS_RCODE_NOTAUTH)
- tsig_record = response.additional[0].rdata
- self.assertEqual(tsig_record.error, dns.DNS_RCODE_BADKEY)
- self.assertEqual(tsig_record.mac_size, 0)
+ self.assert_echoed_dns_error(p, response, response_p, dns.DNS_RCODE_REFUSED)
rcode = self.search_record(self.newrecname)
self.assert_rcode_equals(rcode, dns.DNS_RCODE_NXDOMAIN)
@@ -92,23 +107,149 @@ class TestDNSUpdates(DNSTKeyTest):
self.tkey_trans()
p = self.make_update_request()
- self.bad_sign_packet(p, self.key_name)
+ self.bad_sign_packet(p, self.tkey['name'])
(response, response_p) = self.dns_transaction_udp(p, self.server_ip)
- self.assert_dns_rcode_equals(response, dns.DNS_RCODE_NOTAUTH)
- tsig_record = response.additional[0].rdata
- self.assertEqual(tsig_record.error, dns.DNS_RCODE_BADSIG)
- self.assertEqual(tsig_record.mac_size, 0)
+ self.assert_echoed_dns_error(p, response, response_p, dns.DNS_RCODE_REFUSED)
rcode = self.search_record(self.newrecname)
self.assert_rcode_equals(rcode, dns.DNS_RCODE_NXDOMAIN)
- def test_update_tsig(self):
- "test DNS update with correct TSIG record"
+ def test_update_tsig_bad_algorithm(self):
+ "test DNS update with a TSIG record with a bad algorithm"
self.tkey_trans()
+ algorithm_name = "gss-TSIG"
p = self.make_update_request()
- mac = self.sign_packet(p, self.key_name)
+ mac = self.sign_packet(p, self.tkey['name'],
+ algorithm_name=algorithm_name)
+ (response, response_p) = self.dns_transaction_udp(p, self.server_ip)
+ self.assert_echoed_dns_error(p, response, response_p, dns.DNS_RCODE_REFUSED)
+
+ rcode = self.search_record(self.newrecname)
+ self.assert_rcode_equals(rcode, dns.DNS_RCODE_NXDOMAIN)
+
+ def test_update_tsig_changed_algorithm1(self):
+ "test DNS update with a TSIG record with a changed algorithm"
+
+ algorithm_name = "gss-tsig"
+ self.tkey_trans(algorithm_name=algorithm_name)
+
+ # Now delete the record, it's most likely
+ # a no-op as it should not be there if the test
+ # runs the first time
+ p = self.make_update_request(delete=True)
+ mac = self.sign_packet(p, self.tkey['name'], algorithm_name=algorithm_name)
+ (response, response_p) = self.dns_transaction_udp(p, self.server_ip)
+ self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK)
+ self.verify_packet(response, response_p, mac)
+
+ # Now do an update with the algorithm_name
+ # changed in the requests TSIG message.
+ p = self.make_update_request()
+ algorithm_name = "gss.microsoft.com"
+ mac = self.sign_packet(p, self.tkey['name'],
+ algorithm_name=algorithm_name)
+ algorithm_name = "gss-tsig"
+ (response, response_p) = self.dns_transaction_udp(p, self.server_ip,
+ allow_remaining=True)
+ self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK)
+ self.verify_packet(response, response_p, mac)
+
+ # Check the record is around
+ rcode = self.search_record(self.newrecname)
+ self.assert_rcode_equals(rcode, dns.DNS_RCODE_OK)
+
+ # Now delete the record, with the original
+ # algorithm_name used in the tkey exchange
+ p = self.make_update_request(delete=True)
+ mac = self.sign_packet(p, self.tkey['name'], algorithm_name=algorithm_name)
--
Samba Shared Repository
More information about the samba-cvs
mailing list