]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/unbound/smallapp/unbound-anchor.c
Minimal subset of the unbound sources.
[FreeBSD/FreeBSD.git] / contrib / unbound / smallapp / unbound-anchor.c
1 /*
2  * unbound-anchor.c - update the root anchor if necessary.
3  *
4  * Copyright (c) 2010, NLnet Labs. All rights reserved.
5  *
6  * This software is open source.
7  * 
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 
12  * Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  * 
15  * Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  * 
19  * Neither the name of the NLNET LABS nor the names of its contributors may
20  * be used to endorse or promote products derived from this software without
21  * specific prior written permission.
22  * 
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
27  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35
36 /**
37  * \file
38  *
39  * This file checks to see that the current 5011 keys work to prime the
40  * current root anchor.  If not a certificate is used to update the anchor.
41  *
42  * This is a concept solution for distribution of the DNSSEC root
43  * trust anchor.  It is a small tool, called "unbound-anchor", that
44  * runs before the main validator starts.  I.e. in the init script:
45  * unbound-anchor; unbound.  Thus it is meant to run at system boot time.
46  *
47  * Management-Abstract:
48  *    * first run: fill root.key file with hardcoded DS record.
49  *    * mostly: use RFC5011 tracking, quick . DNSKEY UDP query.
50  *    * failover: use builtin certificate, do https and update.
51  * Special considerations:
52  *    * 30-days RFC5011 timer saves a lot of https traffic.
53  *    * DNSKEY probe must be NOERROR, saves a lot of https traffic.
54  *    * fail if clock before sign date of the root, if cert expired.
55  *    * if the root goes back to unsigned, deals with it.
56  *
57  * It has hardcoded the root DS anchors and the ICANN CA root certificate.
58  * It allows with options to override those.  It also takes root-hints (it
59  * has to do a DNS resolve), and also has hardcoded defaults for those.
60  *
61  * Once it starts, just before the validator starts, it quickly checks if
62  * the root anchor file needs to be updated.  First it tries to use
63  * RFC5011-tracking of the root key.  If that fails (and for 30-days since
64  * last successful probe), then it attempts to update using the
65  * certificate.  So most of the time, the RFC5011 tracking will work fine,
66  * and within a couple milliseconds, the main daemon can start.  It will
67  * have only probed the . DNSKEY, not done expensive https transfers on the
68  * root infrastructure.
69  *
70  * If there is no root key in the root.key file, it bootstraps the
71  * RFC5011-tracking with its builtin DS anchors; if that fails it
72  * bootstraps the RFC5011-tracking using the certificate.  (again to avoid
73  * https, and it is also faster).
74  * 
75  * It uses the XML file by converting it to DS records and writing that to the
76  * key file.  Unbound can detect that the 'special comments' are gone, and
77  * the file contains a list of normal DNSKEY/DS records, and uses that to
78  * bootstrap 5011 (the KSK is made VALID).
79  *
80  * The certificate update is done by fetching root-anchors.xml and
81  * root-anchors.p7s via SSL.  The HTTPS certificate can be logged but is
82  * not validated (https for channel security; the security comes from the
83  * certificate).  The 'data.iana.org' domain name A and AAAA are resolved
84  * without DNSSEC.  It tries a random IP until the transfer succeeds.  It
85  * then checks the p7s signature.
86  *
87  * On any failure, it leaves the root key file untouched.  The main
88  * validator has to cope with it, it cannot fix things (So a failure does
89  * not go 'without DNSSEC', no downgrade).  If it used its builtin stuff or
90  * did the https, it exits with an exit code, so that this can trigger the
91  * init script to log the event and potentially alert the operator that can
92  * do a manual check.
93  *
94  * The date is also checked.  Before 2010-07-15 is a failure (root not
95  * signed yet; avoids attacks on system clock).  The
96  * last-successful-RFC5011-probe (if available) has to be more than 30 days
97  * in the past (otherwise, RFC5011 should have worked).  This keeps
98  * unneccesary https traffic down.  If the main certificate is expired, it
99  * fails.
100  *
101  * The dates on the keys in the xml are checked (uses the libexpat xml
102  * parser), only the valid ones are used to re-enstate RFC5011 tracking.
103  * If 0 keys are valid, the zone has gone to insecure (a special marker is
104  * written in the keyfile that tells the main validator daemon the zone is
105  * insecure).
106  *
107  * Only the root ICANN CA is shipped, not the intermediate ones.  The
108  * intermediate CAs are included in the p7s file that was downloaded.  (the
109  * root cert is valid to 2028 and the intermediate to 2014, today).
110  *
111  * Obviously, the tool also has options so the operator can provide a new
112  * keyfile, a new certificate and new URLs, and fresh root hints.  By
113  * default it logs nothing on failure and success; it 'just works'.
114  *
115  */
116
117 #include "config.h"
118 #include "libunbound/unbound.h"
119 #include <ldns/rr.h>
120 #include <expat.h>
121 #ifndef HAVE_EXPAT_H
122 #error "need libexpat to parse root-anchors.xml file."
123 #endif
124 #ifdef HAVE_GETOPT_H
125 #include <getopt.h>
126 #endif
127 #ifdef HAVE_OPENSSL_SSL_H
128 #include <openssl/ssl.h>
129 #endif
130 #ifdef HAVE_OPENSSL_ERR_H
131 #include <openssl/err.h>
132 #endif
133 #ifdef HAVE_OPENSSL_RAND_H
134 #include <openssl/rand.h>
135 #endif
136 #include <openssl/x509.h>
137 #include <openssl/pem.h>
138
139 /** name of server in URL to fetch HTTPS from */
140 #define URLNAME "data.iana.org"
141 /** path on HTTPS server to xml file */
142 #define XMLNAME "root-anchors/root-anchors.xml"
143 /** path on HTTPS server to p7s file */
144 #define P7SNAME "root-anchors/root-anchors.p7s"
145 /** port number for https access */
146 #define HTTPS_PORT 443
147
148 #ifdef USE_WINSOCK
149 /* sneakily reuse the the wsa_strerror function, on windows */
150 char* wsa_strerror(int err);
151 #endif
152
153 /** verbosity for this application */
154 static int verb = 0;
155
156 /** list of IP addresses */
157 struct ip_list {
158         /** next in list */
159         struct ip_list* next;
160         /** length of addr */
161         socklen_t len;
162         /** address ready to connect to */
163         struct sockaddr_storage addr;
164         /** has the address been used */
165         int used;
166 };
167
168 /** Give unbound-anchor usage, and exit (1). */
169 static void
170 usage()
171 {
172         printf("Usage:  unbound-anchor [opts]\n");
173         printf("        Setup or update root anchor. "
174                 "Most options have defaults.\n");
175         printf("        Run this program before you start the validator.\n");
176         printf("\n");
177         printf("        The anchor and cert have default builtin content\n");
178         printf("        if the file does not exist or is empty.\n");
179         printf("\n");
180         printf("-a file         root key file, default %s\n", ROOT_ANCHOR_FILE);
181         printf("                The key is input and output for this tool.\n");
182         printf("-c file         cert file, default %s\n", ROOT_CERT_FILE);
183         printf("-l              list builtin key and cert on stdout\n");
184         printf("-u name         server in https url, default %s\n", URLNAME);
185         printf("-x path         pathname to xml in url, default %s\n", XMLNAME);
186         printf("-s path         pathname to p7s in url, default %s\n", P7SNAME);
187         printf("-4              work using IPv4 only\n");
188         printf("-6              work using IPv6 only\n");
189         printf("-f resolv.conf  use given resolv.conf to resolve -u name\n");
190         printf("-r root.hints   use given root.hints to resolve -u name\n"
191                 "               builtin root hints are used by default\n");
192         printf("-v              more verbose\n");
193         printf("-C conf         debug, read config\n");
194         printf("-P port         use port for https connect, default 443\n");
195         printf("-F              debug, force update with cert\n");
196         printf("-h              show this usage help\n");
197         printf("Version %s\n", PACKAGE_VERSION);
198         printf("BSD licensed, see LICENSE in source package for details.\n");
199         printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
200         exit(1);
201 }
202
203 /** return the built in root update certificate */
204 static const char*
205 get_builtin_cert(void)
206 {
207         return
208 /* The ICANN CA fetched at 24 Sep 2010.  Valid to 2028 */
209 "-----BEGIN CERTIFICATE-----\n"
210 "MIIDdzCCAl+gAwIBAgIBATANBgkqhkiG9w0BAQsFADBdMQ4wDAYDVQQKEwVJQ0FO\n"
211 "TjEmMCQGA1UECxMdSUNBTk4gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxFjAUBgNV\n"
212 "BAMTDUlDQU5OIFJvb3QgQ0ExCzAJBgNVBAYTAlVTMB4XDTA5MTIyMzA0MTkxMloX\n"
213 "DTI5MTIxODA0MTkxMlowXTEOMAwGA1UEChMFSUNBTk4xJjAkBgNVBAsTHUlDQU5O\n"
214 "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDEw1JQ0FOTiBSb290IENB\n"
215 "MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKDb\n"
216 "cLhPNNqc1NB+u+oVvOnJESofYS9qub0/PXagmgr37pNublVThIzyLPGCJ8gPms9S\n"
217 "G1TaKNIsMI7d+5IgMy3WyPEOECGIcfqEIktdR1YWfJufXcMReZwU4v/AdKzdOdfg\n"
218 "ONiwc6r70duEr1IiqPbVm5T05l1e6D+HkAvHGnf1LtOPGs4CHQdpIUcy2kauAEy2\n"
219 "paKcOcHASvbTHK7TbbvHGPB+7faAztABLoneErruEcumetcNfPMIjXKdv1V1E3C7\n"
220 "MSJKy+jAqqQJqjZoQGB0necZgUMiUv7JK1IPQRM2CXJllcyJrm9WFxY0c1KjBO29\n"
221 "iIKK69fcglKcBuFShUECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B\n"
222 "Af8EBAMCAf4wHQYDVR0OBBYEFLpS6UmDJIZSL8eZzfyNa2kITcBQMA0GCSqGSIb3\n"
223 "DQEBCwUAA4IBAQAP8emCogqHny2UYFqywEuhLys7R9UKmYY4suzGO4nkbgfPFMfH\n"
224 "6M+Zj6owwxlwueZt1j/IaCayoKU3QsrYYoDRolpILh+FPwx7wseUEV8ZKpWsoDoD\n"
225 "2JFbLg2cfB8u/OlE4RYmcxxFSmXBg0yQ8/IoQt/bxOcEEhhiQ168H2yE5rxJMt9h\n"
226 "15nu5JBSewrCkYqYYmaxyOC3WrVGfHZxVI7MpIFcGdvSb2a1uyuua8l0BKgk3ujF\n"
227 "0/wsHNeP22qNyVO+XVBzrM8fk8BSUFuiT/6tZTYXRtEt5aKQZgXbKU5dUF3jT9qg\n"
228 "j/Br5BZw3X/zd325TvnswzMC1+ljLzHnQGGk\n"
229 "-----END CERTIFICATE-----\n"
230                 ;
231 }
232
233 /** return the built in root DS trust anchor */
234 static const char*
235 get_builtin_ds(void)
236 {
237         return
238 ". IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5\n";
239 }
240
241 /** print hex data */
242 static void
243 print_data(char* msg, char* data, int len)
244 {
245         int i;
246         printf("%s: ", msg);
247         for(i=0; i<len; i++) {
248                 printf(" %2.2x", (unsigned char)data[i]);
249         }
250         printf("\n");
251 }
252
253 /** print ub context creation error and exit */
254 static void
255 ub_ctx_error_exit(struct ub_ctx* ctx, const char* str, const char* str2)
256 {
257         ub_ctx_delete(ctx);
258         if(str && str2 && verb) printf("%s: %s\n", str, str2);
259         if(verb) printf("error: could not create unbound resolver context\n");
260         exit(0);
261 }
262
263 /**
264  * Create a new unbound context with the commandline settings applied
265  */
266 static struct ub_ctx* 
267 create_unbound_context(char* res_conf, char* root_hints, char* debugconf,
268         int ip4only, int ip6only)
269 {
270         int r;
271         struct ub_ctx* ctx = ub_ctx_create();
272         if(!ctx) {
273                 if(verb) printf("out of memory\n");
274                 exit(0);
275         }
276         /* do not waste time and network traffic to fetch extra nameservers */
277         r = ub_ctx_set_option(ctx, "target-fetch-policy:", "0 0 0 0 0");
278         if(r && verb) printf("ctx targetfetchpolicy: %s\n", ub_strerror(r));
279         /* read config file first, so its settings can be overridden */
280         if(debugconf) {
281                 r = ub_ctx_config(ctx, debugconf);
282                 if(r) ub_ctx_error_exit(ctx, debugconf, ub_strerror(r));
283         }
284         if(res_conf) {
285                 r = ub_ctx_resolvconf(ctx, res_conf);
286                 if(r) ub_ctx_error_exit(ctx, res_conf, ub_strerror(r));
287         }
288         if(root_hints) {
289                 r = ub_ctx_set_option(ctx, "root-hints:", root_hints);
290                 if(r) ub_ctx_error_exit(ctx, root_hints, ub_strerror(r));
291         }
292         if(ip4only) {
293                 r = ub_ctx_set_option(ctx, "do-ip6:", "no");
294                 if(r) ub_ctx_error_exit(ctx, "ip4only", ub_strerror(r));
295         }
296         if(ip6only) {
297                 r = ub_ctx_set_option(ctx, "do-ip4:", "no");
298                 if(r) ub_ctx_error_exit(ctx, "ip6only", ub_strerror(r));
299         }
300         return ctx;
301 }
302
303 /** printout certificate in detail */
304 static void
305 verb_cert(char* msg, X509* x)
306 {
307         if(verb == 0 || verb == 1) return;
308         if(verb == 2) {
309                 if(msg) printf("%s\n", msg);
310                 X509_print_ex_fp(stdout, x, 0, (unsigned long)-1
311                         ^(X509_FLAG_NO_SUBJECT
312                         |X509_FLAG_NO_ISSUER|X509_FLAG_NO_VALIDITY));
313                 return;
314         }
315         if(msg) printf("%s\n", msg);
316         X509_print_fp(stdout, x);
317 }
318
319 /** printout certificates in detail */
320 static void
321 verb_certs(char* msg, STACK_OF(X509)* sk)
322 {
323         int i, num = sk_X509_num(sk);
324         if(verb == 0 || verb == 1) return;
325         for(i=0; i<num; i++) {
326                 printf("%s (%d/%d)\n", msg, i, num);
327                 verb_cert(NULL, sk_X509_value(sk, i));
328         }
329 }
330
331 /** read certificates from a PEM bio */
332 static STACK_OF(X509)*
333 read_cert_bio(BIO* bio)
334 {
335         STACK_OF(X509) *sk = sk_X509_new_null();
336         if(!sk) {
337                 if(verb) printf("out of memory\n");
338                 exit(0);
339         }
340         while(!BIO_eof(bio)) {
341                 X509* x = PEM_read_bio_X509(bio, NULL, 0, NULL);
342                 if(x == NULL) {
343                         if(verb) {
344                                 printf("failed to read X509\n");
345                                 ERR_print_errors_fp(stdout);
346                         }
347                         continue;
348                 }
349                 if(!sk_X509_push(sk, x)) {
350                         if(verb) printf("out of memory\n");
351                         exit(0);
352                 }
353         }
354         return sk;
355 }
356
357 /* read the certificate file */
358 static STACK_OF(X509)*
359 read_cert_file(char* file)
360 {
361         STACK_OF(X509)* sk;
362         FILE* in;
363         int content = 0;
364         char buf[128];
365         if(file == NULL || strcmp(file, "") == 0) {
366                 return NULL;
367         }
368         sk = sk_X509_new_null();
369         if(!sk) {
370                 if(verb) printf("out of memory\n");
371                 exit(0);
372         }
373         in = fopen(file, "r");
374         if(!in) {
375                 if(verb) printf("%s: %s\n", file, strerror(errno));
376 #ifndef S_SPLINT_S
377                 sk_X509_pop_free(sk, X509_free);
378 #endif
379                 return NULL;
380         }
381         while(!feof(in)) {
382                 X509* x = PEM_read_X509(in, NULL, 0, NULL);
383                 if(x == NULL) {
384                         if(verb) {
385                                 printf("failed to read X509 file\n");
386                                 ERR_print_errors_fp(stdout);
387                         }
388                         continue;
389                 }
390                 if(!sk_X509_push(sk, x)) {
391                         if(verb) printf("out of memory\n");
392                         fclose(in);
393                         exit(0);
394                 }
395                 content = 1;
396                 /* read away newline after --END CERT-- */
397                 if(!fgets(buf, (int)sizeof(buf), in))
398                         break;
399         }
400         fclose(in);
401         if(!content) {
402                 if(verb) printf("%s is empty\n", file);
403 #ifndef S_SPLINT_S
404                 sk_X509_pop_free(sk, X509_free);
405 #endif
406                 return NULL;
407         }
408         return sk;
409 }
410
411 /** read certificates from the builtin certificate */
412 static STACK_OF(X509)*
413 read_builtin_cert(void)
414 {
415         const char* builtin_cert = get_builtin_cert();
416         STACK_OF(X509)* sk;
417         BIO *bio = BIO_new_mem_buf((void*)builtin_cert,
418                 (int)strlen(builtin_cert));
419         if(!bio) {
420                 if(verb) printf("out of memory\n");
421                 exit(0);
422         }
423         sk = read_cert_bio(bio);
424         if(!sk) {
425                 if(verb) printf("internal error, out of memory\n");
426                 exit(0);
427         }
428         BIO_free(bio);
429         return sk;
430 }
431
432 /** read update cert file or use builtin */
433 static STACK_OF(X509)*
434 read_cert_or_builtin(char* file)
435 {
436         STACK_OF(X509) *sk = read_cert_file(file);
437         if(!sk) {
438                 if(verb) printf("using builtin certificate\n");
439                 sk = read_builtin_cert();
440         }
441         if(verb) printf("have %d trusted certificates\n", sk_X509_num(sk));
442         verb_certs("trusted certificates", sk);
443         return sk;
444 }
445
446 static void
447 do_list_builtin(void)
448 {
449         const char* builtin_cert = get_builtin_cert();
450         const char* builtin_ds = get_builtin_ds();
451         printf("%s\n", builtin_ds);
452         printf("%s\n", builtin_cert);
453         exit(0);
454 }
455
456 /** printout IP address with message */
457 static void
458 verb_addr(char* msg, struct ip_list* ip)
459 {
460         if(verb) {
461                 char out[100];
462                 void* a = &((struct sockaddr_in*)&ip->addr)->sin_addr;
463                 if(ip->len != (socklen_t)sizeof(struct sockaddr_in))
464                         a = &((struct sockaddr_in6*)&ip->addr)->sin6_addr;
465
466                 if(inet_ntop((int)((struct sockaddr_in*)&ip->addr)->sin_family,
467                         a, out, (socklen_t)sizeof(out))==0)
468                         printf("%s (inet_ntop error)\n", msg);
469                 else printf("%s %s\n", msg, out);
470         }
471 }
472
473 /** free ip_list */
474 static void
475 ip_list_free(struct ip_list* p)
476 {
477         struct ip_list* np;
478         while(p) {
479                 np = p->next;
480                 free(p);
481                 p = np;
482         }
483 }
484
485 /** create ip_list entry for a RR record */
486 static struct ip_list*
487 RR_to_ip(int tp, char* data, int len, int port)
488 {
489         struct ip_list* ip = (struct ip_list*)calloc(1, sizeof(*ip));
490         uint16_t p = (uint16_t)port;
491         if(tp == LDNS_RR_TYPE_A) {
492                 struct sockaddr_in* sa = (struct sockaddr_in*)&ip->addr;
493                 ip->len = (socklen_t)sizeof(*sa);
494                 sa->sin_family = AF_INET;
495                 sa->sin_port = (in_port_t)htons(p);
496                 if(len != (int)sizeof(sa->sin_addr)) {
497                         if(verb) printf("skipped badly formatted A\n");
498                         free(ip);
499                         return NULL;
500                 }
501                 memmove(&sa->sin_addr, data, sizeof(sa->sin_addr));
502
503         } else if(tp == LDNS_RR_TYPE_AAAA) {
504                 struct sockaddr_in6* sa = (struct sockaddr_in6*)&ip->addr;
505                 ip->len = (socklen_t)sizeof(*sa);
506                 sa->sin6_family = AF_INET6;
507                 sa->sin6_port = (in_port_t)htons(p);
508                 if(len != (int)sizeof(sa->sin6_addr)) {
509                         if(verb) printf("skipped badly formatted AAAA\n");
510                         free(ip);
511                         return NULL;
512                 }
513                 memmove(&sa->sin6_addr, data, sizeof(sa->sin6_addr));
514         } else {
515                 if(verb) printf("internal error: bad type in RRtoip\n");
516                 free(ip);
517                 return NULL;
518         }
519         verb_addr("resolved server address", ip);
520         return ip;
521 }
522
523 /** Resolve name, type, class and add addresses to iplist */
524 static void
525 resolve_host_ip(struct ub_ctx* ctx, char* host, int port, int tp, int cl,
526         struct ip_list** head)
527 {
528         struct ub_result* res = NULL;
529         int r;
530         int i;
531
532         r = ub_resolve(ctx, host, tp, cl, &res);
533         if(r) {
534                 if(verb) printf("error: resolve %s %s: %s\n", host,
535                         (tp==LDNS_RR_TYPE_A)?"A":"AAAA", ub_strerror(r));
536                 return;
537         }
538         if(!res) {
539                 if(verb) printf("out of memory\n");
540                 ub_ctx_delete(ctx);
541                 exit(0);
542         }
543         for(i = 0; res->data[i]; i++) {
544                 struct ip_list* ip = RR_to_ip(tp, res->data[i], res->len[i],
545                         port);
546                 if(!ip) continue;
547                 ip->next = *head;
548                 *head = ip;
549         }
550         ub_resolve_free(res);
551 }
552
553 /** parse a text IP address into a sockaddr */
554 static struct ip_list*
555 parse_ip_addr(char* str, int port)
556 {
557         socklen_t len = 0;
558         struct sockaddr_storage* addr = NULL;
559         struct sockaddr_in6 a6;
560         struct sockaddr_in a;
561         struct ip_list* ip;
562         uint16_t p = (uint16_t)port;
563         memset(&a6, 0, sizeof(a6));
564         memset(&a, 0, sizeof(a));
565
566         if(inet_pton(AF_INET6, str, &a6.sin6_addr) > 0) {
567                 /* it is an IPv6 */
568                 a6.sin6_family = AF_INET6;
569                 a6.sin6_port = (in_port_t)htons(p);
570                 addr = (struct sockaddr_storage*)&a6;
571                 len = (socklen_t)sizeof(struct sockaddr_in6);
572         }
573         if(inet_pton(AF_INET, str, &a.sin_addr) > 0) {
574                 /* it is an IPv4 */
575                 a.sin_family = AF_INET;
576                 a.sin_port = (in_port_t)htons(p);
577                 addr = (struct sockaddr_storage*)&a;
578                 len = (socklen_t)sizeof(struct sockaddr_in);
579         }
580         if(!len) return NULL;
581         ip = (struct ip_list*)calloc(1, sizeof(*ip));
582         if(!ip) {
583                 if(verb) printf("out of memory\n");
584                 exit(0);
585         }
586         ip->len = len;
587         memmove(&ip->addr, addr, len);
588         if(verb) printf("server address is %s\n", str);
589         return ip;
590 }
591
592 /**
593  * Resolve a domain name (even though the resolver is down and there is
594  * no trust anchor).  Without DNSSEC validation.
595  * @param host: the name to resolve.
596  *      If this name is an IP4 or IP6 address this address is returned.
597  * @param port: the port number used for the returned IP structs.
598  * @param res_conf: resolv.conf (if any).
599  * @param root_hints: root hints (if any).
600  * @param debugconf: unbound.conf for debugging options.
601  * @param ip4only: use only ip4 for resolve and only lookup A
602  * @param ip6only: use only ip6 for resolve and only lookup AAAA
603  *      default is to lookup A and AAAA using ip4 and ip6.
604  * @return list of IP addresses.
605  */
606 static struct ip_list*
607 resolve_name(char* host, int port, char* res_conf, char* root_hints,
608         char* debugconf, int ip4only, int ip6only)
609 {
610         struct ub_ctx* ctx;
611         struct ip_list* list = NULL;
612         /* first see if name is an IP address itself */
613         if( (list=parse_ip_addr(host, port)) ) {
614                 return list;
615         }
616         
617         /* create resolver context */
618         ctx = create_unbound_context(res_conf, root_hints, debugconf,
619                 ip4only, ip6only);
620
621         /* try resolution of A */
622         if(!ip6only) {
623                 resolve_host_ip(ctx, host, port, LDNS_RR_TYPE_A,
624                         LDNS_RR_CLASS_IN, &list);
625         }
626
627         /* try resolution of AAAA */
628         if(!ip4only) {
629                 resolve_host_ip(ctx, host, port, LDNS_RR_TYPE_AAAA,
630                         LDNS_RR_CLASS_IN, &list);
631         }
632
633         ub_ctx_delete(ctx);
634         if(!list) {
635                 if(verb) printf("%s has no IP addresses I can use\n", host);
636                 exit(0);
637         }
638         return list;
639 }
640
641 /** clear used flags */
642 static void
643 wipe_ip_usage(struct ip_list* p)
644 {
645         while(p) {
646                 p->used = 0;
647                 p = p->next;
648         }
649 }
650
651 /** cound unused IPs */
652 static int
653 count_unused(struct ip_list* p)
654 {
655         int num = 0;
656         while(p) {
657                 if(!p->used) num++;
658                 p = p->next;
659         }
660         return num;
661 }
662
663 /** pick random unused element from IP list */
664 static struct ip_list*
665 pick_random_ip(struct ip_list* list)
666 {
667         struct ip_list* p = list;
668         int num = count_unused(list);
669         int sel;
670         if(num == 0) return NULL;
671         /* not perfect, but random enough */
672         sel = (int)ldns_get_random() % num;
673         /* skip over unused elements that we did not select */
674         while(sel > 0 && p) {
675                 if(!p->used) sel--;
676                 p = p->next;
677         }
678         /* find the next unused element */
679         while(p && p->used)
680                 p = p->next;
681         if(!p) return NULL; /* robustness */
682         return p;
683 }
684
685 /** close the fd */
686 static void
687 fd_close(int fd)
688 {
689 #ifndef USE_WINSOCK
690         close(fd);
691 #else
692         closesocket(fd);
693 #endif
694 }
695
696 /** printout socket errno */
697 static void
698 print_sock_err(const char* msg)
699 {
700 #ifndef USE_WINSOCK
701         if(verb) printf("%s: %s\n", msg, strerror(errno));
702 #else
703         if(verb) printf("%s: %s\n", msg, wsa_strerror(WSAGetLastError()));
704 #endif
705 }
706
707 /** connect to IP address */
708 static int
709 connect_to_ip(struct ip_list* ip)
710 {
711         int fd;
712         verb_addr("connect to", ip);
713         fd = socket(ip->len==(socklen_t)sizeof(struct sockaddr_in)?
714                 AF_INET:AF_INET6, SOCK_STREAM, 0);
715         if(fd == -1) {
716                 print_sock_err("socket");
717                 return -1;
718         }
719         if(connect(fd, (struct sockaddr*)&ip->addr, ip->len) < 0) {
720                 print_sock_err("connect");
721                 fd_close(fd);
722                 return -1;
723         }
724         return fd;
725 }
726
727 /** create SSL context */
728 static SSL_CTX*
729 setup_sslctx(void)
730 {
731         SSL_CTX* sslctx = SSL_CTX_new(SSLv23_client_method());
732         if(!sslctx) {
733                 if(verb) printf("SSL_CTX_new error\n");
734                 return NULL;
735         }
736         return sslctx;
737 }
738
739 /** initiate TLS on a connection */
740 static SSL*
741 TLS_initiate(SSL_CTX* sslctx, int fd)
742 {
743         X509* x;
744         int r;
745         SSL* ssl = SSL_new(sslctx);
746         if(!ssl) {
747                 if(verb) printf("SSL_new error\n");
748                 return NULL;
749         }
750         SSL_set_connect_state(ssl);
751         (void)SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
752         if(!SSL_set_fd(ssl, fd)) {
753                 if(verb) printf("SSL_set_fd error\n");
754                 SSL_free(ssl);
755                 return NULL;
756         }
757         while(1) {
758                 ERR_clear_error();
759                 if( (r=SSL_do_handshake(ssl)) == 1)
760                         break;
761                 r = SSL_get_error(ssl, r);
762                 if(r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE) {
763                         if(verb) printf("SSL handshake failed\n");
764                         SSL_free(ssl);
765                         return NULL;
766                 }
767                 /* wants to be called again */
768         }
769         x = SSL_get_peer_certificate(ssl);
770         if(!x) {
771                 if(verb) printf("Server presented no peer certificate\n");
772                 SSL_free(ssl);
773                 return NULL;
774         }
775         verb_cert("server SSL certificate", x);
776         X509_free(x);
777         return ssl;
778 }
779
780 /** perform neat TLS shutdown */
781 static void
782 TLS_shutdown(int fd, SSL* ssl, SSL_CTX* sslctx)
783 {
784         /* shutdown the SSL connection nicely */
785         if(SSL_shutdown(ssl) == 0) {
786                 SSL_shutdown(ssl);
787         }
788         SSL_free(ssl);
789         SSL_CTX_free(sslctx);
790         fd_close(fd);
791 }
792
793 /** write a line over SSL */
794 static int
795 write_ssl_line(SSL* ssl, char* str, char* sec)
796 {
797         char buf[1024];
798         size_t l;
799         if(sec) {
800                 snprintf(buf, sizeof(buf), str, sec);
801         } else {
802                 snprintf(buf, sizeof(buf), "%s", str);
803         }
804         l = strlen(buf);
805         if(l+2 >= sizeof(buf)) {
806                 if(verb) printf("line too long\n");
807                 return 0;
808         }
809         if(verb >= 2) printf("SSL_write: %s\n", buf);
810         buf[l] = '\r';
811         buf[l+1] = '\n';
812         buf[l+2] = 0;
813         /* add \r\n */
814         if(SSL_write(ssl, buf, (int)strlen(buf)) <= 0) {
815                 if(verb) printf("could not SSL_write %s", str);
816                 return 0;
817         }
818         return 1;
819 }
820
821 /** process header line, check rcode and keeping track of size */
822 static int
823 process_one_header(char* buf, size_t* clen, int* chunked)
824 {
825         if(verb>=2) printf("header: '%s'\n", buf);
826         if(strncasecmp(buf, "HTTP/1.1 ", 9) == 0) {
827                 /* check returncode */
828                 if(buf[9] != '2') {
829                         if(verb) printf("bad status %s\n", buf+9);
830                         return 0;
831                 }
832         } else if(strncasecmp(buf, "Content-Length: ", 16) == 0) {
833                 if(!*chunked)
834                         *clen = (size_t)atoi(buf+16);
835         } else if(strncasecmp(buf, "Transfer-Encoding: chunked", 19+7) == 0) {
836                 *clen = 0;
837                 *chunked = 1;
838         }
839         return 1;
840 }
841
842 /** 
843  * Read one line from SSL
844  * zero terminates.
845  * skips "\r\n" (but not copied to buf).
846  * @param ssl: the SSL connection to read from (blocking).
847  * @param buf: buffer to return line in.
848  * @param len: size of the buffer.
849  * @return 0 on error, 1 on success.
850  */
851 static int
852 read_ssl_line(SSL* ssl, char* buf, size_t len)
853 {
854         size_t n = 0;
855         int r;
856         int endnl = 0;
857         while(1) {
858                 if(n >= len) {
859                         if(verb) printf("line too long\n");
860                         return 0;
861                 }
862                 if((r = SSL_read(ssl, buf+n, 1)) <= 0) {
863                         if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) {
864                                 /* EOF */
865                                 break;
866                         }
867                         if(verb) printf("could not SSL_read\n");
868                         return 0;
869                 }
870                 if(endnl && buf[n] == '\n') {
871                         break;
872                 } else if(endnl) {
873                         /* bad data */
874                         if(verb) printf("error: stray linefeeds\n");
875                         return 0;
876                 } else if(buf[n] == '\r') {
877                         /* skip \r, and also \n on the wire */
878                         endnl = 1;
879                         continue;
880                 } else if(buf[n] == '\n') {
881                         /* skip the \n, we are done */
882                         break;
883                 } else n++;
884         }
885         buf[n] = 0;
886         return 1;
887 }
888
889 /** read http headers and process them */
890 static size_t
891 read_http_headers(SSL* ssl, size_t* clen)
892 {
893         char buf[1024];
894         int chunked = 0;
895         *clen = 0;
896         while(read_ssl_line(ssl, buf, sizeof(buf))) {
897                 if(buf[0] == 0)
898                         return 1;
899                 if(!process_one_header(buf, clen, &chunked))
900                         return 0;
901         }
902         return 0;
903 }
904
905 /** read a data chunk */
906 static char*
907 read_data_chunk(SSL* ssl, size_t len)
908 {
909         size_t got = 0;
910         int r;
911         char* data = malloc(len+1);
912         if(!data) {
913                 if(verb) printf("out of memory\n");
914                 return NULL;
915         }
916         while(got < len) {
917                 if((r = SSL_read(ssl, data+got, (int)(len-got))) <= 0) {
918                         if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) {
919                                 /* EOF */
920                                 if(verb) printf("could not SSL_read: unexpected EOF\n");
921                                 free(data);
922                                 return NULL;
923                         }
924                         if(verb) printf("could not SSL_read\n");
925                         free(data);
926                         return NULL;
927                 }
928                 if(verb >= 2) printf("at %d/%d\n", (int)got, (int)len);
929                 got += r;
930         }
931         if(verb>=2) printf("read %d data\n", (int)len);
932         data[len] = 0;
933         return data;
934 }
935
936 /** parse chunk header */
937 static int
938 parse_chunk_header(char* buf, size_t* result)
939 {
940         char* e = NULL;
941         size_t v = (size_t)strtol(buf, &e, 16);
942         if(e == buf)
943                 return 0;
944         *result = v;
945         return 1;
946 }
947
948 /** read chunked data from connection */
949 static BIO*
950 do_chunked_read(SSL* ssl)
951 {
952         char buf[1024];
953         size_t len;
954         char* body;
955         BIO* mem = BIO_new(BIO_s_mem());
956         if(verb>=3) printf("do_chunked_read\n");
957         if(!mem) {
958                 if(verb) printf("out of memory\n");
959                 return NULL;
960         }
961         while(read_ssl_line(ssl, buf, sizeof(buf))) {
962                 /* read the chunked start line */
963                 if(verb>=2) printf("chunk header: %s\n", buf);
964                 if(!parse_chunk_header(buf, &len)) {
965                         BIO_free(mem);
966                         if(verb>=3) printf("could not parse chunk header\n");
967                         return NULL;
968                 }
969                 if(verb>=2) printf("chunk len: %d\n", (int)len);
970                 /* are we done? */
971                 if(len == 0) {
972                         char z = 0;
973                         /* skip end-of-chunk-trailer lines,
974                          * until the empty line after that */
975                         do {
976                                 if(!read_ssl_line(ssl, buf, sizeof(buf))) {
977                                         BIO_free(mem);
978                                         return NULL;
979                                 }
980                         } while (strlen(buf) > 0);
981                         /* end of chunks, zero terminate it */
982                         if(BIO_write(mem, &z, 1) <= 0) {
983                                 if(verb) printf("out of memory\n");
984                                 BIO_free(mem);
985                                 return NULL;
986                         }
987                         return mem;
988                 }
989                 /* read the chunked body */
990                 body = read_data_chunk(ssl, len);
991                 if(!body) {
992                         BIO_free(mem);
993                         return NULL;
994                 }
995                 if(BIO_write(mem, body, (int)len) <= 0) {
996                         if(verb) printf("out of memory\n");
997                         free(body);
998                         BIO_free(mem);
999                         return NULL;
1000                 }
1001                 free(body);
1002                 /* skip empty line after data chunk */
1003                 if(!read_ssl_line(ssl, buf, sizeof(buf))) {
1004                         BIO_free(mem);
1005                         return NULL;
1006                 }
1007         }
1008         BIO_free(mem);
1009         return NULL;
1010 }
1011
1012 /** start HTTP1.1 transaction on SSL */
1013 static int
1014 write_http_get(SSL* ssl, char* pathname, char* urlname)
1015 {
1016         if(write_ssl_line(ssl, "GET /%s HTTP/1.1", pathname) &&
1017            write_ssl_line(ssl, "Host: %s", urlname) &&
1018            write_ssl_line(ssl, "User-Agent: unbound-anchor/%s",
1019                 PACKAGE_VERSION) &&
1020            /* We do not really do multiple queries per connection,
1021             * but this header setting is also not needed.
1022             * write_ssl_line(ssl, "Connection: close", NULL) &&*/
1023            write_ssl_line(ssl, "", NULL)) {
1024                 return 1;
1025         }
1026         return 0;
1027 }
1028
1029 /** read chunked data and zero terminate; len is without zero */
1030 static char*
1031 read_chunked_zero_terminate(SSL* ssl, size_t* len)
1032 {
1033         /* do the chunked version */
1034         BIO* tmp = do_chunked_read(ssl);
1035         char* data, *d = NULL;
1036         size_t l;
1037         if(!tmp) {
1038                 if(verb) printf("could not read from https\n");
1039                 return NULL;
1040         }
1041         l = (size_t)BIO_get_mem_data(tmp, &d);
1042         if(verb>=2) printf("chunked data is %d\n", (int)l);
1043         if(l == 0 || d == NULL) {
1044                 if(verb) printf("out of memory\n");
1045                 return NULL;
1046         }
1047         *len = l-1;
1048         data = (char*)malloc(l);
1049         if(data == NULL) {
1050                 if(verb) printf("out of memory\n");
1051                 return NULL;
1052         }
1053         memcpy(data, d, l);
1054         BIO_free(tmp);
1055         return data;
1056 }
1057
1058 /** read HTTP result from SSL */
1059 static BIO*
1060 read_http_result(SSL* ssl)
1061 {
1062         size_t len = 0;
1063         char* data;
1064         BIO* m;
1065         if(!read_http_headers(ssl, &len)) {
1066                 return NULL;
1067         }
1068         if(len == 0) {
1069                 data = read_chunked_zero_terminate(ssl, &len);
1070         } else {
1071                 data = read_data_chunk(ssl, len);
1072         }
1073         if(!data) return NULL;
1074         if(verb >= 4) print_data("read data", data, (int)len);
1075         m = BIO_new_mem_buf(data, (int)len);
1076         if(!m) {
1077                 if(verb) printf("out of memory\n");
1078                 exit(0);
1079         }
1080         return m;
1081 }
1082
1083 /** https to an IP addr, return BIO with pathname or NULL */
1084 static BIO*
1085 https_to_ip(struct ip_list* ip, char* pathname, char* urlname)
1086 {
1087         int fd;
1088         SSL* ssl;
1089         BIO* bio;
1090         SSL_CTX* sslctx = setup_sslctx();
1091         if(!sslctx) {
1092                 return NULL;
1093         }
1094         fd = connect_to_ip(ip);
1095         if(fd == -1) {
1096                 SSL_CTX_free(sslctx);
1097                 return NULL;
1098         }
1099         ssl = TLS_initiate(sslctx, fd);
1100         if(!ssl) {
1101                 SSL_CTX_free(sslctx);
1102                 fd_close(fd);
1103                 return NULL;
1104         }
1105         if(!write_http_get(ssl, pathname, urlname)) {
1106                 if(verb) printf("could not write to server\n");
1107                 SSL_free(ssl);
1108                 SSL_CTX_free(sslctx);
1109                 fd_close(fd);
1110                 return NULL;
1111         }
1112         bio = read_http_result(ssl);
1113         TLS_shutdown(fd, ssl, sslctx);
1114         return bio;
1115 }
1116
1117 /**
1118  * Do a HTTPS, HTTP1.1 over TLS, to fetch a file
1119  * @param ip_list: list of IP addresses to use to fetch from.
1120  * @param pathname: pathname of file on server to GET.
1121  * @param urlname: name to pass as the virtual host for this request.
1122  * @return a memory BIO with the file in it.
1123  */
1124 static BIO*
1125 https(struct ip_list* ip_list, char* pathname, char* urlname)
1126 {
1127         struct ip_list* ip;
1128         BIO* bio = NULL;
1129         /* try random address first, and work through the list */
1130         wipe_ip_usage(ip_list);
1131         while( (ip = pick_random_ip(ip_list)) ) {
1132                 ip->used = 1;
1133                 bio = https_to_ip(ip, pathname, urlname);
1134                 if(bio) break;
1135         }
1136         if(!bio) {
1137                 if(verb) printf("could not fetch %s\n", pathname);
1138                 exit(0);
1139         } else {
1140                 if(verb) printf("fetched %s (%d bytes)\n",
1141                         pathname, (int)BIO_ctrl_pending(bio));
1142         }
1143         return bio;
1144 }
1145
1146 /** free up a downloaded file BIO */
1147 static void
1148 free_file_bio(BIO* bio)
1149 {
1150         char* pp = NULL;
1151         (void)BIO_reset(bio);
1152         (void)BIO_get_mem_data(bio, &pp);
1153         free(pp);
1154         BIO_free(bio);
1155 }
1156
1157 /** XML parse private data during the parse */
1158 struct xml_data {
1159         /** the parser, reference */
1160         XML_Parser parser;
1161         /** the current tag; malloced; or NULL outside of tags */
1162         char* tag;
1163         /** current date to use during the parse */
1164         time_t date;
1165         /** number of keys usefully read in */
1166         int num_keys;
1167         /** the compiled anchors as DS records */
1168         BIO* ds;
1169
1170         /** do we want to use this anchor? */
1171         int use_key;
1172         /** the current anchor: Zone */
1173         BIO* czone;
1174         /** the current anchor: KeyTag */
1175         BIO* ctag;
1176         /** the current anchor: Algorithm */
1177         BIO* calgo;
1178         /** the current anchor: DigestType */
1179         BIO* cdigtype;
1180         /** the current anchor: Digest*/
1181         BIO* cdigest;
1182 };
1183
1184 /** The BIO for the tag */
1185 static BIO*
1186 xml_selectbio(struct xml_data* data, const char* tag)
1187 {
1188         BIO* b = NULL;
1189         if(strcasecmp(tag, "KeyTag") == 0)
1190                 b = data->ctag;
1191         else if(strcasecmp(tag, "Algorithm") == 0)
1192                 b = data->calgo;
1193         else if(strcasecmp(tag, "DigestType") == 0)
1194                 b = data->cdigtype;
1195         else if(strcasecmp(tag, "Digest") == 0)
1196                 b = data->cdigest;
1197         return b;
1198 }
1199
1200 /**
1201  * XML handle character data, the data inside an element.
1202  * @param userData: xml_data structure
1203  * @param s: the character data.  May not all be in one callback.
1204  *      NOT zero terminated.
1205  * @param len: length of this part of the data.
1206  */
1207 void
1208 xml_charhandle(void *userData, const XML_Char *s, int len)
1209 {
1210         struct xml_data* data = (struct xml_data*)userData;
1211         BIO* b = NULL;
1212         /* skip characters outside of elements */
1213         if(!data->tag)
1214                 return;
1215         if(verb>=4) {
1216                 int i;
1217                 printf("%s%s charhandle: '",
1218                         data->use_key?"use ":"",
1219                         data->tag?data->tag:"none");
1220                 for(i=0; i<len; i++)
1221                         printf("%c", s[i]);
1222                 printf("'\n");
1223         }
1224         if(strcasecmp(data->tag, "Zone") == 0) {
1225                 if(BIO_write(data->czone, s, len) <= 0) {
1226                         if(verb) printf("out of memory in BIO_write\n");
1227                         exit(0);
1228                 }
1229                 return;
1230         }
1231         /* only store if key is used */
1232         if(!data->use_key)
1233                 return;
1234         b = xml_selectbio(data, data->tag);
1235         if(b) {
1236                 if(BIO_write(b, s, len) <= 0) {
1237                         if(verb) printf("out of memory in BIO_write\n");
1238                         exit(0);
1239                 }
1240         }
1241 }
1242
1243 /**
1244  * XML fetch value of particular attribute(by name) or NULL if not present.
1245  * @param atts: attribute array (from xml_startelem).
1246  * @param name: name of attribute to look for.
1247  * @return the value or NULL. (ptr into atts).
1248  */
1249 static const XML_Char*
1250 find_att(const XML_Char **atts, XML_Char* name)
1251 {
1252         int i;
1253         for(i=0; atts[i]; i+=2) {
1254                 if(strcasecmp(atts[i], name) == 0)
1255                         return atts[i+1];
1256         }
1257         return NULL;
1258 }
1259
1260 /**
1261  * XML convert DateTime element to time_t.
1262  * [-]CCYY-MM-DDThh:mm:ss[Z|(+|-)hh:mm]
1263  * (with optional .ssssss fractional seconds)
1264  * @param str: the string
1265  * @return a time_t representation or 0 on failure.
1266  */
1267 static time_t
1268 xml_convertdate(const char* str)
1269 {
1270         time_t t = 0;
1271         struct tm tm;
1272         const char* s;
1273         /* for this application, ignore minus in front;
1274          * only positive dates are expected */
1275         s = str;
1276         if(s[0] == '-') s++;
1277         memset(&tm, 0, sizeof(tm));
1278         /* parse initial content of the string (lots of whitespace allowed) */
1279         s = strptime(s, "%t%Y%t-%t%m%t-%t%d%tT%t%H%t:%t%M%t:%t%S%t", &tm);
1280         if(!s) {
1281                 if(verb) printf("xml_convertdate parse failure %s\n", str);
1282                 return 0;
1283         }
1284         /* parse remainder of date string */
1285         if(*s == '.') {
1286                 /* optional '.' and fractional seconds */
1287                 int frac = 0, n = 0;
1288                 if(sscanf(s+1, "%d%n", &frac, &n) < 1) {
1289                         if(verb) printf("xml_convertdate f failure %s\n", str);
1290                         return 0;
1291                 }
1292                 /* fraction is not used, time_t has second accuracy */
1293                 s++;
1294                 s+=n;
1295         }
1296         if(*s == 'Z' || *s == 'z') {
1297                 /* nothing to do for this */
1298                 s++;
1299         } else if(*s == '+' || *s == '-') {
1300                 /* optional timezone spec: Z or +hh:mm or -hh:mm */
1301                 int hr = 0, mn = 0, n = 0;
1302                 if(sscanf(s+1, "%d:%d%n", &hr, &mn, &n) < 2) {
1303                         if(verb) printf("xml_convertdate tz failure %s\n", str);
1304                         return 0;
1305                 }
1306                 if(*s == '+') {
1307                         tm.tm_hour += hr;
1308                         tm.tm_min += mn;
1309                 } else {
1310                         tm.tm_hour -= hr;
1311                         tm.tm_min -= mn;
1312                 }
1313                 s++;
1314                 s += n;
1315         }
1316         if(*s != 0) {
1317                 /* not ended properly */
1318                 /* but ignore, (lenient) */
1319         }
1320
1321         t = mktime(&tm);
1322         if(t == (time_t)-1) {
1323                 if(verb) printf("xml_convertdate mktime failure\n");
1324                 return 0;
1325         }
1326         return t;
1327 }
1328
1329 /**
1330  * XML handle the KeyDigest start tag, check validity periods.
1331  */
1332 static void
1333 handle_keydigest(struct xml_data* data, const XML_Char **atts)
1334 {
1335         data->use_key = 0;
1336         if(find_att(atts, "validFrom")) {
1337                 time_t from = xml_convertdate(find_att(atts, "validFrom"));
1338                 if(from == 0) {
1339                         if(verb) printf("error: xml cannot be parsed\n");
1340                         exit(0);
1341                 }
1342                 if(data->date < from)
1343                         return;
1344         }
1345         if(find_att(atts, "validUntil")) {
1346                 time_t until = xml_convertdate(find_att(atts, "validUntil"));
1347                 if(until == 0) {
1348                         if(verb) printf("error: xml cannot be parsed\n");
1349                         exit(0);
1350                 }
1351                 if(data->date > until)
1352                         return;
1353         }
1354         /* yes we want to use this key */
1355         data->use_key = 1;
1356         (void)BIO_reset(data->ctag);
1357         (void)BIO_reset(data->calgo);
1358         (void)BIO_reset(data->cdigtype);
1359         (void)BIO_reset(data->cdigest);
1360 }
1361
1362 /** See if XML element equals the zone name */
1363 static int
1364 xml_is_zone_name(BIO* zone, char* name)
1365 {
1366         char buf[1024];
1367         char* z = NULL;
1368         long zlen;
1369         (void)BIO_seek(zone, 0);
1370         zlen = BIO_get_mem_data(zone, &z);
1371         if(!zlen || !z) return 0;
1372         /* zero terminate */
1373         if(zlen >= (long)sizeof(buf)) return 0;
1374         memmove(buf, z, (size_t)zlen);
1375         buf[zlen] = 0;
1376         /* compare */
1377         return (strncasecmp(buf, name, strlen(name)) == 0);
1378 }
1379
1380 /** 
1381  * XML start of element. This callback is called whenever an XML tag starts.
1382  * XML_Char is UTF8.
1383  * @param userData: the xml_data structure.
1384  * @param name: the tag that starts.
1385  * @param atts: array of strings, pairs of attr = value, ends with NULL.
1386  *      i.e. att[0]="att[1]" att[2]="att[3]" att[4]isNull
1387  */
1388 static void
1389 xml_startelem(void *userData, const XML_Char *name, const XML_Char **atts)
1390 {
1391         struct xml_data* data = (struct xml_data*)userData;
1392         BIO* b;
1393         if(verb>=4) printf("xml tag start '%s'\n", name);
1394         free(data->tag);
1395         data->tag = strdup(name);
1396         if(!data->tag) {
1397                 if(verb) printf("out of memory\n");
1398                 exit(0);
1399         }
1400         if(verb>=4) {
1401                 int i;
1402                 for(i=0; atts[i]; i+=2) {
1403                         printf("  %s='%s'\n", atts[i], atts[i+1]);
1404                 }
1405         }
1406         /* handle attributes to particular types */
1407         if(strcasecmp(name, "KeyDigest") == 0) {
1408                 handle_keydigest(data, atts);
1409                 return;
1410         } else if(strcasecmp(name, "Zone") == 0) {
1411                 (void)BIO_reset(data->czone);
1412                 return;
1413         }
1414
1415         /* for other types we prepare to pick up the data */
1416         if(!data->use_key)
1417                 return;
1418         b = xml_selectbio(data, data->tag);
1419         if(b) {
1420                 /* empty it */
1421                 (void)BIO_reset(b);
1422         }
1423 }
1424
1425 /** Append str to bio */
1426 static void
1427 xml_append_str(BIO* b, const char* s)
1428 {
1429         if(BIO_write(b, s, (int)strlen(s)) <= 0) {
1430                 if(verb) printf("out of memory in BIO_write\n");
1431                 exit(0);
1432         }
1433 }
1434
1435 /** Append bio to bio */
1436 static void
1437 xml_append_bio(BIO* b, BIO* a)
1438 {
1439         char* z = NULL;
1440         long i, len;
1441         (void)BIO_seek(a, 0);
1442         len = BIO_get_mem_data(a, &z);
1443         if(!len || !z) {
1444                 if(verb) printf("out of memory in BIO_write\n");
1445                 exit(0);
1446         }
1447         /* remove newlines in the data here */
1448         for(i=0; i<len; i++) {
1449                 if(z[i] == '\r' || z[i] == '\n')
1450                         z[i] = ' ';
1451         }
1452         /* write to BIO */
1453         if(BIO_write(b, z, len) <= 0) {
1454                 if(verb) printf("out of memory in BIO_write\n");
1455                 exit(0);
1456         }
1457 }
1458
1459 /** write the parsed xml-DS to the DS list */
1460 static void
1461 xml_append_ds(struct xml_data* data)
1462 {
1463         /* write DS to accumulated DS */
1464         xml_append_str(data->ds, ". IN DS ");
1465         xml_append_bio(data->ds, data->ctag);
1466         xml_append_str(data->ds, " ");
1467         xml_append_bio(data->ds, data->calgo);
1468         xml_append_str(data->ds, " ");
1469         xml_append_bio(data->ds, data->cdigtype);
1470         xml_append_str(data->ds, " ");
1471         xml_append_bio(data->ds, data->cdigest);
1472         xml_append_str(data->ds, "\n");
1473         data->num_keys++;
1474 }
1475
1476 /**
1477  * XML end of element. This callback is called whenever an XML tag ends.
1478  * XML_Char is UTF8.
1479  * @param userData: the xml_data structure
1480  * @param name: the tag that ends.
1481  */
1482 static void
1483 xml_endelem(void *userData, const XML_Char *name)
1484 {
1485         struct xml_data* data = (struct xml_data*)userData;
1486         if(verb>=4) printf("xml tag end   '%s'\n", name);
1487         free(data->tag);
1488         data->tag = NULL;
1489         if(strcasecmp(name, "KeyDigest") == 0) {
1490                 if(data->use_key)
1491                         xml_append_ds(data);
1492                 data->use_key = 0;
1493         } else if(strcasecmp(name, "Zone") == 0) {
1494                 if(!xml_is_zone_name(data->czone, ".")) {
1495                         if(verb) printf("xml not for the right zone\n");
1496                         exit(0);
1497                 }
1498         }
1499 }
1500
1501 /**
1502  * XML parser setup of the callbacks for the tags
1503  */
1504 static void
1505 xml_parse_setup(XML_Parser parser, struct xml_data* data, time_t now)
1506 {
1507         char buf[1024];
1508         memset(data, 0, sizeof(*data));
1509         XML_SetUserData(parser, data);
1510         data->parser = parser;
1511         data->date = now;
1512         data->ds = BIO_new(BIO_s_mem());
1513         data->ctag = BIO_new(BIO_s_mem());
1514         data->czone = BIO_new(BIO_s_mem());
1515         data->calgo = BIO_new(BIO_s_mem());
1516         data->cdigtype = BIO_new(BIO_s_mem());
1517         data->cdigest = BIO_new(BIO_s_mem());
1518         if(!data->ds || !data->ctag || !data->calgo || !data->czone ||
1519                 !data->cdigtype || !data->cdigest) {
1520                 if(verb) printf("out of memory\n");
1521                 exit(0);
1522         }
1523         snprintf(buf, sizeof(buf), "; created by unbound-anchor on %s",
1524                 ctime(&now));
1525         if(BIO_write(data->ds, buf, (int)strlen(buf)) <= 0) {
1526                 if(verb) printf("out of memory\n");
1527                 exit(0);
1528         }
1529         XML_SetElementHandler(parser, xml_startelem, xml_endelem);
1530         XML_SetCharacterDataHandler(parser, xml_charhandle);
1531 }
1532
1533 /**
1534  * Perform XML parsing of the root-anchors file
1535  * Its format description can be read here
1536  * https://data.iana.org/root-anchors/draft-icann-dnssec-trust-anchor.txt
1537  * It uses libexpat.
1538  * @param xml: BIO with xml data.
1539  * @param now: the current time for checking DS validity periods.
1540  * @return memoryBIO with the DS data in zone format.
1541  *      or NULL if the zone is insecure.
1542  *      (It exit()s on error)
1543  */
1544 static BIO*
1545 xml_parse(BIO* xml, time_t now)
1546 {
1547         char* pp;
1548         int len;
1549         XML_Parser parser;
1550         struct xml_data data;
1551
1552         parser = XML_ParserCreate(NULL);
1553         if(!parser) {
1554                 if(verb) printf("could not XML_ParserCreate\n");
1555                 exit(0);
1556         }
1557
1558         /* setup callbacks */
1559         xml_parse_setup(parser, &data, now);
1560
1561         /* parse it */
1562         (void)BIO_reset(xml);
1563         len = (int)BIO_get_mem_data(xml, &pp);
1564         if(!len || !pp) {
1565                 if(verb) printf("out of memory\n");
1566                 exit(0);
1567         }
1568         if(!XML_Parse(parser, pp, len, 1 /*isfinal*/ )) {
1569                 const char *e = XML_ErrorString(XML_GetErrorCode(parser));
1570                 if(verb) printf("XML_Parse failure %s\n", e?e:"");
1571                 exit(0);
1572         }
1573
1574         /* parsed */
1575         if(verb) printf("XML was parsed successfully, %d keys\n",
1576                         data.num_keys);
1577         free(data.tag);
1578         XML_ParserFree(parser);
1579
1580         if(verb >= 4) {
1581                 char* pp = NULL;
1582                 int len;
1583                 (void)BIO_seek(data.ds, 0);
1584                 len = BIO_get_mem_data(data.ds, &pp);
1585                 printf("got DS bio %d: '", len);
1586                 if(!fwrite(pp, (size_t)len, 1, stdout))
1587                         /* compilers do not allow us to ignore fwrite .. */
1588                         fprintf(stderr, "error writing to stdout\n");
1589                 printf("'\n");
1590         }
1591         BIO_free(data.czone);
1592         BIO_free(data.ctag);
1593         BIO_free(data.calgo);
1594         BIO_free(data.cdigtype);
1595         BIO_free(data.cdigest);
1596
1597         if(data.num_keys == 0) {
1598                 /* the root zone seems to have gone insecure */
1599                 BIO_free(data.ds);
1600                 return NULL;
1601         } else {
1602                 return data.ds;
1603         }
1604 }
1605
1606 /** verify a PKCS7 signature, false on failure */
1607 static int
1608 verify_p7sig(BIO* data, BIO* p7s, STACK_OF(X509)* trust)
1609 {
1610         PKCS7* p7;
1611         X509_STORE *store = X509_STORE_new();
1612         int secure = 0;
1613         int i;
1614 #ifdef X509_V_FLAG_CHECK_SS_SIGNATURE
1615         X509_VERIFY_PARAM* param = X509_VERIFY_PARAM_new();
1616         if(!param) {
1617                 if(verb) printf("out of memory\n");
1618                 X509_STORE_free(store);
1619                 return 0;
1620         }
1621         /* do the selfcheck on the root certificate; it checks that the
1622          * input is valid */
1623         X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CHECK_SS_SIGNATURE);
1624         if(store) X509_STORE_set1_param(store, param);
1625 #endif
1626         if(!store) {
1627                 if(verb) printf("out of memory\n");
1628 #ifdef X509_V_FLAG_CHECK_SS_SIGNATURE
1629                 X509_VERIFY_PARAM_free(param);
1630 #endif
1631                 return 0;
1632         }
1633
1634         (void)BIO_reset(p7s);
1635         (void)BIO_reset(data);
1636
1637         /* convert p7s to p7 (the signature) */
1638         p7 = d2i_PKCS7_bio(p7s, NULL);
1639         if(!p7) {
1640                 if(verb) printf("could not parse p7s signature file\n");
1641                 X509_STORE_free(store);
1642                 return 0;
1643         }
1644         if(verb >= 2) printf("parsed the PKCS7 signature\n");
1645
1646         /* convert trust to trusted certificate store */
1647         for(i=0; i<sk_X509_num(trust); i++) {
1648                 if(!X509_STORE_add_cert(store, sk_X509_value(trust, i))) {
1649                         if(verb) printf("failed X509_STORE_add_cert\n");
1650                         X509_STORE_free(store);
1651                         PKCS7_free(p7);
1652                         return 0;
1653                 }
1654         }
1655         if(verb >= 2) printf("setup the X509_STORE\n");
1656
1657         if(PKCS7_verify(p7, NULL, store, data, NULL, 0) == 1) {
1658                 secure = 1;
1659                 if(verb) printf("the PKCS7 signature verified\n");
1660         } else {
1661                 if(verb) {
1662                         ERR_print_errors_fp(stdout);
1663                 }
1664         }
1665
1666         X509_STORE_free(store);
1667         PKCS7_free(p7);
1668         return secure;
1669 }
1670
1671 /** write unsigned root anchor file, a 5011 revoked tp */
1672 static void
1673 write_unsigned_root(char* root_anchor_file)
1674 {
1675         FILE* out;
1676         time_t now = time(NULL);
1677         out = fopen(root_anchor_file, "w");
1678         if(!out) {
1679                 if(verb) printf("%s: %s\n", root_anchor_file, strerror(errno));
1680                 return;
1681         }
1682         if(fprintf(out, "; autotrust trust anchor file\n"
1683                 ";;REVOKED\n"
1684                 ";;id: . 1\n"
1685                 "; This file was written by unbound-anchor on %s"
1686                 "; It indicates that the root does not use DNSSEC\n"
1687                 "; to restart DNSSEC overwrite this file with a\n"
1688                 "; valid trustanchor or (empty-it and run unbound-anchor)\n"
1689                 , ctime(&now)) < 0) {
1690                 if(verb) printf("failed to write 'unsigned' to %s\n",
1691                         root_anchor_file);
1692                 if(verb && errno != 0) printf("%s\n", strerror(errno));
1693         }
1694         fclose(out);
1695 }
1696
1697 /** write root anchor file */
1698 static void
1699 write_root_anchor(char* root_anchor_file, BIO* ds)
1700 {
1701         char* pp = NULL;
1702         int len;
1703         FILE* out;
1704         (void)BIO_seek(ds, 0);
1705         len = BIO_get_mem_data(ds, &pp);
1706         if(!len || !pp) {
1707                 if(verb) printf("out of memory\n");
1708                 return;
1709         }
1710         out = fopen(root_anchor_file, "w");
1711         if(!out) {
1712                 if(verb) printf("%s: %s\n", root_anchor_file, strerror(errno));
1713                 return;
1714         }
1715         if(fwrite(pp, (size_t)len, 1, out) != 1) {
1716                 if(verb) printf("failed to write all data to %s\n",
1717                         root_anchor_file);
1718                 if(verb && errno != 0) printf("%s\n", strerror(errno));
1719         }
1720         fclose(out);
1721 }
1722
1723 /** Perform the verification and update of the trustanchor file */
1724 static void
1725 verify_and_update_anchor(char* root_anchor_file, BIO* xml, BIO* p7s,
1726         STACK_OF(X509)* cert)
1727 {
1728         BIO* ds;
1729
1730         /* verify xml file */
1731         if(!verify_p7sig(xml, p7s, cert)) {
1732                 printf("the PKCS7 signature failed\n");
1733                 exit(0);
1734         }
1735
1736         /* parse the xml file into DS records */
1737         ds = xml_parse(xml, time(NULL));
1738         if(!ds) {
1739                 /* the root zone is unsigned now */
1740                 write_unsigned_root(root_anchor_file);
1741         } else {
1742                 /* reinstate 5011 tracking */
1743                 write_root_anchor(root_anchor_file, ds);
1744         }
1745         BIO_free(ds);
1746 }
1747
1748 #ifdef USE_WINSOCK
1749 static void do_wsa_cleanup(void) { WSACleanup(); }
1750 #endif
1751
1752 /** perform actual certupdate work */
1753 static int
1754 do_certupdate(char* root_anchor_file, char* root_cert_file,
1755         char* urlname, char* xmlname, char* p7sname,
1756         char* res_conf, char* root_hints, char* debugconf,
1757         int ip4only, int ip6only, int port, struct ub_result* dnskey)
1758 {
1759         STACK_OF(X509)* cert;
1760         BIO *xml, *p7s;
1761         struct ip_list* ip_list = NULL;
1762
1763         /* read pem file or provide builtin */
1764         cert = read_cert_or_builtin(root_cert_file);
1765
1766         /* lookup A, AAAA for the urlname (or parse urlname if IP address) */
1767         ip_list = resolve_name(urlname, port, res_conf, root_hints, debugconf,
1768                 ip4only, ip6only);
1769
1770 #ifdef USE_WINSOCK
1771         if(1) { /* libunbound finished, startup WSA for the https connection */
1772                 WSADATA wsa_data;
1773                 int r;
1774                 if((r = WSAStartup(MAKEWORD(2,2), &wsa_data)) != 0) {
1775                         if(verb) printf("WSAStartup failed: %s\n",
1776                                 wsa_strerror(r));
1777                         exit(0);
1778                 }
1779                 atexit(&do_wsa_cleanup);
1780         }
1781 #endif
1782
1783         /* fetch the necessary files over HTTPS */
1784         xml = https(ip_list, xmlname, urlname);
1785         p7s = https(ip_list, p7sname, urlname);
1786
1787         /* verify and update the root anchor */
1788         verify_and_update_anchor(root_anchor_file, xml, p7s, cert);
1789         if(verb) printf("success: the anchor has been updated "
1790                         "using the cert\n");
1791
1792         free_file_bio(xml);
1793         free_file_bio(p7s);
1794 #ifndef S_SPLINT_S
1795         sk_X509_pop_free(cert, X509_free);
1796 #endif
1797         ub_resolve_free(dnskey);
1798         ip_list_free(ip_list);
1799         return 1;
1800 }
1801
1802 /**
1803  * Try to read the root RFC5011 autotrust anchor file,
1804  * @param file: filename.
1805  * @return:
1806  *      0 if does not exist or empty
1807  *      1 if trust-point-revoked-5011
1808  *      2 if it is OK.
1809  */
1810 static int
1811 try_read_anchor(char* file)
1812 {
1813         int empty = 1;
1814         char line[10240];
1815         char* p;
1816         FILE* in = fopen(file, "r");
1817         if(!in) {
1818                 /* only if the file does not exist, can we fix it */
1819                 if(errno != ENOENT) {
1820                         if(verb) printf("%s: %s\n", file, strerror(errno));
1821                         if(verb) printf("error: cannot access the file\n");
1822                         exit(0);
1823                 }
1824                 if(verb) printf("%s does not exist\n", file);
1825                 return 0;
1826         }
1827         while(fgets(line, (int)sizeof(line), in)) {
1828                 line[sizeof(line)-1] = 0;
1829                 if(strncmp(line, ";;REVOKED", 9) == 0) {
1830                         fclose(in);
1831                         if(verb) printf("%s : the trust point is revoked\n"
1832                                 "and the zone is considered unsigned.\n"
1833                                 "if you wish to re-enable, delete the file\n",
1834                                 file);
1835                         return 1;
1836                 }
1837                 p=line;
1838                 while(*p == ' ' || *p == '\t')
1839                         p++;
1840                 if(p[0]==0 || p[0]=='\n' || p[0]==';') continue;
1841                 /* this line is a line of content */
1842                 empty = 0;
1843         }
1844         fclose(in);
1845         if(empty) {
1846                 if(verb) printf("%s is empty\n", file);
1847                 return 0;
1848         }
1849         if(verb) printf("%s has content\n", file);
1850         return 2;
1851 }
1852
1853 /** Write the builtin root anchor to a file */
1854 static void
1855 write_builtin_anchor(char* file)
1856 {
1857         const char* builtin_root_anchor = get_builtin_ds();
1858         FILE* out = fopen(file, "w");
1859         if(!out) {
1860                 if(verb) printf("%s: %s\n", file, strerror(errno));
1861                 if(verb) printf("  could not write builtin anchor\n");
1862                 return;
1863         }
1864         if(!fwrite(builtin_root_anchor, strlen(builtin_root_anchor), 1, out)) {
1865                 if(verb) printf("%s: %s\n", file, strerror(errno));
1866                 if(verb) printf("  could not complete write builtin anchor\n");
1867         }
1868         fclose(out);
1869 }
1870
1871 /** 
1872  * Check the root anchor file.
1873  * If does not exist, provide builtin and write file.
1874  * If empty, provide builtin and write file.
1875  * If trust-point-revoked-5011 file: make the program exit.
1876  * @param root_anchor_file: filename of the root anchor.
1877  * @param used_builtin: set to 1 if the builtin is written.
1878  * @return 0 if trustpoint is insecure, 1 on success.  Exit on failure.
1879  */
1880 static int
1881 provide_builtin(char* root_anchor_file, int* used_builtin)
1882 {
1883         /* try to read it */
1884         switch(try_read_anchor(root_anchor_file))
1885         {
1886                 case 0: /* no exist or empty */
1887                         write_builtin_anchor(root_anchor_file);
1888                         *used_builtin = 1;
1889                         break;
1890                 case 1: /* revoked tp */
1891                         return 0;       
1892                 case 2: /* it is fine */
1893                 default:
1894                         break;
1895         }
1896         return 1;
1897 }
1898
1899 /**
1900  * add an autotrust anchor for the root to the context
1901  */
1902 static void
1903 add_5011_probe_root(struct ub_ctx* ctx, char* root_anchor_file)
1904 {
1905         int r;
1906         r = ub_ctx_set_option(ctx, "auto-trust-anchor-file:", root_anchor_file);
1907         if(r) {
1908                 if(verb) printf("add 5011 probe to ctx: %s\n", ub_strerror(r));
1909                 ub_ctx_delete(ctx);
1910                 exit(0);
1911         }
1912 }
1913
1914 /**
1915  * Prime the root key and return the result.  Exit on error.
1916  * @param ctx: the unbound context to perform the priming with.
1917  * @return: the result of the prime, on error it exit()s.
1918  */
1919 static struct ub_result*
1920 prime_root_key(struct ub_ctx* ctx)
1921 {
1922         struct ub_result* res = NULL;
1923         int r;
1924         r = ub_resolve(ctx, ".", LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN, &res);
1925         if(r) {
1926                 if(verb) printf("resolve DNSKEY: %s\n", ub_strerror(r));
1927                 ub_ctx_delete(ctx);
1928                 exit(0);
1929         }
1930         if(!res) {
1931                 if(verb) printf("out of memory\n");
1932                 ub_ctx_delete(ctx);
1933                 exit(0);
1934         }
1935         return res;
1936 }
1937
1938 /** see if ADDPEND keys exist in autotrust file (if possible) */
1939 static int
1940 read_if_pending_keys(char* file)
1941 {
1942         FILE* in = fopen(file, "r");
1943         char line[8192];
1944         if(!in) {
1945                 if(verb>=2) printf("%s: %s\n", file, strerror(errno));
1946                 return 0;
1947         }
1948         while(fgets(line, (int)sizeof(line), in)) {
1949                 if(line[0]==';') continue;
1950                 if(strstr(line, "[ ADDPEND ]")) {
1951                         fclose(in);
1952                         if(verb) printf("RFC5011-state has ADDPEND keys\n");
1953                         return 1;
1954                 }
1955         }
1956         fclose(in);
1957         return 0;
1958 }
1959
1960 /** read last successful probe time from autotrust file (if possible) */
1961 static int32_t
1962 read_last_success_time(char* file)
1963 {
1964         FILE* in = fopen(file, "r");
1965         char line[1024];
1966         if(!in) {
1967                 if(verb) printf("%s: %s\n", file, strerror(errno));
1968                 return 0;
1969         }
1970         while(fgets(line, (int)sizeof(line), in)) {
1971                 if(strncmp(line, ";;last_success: ", 16) == 0) {
1972                         char* e;
1973                         time_t x = (unsigned int)strtol(line+16, &e, 10);
1974                         fclose(in);
1975                         if(line+16 == e) {
1976                                 if(verb) printf("failed to parse "
1977                                         "last_success probe time\n");
1978                                 return 0;
1979                         }
1980                         if(verb) printf("last successful probe: %s", ctime(&x));
1981                         return (int32_t)x;
1982                 }
1983         }
1984         fclose(in);
1985         if(verb) printf("no last_success probe time in anchor file\n");
1986         return 0;
1987 }
1988
1989 /**
1990  * Read autotrust 5011 probe file and see if the date
1991  * compared to the current date allows a certupdate.
1992  * If the last successful probe was recent then 5011 cannot be behind,
1993  * and the failure cannot be solved with a certupdate.
1994  * The debugconf is to validation-override the date for testing.
1995  * @param root_anchor_file: filename of root key
1996  * @return true if certupdate is ok.
1997  */
1998 static int
1999 probe_date_allows_certupdate(char* root_anchor_file)
2000 {
2001         int has_pending_keys = read_if_pending_keys(root_anchor_file);
2002         int32_t last_success = read_last_success_time(root_anchor_file);
2003         int32_t now = (int32_t)time(NULL);
2004         int32_t leeway = 30 * 24 * 3600; /* 30 days leeway */
2005         /* if the date is before 2010-07-15:00.00.00 then the root has not
2006          * been signed yet, and thus we refuse to take action. */
2007         if(time(NULL) < xml_convertdate("2010-07-15T00:00:00")) {
2008                 if(verb) printf("the date is before the root was first signed,"
2009                         " please correct the clock\n");
2010                 return 0;
2011         }
2012         if(last_success == 0)
2013                 return 1; /* no probe time */
2014         if(has_pending_keys)
2015                 return 1; /* key in ADDPEND state, a previous probe has
2016                 inserted that, and it was present in all recent probes,
2017                 but it has not become active.  The 30 day timer may not have
2018                 expired, but we know(for sure) there is a rollover going on.
2019                 If we only managed to pickup the new key on its last day
2020                 of announcement (for example) this can happen. */
2021         if(now - last_success < 0) {
2022                 if(verb) printf("the last successful probe is in the future,"
2023                         " clock was modified\n");
2024                 return 0;
2025         }
2026         if(now - last_success >= leeway) {
2027                 if(verb) printf("the last successful probe was more than 30 "
2028                         "days ago\n");
2029                 return 1;
2030         }
2031         if(verb) printf("the last successful probe is recent\n");
2032         return 0;
2033 }
2034
2035 /** perform the unbound-anchor work */
2036 static int
2037 do_root_update_work(char* root_anchor_file, char* root_cert_file,
2038         char* urlname, char* xmlname, char* p7sname,
2039         char* res_conf, char* root_hints, char* debugconf,
2040         int ip4only, int ip6only, int force, int port)
2041 {
2042         struct ub_ctx* ctx;
2043         struct ub_result* dnskey;
2044         int used_builtin = 0;
2045
2046         /* see if builtin rootanchor needs to be provided, or if
2047          * rootanchor is 'revoked-trust-point' */
2048         if(!provide_builtin(root_anchor_file, &used_builtin))
2049                 return 0;
2050
2051         /* make unbound context with 5011-probe for root anchor,
2052          * and probe . DNSKEY */
2053         ctx = create_unbound_context(res_conf, root_hints, debugconf,
2054                 ip4only, ip6only);
2055         add_5011_probe_root(ctx, root_anchor_file);
2056         dnskey = prime_root_key(ctx);
2057         ub_ctx_delete(ctx);
2058         
2059         /* if secure: exit */
2060         if(dnskey->secure && !force) {
2061                 if(verb) printf("success: the anchor is ok\n");
2062                 ub_resolve_free(dnskey);
2063                 return used_builtin;
2064         }
2065         if(force && verb) printf("debug cert update forced\n");
2066
2067         /* if not (and NOERROR): check date and do certupdate */
2068         if((dnskey->rcode == 0 &&
2069                 probe_date_allows_certupdate(root_anchor_file)) || force) {
2070                 if(do_certupdate(root_anchor_file, root_cert_file, urlname,
2071                         xmlname, p7sname, res_conf, root_hints, debugconf,
2072                         ip4only, ip6only, port, dnskey))
2073                         return 1;
2074                 return used_builtin;
2075         }
2076         if(verb) printf("fail: the anchor is NOT ok and could not be fixed\n");
2077         ub_resolve_free(dnskey);
2078         return used_builtin;
2079 }
2080
2081 /** getopt global, in case header files fail to declare it. */
2082 extern int optind;
2083 /** getopt global, in case header files fail to declare it. */
2084 extern char* optarg;
2085
2086 /** Main routine for unbound-anchor */
2087 int main(int argc, char* argv[])
2088 {
2089         int c;
2090         char* root_anchor_file = ROOT_ANCHOR_FILE;
2091         char* root_cert_file = ROOT_CERT_FILE;
2092         char* urlname = URLNAME;
2093         char* xmlname = XMLNAME;
2094         char* p7sname = P7SNAME;
2095         char* res_conf = NULL;
2096         char* root_hints = NULL;
2097         char* debugconf = NULL;
2098         int dolist=0, ip4only=0, ip6only=0, force=0, port = HTTPS_PORT;
2099         /* parse the options */
2100         while( (c=getopt(argc, argv, "46C:FP:a:c:f:hlr:s:u:vx:")) != -1) {
2101                 switch(c) {
2102                 case 'l':
2103                         dolist = 1;
2104                         break;
2105                 case '4':
2106                         ip4only = 1;
2107                         break;
2108                 case '6':
2109                         ip6only = 1;
2110                         break;
2111                 case 'a':
2112                         root_anchor_file = optarg;
2113                         break;
2114                 case 'c':
2115                         root_cert_file = optarg;
2116                         break;
2117                 case 'u':
2118                         urlname = optarg;
2119                         break;
2120                 case 'x':
2121                         xmlname = optarg;
2122                         break;
2123                 case 's':
2124                         p7sname = optarg;
2125                         break;
2126                 case 'f':
2127                         res_conf = optarg;
2128                         break;
2129                 case 'r':
2130                         root_hints = optarg;
2131                         break;
2132                 case 'C':
2133                         debugconf = optarg;
2134                         break;
2135                 case 'F':
2136                         force = 1;
2137                         break;
2138                 case 'P':
2139                         port = atoi(optarg);
2140                         break;
2141                 case 'v':
2142                         verb++;
2143                         break;
2144                 case '?':
2145                 case 'h':
2146                 default:
2147                         usage();
2148                 }
2149         }
2150         argc -= optind;
2151         argv += optind;
2152         if(argc != 0)
2153                 usage();
2154
2155         ERR_load_crypto_strings();
2156         ERR_load_SSL_strings();
2157         OpenSSL_add_all_algorithms();
2158         (void)SSL_library_init();
2159
2160         if(dolist) do_list_builtin();
2161
2162         return do_root_update_work(root_anchor_file, root_cert_file, urlname,
2163                 xmlname, p7sname, res_conf, root_hints, debugconf, ip4only,
2164                 ip6only, force, port);
2165 }