]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/test-dnssec-complex.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / resolve / test-dnssec-complex.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
412577e3
LP
2/***
3 This file is part of systemd.
4
5 Copyright 2016 Lennart Poettering
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19***/
20
12634bb4
LP
21#include <netinet/ip.h>
22
412577e3
LP
23#include "sd-bus.h"
24
12634bb4 25#include "af-list.h"
412577e3
LP
26#include "alloc-util.h"
27#include "bus-common-errors.h"
28#include "dns-type.h"
29#include "random-util.h"
30#include "string-util.h"
31#include "time-util.h"
32
33#define DNS_CALL_TIMEOUT_USEC (45*USEC_PER_SEC)
34
12634bb4
LP
35static void prefix_random(const char *name, char **ret) {
36 uint64_t i, u;
37 char *m = NULL;
38
39 u = 1 + (random_u64() & 3);
40
41 for (i = 0; i < u; i++) {
42 _cleanup_free_ char *b = NULL;
43 char *x;
44
45 assert_se(asprintf(&b, "x%" PRIu64 "x", random_u64()));
605405c6 46 x = strjoin(b, ".", name);
12634bb4
LP
47 assert_se(x);
48
49 free(m);
50 m = x;
51 }
52
53 *ret = m;
54 }
55
56static void test_rr_lookup(sd_bus *bus, const char *name, uint16_t type, const char *result) {
412577e3
LP
57 _cleanup_(sd_bus_message_unrefp) sd_bus_message *req = NULL, *reply = NULL;
58 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
59 _cleanup_free_ char *m = NULL;
60 int r;
61
62 /* If the name starts with a dot, we prefix one to three random labels */
63 if (startswith(name, ".")) {
12634bb4
LP
64 prefix_random(name + 1, &m);
65 name = m;
412577e3
LP
66 }
67
68 assert_se(sd_bus_message_new_method_call(
69 bus,
70 &req,
71 "org.freedesktop.resolve1",
72 "/org/freedesktop/resolve1",
73 "org.freedesktop.resolve1.Manager",
74 "ResolveRecord") >= 0);
75
76 assert_se(sd_bus_message_append(req, "isqqt", 0, name, DNS_CLASS_IN, type, UINT64_C(0)) >= 0);
77
78 r = sd_bus_call(bus, req, DNS_CALL_TIMEOUT_USEC, &error, &reply);
79
80 if (r < 0) {
81 assert_se(result);
82 assert_se(sd_bus_error_has_name(&error, result));
83 log_info("[OK] %s/%s resulted in <%s>.", name, dns_type_to_string(type), error.name);
84 } else {
85 assert_se(!result);
86 log_info("[OK] %s/%s succeeded.", name, dns_type_to_string(type));
87 }
88}
89
12634bb4
LP
90static void test_hostname_lookup(sd_bus *bus, const char *name, int family, const char *result) {
91 _cleanup_(sd_bus_message_unrefp) sd_bus_message *req = NULL, *reply = NULL;
92 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
93 _cleanup_free_ char *m = NULL;
94 const char *af;
95 int r;
96
97 af = family == AF_UNSPEC ? "AF_UNSPEC" : af_to_name(family);
98
99 /* If the name starts with a dot, we prefix one to three random labels */
100 if (startswith(name, ".")) {
101 prefix_random(name + 1, &m);
102 name = m;
103 }
104
105 assert_se(sd_bus_message_new_method_call(
106 bus,
107 &req,
108 "org.freedesktop.resolve1",
109 "/org/freedesktop/resolve1",
110 "org.freedesktop.resolve1.Manager",
111 "ResolveHostname") >= 0);
112
113 assert_se(sd_bus_message_append(req, "isit", 0, name, family, UINT64_C(0)) >= 0);
114
115 r = sd_bus_call(bus, req, DNS_CALL_TIMEOUT_USEC, &error, &reply);
116
117 if (r < 0) {
118 assert_se(result);
119 assert_se(sd_bus_error_has_name(&error, result));
120 log_info("[OK] %s/%s resulted in <%s>.", name, af, error.name);
121 } else {
122 assert_se(!result);
123 log_info("[OK] %s/%s succeeded.", name, af);
124 }
125
126}
127
412577e3
LP
128int main(int argc, char* argv[]) {
129 _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
130
131 /* Note that this is a manual test as it requires:
132 *
133 * Full network access
134 * A DNSSEC capable DNS server
135 * That zones contacted are still set up as they were when I wrote this.
136 */
137
138 assert_se(sd_bus_open_system(&bus) >= 0);
139
140 /* Normally signed */
12634bb4
LP
141 test_rr_lookup(bus, "www.eurid.eu", DNS_TYPE_A, NULL);
142 test_hostname_lookup(bus, "www.eurid.eu", AF_UNSPEC, NULL);
143
144 test_rr_lookup(bus, "sigok.verteiltesysteme.net", DNS_TYPE_A, NULL);
145 test_hostname_lookup(bus, "sigok.verteiltesysteme.net", AF_UNSPEC, NULL);
412577e3
LP
146
147 /* Normally signed, NODATA */
12634bb4
LP
148 test_rr_lookup(bus, "www.eurid.eu", DNS_TYPE_RP, BUS_ERROR_NO_SUCH_RR);
149 test_rr_lookup(bus, "sigok.verteiltesysteme.net", DNS_TYPE_RP, BUS_ERROR_NO_SUCH_RR);
412577e3
LP
150
151 /* Invalid signature */
12634bb4
LP
152 test_rr_lookup(bus, "sigfail.verteiltesysteme.net", DNS_TYPE_A, BUS_ERROR_DNSSEC_FAILED);
153 test_hostname_lookup(bus, "sigfail.verteiltesysteme.net", AF_INET, BUS_ERROR_DNSSEC_FAILED);
412577e3
LP
154
155 /* Invalid signature, RSA, wildcard */
12634bb4
LP
156 test_rr_lookup(bus, ".wilda.rhybar.0skar.cz", DNS_TYPE_A, BUS_ERROR_DNSSEC_FAILED);
157 test_hostname_lookup(bus, ".wilda.rhybar.0skar.cz", AF_INET, BUS_ERROR_DNSSEC_FAILED);
412577e3
LP
158
159 /* Invalid signature, ECDSA, wildcard */
12634bb4
LP
160 test_rr_lookup(bus, ".wilda.rhybar.ecdsa.0skar.cz", DNS_TYPE_A, BUS_ERROR_DNSSEC_FAILED);
161 test_hostname_lookup(bus, ".wilda.rhybar.ecdsa.0skar.cz", AF_INET, BUS_ERROR_DNSSEC_FAILED);
412577e3
LP
162
163 /* NXDOMAIN in NSEC domain */
12634bb4
LP
164 test_rr_lookup(bus, "hhh.nasa.gov", DNS_TYPE_A, _BUS_ERROR_DNS "NXDOMAIN");
165 test_hostname_lookup(bus, "hhh.nasa.gov", AF_UNSPEC, _BUS_ERROR_DNS "NXDOMAIN");
412577e3
LP
166
167 /* wildcard, NSEC zone */
12634bb4
LP
168 test_rr_lookup(bus, ".wilda.nsec.0skar.cz", DNS_TYPE_A, NULL);
169 test_hostname_lookup(bus, ".wilda.nsec.0skar.cz", AF_INET, NULL);
412577e3
LP
170
171 /* wildcard, NSEC zone, NODATA */
12634bb4 172 test_rr_lookup(bus, ".wilda.nsec.0skar.cz", DNS_TYPE_RP, BUS_ERROR_NO_SUCH_RR);
412577e3
LP
173
174 /* wildcard, NSEC3 zone */
12634bb4
LP
175 test_rr_lookup(bus, ".wilda.0skar.cz", DNS_TYPE_A, NULL);
176 test_hostname_lookup(bus, ".wilda.0skar.cz", AF_INET, NULL);
412577e3
LP
177
178 /* wildcard, NSEC3 zone, NODATA */
12634bb4 179 test_rr_lookup(bus, ".wilda.0skar.cz", DNS_TYPE_RP, BUS_ERROR_NO_SUCH_RR);
412577e3
LP
180
181 /* wildcard, NSEC zone, CNAME */
12634bb4
LP
182 test_rr_lookup(bus, ".wild.nsec.0skar.cz", DNS_TYPE_A, NULL);
183 test_hostname_lookup(bus, ".wild.nsec.0skar.cz", AF_UNSPEC, NULL);
184 test_hostname_lookup(bus, ".wild.nsec.0skar.cz", AF_INET, NULL);
412577e3
LP
185
186 /* wildcard, NSEC zone, NODATA, CNAME */
12634bb4 187 test_rr_lookup(bus, ".wild.nsec.0skar.cz", DNS_TYPE_RP, BUS_ERROR_NO_SUCH_RR);
412577e3
LP
188
189 /* wildcard, NSEC3 zone, CNAME */
12634bb4
LP
190 test_rr_lookup(bus, ".wild.0skar.cz", DNS_TYPE_A, NULL);
191 test_hostname_lookup(bus, ".wild.0skar.cz", AF_UNSPEC, NULL);
192 test_hostname_lookup(bus, ".wild.0skar.cz", AF_INET, NULL);
412577e3
LP
193
194 /* wildcard, NSEC3 zone, NODATA, CNAME */
12634bb4 195 test_rr_lookup(bus, ".wild.0skar.cz", DNS_TYPE_RP, BUS_ERROR_NO_SUCH_RR);
412577e3
LP
196
197 /* NODATA due to empty non-terminal in NSEC domain */
12634bb4
LP
198 test_rr_lookup(bus, "herndon.nasa.gov", DNS_TYPE_A, BUS_ERROR_NO_SUCH_RR);
199 test_hostname_lookup(bus, "herndon.nasa.gov", AF_UNSPEC, BUS_ERROR_NO_SUCH_RR);
200 test_hostname_lookup(bus, "herndon.nasa.gov", AF_INET, BUS_ERROR_NO_SUCH_RR);
201 test_hostname_lookup(bus, "herndon.nasa.gov", AF_INET6, BUS_ERROR_NO_SUCH_RR);
412577e3
LP
202
203 /* NXDOMAIN in NSEC root zone: */
12634bb4
LP
204 test_rr_lookup(bus, "jasdhjas.kjkfgjhfjg", DNS_TYPE_A, _BUS_ERROR_DNS "NXDOMAIN");
205 test_hostname_lookup(bus, "jasdhjas.kjkfgjhfjg", AF_UNSPEC, _BUS_ERROR_DNS "NXDOMAIN");
206 test_hostname_lookup(bus, "jasdhjas.kjkfgjhfjg", AF_INET, _BUS_ERROR_DNS "NXDOMAIN");
207 test_hostname_lookup(bus, "jasdhjas.kjkfgjhfjg", AF_INET6, _BUS_ERROR_DNS "NXDOMAIN");
412577e3
LP
208
209 /* NXDOMAIN in NSEC3 .com zone: */
12634bb4
LP
210 test_rr_lookup(bus, "kjkfgjhfjgsdfdsfd.com", DNS_TYPE_A, _BUS_ERROR_DNS "NXDOMAIN");
211 test_hostname_lookup(bus, "kjkfgjhfjgsdfdsfd.com", AF_INET, _BUS_ERROR_DNS "NXDOMAIN");
212 test_hostname_lookup(bus, "kjkfgjhfjgsdfdsfd.com", AF_INET6, _BUS_ERROR_DNS "NXDOMAIN");
213 test_hostname_lookup(bus, "kjkfgjhfjgsdfdsfd.com", AF_UNSPEC, _BUS_ERROR_DNS "NXDOMAIN");
214
215 /* Unsigned A */
216 test_rr_lookup(bus, "poettering.de", DNS_TYPE_A, NULL);
217 test_rr_lookup(bus, "poettering.de", DNS_TYPE_AAAA, NULL);
218 test_hostname_lookup(bus, "poettering.de", AF_UNSPEC, NULL);
219 test_hostname_lookup(bus, "poettering.de", AF_INET, NULL);
220 test_hostname_lookup(bus, "poettering.de", AF_INET6, NULL);
221
349cc4a5 222#if HAVE_LIBIDN2 || HAVE_LIBIDN
12634bb4
LP
223 /* Unsigned A with IDNA conversion necessary */
224 test_hostname_lookup(bus, "pöttering.de", AF_UNSPEC, NULL);
225 test_hostname_lookup(bus, "pöttering.de", AF_INET, NULL);
226 test_hostname_lookup(bus, "pöttering.de", AF_INET6, NULL);
227#endif
412577e3 228
8f4560c7
LP
229 /* DNAME, pointing to NXDOMAIN */
230 test_rr_lookup(bus, ".ireallyhpoethisdoesnexist.xn--kprw13d.", DNS_TYPE_A, _BUS_ERROR_DNS "NXDOMAIN");
231 test_rr_lookup(bus, ".ireallyhpoethisdoesnexist.xn--kprw13d.", DNS_TYPE_RP, _BUS_ERROR_DNS "NXDOMAIN");
232 test_hostname_lookup(bus, ".ireallyhpoethisdoesntexist.xn--kprw13d.", AF_UNSPEC, _BUS_ERROR_DNS "NXDOMAIN");
233 test_hostname_lookup(bus, ".ireallyhpoethisdoesntexist.xn--kprw13d.", AF_INET, _BUS_ERROR_DNS "NXDOMAIN");
234 test_hostname_lookup(bus, ".ireallyhpoethisdoesntexist.xn--kprw13d.", AF_INET6, _BUS_ERROR_DNS "NXDOMAIN");
235
412577e3
LP
236 return 0;
237}