compute_cookie(ns_client_t *client, uint32_t when, uint32_t nonce,
const unsigned char *secret, isc_buffer_t *buf) {
unsigned char digest[ISC_MAX_MD_SIZE] ISC_NONSTRING = { 0 };
- STATIC_ASSERT(ISC_MAX_MD_SIZE >= ISC_SIPHASH24_TAG_LENGTH, "You need "
- "to "
- "increase "
- "the digest "
- "buffer.");
- STATIC_ASSERT(ISC_MAX_MD_SIZE >= ISC_AES_BLOCK_LENGTH, "You need to "
- "increase the "
- "digest "
- "buffer.");
+ STATIC_ASSERT(ISC_MAX_MD_SIZE >= ISC_SIPHASH24_TAG_LENGTH,
+ "You need to increase the digest buffer.");
+ STATIC_ASSERT(ISC_MAX_MD_SIZE >= ISC_AES_BLOCK_LENGTH,
+ "You need to increase the digest buffer.");
switch (client->manager->sctx->cookiealg) {
case ns_cookiealg_siphash24: {
} else {
ns_stats_increment(client->manager->sctx->nsstats,
ns_statscounter_cookiebadsize);
+ client->attributes |= NS_CLIENTATTR_BADCOOKIE;
}
return;
}
* Only accept COOKIE if we have talked to the client in the last hour.
*/
now = isc_stdtime_now();
- if (isc_serial_gt(when, (now + 300)) || /* In the future. */
- isc_serial_lt(when, (now - 3600)))
- { /* In the past. */
+ if (isc_serial_gt(when, (now + 300)) /* In the future. */ ||
+ isc_serial_lt(when, (now - 3600)) /* In the past. */)
+ {
+ client->attributes |= NS_CLIENTATTR_BADCOOKIE;
ns_stats_increment(client->manager->sctx->nsstats,
ns_statscounter_cookiebadtime);
return;
}
}
+ client->attributes |= NS_CLIENTATTR_BADCOOKIE;
ns_stats_increment(client->manager->sctx->nsstats,
ns_statscounter_cookienomatch);
}
#define NS_CLIENTATTR_MULTICAST 0x00008 /*%< recv'd from multicast */
#define NS_CLIENTATTR_WANTDNSSEC 0x00010 /*%< include dnssec records */
#define NS_CLIENTATTR_WANTNSID 0x00020 /*%< include nameserver ID */
-/* Obsolete: NS_CLIENTATTR_FILTER_AAAA 0x00040 */
+#define NS_CLIENTATTR_BADCOOKIE \
+ 0x00040 /*%< Presented cookie is bad/out-of-date */
/* Obsolete: NS_CLIENTATTR_FILTER_AAAA_RC 0x00080 */
#define NS_CLIENTATTR_WANTAD 0x00100 /*%< want AD in response if possible */
#define NS_CLIENTATTR_WANTCOOKIE 0x00200 /*%< return a COOKIE */
#define WANTDNSSEC(c) (((c)->attributes & NS_CLIENTATTR_WANTDNSSEC) != 0)
/*% Want WANTAD? */
#define WANTAD(c) (((c)->attributes & NS_CLIENTATTR_WANTAD) != 0)
+/*% Client presented a bad COOKIE. */
+#define BADCOOKIE(c) (((c)->attributes & NS_CLIENTATTR_BADCOOKIE) != 0)
/*% Client presented a valid COOKIE. */
#define HAVECOOKIE(c) (((c)->attributes & NS_CLIENTATTR_HAVECOOKIE) != 0)
/*% Client presented a COOKIE. */
CALL_HOOK(NS_QUERY_START_BEGIN, qctx);
/*
- * If we require a server cookie then send back BADCOOKIE
- * before we have done too much work.
+ * If we require a server cookie or the presented server
+ * cookie was bad then send back BADCOOKIE before we have
+ * done too much work.
*/
- if (!TCP(qctx->client) && qctx->view->requireservercookie &&
- WANTCOOKIE(qctx->client) && !HAVECOOKIE(qctx->client))
+ if (!TCP(qctx->client) &&
+ (BADCOOKIE(qctx->client) ||
+ (qctx->view->requireservercookie && WANTCOOKIE(qctx->client) &&
+ !HAVECOOKIE(qctx->client))))
{
qctx->client->message->flags &= ~DNS_MESSAGEFLAG_AA;
qctx->client->message->flags &= ~DNS_MESSAGEFLAG_AD;