mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-01-05 14:29:37 -05:00
unbound-anchor work
git-svn-id: file:///svn/unbound/trunk@2243 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
1c2a8d977c
commit
8ef0b0ff30
3 changed files with 299 additions and 53 deletions
38
configure
vendored
38
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 expat.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
|
||||
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
|
||||
|
|
@ -15601,7 +15601,41 @@ $as_echo "#define USE_MINI_EVENT 1" >>confdefs.h
|
|||
|
||||
fi
|
||||
|
||||
# set static linking if requested
|
||||
# check for libexpat
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libexpat" >&5
|
||||
$as_echo_n "checking for libexpat... " >&6; }
|
||||
found_libexpat="no"
|
||||
for dir in /usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr; do
|
||||
echo if test -f "$dir/include/expat.h"
|
||||
if test -f "$dir/include/expat.h"; then
|
||||
found_libexpat="yes"
|
||||
if test "$dir" != "/usr"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$dir/include"
|
||||
LDFLAGS="$LDFLAGS -L$dir/lib"
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found in $dir" >&5
|
||||
$as_echo "found in $dir" >&6; }
|
||||
break;
|
||||
fi
|
||||
done
|
||||
if test x_$found_libexpat != x_yes; then
|
||||
as_fn_error "Could not find libexpat, expat.h" "$LINENO" 5
|
||||
fi
|
||||
for ac_header in expat.h
|
||||
do :
|
||||
ac_fn_c_check_header_compile "$LINENO" "expat.h" "ac_cv_header_expat_h" "$ac_includes_default
|
||||
"
|
||||
if test "x$ac_cv_header_expat_h" = x""yes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_EXPAT_H 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
|
||||
# set static linking if requestd
|
||||
|
||||
staticexe=""
|
||||
# Check whether --enable-staticexe was given.
|
||||
|
|
|
|||
22
configure.ac
22
configure.ac
|
|
@ -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 expat.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],,, [AC_INCLUDES_DEFAULT])
|
||||
|
||||
# check for types.
|
||||
# Using own tests for int64* because autoconf builtin only give 32bit.
|
||||
|
|
@ -528,6 +528,26 @@ else
|
|||
AC_DEFINE(USE_MINI_EVENT, 1, [Define if you want to use internal select based events])
|
||||
fi
|
||||
|
||||
# check for libexpat
|
||||
AC_MSG_CHECKING(for libexpat)
|
||||
found_libexpat="no"
|
||||
for dir in /usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr; do
|
||||
if test -f "$dir/include/expat.h"; then
|
||||
found_libexpat="yes"
|
||||
dnl assume /usr is in default path.
|
||||
if test "$dir" != "/usr"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$dir/include"
|
||||
LDFLAGS="$LDFLAGS -L$dir/lib"
|
||||
fi
|
||||
AC_MSG_RESULT(found in $dir)
|
||||
break;
|
||||
fi
|
||||
done
|
||||
if test x_$found_libexpat != x_yes; then
|
||||
AC_ERROR([Could not find libexpat, expat.h])
|
||||
fi
|
||||
AC_CHECK_HEADERS([expat.h],,, [AC_INCLUDES_DEFAULT])
|
||||
|
||||
# set static linking if requested
|
||||
AC_SUBST(staticexe)
|
||||
staticexe=""
|
||||
|
|
|
|||
|
|
@ -50,6 +50,8 @@
|
|||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/pem.h>
|
||||
|
||||
/* TODO configure defines with prefix */
|
||||
/** root key file, 5011 tracked */
|
||||
|
|
@ -68,6 +70,16 @@
|
|||
/** verbosity for this application */
|
||||
static int verb = 0;
|
||||
|
||||
/** list of IP addresses */
|
||||
struct ip_list {
|
||||
/** next in list */
|
||||
struct ip_list* next;
|
||||
/** length of addr */
|
||||
socklen_t len;
|
||||
/** address ready to connect to */
|
||||
struct sockaddr_storage addr;
|
||||
};
|
||||
|
||||
/** Give unbound-anchor usage, and exit (1). */
|
||||
static void
|
||||
usage()
|
||||
|
|
@ -105,6 +117,222 @@ usage()
|
|||
exit(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;
|
||||
}
|
||||
|
||||
/** read certificates from a PEM bio */
|
||||
static STACK_OF(X509)*
|
||||
read_cert_bio(BIO* bio)
|
||||
{
|
||||
STACK_OF(X509) *sk = sk_X509_new_null();
|
||||
if(!sk) {
|
||||
if(verb) printf("out of memory\n");
|
||||
exit(0);
|
||||
}
|
||||
while(!BIO_eof(bio)) {
|
||||
X509* x = PEM_read_bio_X509(bio, NULL, 0, NULL);
|
||||
if(x == NULL) {
|
||||
if(verb) printf("failed to read X509\n");
|
||||
continue;
|
||||
}
|
||||
if(!sk_X509_push(sk, x)) {
|
||||
if(verb) printf("out of memory\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
return sk;
|
||||
}
|
||||
|
||||
/* read the certificate file */
|
||||
static STACK_OF(X509)*
|
||||
read_cert_file(char* file)
|
||||
{
|
||||
STACK_OF(X509)* sk = sk_X509_new_null();
|
||||
FILE* in;
|
||||
int content = 0;
|
||||
if(!sk) {
|
||||
if(verb) printf("out of memory\n");
|
||||
exit(0);
|
||||
}
|
||||
in = fopen(file, "r");
|
||||
if(!in) {
|
||||
if(verb) printf("%s: %s\n", file, strerror(errno));
|
||||
sk_X509_free(sk);
|
||||
return NULL;
|
||||
}
|
||||
while(!feof(in)) {
|
||||
X509* x = PEM_read_X509(in, NULL, 0, NULL);
|
||||
if(x == NULL) {
|
||||
if(verb) printf("failed to read X509\n");
|
||||
continue;
|
||||
}
|
||||
if(!sk_X509_push(sk, x)) {
|
||||
if(verb) printf("out of memory\n");
|
||||
fclose(in);
|
||||
exit(0);
|
||||
}
|
||||
content = 1;
|
||||
}
|
||||
fclose(in);
|
||||
if(!content) {
|
||||
if(verb) printf("%s is empty\n", file);
|
||||
sk_X509_free(sk);
|
||||
return NULL;
|
||||
}
|
||||
return sk;
|
||||
}
|
||||
|
||||
/** read certificates from the builtin certificate */
|
||||
static STACK_OF(X509)*
|
||||
read_builtin_cert(void)
|
||||
{
|
||||
const char* builtin_cert =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIDdzCCAl+gAwIBAgIBATANBgkqhkiG9w0BAQsFADBdMQ4wDAYDVQQKEwVJQ0FO\n"
|
||||
"TjEmMCQGA1UECxMdSUNBTk4gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxFjAUBgNV\n"
|
||||
"BAMTDUlDQU5OIFJvb3QgQ0ExCzAJBgNVBAYTAlVTMB4XDTA5MTIyMzA0MTkxMloX\n"
|
||||
"DTI5MTIxODA0MTkxMlowXTEOMAwGA1UEChMFSUNBTk4xJjAkBgNVBAsTHUlDQU5O\n"
|
||||
"IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDEw1JQ0FOTiBSb290IENB\n"
|
||||
"MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKDb\n"
|
||||
"cLhPNNqc1NB+u+oVvOnJESofYS9qub0/PXagmgr37pNublVThIzyLPGCJ8gPms9S\n"
|
||||
"G1TaKNIsMI7d+5IgMy3WyPEOECGIcfqEIktdR1YWfJufXcMReZwU4v/AdKzdOdfg\n"
|
||||
"ONiwc6r70duEr1IiqPbVm5T05l1e6D+HkAvHGnf1LtOPGs4CHQdpIUcy2kauAEy2\n"
|
||||
"paKcOcHASvbTHK7TbbvHGPB+7faAztABLoneErruEcumetcNfPMIjXKdv1V1E3C7\n"
|
||||
"MSJKy+jAqqQJqjZoQGB0necZgUMiUv7JK1IPQRM2CXJllcyJrm9WFxY0c1KjBO29\n"
|
||||
"iIKK69fcglKcBuFShUECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B\n"
|
||||
"Af8EBAMCAf4wHQYDVR0OBBYEFLpS6UmDJIZSL8eZzfyNa2kITcBQMA0GCSqGSIb3\n"
|
||||
"DQEBCwUAA4IBAQAP8emCogqHny2UYFqywEuhLys7R9UKmYY4suzGO4nkbgfPFMfH\n"
|
||||
"6M+Zj6owwxlwueZt1j/IaCayoKU3QsrYYoDRolpILh+FPwx7wseUEV8ZKpWsoDoD\n"
|
||||
"2JFbLg2cfB8u/OlE4RYmcxxFSmXBg0yQ8/IoQt/bxOcEEhhiQ168H2yE5rxJMt9h\n"
|
||||
"15nu5JBSewrCkYqYYmaxyOC3WrVGfHZxVI7MpIFcGdvSb2a1uyuua8l0BKgk3ujF\n"
|
||||
"0/wsHNeP22qNyVO+XVBzrM8fk8BSUFuiT/6tZTYXRtEt5aKQZgXbKU5dUF3jT9qg\n"
|
||||
"j/Br5BZw3X/zd325TvnswzMC1+ljLzHnQGGk\n"
|
||||
"-----END CERTIFICATE-----\n"
|
||||
;
|
||||
STACK_OF(X509)* sk;
|
||||
BIO *bio = BIO_new_mem_buf((void*)builtin_cert, strlen(builtin_cert));
|
||||
if(!bio) {
|
||||
if(verb) printf("out of memory\n");
|
||||
exit(0);
|
||||
}
|
||||
sk = read_cert_bio(bio);
|
||||
if(!sk) {
|
||||
if(verb) printf("internal error, out of memory\n");
|
||||
exit(0);
|
||||
}
|
||||
BIO_free(bio);
|
||||
return sk;
|
||||
}
|
||||
|
||||
/** read update cert file or use builtin */
|
||||
static STACK_OF(X509)*
|
||||
read_cert_or_builtin(char* file, int* write_cert)
|
||||
{
|
||||
STACK_OF(X509) *sk = read_cert_file(file);
|
||||
if(!sk) {
|
||||
*write_cert = 1;
|
||||
if(verb) printf("using builtin certificate\n");
|
||||
sk = read_builtin_cert();
|
||||
}
|
||||
if(verb) printf("have %d trusted certificates\n", sk_X509_num(sk));
|
||||
return sk;
|
||||
}
|
||||
|
||||
/** Resolve name, type, class and add addresses to iplist */
|
||||
static void
|
||||
add_ip(struct ub_ctx* ctx, char* host, int tp, int cl, struct ip_list** head)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a domain name (even though the resolver is down and there is
|
||||
* no trust anchor). Without DNSSEC validation.
|
||||
*/
|
||||
static struct ip_list*
|
||||
resolve_name(char* host, char* res_conf, char* root_hints, char* debugconf,
|
||||
int ip4only, int ip6only)
|
||||
{
|
||||
struct ub_ctx* ctx;
|
||||
struct ip_list* list = NULL;
|
||||
/* first see if name is an IP address itself */
|
||||
/* TODO */
|
||||
|
||||
/* create resolver context */
|
||||
ctx = create_unbound_context(res_conf, root_hints, debugconf,
|
||||
ip4only, ip6only);
|
||||
|
||||
/* try resolution of A */
|
||||
if(!ip6only) {
|
||||
add_ip(ctx, host, LDNS_RR_TYPE_A, LDNS_RR_CLASS_IN, &list);
|
||||
}
|
||||
|
||||
/* try resolution of AAAA */
|
||||
if(!ip4only) {
|
||||
add_ip(ctx, host, LDNS_RR_TYPE_AAAA, LDNS_RR_CLASS_IN, &list);
|
||||
}
|
||||
|
||||
ub_ctx_delete(ctx);
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do a HTTPS, HTTP1.1 over TLS, to fetch a file
|
||||
* @param ip_list: list of IP addresses to use to fetch from.
|
||||
* @param pathname: pathname of file on server to GET.
|
||||
* @return a memory BIO with the file in it.
|
||||
*/
|
||||
static BIO*
|
||||
https(struct ip_list* ip_list, char* pathname)
|
||||
{
|
||||
}
|
||||
|
||||
/** perform actual certupdate work */
|
||||
static int
|
||||
do_certupdate(char* root_anchor_file, char* root_cert_file,
|
||||
|
|
@ -112,11 +340,21 @@ do_certupdate(char* root_anchor_file, char* root_cert_file,
|
|||
char* res_conf, char* root_hints, char* debugconf,
|
||||
int ip4only, int ip6only, struct ub_result* dnskey)
|
||||
{
|
||||
int write_cert = 0;
|
||||
STACK_OF(X509)* cert;
|
||||
BIO *pem, *xml, *p7s;
|
||||
struct ip_list* ip_list;
|
||||
/* read pem file or provide builtin */
|
||||
cert = read_cert_or_builtin(root_cert_file, &write_cert);
|
||||
|
||||
/* lookup A, AAAA for the urlname (or parse urlname if IP address) */
|
||||
ip_list = resolve_name(urlname, res_conf, root_hints, debugconf,
|
||||
ip4only, ip6only);
|
||||
|
||||
/* fetch the necessary files over HTTPS */
|
||||
xml = https(ip_list, xmlname);
|
||||
p7s = https(ip_list, p7sname);
|
||||
pem = https(ip_list, pemname);
|
||||
|
||||
/* update the pem file (optional) */
|
||||
|
||||
|
|
@ -126,6 +364,10 @@ do_certupdate(char* root_anchor_file, char* root_cert_file,
|
|||
/* reinstate 5011 tracking */
|
||||
if(verb) printf("success: the anchor has been updated "
|
||||
"using the cert\n");
|
||||
BIO_free(xml);
|
||||
BIO_free(p7s);
|
||||
BIO_free(pem);
|
||||
sk_X509_free(cert);
|
||||
ub_resolve_free(dnskey);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -223,56 +465,6 @@ provide_builtin(char* root_anchor_file)
|
|||
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
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in a new issue