From f50ae72ec3417cae55dd4e085991c01af9fdc5f1 Mon Sep 17 00:00:00 2001 From: Martin Nagy Date: Wed, 11 Feb 2009 20:37:59 +0100 Subject: Initial commit --- bin/tests/dst/Kdh.+002+18602.key | 1 + bin/tests/dst/Kdh.+002+18602.private | 6 + bin/tests/dst/Kdh.+002+48957.key | 1 + bin/tests/dst/Kdh.+002+48957.private | 6 + bin/tests/dst/Ktest.+001+00002.key | 1 + bin/tests/dst/Ktest.+001+54622.key | 1 + bin/tests/dst/Ktest.+001+54622.private | 10 + bin/tests/dst/Ktest.+003+23616.key | 1 + bin/tests/dst/Ktest.+003+23616.private | 7 + bin/tests/dst/Ktest.+003+49667.key | 1 + bin/tests/dst/Makefile.in | 65 + bin/tests/dst/dst_2_data | 16 + bin/tests/dst/dst_test.c | 294 +++ bin/tests/dst/gsstest.c | 566 ++++++ bin/tests/dst/t2_data_1 | 3077 ++++++++++++++++++++++++++++++++ bin/tests/dst/t2_data_2 | 3077 ++++++++++++++++++++++++++++++++ bin/tests/dst/t2_dsasig | 3 + bin/tests/dst/t2_rsasig | 6 + bin/tests/dst/t_dst.c | 933 ++++++++++ 19 files changed, 8072 insertions(+) create mode 100644 bin/tests/dst/Kdh.+002+18602.key create mode 100644 bin/tests/dst/Kdh.+002+18602.private create mode 100644 bin/tests/dst/Kdh.+002+48957.key create mode 100644 bin/tests/dst/Kdh.+002+48957.private create mode 100644 bin/tests/dst/Ktest.+001+00002.key create mode 100644 bin/tests/dst/Ktest.+001+54622.key create mode 100644 bin/tests/dst/Ktest.+001+54622.private create mode 100644 bin/tests/dst/Ktest.+003+23616.key create mode 100644 bin/tests/dst/Ktest.+003+23616.private create mode 100644 bin/tests/dst/Ktest.+003+49667.key create mode 100644 bin/tests/dst/Makefile.in create mode 100644 bin/tests/dst/dst_2_data create mode 100644 bin/tests/dst/dst_test.c create mode 100755 bin/tests/dst/gsstest.c create mode 100644 bin/tests/dst/t2_data_1 create mode 100644 bin/tests/dst/t2_data_2 create mode 100644 bin/tests/dst/t2_dsasig create mode 100644 bin/tests/dst/t2_rsasig create mode 100644 bin/tests/dst/t_dst.c (limited to 'bin/tests/dst') diff --git a/bin/tests/dst/Kdh.+002+18602.key b/bin/tests/dst/Kdh.+002+18602.key new file mode 100644 index 0000000..09b4cf5 --- /dev/null +++ b/bin/tests/dst/Kdh.+002+18602.key @@ -0,0 +1 @@ +dh. IN KEY 0 2 2 AAEBAAAAYIHI/wjtOagNga9GILSoS02IVelgLilPE/TfhtvShsiDAXqb IfxQcj2JkuOnNLs5ttb2WZXWl5/jsSjIxHMwMF2XY4gwt/lwHBf/vgYH r7aIxnKXov1jk9rymTLHGKIOtg== diff --git a/bin/tests/dst/Kdh.+002+18602.private b/bin/tests/dst/Kdh.+002+18602.private new file mode 100644 index 0000000..a2245bf --- /dev/null +++ b/bin/tests/dst/Kdh.+002+18602.private @@ -0,0 +1,6 @@ +Private-key-format: v1.2 +Algorithm: 2 (DH) +Prime(p): ///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxObIlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjo2IP////////// +Generator(g): Ag== +Private_value(x): bpdsGQ1jbV3f2CGN/0Pk5KM1MlkFmMryPO1J1zoGn585fRmc9Ygw6l/HKmi2ViiDNorvd9/eV9uyYO6lYZC82R3D7rST1mAqCwbg/8gNE5dXBRbRIIq3qIl6GUYYs8mK +Public_value(y): gcj/CO05qA2Br0YgtKhLTYhV6WAuKU8T9N+G29KGyIMBepsh/FByPYmS46c0uzm21vZZldaXn+OxKMjEczAwXZdjiDC3+XAcF/++BgevtojGcpei/WOT2vKZMscYog62 diff --git a/bin/tests/dst/Kdh.+002+48957.key b/bin/tests/dst/Kdh.+002+48957.key new file mode 100644 index 0000000..9838829 --- /dev/null +++ b/bin/tests/dst/Kdh.+002+48957.key @@ -0,0 +1 @@ +dh. IN KEY 0 2 2 AAEBAAAAYOuaKjyMXYame2F6/ZFdEmXv0a2edB+69PEZgrExA6SJlivn 4KqAsfBHr/+0BCb+7nfWeMDSh2BXnSzWkXF1wMaCHMuz9EleG1gKFKeV Q9gKli88Cb8/jbovWChrGBNp2w== diff --git a/bin/tests/dst/Kdh.+002+48957.private b/bin/tests/dst/Kdh.+002+48957.private new file mode 100644 index 0000000..e191235 --- /dev/null +++ b/bin/tests/dst/Kdh.+002+48957.private @@ -0,0 +1,6 @@ +Private-key-format: v1.2 +Algorithm: 2 (DH) +Prime(p): ///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxObIlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjo2IP////////// +Generator(g): Ag== +Private_value(x): WJG0moh+QoZV+DYhqW7Z6O6TYpYGtSlN0Ym6JV6VRnzeH69OqMUFivqZorj3a3ofR/4zogNVyy5KLLj2NFTaLGP4Hcvt7uETJik6HrjLMhGf40QPXYgVK57Im0rv88Ca +Public_value(y): 65oqPIxdhqZ7YXr9kV0SZe/RrZ50H7r08RmCsTEDpImWK+fgqoCx8Eev/7QEJv7ud9Z4wNKHYFedLNaRcXXAxoIcy7P0SV4bWAoUp5VD2AqWLzwJvz+Nui9YKGsYE2nb diff --git a/bin/tests/dst/Ktest.+001+00002.key b/bin/tests/dst/Ktest.+001+00002.key new file mode 100644 index 0000000..a8b4b4d --- /dev/null +++ b/bin/tests/dst/Ktest.+001+00002.key @@ -0,0 +1 @@ +test. IN DNSKEY 49152 2 1 diff --git a/bin/tests/dst/Ktest.+001+54622.key b/bin/tests/dst/Ktest.+001+54622.key new file mode 100644 index 0000000..b0277e3 --- /dev/null +++ b/bin/tests/dst/Ktest.+001+54622.key @@ -0,0 +1 @@ +test. IN DNSKEY 257 3 1 AQPQjwSpaVzxIgRCpiUoozUQKGh2oX8NIFKDOvtxK+tn536OZg2cROKTlgGEHXJK9YHfW/6nzQULTVpb63P+SQMmjCCidb8IYyhItixRztVeJQ== diff --git a/bin/tests/dst/Ktest.+001+54622.private b/bin/tests/dst/Ktest.+001+54622.private new file mode 100644 index 0000000..c97ac30 --- /dev/null +++ b/bin/tests/dst/Ktest.+001+54622.private @@ -0,0 +1,10 @@ +Private-key-format: v1.2 +Algorithm: 1 (RSA) +Modulus: 0I8EqWlc8SIEQqYlKKM1EChodqF/DSBSgzr7cSvrZ+d+jmYNnETik5YBhB1ySvWB31v+p80FC01aW+tz/kkDJowgonW/CGMoSLYsUc7VXiU= +PublicExponent: Aw== +PrivateExponent: iwoDG5uTS2wC1xluGxd4tXBFpGuqCMA3AidSS3Kc7++ptEQJEtiXC9kfCJMvZhGfQLaujft2OgrmkcuDVtPIbQWEENhyJhb4Lk82kFXbfus= +Prime1: /rSKuzcZY7R5cY2YWD4CiBNyj9WJMq1wWmBnb9+5M08nTl5E9NW5qQ== +Prime2: 0Z5shXQYd16E2Gs6e5WxtO0Oqlly2KkSqXohwTQWDWTb8Pw0WTZmHQ== +Exponent1: qc2x0iS7l82mS7O65X6sWrehtTkGIcj1kZWaSpUmIjTE3umDTePRGw== +Exponent2: i77zA6K6+j8DOvIm/Q52eJ4JxuZMkHC3G6bBK3gOs5iSoKgi5iREEw== +Coefficient: 3+wYZB0SJad7z2EsjzgbSlg6CawoaOvrROGSbwSiW5DCsMFROudOTw== diff --git a/bin/tests/dst/Ktest.+003+23616.key b/bin/tests/dst/Ktest.+003+23616.key new file mode 100644 index 0000000..958d585 --- /dev/null +++ b/bin/tests/dst/Ktest.+003+23616.key @@ -0,0 +1 @@ +test. IN DNSKEY 16641 3 3 ANp1//lqDlEfTavcFI+cyudNfgEz73V/K7fSDvkA0eDYcGg/kSvEjAEO/oLWCERltkuC55ZcM/mSv17WF1d/wR6kww/pLI9eXwkjftAYqs5sNxk+mbEGl6zwve9wq5z7IoTY5/J4l7XLCKftg/wGvrzXQhggIkRvEh3myhxd+ouILcpfvTIthWlTKiH59tSJpmgmiSMTE7nDYaf10iVRWN6DMSprgejiH05/fpmyZAt44tyAh4m1wXS5u4tam1PXDJYJozn7EfQ8e2weIv1yC+t6PHSx diff --git a/bin/tests/dst/Ktest.+003+23616.private b/bin/tests/dst/Ktest.+003+23616.private new file mode 100644 index 0000000..5781c9d --- /dev/null +++ b/bin/tests/dst/Ktest.+003+23616.private @@ -0,0 +1,7 @@ +Private-key-format: v1.2 +Algorithm: 3 (DSA) +Prime(p): 73V/K7fSDvkA0eDYcGg/kSvEjAEO/oLWCERltkuC55ZcM/mSv17WF1d/wR6kww/pLI9eXwkjftAYqs5sNxk+mQ== +Subprime(q): 2nX/+WoOUR9Nq9wUj5zK501+ATM= +Base(g): sQaXrPC973CrnPsihNjn8niXtcsIp+2D/Aa+vNdCGCAiRG8SHebKHF36i4gtyl+9Mi2FaVMqIfn21ImmaCaJIw== +Private_value(x): Nky4tvIwg6xlcyeHXr4k2DEZg0E= +Public_value(y): ExO5w2Gn9dIlUVjegzEqa4Ho4h9Of36ZsmQLeOLcgIeJtcF0ubuLWptT1wyWCaM5+xH0PHtsHiL9cgvrejx0sQ== diff --git a/bin/tests/dst/Ktest.+003+49667.key b/bin/tests/dst/Ktest.+003+49667.key new file mode 100644 index 0000000..fb73f57 --- /dev/null +++ b/bin/tests/dst/Ktest.+003+49667.key @@ -0,0 +1 @@ +test. IN DNSKEY 49152 2 3 diff --git a/bin/tests/dst/Makefile.in b/bin/tests/dst/Makefile.in new file mode 100644 index 0000000..9b317fc --- /dev/null +++ b/bin/tests/dst/Makefile.in @@ -0,0 +1,65 @@ +# Copyright (C) 2004, 2006-2008 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 1999-2002 Internet Software Consortium. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +# $Id: Makefile.in,v 1.46 2008/05/19 23:47:03 tbox Exp $ + +srcdir = @srcdir@ +VPATH = @srcdir@ +top_srcdir = @top_srcdir@ + +@BIND9_MAKE_INCLUDES@ + +CINCLUDES = ${TEST_INCLUDES} ${DNS_INCLUDES} \ + ${ISC_INCLUDES} @DST_GSSAPI_INC@ + +CDEFINES = +CWARNINGS = + +DNSLIBS = ../../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@ +ISCLIBS = ../../../lib/isc/libisc.@A@ + +DNSDEPLIBS = ../../../lib/dns/libdns.@A@ +ISCDEPLIBS = ../../../lib/isc/libisc.@A@ + +DEPLIBS = ${DNSDEPLIBS} ${ISCDEPLIBS} + +LIBS = ${DNSLIBS} ${ISCLIBS} @LIBS@ + +TLIB = ../../../lib/tests/libt_api.@A@ + +TARGETS = dst_test@EXEEXT@ t_dst@EXEEXT@ gsstest@EXEEXT@ + +SRCS = dst_test.c t_dst.c gsstest.c + +@BIND9_MAKE_RULES@ + +dst_test@EXEEXT@: dst_test.@O@ ${DEPLIBS} + ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ + dst_test.@O@ ${LIBS} + +t_dst@EXEEXT@: t_dst.@O@ ${DEPLIBS} ${TLIB} + ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ + t_dst.@O@ ${TLIB} ${LIBS} + +gsstest@EXEEXT@: gsstest.@O@ ${DEPLIBS} + ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ + gsstest.@O@ ${LIBS} + +test: t_dst@EXEEXT@ + ../genrandom@EXEEXT@ 100 randomfile + -@ ./t_dst@EXEEXT@ -b @srcdir@ -q 1800 -a + +clean distclean:: + rm -f ${TARGETS} randomfile diff --git a/bin/tests/dst/dst_2_data b/bin/tests/dst/dst_2_data new file mode 100644 index 0000000..a303065 --- /dev/null +++ b/bin/tests/dst/dst_2_data @@ -0,0 +1,16 @@ +# +# data for signature verification test +# +# format: +# datafile, sigpath, keyname, keyid, alg, exp_result +# +t2_data_1 t2_dsasig test. 23616 DST_ALG_DSA ISC_R_SUCCESS +t2_data_1 t2_rsasig test. 54622 DST_ALG_RSAMD5 ISC_R_SUCCESS +# wrong sig +t2_data_1 t2_dsasig test. 54622 DST_ALG_RSAMD5 !ISC_R_SUCCESS +# wrong key +#t2_data_1 t2_dsasig test. 54622 DST_ALG_DSA !ISC_R_SUCCESS +# wrong alg +#t2_data_1 t2_dsasig test. 23616 DST_ALG_RSAMD5 !ISC_R_SUCCESS +# wrong data +t2_data_2 t2_dsasig test. 23616 DST_ALG_DSA !ISC_R_SUCCESS diff --git a/bin/tests/dst/dst_test.c b/bin/tests/dst/dst_test.c new file mode 100644 index 0000000..8347a7d --- /dev/null +++ b/bin/tests/dst/dst_test.c @@ -0,0 +1,294 @@ +/* + * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: dst_test.c,v 1.43 2007/06/19 23:47:00 tbox Exp $ */ + +#include + +#include + +#include /* XXX */ + +#include +#include +#include +#include +#include /* Required for HP/UX (and others?) */ + +#include +#include +#include + +#include +#include + +char *current; +const char *tmp = "/tmp"; + +static void +use(dst_key_t *key, isc_mem_t *mctx) { + isc_result_t ret; + const char *data = "This is some data"; + unsigned char sig[512]; + isc_buffer_t databuf, sigbuf; + isc_region_t datareg, sigreg; + dst_context_t *ctx = NULL; + + isc_buffer_init(&sigbuf, sig, sizeof(sig)); + /* + * Advance 1 byte for fun. + */ + isc_buffer_add(&sigbuf, 1); + + isc_buffer_init(&databuf, data, strlen(data)); + isc_buffer_add(&databuf, strlen(data)); + isc_buffer_usedregion(&databuf, &datareg); + + ret = dst_context_create(key, mctx, &ctx); + if (ret != ISC_R_SUCCESS) { + printf("contextcreate(%d) returned: %s\n", dst_key_alg(key), + isc_result_totext(ret)); + return; + } + ret = dst_context_adddata(ctx, &datareg); + if (ret != ISC_R_SUCCESS) { + printf("adddata(%d) returned: %s\n", dst_key_alg(key), + isc_result_totext(ret)); + dst_context_destroy(&ctx); + return; + } + ret = dst_context_sign(ctx, &sigbuf); + printf("sign(%d) returned: %s\n", dst_key_alg(key), + isc_result_totext(ret)); + dst_context_destroy(&ctx); + + isc_buffer_forward(&sigbuf, 1); + isc_buffer_remainingregion(&sigbuf, &sigreg); + ret = dst_context_create(key, mctx, &ctx); + if (ret != ISC_R_SUCCESS) { + printf("contextcreate(%d) returned: %s\n", dst_key_alg(key), + isc_result_totext(ret)); + return; + } + ret = dst_context_adddata(ctx, &datareg); + if (ret != ISC_R_SUCCESS) { + printf("adddata(%d) returned: %s\n", dst_key_alg(key), + isc_result_totext(ret)); + dst_context_destroy(&ctx); + return; + } + ret = dst_context_verify(ctx, &sigreg); + printf("verify(%d) returned: %s\n", dst_key_alg(key), + isc_result_totext(ret)); + dst_context_destroy(&ctx); +} + +static void +dns(dst_key_t *key, isc_mem_t *mctx) { + unsigned char buffer1[2048]; + unsigned char buffer2[2048]; + isc_buffer_t buf1, buf2; + isc_region_t r1, r2; + dst_key_t *newkey = NULL; + isc_result_t ret; + isc_boolean_t match; + + isc_buffer_init(&buf1, buffer1, sizeof(buffer1)); + ret = dst_key_todns(key, &buf1); + printf("todns(%d) returned: %s\n", dst_key_alg(key), + isc_result_totext(ret)); + if (ret != ISC_R_SUCCESS) + return; + ret = dst_key_fromdns(dst_key_name(key), dns_rdataclass_in, + &buf1, mctx, &newkey); + printf("fromdns(%d) returned: %s\n", dst_key_alg(key), + isc_result_totext(ret)); + if (ret != ISC_R_SUCCESS) + return; + isc_buffer_init(&buf2, buffer2, sizeof(buffer2)); + ret = dst_key_todns(newkey, &buf2); + printf("todns2(%d) returned: %s\n", dst_key_alg(key), + isc_result_totext(ret)); + if (ret != ISC_R_SUCCESS) + return; + isc_buffer_usedregion(&buf1, &r1); + isc_buffer_usedregion(&buf2, &r2); + match = ISC_TF(r1.length == r2.length && + memcmp(r1.base, r2.base, r1.length) == 0); + printf("compare(%d): %s\n", dst_key_alg(key), + match ? "true" : "false"); + dst_key_free(&newkey); +} + +static void +io(dns_name_t *name, int id, int alg, int type, isc_mem_t *mctx) { + dst_key_t *key = NULL; + isc_result_t ret; + + ret = dst_key_fromfile(name, id, alg, type, current, mctx, &key); + printf("read(%d) returned: %s\n", alg, isc_result_totext(ret)); + if (ret != 0) + return; + ret = dst_key_tofile(key, type, tmp); + printf("write(%d) returned: %s\n", alg, isc_result_totext(ret)); + if (ret != 0) + return; + use(key, mctx); + dns(key, mctx); + dst_key_free(&key); +} + +static void +dh(dns_name_t *name1, int id1, dns_name_t *name2, int id2, isc_mem_t *mctx) { + dst_key_t *key1 = NULL, *key2 = NULL; + isc_result_t ret; + isc_buffer_t b1, b2; + isc_region_t r1, r2; + unsigned char array1[1024], array2[1024]; + int alg = DST_ALG_DH; + int type = DST_TYPE_PUBLIC|DST_TYPE_PRIVATE|DST_TYPE_KEY; + + ret = dst_key_fromfile(name1, id1, alg, type, current, mctx, &key1); + printf("read(%d) returned: %s\n", alg, isc_result_totext(ret)); + if (ret != 0) + return; + ret = dst_key_fromfile(name2, id2, alg, type, current, mctx, &key2); + printf("read(%d) returned: %s\n", alg, isc_result_totext(ret)); + if (ret != 0) + return; + + ret = dst_key_tofile(key1, type, tmp); + printf("write(%d) returned: %s\n", alg, isc_result_totext(ret)); + if (ret != 0) + return; + ret = dst_key_tofile(key2, type, tmp); + printf("write(%d) returned: %s\n", alg, isc_result_totext(ret)); + if (ret != 0) + return; + + isc_buffer_init(&b1, array1, sizeof(array1)); + ret = dst_key_computesecret(key1, key2, &b1); + printf("computesecret() returned: %s\n", isc_result_totext(ret)); + if (ret != 0) + return; + + isc_buffer_init(&b2, array2, sizeof(array2)); + ret = dst_key_computesecret(key2, key1, &b2); + printf("computesecret() returned: %s\n", isc_result_totext(ret)); + if (ret != 0) + return; + + isc_buffer_usedregion(&b1, &r1); + isc_buffer_usedregion(&b2, &r2); + + if (r1.length != r2.length || memcmp(r1.base, r2.base, r1.length) != 0) + { + int i; + printf("secrets don't match\n"); + printf("secret 1: %d bytes\n", r1.length); + for (i = 0; i < (int) r1.length; i++) + printf("%02x ", r1.base[i]); + printf("\n"); + printf("secret 2: %d bytes\n", r2.length); + for (i = 0; i < (int) r2.length; i++) + printf("%02x ", r2.base[i]); + printf("\n"); + } + dst_key_free(&key1); + dst_key_free(&key2); +} + +static void +generate(int alg, isc_mem_t *mctx) { + isc_result_t ret; + dst_key_t *key = NULL; + + ret = dst_key_generate(dns_rootname, alg, 512, 0, 0, 0, + dns_rdataclass_in, mctx, &key); + printf("generate(%d) returned: %s\n", alg, isc_result_totext(ret)); + if (ret != ISC_R_SUCCESS) + return; + + if (alg != DST_ALG_DH) + use(key, mctx); + + dst_key_free(&key); +} + +int +main(void) { + isc_mem_t *mctx = NULL; + isc_entropy_t *ectx = NULL; + isc_buffer_t b; + dns_fixedname_t fname; + dns_name_t *name; + isc_result_t result; + + result = isc_mem_create(0, 0, &mctx); + if (result != ISC_R_SUCCESS) + return (1); + + current = isc_mem_get(mctx, 256); + if (current == NULL) + return (1); + getcwd(current, 256); + + dns_result_register(); + + result = isc_entropy_create(mctx, &ectx); + if (result != ISC_R_SUCCESS) + return (1); + result = isc_entropy_createfilesource(ectx, "randomfile"); + if (result != ISC_R_SUCCESS) + return (1); + dst_lib_init(mctx, ectx, ISC_ENTROPY_BLOCKING|ISC_ENTROPY_GOODONLY); + + dns_fixedname_init(&fname); + name = dns_fixedname_name(&fname); + isc_buffer_init(&b, "test.", 5); + isc_buffer_add(&b, 5); + result = dns_name_fromtext(name, &b, NULL, ISC_FALSE, NULL); + if (result != ISC_R_SUCCESS) + return (1); + io(name, 23616, DST_ALG_DSA, DST_TYPE_PRIVATE|DST_TYPE_PUBLIC, mctx); + io(name, 54622, DST_ALG_RSAMD5, DST_TYPE_PRIVATE|DST_TYPE_PUBLIC, + mctx); + + io(name, 49667, DST_ALG_DSA, DST_TYPE_PRIVATE|DST_TYPE_PUBLIC, mctx); + io(name, 2, DST_ALG_RSAMD5, DST_TYPE_PRIVATE|DST_TYPE_PUBLIC, mctx); + + isc_buffer_init(&b, "dh.", 3); + isc_buffer_add(&b, 3); + result = dns_name_fromtext(name, &b, NULL, ISC_FALSE, NULL); + if (result != ISC_R_SUCCESS) + return (1); + dh(name, 18602, name, 48957, mctx); + + generate(DST_ALG_RSAMD5, mctx); + generate(DST_ALG_DH, mctx); + generate(DST_ALG_DSA, mctx); + generate(DST_ALG_HMACMD5, mctx); + + dst_lib_destroy(); + isc_entropy_detach(&ectx); + + isc_mem_put(mctx, current, 256); +/* isc_mem_stats(mctx, stdout);*/ + isc_mem_destroy(&mctx); + + return (0); +} diff --git a/bin/tests/dst/gsstest.c b/bin/tests/dst/gsstest.c new file mode 100755 index 0000000..98e16d2 --- /dev/null +++ b/bin/tests/dst/gsstest.c @@ -0,0 +1,566 @@ +/* + * Copyright (C) 2006, 2007 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: gsstest.c,v 1.6 2007/06/19 23:47:00 tbox Exp $ */ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#ifdef GSSAPI +#include ISC_PLATFORM_GSSAPIHEADER + +struct dst_context { + unsigned int magic; + dst_key_t *key; + isc_mem_t *mctx; + void *opaque; +}; + +#define CHECK(str, x) { \ + if ((x) != ISC_R_SUCCESS) { \ + fprintf(stderr, "I:%d:%s: %s\n", __LINE__, (str), isc_result_totext(x)); \ + goto end; \ + } \ +} + +static char contextname[512]; +static char gssid[512]; +static char serveraddress[512]; +static dns_fixedname_t servername, gssname; + +static isc_mem_t *mctx; +static dns_requestmgr_t *requestmgr; +static isc_sockaddr_t address; + +static dns_tsig_keyring_t *ring; +static dns_tsigkey_t *tsigkey = NULL; +static gss_ctx_id_t gssctx; +static gss_ctx_id_t *gssctxp = &gssctx; + +#define RUNCHECK(x) RUNTIME_CHECK((x) == ISC_R_SUCCESS) + +#define PORT 53 +#define TIMEOUT 30 + +static void initctx1(isc_task_t *task, isc_event_t *event); +static void sendquery(isc_task_t *task, isc_event_t *event); +static void setup(); + +static void +console(isc_task_t *task, isc_event_t *event) +{ + char buf[32]; + isc_event_t *ev = NULL; + + isc_event_free(&event); + + while(1) { + printf("\nCommand => "); + scanf("%s", buf); + + if(strcmp(buf, "quit") == 0) { + isc_app_shutdown(); + return; + } + + if(strcmp(buf, "initctx") == 0) { + ev = isc_event_allocate(mctx, (void *)1, 1, initctx1, + NULL, sizeof(*event)); + isc_task_send(task, &ev); + return; + } + + if(strcmp(buf, "query") == 0) { + ev = isc_event_allocate(mctx, (void *)1, 1, sendquery, + NULL, sizeof(*event)); + isc_task_send(task, &ev); + return; + } + + printf("Unknown command\n"); + } +} + +static void +recvresponse(isc_task_t *task, isc_event_t *event) { + dns_requestevent_t *reqev = (dns_requestevent_t *)event; + isc_result_t result, result2; + dns_message_t *query, *response = NULL; + isc_buffer_t outtoken; + isc_buffer_t outbuf; + char output[10 * 1024]; + + unsigned char array[DNS_NAME_MAXTEXT + 1]; + isc_buffer_init(&outtoken, array, sizeof(array)); + + UNUSED(task); + + REQUIRE(reqev != NULL); + + if (reqev->result != ISC_R_SUCCESS) { + fprintf(stderr, "I:request event result: %s\n", + isc_result_totext(reqev->result)); + goto end; + } + + query = reqev->ev_arg; + + response = NULL; + result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response); + CHECK("dns_message_create", result); + + printf("\nReceived Response:\n"); + + result2 = dns_request_getresponse(reqev->request, response, + DNS_MESSAGEPARSE_PRESERVEORDER); + isc_buffer_init(&outbuf, output, sizeof(output)); + result = dns_message_totext(response, &dns_master_style_debug, 0, + &outbuf); + CHECK("dns_message_totext", result); + printf("%.*s\n", (int)isc_buffer_usedlength(&outbuf), + (char *)isc_buffer_base(&outbuf)); + + CHECK("dns_request_getresponse", result2); + + if (response) + dns_message_destroy(&response); + +end: + if (query) + dns_message_destroy(&query); + + if (reqev->request) + dns_request_destroy(&reqev->request); + + isc_event_free(&event); + + event = isc_event_allocate(mctx, (void *)1, 1, console, NULL, + sizeof(*event)); + isc_task_send(task, &event); + return; +} + + +static void +sendquery(isc_task_t *task, isc_event_t *event) +{ + dns_request_t *request = NULL; + dns_message_t *message = NULL; + dns_name_t *qname = NULL; + dns_rdataset_t *qrdataset = NULL; + isc_result_t result; + dns_fixedname_t queryname; + isc_buffer_t buf; + isc_buffer_t outbuf; + char output[10 * 1024]; + + static char host[256]; + + isc_event_free(&event); + + printf("Query => "); + scanf("%s", host); + + dns_fixedname_init(&queryname); + isc_buffer_init(&buf, host, strlen(host)); + isc_buffer_add(&buf, strlen(host)); + result = dns_name_fromtext(dns_fixedname_name(&queryname), &buf, + dns_rootname, ISC_FALSE, NULL); + CHECK("dns_name_fromtext", result); + + result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &message); + + message->opcode = dns_opcode_query; + message->rdclass = dns_rdataclass_in; + message->id = (unsigned short)(random() & 0xFFFF); + + result = dns_message_gettempname(message, &qname); + if (result != ISC_R_SUCCESS) + goto end; + + result = dns_message_gettemprdataset(message, &qrdataset); + if (result != ISC_R_SUCCESS) + goto end; + + dns_name_init(qname, NULL); + dns_name_clone(dns_fixedname_name(&queryname), qname); + dns_rdataset_init(qrdataset); + dns_rdataset_makequestion(qrdataset, dns_rdataclass_in, + dns_rdatatype_a); + ISC_LIST_APPEND(qname->list, qrdataset, link); + dns_message_addname(message, qname, DNS_SECTION_QUESTION); + + result = dns_request_create(requestmgr, message, &address, 0, tsigkey, + TIMEOUT, task, recvresponse, + message, &request); + CHECK("dns_request_create", result); + + printf("Submitting query:\n"); + isc_buffer_init(&outbuf, output, sizeof(output)); + result = dns_message_totext(message, &dns_master_style_debug, 0, + &outbuf); + CHECK("dns_message_totext", result); + printf("%.*s\n", (int)isc_buffer_usedlength(&outbuf), + (char *)isc_buffer_base(&outbuf)); + + return; + + end: + if (qname != NULL) + dns_message_puttempname(message, &qname); + if (qrdataset != NULL) + dns_message_puttemprdataset(message, &qrdataset); + if (message != NULL) + dns_message_destroy(&message); +} + +static void +initctx2(isc_task_t *task, isc_event_t *event) { + dns_requestevent_t *reqev = (dns_requestevent_t *)event; + isc_result_t result; + dns_message_t *query, *response = NULL; + isc_buffer_t outtoken; + unsigned char array[DNS_NAME_MAXTEXT + 1]; + dns_rdataset_t *rdataset; + dns_rdatatype_t qtype; + dns_name_t *question_name; + + UNUSED(task); + + REQUIRE(reqev != NULL); + + if (reqev->result != ISC_R_SUCCESS) { + fprintf(stderr, "I:request event result: %s\n", + isc_result_totext(reqev->result)); + goto end; + } + + query = reqev->ev_arg; + + response = NULL; + result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response); + CHECK("dns_message_create", result); + + result = dns_request_getresponse(reqev->request, response, + DNS_MESSAGEPARSE_PRESERVEORDER); + CHECK("dns_request_getresponse", result); + + if (response->rcode != dns_rcode_noerror) { + result = ISC_RESULTCLASS_DNSRCODE + response->rcode; + fprintf(stderr, "I:response rcode: %s\n", + isc_result_totext(result)); + goto end; + } + + printf("Received token from server, calling gss_init_sec_context()\n"); + isc_buffer_init(&outtoken, array, DNS_NAME_MAXTEXT + 1); + result = dns_tkey_processgssresponse(query, response, + dns_fixedname_name(&gssname), + &gssctx, &outtoken, + &tsigkey, ring); + gssctx = *gssctxp; + CHECK("dns_tkey_processgssresponse", result); + printf("Context accepted\n"); + + question_name = NULL; + dns_message_currentname(response, DNS_SECTION_ANSWER, &question_name); + rdataset = ISC_LIST_HEAD(question_name->list); + INSIST(rdataset != NULL); + qtype = rdataset->type; + if(qtype == dns_rdatatype_tkey) { + printf("Received TKEY response from server\n"); + printf("Context completed\n"); + } else { + printf("Did not receive TKEY response from server\n"); + printf("Context not completed\n"); + dns_tsigkey_detach(&tsigkey); + tsigkey = NULL; + } + + if(response) + dns_message_destroy(&response); + +end: + if(query) + dns_message_destroy(&query); + + if(reqev->request) + dns_request_destroy(&reqev->request); + + isc_event_free(&event); + + event = isc_event_allocate(mctx, (void *)1, 1, console, NULL, + sizeof(*event)); + isc_task_send(task, &event); + return; +} + +static void +initctx1(isc_task_t *task, isc_event_t *event) { + isc_result_t result; + isc_buffer_t buf; + dns_message_t *query; + dns_request_t *request; + + isc_event_free(&event); + + printf("Initctx - GSS name => "); + scanf("%s", gssid); + + sprintf(contextname, "gsstest.context.%d.", (int)time(NULL)); + + printf("Initctx - context name we're using: %s\n", contextname); + + printf("Negotiating GSSAPI context: "); + printf(gssid); + printf("\n"); + + /* + * Setup a GSSAPI context with the server + */ + dns_fixedname_init(&servername); + isc_buffer_init(&buf, contextname, strlen(contextname)); + isc_buffer_add(&buf, strlen(contextname)); + result = dns_name_fromtext(dns_fixedname_name(&servername), &buf, + dns_rootname, ISC_FALSE, NULL); + CHECK("dns_name_fromtext", result); + + /* Make name happen */ + dns_fixedname_init(&gssname); + isc_buffer_init(&buf, gssid, strlen(gssid)); + isc_buffer_add(&buf, strlen(gssid)); + result = dns_name_fromtext(dns_fixedname_name(&gssname), &buf, + dns_rootname, ISC_FALSE, NULL); + CHECK("dns_name_fromtext", result); + + query = NULL; + result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &query); + CHECK("dns_message_create", result); + + printf("Calling gss_init_sec_context()\n"); + gssctx = GSS_C_NO_CONTEXT; + result = dns_tkey_buildgssquery(query, dns_fixedname_name(&servername), + dns_fixedname_name(&gssname), + NULL, 36000, &gssctx, ISC_TRUE); + CHECK("dns_tkey_buildgssquery", result); + + printf("Sending context token to server\n"); + request = NULL; + result = dns_request_create(requestmgr, query, &address, 0, NULL, + TIMEOUT, task, initctx2, query, &request); + CHECK("dns_request_create", result); + + return; +end: + event = isc_event_allocate(mctx, (void *)1, 1, console, NULL, + sizeof(*event)); + isc_task_send(task, &event);return; +} + +static void +setup(void) +{ + struct in_addr inaddr; + int c; + + while (1) { + printf("Server IP => "); + c = scanf("%s", serveraddress); + + if(c == EOF || strcmp(serveraddress, "quit") == 0) { + isc_app_shutdown(); + return; + } + + if (inet_pton(AF_INET, serveraddress, &inaddr) == 1) { + isc_sockaddr_fromin(&address, &inaddr, PORT); + return; + } + + }; +} + +int +main(int argc, char *argv[]) { + isc_taskmgr_t *taskmgr; + isc_timermgr_t *timermgr; + isc_socketmgr_t *socketmgr; + isc_socket_t *sock; + unsigned int attrs, attrmask; + isc_sockaddr_t bind_any; + dns_dispatchmgr_t *dispatchmgr; + dns_dispatch_t *dispatchv4; + dns_view_t *view; + isc_entropy_t *ectx; + isc_task_t *task; + isc_log_t *lctx = NULL; + isc_logconfig_t *lcfg = NULL; + isc_logdestination_t destination; + + UNUSED(argv); + UNUSED(argc); + + RUNCHECK(isc_app_start()); + + dns_result_register(); + + mctx = NULL; + RUNCHECK(isc_mem_create(0, 0, &mctx)); + + RUNCHECK(isc_log_create(mctx, &lctx, &lcfg)); + isc_log_setcontext(lctx); + dns_log_init(lctx); + dns_log_setcontext(lctx); + + /* + * Create and install the default channel. + */ + destination.file.stream = stderr; + destination.file.name = NULL; + destination.file.versions = ISC_LOG_ROLLNEVER; + destination.file.maximum_size = 0; + RUNCHECK(isc_log_createchannel(lcfg, "_default", + ISC_LOG_TOFILEDESC, + ISC_LOG_DYNAMIC, + &destination, ISC_LOG_PRINTTIME)); + RUNCHECK(isc_log_usechannel(lcfg, "_default", NULL, NULL)); + + isc_log_setdebuglevel(lctx, 9); + + ectx = NULL; + RUNCHECK(isc_entropy_create(mctx, &ectx)); + RUNCHECK(isc_entropy_createfilesource(ectx, "/dev/urandom")); + + RUNCHECK(dst_lib_init(mctx, ectx, ISC_ENTROPY_GOODONLY)); + + taskmgr = NULL; + RUNCHECK(isc_taskmgr_create(mctx, 1, 0, &taskmgr)); + task = NULL; + RUNCHECK(isc_task_create(taskmgr, 0, &task)); + timermgr = NULL; + RUNCHECK(isc_timermgr_create(mctx, &timermgr)); + socketmgr = NULL; + RUNCHECK(isc_socketmgr_create(mctx, &socketmgr)); + dispatchmgr = NULL; + RUNCHECK(dns_dispatchmgr_create(mctx, ectx, &dispatchmgr)); + isc_sockaddr_any(&bind_any); + attrs = DNS_DISPATCHATTR_UDP | + DNS_DISPATCHATTR_MAKEQUERY | + DNS_DISPATCHATTR_IPV4; + attrmask = DNS_DISPATCHATTR_UDP | + DNS_DISPATCHATTR_TCP | + DNS_DISPATCHATTR_IPV4 | + DNS_DISPATCHATTR_IPV6; + dispatchv4 = NULL; + RUNCHECK(dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, + &bind_any, 4096, 4, 2, 3, 5, + attrs, attrmask, &dispatchv4)); + requestmgr = NULL; + RUNCHECK(dns_requestmgr_create(mctx, timermgr, socketmgr, taskmgr, + dispatchmgr, dispatchv4, NULL, + &requestmgr)); + + ring = NULL; + RUNCHECK(dns_tsigkeyring_create(mctx, &ring)); + + view = NULL; + RUNCHECK(dns_view_create(mctx, 0, "_test", &view)); + dns_view_setkeyring(view, ring); + + sock = NULL; + RUNCHECK(isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, + &sock)); + + setup(); + + RUNCHECK(isc_app_onrun(mctx, task, console, NULL)); + + (void)isc_app_run(); + + if (tsigkey) + dns_tsigkey_detach(&tsigkey); + + dns_requestmgr_shutdown(requestmgr); + dns_requestmgr_detach(&requestmgr); + + dns_dispatch_detach(&dispatchv4); + dns_dispatchmgr_destroy(&dispatchmgr); + + isc_timermgr_destroy(&timermgr); + + isc_task_detach(&task); + isc_taskmgr_destroy(&taskmgr); + + isc_socket_detach(&sock); + isc_socketmgr_destroy(&socketmgr); + + isc_mem_stats(mctx, stdout); + + dns_view_detach(&view); + + dst_lib_destroy(); + isc_entropy_detach(&ectx); + + isc_mem_stats(mctx, stdout); + isc_mem_destroy(&mctx); + + isc_app_finish(); + + return (0); +} +#else +int +main(int argc, char *argv[]) { + UNUSED(argc); + UNUSED(argv); + fprintf(stderr, "R:GSSAPIONLY\n"); + return (0); +} +#endif diff --git a/bin/tests/dst/t2_data_1 b/bin/tests/dst/t2_data_1 new file mode 100644 index 0000000..b1a9bf5 --- /dev/null +++ b/bin/tests/dst/t2_data_1 @@ -0,0 +1,3077 @@ +Network Working Group P. Mockapetris +Request for Comments: 1035 ISI + November 1987 +Obsoletes: RFCs 882, 883, 973 + + DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION + + +1. STATUS OF THIS MEMO + +This RFC describes the details of the domain system and protocol, and +assumes that the reader is familiar with the concepts discussed in a +companion RFC, "Domain Names - Concepts and Facilities" [RFC-1034]. + +The domain system is a mixture of functions and data types which are an +official protocol and functions and data types which are still +experimental. Since the domain system is intentionally extensible, new +data types and experimental behavior should always be expected in parts +of the system beyond the official protocol. The official protocol parts +include standard queries, responses and the Internet class RR data +formats (e.g., host addresses). Since the previous RFC set, several +definitions have changed, so some previous definitions are obsolete. + +Experimental or obsolete features are clearly marked in these RFCs, and +such information should be used with caution. + +The reader is especially cautioned not to depend on the values which +appear in examples to be current or complete, since their purpose is +primarily pedagogical. Distribution of this memo is unlimited. + + Table of Contents + + 1. STATUS OF THIS MEMO 1 + 2. INTRODUCTION 3 + 2.1. Overview 3 + 2.2. Common configurations 4 + 2.3. Conventions 7 + 2.3.1. Preferred name syntax 7 + 2.3.2. Data Transmission Order 8 + 2.3.3. Character Case 9 + 2.3.4. Size limits 10 + 3. DOMAIN NAME SPACE AND RR DEFINITIONS 10 + 3.1. Name space definitions 10 + 3.2. RR definitions 11 + 3.2.1. Format 11 + 3.2.2. TYPE values 12 + 3.2.3. QTYPE values 12 + 3.2.4. CLASS values 13 + + + +Mockapetris [Page 1] + +RFC 1035 Domain Implementation and Specification November 1987 + + + 3.2.5. QCLASS values 13 + 3.3. Standard RRs 13 + 3.3.1. CNAME RDATA format 14 + 3.3.2. HINFO RDATA format 14 + 3.3.3. MB RDATA format (EXPERIMENTAL) 14 + 3.3.4. MD RDATA format (Obsolete) 15 + 3.3.5. MF RDATA format (Obsolete) 15 + 3.3.6. MG RDATA format (EXPERIMENTAL) 16 + 3.3.7. MINFO RDATA format (EXPERIMENTAL) 16 + 3.3.8. MR RDATA format (EXPERIMENTAL) 17 + 3.3.9. MX RDATA format 17 + 3.3.10. NULL RDATA format (EXPERIMENTAL) 17 + 3.3.11. NS RDATA format 18 + 3.3.12. PTR RDATA format 18 + 3.3.13. SOA RDATA format 19 + 3.3.14. TXT RDATA format 20 + 3.4. ARPA Internet specific RRs 20 + 3.4.1. A RDATA format 20 + 3.4.2. WKS RDATA format 21 + 3.5. IN-ADDR.ARPA domain 22 + 3.6. Defining new types, classes, and special namespaces 24 + 4. MESSAGES 25 + 4.1. Format 25 + 4.1.1. Header section format 26 + 4.1.2. Question section format 28 + 4.1.3. Resource record format 29 + 4.1.4. Message compression 30 + 4.2. Transport 32 + 4.2.1. UDP usage 32 + 4.2.2. TCP usage 32 + 5. MASTER FILES 33 + 5.1. Format 33 + 5.2. Use of master files to define zones 35 + 5.3. Master file example 36 + 6. NAME SERVER IMPLEMENTATION 37 + 6.1. Architecture 37 + 6.1.1. Control 37 + 6.1.2. Database 37 + 6.1.3. Time 39 + 6.2. Standard query processing 39 + 6.3. Zone refresh and reload processing 39 + 6.4. Inverse queries (Optional) 40 + 6.4.1. The contents of inverse queries and responses 40 + 6.4.2. Inverse query and response example 41 + 6.4.3. Inverse query processing 42 + + + + + + +Mockapetris [Page 2] + +RFC 1035 Domain Implementation and Specification November 1987 + + + 6.5. Completion queries and responses 42 + 7. RESOLVER IMPLEMENTATION 43 + 7.1. Transforming a user request into a query 43 + 7.2. Sending the queries 44 + 7.3. Processing responses 46 + 7.4. Using the cache 47 + 8. MAIL SUPPORT 47 + 8.1. Mail exchange binding 48 + 8.2. Mailbox binding (Experimental) 48 + 9. REFERENCES and BIBLIOGRAPHY 50 + Index 54 + +2. INTRODUCTION + +2.1. Overview + +The goal of domain names is to provide a mechanism for naming resources +in such a way that the names are usable in different hosts, networks, +protocol families, internets, and administrative organizations. + +From the user's point of view, domain names are useful as arguments to a +local agent, called a resolver, which retrieves information associated +with the domain name. Thus a user might ask for the host address or +mail information associated with a particular domain name. To enable +the user to request a particular type of information, an appropriate +query type is passed to the resolver with the domain name. To the user, +the domain tree is a single information space; the resolver is +responsible for hiding the distribution of data among name servers from +the user. + +From the resolver's point of view, the database that makes up the domain +space is distributed among various name servers. Different parts of the +domain space are stored in different name servers, although a particular +data item will be stored redundantly in two or more name servers. The +resolver starts with knowledge of at least one name server. When the +resolver processes a user query it asks a known name server for the +information; in return, the resolver either receives the desired +information or a referral to another name server. Using these +referrals, resolvers learn the identities and contents of other name +servers. Resolvers are responsible for dealing with the distribution of +the domain space and dealing with the effects of name server failure by +consulting redundant databases in other servers. + +Name servers manage two kinds of data. The first kind of data held in +sets called zones; each zone is the complete database for a particular +"pruned" subtree of the domain space. This data is called +authoritative. A name server periodically checks to make sure that its +zones are up to date, and if not, obtains a new copy of updated zones + + + +Mockapetris [Page 3] + +RFC 1035 Domain Implementation and Specification November 1987 + + +from master files stored locally or in another name server. The second +kind of data is cached data which was acquired by a local resolver. +This data may be incomplete, but improves the performance of the +retrieval process when non-local data is repeatedly accessed. Cached +data is eventually discarded by a timeout mechanism. + +This functional structure isolates the problems of user interface, +failure recovery, and distribution in the resolvers and isolates the +database update and refresh problems in the name servers. + +2.2. Common configurations + +A host can participate in the domain name system in a number of ways, +depending on whether the host runs programs that retrieve information +from the domain system, name servers that answer queries from other +hosts, or various combinations of both functions. The simplest, and +perhaps most typical, configuration is shown below: + + Local Host | Foreign + | + +---------+ +----------+ | +--------+ + | | user queries | |queries | | | + | User |-------------->| |---------|->|Foreign | + | Program | | Resolver | | | Name | + | |<--------------| |<--------|--| Server | + | | user responses| |responses| | | + +---------+ +----------+ | +--------+ + | A | + cache additions | | references | + V | | + +----------+ | + | cache | | + +----------+ | + +User programs interact with the domain name space through resolvers; the +format of user queries and user responses is specific to the host and +its operating system. User queries will typically be operating system +calls, and the resolver and its cache will be part of the host operating +system. Less capable hosts may choose to implement the resolver as a +subroutine to be linked in with every program that needs its services. +Resolvers answer user queries with information they acquire via queries +to foreign name servers and the local cache. + +Note that the resolver may have to make several queries to several +different foreign name servers to answer a particular user query, and +hence the resolution of a user query may involve several network +accesses and an arbitrary amount of time. The queries to foreign name +servers and the corresponding responses have a standard format described + + + +Mockapetris [Page 4] + +RFC 1035 Domain Implementation and Specification November 1987 + + +in this memo, and may be datagrams. + +Depending on its capabilities, a name server could be a stand alone +program on a dedicated machine or a process or processes on a large +timeshared host. A simple configuration might be: + + Local Host | Foreign + | + +---------+ | + / /| | + +---------+ | +----------+ | +--------+ + | | | | |responses| | | + | | | | Name |---------|->|Foreign | + | Master |-------------->| Server | | |Resolver| + | files | | | |<--------|--| | + | |/ | | queries | +--------+ + +---------+ +----------+ | + +Here a primary name server acquires information about one or more zones +by reading master files from its local file system, and answers queries +about those zones that arrive from foreign resolvers. + +The DNS requires that all zones be redundantly supported by more than +one name server. Designated secondary servers can acquire zones and +check for updates from the primary server using the zone transfer +protocol of the DNS. This configuration is shown below: + + Local Host | Foreign + | + +---------+ | + / /| | + +---------+ | +----------+ | +--------+ + | | | | |responses| | | + | | | | Name |---------|->|Foreign | + | Master |-------------->| Server | | |Resolver| + | files | | | |<--------|--| | + | |/ | | queries | +--------+ + +---------+ +----------+ | + A |maintenance | +--------+ + | +------------|->| | + | queries | |Foreign | + | | | Name | + +------------------|--| Server | + maintenance responses | +--------+ + +In this configuration, the name server periodically establishes a +virtual circuit to a foreign name server to acquire a copy of a zone or +to check that an existing copy has not changed. The messages sent for + + + +Mockapetris [Page 5] + +RFC 1035 Domain Implementation and Specification November 1987 + + +these maintenance activities follow the same form as queries and +responses, but the message sequences are somewhat different. + +The information flow in a host that supports all aspects of the domain +name system is shown below: + + Local Host | Foreign + | + +---------+ +----------+ | +--------+ + | | user queries | |queries | | | + | User |-------------->| |---------|->|Foreign | + | Program | | Resolver | | | Name | + | |<--------------| |<--------|--| Server | + | | user responses| |responses| | | + +---------+ +----------+ | +--------+ + | A | + cache additions | | references | + V | | + +----------+ | + | Shared | | + | database | | + +----------+ | + A | | + +---------+ refreshes | | references | + / /| | V | + +---------+ | +----------+ | +--------+ + | | | | |responses| | | + | | | | Name |---------|->|Foreign | + | Master |-------------->| Server | | |Resolver| + | files | | | |<--------|--| | + | |/ | | queries | +--------+ + +---------+ +----------+ | + A |maintenance | +--------+ + | +------------|->| | + | queries | |Foreign | + | | | Name | + +------------------|--| Server | + maintenance responses | +--------+ + +The shared database holds domain space data for the local name server +and resolver. The contents of the shared database will typically be a +mixture of authoritative data maintained by the periodic refresh +operations of the name server and cached data from previous resolver +requests. The structure of the domain data and the necessity for +synchronization between name servers and resolvers imply the general +characteristics of this database, but the actual format is up to the +local implementor. + + + + +Mockapetris [Page 6] + +RFC 1035 Domain Implementation and Specification November 1987 + + +Information flow can also be tailored so that a group of hosts act +together to optimize activities. Sometimes this is done to offload less +capable hosts so that they do not have to implement a full resolver. +This can be appropriate for PCs or hosts which want to minimize the +amount of new network code which is required. This scheme can also +allow a group of hosts can share a small number of caches rather than +maintaining a large number of separate caches, on the premise that the +centralized caches will have a higher hit ratio. In either case, +resolvers are replaced with stub resolvers which act as front ends to +resolvers located in a recursive server in one or more name servers +known to perform that service: + + Local Hosts | Foreign + | + +---------+ | + | | responses | + | Stub |<--------------------+ | + | Resolver| | | + | |----------------+ | | + +---------+ recursive | | | + queries | | | + V | | + +---------+ recursive +----------+ | +--------+ + | | queries | |queries | | | + | Stub |-------------->| Recursive|---------|->|Foreign | + | Resolver| | Server | | | Name | + | |<--------------| |<--------|--| Server | + +---------+ responses | |responses| | | + +----------+ | +--------+ + | Central | | + | cache | | + +----------+ | + +In any case, note that domain components are always replicated for +reliability whenever possible. + +2.3. Conventions + +The domain system has several conventions dealing with low-level, but +fundamental, issues. While the implementor is free to violate these +conventions WITHIN HIS OWN SYSTEM, he must observe these conventions in +ALL behavior observed from other hosts. + +2.3.1. Preferred name syntax + +The DNS specifications attempt to be as general as possible in the rules +for constructing domain names. The idea is that the name of any +existing object can be expressed as a domain name with minimal changes. + + + +Mockapetris [Page 7] + +RFC 1035 Domain Implementation and Specification November 1987 + + +However, when assigning a domain name for an object, the prudent user +will select a name which satisfies both the rules of the domain system +and any existing rules for the object, whether these rules are published +or implied by existing programs. + +For example, when naming a mail domain, the user should satisfy both the +rules of this memo and those in RFC-822. When creating a new host name, +the old rules for HOSTS.TXT should be followed. This avoids problems +when old software is converted to use domain names. + +The following syntax will result in fewer problems with many + +applications that use domain names (e.g., mail, TELNET). + + ::= | " " + + ::=