1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2016 Lennart Poettering
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.
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.
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/>.
21 #include <netinet/ip.h>
26 #include "alloc-util.h"
27 #include "bus-common-errors.h"
29 #include "random-util.h"
30 #include "resolved-def.h"
31 #include "string-util.h"
32 #include "time-util.h"
34 static void prefix_random(const char *name
, char **ret
) {
38 u
= 1 + (random_u64() & 3);
40 for (i
= 0; i
< u
; i
++) {
41 _cleanup_free_
char *b
= NULL
;
44 assert_se(asprintf(&b
, "x%" PRIu64
"x", random_u64()));
45 x
= strjoin(b
, ".", name
);
55 static void test_rr_lookup(sd_bus
*bus
, const char *name
, uint16_t type
, const char *result
) {
56 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*req
= NULL
, *reply
= NULL
;
57 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
58 _cleanup_free_
char *m
= NULL
;
61 /* If the name starts with a dot, we prefix one to three random labels */
62 if (startswith(name
, ".")) {
63 prefix_random(name
+ 1, &m
);
67 assert_se(sd_bus_message_new_method_call(
70 "org.freedesktop.resolve1",
71 "/org/freedesktop/resolve1",
72 "org.freedesktop.resolve1.Manager",
73 "ResolveRecord") >= 0);
75 assert_se(sd_bus_message_append(req
, "isqqt", 0, name
, DNS_CLASS_IN
, type
, UINT64_C(0)) >= 0);
77 r
= sd_bus_call(bus
, req
, SD_RESOLVED_QUERY_TIMEOUT_USEC
, &error
, &reply
);
81 assert_se(sd_bus_error_has_name(&error
, result
));
82 log_info("[OK] %s/%s resulted in <%s>.", name
, dns_type_to_string(type
), error
.name
);
85 log_info("[OK] %s/%s succeeded.", name
, dns_type_to_string(type
));
89 static void test_hostname_lookup(sd_bus
*bus
, const char *name
, int family
, const char *result
) {
90 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*req
= NULL
, *reply
= NULL
;
91 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
92 _cleanup_free_
char *m
= NULL
;
96 af
= family
== AF_UNSPEC
? "AF_UNSPEC" : af_to_name(family
);
98 /* If the name starts with a dot, we prefix one to three random labels */
99 if (startswith(name
, ".")) {
100 prefix_random(name
+ 1, &m
);
104 assert_se(sd_bus_message_new_method_call(
107 "org.freedesktop.resolve1",
108 "/org/freedesktop/resolve1",
109 "org.freedesktop.resolve1.Manager",
110 "ResolveHostname") >= 0);
112 assert_se(sd_bus_message_append(req
, "isit", 0, name
, family
, UINT64_C(0)) >= 0);
114 r
= sd_bus_call(bus
, req
, SD_RESOLVED_QUERY_TIMEOUT_USEC
, &error
, &reply
);
118 assert_se(sd_bus_error_has_name(&error
, result
));
119 log_info("[OK] %s/%s resulted in <%s>.", name
, af
, error
.name
);
122 log_info("[OK] %s/%s succeeded.", name
, af
);
127 int main(int argc
, char* argv
[]) {
128 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*bus
= NULL
;
130 /* Note that this is a manual test as it requires:
132 * Full network access
133 * A DNSSEC capable DNS server
134 * That zones contacted are still set up as they were when I wrote this.
137 assert_se(sd_bus_open_system(&bus
) >= 0);
139 /* Normally signed */
140 test_rr_lookup(bus
, "www.eurid.eu", DNS_TYPE_A
, NULL
);
141 test_hostname_lookup(bus
, "www.eurid.eu", AF_UNSPEC
, NULL
);
143 test_rr_lookup(bus
, "sigok.verteiltesysteme.net", DNS_TYPE_A
, NULL
);
144 test_hostname_lookup(bus
, "sigok.verteiltesysteme.net", AF_UNSPEC
, NULL
);
146 /* Normally signed, NODATA */
147 test_rr_lookup(bus
, "www.eurid.eu", DNS_TYPE_RP
, BUS_ERROR_NO_SUCH_RR
);
148 test_rr_lookup(bus
, "sigok.verteiltesysteme.net", DNS_TYPE_RP
, BUS_ERROR_NO_SUCH_RR
);
150 /* Invalid signature */
151 test_rr_lookup(bus
, "sigfail.verteiltesysteme.net", DNS_TYPE_A
, BUS_ERROR_DNSSEC_FAILED
);
152 test_hostname_lookup(bus
, "sigfail.verteiltesysteme.net", AF_INET
, BUS_ERROR_DNSSEC_FAILED
);
154 /* Invalid signature, RSA, wildcard */
155 test_rr_lookup(bus
, ".wilda.rhybar.0skar.cz", DNS_TYPE_A
, BUS_ERROR_DNSSEC_FAILED
);
156 test_hostname_lookup(bus
, ".wilda.rhybar.0skar.cz", AF_INET
, BUS_ERROR_DNSSEC_FAILED
);
158 /* Invalid signature, ECDSA, wildcard */
159 test_rr_lookup(bus
, ".wilda.rhybar.ecdsa.0skar.cz", DNS_TYPE_A
, BUS_ERROR_DNSSEC_FAILED
);
160 test_hostname_lookup(bus
, ".wilda.rhybar.ecdsa.0skar.cz", AF_INET
, BUS_ERROR_DNSSEC_FAILED
);
162 /* NXDOMAIN in NSEC domain */
163 test_rr_lookup(bus
, "hhh.nasa.gov", DNS_TYPE_A
, _BUS_ERROR_DNS
"NXDOMAIN");
164 test_hostname_lookup(bus
, "hhh.nasa.gov", AF_UNSPEC
, _BUS_ERROR_DNS
"NXDOMAIN");
166 /* wildcard, NSEC zone */
167 test_rr_lookup(bus
, ".wilda.nsec.0skar.cz", DNS_TYPE_A
, NULL
);
168 test_hostname_lookup(bus
, ".wilda.nsec.0skar.cz", AF_INET
, NULL
);
170 /* wildcard, NSEC zone, NODATA */
171 test_rr_lookup(bus
, ".wilda.nsec.0skar.cz", DNS_TYPE_RP
, BUS_ERROR_NO_SUCH_RR
);
173 /* wildcard, NSEC3 zone */
174 test_rr_lookup(bus
, ".wilda.0skar.cz", DNS_TYPE_A
, NULL
);
175 test_hostname_lookup(bus
, ".wilda.0skar.cz", AF_INET
, NULL
);
177 /* wildcard, NSEC3 zone, NODATA */
178 test_rr_lookup(bus
, ".wilda.0skar.cz", DNS_TYPE_RP
, BUS_ERROR_NO_SUCH_RR
);
180 /* wildcard, NSEC zone, CNAME */
181 test_rr_lookup(bus
, ".wild.nsec.0skar.cz", DNS_TYPE_A
, NULL
);
182 test_hostname_lookup(bus
, ".wild.nsec.0skar.cz", AF_UNSPEC
, NULL
);
183 test_hostname_lookup(bus
, ".wild.nsec.0skar.cz", AF_INET
, NULL
);
185 /* wildcard, NSEC zone, NODATA, CNAME */
186 test_rr_lookup(bus
, ".wild.nsec.0skar.cz", DNS_TYPE_RP
, BUS_ERROR_NO_SUCH_RR
);
188 /* wildcard, NSEC3 zone, CNAME */
189 test_rr_lookup(bus
, ".wild.0skar.cz", DNS_TYPE_A
, NULL
);
190 test_hostname_lookup(bus
, ".wild.0skar.cz", AF_UNSPEC
, NULL
);
191 test_hostname_lookup(bus
, ".wild.0skar.cz", AF_INET
, NULL
);
193 /* wildcard, NSEC3 zone, NODATA, CNAME */
194 test_rr_lookup(bus
, ".wild.0skar.cz", DNS_TYPE_RP
, BUS_ERROR_NO_SUCH_RR
);
196 /* NODATA due to empty non-terminal in NSEC domain */
197 test_rr_lookup(bus
, "herndon.nasa.gov", DNS_TYPE_A
, BUS_ERROR_NO_SUCH_RR
);
198 test_hostname_lookup(bus
, "herndon.nasa.gov", AF_UNSPEC
, BUS_ERROR_NO_SUCH_RR
);
199 test_hostname_lookup(bus
, "herndon.nasa.gov", AF_INET
, BUS_ERROR_NO_SUCH_RR
);
200 test_hostname_lookup(bus
, "herndon.nasa.gov", AF_INET6
, BUS_ERROR_NO_SUCH_RR
);
202 /* NXDOMAIN in NSEC root zone: */
203 test_rr_lookup(bus
, "jasdhjas.kjkfgjhfjg", DNS_TYPE_A
, _BUS_ERROR_DNS
"NXDOMAIN");
204 test_hostname_lookup(bus
, "jasdhjas.kjkfgjhfjg", AF_UNSPEC
, _BUS_ERROR_DNS
"NXDOMAIN");
205 test_hostname_lookup(bus
, "jasdhjas.kjkfgjhfjg", AF_INET
, _BUS_ERROR_DNS
"NXDOMAIN");
206 test_hostname_lookup(bus
, "jasdhjas.kjkfgjhfjg", AF_INET6
, _BUS_ERROR_DNS
"NXDOMAIN");
208 /* NXDOMAIN in NSEC3 .com zone: */
209 test_rr_lookup(bus
, "kjkfgjhfjgsdfdsfd.com", DNS_TYPE_A
, _BUS_ERROR_DNS
"NXDOMAIN");
210 test_hostname_lookup(bus
, "kjkfgjhfjgsdfdsfd.com", AF_INET
, _BUS_ERROR_DNS
"NXDOMAIN");
211 test_hostname_lookup(bus
, "kjkfgjhfjgsdfdsfd.com", AF_INET6
, _BUS_ERROR_DNS
"NXDOMAIN");
212 test_hostname_lookup(bus
, "kjkfgjhfjgsdfdsfd.com", AF_UNSPEC
, _BUS_ERROR_DNS
"NXDOMAIN");
215 test_rr_lookup(bus
, "poettering.de", DNS_TYPE_A
, NULL
);
216 test_rr_lookup(bus
, "poettering.de", DNS_TYPE_AAAA
, NULL
);
217 test_hostname_lookup(bus
, "poettering.de", AF_UNSPEC
, NULL
);
218 test_hostname_lookup(bus
, "poettering.de", AF_INET
, NULL
);
219 test_hostname_lookup(bus
, "poettering.de", AF_INET6
, NULL
);
221 #if HAVE_LIBIDN2 || HAVE_LIBIDN
222 /* Unsigned A with IDNA conversion necessary */
223 test_hostname_lookup(bus
, "pöttering.de", AF_UNSPEC
, NULL
);
224 test_hostname_lookup(bus
, "pöttering.de", AF_INET
, NULL
);
225 test_hostname_lookup(bus
, "pöttering.de", AF_INET6
, NULL
);
228 /* DNAME, pointing to NXDOMAIN */
229 test_rr_lookup(bus
, ".ireallyhpoethisdoesnexist.xn--kprw13d.", DNS_TYPE_A
, _BUS_ERROR_DNS
"NXDOMAIN");
230 test_rr_lookup(bus
, ".ireallyhpoethisdoesnexist.xn--kprw13d.", DNS_TYPE_RP
, _BUS_ERROR_DNS
"NXDOMAIN");
231 test_hostname_lookup(bus
, ".ireallyhpoethisdoesntexist.xn--kprw13d.", AF_UNSPEC
, _BUS_ERROR_DNS
"NXDOMAIN");
232 test_hostname_lookup(bus
, ".ireallyhpoethisdoesntexist.xn--kprw13d.", AF_INET
, _BUS_ERROR_DNS
"NXDOMAIN");
233 test_hostname_lookup(bus
, ".ireallyhpoethisdoesntexist.xn--kprw13d.", AF_INET6
, _BUS_ERROR_DNS
"NXDOMAIN");