} dig_ednsoptname_t;
dig_ednsoptname_t optnames[] = {
- { 1, "LLQ" }, /* draft-sekar-dns-llq */
- { 3, "NSID" }, /* RFC 5001 */
- { 5, "DAU" }, /* RFC 6975 */
- { 6, "DHU" }, /* RFC 6975 */
- { 7, "N3U" }, /* RFC 6975 */
- { 8, "ECS" }, /* RFC 7871 */
- { 9, "EXPIRE" }, /* RFC 7314 */
- { 10, "COOKIE" }, /* RFC 7873 */
- { 11, "KEEPALIVE" }, /* RFC 7828 */
- { 12, "PADDING" }, /* RFC 7830 */
- { 12, "PAD" }, /* shorthand */
- { 13, "CHAIN" }, /* RFC 7901 */
- { 14, "KEY-TAG" }, /* RFC 8145 */
- { 16, "CLIENT-TAG" }, /* draft-bellis-dnsop-edns-tags */
- { 17, "SERVER-TAG" }, /* draft-bellis-dnsop-edns-tags */
- { 26946, "DEVICEID" }, /* Brian Hartvigsen */
+ { 1, "LLQ" }, /* draft-sekar-dns-llq */
+ { 3, "NSID" }, /* RFC 5001 */
+ { 5, "DAU" }, /* RFC 6975 */
+ { 6, "DHU" }, /* RFC 6975 */
+ { 7, "N3U" }, /* RFC 6975 */
+ { 8, "ECS" }, /* RFC 7871 */
+ { 9, "EXPIRE" }, /* RFC 7314 */
+ { 10, "COOKIE" }, /* RFC 7873 */
+ { 11, "KEEPALIVE" }, /* RFC 7828 */
+ { 12, "PADDING" }, /* RFC 7830 */
+ { 12, "PAD" }, /* shorthand */
+ { 13, "CHAIN" }, /* RFC 7901 */
+ { 14, "KEY-TAG" }, /* RFC 8145 */
+ { 15, "EDE" }, /* ietf-dnsop-extended-error-16 */
+ { 16, "CLIENT-TAG" }, /* draft-bellis-dnsop-edns-tags */
+ { 17, "SERVER-TAG" }, /* draft-bellis-dnsop-edns-tags */
+ { 26946, "DEVICEID" }, /* Brian Hartvigsen */
};
#define N_EDNS_OPTNAMES (sizeof(optnames) / sizeof(optnames[0]))
#define DNS_MESSAGEEXTFLAG_DO 0x8000U
/*%< EDNS0 extended OPT codes */
-#define DNS_OPT_LLQ 1 /*%< LLQ opt code */
-#define DNS_OPT_NSID 3 /*%< NSID opt code */
-#define DNS_OPT_CLIENT_SUBNET 8 /*%< client subnet opt code */
-#define DNS_OPT_EXPIRE 9 /*%< EXPIRE opt code */
-#define DNS_OPT_COOKIE 10 /*%< COOKIE opt code */
-#define DNS_OPT_PAD 12 /*%< PAD opt code */
-#define DNS_OPT_KEY_TAG 14 /*%< Key tag opt code */
-#define DNS_OPT_CLIENT_TAG 16 /*%< Client tag opt code */
-#define DNS_OPT_SERVER_TAG 17 /*%< Server tag opt code */
+#define DNS_OPT_LLQ 1 /*%< LLQ opt code */
+#define DNS_OPT_NSID 3 /*%< NSID opt code */
+#define DNS_OPT_CLIENT_SUBNET 8 /*%< client subnet opt code */
+#define DNS_OPT_EXPIRE 9 /*%< EXPIRE opt code */
+#define DNS_OPT_COOKIE 10 /*%< COOKIE opt code */
+#define DNS_OPT_TCP_KEEPALIVE 11 /*%< TCP keepalive opt code */
+#define DNS_OPT_PAD 12 /*%< PAD opt code */
+#define DNS_OPT_KEY_TAG 14 /*%< Key tag opt code */
+#define DNS_OPT_EDE 15 /*%< Extended DNS Error opt code */
+#define DNS_OPT_CLIENT_TAG 16 /*%< Client tag opt code */
+#define DNS_OPT_SERVER_TAG 17 /*%< Server tag opt code */
/*%< Experimental options [65001...65534] as per RFC6891 */
#include <isc/buffer.h>
#include <isc/mem.h>
#include <isc/print.h>
-#include <isc/string.h> /* Required for HP/UX (and others?) */
+#include <isc/string.h> /* Required for HP/UX (and others?) */
+#include <isc/utf8.h>
#include <isc/util.h>
#include <dns/dnssec.h>
"RESERVED15"
};
+static const char *edetext[] = { "Other",
+ "Unsupported DNSKEY Algorithm",
+ "Unsupported DS Digest Type",
+ "Stale Answer",
+ "Forged Answer",
+ "DNSSEC Indeterminate",
+ "DNSSEC Bogus",
+ "Signature Expired",
+ "Signature Not Yet Valid",
+ "DNSKEY Missing",
+ "RRSIGs Missing",
+ "No Zone Key Bit Set",
+ "NSEC Missing",
+ "Cached Error",
+ "Not Ready",
+ "Blocked",
+ "Censored",
+ "Filtered",
+ "Prohibited",
+ "Stale NXDOMAIN Answer",
+ "Not Authoritative",
+ "Not Supported",
+ "No Reachable Authority",
+ "Network Error",
+ "Invalid Data" };
+
/*%
* "helper" type, which consists of a block of some type, and is linkable.
* For it to work, sizeof(dns_msgblock_t) must be a multiple of the pointer
* Print EDNS info, if any.
*
* WARNING: The option contents may be malformed as
- * dig +ednsopt=value:<content> does not validity
+ * dig +ednsopt=value:<content> does not perform validity
* checking.
*/
dns_rdata_init(&rdata);
dns_rdataset_t *ps = NULL;
dns_name_t *name = NULL;
isc_result_t result;
- char buf[sizeof("1234567890")];
+ char buf[sizeof("1234567890 ")];
uint32_t mbz;
dns_rdata_t rdata;
isc_buffer_t optbuf;
ADD_STRING(target, "\n");
continue;
}
+ } else if (optcode == DNS_OPT_EDE) {
+ ADD_STRING(target, "; EDE:");
+ if (optlen >= 2U) {
+ uint16_t ede;
+ ede = isc_buffer_getuint16(&optbuf);
+ snprintf(buf, sizeof(buf), ": %u", ede);
+ ADD_STRING(target, buf);
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+ if (ede < ARRAY_SIZE(edetext)) {
+ ADD_STRING(target, " (");
+ ADD_STRING(target,
+ edetext[ede]);
+ ADD_STRING(target, ")");
+ }
+ optlen -= 2;
+ } else if (optlen == 1U) {
+ /* Malformed */
+ optdata = isc_buffer_current(&optbuf);
+ snprintf(buf, sizeof(buf),
+ " %02x (\"%c\")\n", optdata[0],
+ isprint(optdata[0])
+ ? optdata[0]
+ : '.');
+ isc_buffer_forward(&optbuf, optlen);
+ ADD_STRING(target, buf);
+ continue;
+ }
} else if (optcode == DNS_OPT_CLIENT_TAG) {
uint16_t id;
ADD_STRING(target, "; CLIENT-TAG");
ADD_STRING(target, ": ");
optdata = isc_buffer_current(&optbuf);
- for (i = 0; i < optlen; i++) {
- const char *sep;
- switch (optcode) {
- case DNS_OPT_COOKIE:
- sep = "";
- break;
- default:
- sep = " ";
- break;
+ if (optcode != DNS_OPT_EDE) {
+ for (i = 0; i < optlen; i++) {
+ const char *sep;
+ switch (optcode) {
+ case DNS_OPT_COOKIE:
+ sep = "";
+ break;
+ default:
+ sep = " ";
+ break;
+ }
+ snprintf(buf, sizeof(buf),
+ "%02x%s", optdata[i],
+ sep);
+ ADD_STRING(target, buf);
}
- snprintf(buf, sizeof(buf), "%02x%s",
- optdata[i], sep);
- ADD_STRING(target, buf);
}
isc_buffer_forward(&optbuf, optlen);
/*
* For non-COOKIE options, add a printable
- * version
+ * version.
*/
- ADD_STRING(target, "(\"");
+ if (optcode != DNS_OPT_EDE) {
+ ADD_STRING(target, "(\"");
+ } else {
+ ADD_STRING(target, "(");
+ }
if (isc_buffer_availablelength(target) < optlen)
return (ISC_R_NOSPACE);
for (i = 0; i < optlen; i++) {
else
isc_buffer_putstr(target, ".");
}
- ADD_STRING(target, "\")");
+ if (optcode != DNS_OPT_EDE) {
+ ADD_STRING(target, "\")");
+ } else {
+ ADD_STRING(target, ")");
+ }
}
ADD_STRING(target, "\n");
}
DNS_RDATATYPEATTR_META | \
DNS_RDATATYPEATTR_NOTQUESTION)
+#include <isc/utf8.h>
+
static inline isc_result_t
fromtext_opt(ARGS_FROMTEXT) {
/*
}
isc_region_consume(&sregion, length);
break;
+ case DNS_OPT_EDE:
+ if (length < 2) {
+ return (DNS_R_OPTERR);
+ }
+ /* UTF-8 Byte Order Mark is not permitted. RFC 5198 */
+ if (isc_utf8_bom(sregion.base + 2, length - 2)) {
+ return (DNS_R_OPTERR);
+ }
+ /*
+ * The EXTRA-TEXT field is specified as UTF-8, and
+ * therefore must be validated for correctness
+ * according to RFC 3269 security considerations.
+ */
+ if (!isc_utf8_valid(sregion.base + 2, length - 2)) {
+ return (DNS_R_OPTERR);
+ }
+ isc_region_consume(&sregion, length);
+ break;
case DNS_OPT_CLIENT_TAG:
/* FALLTHROUGH */
case DNS_OPT_SERVER_TAG:
rwlock.@O@ \
safe.@O@ serial.@O@ siphash.@O@ sha1.@O@ sha2.@O@ sockaddr.@O@ stats.@O@ \
string.@O@ strtoul.@O@ symtab.@O@ task.@O@ taskpool.@O@ \
- tm.@O@ timer.@O@ version.@O@ \
+ tm.@O@ timer.@O@ utf8.@O@ version.@O@ \
${UNIXOBJS} ${NLSOBJS} ${THREADOBJS}
SYMTBLOBJS = backtrace-emptytbl.@O@
ratelimiter.c refcount.c region.c regex.c result.c rwlock.c \
safe.c serial.c siphash.c sha1.c sha2.c sockaddr.c stats.c string.c \
strtoul.c symtab.c task.c taskpool.c timer.c \
- tm.c version.c
+ tm.c utf8.c version.c
LIBS = @ISC_OPENSSL_LIBS@ @LIBS@
region.h resource.h result.h resultclass.h rwlock.h \
safe.h serial.h siphash.h sha1.h sha2.h sockaddr.h socket.h \
stats.h stdatomic.h stdio.h stdlib.h string.h symtab.h task.h \
- taskpool.h timer.h tm.h types.h util.h version.h \
+ taskpool.h timer.h tm.h types.h utf8.h util.h version.h \
xml.h
SUBDIRS =
--- /dev/null
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+/*! \file isc/utf8.h */
+
+#pragma once
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+bool
+isc_utf8_bom(const unsigned char *buf, size_t len);
+/*<
+ * Returns 'true' if the string of bytes in 'buf' starts
+ * with an UTF-8 Byte Order Mark.
+ *
+ * Requires:
+ *\li 'buf' != NULL
+ */
+
+bool
+isc_utf8_valid(const unsigned char *buf, size_t len);
+/*<
+ * Returns 'true' if the string of bytes in 'buf' is a valid UTF-8
+ * byte sequence otherwise 'false' is returned.
+ *
+ * Requires:
+ *\li 'buf' != NULL
+ */
+
+ISC_LANG_ENDDECLS
--- /dev/null
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#include <config.h>
+
+#include <string.h>
+
+#include <isc/utf8.h>
+#include <isc/util.h>
+
+/*
+ * UTF-8 is defined in "The Unicode Standard -- Version 4.0"
+ * Also see RFC 3629.
+ *
+ * Char. number range | UTF-8 octet sequence
+ * (hexadecimal) | (binary)
+ * --------------------+---------------------------------------------
+ * 0000 0000-0000 007F | 0xxxxxxx
+ * 0000 0080-0000 07FF | 110xxxxx 10xxxxxx
+ * 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
+ * 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ */
+bool
+isc_utf8_valid(const unsigned char *buf, size_t len) {
+ REQUIRE(buf != NULL);
+
+ for (size_t i = 0; i < len; i++) {
+ if (buf[i] <= 0x7f) {
+ continue;
+ }
+ if ((i + 1) < len && (buf[i] & 0xe0) == 0xc0 &&
+ (buf[i + 1] & 0xc0) == 0x80) {
+ unsigned int w;
+ w = (buf[i] & 0x1f) << 6;
+ w |= (buf[++i] & 0x3f);
+ if (w < 0x80) {
+ return (false);
+ }
+ continue;
+ }
+ if ((i + 2) < len && (buf[i] & 0xf0) == 0xe0 &&
+ (buf[i + 1] & 0xc0) == 0x80 && (buf[i + 2] & 0xc0) == 0x80)
+ {
+ unsigned int w;
+ w = (buf[i] & 0x0f) << 12;
+ w |= (buf[++i] & 0x3f) << 6;
+ w |= (buf[++i] & 0x3f);
+ if (w < 0x0800) {
+ return (false);
+ }
+ continue;
+ }
+ if ((i + 3) < len && (buf[i] & 0xf8) == 0xf0 &&
+ (buf[i + 1] & 0xc0) == 0x80 &&
+ (buf[i + 2] & 0xc0) == 0x80 && (buf[i + 3] & 0xc0) == 0x80)
+ {
+ unsigned int w;
+ w = (buf[i] & 0x07) << 18;
+ w |= (buf[++i] & 0x3f) << 12;
+ w |= (buf[++i] & 0x3f) << 6;
+ w |= (buf[++i] & 0x3f);
+ if (w < 0x10000 || w > 0x10FFFF) {
+ return (false);
+ }
+ continue;
+ }
+ return (false);
+ }
+ return (true);
+}
+
+bool
+isc_utf8_bom(const unsigned char *buf, size_t len) {
+ REQUIRE(buf != NULL);
+
+ if (len >= 3U && !memcmp(buf, "\xef\xbb\xbf", 3)) {
+ return (true);
+ }
+ return (false);
+}
isc_timermgr_poke
isc_tm_timegm
isc_tm_strptime
+isc_utf8_bom
+isc_utf8_valid
isc_win32os_versioncheck
openlog
@IF PKCS11
<ClInclude Include="..\include\isc\types.h">
<Filter>Library Header Files</Filter>
</ClInclude>
+ <ClInclude Include="..\include\isc\utf8.h">
+ <Filter>Library Header Files</Filter>
+ </ClInclude>
<ClInclude Include="..\include\isc\util.h">
<Filter>Library Header Files</Filter>
</ClInclude>
<ClCompile Include="..\tm.c">
<Filter>Library Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\utf8.c">
+ <Filter>Library Source Files</Filter>
+ </ClCompile>
@IF PKCS11
<ClCompile Include="..\pk11.c">
<Filter>Library Source Files</Filter>
<ClInclude Include="..\include\isc\timer.h" />
<ClInclude Include="..\include\isc\tm.h" />
<ClInclude Include="..\include\isc\types.h" />
+ <ClInclude Include="..\include\isc\utf8.h" />
<ClInclude Include="..\include\isc\util.h" />
<ClInclude Include="..\include\isc\version.h" />
<ClInclude Include="..\include\isc\xml.h" />
<ClCompile Include="..\taskpool.c" />
<ClCompile Include="..\timer.c" />
<ClCompile Include="..\tm.c" />
+ <ClCompile Include="..\utf8.c" />
@IF PKCS11
<ClCompile Include="..\pk11.c" />
<ClCompile Include="..\pk11_result.c" />
./lib/isc/include/isc/timer.h C 1998,1999,2000,2001,2002,2004,2005,2006,2007,2008,2009,2012,2013,2014,2016,2018,2019,2020
./lib/isc/include/isc/tm.h C 2014,2016,2018,2019,2020
./lib/isc/include/isc/types.h C 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2012,2013,2014,2016,2018,2019,2020
+./lib/isc/include/isc/utf8.h C 2020
./lib/isc/include/isc/util.h C 1998,1999,2000,2001,2004,2005,2006,2007,2010,2011,2012,2015,2016,2017,2018,2019,2020
./lib/isc/include/isc/version.h C 2001,2004,2005,2006,2007,2016,2018,2019,2020
./lib/isc/include/isc/xml.h C 2006,2007,2016,2018,2019,2020
./lib/isc/unix/strerror.c C 2001,2004,2005,2007,2009,2016,2018,2019,2020
./lib/isc/unix/syslog.c C 2001,2004,2005,2007,2016,2018,2019,2020
./lib/isc/unix/time.c C 1998,1999,2000,2001,2003,2004,2005,2006,2007,2008,2011,2012,2014,2015,2016,2017,2018,2019,2020
+./lib/isc/utf8.c C 2020
./lib/isc/version.c C 1998,1999,2000,2001,2004,2005,2007,2016,2018,2019,2020
./lib/isc/win32/DLLMain.c C 2001,2004,2007,2016,2018,2019,2020
./lib/isc/win32/Makefile.in MAKE 1999,2000,2001,2004,2007,2009,2012,2014,2015,2016,2018,2019,2020