1 /* Test getnetbyname and getnetbyaddr.
2 Copyright (C) 2016-2022 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19 #include <netdb.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <support/check.h>
23 #include <support/check_nss.h>
24 #include <support/resolv_test.h>
25 #include <support/support.h>
26 #include <support/xmemstream.h>
27
28 static void
send_ptr(struct resolv_response_builder * b,const char * qname,uint16_t qclass,uint16_t qtype,const char * alias)29 send_ptr (struct resolv_response_builder *b,
30 const char *qname, uint16_t qclass, uint16_t qtype,
31 const char *alias)
32 {
33 resolv_response_init (b, (struct resolv_response_flags) {});
34 resolv_response_add_question (b, qname, qclass, qtype);
35 resolv_response_section (b, ns_s_an);
36 resolv_response_open_record (b, qname, qclass, T_PTR, 0);
37 resolv_response_add_name (b, alias);
38 resolv_response_close_record (b);
39 }
40
41 static void
handle_code(const struct resolv_response_context * ctx,struct resolv_response_builder * b,const char * qname,uint16_t qclass,uint16_t qtype,int code)42 handle_code (const struct resolv_response_context *ctx,
43 struct resolv_response_builder *b,
44 const char *qname, uint16_t qclass, uint16_t qtype,
45 int code)
46 {
47 switch (code)
48 {
49 case 1:
50 send_ptr (b, qname, qclass, qtype, "1.in-addr.arpa");
51 break;
52 case 2:
53 send_ptr (b, qname, qclass, qtype, "2.1.in-addr.arpa");
54 break;
55 case 3:
56 send_ptr (b, qname, qclass, qtype, "3.2.1.in-addr.arpa");
57 break;
58 case 4:
59 send_ptr (b, qname, qclass, qtype, "4.3.2.1.in-addr.arpa");
60 break;
61 case 5:
62 /* Test multiple PTR records. */
63 resolv_response_init (b, (struct resolv_response_flags) {});
64 resolv_response_add_question (b, qname, qclass, qtype);
65 resolv_response_section (b, ns_s_an);
66 resolv_response_open_record (b, qname, qclass, T_PTR, 0);
67 resolv_response_add_name (b, "127.in-addr.arpa");
68 resolv_response_close_record (b);
69 resolv_response_open_record (b, qname, qclass, T_PTR, 0);
70 resolv_response_add_name (b, "0.in-addr.arpa");
71 resolv_response_close_record (b);
72 break;
73 case 6:
74 /* Test skipping of RRSIG record. */
75 resolv_response_init (b, (struct resolv_response_flags) { });
76 resolv_response_add_question (b, qname, qclass, qtype);
77 resolv_response_section (b, ns_s_an);
78
79 resolv_response_open_record (b, qname, qclass, T_PTR, 0);
80 resolv_response_add_name (b, "127.in-addr.arpa");
81 resolv_response_close_record (b);
82
83 resolv_response_open_record (b, qname, qclass, 46 /* RRSIG */, 0);
84 {
85 char buf[500];
86 memset (buf, 0x3f, sizeof (buf));
87 resolv_response_add_data (b, buf, sizeof (buf));
88 }
89 resolv_response_close_record (b);
90
91 resolv_response_open_record (b, qname, qclass, T_PTR, 0);
92 resolv_response_add_name (b, "0.in-addr.arpa");
93 resolv_response_close_record (b);
94 break;
95 case 7:
96 /* Test CNAME handling. */
97 resolv_response_init (b, (struct resolv_response_flags) { });
98 resolv_response_add_question (b, qname, qclass, qtype);
99 resolv_response_section (b, ns_s_an);
100 resolv_response_open_record (b, qname, qclass, T_CNAME, 0);
101 resolv_response_add_name (b, "cname.example");
102 resolv_response_close_record (b);
103 resolv_response_open_record (b, "cname.example", qclass, T_PTR, 0);
104 resolv_response_add_name (b, "4.3.2.1.in-addr.arpa");
105 resolv_response_close_record (b);
106 break;
107
108 case 100:
109 resolv_response_init (b, (struct resolv_response_flags) { .rcode = 0, });
110 resolv_response_add_question (b, qname, qclass, qtype);
111 break;
112 case 101:
113 resolv_response_init (b, (struct resolv_response_flags)
114 { .rcode = NXDOMAIN, });
115 resolv_response_add_question (b, qname, qclass, qtype);
116 break;
117 case 102:
118 resolv_response_init (b, (struct resolv_response_flags) {.rcode = SERVFAIL});
119 resolv_response_add_question (b, qname, qclass, qtype);
120 break;
121 case 103:
122 /* Check response length matching. */
123 if (!ctx->tcp)
124 {
125 resolv_response_init (b, (struct resolv_response_flags) {.tc = true});
126 resolv_response_add_question (b, qname, qclass, qtype);
127 }
128 else
129 {
130 resolv_response_init (b, (struct resolv_response_flags) {.ancount = 1});
131 resolv_response_add_question (b, qname, qclass, qtype);
132 resolv_response_section (b, ns_s_an);
133 resolv_response_open_record (b, qname, qclass, T_PTR, 0);
134 resolv_response_add_name (b, "127.in-addr.arpa");
135 resolv_response_close_record (b);
136 resolv_response_open_record (b, qname, qclass, T_PTR, 0);
137 resolv_response_add_name (b, "example");
138 resolv_response_close_record (b);
139
140 resolv_response_open_record (b, qname, qclass, T_PTR, 0);
141 size_t to_fill = 65535 - resolv_response_length (b)
142 - 2 /* length, "n" */ - 2 /* compression reference */
143 - 2 /* RR type */;
144 for (size_t i = 0; i < to_fill; ++i)
145 resolv_response_add_data (b, "", 1);
146 resolv_response_close_record (b);
147 resolv_response_add_name (b, "n.example");
148 uint16_t rrtype = htons (T_PTR);
149 resolv_response_add_data (b, &rrtype, sizeof (rrtype));
150 }
151 break;
152 case 104:
153 send_ptr (b, qname, qclass, qtype, "host.example");
154 break;
155 default:
156 FAIL_EXIT1 ("invalid QNAME: %s (code %d)", qname, code);
157 }
158 }
159
160 static void
response(const struct resolv_response_context * ctx,struct resolv_response_builder * b,const char * qname,uint16_t qclass,uint16_t qtype)161 response (const struct resolv_response_context *ctx,
162 struct resolv_response_builder *b,
163 const char *qname, uint16_t qclass, uint16_t qtype)
164 {
165 int code;
166 if (strstr (qname, "in-addr.arpa") == NULL)
167 {
168 char *tail;
169 if (sscanf (qname, "code%d.%ms", &code, &tail) != 2
170 || strcmp (tail, "example") != 0)
171 FAIL_EXIT1 ("invalid QNAME: %s", qname);
172 free (tail);
173 handle_code (ctx, b, qname, qclass, qtype, code);
174 }
175 else
176 {
177 /* Reverse lookup. */
178 int components[4];
179 char *tail;
180 if (sscanf (qname, "%d.%d.%d.%d.%ms",
181 components, components + 1, components + 2, components + 3,
182 &tail) != 5
183 || strcmp (tail, "in-addr.arpa") != 0)
184 FAIL_EXIT1 ("invalid QNAME: %s", qname);
185 free (tail);
186 handle_code (ctx, b, qname, qclass, qtype, components[3]);
187 }
188 }
189
190 static void
check_reverse(int code,const char * expected)191 check_reverse (int code, const char *expected)
192 {
193 char *query = xasprintf ("code=%d", code);
194 check_netent (query, getnetbyaddr (code, AF_INET), expected);
195 free (query);
196 }
197
198 /* Test for CVE-2016-3075. */
199 static void
check_long_name(void)200 check_long_name (void)
201 {
202 struct xmemstream mem;
203 xopen_memstream (&mem);
204
205 char label[65];
206 memset (label, 'x', 63);
207 label[63] = '.';
208 label[64] = '\0';
209 for (unsigned i = 0; i < 64 * 1024 * 1024 / strlen (label); ++i)
210 fprintf (mem.out, "%s", label);
211
212 xfclose_memstream (&mem);
213
214 check_netent ("long name", getnetbyname (mem.buffer),
215 "error: NO_RECOVERY\n");
216
217 free (mem.buffer);
218 }
219
220 static int
do_test(void)221 do_test (void)
222 {
223 struct resolv_test *obj = resolv_test_start
224 ((struct resolv_redirect_config)
225 {
226 .response_callback = response
227 });
228
229 /* Lookup by name, success cases. */
230 check_netent ("code1.example", getnetbyname ("code1.example"),
231 "alias: 1.in-addr.arpa\n"
232 "net: 0x00000001\n");
233 check_netent ("code2.example", getnetbyname ("code2.example"),
234 "alias: 2.1.in-addr.arpa\n"
235 "net: 0x00000102\n");
236 check_netent ("code3.example", getnetbyname ("code3.example"),
237 "alias: 3.2.1.in-addr.arpa\n"
238 "net: 0x00010203\n");
239 check_netent ("code4.example", getnetbyname ("code4.example"),
240 "alias: 4.3.2.1.in-addr.arpa\n"
241 "net: 0x01020304\n");
242 check_netent ("code5.example", getnetbyname ("code5.example"),
243 "alias: 127.in-addr.arpa\n"
244 "alias: 0.in-addr.arpa\n"
245 "net: 0x0000007f\n");
246 check_netent ("code6.example", getnetbyname ("code6.example"),
247 "alias: 127.in-addr.arpa\n"
248 "alias: 0.in-addr.arpa\n"
249 "net: 0x0000007f\n");
250 check_netent ("code7.example", getnetbyname ("code7.example"),
251 "alias: 4.3.2.1.in-addr.arpa\n"
252 "net: 0x01020304\n");
253
254 /* Lookup by name, failure cases. */
255 check_netent ("code100.example", getnetbyname ("code100.example"),
256 "error: NO_ADDRESS\n");
257 check_netent ("code101.example", getnetbyname ("code101.example"),
258 "error: HOST_NOT_FOUND\n");
259 check_netent ("code102.example", getnetbyname ("code102.example"),
260 "error: TRY_AGAIN\n");
261 check_netent ("code103.example", getnetbyname ("code103.example"),
262 "error: NO_RECOVERY\n");
263 /* Test bug #17630. */
264 check_netent ("code104.example", getnetbyname ("code104.example"),
265 "error: TRY_AGAIN\n");
266
267 /* Lookup by address, success cases. */
268 check_reverse (1,
269 "name: 1.in-addr.arpa\n"
270 "net: 0x00000001\n");
271 check_reverse (2,
272 "name: 2.1.in-addr.arpa\n"
273 "net: 0x00000002\n");
274 check_reverse (3,
275 "name: 3.2.1.in-addr.arpa\n"
276 "net: 0x00000003\n");
277 check_reverse (4,
278 "name: 4.3.2.1.in-addr.arpa\n"
279 "net: 0x00000004\n");
280 check_reverse (5,
281 "name: 127.in-addr.arpa\n"
282 "alias: 0.in-addr.arpa\n"
283 "net: 0x00000005\n");
284 check_reverse (6,
285 "name: 127.in-addr.arpa\n"
286 "alias: 0.in-addr.arpa\n"
287 "net: 0x00000006\n");
288 check_reverse (7,
289 "name: 4.3.2.1.in-addr.arpa\n"
290 "net: 0x00000007\n");
291
292 /* Lookup by address, failure cases. */
293 check_reverse (100,
294 "error: NO_ADDRESS\n");
295 check_reverse (101,
296 "error: HOST_NOT_FOUND\n");
297 check_reverse (102,
298 "error: TRY_AGAIN\n");
299 check_reverse (103,
300 "error: NO_RECOVERY\n");
301
302 check_long_name ();
303
304 resolv_test_end (obj);
305
306 return 0;
307 }
308
309 #include <support/test-driver.c>
310