1 // Copyright 2021 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/dns/public/dns_over_https_server_config.h"
6
7 #include <string>
8 #include <string_view>
9
10 #include "base/json/json_reader.h"
11 #include "net/base/ip_address.h"
12 #include "net/dns/public/dns_over_https_config.h"
13 #include "testing/gmock/include/gmock/gmock.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace net {
17 namespace {
18
19 const IPAddress ip1(192, 0, 2, 1);
20 const IPAddress ip2(0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
21 const IPAddress ip3(192, 0, 2, 2);
22 const IPAddress ip4(0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2);
23 const DnsOverHttpsServerConfig::Endpoints endpoints{{ip1, ip2}, {ip3, ip4}};
24
TEST(DnsOverHttpsServerConfigTest,ValidWithGet)25 TEST(DnsOverHttpsServerConfigTest, ValidWithGet) {
26 auto parsed = DnsOverHttpsServerConfig::FromString(
27 "https://dnsserver.example.net/dns-query{?dns}");
28 EXPECT_THAT(parsed, testing::Optional(testing::Property(
29 &DnsOverHttpsServerConfig::use_post, false)));
30
31 parsed = DnsOverHttpsServerConfig::FromString(
32 "https://dnsserver.example.net/dns-query{?dns,extra}");
33 EXPECT_THAT(parsed, testing::Optional(testing::Property(
34 &DnsOverHttpsServerConfig::use_post, false)));
35
36 parsed = DnsOverHttpsServerConfig::FromString(
37 "https://query:{dns}@dnsserver.example.net");
38 EXPECT_THAT(parsed, testing::Optional(testing::Property(
39 &DnsOverHttpsServerConfig::use_post, false)));
40
41 parsed = DnsOverHttpsServerConfig::FromString(
42 "https://dnsserver.example.net{/dns}");
43 EXPECT_THAT(parsed, testing::Optional(testing::Property(
44 &DnsOverHttpsServerConfig::use_post, false)));
45 }
46
TEST(DnsOverHttpsServerConfigTest,ValidWithPost)47 TEST(DnsOverHttpsServerConfigTest, ValidWithPost) {
48 auto parsed = DnsOverHttpsServerConfig::FromString(
49 "https://dnsserver.example.net/dns-query{?query}");
50 EXPECT_THAT(parsed, testing::Optional(testing::Property(
51 &DnsOverHttpsServerConfig::use_post, true)));
52
53 parsed = DnsOverHttpsServerConfig::FromString(
54 "https://dnsserver.example.net/dns-query");
55 EXPECT_THAT(parsed, testing::Optional(testing::Property(
56 &DnsOverHttpsServerConfig::use_post, true)));
57 }
58
TEST(DnsOverHttpsServerConfigTest,Invalid)59 TEST(DnsOverHttpsServerConfigTest, Invalid) {
60 // Invalid template format
61 EXPECT_FALSE(DnsOverHttpsServerConfig::FromString(
62 "https://dnsserver.example.net/dns-query{{?dns}}"));
63 // Must be HTTPS
64 EXPECT_FALSE(DnsOverHttpsServerConfig::FromString(
65 "http://dnsserver.example.net/dns-query"));
66 EXPECT_FALSE(DnsOverHttpsServerConfig::FromString(
67 "http://dnsserver.example.net/dns-query{?dns}"));
68 // Template must expand to a valid URL
69 EXPECT_FALSE(DnsOverHttpsServerConfig::FromString("https://{?dns}"));
70 // The hostname must not contain the dns variable
71 EXPECT_FALSE(
72 DnsOverHttpsServerConfig::FromString("https://{dns}.dnsserver.net"));
73 }
74
TEST(DnsOverHttpsServerConfigTest,Empty)75 TEST(DnsOverHttpsServerConfigTest, Empty) {
76 EXPECT_FALSE(net::DnsOverHttpsServerConfig::FromString(""));
77 }
78
TEST(DnsOverHttpsServerConfigTest,Simple)79 TEST(DnsOverHttpsServerConfigTest, Simple) {
80 auto parsed = DnsOverHttpsServerConfig::FromString(
81 "https://dnsserver.example.net/dns-query{?dns}");
82 EXPECT_THAT(parsed, testing::Optional(testing::Property(
83 &DnsOverHttpsServerConfig::IsSimple, true)));
84 }
85
TEST(DnsOverHttpsServerConfigTest,ToValueSimple)86 TEST(DnsOverHttpsServerConfigTest, ToValueSimple) {
87 auto parsed = DnsOverHttpsServerConfig::FromString(
88 "https://dnsserver.example.net/dns-query{?dns}");
89 ASSERT_TRUE(parsed);
90
91 base::Value expected = *base::JSONReader::Read(R"(
92 {
93 "template": "https://dnsserver.example.net/dns-query{?dns}"
94 }
95 )");
96 EXPECT_EQ(expected.GetDict(), parsed->ToValue());
97 }
98
TEST(DnsOverHttpsServerConfigTest,ToValueWithEndpoints)99 TEST(DnsOverHttpsServerConfigTest, ToValueWithEndpoints) {
100 auto parsed = DnsOverHttpsServerConfig::FromString(
101 "https://dnsserver.example.net/dns-query{?dns}", endpoints);
102 ASSERT_TRUE(parsed);
103
104 EXPECT_THAT(parsed, testing::Optional(testing::Property(
105 &DnsOverHttpsServerConfig::IsSimple, false)));
106 EXPECT_THAT(parsed, testing::Optional(testing::Property(
107 &DnsOverHttpsServerConfig::endpoints, endpoints)));
108
109 base::Value expected = *base::JSONReader::Read(
110 R"({
111 "template": "https://dnsserver.example.net/dns-query{?dns}",
112 "endpoints": [{
113 "ips": ["192.0.2.1", "2001:db8::1"]
114 }, {
115 "ips": ["192.0.2.2", "2001:db8::2"]
116 }]
117 })");
118 EXPECT_EQ(expected.GetDict(), parsed->ToValue());
119 }
120
TEST(DnsOverHttpsServerConfigTest,FromValueSimple)121 TEST(DnsOverHttpsServerConfigTest, FromValueSimple) {
122 base::Value input = *base::JSONReader::Read(R"(
123 {
124 "template": "https://dnsserver.example.net/dns-query{?dns}"
125 }
126 )");
127
128 auto parsed =
129 DnsOverHttpsServerConfig::FromValue(std::move(input).TakeDict());
130
131 auto expected = DnsOverHttpsServerConfig::FromString(
132 "https://dnsserver.example.net/dns-query{?dns}");
133 EXPECT_EQ(expected, parsed);
134 }
135
TEST(DnsOverHttpsServerConfigTest,FromValueWithEndpoints)136 TEST(DnsOverHttpsServerConfigTest, FromValueWithEndpoints) {
137 base::Value input = *base::JSONReader::Read(R"(
138 {
139 "template": "https://dnsserver.example.net/dns-query{?dns}",
140 "endpoints": [{
141 "ips": ["192.0.2.1", "2001:db8::1"]
142 }, {
143 "ips": ["192.0.2.2", "2001:db8::2"]
144 }]
145 }
146 )");
147
148 auto parsed =
149 DnsOverHttpsServerConfig::FromValue(std::move(input).TakeDict());
150
151 auto expected = DnsOverHttpsServerConfig::FromString(
152 "https://dnsserver.example.net/dns-query{?dns}", endpoints);
153 EXPECT_EQ(expected, parsed);
154 }
155
TEST(DnsOverHttpsServerConfigTest,FromValueWithUnknownKey)156 TEST(DnsOverHttpsServerConfigTest, FromValueWithUnknownKey) {
157 base::Value input = *base::JSONReader::Read(R"(
158 {
159 "template": "https://dnsserver.example.net/dns-query{?dns}",
160 "unknown key": "value is ignored"
161 }
162 )");
163
164 auto parsed =
165 DnsOverHttpsServerConfig::FromValue(std::move(input).TakeDict());
166
167 auto expected = DnsOverHttpsServerConfig::FromString(
168 "https://dnsserver.example.net/dns-query{?dns}");
169 EXPECT_EQ(expected, parsed);
170 }
171
TEST(DnsOverHttpsServerConfigTest,FromValueInvalid)172 TEST(DnsOverHttpsServerConfigTest, FromValueInvalid) {
173 // Empty dict
174 EXPECT_FALSE(DnsOverHttpsServerConfig::FromValue(base::Value::Dict()));
175
176 // Wrong scheme
177 std::string_view input = R"(
178 {
179 "template": "http://dnsserver.example.net/dns-query{?dns}"
180 }
181 )";
182 EXPECT_FALSE(DnsOverHttpsServerConfig::FromValue(
183 std::move(base::JSONReader::Read(input)->GetDict())));
184
185 // Wrong template type
186 input = R"({"template": 12345})";
187 EXPECT_FALSE(DnsOverHttpsServerConfig::FromValue(
188 std::move(base::JSONReader::Read(input)->GetDict())));
189
190 // Wrong endpoints type
191 input = R"(
192 {
193 "template": "https://dnsserver.example.net/dns-query{?dns}",
194 "endpoints": {
195 "ips": ["192.0.2.1", "2001:db8::1"]
196 }
197 }
198 )";
199 EXPECT_FALSE(DnsOverHttpsServerConfig::FromValue(
200 std::move(base::JSONReader::Read(input)->GetDict())));
201
202 // Wrong "ips" type
203 input = R"(
204 {
205 "template": "https://dnsserver.example.net/dns-query{?dns}",
206 "endpoints": [{
207 "ips": "192.0.2.1"
208 }]
209 }
210 )";
211 EXPECT_FALSE(DnsOverHttpsServerConfig::FromValue(
212 std::move(base::JSONReader::Read(input)->GetDict())));
213
214 // Wrong IP type
215 input = R"(
216 {
217 "template": "https://dnsserver.example.net/dns-query{?dns}",
218 "endpoints": [{
219 "ips": ["2001:db8::1", 192.021]
220 }]
221 }
222 )";
223 EXPECT_FALSE(DnsOverHttpsServerConfig::FromValue(
224 std::move(base::JSONReader::Read(input)->GetDict())));
225
226 // Bad IP address
227 input = R"(
228 {
229 "template": "https://dnsserver.example.net/dns-query{?dns}",
230 "endpoints": [{
231 "ips": ["2001:db8::1", "256.257.258.259"]
232 }]
233 }
234 )";
235 EXPECT_FALSE(DnsOverHttpsServerConfig::FromValue(
236 std::move(base::JSONReader::Read(input)->GetDict())));
237 }
238
239 } // namespace
240 } // namespace net
241