View | Details | Raw Unified | Return to bug 1228257
Collapse All | Expand All

(-)a/bin/tests/system/tsiggss/authsock.pl (+5 lines)
Lines 33-38 if (!defined($path)) { Link Here
33
	exit(1);
33
	exit(1);
34
}
34
}
35
35
36
# Enable output autoflush so that it's not lost when the parent sends TERM.
37
select STDOUT;
38
$| = 1;
39
36
unlink($path);
40
unlink($path);
37
my $server = IO::Socket::UNIX->new(Local => $path, Type => SOCK_STREAM, Listen => 8) or
41
my $server = IO::Socket::UNIX->new(Local => $path, Type => SOCK_STREAM, Listen => 8) or
38
    die "unable to create socket $path";
42
    die "unable to create socket $path";
Lines 50-55 if ($timeout != 0) { Link Here
50
}
54
}
51
55
52
while (my $client = $server->accept()) {
56
while (my $client = $server->accept()) {
57
	printf("accept()\n");
53
	$client->recv(my $buf, 8, 0);
58
	$client->recv(my $buf, 8, 0);
54
	my ($version, $req_len) = unpack('N N', $buf);
59
	my ($version, $req_len) = unpack('N N', $buf);
55
60
(-)a/bin/tests/system/tsiggss/tests.sh (-5 / +7 lines)
Lines 117-123 status=$((status + ret)) Link Here
117
117
118
echo_i "testing external update policy (CNAME) with auth sock ($n)"
118
echo_i "testing external update policy (CNAME) with auth sock ($n)"
119
ret=0
119
ret=0
120
$PERL ./authsock.pl --type=CNAME --path=ns1/auth.sock --pidfile=authsock.pid --timeout=120 >/dev/null 2>&1 &
120
$PERL ./authsock.pl --type=CNAME --path=ns1/auth.sock --pidfile=authsock.pid --timeout=120 >authsock.log 2>&1 &
121
sleep 1
121
sleep 1
122
test_update $n testcname.example.nil. CNAME "86400 CNAME testdenied.example.nil" "testdenied" || ret=1
122
test_update $n testcname.example.nil. CNAME "86400 CNAME testdenied.example.nil" "testdenied" || ret=1
123
n=$((n + 1))
123
n=$((n + 1))
Lines 131-147 n=$((n + 1)) Link Here
131
if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
131
if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
132
status=$((status + ret))
132
status=$((status + ret))
133
133
134
echo_i "testing external policy with SIG(0) key ($n)"
134
echo_i "testing external policy with unsupported SIG(0) key ($n)"
135
ret=0
135
ret=0
136
$NSUPDATE -k ns1/Kkey.example.nil.*.private <<END >/dev/null 2>&1 || ret=1
136
$NSUPDATE -d -k ns1/Kkey.example.nil.*.private <<END >nsupdate.out${n} 2>&1 || true
137
debug
137
server 10.53.0.1 ${PORT}
138
server 10.53.0.1 ${PORT}
138
zone example.nil
139
zone example.nil
139
update add fred.example.nil 120 cname foo.bar.
140
update add fred.example.nil 120 cname foo.bar.
140
send
141
send
141
END
142
END
142
output=$($DIG $DIGOPTS +short cname fred.example.nil.)
143
output=$($DIG $DIGOPTS +short cname fred.example.nil.)
143
[ -n "$output" ] || ret=1
144
# update must have failed - SIG(0) signer is not supported
144
[ $ret -eq 0 ] || echo_i "failed"
145
[ -n "$output" ] && ret=1
146
grep -F "signer=key.example.nil" authsock.log >/dev/null && ret=1
145
n=$((n + 1))
147
n=$((n + 1))
146
if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
148
if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
147
status=$((status + ret))
149
status=$((status + ret))
(-)a/bin/tests/system/upforwd/tests.sh (-3 / +6 lines)
Lines 229-238 fi Link Here
229
n=$((n + 1))
229
n=$((n + 1))
230
230
231
if test -f keyname; then
231
if test -f keyname; then
232
  echo_i "checking update forwarding to with sig0 ($n)"
232
  echo_i "checking update forwarding to with sig0 (expected to fail) ($n)"
233
  ret=0
233
  ret=0
234
  keyname=$(cat keyname)
234
  keyname=$(cat keyname)
235
  $NSUPDATE -k $keyname.private -- - <<EOF
235
  # SIG(0) is removed, update is expected to fail.
236
  {
237
    $NSUPDATE -k $keyname.private -- - <<EOF
236
	local 10.53.0.1
238
	local 10.53.0.1
237
	server 10.53.0.3 ${PORT}
239
	server 10.53.0.3 ${PORT}
238
	zone example2
240
	zone example2
Lines 240-247 if test -f keyname; then Link Here
240
	update add unsigned.example2. 600 TXT Foo
242
	update add unsigned.example2. 600 TXT Foo
241
	send
243
	send
242
EOF
244
EOF
245
  } >nsupdate.out.$n 2>&1 && ret=1
243
  $DIG -p ${PORT} unsigned.example2 A @10.53.0.1 >dig.out.ns1.test$n || ret=1
246
  $DIG -p ${PORT} unsigned.example2 A @10.53.0.1 >dig.out.ns1.test$n || ret=1
244
  grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1
247
  grep "status: NOERROR" dig.out.ns1.test$n >/dev/null && ret=1
245
  if [ $ret != 0 ]; then echo_i "failed"; fi
248
  if [ $ret != 0 ]; then echo_i "failed"; fi
246
  status=$((status + ret))
249
  status=$((status + ret))
247
  n=$((n + 1))
250
  n=$((n + 1))
(-)a/doc/arm/general.rst (-4 / +2 lines)
Lines 383-392 Notes Link Here
383
.. [#rfc1035_2] CLASS ANY queries are not supported. This is considered a
383
.. [#rfc1035_2] CLASS ANY queries are not supported. This is considered a
384
   feature.
384
   feature.
385
385
386
.. [#rfc2931] When receiving a query signed with a SIG(0), the server is
386
.. [#rfc2931] Support for SIG(0) message verification was removed
387
   only able to verify the signature if it has the key in its local
387
   as part of the mitigation of CVE-2024-1975.
388
   authoritative data; it cannot do recursion or validation to
389
   retrieve unknown keys.
390
388
391
.. [#rfc2874] Compliance is with loading and serving of A6 records only.
389
.. [#rfc2874] Compliance is with loading and serving of A6 records only.
392
   A6 records were moved to the experimental category by :rfc:`3363`.
390
   A6 records were moved to the experimental category by :rfc:`3363`.
(-)a/doc/arm/intro-security.inc.rst (-1 / +1 lines)
Lines 47-53 or ports come preconfigured with local (loopback address) security preconfigured Link Here
47
If ``rndc`` is being invoked from a remote host, further configuration is required.
47
If ``rndc`` is being invoked from a remote host, further configuration is required.
48
The ``nsupdate`` tool uses **Dynamic DNS (DDNS)** features and allows users to dynamically
48
The ``nsupdate`` tool uses **Dynamic DNS (DDNS)** features and allows users to dynamically
49
change the contents of the zone file(s). ``nsupdate`` access and security may be controlled
49
change the contents of the zone file(s). ``nsupdate`` access and security may be controlled
50
using ``named.conf`` :ref:`statements or using TSIG or SIG(0) cryptographic methods <dynamic_update_security>`.
50
using ``named.conf`` :ref:`statements or via the TSIG cryptographic method <dynamic_update_security>`.
51
Clearly, if the remote hosts used for either ``rndc`` or DDNS lie within a network entirely
51
Clearly, if the remote hosts used for either ``rndc`` or DDNS lie within a network entirely
52
under the user's control, the security threat may be regarded as non-existent. Any implementation requirements,
52
under the user's control, the security threat may be regarded as non-existent. Any implementation requirements,
53
therefore, depend on the site's security policy.
53
therefore, depend on the site's security policy.
(-)a/doc/arm/reference.rst (-2 / +2 lines)
Lines 7450-7456 the zone's filename, unless :any:`inline-signing` is enabled. Link Here
7450
   updates are allowed. It specifies a set of rules, in which each rule
7450
   updates are allowed. It specifies a set of rules, in which each rule
7451
   either grants or denies permission for one or more names in the zone to
7451
   either grants or denies permission for one or more names in the zone to
7452
   be updated by one or more identities. Identity is determined by the key
7452
   be updated by one or more identities. Identity is determined by the key
7453
   that signed the update request, using either TSIG or SIG(0). In most
7453
   that signed the update request, using TSIG. In most
7454
   cases, :any:`update-policy` rules only apply to key-based identities. There
7454
   cases, :any:`update-policy` rules only apply to key-based identities. There
7455
   is no way to specify update permissions based on the client source address.
7455
   is no way to specify update permissions based on the client source address.
7456
7456
Lines 7507-7513 the zone's filename, unless :any:`inline-signing` is enabled. Link Here
7507
   field. Details for each rule type are described below.
7507
   field. Details for each rule type are described below.
7508
7508
7509
   The ``identity`` field must be set to a fully qualified domain name. In
7509
   The ``identity`` field must be set to a fully qualified domain name. In
7510
   most cases, this represents the name of the TSIG or SIG(0) key that
7510
   most cases, this represents the name of the TSIG key that
7511
   must be used to sign the update request. If the specified name is a
7511
   must be used to sign the update request. If the specified name is a
7512
   wildcard, it is subject to DNS wildcard expansion, and the rule may
7512
   wildcard, it is subject to DNS wildcard expansion, and the rule may
7513
   apply to multiple identities. When a TKEY exchange has been used to
7513
   apply to multiple identities. When a TKEY exchange has been used to
(-)a/doc/arm/security.inc.rst (-2 / +2 lines)
Lines 85-91 Limiting access to the server by outside parties can help prevent Link Here
85
spoofing and denial of service (DoS) attacks against the server.
85
spoofing and denial of service (DoS) attacks against the server.
86
86
87
ACLs match clients on the basis of up to three characteristics: 1) The
87
ACLs match clients on the basis of up to three characteristics: 1) The
88
client's IP address; 2) the TSIG or SIG(0) key that was used to sign the
88
client's IP address; 2) the TSIG key that was used to sign the
89
request, if any; and 3) an address prefix encoded in an EDNS
89
request, if any; and 3) an address prefix encoded in an EDNS
90
Client-Subnet option, if any.
90
Client-Subnet option, if any.
91
91
Lines 126-132 and no queries at all from the networks specified in ``bogusnets``. Link Here
126
126
127
In addition to network addresses and prefixes, which are matched against
127
In addition to network addresses and prefixes, which are matched against
128
the source address of the DNS request, ACLs may include ``key``
128
the source address of the DNS request, ACLs may include ``key``
129
elements, which specify the name of a TSIG or SIG(0) key.
129
elements, which specify the name of a TSIG key.
130
130
131
When BIND 9 is built with GeoIP support, ACLs can also be used for
131
When BIND 9 is built with GeoIP support, ACLs can also be used for
132
geographic access restrictions. This is done by specifying an ACL
132
geographic access restrictions. This is done by specifying an ACL
(-)a/doc/arm/sig0.inc.rst (-14 / +2 lines)
Lines 12-28 Link Here
12
SIG(0)
12
SIG(0)
13
------
13
------
14
14
15
BIND partially supports DNSSEC SIG(0) transaction signatures as
15
Support for DNSSEC SIG(0) transaction signatures has been removed.
16
specified in :rfc:`2535` and :rfc:`2931`. SIG(0) uses public/private keys to
16
This is a countermeasure for CVE-2024-1975.
17
authenticate messages. Access control is performed in the same manner as with
18
TSIG keys; privileges can be granted or denied in ACL directives based
19
on the key name.
20
21
When a SIG(0) signed message is received, it is only verified if
22
the key is known and trusted by the server. The server does not attempt
23
to recursively fetch or validate the key.
24
25
SIG(0) signing of multiple-message TCP streams is not supported.
26
27
The only tool shipped with BIND 9 that generates SIG(0) signed messages
28
is :iscman:`nsupdate`.
(-)a/lib/dns/message.c (-93 / +6 lines)
Lines 3288-3398 dns_message_dumpsig(dns_message_t *msg, char *txt1) { Link Here
3288
3288
3289
isc_result_t
3289
isc_result_t
3290
dns_message_checksig(dns_message_t *msg, dns_view_t *view) {
3290
dns_message_checksig(dns_message_t *msg, dns_view_t *view) {
3291
	isc_buffer_t b, msgb;
3291
	isc_buffer_t msgb;
3292
3292
3293
	REQUIRE(DNS_MESSAGE_VALID(msg));
3293
	REQUIRE(DNS_MESSAGE_VALID(msg));
3294
3294
3295
	if (msg->tsigkey == NULL && msg->tsig == NULL && msg->sig0 == NULL) {
3295
	if (msg->tsigkey == NULL && msg->tsig == NULL) {
3296
		return (ISC_R_SUCCESS);
3296
		return (ISC_R_SUCCESS);
3297
	}
3297
	}
3298
3298
3299
	INSIST(msg->saved.base != NULL);
3299
	INSIST(msg->saved.base != NULL);
3300
	isc_buffer_init(&msgb, msg->saved.base, msg->saved.length);
3300
	isc_buffer_init(&msgb, msg->saved.base, msg->saved.length);
3301
	isc_buffer_add(&msgb, msg->saved.length);
3301
	isc_buffer_add(&msgb, msg->saved.length);
3302
	if (msg->tsigkey != NULL || msg->tsig != NULL) {
3303
#ifdef SKAN_MSG_DEBUG
3302
#ifdef SKAN_MSG_DEBUG
3304
		dns_message_dumpsig(msg, "dns_message_checksig#1");
3303
	dns_message_dumpsig(msg, "dns_message_checksig#1");
3305
#endif /* ifdef SKAN_MSG_DEBUG */
3304
#endif /* ifdef SKAN_MSG_DEBUG */
3306
		if (view != NULL) {
3305
	if (view != NULL) {
3307
			return (dns_view_checksig(view, &msgb, msg));
3306
		return (dns_view_checksig(view, &msgb, msg));
3308
		} else {
3309
			return (dns_tsig_verify(&msgb, msg, NULL, NULL));
3310
		}
3311
	} else {
3307
	} else {
3312
		dns_rdata_t rdata = DNS_RDATA_INIT;
3308
		return (dns_tsig_verify(&msgb, msg, NULL, NULL));
3313
		dns_rdata_sig_t sig;
3314
		dns_rdataset_t keyset;
3315
		isc_result_t result;
3316
3317
		result = dns_rdataset_first(msg->sig0);
3318
		INSIST(result == ISC_R_SUCCESS);
3319
		dns_rdataset_current(msg->sig0, &rdata);
3320
3321
		/*
3322
		 * This can occur when the message is a dynamic update, since
3323
		 * the rdata length checking is relaxed.  This should not
3324
		 * happen in a well-formed message, since the SIG(0) is only
3325
		 * looked for in the additional section, and the dynamic update
3326
		 * meta-records are in the prerequisite and update sections.
3327
		 */
3328
		if (rdata.length == 0) {
3329
			return (ISC_R_UNEXPECTEDEND);
3330
		}
3331
3332
		result = dns_rdata_tostruct(&rdata, &sig, NULL);
3333
		if (result != ISC_R_SUCCESS) {
3334
			return (result);
3335
		}
3336
3337
		dns_rdataset_init(&keyset);
3338
		if (view == NULL) {
3339
			result = DNS_R_KEYUNAUTHORIZED;
3340
			goto freesig;
3341
		}
3342
		result = dns_view_simplefind(view, &sig.signer,
3343
					     dns_rdatatype_key /* SIG(0) */, 0,
3344
					     0, false, &keyset, NULL);
3345
3346
		if (result != ISC_R_SUCCESS) {
3347
			/* XXXBEW Should possibly create a fetch here */
3348
			result = DNS_R_KEYUNAUTHORIZED;
3349
			goto freesig;
3350
		} else if (keyset.trust < dns_trust_secure) {
3351
			/* XXXBEW Should call a validator here */
3352
			result = DNS_R_KEYUNAUTHORIZED;
3353
			goto freesig;
3354
		}
3355
		result = dns_rdataset_first(&keyset);
3356
		INSIST(result == ISC_R_SUCCESS);
3357
		for (; result == ISC_R_SUCCESS;
3358
		     result = dns_rdataset_next(&keyset))
3359
		{
3360
			dst_key_t *key = NULL;
3361
3362
			dns_rdata_reset(&rdata);
3363
			dns_rdataset_current(&keyset, &rdata);
3364
			isc_buffer_init(&b, rdata.data, rdata.length);
3365
			isc_buffer_add(&b, rdata.length);
3366
3367
			result = dst_key_fromdns(&sig.signer, rdata.rdclass, &b,
3368
						 view->mctx, &key);
3369
			if (result != ISC_R_SUCCESS) {
3370
				continue;
3371
			}
3372
			if (dst_key_alg(key) != sig.algorithm ||
3373
			    dst_key_id(key) != sig.keyid ||
3374
			    !(dst_key_proto(key) == DNS_KEYPROTO_DNSSEC ||
3375
			      dst_key_proto(key) == DNS_KEYPROTO_ANY))
3376
			{
3377
				dst_key_free(&key);
3378
				continue;
3379
			}
3380
			result = dns_dnssec_verifymessage(&msgb, msg, key);
3381
			dst_key_free(&key);
3382
			if (result == ISC_R_SUCCESS) {
3383
				break;
3384
			}
3385
		}
3386
		if (result == ISC_R_NOMORE) {
3387
			result = DNS_R_KEYUNAUTHORIZED;
3388
		}
3389
3390
	freesig:
3391
		if (dns_rdataset_isassociated(&keyset)) {
3392
			dns_rdataset_disassociate(&keyset);
3393
		}
3394
		dns_rdata_freestruct(&sig);
3395
		return (result);
3396
	}
3309
	}
3397
}
3310
}
3398
3311
(-)a/lib/ns/client.c (+7 lines)
Lines 2168-2173 ns__client_request(isc_nmhandle_t *handle, isc_result_t eresult, Link Here
2168
		ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
2168
		ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
2169
			      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
2169
			      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
2170
			      "request is signed by a nonauthoritative key");
2170
			      "request is signed by a nonauthoritative key");
2171
	} else if (result == DNS_R_NOTVERIFIEDYET &&
2172
		   client->message->sig0 != NULL)
2173
	{
2174
		ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
2175
			      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
2176
			      "request has a SIG(0) signature but its support "
2177
			      "was removed (CVE-2024-1975)");
2171
	} else {
2178
	} else {
2172
		char tsigrcode[64];
2179
		char tsigrcode[64];
2173
		isc_buffer_t b;
2180
		isc_buffer_t b;

Return to bug 1228257