mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
Add new default siphash24 cookie algorithm, but keep AES as legacy
This commit changes the BIND cookie algorithms to match draft-sury-toorop-dnsop-server-cookies-00. Namely, it changes the Client Cookie algorithm to use SipHash 2-4, adds the new Server Cookie algorithm using SipHash 2-4, and changes the default for the Server Cookie algorithm to be siphash24. Add siphash24 cookie algorithm, and make it keep legacy aes as
This commit is contained in:
parent
afa81ee4e4
commit
a912f31398
19 changed files with 165 additions and 86 deletions
|
|
@ -50,7 +50,7 @@ options {\n\
|
||||||
automatic-interface-scan yes;\n\
|
automatic-interface-scan yes;\n\
|
||||||
bindkeys-file \"" NAMED_SYSCONFDIR "/bind.keys\";\n\
|
bindkeys-file \"" NAMED_SYSCONFDIR "/bind.keys\";\n\
|
||||||
# blackhole {none;};\n"
|
# blackhole {none;};\n"
|
||||||
" cookie-algorithm aes;\n"
|
" cookie-algorithm siphash24;\n"
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
" coresize default;\n\
|
" coresize default;\n\
|
||||||
datasize default;\n"
|
datasize default;\n"
|
||||||
|
|
|
||||||
|
|
@ -222,7 +222,7 @@ options {
|
||||||
check-srv-cname ( fail | warn | ignore );
|
check-srv-cname ( fail | warn | ignore );
|
||||||
check-wildcard <replaceable>boolean</replaceable>;
|
check-wildcard <replaceable>boolean</replaceable>;
|
||||||
clients-per-query <replaceable>integer</replaceable>;
|
clients-per-query <replaceable>integer</replaceable>;
|
||||||
cookie-algorithm ( aes );
|
cookie-algorithm ( aes | siphash24 );
|
||||||
cookie-secret <replaceable>string</replaceable>;
|
cookie-secret <replaceable>string</replaceable>;
|
||||||
coresize ( default | unlimited | <replaceable>sizeval</replaceable> );
|
coresize ( default | unlimited | <replaceable>sizeval</replaceable> );
|
||||||
datasize ( default | unlimited | <replaceable>sizeval</replaceable> );
|
datasize ( default | unlimited | <replaceable>sizeval</replaceable> );
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@
|
||||||
#include <isc/print.h>
|
#include <isc/print.h>
|
||||||
#include <isc/refcount.h>
|
#include <isc/refcount.h>
|
||||||
#include <isc/resource.h>
|
#include <isc/resource.h>
|
||||||
|
#include <isc/siphash.h>
|
||||||
#include <isc/socket.h>
|
#include <isc/socket.h>
|
||||||
#include <isc/stat.h>
|
#include <isc/stat.h>
|
||||||
#include <isc/stats.h>
|
#include <isc/stats.h>
|
||||||
|
|
@ -9129,7 +9130,9 @@ load_configuration(const char *filename, named_server_t *server,
|
||||||
obj = NULL;
|
obj = NULL;
|
||||||
result = named_config_get(maps, "cookie-algorithm", &obj);
|
result = named_config_get(maps, "cookie-algorithm", &obj);
|
||||||
INSIST(result == ISC_R_SUCCESS);
|
INSIST(result == ISC_R_SUCCESS);
|
||||||
if (strcasecmp(cfg_obj_asstring(obj), "aes") == 0) {
|
if (strcasecmp(cfg_obj_asstring(obj), "siphash24") == 0) {
|
||||||
|
server->sctx->cookiealg = ns_cookiealg_siphash24;
|
||||||
|
} else if (strcasecmp(cfg_obj_asstring(obj), "aes") == 0) {
|
||||||
server->sctx->cookiealg = ns_cookiealg_aes;
|
server->sctx->cookiealg = ns_cookiealg_aes;
|
||||||
} else {
|
} else {
|
||||||
INSIST(0);
|
INSIST(0);
|
||||||
|
|
@ -9188,12 +9191,18 @@ load_configuration(const char *filename, named_server_t *server,
|
||||||
|
|
||||||
usedlength = isc_buffer_usedlength(&b);
|
usedlength = isc_buffer_usedlength(&b);
|
||||||
switch (server->sctx->cookiealg) {
|
switch (server->sctx->cookiealg) {
|
||||||
|
case ns_cookiealg_siphash24:
|
||||||
|
expectedlength = ISC_SIPHASH24_KEY_LENGTH;
|
||||||
|
if (usedlength != expectedlength) {
|
||||||
|
CHECKM(ISC_R_RANGE,
|
||||||
|
"SipHash-2-4 cookie-secret must be 128 bits");
|
||||||
|
}
|
||||||
|
break;
|
||||||
case ns_cookiealg_aes:
|
case ns_cookiealg_aes:
|
||||||
expectedlength = ISC_AES128_KEYLENGTH;
|
expectedlength = ISC_AES128_KEYLENGTH;
|
||||||
if (usedlength != expectedlength) {
|
if (usedlength != expectedlength) {
|
||||||
CHECKM(ISC_R_RANGE,
|
CHECKM(ISC_R_RANGE,
|
||||||
"AES cookie-secret must be "
|
"AES cookie-secret must be 128 bits");
|
||||||
"128 bits");
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
options {
|
options {
|
||||||
cookie-algorithm sha1;
|
cookie-algorithm aes;
|
||||||
cookie-secret "ebc7701beabb4a40c57d140eeb6733fafba4272f"; // 160 bits
|
cookie-secret "ebc7701beabb4a40c57d140eeb6733faaa"; // 136 bits
|
||||||
};
|
};
|
||||||
|
|
@ -10,6 +10,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
options {
|
options {
|
||||||
cookie-algorithm sha256;
|
cookie-algorithm siphash24;
|
||||||
cookie-secret "ebc7701beabb4a40c57d140eeb6733fafba4272f"; // 160 bits
|
cookie-secret "ebc7701beabb4a40c57d140eeb6733faaabbccdd"; // 160 bits
|
||||||
};
|
};
|
||||||
|
|
@ -10,6 +10,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
options {
|
options {
|
||||||
cookie-algorithm sha1;
|
cookie-algorithm aes;
|
||||||
cookie-secret "ebc7701beabb4a40c57d140eeb6733fafba4272fff"; // 168 bits
|
cookie-secret "ebc7701beabb4a40c57d140eeb6733fa"; // 128 bits
|
||||||
};
|
};
|
||||||
|
|
@ -10,6 +10,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
options {
|
options {
|
||||||
cookie-algorithm sha256;
|
cookie-algorithm siphash24;
|
||||||
cookie-secret "b174e3800b6734f73268f15831c957860a8ee1229cfb9039c1514836f53efbed";
|
cookie-secret "ebc7701beabb4a40c57d140eeb6733fa"; // 128 bits
|
||||||
};
|
};
|
||||||
|
|
@ -28,8 +28,8 @@ options {
|
||||||
listen-on-v6 { none; };
|
listen-on-v6 { none; };
|
||||||
recursion yes;
|
recursion yes;
|
||||||
dnssec-validation yes;
|
dnssec-validation yes;
|
||||||
cookie-algorithm sha1;
|
cookie-algorithm siphash24;
|
||||||
cookie-secret "569d36a6cc27d6bf55502183302ba352745255a2";
|
cookie-secret "569d36a6cc27d6bf55502183302ba352";
|
||||||
require-server-cookie yes;
|
require-server-cookie yes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,9 @@ options {
|
||||||
listen-on-v6 { none; };
|
listen-on-v6 { none; };
|
||||||
recursion yes;
|
recursion yes;
|
||||||
dnssec-validation yes;
|
dnssec-validation yes;
|
||||||
cookie-algorithm sha1;
|
cookie-algorithm siphash24;
|
||||||
cookie-secret "569d36a6cc27d6bf55502183302ba352745255a2";
|
cookie-secret "569d36a6cc27d6bf55502183302ba352";
|
||||||
cookie-secret "6b300e27a0db46d4b046e4189790fa7db3c1ffb3";
|
cookie-secret "6b300e27a0db46d4b046e4189790fa7d";
|
||||||
require-server-cookie yes;
|
require-server-cookie yes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,8 @@ options {
|
||||||
listen-on-v6 { none; };
|
listen-on-v6 { none; };
|
||||||
recursion yes;
|
recursion yes;
|
||||||
dnssec-validation yes;
|
dnssec-validation yes;
|
||||||
cookie-algorithm sha1;
|
cookie-algorithm siphash24;
|
||||||
cookie-secret "6b300e27a0db46d4b046e4189790fa7db3c1ffb3";
|
cookie-secret "6b300e27a0db46d4b046e4189790fa7d";
|
||||||
require-server-cookie yes;
|
require-server-cookie yes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -211,12 +211,12 @@ status=`expr $status + $ret`
|
||||||
#
|
#
|
||||||
# Test shared cookie-secret support.
|
# Test shared cookie-secret support.
|
||||||
#
|
#
|
||||||
# NS4 has cookie-secret "569d36a6cc27d6bf55502183302ba352745255a2";
|
# NS4 has cookie-secret "569d36a6cc27d6bf55502183302ba352";
|
||||||
#
|
#
|
||||||
# NS5 has cookie-secret "569d36a6cc27d6bf55502183302ba352745255a2";
|
# NS5 has cookie-secret "569d36a6cc27d6bf55502183302ba352";
|
||||||
# NS5 has cookie-secret "6b300e27a0db46d4b046e4189790fa7db3c1ffb3"; (alternate)
|
# NS5 has cookie-secret "6b300e27a0db46d4b046e4189790fa7d"; (alternate)
|
||||||
#
|
#
|
||||||
# NS6 has cookie-secret "6b300e27a0db46d4b046e4189790fa7db3c1ffb3";
|
# NS6 has cookie-secret "6b300e27a0db46d4b046e4189790fa7d";
|
||||||
#
|
#
|
||||||
# Server cookies from NS4 are accepted by NS5 and not NS6
|
# Server cookies from NS4 are accepted by NS5 and not NS6
|
||||||
# Server cookies from NS5 are accepted by NS4 and not NS6
|
# Server cookies from NS5 are accepted by NS4 and not NS6
|
||||||
|
|
|
||||||
24
configure
vendored
24
configure
vendored
|
|
@ -850,7 +850,6 @@ infodir
|
||||||
docdir
|
docdir
|
||||||
oldincludedir
|
oldincludedir
|
||||||
includedir
|
includedir
|
||||||
runstatedir
|
|
||||||
localstatedir
|
localstatedir
|
||||||
sharedstatedir
|
sharedstatedir
|
||||||
sysconfdir
|
sysconfdir
|
||||||
|
|
@ -1019,7 +1018,6 @@ datadir='${datarootdir}'
|
||||||
sysconfdir='${prefix}/etc'
|
sysconfdir='${prefix}/etc'
|
||||||
sharedstatedir='${prefix}/com'
|
sharedstatedir='${prefix}/com'
|
||||||
localstatedir='${prefix}/var'
|
localstatedir='${prefix}/var'
|
||||||
runstatedir='${localstatedir}/run'
|
|
||||||
includedir='${prefix}/include'
|
includedir='${prefix}/include'
|
||||||
oldincludedir='/usr/include'
|
oldincludedir='/usr/include'
|
||||||
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
|
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
|
||||||
|
|
@ -1272,15 +1270,6 @@ do
|
||||||
| -silent | --silent | --silen | --sile | --sil)
|
| -silent | --silent | --silen | --sile | --sil)
|
||||||
silent=yes ;;
|
silent=yes ;;
|
||||||
|
|
||||||
-runstatedir | --runstatedir | --runstatedi | --runstated \
|
|
||||||
| --runstate | --runstat | --runsta | --runst | --runs \
|
|
||||||
| --run | --ru | --r)
|
|
||||||
ac_prev=runstatedir ;;
|
|
||||||
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
|
|
||||||
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
|
|
||||||
| --run=* | --ru=* | --r=*)
|
|
||||||
runstatedir=$ac_optarg ;;
|
|
||||||
|
|
||||||
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
|
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
|
||||||
ac_prev=sbindir ;;
|
ac_prev=sbindir ;;
|
||||||
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
|
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
|
||||||
|
|
@ -1418,7 +1407,7 @@ fi
|
||||||
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
|
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
|
||||||
datadir sysconfdir sharedstatedir localstatedir includedir \
|
datadir sysconfdir sharedstatedir localstatedir includedir \
|
||||||
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
|
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
|
||||||
libdir localedir mandir runstatedir
|
libdir localedir mandir
|
||||||
do
|
do
|
||||||
eval ac_val=\$$ac_var
|
eval ac_val=\$$ac_var
|
||||||
# Remove trailing slashes.
|
# Remove trailing slashes.
|
||||||
|
|
@ -1571,7 +1560,6 @@ Fine tuning of the installation directories:
|
||||||
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
|
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
|
||||||
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
|
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
|
||||||
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
|
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
|
||||||
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
|
|
||||||
--libdir=DIR object code libraries [EPREFIX/lib]
|
--libdir=DIR object code libraries [EPREFIX/lib]
|
||||||
--includedir=DIR C header files [PREFIX/include]
|
--includedir=DIR C header files [PREFIX/include]
|
||||||
--oldincludedir=DIR C header files for non-gcc [/usr/include]
|
--oldincludedir=DIR C header files for non-gcc [/usr/include]
|
||||||
|
|
@ -4010,7 +3998,7 @@ else
|
||||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||||
since some C++ compilers masquerading as C compilers
|
since some C++ compilers masquerading as C compilers
|
||||||
incorrectly reject 9223372036854775807. */
|
incorrectly reject 9223372036854775807. */
|
||||||
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
|
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
|
||||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||||
&& LARGE_OFF_T % 2147483647 == 1)
|
&& LARGE_OFF_T % 2147483647 == 1)
|
||||||
? 1 : -1];
|
? 1 : -1];
|
||||||
|
|
@ -4056,7 +4044,7 @@ else
|
||||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||||
since some C++ compilers masquerading as C compilers
|
since some C++ compilers masquerading as C compilers
|
||||||
incorrectly reject 9223372036854775807. */
|
incorrectly reject 9223372036854775807. */
|
||||||
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
|
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
|
||||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||||
&& LARGE_OFF_T % 2147483647 == 1)
|
&& LARGE_OFF_T % 2147483647 == 1)
|
||||||
? 1 : -1];
|
? 1 : -1];
|
||||||
|
|
@ -4080,7 +4068,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||||
since some C++ compilers masquerading as C compilers
|
since some C++ compilers masquerading as C compilers
|
||||||
incorrectly reject 9223372036854775807. */
|
incorrectly reject 9223372036854775807. */
|
||||||
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
|
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
|
||||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||||
&& LARGE_OFF_T % 2147483647 == 1)
|
&& LARGE_OFF_T % 2147483647 == 1)
|
||||||
? 1 : -1];
|
? 1 : -1];
|
||||||
|
|
@ -4125,7 +4113,7 @@ else
|
||||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||||
since some C++ compilers masquerading as C compilers
|
since some C++ compilers masquerading as C compilers
|
||||||
incorrectly reject 9223372036854775807. */
|
incorrectly reject 9223372036854775807. */
|
||||||
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
|
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
|
||||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||||
&& LARGE_OFF_T % 2147483647 == 1)
|
&& LARGE_OFF_T % 2147483647 == 1)
|
||||||
? 1 : -1];
|
? 1 : -1];
|
||||||
|
|
@ -4149,7 +4137,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||||
since some C++ compilers masquerading as C compilers
|
since some C++ compilers masquerading as C compilers
|
||||||
incorrectly reject 9223372036854775807. */
|
incorrectly reject 9223372036854775807. */
|
||||||
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
|
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
|
||||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||||
&& LARGE_OFF_T % 2147483647 == 1)
|
&& LARGE_OFF_T % 2147483647 == 1)
|
||||||
? 1 : -1];
|
? 1 : -1];
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,7 @@ options {
|
||||||
check-wildcard <boolean>;
|
check-wildcard <boolean>;
|
||||||
cleaning-interval <integer>; // obsolete
|
cleaning-interval <integer>; // obsolete
|
||||||
clients-per-query <integer>;
|
clients-per-query <integer>;
|
||||||
cookie-algorithm ( aes );
|
cookie-algorithm ( aes | siphash24 );
|
||||||
cookie-secret <string>; // may occur multiple times
|
cookie-secret <string>; // may occur multiple times
|
||||||
coresize ( default | unlimited | <sizeval> );
|
coresize ( default | unlimited | <sizeval> );
|
||||||
datasize ( default | unlimited | <sizeval> );
|
datasize ( default | unlimited | <sizeval> );
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
#include <isc/print.h>
|
#include <isc/print.h>
|
||||||
#include <isc/region.h>
|
#include <isc/region.h>
|
||||||
#include <isc/result.h>
|
#include <isc/result.h>
|
||||||
|
#include <isc/siphash.h>
|
||||||
#include <isc/sockaddr.h>
|
#include <isc/sockaddr.h>
|
||||||
#include <isc/string.h>
|
#include <isc/string.h>
|
||||||
#include <isc/symtab.h>
|
#include <isc/symtab.h>
|
||||||
|
|
@ -857,7 +858,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
|
||||||
dns_name_t *name;
|
dns_name_t *name;
|
||||||
isc_buffer_t b;
|
isc_buffer_t b;
|
||||||
uint32_t lifetime = 3600;
|
uint32_t lifetime = 3600;
|
||||||
const char *ccalg = "aes";
|
const char *ccalg = "siphash24";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* { "name", scale, value }
|
* { "name", scale, value }
|
||||||
|
|
@ -1350,8 +1351,14 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
|
||||||
if (strcasecmp(ccalg, "aes") == 0 &&
|
if (strcasecmp(ccalg, "aes") == 0 &&
|
||||||
usedlength != ISC_AES128_KEYLENGTH) {
|
usedlength != ISC_AES128_KEYLENGTH) {
|
||||||
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
||||||
"AES cookie-secret must be "
|
"AES cookie-secret must be 128 bits");
|
||||||
"128 bits");
|
if (result == ISC_R_SUCCESS)
|
||||||
|
result = ISC_R_RANGE;
|
||||||
|
}
|
||||||
|
if (strcasecmp(ccalg, "siphash24") == 0 &&
|
||||||
|
usedlength != ISC_SIPHASH24_KEY_LENGTH) {
|
||||||
|
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
||||||
|
"SipHash-2-4 cookie-secret must be 128 bits");
|
||||||
if (result == ISC_R_SUCCESS)
|
if (result == ISC_R_SUCCESS)
|
||||||
result = ISC_R_RANGE;
|
result = ISC_R_RANGE;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,14 +21,13 @@
|
||||||
#include <isc/print.h>
|
#include <isc/print.h>
|
||||||
#include <isc/string.h>
|
#include <isc/string.h>
|
||||||
#include <isc/random.h>
|
#include <isc/random.h>
|
||||||
|
#include <isc/siphash.h>
|
||||||
#include <isc/socket.h>
|
#include <isc/socket.h>
|
||||||
#include <isc/stats.h>
|
#include <isc/stats.h>
|
||||||
#include <isc/task.h>
|
#include <isc/task.h>
|
||||||
#include <isc/timer.h>
|
#include <isc/timer.h>
|
||||||
#include <isc/util.h>
|
#include <isc/util.h>
|
||||||
|
|
||||||
#include <isc/aes.h>
|
|
||||||
|
|
||||||
#include <dns/acl.h>
|
#include <dns/acl.h>
|
||||||
#include <dns/adb.h>
|
#include <dns/adb.h>
|
||||||
#include <dns/badcache.h>
|
#include <dns/badcache.h>
|
||||||
|
|
@ -201,7 +200,7 @@ typedef struct query {
|
||||||
isc_mem_t * mctx;
|
isc_mem_t * mctx;
|
||||||
dns_dispatchmgr_t * dispatchmgr;
|
dns_dispatchmgr_t * dispatchmgr;
|
||||||
dns_dispatch_t * dispatch;
|
dns_dispatch_t * dispatch;
|
||||||
bool exclusivesocket;
|
bool exclusivesocket;
|
||||||
dns_adbaddrinfo_t * addrinfo;
|
dns_adbaddrinfo_t * addrinfo;
|
||||||
isc_socket_t * tcpsocket;
|
isc_socket_t * tcpsocket;
|
||||||
isc_time_t start;
|
isc_time_t start;
|
||||||
|
|
@ -213,7 +212,7 @@ typedef struct query {
|
||||||
dns_tsigkey_t *tsigkey;
|
dns_tsigkey_t *tsigkey;
|
||||||
isc_socketevent_t sendevent;
|
isc_socketevent_t sendevent;
|
||||||
isc_dscp_t dscp;
|
isc_dscp_t dscp;
|
||||||
int ednsversion;
|
int ednsversion;
|
||||||
unsigned int options;
|
unsigned int options;
|
||||||
isc_sockeventattr_t attributes;
|
isc_sockeventattr_t attributes;
|
||||||
unsigned int sends;
|
unsigned int sends;
|
||||||
|
|
@ -2271,29 +2270,56 @@ add_triededns512(fetchctx_t *fctx, isc_sockaddr_t *address) {
|
||||||
ISC_LIST_INITANDAPPEND(fctx->edns512, tried, link);
|
ISC_LIST_INITANDAPPEND(fctx->edns512, tried, link);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static inline size_t
|
||||||
compute_cc(resquery_t *query, unsigned char *cookie, size_t len) {
|
addr2buf(void *buf, const size_t bufsize, const isc_sockaddr_t *sockaddr) {
|
||||||
unsigned char digest[ISC_AES_BLOCK_LENGTH];
|
|
||||||
unsigned char input[16];
|
|
||||||
isc_netaddr_t netaddr;
|
isc_netaddr_t netaddr;
|
||||||
unsigned int i;
|
isc_netaddr_fromsockaddr(&netaddr, sockaddr);
|
||||||
|
|
||||||
INSIST(len >= 8U);
|
|
||||||
|
|
||||||
isc_netaddr_fromsockaddr(&netaddr, &query->addrinfo->sockaddr);
|
|
||||||
switch (netaddr.family) {
|
switch (netaddr.family) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
memmove(input, (unsigned char *)&netaddr.type.in, 4);
|
INSIST(bufsize >= 4);
|
||||||
memset(input + 4, 0, 12);
|
memmove(buf, &netaddr.type.in, 4);
|
||||||
break;
|
return (4);
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
memmove(input, (unsigned char *)&netaddr.type.in6, 16);
|
INSIST(bufsize >= 16);
|
||||||
break;
|
memmove(buf, &netaddr.type.in6, 16);
|
||||||
|
return (16);
|
||||||
|
default:
|
||||||
|
INSIST(0);
|
||||||
|
ISC_UNREACHABLE();
|
||||||
}
|
}
|
||||||
isc_aes128_crypt(query->fctx->res->view->secret, input, digest);
|
return (0);
|
||||||
for (i = 0; i < 8; i++)
|
}
|
||||||
digest[i] ^= digest[i + 8];
|
|
||||||
memmove(cookie, digest, 8);
|
static inline isc_socket_t *
|
||||||
|
query2sock(const resquery_t *query) {
|
||||||
|
if (query->exclusivesocket) {
|
||||||
|
return (dns_dispatch_getentrysocket(query->dispentry));
|
||||||
|
} else {
|
||||||
|
return (dns_dispatch_getsocket(query->dispatch));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline size_t
|
||||||
|
add_serveraddr(uint8_t *buf, const size_t bufsize, const resquery_t *query)
|
||||||
|
{
|
||||||
|
return (addr2buf(buf, bufsize, &query->addrinfo->sockaddr));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CLIENT_COOKIE_SIZE 8U
|
||||||
|
|
||||||
|
static void
|
||||||
|
compute_cc(const resquery_t *query, uint8_t *cookie, const size_t len) {
|
||||||
|
INSIST(len >= CLIENT_COOKIE_SIZE);
|
||||||
|
STATIC_ASSERT(sizeof(query->fctx->res->view->secret)
|
||||||
|
>= ISC_SIPHASH24_KEY_LENGTH,
|
||||||
|
"The view->secret size can't fit SipHash 2-4 key length");
|
||||||
|
|
||||||
|
uint8_t buf[16] ISC_NONSTRING = { 0 };
|
||||||
|
size_t buflen = add_serveraddr(buf, sizeof(buf), query);
|
||||||
|
|
||||||
|
uint8_t digest[ISC_SIPHASH24_TAG_LENGTH] ISC_NONSTRING = { 0 };
|
||||||
|
isc_siphash24(query->fctx->res->view->secret, buf, buflen, digest);
|
||||||
|
memmove(cookie, digest, CLIENT_COOKIE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
|
|
@ -2753,10 +2779,8 @@ resquery_send(resquery_t *query) {
|
||||||
*/
|
*/
|
||||||
dns_message_reset(fctx->qmessage, DNS_MESSAGE_INTENTRENDER);
|
dns_message_reset(fctx->qmessage, DNS_MESSAGE_INTENTRENDER);
|
||||||
|
|
||||||
if (query->exclusivesocket)
|
sock = query2sock(query);
|
||||||
sock = dns_dispatch_getentrysocket(query->dispentry);
|
|
||||||
else
|
|
||||||
sock = dns_dispatch_getsocket(query->dispatch);
|
|
||||||
/*
|
/*
|
||||||
* Send the query!
|
* Send the query!
|
||||||
*/
|
*/
|
||||||
|
|
@ -5334,9 +5358,9 @@ validated(isc_task_t *task, isc_event_t *event) {
|
||||||
REQUIRE(event->ev_type == DNS_EVENT_VALIDATORDONE);
|
REQUIRE(event->ev_type == DNS_EVENT_VALIDATORDONE);
|
||||||
valarg = event->ev_arg;
|
valarg = event->ev_arg;
|
||||||
fctx = valarg->fctx;
|
fctx = valarg->fctx;
|
||||||
|
REQUIRE(VALID_FCTX(fctx));
|
||||||
res = fctx->res;
|
res = fctx->res;
|
||||||
addrinfo = valarg->addrinfo;
|
addrinfo = valarg->addrinfo;
|
||||||
REQUIRE(VALID_FCTX(fctx));
|
|
||||||
REQUIRE(!ISC_LIST_EMPTY(fctx->validators));
|
REQUIRE(!ISC_LIST_EMPTY(fctx->validators));
|
||||||
|
|
||||||
vevent = (dns_validatorevent_t *)event;
|
vevent = (dns_validatorevent_t *)event;
|
||||||
|
|
@ -9548,11 +9572,7 @@ rctx_logpacket(respctx_t *rctx) {
|
||||||
dtmsgtype = DNS_DTTYPE_RR;
|
dtmsgtype = DNS_DTTYPE_RR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rctx->query->exclusivesocket) {
|
sock = query2sock(rctx->query);
|
||||||
sock = dns_dispatch_getentrysocket(rctx->query->dispentry);
|
|
||||||
} else {
|
|
||||||
sock = dns_dispatch_getsocket(rctx->query->dispatch);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sock != NULL) {
|
if (sock != NULL) {
|
||||||
result = isc_socket_getsockname(sock, &localaddr);
|
result = isc_socket_getsockname(sock, &localaddr);
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,12 @@
|
||||||
*/
|
*/
|
||||||
#define UNUSED(x) (void)(x)
|
#define UNUSED(x) (void)(x)
|
||||||
|
|
||||||
|
#if __GNUC__ >= 8 && !defined(__clang__)
|
||||||
|
#define ISC_NONSTRING __attribute__((nonstring))
|
||||||
|
#else
|
||||||
|
#define ISC_NONSTRING
|
||||||
|
#endif /* __GNUC__ */
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
* The opposite: silent warnings about stored values which are never read.
|
* The opposite: silent warnings about stored values which are never read.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -899,7 +899,7 @@ static cfg_type_t cfg_type_bracketed_portlist = {
|
||||||
&cfg_rep_list, &cfg_type_portrange
|
&cfg_rep_list, &cfg_type_portrange
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *cookiealg_enums[] = { "aes", NULL };
|
static const char *cookiealg_enums[] = { "aes", "siphash24", NULL };
|
||||||
static cfg_type_t cfg_type_cookiealg = {
|
static cfg_type_t cfg_type_cookiealg = {
|
||||||
"cookiealg", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
|
"cookiealg", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
|
||||||
&cfg_rep_string, &cookiealg_enums
|
&cfg_rep_string, &cookiealg_enums
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
#include <isc/random.h>
|
#include <isc/random.h>
|
||||||
#include <isc/safe.h>
|
#include <isc/safe.h>
|
||||||
#include <isc/serial.h>
|
#include <isc/serial.h>
|
||||||
|
#include <isc/siphash.h>
|
||||||
#include <isc/stats.h>
|
#include <isc/stats.h>
|
||||||
#include <isc/stdio.h>
|
#include <isc/stdio.h>
|
||||||
#include <isc/string.h>
|
#include <isc/string.h>
|
||||||
|
|
@ -1919,23 +1920,63 @@ static void
|
||||||
compute_cookie(ns_client_t *client, uint32_t when, uint32_t nonce,
|
compute_cookie(ns_client_t *client, uint32_t when, uint32_t nonce,
|
||||||
const unsigned char *secret, isc_buffer_t *buf)
|
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.");
|
||||||
|
|
||||||
switch (client->sctx->cookiealg) {
|
switch (client->sctx->cookiealg) {
|
||||||
|
case ns_cookiealg_siphash24: {
|
||||||
|
unsigned char input[16 + 16] ISC_NONSTRING = { 0 };
|
||||||
|
size_t inputlen = 0;
|
||||||
|
isc_netaddr_t netaddr;
|
||||||
|
unsigned char *cp;
|
||||||
|
|
||||||
|
cp = isc_buffer_used(buf);
|
||||||
|
isc_buffer_putmem(buf, client->cookie, 8);
|
||||||
|
isc_buffer_putuint8(buf, NS_COOKIE_VERSION_1);
|
||||||
|
isc_buffer_putuint24(buf, 0); /* Reserved */
|
||||||
|
isc_buffer_putuint32(buf, when);
|
||||||
|
|
||||||
|
memmove(input, cp, 16);
|
||||||
|
|
||||||
|
isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
|
||||||
|
switch (netaddr.family) {
|
||||||
|
case AF_INET:
|
||||||
|
cp = (unsigned char *)&netaddr.type.in;
|
||||||
|
memmove(input + 16, cp, 4);
|
||||||
|
inputlen = 20;
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
cp = (unsigned char *)&netaddr.type.in6;
|
||||||
|
memmove(input + 16, cp, 16);
|
||||||
|
inputlen = 32;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
INSIST(0);
|
||||||
|
ISC_UNREACHABLE();
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_siphash24(secret, input, inputlen, digest);
|
||||||
|
isc_buffer_putmem(buf, digest, 8);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ns_cookiealg_aes: {
|
case ns_cookiealg_aes: {
|
||||||
unsigned char digest[ISC_AES_BLOCK_LENGTH];
|
unsigned char input[4 + 4 + 16] ISC_NONSTRING = { 0 };
|
||||||
unsigned char input[4 + 4 + 16];
|
|
||||||
isc_netaddr_t netaddr;
|
isc_netaddr_t netaddr;
|
||||||
unsigned char *cp;
|
unsigned char *cp;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
memset(input, 0, sizeof(input));
|
|
||||||
cp = isc_buffer_used(buf);
|
cp = isc_buffer_used(buf);
|
||||||
isc_buffer_putmem(buf, client->cookie, 8);
|
isc_buffer_putmem(buf, client->cookie, 8);
|
||||||
isc_buffer_putuint32(buf, nonce);
|
isc_buffer_putuint32(buf, nonce);
|
||||||
isc_buffer_putuint32(buf, when);
|
isc_buffer_putuint32(buf, when);
|
||||||
memmove(input, cp, 16);
|
memmove(input, cp, 16);
|
||||||
isc_aes128_crypt(secret, input, digest);
|
isc_aes128_crypt(secret, input, digest);
|
||||||
for (i = 0; i < 8; i++)
|
for (i = 0; i < 8; i++) {
|
||||||
input[i] = digest[i] ^ digest[i + 8];
|
input[i] = digest[i] ^ digest[i + 8];
|
||||||
|
}
|
||||||
isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
|
isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
|
||||||
switch (netaddr.family) {
|
switch (netaddr.family) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
|
|
@ -1948,14 +1989,19 @@ compute_cookie(ns_client_t *client, uint32_t when, uint32_t nonce,
|
||||||
cp = (unsigned char *)&netaddr.type.in6;
|
cp = (unsigned char *)&netaddr.type.in6;
|
||||||
memmove(input + 8, cp, 16);
|
memmove(input + 8, cp, 16);
|
||||||
isc_aes128_crypt(secret, input, digest);
|
isc_aes128_crypt(secret, input, digest);
|
||||||
for (i = 0; i < 8; i++)
|
for (i = 0; i < 8; i++) {
|
||||||
input[i + 8] = digest[i] ^ digest[i + 8];
|
input[i + 8] = digest[i] ^ digest[i + 8];
|
||||||
|
}
|
||||||
isc_aes128_crypt(client->sctx->secret, input + 8,
|
isc_aes128_crypt(client->sctx->secret, input + 8,
|
||||||
digest);
|
digest);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
INSIST(0);
|
||||||
|
ISC_UNREACHABLE();
|
||||||
}
|
}
|
||||||
for (i = 0; i < 8; i++)
|
for (i = 0; i < 8; i++) {
|
||||||
digest[i] ^= digest[i + 8];
|
digest[i] ^= digest[i + 8];
|
||||||
|
}
|
||||||
isc_buffer_putmem(buf, digest, 8);
|
isc_buffer_putmem(buf, digest, 8);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,10 @@ typedef struct ns_server ns_server_t;
|
||||||
typedef struct ns_stats ns_stats_t;
|
typedef struct ns_stats ns_stats_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ns_cookiealg_aes
|
ns_cookiealg_aes,
|
||||||
|
ns_cookiealg_siphash24
|
||||||
} ns_cookiealg_t;
|
} ns_cookiealg_t;
|
||||||
|
|
||||||
|
#define NS_COOKIE_VERSION_1 1
|
||||||
|
|
||||||
#endif /* NS_TYPES_H */
|
#endif /* NS_TYPES_H */
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue