chiark / gitweb /
resolved: never attempt to resolve loopback addresses via DNS/LLMNR/mDNS
[elogind.git] / src / test / test-dns-domain.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2014 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
22 #include "macro.h"
23 #include "dns-domain.h"
24
25 static void test_dns_label_unescape_one(const char *what, const char *expect, size_t buffer_sz, int ret) {
26         char buffer[buffer_sz];
27         int r;
28
29         r = dns_label_unescape(&what, buffer, buffer_sz);
30         assert_se(r == ret);
31
32         if (r < 0)
33                 return;
34
35         assert_se(streq(buffer, expect));
36 }
37
38 static void test_dns_label_unescape(void) {
39         test_dns_label_unescape_one("hallo", "hallo", 6, 5);
40         test_dns_label_unescape_one("hallo", "hallo", 4, -ENOSPC);
41         test_dns_label_unescape_one("", "", 10, 0);
42         test_dns_label_unescape_one("hallo\\.foobar", "hallo.foobar", 20, 12);
43         test_dns_label_unescape_one("hallo.foobar", "hallo", 10, 5);
44         test_dns_label_unescape_one("hallo\n.foobar", "hallo", 20, -EINVAL);
45         test_dns_label_unescape_one("hallo\\", "hallo", 20, -EINVAL);
46         test_dns_label_unescape_one("hallo\\032 ", "hallo  ", 20, 7);
47         test_dns_label_unescape_one(".", "", 20, 0);
48         test_dns_label_unescape_one("..", "", 20, -EINVAL);
49         test_dns_label_unescape_one(".foobar", "", 20, -EINVAL);
50         test_dns_label_unescape_one("foobar.", "foobar", 20, 6);
51 }
52
53 static void test_dns_label_unescape_suffix_one(const char *what, const char *expect1, const char *expect2, size_t buffer_sz, int ret1, int ret2) {
54         char buffer[buffer_sz];
55         const char *label;
56         int r;
57
58         label = what + strlen(what);
59
60         r = dns_label_unescape_suffix(what, &label, buffer, buffer_sz);
61         assert_se(r == ret1);
62         if (r >= 0)
63                 assert_se(streq(buffer, expect1));
64
65         r = dns_label_unescape_suffix(what, &label, buffer, buffer_sz);
66         assert_se(r == ret2);
67         if (r >= 0)
68                 assert_se(streq(buffer, expect2));
69 }
70
71 static void test_dns_label_unescape_suffix(void) {
72         test_dns_label_unescape_suffix_one("hallo", "hallo", "", 6, 5, 0);
73         test_dns_label_unescape_suffix_one("hallo", "hallo", "", 4, -ENOSPC, -ENOSPC);
74         test_dns_label_unescape_suffix_one("", "", "", 10, 0, 0);
75         test_dns_label_unescape_suffix_one("hallo\\.foobar", "hallo.foobar", "", 20, 12, 0);
76         test_dns_label_unescape_suffix_one("hallo.foobar", "foobar", "hallo", 10, 6, 5);
77         test_dns_label_unescape_suffix_one("hallo.foobar\n", "foobar", "foobar", 20, -EINVAL, -EINVAL);
78         test_dns_label_unescape_suffix_one("hallo\\", "hallo", "hallo", 20, -EINVAL, -EINVAL);
79         test_dns_label_unescape_suffix_one("hallo\\032 ", "hallo  ", "", 20, 7, 0);
80         test_dns_label_unescape_suffix_one(".", "", "", 20, 0, 0);
81         test_dns_label_unescape_suffix_one("..", "", "", 20, 0, 0);
82         test_dns_label_unescape_suffix_one(".foobar", "foobar", "", 20, 6, -EINVAL);
83         test_dns_label_unescape_suffix_one("foobar.", "", "foobar", 20, 0, 6);
84         test_dns_label_unescape_suffix_one("foo\\\\bar", "foo\\bar", "", 20, 7, 0);
85         test_dns_label_unescape_suffix_one("foo.bar", "bar", "foo", 20, 3, 3);
86         test_dns_label_unescape_suffix_one("foo..bar", "bar", "", 20, 3, -EINVAL);
87         test_dns_label_unescape_suffix_one("foo...bar", "bar", "", 20, 3, -EINVAL);
88         test_dns_label_unescape_suffix_one("foo\\.bar", "foo.bar", "", 20, 7, 0);
89         test_dns_label_unescape_suffix_one("foo\\\\.bar", "bar", "foo\\", 20, 3, 4);
90         test_dns_label_unescape_suffix_one("foo\\\\\\.bar", "foo\\.bar", "", 20, 8, 0);
91 }
92
93 static void test_dns_label_escape_one(const char *what, size_t l, const char *expect, int ret) {
94         _cleanup_free_ char *t = NULL;
95         int r;
96
97         r = dns_label_escape(what, l, &t);
98         assert_se(r == ret);
99
100         if (r < 0)
101                 return;
102
103         assert_se(streq_ptr(expect, t));
104 }
105
106 static void test_dns_label_escape(void) {
107         test_dns_label_escape_one("", 0, "", 0);
108         test_dns_label_escape_one("hallo", 5, "hallo", 5);
109         test_dns_label_escape_one("hallo", 6, NULL, -EINVAL);
110         test_dns_label_escape_one("hallo hallo.foobar,waldi", 24, "hallo\\032hallo\\.foobar\\044waldi", 31);
111 }
112
113 static void test_dns_name_normalize_one(const char *what, const char *expect, int ret) {
114         _cleanup_free_ char *t = NULL;
115         int r;
116
117         r = dns_name_normalize(what, &t);
118         assert_se(r == ret);
119
120         if (r < 0)
121                 return;
122
123         assert_se(streq_ptr(expect, t));
124 }
125
126 static void test_dns_name_normalize(void) {
127         test_dns_name_normalize_one("", "", 0);
128         test_dns_name_normalize_one("f", "f", 0);
129         test_dns_name_normalize_one("f.waldi", "f.waldi", 0);
130         test_dns_name_normalize_one("f \\032.waldi", "f\\032\\032.waldi", 0);
131         test_dns_name_normalize_one("\\000", NULL, -EINVAL);
132         test_dns_name_normalize_one("..", NULL, -EINVAL);
133         test_dns_name_normalize_one(".foobar", NULL, -EINVAL);
134         test_dns_name_normalize_one("foobar.", "foobar", 0);
135         test_dns_name_normalize_one(".", "", 0);
136 }
137
138 static void test_dns_name_equal_one(const char *a, const char *b, int ret) {
139         int r;
140
141         r = dns_name_equal(a, b);
142         assert_se(r == ret);
143
144         r = dns_name_equal(b, a);
145         assert_se(r == ret);
146 }
147
148 static void test_dns_name_equal(void) {
149         test_dns_name_equal_one("", "", true);
150         test_dns_name_equal_one("x", "x", true);
151         test_dns_name_equal_one("x", "x.", true);
152         test_dns_name_equal_one("abc.def", "abc.def", true);
153         test_dns_name_equal_one("abc.def", "ABC.def", true);
154         test_dns_name_equal_one("abc.def", "CBA.def", false);
155         test_dns_name_equal_one("", "xxx", false);
156         test_dns_name_equal_one("ab", "a", false);
157         test_dns_name_equal_one("\\000", "xxxx", -EINVAL);
158         test_dns_name_equal_one(".", "", true);
159         test_dns_name_equal_one(".", ".", true);
160         test_dns_name_equal_one("..", "..", -EINVAL);
161 }
162
163 static void test_dns_name_between_one(const char *a, const char *b, const char *c, int ret) {
164         int r;
165
166         r = dns_name_between(a, b, c);
167         assert_se(r == ret);
168
169         r = dns_name_between(c, b, a);
170         if (ret >= 0)
171                 assert_se(r == 0);
172         else
173                 assert_se(r == ret);
174 }
175
176 static void test_dns_name_between(void) {
177         /* see https://tools.ietf.org/html/rfc4034#section-6.1
178            Note that we use "\033.z.example" in stead of "\001.z.example" as we
179            consider the latter invalid */
180         test_dns_name_between_one("example", "a.example", "yljkjljk.a.example", true);
181         test_dns_name_between_one("a.example", "yljkjljk.a.example", "Z.a.example", true);
182         test_dns_name_between_one("yljkjljk.a.example", "Z.a.example", "zABC.a.EXAMPLE", true);
183         test_dns_name_between_one("Z.a.example", "zABC.a.EXAMPLE", "z.example", true);
184         test_dns_name_between_one("zABC.a.EXAMPLE", "z.example", "\\033.z.example", true);
185         test_dns_name_between_one("z.example", "\\033.z.example", "*.z.example", true);
186         test_dns_name_between_one("\\033.z.example", "*.z.example", "\\200.z.example", true);
187         test_dns_name_between_one("*.z.example", "\\200.z.example", "example", true);
188         test_dns_name_between_one("\\200.z.example", "example", "a.example", true);
189
190         test_dns_name_between_one("example", "a.example", "example", -EINVAL);
191         test_dns_name_between_one("example", "example", "yljkjljk.a.example", false);
192         test_dns_name_between_one("example", "yljkjljk.a.example", "yljkjljk.a.example", false);
193 }
194
195 static void test_dns_name_endswith_one(const char *a, const char *b, int ret) {
196         assert_se(dns_name_endswith(a, b) == ret);
197 }
198
199 static void test_dns_name_endswith(void) {
200         test_dns_name_endswith_one("", "", true);
201         test_dns_name_endswith_one("", "xxx", false);
202         test_dns_name_endswith_one("xxx", "", true);
203         test_dns_name_endswith_one("x", "x", true);
204         test_dns_name_endswith_one("x", "y", false);
205         test_dns_name_endswith_one("x.y", "y", true);
206         test_dns_name_endswith_one("x.y", "Y", true);
207         test_dns_name_endswith_one("x.y", "x", false);
208         test_dns_name_endswith_one("x.y.z", "Z", true);
209         test_dns_name_endswith_one("x.y.z", "y.Z", true);
210         test_dns_name_endswith_one("x.y.z", "x.y.Z", true);
211         test_dns_name_endswith_one("x.y.z", "waldo", false);
212         test_dns_name_endswith_one("x.y.z.u.v.w", "y.z", false);
213         test_dns_name_endswith_one("x.y.z.u.v.w", "u.v.w", true);
214         test_dns_name_endswith_one("x.y\001.z", "waldo", -EINVAL);
215 }
216
217 static void test_dns_name_root(void) {
218         assert_se(dns_name_root("") == true);
219         assert_se(dns_name_root(".") == true);
220         assert_se(dns_name_root("xxx") == false);
221         assert_se(dns_name_root("xxx.") == false);
222         assert_se(dns_name_root("..") == -EINVAL);
223 }
224
225 static void test_dns_name_single_label(void) {
226         assert_se(dns_name_single_label("") == false);
227         assert_se(dns_name_single_label(".") == false);
228         assert_se(dns_name_single_label("..") == -EINVAL);
229         assert_se(dns_name_single_label("x") == true);
230         assert_se(dns_name_single_label("x.") == true);
231         assert_se(dns_name_single_label("xx.yy") == false);
232 }
233
234 static void test_dns_name_reverse_one(const char *address, const char *name) {
235         _cleanup_free_ char *p = NULL;
236         union in_addr_union a, b = {};
237         int familya, familyb;
238
239         assert_se(in_addr_from_string_auto(address, &familya, &a) >= 0);
240         assert_se(dns_name_reverse(familya, &a, &p) >= 0);
241         assert_se(streq(p, name));
242         assert_se(dns_name_address(p, &familyb, &b) > 0);
243         assert_se(familya == familyb);
244         assert_se(in_addr_equal(familya, &a, &b));
245 }
246
247 static void test_dns_name_reverse(void) {
248         test_dns_name_reverse_one("47.11.8.15", "15.8.11.47.in-addr.arpa");
249         test_dns_name_reverse_one("fe80::47", "7.4.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.e.f.ip6.arpa");
250         test_dns_name_reverse_one("127.0.0.1", "1.0.0.127.in-addr.arpa");
251         test_dns_name_reverse_one("::1", "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa");
252 }
253
254 int main(int argc, char *argv[]) {
255
256         test_dns_label_unescape();
257         test_dns_label_unescape_suffix();
258         test_dns_label_escape();
259         test_dns_name_normalize();
260         test_dns_name_equal();
261         test_dns_name_endswith();
262         test_dns_name_between();
263         test_dns_name_root();
264         test_dns_name_single_label();
265         test_dns_name_reverse();
266
267         return 0;
268 }