xref: /netbsd-src/external/bsd/unbound/dist/winrc/anchor-update.c (revision 796c32c94f6e154afc9de0f63da35c91bb739b45)
1 /*
2  * winrc/anchor-update.c - windows trust anchor update util
3  *
4  * Copyright (c) 2009, 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
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 /**
37  * \file
38  *
39  * This file is made because contrib/update-anchor.sh does not work on
40  * windows (no shell).
41  */
42 #include "config.h"
43 #include "libunbound/unbound.h"
44 #include "sldns/rrdef.h"
45 #include "sldns/pkthdr.h"
46 #include "sldns/wire2str.h"
47 
48 /** usage */
49 static void
50 usage(void)
51 {
52 	printf("usage: { name-of-domain filename }+ \n");
53 	printf("exit codes: 0 anchors updated, 1 no changes, 2 errors.\n");
54 	exit(1);
55 }
56 
57 /** fatal exit */
58 static void fatal(const char* str)
59 {
60 	printf("fatal error: %s\n", str);
61 	exit(2);
62 }
63 
64 /** lookup data */
65 static struct ub_result*
66 do_lookup(struct ub_ctx* ctx, char* domain)
67 {
68 	struct ub_result* result = NULL;
69 	int r;
70 	r = ub_resolve(ctx, domain, LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN,
71 		&result);
72 	if(r) {
73 		printf("failed to lookup %s\n", ub_strerror(r));
74 		fatal("ub_resolve failed");
75 	}
76 	if(!result->havedata && (result->rcode == LDNS_RCODE_SERVFAIL ||
77 		result->rcode == LDNS_RCODE_REFUSED))
78 		return NULL; /* probably no internet connection */
79 	if(!result->havedata) fatal("result has no data");
80 	if(!result->secure) fatal("result is not secure");
81 	return result;
82 }
83 
84 /** print result to file */
85 static void
86 do_print(struct ub_result* result, char* file)
87 {
88 	FILE* out = fopen(file, "w");
89 	char s[65535], t[32];
90 	int i;
91 	if(!out) {
92 		perror(file);
93 		fatal("fopen failed");
94 	}
95 	i = 0;
96 	if(result->havedata)
97 	  while(result->data[i]) {
98 		sldns_wire2str_rdata_buf((uint8_t*)result->data[i],
99 			(size_t)result->len[i], s, sizeof(s),
100 			(uint16_t)result->qtype);
101 		sldns_wire2str_type_buf((uint16_t)result->qtype, t, sizeof(t));
102 		fprintf(out, "%s\t%s\t%s\n", result->qname, t, s);
103 		i++;
104 	}
105 	fclose(out);
106 }
107 
108 /** update domain to file */
109 static int
110 do_update(char* domain, char* file)
111 {
112 	struct ub_ctx* ctx;
113 	struct ub_result* result;
114 	int r;
115 	printf("updating %s to %s\n", domain, file);
116 	ctx = ub_ctx_create();
117 	if(!ctx) fatal("ub_ctx_create failed");
118 
119 	if((r=ub_ctx_add_ta_file(ctx, file))) {
120 		printf("%s\n", ub_strerror(r));
121 		fatal("ub_ctx_add_ta_file failed");
122 	}
123 
124 	if(!(result=do_lookup(ctx, domain))) {
125 		ub_ctx_delete(ctx);
126 		return 1;
127 	}
128 	ub_ctx_delete(ctx);
129 	do_print(result, file);
130 	ub_resolve_free(result);
131 	return 0;
132 }
133 
134 /** anchor update main */
135 int main(int argc, char** argv)
136 {
137 	int retcode = 1;
138 	if(argc == 1) {
139 		usage();
140 	}
141 	argc--;
142 	argv++;
143 	while(argc > 0) {
144 		int r = do_update(argv[0], argv[1]);
145 		if(r == 0) retcode = 0;
146 
147 		/* next */
148 		argc-=2;
149 		argv+=2;
150 	}
151 	return retcode;
152 }
153