diff --git a/CHANGES b/CHANGES index 12b0e653d3..79ac0ef512 100644 --- a/CHANGES +++ b/CHANGES @@ -1,9 +1,13 @@ -1948. [bug] If was possible to trigger a REQUIRE failure in - xfrin.c:maybe_free() if named ran out of memory. +1951. [security] Drop queries from particular well known ports. + Don't return FORMERR to queries from particular + well known ports. [RT #15636] + 1950. [port] Solaris 2.5.1 and earlier cannot bind() then connect() a TCP socket. This prevents the source address being set for TCP connections. [RT #15628] +1948. [bug] If was possible to trigger a REQUIRE failure in + xfrin.c:maybe_free() if named ran out of memory. [RT #15568] 1946. [bug] resume_dslookup() could trigger a REQUIRE failure diff --git a/README b/README index 574b07d732..47fd05a314 100644 --- a/README +++ b/README @@ -265,6 +265,8 @@ Building Enable DNSSEC signature chasing support in dig. -DDIG_SIGCHASE=1 (sets -DDIG_SIGCHASE_TD=1 and -DDIG_SIGCHASE_BU=1) + Disable dropping queries from particular well known ports. + -DNS_CLIENT_DROPPORT=0 LDFLAGS Linker flags. Defaults to empty string. diff --git a/bin/named/client.c b/bin/named/client.c index baecc2345c..d4fb134b6d 100644 --- a/bin/named/client.c +++ b/bin/named/client.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: client.c,v 1.176.2.13.4.26 2005/07/27 02:53:14 marka Exp $ */ +/* $Id: client.c,v 1.176.2.13.4.27 2006/01/04 05:13:19 marka Exp $ */ #include @@ -164,6 +164,12 @@ struct ns_clientmgr { * Must be greater than any valid state. */ +/* + * Enable ns_client_dropport() by default. + */ +#ifndef NS_CLIENT_DROPPORT +#define NS_CLIENT_DROPPORT 1 +#endif static void client_read(ns_client_t *client); static void client_accept(ns_client_t *client); @@ -972,6 +978,34 @@ ns_client_send(ns_client_t *client) { ns_client_next(client, result); } +#if NS_CLIENT_DROPPORT +#define DROPPORT_NO 0 +#define DROPPORT_REQUEST 1 +#define DROPPORT_RESPONSE 2 +/*% + * ns_client_dropport determines if certain requests / responses + * should be dropped based on the port number. + * + * Returns: + * \li 0: Don't drop. + * \li 1: Drop request. + * \li 2: Drop (error) response. + */ +static int +ns_client_dropport(in_port_t port) { + switch (port) { + case 7: /* echo */ + case 13: /* daytime */ + case 19: /* chargen */ + case 37: /* time */ + return (DROPPORT_REQUEST); + case 464: /* kpasswd */ + return (DROPPORT_RESPONSE); + } + return (DROPPORT_NO); +} +#endif + void ns_client_error(ns_client_t *client, isc_result_t result) { dns_rcode_t rcode; @@ -984,6 +1018,28 @@ ns_client_error(ns_client_t *client, isc_result_t result) { message = client->message; rcode = dns_result_torcode(result); +#if NS_CLIENT_DROPPORT + /* + * Don't send FORMERR to ports on the drop port list. + */ + if (rcode == dns_rcode_formerr && + ns_client_dropport(isc_sockaddr_getport(&client->peeraddr)) != + DROPPORT_NO) { + char buf[64]; + isc_buffer_t b; + + isc_buffer_init(&b, buf, sizeof(buf) - 1); + if (dns_rcode_totext(rcode, &b) != ISC_R_SUCCESS) + isc_buffer_putstr(&b, "UNKNOWN RCODE"); + ns_client_log(client, DNS_LOGCATEGORY_SECURITY, + NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), + "dropped error (%.*s) response: suspicious port", + (int)isc_buffer_usedlength(&b), buf); + ns_client_next(client, ISC_R_SUCCESS); + return; + } +#endif + /* * Message may be an in-progress reply that we had trouble * with, in which case QR will be set. We need to clear QR before @@ -1208,6 +1264,17 @@ client_request(isc_task_t *task, isc_event_t *event) { isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); +#if NS_CLIENT_DROPPORT + if (ns_client_dropport(isc_sockaddr_getport(&client->peeraddr)) == + DROPPORT_REQUEST) { + ns_client_log(client, DNS_LOGCATEGORY_SECURITY, + NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), + "dropped request: suspicious port"); + ns_client_next(client, ISC_R_SUCCESS); + goto cleanup; + } +#endif + ns_client_log(client, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), "%s request",