]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
unbound-anchor work
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 23 Sep 2010 15:28:08 +0000 (15:28 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 23 Sep 2010 15:28:08 +0000 (15:28 +0000)
git-svn-id: file:///svn/unbound/trunk@2243 be551aaa-1e26-0410-a405-d3ace91eadb9

configure
configure.ac
smallapp/unbound-anchor.c

index b10d2d07535a11bf57606d7861e6287550c8634b..06b766351ed8cf0e2db940c024861b45f95832c9 100755 (executable)
--- a/configure
+++ b/configure
@@ -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.
index dd3c4d9d1942ce29e9d56f42f526014a474a6496..eedc2f5d61628e896d2e7c5991a5f56ea508907c 100644 (file)
@@ -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=""
index 48d01dff8fb994ff46e808edfd3d2d7024db8197..431e1a3979266c7c94973c8e70458f7d29743fc1 100644 (file)
@@ -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 */
 /** 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
  */