1 /* Test the behavior of the trust-ad option.
2 Copyright (C) 2019-2022 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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.
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.
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/>. */
22 #include <support/check.h>
23 #include <support/check_nss.h>
24 #include <support/resolv_test.h>
25 #include <support/support.h>
27 /* This controls properties of the response. volatile because
28 __res_send is incorrectly declared as __THROW. */
29 static volatile unsigned char response_number
;
30 static volatile bool response_ad_bit
;
31 static volatile bool query_ad_bit
;
34 response (const struct resolv_response_context
*ctx
,
35 struct resolv_response_builder
*b
,
36 const char *qname
, uint16_t qclass
, uint16_t qtype
)
38 TEST_COMPARE (qclass
, C_IN
);
39 TEST_COMPARE (qtype
, T_A
);
40 TEST_COMPARE_STRING (qname
, "www.example");
43 memcpy (&header
, ctx
->query_buffer
, sizeof (header
));
44 TEST_COMPARE (header
.ad
, query_ad_bit
);
46 struct resolv_response_flags flags
= { .ad
= response_ad_bit
, };
47 resolv_response_init (b
, flags
);
48 resolv_response_add_question (b
, qname
, qclass
, qtype
);
49 resolv_response_section (b
, ns_s_an
);
50 resolv_response_open_record (b
, qname
, qclass
, T_A
, 0x12345678);
51 char addr
[4] = { 192, 0, 2, response_number
};
52 resolv_response_add_data (b
, addr
, sizeof (addr
));
53 resolv_response_close_record (b
);
57 check_answer (const unsigned char *buffer
, size_t buffer_length
,
61 TEST_VERIFY (buffer_length
> sizeof (header
));
62 memcpy (&header
, buffer
, sizeof (header
));
63 TEST_COMPARE (0, header
.aa
);
64 TEST_COMPARE (expected_ad
, header
.ad
);
65 TEST_COMPARE (0, header
.opcode
);
66 TEST_COMPARE (1, header
.qr
);
67 TEST_COMPARE (0, header
.rcode
);
68 TEST_COMPARE (1, header
.rd
);
69 TEST_COMPARE (0, header
.tc
);
70 TEST_COMPARE (1, ntohs (header
.qdcount
));
71 TEST_COMPARE (1, ntohs (header
.ancount
));
72 TEST_COMPARE (0, ntohs (header
.nscount
));
73 TEST_COMPARE (0, ntohs (header
.arcount
));
75 char *description
= xasprintf ("response=%d ad=%d",
76 response_number
, expected_ad
);
77 char *expected
= xasprintf ("name: www.example\n"
78 "address: 192.0.2.%d\n", response_number
);
79 check_dns_packet (description
, buffer
, buffer_length
, expected
);
87 struct resolv_test
*aux
= resolv_test_start
88 ((struct resolv_redirect_config
)
90 .response_callback
= response
,
93 /* By default, the resolver is not trusted, and the AD bit is
96 static const unsigned char hand_crafted_query
[] =
98 10, 11, /* Transaction ID. */
99 1, 0x20, /* Query with RD, AD flags. */
100 0, 1, /* One question. */
101 0, 0, 0, 0, 0, 0, /* The other sections are empty. */
102 3, 'w', 'w', 'w', 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 0,
103 0, T_A
, /* A query. */
104 0, 1, /* Class IN. */
108 response_ad_bit
= false;
110 unsigned char buffer
[512];
111 memset (buffer
, 255, sizeof (buffer
));
113 int ret
= res_send (hand_crafted_query
, sizeof (hand_crafted_query
),
114 buffer
, sizeof (buffer
));
115 TEST_VERIFY (ret
> 0);
116 check_answer (buffer
, ret
, false);
119 memset (buffer
, 255, sizeof (buffer
));
120 query_ad_bit
= false;
121 ret
= res_query ("www.example", C_IN
, T_A
, buffer
, sizeof (buffer
));
122 TEST_VERIFY (ret
> 0);
123 check_answer (buffer
, ret
, false);
124 response_ad_bit
= true;
126 response_ad_bit
= true;
130 ret
= res_send (hand_crafted_query
, sizeof (hand_crafted_query
),
131 buffer
, sizeof (buffer
));
132 TEST_VERIFY (ret
> 0);
133 check_answer (buffer
, ret
, false);
136 memset (buffer
, 255, sizeof (buffer
));
137 query_ad_bit
= false;
138 ret
= res_query ("www.example", C_IN
, T_A
, buffer
, sizeof (buffer
));
139 TEST_VERIFY (ret
> 0);
140 check_answer (buffer
, ret
, false);
142 /* No AD bit set in generated queries. */
143 memset (buffer
, 255, sizeof (buffer
));
144 ret
= res_mkquery (QUERY
, "www.example", C_IN
, T_A
,
145 (const unsigned char *) "", 0, NULL
,
146 buffer
, sizeof (buffer
));
148 memcpy (&header
, buffer
, sizeof (header
));
149 TEST_VERIFY (!header
.ad
);
151 /* With RES_TRUSTAD, the AD bit is passed through if it set in the
152 response. It is also included in queries. */
154 _res
.options
|= RES_TRUSTAD
;
157 response_ad_bit
= false;
160 memset (buffer
, 255, sizeof (buffer
));
161 ret
= res_send (hand_crafted_query
, sizeof (hand_crafted_query
),
162 buffer
, sizeof (buffer
));
163 TEST_VERIFY (ret
> 0);
164 check_answer (buffer
, ret
, false);
167 memset (buffer
, 255, sizeof (buffer
));
168 ret
= res_query ("www.example", C_IN
, T_A
, buffer
, sizeof (buffer
));
169 TEST_VERIFY (ret
> 0);
170 check_answer (buffer
, ret
, false);
172 response_ad_bit
= true;
175 memset (buffer
, 0, sizeof (buffer
));
176 ret
= res_send (hand_crafted_query
, sizeof (hand_crafted_query
),
177 buffer
, sizeof (buffer
));
178 TEST_VERIFY (ret
> 0);
179 check_answer (buffer
, ret
, true);
182 memset (buffer
, 0, sizeof (buffer
));
183 ret
= res_query ("www.example", C_IN
, T_A
, buffer
, sizeof (buffer
));
184 TEST_VERIFY (ret
> 0);
185 check_answer (buffer
, ret
, true);
187 /* AD bit set in generated queries. */
188 memset (buffer
, 0, sizeof (buffer
));
189 ret
= res_mkquery (QUERY
, "www.example", C_IN
, T_A
,
190 (const unsigned char *) "", 0, NULL
,
191 buffer
, sizeof (buffer
));
192 memcpy (&header
, buffer
, sizeof (header
));
193 TEST_VERIFY (header
.ad
);
195 resolv_test_end (aux
);
200 #include <support/test-driver.c>