Commit 4eb99892 authored by Evan Hunt's avatar Evan Hunt

[master] algorithm flexibility for rndc

3525.	[func]		Support for additional signing algorithms in rndc:
			hmac-sha1, -sha224, -sha256, -sha384, and -sha512.
			The -A option to rndc-confgen can be used to
			select the algorithm for the generated key.
			(The default is still hmac-md5; this may
			change in a future release.) [RT #20363]
parent 1f068360
3525. [func] Support for additional signing algorithms in rndc:
hmac-sha1, -sha224, -sha256, -sha384, and -sha512.
The -A option to rndc-confgen can be used to
select the algorithm for the generated key.
(The default is still hmac-md5; this may
change in a future release.) [RT #20363]
3524. [func] Added an alternate statistics channel in JSON format,
when the server is built with the json-c library:
http://[address]:[port]/json. [RT #32630]
......
......@@ -869,7 +869,7 @@ A: If you run Tiger(Mac OS 10.4) or later then this is all you need to do:
Copy the key statement from /etc/rndc.conf into /etc/rndc.key, e.g.:
key "rndc-key" {
algorithm hmac-md5;
algorithm hmac-sha256;
secret "uvceheVuqf17ZwIcTydddw==";
};
......
......@@ -30,6 +30,7 @@
<year>2008</year>
<year>2009</year>
<year>2010</year>
<year>2013</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
<copyright>
......@@ -1564,7 +1565,7 @@ rand_irqs="3 14 15"</programlisting>
<informalexample>
<programlisting>
key "rndc-key" {
algorithm hmac-md5;
algorithm hmac-sha256;
secret "uvceheVuqf17ZwIcTydddw==";
};</programlisting>
</informalexample>
......
......@@ -57,7 +57,6 @@
#include "util.h"
#include "keygen.h"
#define DEFAULT_KEYLENGTH 128 /*% Bits. */
#define DEFAULT_KEYNAME "rndc-key"
#define DEFAULT_SERVER "127.0.0.1"
#define DEFAULT_PORT 953
......@@ -80,7 +79,8 @@ Usage:\n\
%s [-a] [-b bits] [-c keyfile] [-k keyname] [-p port] [-r randomfile] \
[-s addr] [-t chrootdir] [-u user]\n\
-a: generate just the key clause and write it to keyfile (%s)\n\
-b bits: from 1 through 512, default %d; total length of the secret\n\
-A alg: algorithm (default hmac-md5)\n\
-b bits: from 1 through 512, default 256; total length of the secret\n\
-c keyfile: specify an alternate key file (requires -a)\n\
-k keyname: the name as it will be used in named.conf and rndc.conf\n\
-p port: the port named will listen on and rndc will connect to\n\
......@@ -88,7 +88,7 @@ Usage:\n\
-s addr: the address to which rndc should connect\n\
-t chrootdir: write a keyfile in chrootdir as well (requires -a)\n\
-u user: set the keyfile owner to \"user\" (requires -a)\n",
progname, keydef, DEFAULT_KEYLENGTH);
progname, keydef);
exit (status);
}
......@@ -103,12 +103,12 @@ main(int argc, char **argv) {
const char *keyname = NULL;
const char *randomfile = NULL;
const char *serveraddr = NULL;
dns_secalg_t alg = DST_ALG_HMACMD5;
const char *algname = alg_totext(alg);
dns_secalg_t alg;
const char *algname;
char *p;
int ch;
int port;
int keysize;
int keysize = -1;
struct in_addr addr4_dummy;
struct in6_addr addr6_dummy;
char *chrootdir = NULL;
......@@ -124,18 +124,25 @@ main(int argc, char **argv) {
progname = program;
keyname = DEFAULT_KEYNAME;
keysize = DEFAULT_KEYLENGTH;
alg = DST_ALG_HMACMD5;
serveraddr = DEFAULT_SERVER;
port = DEFAULT_PORT;
isc_commandline_errprint = ISC_FALSE;
while ((ch = isc_commandline_parse(argc, argv,
"ab:c:hk:Mmp:r:s:t:u:Vy")) != -1) {
"aA:b:c:hk:Mmp:r:s:t:u:Vy")) != -1)
{
switch (ch) {
case 'a':
keyonly = ISC_TRUE;
break;
case 'A':
algname = isc_commandline_argument;
alg = alg_fromtext(algname);
if (alg == DST_ALG_UNKNOWN)
fatal("Unsupported algorithm '%s'", algname);
break;
case 'b':
keysize = strtol(isc_commandline_argument, &p, 10);
if (*p != '\0' || keysize < 0)
......@@ -203,6 +210,10 @@ main(int argc, char **argv) {
if (argc > 0)
usage(1);
if (keysize < 0)
keysize = alg_bits(alg);
algname = alg_totext(alg);
DO("create memory context", isc_mem_create(0, 0, &mctx));
isc_buffer_init(&key_txtbuffer, &key_txtsecret, sizeof(key_txtsecret));
......
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "&#8212;">]>
[<!ENTITY mdash "&#8212;">]>
<!--
- Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2001, 2003 Internet Software Consortium.
......@@ -41,6 +41,7 @@
<year>2005</year>
<year>2007</year>
<year>2009</year>
<year>2013</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
<copyright>
......@@ -54,6 +55,7 @@
<cmdsynopsis>
<command>rndc-confgen</command>
<arg><option>-a</option></arg>
<arg><option>-A <replaceable class="parameter">algorithm</replaceable></option></arg>
<arg><option>-b <replaceable class="parameter">keysize</replaceable></option></arg>
<arg><option>-c <replaceable class="parameter">keyfile</replaceable></option></arg>
<arg><option>-h</option></arg>
......@@ -128,12 +130,24 @@
</listitem>
</varlistentry>
<varlistentry>
<term>-A <replaceable class="parameter">algorithm</replaceable></term>
<listitem>
<para>
Specifies the algorithm to use for the TSIG key. Available
choices are: hmac-md5, hmac-sha1, hmac-sha224, hmac-sha256,
hmac-sha384 and hmac-sha512. The default is hmac-md5.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>-b <replaceable class="parameter">keysize</replaceable></term>
<listitem>
<para>
Specifies the size of the authentication key in bits.
Must be between 1 and 512 bits; the default is 128.
Must be between 1 and 512 bits; the default is the
hash size.
</para>
</listitem>
</varlistentry>
......
......@@ -71,6 +71,7 @@ typedef ISC_LIST(controllistener_t) controllistenerlist_t;
struct controlkey {
char * keyname;
isc_uint32_t algorithm;
isc_region_t secret;
ISC_LINK(controlkey_t) link;
};
......@@ -325,6 +326,7 @@ control_recvmessage(isc_task_t *task, isc_event_t *event) {
isccc_sexpr_t *request = NULL;
isccc_sexpr_t *response = NULL;
isccc_region_t ccregion;
isc_uint32_t algorithm;
isccc_region_t secret;
isc_stdtime_t now;
isc_buffer_t b;
......@@ -343,6 +345,7 @@ control_recvmessage(isc_task_t *task, isc_event_t *event) {
conn = event->ev_arg;
listener = conn->listener;
algorithm = DST_ALG_UNKNOWN;
secret.rstart = NULL;
/* Is the server shutting down? */
......@@ -369,7 +372,9 @@ control_recvmessage(isc_task_t *task, isc_event_t *event) {
goto cleanup;
memcpy(secret.rstart, key->secret.base, key->secret.length);
secret.rend = secret.rstart + key->secret.length;
result = isccc_cc_fromwire(&ccregion, &request, &secret);
algorithm = key->algorithm;
result = isccc_cc_fromwire(&ccregion, &request,
algorithm, &secret);
if (result == ISC_R_SUCCESS)
break;
isc_mem_put(listener->mctx, secret.rstart, REGION_SIZE(secret));
......@@ -483,7 +488,7 @@ control_recvmessage(isc_task_t *task, isc_event_t *event) {
ccregion.rstart = conn->buffer + 4;
ccregion.rend = conn->buffer + sizeof(conn->buffer);
result = isccc_cc_towire(response, &ccregion, &secret);
result = isccc_cc_towire(response, &ccregion, algorithm, &secret);
if (result != ISC_R_SUCCESS)
goto cleanup_response;
isc_buffer_init(&b, conn->buffer, 4);
......@@ -696,6 +701,7 @@ controlkeylist_fromcfg(const cfg_obj_t *keylist, isc_mem_t *mctx,
if (key == NULL)
goto cleanup;
key->keyname = newstr;
key->algorithm = DST_ALG_UNKNOWN;
key->secret.base = NULL;
key->secret.length = 0;
ISC_LINK_INIT(key, link);
......@@ -740,6 +746,7 @@ register_keys(const cfg_obj_t *control, const cfg_obj_t *keylist,
const cfg_obj_t *secretobj = NULL;
const char *algstr = NULL;
const char *secretstr = NULL;
unsigned int algtype;
(void)cfg_map_get(keydef, "algorithm", &algobj);
(void)cfg_map_get(keydef, "secret", &secretobj);
......@@ -748,8 +755,8 @@ register_keys(const cfg_obj_t *control, const cfg_obj_t *keylist,
algstr = cfg_obj_asstring(algobj);
secretstr = cfg_obj_asstring(secretobj);
if (ns_config_getkeyalgorithm(algstr, NULL, NULL) !=
ISC_R_SUCCESS)
if (ns_config_getkeyalgorithm2(algstr, NULL,
&algtype, NULL) != ISC_R_SUCCESS)
{
cfg_obj_log(control, ns_g_lctx,
ISC_LOG_WARNING,
......@@ -762,6 +769,7 @@ register_keys(const cfg_obj_t *control, const cfg_obj_t *keylist,
continue;
}
keyid->algorithm = algtype;
isc_buffer_init(&b, secret, sizeof(secret));
result = isc_base64_decodestring(secretstr, &b);
......@@ -812,6 +820,7 @@ get_rndckey(isc_mem_t *mctx, controlkeylist_t *keyids) {
const char *secretstr = NULL;
controlkey_t *keyid = NULL;
char secret[1024];
unsigned int algtype;
isc_buffer_t b;
CHECK(cfg_parser_create(mctx, ns_g_lctx, &pctx));
......@@ -825,6 +834,7 @@ get_rndckey(isc_mem_t *mctx, controlkeylist_t *keyids) {
cfg_obj_asstring(cfg_map_getname(key)));
keyid->secret.base = NULL;
keyid->secret.length = 0;
keyid->algorithm = DST_ALG_UNKNOWN;
ISC_LINK_INIT(keyid, link);
if (keyid->keyname == NULL)
CHECK(ISC_R_NOMEMORY);
......@@ -838,7 +848,8 @@ get_rndckey(isc_mem_t *mctx, controlkeylist_t *keyids) {
algstr = cfg_obj_asstring(algobj);
secretstr = cfg_obj_asstring(secretobj);
if (ns_config_getkeyalgorithm(algstr, NULL, NULL) != ISC_R_SUCCESS) {
if (ns_config_getkeyalgorithm2(algstr, NULL,
&algtype, NULL) != ISC_R_SUCCESS) {
cfg_obj_log(key, ns_g_lctx,
ISC_LOG_WARNING,
"unsupported algorithm '%s' in "
......@@ -848,6 +859,7 @@ get_rndckey(isc_mem_t *mctx, controlkeylist_t *keyids) {
goto cleanup;
}
keyid->algorithm = algtype;
isc_buffer_init(&b, secret, sizeof(secret));
result = isc_base64_decodestring(secretstr, &b);
......
......@@ -77,6 +77,7 @@ static unsigned int remoteport = 0;
static isc_socketmgr_t *socketmgr = NULL;
static unsigned char databuf[2048];
static isccc_ccmsg_t ccmsg;
static isc_uint32_t algorithm;
static isccc_region_t secret;
static isc_boolean_t failed = ISC_FALSE;
static isc_boolean_t c_flag = ISC_FALSE;
......@@ -251,7 +252,8 @@ rndc_recvdone(isc_task_t *task, isc_event_t *event) {
source.rstart = isc_buffer_base(&ccmsg.buffer);
source.rend = isc_buffer_used(&ccmsg.buffer);
DO("parse message", isccc_cc_fromwire(&source, &response, &secret));
DO("parse message",
isccc_cc_fromwire(&source, &response, algorithm, &secret));
data = isccc_alist_lookup(response, "_data");
if (data == NULL)
......@@ -305,7 +307,8 @@ rndc_recvnonce(isc_task_t *task, isc_event_t *event) {
"* the remote server is using an older version of"
" the command protocol,\n"
"* this host is not authorized to connect,\n"
"* the clocks are not synchronized, or\n"
"* the clocks are not synchronized,\n"
"* the the key signing algorithm is incorrect, or\n"
"* the key is invalid.");
if (ccmsg.result != ISC_R_SUCCESS)
......@@ -314,7 +317,8 @@ rndc_recvnonce(isc_task_t *task, isc_event_t *event) {
source.rstart = isc_buffer_base(&ccmsg.buffer);
source.rend = isc_buffer_used(&ccmsg.buffer);
DO("parse message", isccc_cc_fromwire(&source, &response, &secret));
DO("parse message",
isccc_cc_fromwire(&source, &response, algorithm, &secret));
_ctrl = isccc_alist_lookup(response, "_ctrl");
if (_ctrl == NULL)
......@@ -341,7 +345,8 @@ rndc_recvnonce(isc_task_t *task, isc_event_t *event) {
}
message.rstart = databuf + 4;
message.rend = databuf + sizeof(databuf);
DO("render message", isccc_cc_towire(request, &message, &secret));
DO("render message",
isccc_cc_towire(request, &message, algorithm, &secret));
len = sizeof(databuf) - REGION_SIZE(message);
isc_buffer_init(&b, databuf, 4);
isc_buffer_putuint32(&b, len - 4);
......@@ -403,7 +408,8 @@ rndc_connected(isc_task_t *task, isc_event_t *event) {
fatal("out of memory");
message.rstart = databuf + 4;
message.rend = databuf + sizeof(databuf);
DO("render message", isccc_cc_towire(request, &message, &secret));
DO("render message",
isccc_cc_towire(request, &message, algorithm, &secret));
len = sizeof(databuf) - REGION_SIZE(message);
isc_buffer_init(&b, databuf, 4);
isc_buffer_putuint32(&b, len - 4);
......@@ -483,7 +489,7 @@ parse_config(isc_mem_t *mctx, isc_log_t *log, const char *keyname,
const cfg_obj_t *address = NULL;
const cfg_listelt_t *elt;
const char *secretstr;
const char *algorithm;
const char *algorithmstr;
static char secretarray[1024];
const cfg_type_t *conftype = &cfg_type_rndcconf;
isc_boolean_t key_only = ISC_FALSE;
......@@ -584,10 +590,22 @@ parse_config(isc_mem_t *mctx, isc_log_t *log, const char *keyname,
fatal("key must have algorithm and secret");
secretstr = cfg_obj_asstring(secretobj);
algorithm = cfg_obj_asstring(algorithmobj);
if (strcasecmp(algorithm, "hmac-md5") != 0)
fatal("unsupported algorithm: %s", algorithm);
algorithmstr = cfg_obj_asstring(algorithmobj);
if (strcasecmp(algorithmstr, "hmac-md5") == 0)
algorithm = ISCCC_ALG_HMACMD5;
else if (strcasecmp(algorithmstr, "hmac-sha1") == 0)
algorithm = ISCCC_ALG_HMACSHA1;
else if (strcasecmp(algorithmstr, "hmac-sha224") == 0)
algorithm = ISCCC_ALG_HMACSHA224;
else if (strcasecmp(algorithmstr, "hmac-sha256") == 0)
algorithm = ISCCC_ALG_HMACSHA256;
else if (strcasecmp(algorithmstr, "hmac-sha384") == 0)
algorithm = ISCCC_ALG_HMACSHA384;
else if (strcasecmp(algorithmstr, "hmac-sha512") == 0)
algorithm = ISCCC_ALG_HMACSHA512;
else
fatal("unsupported algorithm: %s", algorithmstr);
secret.rstart = (unsigned char *)secretarray;
secret.rend = (unsigned char *)secretarray + sizeof(secretarray);
......
......@@ -31,7 +31,7 @@ server localhost {
};
key "cc64b3d1db63fc88d7cb5d2f9f57d258" {
algorithm hmac-md5;
algorithm hmac-sha256;
secret "34f88008d07deabbe65bd01f1d233d47";
};
......@@ -42,6 +42,6 @@ server "test1" {
};
key "key" {
algorithm hmac-md5;
algorithm hmac-sha256;
secret "c3Ryb25nIGVub3VnaCBmb3IgYSBtYW4gYnV0IG1hZGUgZm9yIGEgd29tYW4K";
};
......@@ -40,6 +40,7 @@
<year>2004</year>
<year>2005</year>
<year>2007</year>
<year>2013</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
<copyright>
......@@ -119,11 +120,12 @@
<para>
The <option>key</option> statement begins with an identifying
string, the name of the key. The statement has two clauses.
<option>algorithm</option> identifies the encryption algorithm
<option>algorithm</option> identifies the authentication algorithm
for <command>rndc</command> to use; currently only HMAC-MD5
is
(for compatibility), HMAC-SHA1, HMAC-SHA224, HMAC-SHA256
(default), HMAC-SHA384 and HMAC-SHA512 are
supported. This is followed by a secret clause which contains
the base-64 encoding of the algorithm's encryption key. The
the base-64 encoding of the algorithm's authentication key. The
base-64 string is enclosed in double quotes.
</para>
<para>
......@@ -166,14 +168,14 @@
</para>
<para><programlisting>
key samplekey {
algorithm hmac-md5;
algorithm hmac-sha256;
secret "6FMfj43Osz4lyb24OIe2iGEz9lf1llJO+lz";
};
</programlisting>
</para>
<para><programlisting>
key testkey {
algorithm hmac-md5;
algorithm hmac-sha256;
secret "R3HI8P6BKw9ZwXwN3VZKuQ==";
};
</programlisting>
......@@ -186,8 +188,8 @@
Commands to the localhost server will use the samplekey key, which
must also be defined in the server's configuration file with the
same name and secret. The key statement indicates that samplekey
uses the HMAC-MD5 algorithm and its secret clause contains the
base-64 encoding of the HMAC-MD5 secret enclosed in double quotes.
uses the HMAC-SHA256 algorithm and its secret clause contains the
base-64 encoding of the HMAC-SHA256 secret enclosed in double quotes.
</para>
<para>
If <command>rndc -s testserver</command> is used then <command>rndc</command> will
......
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "&#8212;">]>
[<!ENTITY mdash "&#8212;">]>
<!--
- Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000, 2001 Internet Software Consortium.
......@@ -40,6 +40,7 @@
<year>2004</year>
<year>2005</year>
<year>2007</year>
<year>2013</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
<copyright>
......@@ -75,12 +76,14 @@
arguments.
</para>
<para><command>rndc</command>
communicates with the name server
over a TCP connection, sending commands authenticated with
digital signatures. In the current versions of
communicates with the name server over a TCP connection, sending
commands authenticated with digital signatures. In the current
versions of
<command>rndc</command> and <command>named</command>,
the only supported authentication algorithm is HMAC-MD5,
which uses a shared secret on each end of the connection.
the only supported authentication algorithms are HMAC-MD5
(for compatibility), HMAC-SHA1, HMAC-SHA224, HMAC-SHA256
(default), HMAC-SHA384 and HMAC-SHA512.
They use a shared secret on each end of the connection.
This provides TSIG-style authentication for the command
request and the name server's response. All commands sent
over the channel must be signed by a key_id known to the
......@@ -144,7 +147,7 @@
<command>rndc</command>. If no server is supplied on the
command line, the host named by the default-server clause
in the options statement of the <command>rndc</command>
configuration file will be used.
configuration file will be used.
</para>
</listitem>
</varlistentry>
......
......@@ -36,7 +36,7 @@ options {
key rndc_key {
secret "1234abcd8765";
algorithm hmac-md5;
algorithm hmac-sha256;
};
controls {
......
......@@ -37,7 +37,7 @@ options {
key rndc_key {
secret "1234abcd8765";
algorithm hmac-md5;
algorithm hmac-sha256;
};
controls {
......
......@@ -39,7 +39,7 @@ options {
key rndc_key {
secret "1234abcd8765";
algorithm hmac-md5;
algorithm hmac-sha256;
};
controls {
......
......@@ -34,7 +34,7 @@ options {
key rndc_key {
secret "1234abcd8765";
algorithm hmac-md5;
algorithm hmac-sha256;
};
controls {
......
......@@ -19,7 +19,7 @@
key rndc_key {
secret "1234abcd8765";
algorithm hmac-md5;
algorithm hmac-sha256;
};
controls {
......
......@@ -22,6 +22,6 @@ options {
};
key rndc_key {
algorithm hmac-md5;
algorithm hmac-sha256;
secret "1234abcd8765";
};
......@@ -18,5 +18,5 @@
key rndc_key {
secret "1234abcd8765";
algorithm hmac-md5;
algorithm hmac-sha256;
};
......@@ -36,6 +36,7 @@ DIG=$TOP/bin/dig/dig
RNDC=$TOP/bin/rndc/rndc
NSUPDATE=$TOP/bin/nsupdate/nsupdate
DDNSCONFGEN=$TOP/bin/confgen/ddns-confgen
RNDCCONFGEN=$TOP/bin/confgen/rndc-confgen
KEYGEN=$TOP/bin/dnssec/dnssec-keygen
KEYFRLAB=$TOP/bin/dnssec/dnssec-keyfromlabel
SIGNER=$TOP/bin/dnssec/dnssec-signzone
......
......@@ -20,7 +20,7 @@
key rndc_key {
secret "1234abcd8765";
algorithm hmac-md5;
algorithm hmac-sha256;
};
controls {
......
......@@ -20,7 +20,7 @@
key rndc_key {
secret "1234abcd8765";
algorithm hmac-md5;
algorithm hmac-sha256;
};
controls {
......
......@@ -23,7 +23,7 @@
*
* e.g.
* key "cc64b3d1db63fc88d7cb5d2f9f57d258" {
* algorithm hmac-md5;
* algorithm hmac-sha256;
* secret "34f88008d07deabbe65bd01f1d233d47";
* };
*
......@@ -36,7 +36,7 @@
*/
key "cc64b3d1db63fc88d7cb5d2f9f57d258" {
algorithm hmac-md5;
algorithm hmac-sha256;
secret "34f88008d07deabbe65bd01f1d233d47";
};
......
......@@ -17,7 +17,7 @@
/* $Id: rndc.conf,v 1.5 2007/06/19 23:47:02 tbox Exp $ */
key "cc64b3d1db63fc88d7cb5d2f9f57d258" {
algorithm hmac-md5;
algorithm hmac-sha256;
secret "34f88008d07deabbe65bd01f1d233d47";
};
......
......@@ -37,7 +37,7 @@ options {
key rndc_key {
secret "1234abcd8765";