mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-01-27 17:09:20 -05:00
unbound-anchor work
git-svn-id: file:///svn/unbound/trunk@2242 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
1797024a4e
commit
1c2a8d977c
9 changed files with 651 additions and 11 deletions
20
Makefile.in
20
Makefile.in
|
|
@ -110,6 +110,8 @@ CONTROL_SRC=smallapp/unbound-control.c smallapp/worker_cb.c $(COMMON_SRC)
|
|||
CONTROL_OBJ=$(addprefix $(BUILD),$(CONTROL_SRC:.c=.lo)) $(COMPAT_OBJ)
|
||||
HOST_SRC=smallapp/unbound-host.c
|
||||
HOST_OBJ=$(addprefix $(BUILD),$(HOST_SRC:.c=.lo)) $(filter-out $(BUILD)compat/ctime_r.lo, $(COMPAT_OBJ))
|
||||
UBANCHOR_SRC=smallapp/unbound-anchor.c
|
||||
UBANCHOR_OBJ=$(addprefix $(BUILD),$(UBANCHOR_SRC:.c=.lo)) $(filter-out $(BUILD)compat/ctime_r.lo, $(COMPAT_OBJ))
|
||||
TESTBOUND_SRC=testcode/testbound.c testcode/ldns-testpkts.c \
|
||||
daemon/worker.c daemon/acl_list.c daemon/daemon.c daemon/stats.c \
|
||||
testcode/replay.c testcode/fake_event.c $(filter-out util/netevent.c \
|
||||
|
|
@ -141,7 +143,7 @@ ALL_SRC=$(sort $(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) \
|
|||
$(TESTBOUND_SRC) $(LOCKVERIFY_SRC) $(PKTVIEW_SRC) $(SIGNIT_SRC) \
|
||||
$(MEMSTATS_SRC) $(CHECKCONF_SRC) $(LIBUNBOUND_SRC) $(HOST_SRC) \
|
||||
$(ASYNCLOOK_SRC) $(STREAMTCP_SRC) $(PERF_SRC) $(DELAYER_SRC) \
|
||||
$(HARVEST_SRC) $(CONTROL_SRC))
|
||||
$(HARVEST_SRC) $(CONTROL_SRC) $(UBANCHOR_SRC))
|
||||
ALL_OBJ=$(addprefix $(BUILD),$(ALL_SRC:.c=.lo) \
|
||||
$(addprefix compat/,$(LIBOBJS:.o=.lo))) $(COMPAT_OBJ)
|
||||
|
||||
|
|
@ -149,6 +151,7 @@ ifeq "$(UB_ON_WINDOWS)" "yes"
|
|||
DAEMON_SRC+=winrc/win_svc.c winrc/w_inst.c
|
||||
DAEMON_OBJ+=$(BUILD)winrc/rsrc_unbound.o $(BUILD)winrc/win_svc.lo
|
||||
HOST_OBJ+=$(BUILD)winrc/rsrc_unbound_host.o
|
||||
UBANCHOR_OBJ+=$(BUILD)winrc/rsrc_unbound_anchor.o
|
||||
CONTROL_OBJ+=$(BUILD)winrc/rsrc_unbound_control.o
|
||||
CHECKCONF_OBJ+=$(BUILD)winrc/rsrc_unbound_checkconf.o
|
||||
|
||||
|
|
@ -188,7 +191,7 @@ $(BUILD)%.lo: $(srcdir)/%.c
|
|||
@-if test ! -d $(dir $@); then $(INSTALL) -d $(patsubst %/,%,$(dir $@)); fi
|
||||
$Q$(COMPILE) -o $@ -c $<
|
||||
|
||||
all: $(COMMON_OBJ) unbound$(EXEEXT) unbound-checkconf$(EXEEXT) lib unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-control-setup $(WINAPPS)
|
||||
all: $(COMMON_OBJ) unbound$(EXEEXT) unbound-checkconf$(EXEEXT) lib unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup $(WINAPPS)
|
||||
|
||||
TEST_BIN=$(addsuffix $(EXEEXT),asynclook delayer harvest lock-verify \
|
||||
memstats perf pktview signit streamtcp testbound unittest)
|
||||
|
|
@ -238,6 +241,10 @@ unbound-host$(EXEEXT): $(HOST_OBJ) libunbound.la $(ldnslib)
|
|||
$(INFO) Link $@
|
||||
$Q$(LINK) -o $@ $(sort $(HOST_OBJ)) -L. -L.libs -lunbound $(LIBS)
|
||||
|
||||
unbound-anchor$(EXEEXT): $(UBANCHOR_OBJ) libunbound.la $(ldnslib)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK) -o $@ $(sort $(UBANCHOR_OBJ)) -L. -L.libs -lunbound -lexpat -lssl $(LIBS)
|
||||
|
||||
unbound-service-install$(EXEEXT): $(SVCINST_OBJ)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK) -o $@ $(sort $(SVCINST_OBJ)) $(LIBS)
|
||||
|
|
@ -343,7 +350,7 @@ util/configparser.c util/configparser.h: $(srcdir)/util/configparser.y
|
|||
|
||||
clean:
|
||||
rm -f *.o *.d *.lo *~ tags
|
||||
rm -f unbound$(EXEEXT) unbound-checkconf$(EXEEXT) unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-control-setup libunbound.la
|
||||
rm -f unbound$(EXEEXT) unbound-checkconf$(EXEEXT) unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup libunbound.la
|
||||
rm -rf autom4te.cache .libs build doc/html doc/xml
|
||||
|
||||
realclean: clean
|
||||
|
|
@ -380,6 +387,7 @@ strip:
|
|||
$(STRIP) unbound-checkconf$(EXEEXT)
|
||||
$(STRIP) unbound-control$(EXEEXT)
|
||||
$(STRIP) unbound-host$(EXEEXT)
|
||||
$(STRIP) unbound-anchor$(EXEEXT)
|
||||
|
||||
install: all
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(sbindir)
|
||||
|
|
@ -394,6 +402,7 @@ install: all
|
|||
$(LIBTOOL) --mode=install cp unbound-checkconf$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-checkconf$(EXEEXT)
|
||||
$(LIBTOOL) --mode=install cp unbound-control$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-control$(EXEEXT)
|
||||
$(LIBTOOL) --mode=install cp unbound-host$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-host$(EXEEXT)
|
||||
$(LIBTOOL) --mode=install cp unbound-anchor$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-anchor$(EXEEXT)
|
||||
ifeq "$(WITH_PYTHONMODULE)" "yes"
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(PYTHON_SITE_PKG)
|
||||
$(INSTALL) -c -m 644 pythonmod/unboundmodule.py $(DESTDIR)$(PYTHON_SITE_PKG)/unboundmodule.py
|
||||
|
|
@ -407,6 +416,7 @@ endif
|
|||
$(INSTALL) -c -m 644 doc/unbound.8 $(DESTDIR)$(mandir)/man8
|
||||
$(INSTALL) -c -m 644 doc/unbound-checkconf.8 $(DESTDIR)$(mandir)/man8
|
||||
$(INSTALL) -c -m 644 doc/unbound-control.8 $(DESTDIR)$(mandir)/man8
|
||||
$(INSTALL) -c -m 644 doc/unbound-anchor.8 $(DESTDIR)$(mandir)/man8
|
||||
$(INSTALL) -c -m 644 doc/unbound.conf.5 $(DESTDIR)$(mandir)/man5
|
||||
$(INSTALL) -c -m 644 $(srcdir)/doc/unbound-host.1 $(DESTDIR)$(mandir)/man1
|
||||
$(INSTALL) -c -m 644 doc/libunbound.3 $(DESTDIR)$(mandir)/man3
|
||||
|
|
@ -417,8 +427,8 @@ endif
|
|||
$(LIBTOOL) --mode=finish $(DESTDIR)$(libdir)
|
||||
|
||||
uninstall:
|
||||
rm -f -- $(DESTDIR)$(sbindir)/unbound$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-checkconf$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-host$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-control$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-control-setup
|
||||
rm -f -- $(DESTDIR)$(mandir)/man8/unbound.8 $(DESTDIR)$(mandir)/man8/unbound-checkconf.8 $(DESTDIR)$(mandir)/man5/unbound.conf.5 $(DESTDIR)$(mandir)/man8/unbound-control.8
|
||||
rm -f -- $(DESTDIR)$(sbindir)/unbound$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-checkconf$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-host$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-control$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-anchor$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-control-setup
|
||||
rm -f -- $(DESTDIR)$(mandir)/man8/unbound.8 $(DESTDIR)$(mandir)/man8/unbound-checkconf.8 $(DESTDIR)$(mandir)/man5/unbound.conf.5 $(DESTDIR)$(mandir)/man8/unbound-control.8 $(DESTDIR)$(mandir)/man8/unbound-anchor.8
|
||||
rm -f -- $(DESTDIR)$(mandir)/man1/unbound-host.1 $(DESTDIR)$(mandir)/man3/libunbound.3
|
||||
rm -f -- $(DESTDIR)$(includedir)/unbound.h
|
||||
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/libunbound.la
|
||||
|
|
|
|||
|
|
@ -84,6 +84,9 @@
|
|||
/* Define to 1 if you have the `ev_loop' function. */
|
||||
#undef HAVE_EV_LOOP
|
||||
|
||||
/* Define to 1 if you have the <expat.h> header file. */
|
||||
#undef HAVE_EXPAT_H
|
||||
|
||||
/* Define to 1 if you have the `fcntl' function. */
|
||||
#undef HAVE_FCNTL
|
||||
|
||||
|
|
|
|||
5
configure
vendored
5
configure
vendored
|
|
@ -12421,7 +12421,7 @@ CC="$lt_save_CC"
|
|||
|
||||
|
||||
# Checks for header files.
|
||||
for ac_header in stdarg.h stdbool.h netinet/in.h sys/param.h sys/socket.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h
|
||||
for ac_header in stdarg.h stdbool.h netinet/in.h sys/param.h sys/socket.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h expat.h
|
||||
do :
|
||||
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
||||
ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
|
||||
|
|
@ -16542,7 +16542,7 @@ _ACEOF
|
|||
|
||||
|
||||
|
||||
ac_config_files="$ac_config_files Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8"
|
||||
ac_config_files="$ac_config_files Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8"
|
||||
|
||||
ac_config_headers="$ac_config_headers config.h"
|
||||
|
||||
|
|
@ -17497,6 +17497,7 @@ do
|
|||
"doc/example.conf") CONFIG_FILES="$CONFIG_FILES doc/example.conf" ;;
|
||||
"doc/libunbound.3") CONFIG_FILES="$CONFIG_FILES doc/libunbound.3" ;;
|
||||
"doc/unbound.8") CONFIG_FILES="$CONFIG_FILES doc/unbound.8" ;;
|
||||
"doc/unbound-anchor.8") CONFIG_FILES="$CONFIG_FILES doc/unbound-anchor.8" ;;
|
||||
"doc/unbound-checkconf.8") CONFIG_FILES="$CONFIG_FILES doc/unbound-checkconf.8" ;;
|
||||
"doc/unbound.conf.5") CONFIG_FILES="$CONFIG_FILES doc/unbound.conf.5" ;;
|
||||
"doc/unbound-control.8") CONFIG_FILES="$CONFIG_FILES doc/unbound-control.8" ;;
|
||||
|
|
|
|||
|
|
@ -218,7 +218,7 @@ AC_CHECK_TOOL(STRIP, strip)
|
|||
ACX_LIBTOOL_C_ONLY
|
||||
|
||||
# Checks for header files.
|
||||
AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h sys/param.h sys/socket.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h sys/param.h sys/socket.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h expat.h],,, [AC_INCLUDES_DEFAULT])
|
||||
|
||||
# check for types.
|
||||
# Using own tests for int64* because autoconf builtin only give 32bit.
|
||||
|
|
@ -816,6 +816,6 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
|||
#define UNBOUND_DNS_PORT 53
|
||||
])
|
||||
|
||||
AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8])
|
||||
AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8])
|
||||
AC_CONFIG_HEADER([config.h])
|
||||
AC_OUTPUT
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
23 September 2010: Wouter
|
||||
- unbound-anchor app, unbound requires libexpat (xml parser library).
|
||||
|
||||
22 September 2010: Wouter
|
||||
- compliance with draft-ietf-dnsop-default-local-zones-14, removed
|
||||
reverse ipv6 orchid prefix from builtin list.
|
||||
|
|
|
|||
64
doc/unbound-anchor.8.in
Normal file
64
doc/unbound-anchor.8.in
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
.TH "unbound-anchor" "8" "@date@" "NLnet Labs" "unbound @version@"
|
||||
.\"
|
||||
.\" unbound-control.8 -- unbound remote control manual
|
||||
.\"
|
||||
.\" Copyright (c) 2008, NLnet Labs. All rights reserved.
|
||||
.\"
|
||||
.\" See LICENSE for the license.
|
||||
.\"
|
||||
.\"
|
||||
.SH "NAME"
|
||||
.LP
|
||||
.B unbound\-anchor
|
||||
\- Unbound anchor utility.
|
||||
.SH "SYNOPSIS"
|
||||
.B unbound\-anchor
|
||||
.RB [ opts ]
|
||||
.SH "DESCRIPTION"
|
||||
.B Unbound\-anchor
|
||||
performs setup or update of the root trust anchor for DNSSEC validation.
|
||||
It can be run (as root) from the commandline, or run as part of startup
|
||||
scripts. Before you start the \fIunbound\fR(8) DNS server.
|
||||
.P
|
||||
It provides builtin default contents for the root anchor and root update
|
||||
certificate files.
|
||||
.P
|
||||
It tests if the root anchor file works, and if not, and an update is possible,
|
||||
attempts to update the root anchor using the root update certificate.
|
||||
It performs a https fetch of root-anchors.xml and checks the results, if
|
||||
all checks are successful, it updates the root anchor file. Otherwise
|
||||
the root anchor file is unchanged. It performs RFC5011 tracking if the
|
||||
DNSSEC information available via the DNS makes that possible.
|
||||
.P
|
||||
If does not perform an update if the certificate is expired, if the network
|
||||
is down or other errors occur.
|
||||
.P
|
||||
The available options are:
|
||||
.TP
|
||||
.B \-a \fIfile
|
||||
The root anchor key file, that is read in and written out.
|
||||
Default is /usr/local/etc/unbound/root.key.
|
||||
.TP
|
||||
.B \-c \fIfile
|
||||
The root update certificate file, that is read in. It can be updated too.
|
||||
Default is /usr/local/etc/unbound/icannbundle.pem.
|
||||
.TP
|
||||
.B \-h
|
||||
Show the version and commandline option help.
|
||||
.TP
|
||||
.B \-v
|
||||
More verbose. Prints output detailing what happens.
|
||||
.TP
|
||||
.B \-C \fIcfgfile
|
||||
Config file to read with debug settings.
|
||||
.SH "FILES"
|
||||
.TP
|
||||
.I /usr/local/etc/unbound/root.key
|
||||
The root anchor file, updated with 5011 tracking, and read and written to.
|
||||
.TP
|
||||
.I /usr/local/etc/unbound/icannbundle.pem
|
||||
The trusted self\-signed certificate that is used to verify the downloaded
|
||||
DNSSEC root trust anchor.
|
||||
.SH "SEE ALSO"
|
||||
\fIunbound.conf\fR(5),
|
||||
\fIunbound\fR(8).
|
||||
|
|
@ -260,14 +260,15 @@ if [ "$DOWIN" = "yes" ]; then
|
|||
$strip anchor-update.exe
|
||||
$strip unbound-control.exe
|
||||
$strip unbound-host.exe
|
||||
$strip unbound-anchor.exe
|
||||
$strip unbound-checkconf.exe
|
||||
$strip unbound-service-install.exe
|
||||
$strip unbound-service-remove.exe
|
||||
cd tmp.$$
|
||||
cp ../doc/example.conf example.conf
|
||||
cp ../unbound.exe ../unbound-host.exe ../unbound-control.exe ../unbound-checkconf.exe ../unbound-service-install.exe ../unbound-service-remove.exe ../LICENSE ../winrc/unbound-website.url ../winrc/service.conf ../winrc/README.txt .
|
||||
cp ../unbound.exe ../unbound-anchor.exe ../unbound-host.exe ../unbound-control.exe ../unbound-checkconf.exe ../unbound-service-install.exe ../unbound-service-remove.exe ../LICENSE ../winrc/unbound-website.url ../winrc/service.conf ../winrc/README.txt .
|
||||
# zipfile
|
||||
zip ../$file LICENSE README.txt unbound.exe unbound-host.exe unbound-control.exe unbound-checkconf.exe unbound-service-install.exe unbound-service-remove.exe example.conf service.conf unbound-website.url
|
||||
zip ../$file LICENSE README.txt unbound.exe unbound-anchor.exe unbound-host.exe unbound-control.exe unbound-checkconf.exe unbound-service-install.exe unbound-service-remove.exe example.conf service.conf unbound-website.url
|
||||
info "Testing $file"
|
||||
(cd .. ; zip -T $file )
|
||||
# installer
|
||||
|
|
@ -385,6 +386,7 @@ replace_all doc/unbound.8.in
|
|||
replace_all doc/unbound.conf.5.in
|
||||
replace_all doc/unbound-checkconf.8.in
|
||||
replace_all doc/unbound-control.8.in
|
||||
replace_all doc/unbound-anchor.8.in
|
||||
replace_all doc/unbound-host.1
|
||||
replace_all doc/libunbound.3.in
|
||||
|
||||
|
|
|
|||
520
smallapp/unbound-anchor.c
Normal file
520
smallapp/unbound-anchor.c
Normal file
|
|
@ -0,0 +1,520 @@
|
|||
/*
|
||||
* unbound-anchor.c - update the root anchor if necessary.
|
||||
*
|
||||
* Copyright (c) 2010, NLnet Labs. All rights reserved.
|
||||
*
|
||||
* This software is open source.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* This file checks to see that the current 5011 keys work to prime the
|
||||
* current root anchor. If not a certificate is used to update the anchor.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "libunbound/unbound.h"
|
||||
#include <ldns/rr.h>
|
||||
#include <expat.h>
|
||||
#ifndef HAVE_EXPAT_H
|
||||
#error "need libexpat to parse root-anchors.xml file."
|
||||
#endif
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
|
||||
/* TODO configure defines with prefix */
|
||||
/** root key file, 5011 tracked */
|
||||
#define ROOT_ANCHOR_FILE "/usr/local/etc/unbound/root.key"
|
||||
/** root update cert file */
|
||||
#define ROOT_CERT_FILE "/usr/local/etc/unbound/icannbundle.pem"
|
||||
/** name of server in URL to fetch HTTPS from */
|
||||
#define URLNAME "data.iana.org"
|
||||
/** path on HTTPS server to xml file */
|
||||
#define XMLNAME "/root-anchors/root-anchors.xml"
|
||||
/** path on HTTPS server to p7s file */
|
||||
#define P7SNAME "/root-anchors/root-anchors.p7s"
|
||||
/** path on HTTPS server to pem file */
|
||||
#define PEMNAME "/root-anchors/icannbundle.pem"
|
||||
|
||||
/** verbosity for this application */
|
||||
static int verb = 0;
|
||||
|
||||
/** Give unbound-anchor usage, and exit (1). */
|
||||
static void
|
||||
usage()
|
||||
{
|
||||
printf("Usage: unbound-anchor [opts]\n");
|
||||
printf(" Setup or update root anchor. "
|
||||
"Most options have defaults.\n");
|
||||
printf(" Run this program before you start the validator.\n");
|
||||
printf("\n");
|
||||
printf(" The anchor and cert are filled with default builtin\n");
|
||||
printf(" values if the file does not exist or is empty.\n");
|
||||
printf("\n");
|
||||
printf("-a file root key file, default %s\n", ROOT_ANCHOR_FILE);
|
||||
printf("-c file cert file, default %s\n", ROOT_CERT_FILE);
|
||||
/* TODO
|
||||
printf("-o file output key file, if enabled new key written"
|
||||
" there and exit code 4 for manual change\n");
|
||||
*/
|
||||
printf("-u name server in https url, default %s\n", URLNAME);
|
||||
printf("-x path pathname to xml, default %s\n", XMLNAME);
|
||||
printf("-s path pathname to p7s, default %s\n", P7SNAME);
|
||||
printf("-p path pathname to pem, default %s\n", PEMNAME);
|
||||
printf("-4 work using IPv4 only\n");
|
||||
printf("-6 work using IPv6 only\n");
|
||||
printf("-f resolv.conf use given resolv.conf to resolve -u name\n");
|
||||
printf("-r root.hints use given root.hints to resolve -u name\n"
|
||||
" builtin root hints are used by default\n");
|
||||
printf("-v more verbose\n");
|
||||
printf("-C conf debug, read config\n");
|
||||
printf("-F debug, force update with cert\n");
|
||||
printf("-h show this usage help\n");
|
||||
printf("Version %s\n", PACKAGE_VERSION);
|
||||
printf("BSD licensed, see LICENSE in source package for details.\n");
|
||||
printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/** perform actual certupdate work */
|
||||
static int
|
||||
do_certupdate(char* root_anchor_file, char* root_cert_file,
|
||||
char* urlname, char* xmlname, char* p7sname, char* pemname,
|
||||
char* res_conf, char* root_hints, char* debugconf,
|
||||
int ip4only, int ip6only, struct ub_result* dnskey)
|
||||
{
|
||||
/* read pem file or provide builtin */
|
||||
|
||||
/* lookup A, AAAA for the urlname (or parse urlname if IP address) */
|
||||
|
||||
/* fetch the necessary files over HTTPS */
|
||||
|
||||
/* update the pem file (optional) */
|
||||
|
||||
/* verify and update the root anchor */
|
||||
/* verify xml file */
|
||||
/* see if xml file verifies the dnskey that was probed */
|
||||
/* reinstate 5011 tracking */
|
||||
if(verb) printf("success: the anchor has been updated "
|
||||
"using the cert\n");
|
||||
ub_resolve_free(dnskey);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to read the root RFC5011 autotrust anchor file,
|
||||
* @param file: filename.
|
||||
* @return:
|
||||
* 0 if does not exist or empty
|
||||
* 1 if trust-point-revoked-5011
|
||||
* 2 if it is OK.
|
||||
*/
|
||||
static int
|
||||
try_read_anchor(char* file)
|
||||
{
|
||||
int empty = 1;
|
||||
char line[10240];
|
||||
char* p;
|
||||
FILE* in = fopen(file, "r");
|
||||
if(!in) {
|
||||
/* only if the file does not exist, can we fix it */
|
||||
if(errno != ENOENT) {
|
||||
if(verb) printf("%s: %s\n", file, strerror(errno));
|
||||
if(verb) printf("error: cannot access the file\n");
|
||||
exit(0);
|
||||
}
|
||||
if(verb) printf("%s does not exist\n", file);
|
||||
return 0;
|
||||
}
|
||||
while(fgets(line, (int)sizeof(line), in)) {
|
||||
line[sizeof(line)-1] = 0;
|
||||
if(strncmp(line, ";;REVOKED", 9) == 0) {
|
||||
fclose(in);
|
||||
if(verb) printf("%s : the trust point is revoked\n"
|
||||
"and the zone is considered unsigned.\n"
|
||||
"if you wish to re-enable, delete the file\n",
|
||||
file);
|
||||
return 1;
|
||||
}
|
||||
p=line;
|
||||
while(*p == ' ' || *p == '\t')
|
||||
p++;
|
||||
if(p[0]==0 || p[0]=='\n' || p[0]==';') continue;
|
||||
/* this line is a line of content */
|
||||
empty = 0;
|
||||
}
|
||||
fclose(in);
|
||||
if(empty) {
|
||||
if(verb) printf("%s is empty\n", file);
|
||||
return 0;
|
||||
}
|
||||
if(verb) printf("%s has content\n", file);
|
||||
return 2;
|
||||
}
|
||||
|
||||
/** Write the builtin root anchor to a file */
|
||||
static void
|
||||
write_builtin_anchor(char* file)
|
||||
{
|
||||
const char* builtin_root_anchor = ". IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5\n";
|
||||
FILE* out = fopen(file, "w");
|
||||
if(!out) {
|
||||
if(verb) printf("%s: %s\n", file, strerror(errno));
|
||||
if(verb) printf(" could not write builtin anchor\n");
|
||||
return;
|
||||
}
|
||||
if(!fwrite(builtin_root_anchor, strlen(builtin_root_anchor), 1, out)) {
|
||||
if(verb) printf("%s: %s\n", file, strerror(errno));
|
||||
if(verb) printf(" could not complete write builtin anchor\n");
|
||||
}
|
||||
fclose(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the root anchor file.
|
||||
* If does not exist, provide builtin and write file.
|
||||
* If empty, provide builtin and write file.
|
||||
* If trust-point-revoked-5011 file: make the program exit.
|
||||
*/
|
||||
static int
|
||||
provide_builtin(char* root_anchor_file)
|
||||
{
|
||||
/* try to read it */
|
||||
switch(try_read_anchor(root_anchor_file))
|
||||
{
|
||||
case 0: /* no exist or empty */
|
||||
write_builtin_anchor(root_anchor_file);
|
||||
break;
|
||||
case 1: /* revoked tp */
|
||||
return 0;
|
||||
case 2: /* it is fine */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** print ub context creation error and exit */
|
||||
static void
|
||||
ub_ctx_error_exit(struct ub_ctx* ctx, const char* str, const char* str2)
|
||||
{
|
||||
ub_ctx_delete(ctx);
|
||||
if(str && str2 && verb) printf("%s: %s\n", str, str2);
|
||||
if(verb) printf("error: could not create unbound resolver context\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new unbound context with the commandline settings applied
|
||||
*/
|
||||
static struct ub_ctx*
|
||||
create_unbound_context(char* res_conf, char* root_hints, char* debugconf,
|
||||
int ip4only, int ip6only)
|
||||
{
|
||||
int r;
|
||||
struct ub_ctx* ctx = ub_ctx_create();
|
||||
if(!ctx) {
|
||||
if(verb) printf("out of memory\n");
|
||||
exit(0);
|
||||
}
|
||||
/* do not waste time and network traffic to fetch extra nameservers */
|
||||
r = ub_ctx_set_option(ctx, "target-fetch-policy:", "0 0 0 0 0");
|
||||
if(r && verb) printf("ctx targetfetchpolicy: %s\n", ub_strerror(r));
|
||||
/* read config file first, so its settings can be overridden */
|
||||
if(debugconf) {
|
||||
r = ub_ctx_config(ctx, debugconf);
|
||||
if(r) ub_ctx_error_exit(ctx, debugconf, ub_strerror(r));
|
||||
}
|
||||
if(res_conf) {
|
||||
r = ub_ctx_resolvconf(ctx, res_conf);
|
||||
if(r) ub_ctx_error_exit(ctx, res_conf, ub_strerror(r));
|
||||
}
|
||||
if(root_hints) {
|
||||
r = ub_ctx_set_option(ctx, "root-hints:", root_hints);
|
||||
if(r) ub_ctx_error_exit(ctx, root_hints, ub_strerror(r));
|
||||
}
|
||||
if(ip4only) {
|
||||
r = ub_ctx_set_option(ctx, "do-ip6:", "no");
|
||||
if(r) ub_ctx_error_exit(ctx, "ip4only", ub_strerror(r));
|
||||
}
|
||||
if(ip6only) {
|
||||
r = ub_ctx_set_option(ctx, "do-ip4:", "no");
|
||||
if(r) ub_ctx_error_exit(ctx, "ip6only", ub_strerror(r));
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
* add an autotrust anchor for the root to the context
|
||||
*/
|
||||
static void
|
||||
add_5011_probe_root(struct ub_ctx* ctx, char* root_anchor_file)
|
||||
{
|
||||
int r;
|
||||
r = ub_ctx_set_option(ctx, "auto-trust-anchor-file:", root_anchor_file);
|
||||
if(r) {
|
||||
if(verb) printf("add 5011 probe to ctx: %s\n", ub_strerror(r));
|
||||
ub_ctx_delete(ctx);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prime the root key and return the result. Exit on error.
|
||||
*/
|
||||
static struct ub_result*
|
||||
prime_root_key(struct ub_ctx* ctx)
|
||||
{
|
||||
struct ub_result* res = NULL;
|
||||
int r;
|
||||
r = ub_resolve(ctx, ".", LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN, &res);
|
||||
if(r) {
|
||||
if(verb) printf("resolve DNSKEY: %s\n", ub_strerror(r));
|
||||
ub_ctx_delete(ctx);
|
||||
exit(0);
|
||||
}
|
||||
if(!res) {
|
||||
if(verb) printf("out of memory\n");
|
||||
ub_ctx_delete(ctx);
|
||||
exit(0);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/** read last successful probe time from autotrust file (if possible) */
|
||||
static int32_t
|
||||
read_last_success_time(char* file)
|
||||
{
|
||||
FILE* in = fopen(file, "r");
|
||||
char line[1024];
|
||||
if(!in) {
|
||||
if(verb) printf("%s: %s\n", file, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
while(fgets(line, (int)sizeof(line), in)) {
|
||||
if(strncmp(line, ";;last_success: ", 16) == 0) {
|
||||
char* e;
|
||||
time_t x = (unsigned int)strtol(line+16, &e, 10);
|
||||
fclose(in);
|
||||
if(line+16 == e) {
|
||||
if(verb) printf("failed to parse "
|
||||
"last_success probe time\n");
|
||||
return 0;
|
||||
}
|
||||
if(verb) printf("last successful probe: %s", ctime(&x));
|
||||
return (int32_t)x;
|
||||
}
|
||||
}
|
||||
fclose(in);
|
||||
if(verb) printf("no last_success probe time in anchor file\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current time.
|
||||
* @param debugconf: with override time for tests
|
||||
*/
|
||||
static int32_t
|
||||
get_time_now(char* debugconf)
|
||||
{
|
||||
if(debugconf) {
|
||||
FILE* in = fopen(debugconf, "r");
|
||||
char line[1024];
|
||||
if(!in) {
|
||||
if(verb) printf("%s: %s\n", debugconf, strerror(errno));
|
||||
return (int32_t)time(NULL);
|
||||
}
|
||||
/* must be ^val-override-date: 1234567$ formatted */
|
||||
while(fgets(line, (int)sizeof(line), in)) {
|
||||
if(strncmp(line, "val-override-date: ", 19) == 0) {
|
||||
fclose(in);
|
||||
return (int32_t)atoi(line+19);
|
||||
}
|
||||
}
|
||||
fclose(in);
|
||||
}
|
||||
return (int32_t)time(NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read autotrust 5011 probe file and see if the date
|
||||
* compared to the current date allows a certupdate.
|
||||
* If the last successful probe was recent then 5011 cannot be behind,
|
||||
* and the failure cannot be solved with a certupdate.
|
||||
* The debugconf is to validation-override the date for testing.
|
||||
* @return true if certupdate is ok.
|
||||
*/
|
||||
static int
|
||||
probe_date_allows_certupdate(char* root_anchor_file, char* debugconf)
|
||||
{
|
||||
int32_t last_success = read_last_success_time(root_anchor_file);
|
||||
int32_t now = get_time_now(debugconf);
|
||||
int32_t leeway = 30 * 24 * 3600; /* 30 days leeway */
|
||||
/* if the date is before 2010-07-15:00.00.00 then the root has not
|
||||
* been signed yet, and thus we refuse to take action. */
|
||||
if(now - 1279144800 < 0) {
|
||||
if(verb) printf("the date is before the root was first signed,"
|
||||
" please correct the clock\n");
|
||||
return 0;
|
||||
}
|
||||
if(now - last_success < 0) {
|
||||
if(verb) printf("the last successful probe is in the future,"
|
||||
" clock was modified\n");
|
||||
return 0;
|
||||
}
|
||||
if(now - last_success >= leeway) {
|
||||
if(verb) printf("the last successful probe was more than 30 "
|
||||
"days ago\n");
|
||||
return 1;
|
||||
}
|
||||
if(verb) printf("the last successful probe is recent\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** perform the unbound-anchor work */
|
||||
static int
|
||||
do_root_update_work(char* root_anchor_file, char* root_cert_file,
|
||||
char* urlname, char* xmlname, char* p7sname, char* pemname,
|
||||
char* res_conf, char* root_hints, char* debugconf,
|
||||
int ip4only, int ip6only, int force)
|
||||
{
|
||||
struct ub_ctx* ctx;
|
||||
struct ub_result* dnskey;
|
||||
|
||||
/* see if builtin rootanchor needs to be provided, or if
|
||||
* rootanchor is 'revoked-trust-point' */
|
||||
if(!provide_builtin(root_anchor_file))
|
||||
return 0;
|
||||
|
||||
/* make unbound context with 5011-probe for root anchor,
|
||||
* and probe . DNSKEY */
|
||||
ctx = create_unbound_context(res_conf, root_hints, debugconf,
|
||||
ip4only, ip6only);
|
||||
add_5011_probe_root(ctx, root_anchor_file);
|
||||
dnskey = prime_root_key(ctx);
|
||||
ub_ctx_delete(ctx);
|
||||
|
||||
/* if secure: exit */
|
||||
if(dnskey->secure && !force) {
|
||||
if(verb) printf("success: the anchor is ok\n");
|
||||
ub_resolve_free(dnskey);
|
||||
return 0;
|
||||
}
|
||||
if(force && verb) printf("debug cert update forced\n");
|
||||
|
||||
/* if not (and NOERROR): check date and do certupdate */
|
||||
if((dnskey->rcode == 0 && probe_date_allows_certupdate(root_anchor_file,
|
||||
debugconf)) || force)
|
||||
return do_certupdate(root_anchor_file, root_cert_file,
|
||||
urlname, xmlname, p7sname, pemname,
|
||||
res_conf, root_hints, debugconf, ip4only, ip6only,
|
||||
dnskey);
|
||||
if(verb) printf("fail: the anchor is NOT ok and could not be fixed\n");
|
||||
ub_resolve_free(dnskey);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** getopt global, in case header files fail to declare it. */
|
||||
extern int optind;
|
||||
/** getopt global, in case header files fail to declare it. */
|
||||
extern char* optarg;
|
||||
|
||||
/** Main routine for checkconf */
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int c;
|
||||
char* root_anchor_file = ROOT_ANCHOR_FILE;
|
||||
char* root_cert_file = ROOT_CERT_FILE;
|
||||
char* urlname = URLNAME;
|
||||
char* xmlname = XMLNAME;
|
||||
char* p7sname = P7SNAME;
|
||||
char* pemname = PEMNAME;
|
||||
char* res_conf = NULL;
|
||||
char* root_hints = NULL;
|
||||
char* debugconf = NULL;
|
||||
int ip4only=0, ip6only=0, force=0;
|
||||
/* parse the options */
|
||||
while( (c=getopt(argc, argv, "46C:Fa:c:f:hp:r:s:u:vx:")) != -1) {
|
||||
switch(c) {
|
||||
case '4':
|
||||
ip4only = 1;
|
||||
break;
|
||||
case '6':
|
||||
ip6only = 1;
|
||||
break;
|
||||
case 'a':
|
||||
root_anchor_file = optarg;
|
||||
break;
|
||||
case 'c':
|
||||
root_cert_file = optarg;
|
||||
break;
|
||||
case 'u':
|
||||
urlname = optarg;
|
||||
break;
|
||||
case 'x':
|
||||
xmlname = optarg;
|
||||
break;
|
||||
case 's':
|
||||
p7sname = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
pemname = optarg;
|
||||
break;
|
||||
case 'f':
|
||||
res_conf = optarg;
|
||||
break;
|
||||
case 'r':
|
||||
root_hints = optarg;
|
||||
break;
|
||||
case 'C':
|
||||
debugconf = optarg;
|
||||
break;
|
||||
case 'F':
|
||||
force = 1;
|
||||
break;
|
||||
case 'v':
|
||||
verb++;
|
||||
break;
|
||||
case '?':
|
||||
case 'h':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
if(argc != 0)
|
||||
usage();
|
||||
return do_root_update_work(root_anchor_file, root_cert_file,
|
||||
urlname, xmlname, p7sname, pemname,
|
||||
res_conf, root_hints, debugconf, ip4only, ip6only, force);
|
||||
}
|
||||
37
winrc/rsrc_unbound_anchor.rc
Normal file
37
winrc/rsrc_unbound_anchor.rc
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
Unbound resource file for windows. For use with windres
|
||||
*/
|
||||
#include "winver.h"
|
||||
#include "config.h"
|
||||
|
||||
1 ICON "winrc/combined.ico"
|
||||
|
||||
1 VERSIONINFO
|
||||
FILEVERSION RSRC_PACKAGE_VERSION
|
||||
PRODUCTVERSION RSRC_PACKAGE_VERSION
|
||||
FILEFLAGSMASK 0
|
||||
FILEFLAGS 0
|
||||
FILEOS VOS__WINDOWS32
|
||||
FILETYPE VFT_APP
|
||||
FILESUBTYPE 0
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904E4"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "NLnet Labs"
|
||||
VALUE "FileDescription", "Unbound Anchor Utility"
|
||||
VALUE "FileVersion", PACKAGE_VERSION
|
||||
VALUE "InternalName", "unbound-anchor"
|
||||
VALUE "OriginalFilename", "unbound-anchor.exe"
|
||||
VALUE "ProductName", "unbound"
|
||||
VALUE "ProductVersion", PACKAGE_VERSION
|
||||
VALUE "LegalCopyright", "(C) 2010 NLnet Labs. Source is BSD licensed."
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
/* English(409), windows ANSI codepage (1252) */
|
||||
VALUE "Translation", 0x409, 0x1252
|
||||
END
|
||||
END
|
||||
Loading…
Reference in a new issue