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