Line data Source code
1 : /* Copyright (c) 2014-2021, The Tor Project, Inc. */
2 : /* See LICENSE for licensing information */
3 :
4 : #include "orconfig.h"
5 :
6 : #define CONNECTION_PRIVATE
7 : #define CONNECTION_EDGE_PRIVATE
8 :
9 : #include "core/or/or.h"
10 : #include "test/test.h"
11 :
12 : #include "feature/client/addressmap.h"
13 : #include "app/config/config.h"
14 : #include "lib/confmgt/confmgt.h"
15 : #include "core/mainloop/connection.h"
16 : #include "core/or/connection_edge.h"
17 : #include "feature/nodelist/nodelist.h"
18 :
19 : #include "feature/hs/hs_cache.h"
20 :
21 : #include "core/or/entry_connection_st.h"
22 : #include "core/or/socks_request_st.h"
23 :
24 : #include "lib/encoding/confline.h"
25 :
26 : static void *
27 16 : entryconn_rewrite_setup(const struct testcase_t *tc)
28 : {
29 16 : (void)tc;
30 16 : entry_connection_t *ec = entry_connection_new(CONN_TYPE_AP, AF_INET);
31 16 : addressmap_init();
32 16 : return ec;
33 : }
34 :
35 : static int
36 16 : entryconn_rewrite_teardown(const struct testcase_t *tc, void *arg)
37 : {
38 16 : (void)tc;
39 16 : entry_connection_t *ec = arg;
40 16 : if (ec)
41 16 : connection_free_minimal(ENTRY_TO_CONN(ec));
42 16 : addressmap_free_all();
43 16 : return 1;
44 : }
45 :
46 : static struct testcase_setup_t test_rewrite_setup = {
47 : entryconn_rewrite_setup, entryconn_rewrite_teardown
48 : };
49 :
50 : /* Simple rewrite: no changes needed */
51 : static void
52 1 : test_entryconn_rewrite_basic(void *arg)
53 : {
54 1 : entry_connection_t *ec = arg;
55 1 : rewrite_result_t rr;
56 :
57 1 : tt_assert(ec->socks_request);
58 1 : strlcpy(ec->socks_request->address, "www.TORproject.org",
59 : sizeof(ec->socks_request->address));
60 1 : ec->socks_request->command = SOCKS_COMMAND_CONNECT;
61 1 : connection_ap_handshake_rewrite(ec, &rr);
62 :
63 1 : tt_int_op(rr.should_close, OP_EQ, 0);
64 1 : tt_int_op(rr.end_reason, OP_EQ, 0);
65 1 : tt_int_op(rr.automap, OP_EQ, 0);
66 1 : tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
67 1 : tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
68 1 : tt_str_op(rr.orig_address, OP_EQ, "www.torproject.org");
69 1 : tt_str_op(ec->socks_request->address, OP_EQ, "www.torproject.org");
70 1 : tt_str_op(ec->original_dest_address, OP_EQ, "www.torproject.org");
71 :
72 1 : done:
73 1 : ;
74 1 : }
75 :
76 : /* Rewrite but reject because of disallowed .exit */
77 : static void
78 1 : test_entryconn_rewrite_bad_dotexit(void *arg)
79 : {
80 1 : entry_connection_t *ec = arg;
81 1 : rewrite_result_t rr;
82 :
83 1 : tt_assert(ec->socks_request);
84 1 : strlcpy(ec->socks_request->address, "www.TORproject.org.foo.exit",
85 : sizeof(ec->socks_request->address));
86 1 : ec->socks_request->command = SOCKS_COMMAND_CONNECT;
87 1 : connection_ap_handshake_rewrite(ec, &rr);
88 :
89 1 : tt_int_op(rr.should_close, OP_EQ, 1);
90 1 : tt_int_op(rr.end_reason, OP_EQ, END_STREAM_REASON_TORPROTOCOL);
91 :
92 1 : done:
93 1 : ;
94 1 : }
95 :
96 : /* Automap on resolve, connect to automapped address, resolve again and get
97 : * same answer. (IPv4) */
98 : static void
99 1 : test_entryconn_rewrite_automap_ipv4(void *arg)
100 : {
101 1 : entry_connection_t *ec = arg;
102 1 : entry_connection_t *ec2=NULL, *ec3=NULL;
103 1 : rewrite_result_t rr;
104 1 : char *msg = NULL;
105 :
106 1 : ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET);
107 1 : ec3 = entry_connection_new(CONN_TYPE_AP, AF_INET);
108 :
109 1 : get_options_mutable()->AutomapHostsOnResolve = 1;
110 1 : smartlist_add_strdup(get_options_mutable()->AutomapHostsSuffixes, ".");
111 1 : parse_virtual_addr_network("127.202.0.0/16", AF_INET, 0, &msg);
112 :
113 : /* Automap this on resolve. */
114 1 : strlcpy(ec->socks_request->address, "WWW.MIT.EDU",
115 : sizeof(ec->socks_request->address));
116 1 : ec->socks_request->command = SOCKS_COMMAND_RESOLVE;
117 1 : connection_ap_handshake_rewrite(ec, &rr);
118 :
119 1 : tt_int_op(rr.automap, OP_EQ, 1);
120 1 : tt_int_op(rr.should_close, OP_EQ, 0);
121 1 : tt_int_op(rr.end_reason, OP_EQ, 0);
122 1 : tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
123 1 : tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
124 1 : tt_str_op(rr.orig_address, OP_EQ, "www.mit.edu");
125 1 : tt_str_op(ec->original_dest_address, OP_EQ, "www.mit.edu");
126 :
127 1 : tt_assert(!strcmpstart(ec->socks_request->address,"127.202."));
128 :
129 : /* Connect to it and make sure we get the original address back. */
130 1 : strlcpy(ec2->socks_request->address, ec->socks_request->address,
131 : sizeof(ec2->socks_request->address));
132 :
133 1 : ec2->socks_request->command = SOCKS_COMMAND_CONNECT;
134 1 : connection_ap_handshake_rewrite(ec2, &rr);
135 :
136 1 : tt_int_op(rr.automap, OP_EQ, 0);
137 1 : tt_int_op(rr.should_close, OP_EQ, 0);
138 1 : tt_int_op(rr.end_reason, OP_EQ, 0);
139 1 : tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
140 1 : tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
141 1 : tt_str_op(rr.orig_address, OP_EQ, ec->socks_request->address);
142 1 : tt_str_op(ec2->original_dest_address, OP_EQ, ec->socks_request->address);
143 1 : tt_str_op(ec2->socks_request->address, OP_EQ, "www.mit.edu");
144 :
145 : /* Resolve it again, make sure the answer is the same. */
146 1 : strlcpy(ec3->socks_request->address, "www.MIT.EDU",
147 : sizeof(ec3->socks_request->address));
148 1 : ec3->socks_request->command = SOCKS_COMMAND_RESOLVE;
149 1 : connection_ap_handshake_rewrite(ec3, &rr);
150 :
151 1 : tt_int_op(rr.automap, OP_EQ, 1);
152 1 : tt_int_op(rr.should_close, OP_EQ, 0);
153 1 : tt_int_op(rr.end_reason, OP_EQ, 0);
154 1 : tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
155 1 : tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
156 1 : tt_str_op(rr.orig_address, OP_EQ, "www.mit.edu");
157 1 : tt_str_op(ec3->original_dest_address, OP_EQ, "www.mit.edu");
158 :
159 1 : tt_str_op(ec3->socks_request->address, OP_EQ,
160 : ec->socks_request->address);
161 :
162 1 : done:
163 1 : connection_free_minimal(ENTRY_TO_CONN(ec2));
164 1 : connection_free_minimal(ENTRY_TO_CONN(ec3));
165 1 : }
166 :
167 : /* Automap on resolve, connect to automapped address, resolve again and get
168 : * same answer. (IPv6) */
169 : static void
170 1 : test_entryconn_rewrite_automap_ipv6(void *arg)
171 : {
172 1 : (void)arg;
173 1 : entry_connection_t *ec =NULL;
174 1 : entry_connection_t *ec2=NULL, *ec3=NULL;
175 1 : rewrite_result_t rr;
176 1 : char *msg = NULL;
177 :
178 1 : ec = entry_connection_new(CONN_TYPE_AP, AF_INET6);
179 1 : ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET6);
180 1 : ec3 = entry_connection_new(CONN_TYPE_AP, AF_INET6);
181 :
182 1 : get_options_mutable()->AutomapHostsOnResolve = 1;
183 1 : smartlist_add_strdup(get_options_mutable()->AutomapHostsSuffixes, ".");
184 1 : parse_virtual_addr_network("FE80::/32", AF_INET6, 0, &msg);
185 :
186 : /* Automap this on resolve. */
187 1 : strlcpy(ec->socks_request->address, "WWW.MIT.EDU",
188 : sizeof(ec->socks_request->address));
189 1 : ec->socks_request->command = SOCKS_COMMAND_RESOLVE;
190 1 : connection_ap_handshake_rewrite(ec, &rr);
191 :
192 1 : tt_int_op(rr.automap, OP_EQ, 1);
193 1 : tt_int_op(rr.should_close, OP_EQ, 0);
194 1 : tt_int_op(rr.end_reason, OP_EQ, 0);
195 1 : tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
196 1 : tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
197 1 : tt_str_op(rr.orig_address, OP_EQ, "www.mit.edu");
198 1 : tt_str_op(ec->original_dest_address, OP_EQ, "www.mit.edu");
199 :
200 : /* Yes, this [ should be here. */
201 1 : tt_assert(!strcmpstart(ec->socks_request->address,"[fe80:"));
202 :
203 : /* Connect to it and make sure we get the original address back. */
204 1 : strlcpy(ec2->socks_request->address, ec->socks_request->address,
205 : sizeof(ec2->socks_request->address));
206 :
207 1 : ec2->socks_request->command = SOCKS_COMMAND_CONNECT;
208 1 : connection_ap_handshake_rewrite(ec2, &rr);
209 :
210 1 : tt_int_op(rr.automap, OP_EQ, 0);
211 1 : tt_int_op(rr.should_close, OP_EQ, 0);
212 1 : tt_int_op(rr.end_reason, OP_EQ, 0);
213 1 : tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
214 1 : tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
215 1 : tt_str_op(rr.orig_address, OP_EQ, ec->socks_request->address);
216 1 : tt_str_op(ec2->original_dest_address, OP_EQ, ec->socks_request->address);
217 1 : tt_str_op(ec2->socks_request->address, OP_EQ, "www.mit.edu");
218 :
219 : /* Resolve it again, make sure the answer is the same. */
220 1 : strlcpy(ec3->socks_request->address, "www.MIT.EDU",
221 : sizeof(ec3->socks_request->address));
222 1 : ec3->socks_request->command = SOCKS_COMMAND_RESOLVE;
223 1 : connection_ap_handshake_rewrite(ec3, &rr);
224 :
225 1 : tt_int_op(rr.automap, OP_EQ, 1);
226 1 : tt_int_op(rr.should_close, OP_EQ, 0);
227 1 : tt_int_op(rr.end_reason, OP_EQ, 0);
228 1 : tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
229 1 : tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
230 1 : tt_str_op(rr.orig_address, OP_EQ, "www.mit.edu");
231 1 : tt_str_op(ec3->original_dest_address, OP_EQ, "www.mit.edu");
232 :
233 1 : tt_str_op(ec3->socks_request->address, OP_EQ,
234 : ec->socks_request->address);
235 :
236 1 : done:
237 1 : connection_free_minimal(ENTRY_TO_CONN(ec));
238 1 : connection_free_minimal(ENTRY_TO_CONN(ec2));
239 1 : connection_free_minimal(ENTRY_TO_CONN(ec3));
240 1 : }
241 :
242 : #if 0
243 : /* FFFF not actually supported. */
244 : /* automap on resolve, reverse lookup. */
245 : static void
246 : test_entryconn_rewrite_automap_reverse(void *arg)
247 : {
248 : entry_connection_t *ec = arg;
249 : entry_connection_t *ec2=NULL;
250 : rewrite_result_t rr;
251 : char *msg = NULL;
252 :
253 : ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET);
254 :
255 : get_options_mutable()->AutomapHostsOnResolve = 1;
256 : get_options_mutable()->SafeLogging_ = SAFELOG_SCRUB_NONE;
257 : smartlist_add(get_options_mutable()->AutomapHostsSuffixes,
258 : tor_strdup(".bloom"));
259 : parse_virtual_addr_network("127.80.0.0/16", AF_INET, 0, &msg);
260 :
261 : /* Automap this on resolve. */
262 : strlcpy(ec->socks_request->address, "www.poldy.BLOOM",
263 : sizeof(ec->socks_request->address));
264 : ec->socks_request->command = SOCKS_COMMAND_RESOLVE;
265 : connection_ap_handshake_rewrite(ec, &rr);
266 :
267 : tt_int_op(rr.automap, OP_EQ, 1);
268 : tt_int_op(rr.should_close, OP_EQ, 0);
269 : tt_int_op(rr.end_reason, OP_EQ, 0);
270 : tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
271 : tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
272 : tt_str_op(rr.orig_address, OP_EQ, "www.poldy.bloom");
273 : tt_str_op(ec->original_dest_address, OP_EQ, "www.poldy.bloom");
274 :
275 : tt_assert(!strcmpstart(ec->socks_request->address,"127.80."));
276 :
277 : strlcpy(ec2->socks_request->address, ec->socks_request->address,
278 : sizeof(ec2->socks_request->address));
279 : ec2->socks_request->command = SOCKS_COMMAND_RESOLVE_PTR;
280 : connection_ap_handshake_rewrite(ec2, &rr);
281 :
282 : tt_int_op(rr.automap, OP_EQ, 0);
283 : tt_int_op(rr.should_close, OP_EQ, 1);
284 : tt_int_op(rr.end_reason, OP_EQ,
285 : END_STREAM_REASON_DONE|END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
286 : tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
287 : tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
288 :
289 : done:
290 : connection_free_minimal(ENTRY_TO_CONN(ec2));
291 : }
292 : #endif /* 0 */
293 :
294 : /* Rewrite because of cached DNS entry. */
295 : static void
296 1 : test_entryconn_rewrite_cached_dns_ipv4(void *arg)
297 : {
298 1 : entry_connection_t *ec = arg;
299 1 : rewrite_result_t rr;
300 1 : time_t expires = time(NULL) + 3600;
301 1 : entry_connection_t *ec2=NULL;
302 :
303 1 : ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET);
304 :
305 1 : addressmap_register("www.friendly.example.com",
306 : tor_strdup("240.240.241.241"),
307 : expires,
308 : ADDRMAPSRC_DNS,
309 : 0, 0, 0);
310 :
311 1 : strlcpy(ec->socks_request->address, "www.friendly.example.com",
312 : sizeof(ec->socks_request->address));
313 1 : strlcpy(ec2->socks_request->address, "www.friendly.example.com",
314 : sizeof(ec2->socks_request->address));
315 :
316 1 : ec->socks_request->command = SOCKS_COMMAND_CONNECT;
317 1 : ec2->socks_request->command = SOCKS_COMMAND_CONNECT;
318 :
319 1 : ec2->entry_cfg.use_cached_ipv4_answers = 1; /* only ec2 gets this flag */
320 1 : connection_ap_handshake_rewrite(ec, &rr);
321 :
322 1 : tt_int_op(rr.automap, OP_EQ, 0);
323 1 : tt_int_op(rr.should_close, OP_EQ, 0);
324 1 : tt_int_op(rr.end_reason, OP_EQ, 0);
325 1 : tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
326 1 : tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
327 1 : tt_str_op(rr.orig_address, OP_EQ, "www.friendly.example.com");
328 1 : tt_str_op(ec->socks_request->address, OP_EQ, "www.friendly.example.com");
329 :
330 1 : connection_ap_handshake_rewrite(ec2, &rr);
331 1 : tt_int_op(rr.automap, OP_EQ, 0);
332 1 : tt_int_op(rr.should_close, OP_EQ, 0);
333 1 : tt_int_op(rr.end_reason, OP_EQ, 0);
334 1 : tt_i64_op(rr.map_expires, OP_EQ, expires);
335 1 : tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
336 1 : tt_str_op(rr.orig_address, OP_EQ, "www.friendly.example.com");
337 1 : tt_str_op(ec2->socks_request->address, OP_EQ, "240.240.241.241");
338 :
339 1 : done:
340 1 : connection_free_minimal(ENTRY_TO_CONN(ec2));
341 1 : }
342 :
343 : /* Rewrite because of cached DNS entry. */
344 : static void
345 1 : test_entryconn_rewrite_cached_dns_ipv6(void *arg)
346 : {
347 1 : entry_connection_t *ec = NULL;
348 1 : rewrite_result_t rr;
349 1 : time_t expires = time(NULL) + 3600;
350 1 : entry_connection_t *ec2=NULL;
351 :
352 1 : (void)arg;
353 :
354 1 : ec = entry_connection_new(CONN_TYPE_AP, AF_INET6);
355 1 : ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET6);
356 :
357 1 : addressmap_register("www.friendly.example.com",
358 : tor_strdup("[::f00f]"),
359 : expires,
360 : ADDRMAPSRC_DNS,
361 : 0, 0, 0);
362 :
363 1 : strlcpy(ec->socks_request->address, "www.friendly.example.com",
364 : sizeof(ec->socks_request->address));
365 1 : strlcpy(ec2->socks_request->address, "www.friendly.example.com",
366 : sizeof(ec2->socks_request->address));
367 :
368 1 : ec->socks_request->command = SOCKS_COMMAND_CONNECT;
369 1 : ec2->socks_request->command = SOCKS_COMMAND_CONNECT;
370 :
371 1 : ec2->entry_cfg.use_cached_ipv6_answers = 1; /* only ec2 gets this flag */
372 1 : connection_ap_handshake_rewrite(ec, &rr);
373 :
374 1 : tt_int_op(rr.automap, OP_EQ, 0);
375 1 : tt_int_op(rr.should_close, OP_EQ, 0);
376 1 : tt_int_op(rr.end_reason, OP_EQ, 0);
377 1 : tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
378 1 : tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
379 1 : tt_str_op(rr.orig_address, OP_EQ, "www.friendly.example.com");
380 1 : tt_str_op(ec->socks_request->address, OP_EQ, "www.friendly.example.com");
381 :
382 1 : connection_ap_handshake_rewrite(ec2, &rr);
383 1 : tt_int_op(rr.automap, OP_EQ, 0);
384 1 : tt_int_op(rr.should_close, OP_EQ, 0);
385 1 : tt_int_op(rr.end_reason, OP_EQ, 0);
386 1 : tt_i64_op(rr.map_expires, OP_EQ, expires);
387 1 : tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
388 1 : tt_str_op(rr.orig_address, OP_EQ, "www.friendly.example.com");
389 1 : tt_str_op(ec2->socks_request->address, OP_EQ, "[::f00f]");
390 :
391 1 : done:
392 1 : connection_free_minimal(ENTRY_TO_CONN(ec));
393 1 : connection_free_minimal(ENTRY_TO_CONN(ec2));
394 1 : }
395 :
396 : /* Fail to connect to unmapped address in virtual range. */
397 : static void
398 1 : test_entryconn_rewrite_unmapped_virtual(void *arg)
399 : {
400 1 : entry_connection_t *ec = arg;
401 1 : rewrite_result_t rr;
402 1 : entry_connection_t *ec2 = NULL;
403 1 : char *msg = NULL;
404 :
405 1 : ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET6);
406 :
407 1 : parse_virtual_addr_network("18.202.0.0/16", AF_INET, 0, &msg);
408 1 : parse_virtual_addr_network("[ABCD::]/16", AF_INET6, 0, &msg);
409 :
410 1 : strlcpy(ec->socks_request->address, "18.202.5.5",
411 : sizeof(ec->socks_request->address));
412 1 : ec->socks_request->command = SOCKS_COMMAND_CONNECT;
413 1 : connection_ap_handshake_rewrite(ec, &rr);
414 :
415 1 : tt_int_op(rr.should_close, OP_EQ, 1);
416 1 : tt_int_op(rr.end_reason, OP_EQ, END_STREAM_REASON_INTERNAL);
417 1 : tt_int_op(rr.automap, OP_EQ, 0);
418 1 : tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
419 1 : tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
420 :
421 1 : strlcpy(ec2->socks_request->address, "[ABCD:9::5314:9543]",
422 : sizeof(ec2->socks_request->address));
423 1 : ec2->socks_request->command = SOCKS_COMMAND_CONNECT;
424 1 : connection_ap_handshake_rewrite(ec2, &rr);
425 :
426 1 : tt_int_op(rr.should_close, OP_EQ, 1);
427 1 : tt_int_op(rr.end_reason, OP_EQ, END_STREAM_REASON_INTERNAL);
428 1 : tt_int_op(rr.automap, OP_EQ, 0);
429 1 : tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
430 1 : tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
431 :
432 1 : done:
433 1 : connection_free_minimal(ENTRY_TO_CONN(ec2));
434 1 : }
435 :
436 : /* Rewrite because of mapaddress option */
437 : static void
438 1 : test_entryconn_rewrite_mapaddress(void *arg)
439 : {
440 1 : entry_connection_t *ec = arg;
441 1 : rewrite_result_t rr;
442 :
443 1 : config_line_append(&get_options_mutable()->AddressMap,
444 : "MapAddress", "meta metaobjects.example");
445 1 : config_register_addressmaps(get_options());
446 :
447 1 : strlcpy(ec->socks_request->address, "meta",
448 : sizeof(ec->socks_request->address));
449 1 : ec->socks_request->command = SOCKS_COMMAND_CONNECT;
450 1 : connection_ap_handshake_rewrite(ec, &rr);
451 :
452 1 : tt_int_op(rr.should_close, OP_EQ, 0);
453 1 : tt_int_op(rr.end_reason, OP_EQ, 0);
454 1 : tt_int_op(rr.automap, OP_EQ, 0);
455 1 : tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
456 1 : tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
457 1 : tt_str_op(ec->socks_request->address, OP_EQ, "metaobjects.example");
458 :
459 1 : done:
460 1 : ;
461 1 : }
462 :
463 : /* Reject reverse lookups of internal address. */
464 : static void
465 1 : test_entryconn_rewrite_reject_internal_reverse(void *arg)
466 : {
467 1 : entry_connection_t *ec = arg;
468 1 : rewrite_result_t rr;
469 :
470 1 : strlcpy(ec->socks_request->address, "10.0.0.1",
471 : sizeof(ec->socks_request->address));
472 1 : ec->socks_request->command = SOCKS_COMMAND_RESOLVE_PTR;
473 1 : connection_ap_handshake_rewrite(ec, &rr);
474 :
475 1 : tt_int_op(rr.should_close, OP_EQ, 1);
476 1 : tt_int_op(rr.end_reason, OP_EQ, END_STREAM_REASON_SOCKSPROTOCOL |
477 : END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
478 1 : tt_int_op(rr.automap, OP_EQ, 0);
479 1 : tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
480 1 : tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
481 :
482 1 : done:
483 1 : ;
484 1 : }
485 :
486 : /* Rewrite into .exit because of virtual address mapping. */
487 : static void
488 1 : test_entryconn_rewrite_automap_exit(void *arg)
489 : {
490 1 : entry_connection_t *ec = arg;
491 1 : entry_connection_t *ec2=NULL;
492 1 : rewrite_result_t rr;
493 1 : char *msg = NULL;
494 :
495 1 : ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET);
496 :
497 1 : smartlist_add_strdup(get_options_mutable()->AutomapHostsSuffixes,
498 : ".EXIT");
499 1 : parse_virtual_addr_network("127.1.0.0/16", AF_INET, 0, &msg);
500 :
501 : /* Try to automap this on resolve. */
502 1 : strlcpy(ec->socks_request->address, "website.example.exit",
503 : sizeof(ec->socks_request->address));
504 1 : ec->socks_request->command = SOCKS_COMMAND_RESOLVE;
505 1 : connection_ap_handshake_rewrite(ec, &rr);
506 :
507 : /* Make sure it isn't allowed -- there is no longer an AllowDotExit
508 : * option. */
509 1 : tt_int_op(rr.automap, OP_EQ, 0);
510 1 : tt_int_op(rr.should_close, OP_EQ, 1);
511 1 : tt_int_op(rr.end_reason, OP_EQ, END_STREAM_REASON_TORPROTOCOL);
512 :
513 1 : done:
514 1 : connection_free_minimal(ENTRY_TO_CONN(ec2));
515 1 : }
516 :
517 : /* Rewrite into .exit because of mapaddress */
518 : static void
519 1 : test_entryconn_rewrite_mapaddress_exit(void *arg)
520 : {
521 1 : entry_connection_t *ec = arg;
522 1 : rewrite_result_t rr;
523 :
524 1 : config_line_append(&get_options_mutable()->AddressMap,
525 : "MapAddress", "*.example.com *.example.com.abc.exit");
526 1 : config_register_addressmaps(get_options());
527 :
528 : /* Automap this on resolve. */
529 1 : strlcpy(ec->socks_request->address, "abc.example.com",
530 : sizeof(ec->socks_request->address));
531 1 : ec->socks_request->command = SOCKS_COMMAND_CONNECT;
532 1 : connection_ap_handshake_rewrite(ec, &rr);
533 :
534 1 : tt_int_op(rr.automap, OP_EQ, 0);
535 1 : tt_int_op(rr.should_close, OP_EQ, 0);
536 1 : tt_int_op(rr.end_reason, OP_EQ, 0);
537 1 : tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
538 1 : tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_TORRC);
539 1 : tt_str_op(rr.orig_address, OP_EQ, "abc.example.com");
540 1 : tt_str_op(ec->socks_request->address, OP_EQ, "abc.example.com.abc.exit");
541 1 : done:
542 1 : ;
543 1 : }
544 :
545 : /* Map foo.onion to longthing.onion, and also automap. */
546 : static void
547 1 : test_entryconn_rewrite_mapaddress_automap_onion(void *arg)
548 : {
549 1 : entry_connection_t *ec = arg;
550 1 : entry_connection_t *ec2 = NULL;
551 1 : entry_connection_t *ec3 = NULL;
552 1 : entry_connection_t *ec4 = NULL;
553 1 : rewrite_result_t rr;
554 1 : char *msg = NULL;
555 :
556 1 : ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET);
557 1 : ec3 = entry_connection_new(CONN_TYPE_AP, AF_INET);
558 1 : ec4 = entry_connection_new(CONN_TYPE_AP, AF_INET);
559 :
560 1 : get_options_mutable()->AutomapHostsOnResolve = 1;
561 1 : smartlist_add_strdup(get_options_mutable()->AutomapHostsSuffixes,
562 : ".onion");
563 1 : parse_virtual_addr_network("192.168.0.0/16", AF_INET, 0, &msg);
564 1 : config_line_append(&get_options_mutable()->AddressMap,
565 : "MapAddress", "foo.onion abcdefghijklmnop.onion");
566 1 : config_register_addressmaps(get_options());
567 :
568 : /* Connect to foo.onion. */
569 1 : strlcpy(ec->socks_request->address, "foo.onion",
570 : sizeof(ec->socks_request->address));
571 1 : ec->socks_request->command = SOCKS_COMMAND_CONNECT;
572 1 : connection_ap_handshake_rewrite(ec, &rr);
573 :
574 1 : tt_int_op(rr.automap, OP_EQ, 0);
575 1 : tt_int_op(rr.should_close, OP_EQ, 0);
576 1 : tt_int_op(rr.end_reason, OP_EQ, 0);
577 1 : tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
578 1 : tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
579 1 : tt_str_op(rr.orig_address, OP_EQ, "foo.onion");
580 1 : tt_str_op(ec->socks_request->address, OP_EQ, "abcdefghijklmnop.onion");
581 :
582 : /* Okay, resolve foo.onion */
583 1 : strlcpy(ec2->socks_request->address, "foo.onion",
584 : sizeof(ec2->socks_request->address));
585 1 : ec2->socks_request->command = SOCKS_COMMAND_RESOLVE;
586 1 : connection_ap_handshake_rewrite(ec2, &rr);
587 :
588 1 : tt_int_op(rr.automap, OP_EQ, 1);
589 1 : tt_int_op(rr.should_close, OP_EQ, 0);
590 1 : tt_int_op(rr.end_reason, OP_EQ, 0);
591 1 : tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
592 1 : tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
593 1 : tt_str_op(rr.orig_address, OP_EQ, "foo.onion");
594 1 : tt_assert(!strcmpstart(ec2->socks_request->address, "192.168."));
595 :
596 : /* Now connect */
597 1 : strlcpy(ec3->socks_request->address, ec2->socks_request->address,
598 : sizeof(ec3->socks_request->address));
599 1 : ec3->socks_request->command = SOCKS_COMMAND_CONNECT;
600 1 : connection_ap_handshake_rewrite(ec3, &rr);
601 1 : tt_int_op(rr.automap, OP_EQ, 0);
602 1 : tt_int_op(rr.should_close, OP_EQ, 0);
603 1 : tt_int_op(rr.end_reason, OP_EQ, 0);
604 1 : tt_assert(!strcmpstart(ec3->socks_request->address,
605 : "abcdefghijklmnop.onion"));
606 :
607 : /* Now resolve abcefghijklmnop.onion. */
608 1 : strlcpy(ec4->socks_request->address, "abcdefghijklmnop.onion",
609 : sizeof(ec4->socks_request->address));
610 1 : ec4->socks_request->command = SOCKS_COMMAND_RESOLVE;
611 1 : connection_ap_handshake_rewrite(ec4, &rr);
612 :
613 1 : tt_int_op(rr.automap, OP_EQ, 1);
614 1 : tt_int_op(rr.should_close, OP_EQ, 0);
615 1 : tt_int_op(rr.end_reason, OP_EQ, 0);
616 1 : tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
617 1 : tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
618 1 : tt_str_op(rr.orig_address, OP_EQ, "abcdefghijklmnop.onion");
619 1 : tt_assert(!strcmpstart(ec4->socks_request->address, "192.168."));
620 : /* XXXX doesn't work
621 : tt_str_op(ec4->socks_request->address, OP_EQ, ec2->socks_request->address);
622 : */
623 :
624 1 : done:
625 1 : connection_free_minimal(ENTRY_TO_CONN(ec2));
626 1 : connection_free_minimal(ENTRY_TO_CONN(ec3));
627 1 : connection_free_minimal(ENTRY_TO_CONN(ec4));
628 1 : }
629 :
630 : static void
631 3 : test_entryconn_rewrite_mapaddress_automap_onion_common(entry_connection_t *ec,
632 : int map_to_onion,
633 : int map_to_address)
634 : {
635 3 : entry_connection_t *ec2 = NULL;
636 3 : entry_connection_t *ec3 = NULL;
637 3 : rewrite_result_t rr;
638 :
639 3 : ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET);
640 3 : ec3 = entry_connection_new(CONN_TYPE_AP, AF_INET);
641 :
642 : /* Connect to irc.example.com */
643 3 : strlcpy(ec->socks_request->address, "irc.example.com",
644 : sizeof(ec->socks_request->address));
645 3 : ec->socks_request->command = SOCKS_COMMAND_CONNECT;
646 3 : connection_ap_handshake_rewrite(ec, &rr);
647 :
648 3 : tt_int_op(rr.automap, OP_EQ, 0);
649 3 : tt_int_op(rr.should_close, OP_EQ, 0);
650 3 : tt_int_op(rr.end_reason, OP_EQ, 0);
651 3 : tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
652 3 : tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
653 3 : tt_str_op(rr.orig_address, OP_EQ, "irc.example.com");
654 4 : tt_str_op(ec->socks_request->address, OP_EQ,
655 : map_to_onion ? "abcdefghijklmnop.onion" : "irc.example.com");
656 :
657 : /* Okay, resolve irc.example.com */
658 3 : strlcpy(ec2->socks_request->address, "irc.example.com",
659 : sizeof(ec2->socks_request->address));
660 3 : ec2->socks_request->command = SOCKS_COMMAND_RESOLVE;
661 3 : connection_ap_handshake_rewrite(ec2, &rr);
662 :
663 3 : tt_int_op(rr.automap, OP_EQ, map_to_onion && map_to_address);
664 3 : tt_int_op(rr.should_close, OP_EQ, 0);
665 3 : tt_int_op(rr.end_reason, OP_EQ, 0);
666 3 : tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
667 3 : tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
668 3 : tt_str_op(rr.orig_address, OP_EQ, "irc.example.com");
669 3 : if (map_to_onion && map_to_address)
670 1 : tt_assert(!strcmpstart(ec2->socks_request->address, "192.168."));
671 :
672 : /* Now connect */
673 3 : strlcpy(ec3->socks_request->address, ec2->socks_request->address,
674 : sizeof(ec3->socks_request->address));
675 3 : ec3->socks_request->command = SOCKS_COMMAND_CONNECT;
676 3 : connection_ap_handshake_rewrite(ec3, &rr);
677 3 : tt_int_op(rr.automap, OP_EQ, 0);
678 3 : tt_int_op(rr.should_close, OP_EQ, 0);
679 3 : tt_int_op(rr.end_reason, OP_EQ, 0);
680 3 : if (map_to_onion)
681 2 : tt_assert(!strcmpstart(ec3->socks_request->address,
682 : "abcdefghijklmnop.onion"));
683 :
684 3 : done:
685 3 : connection_free_minimal(ENTRY_TO_CONN(ec2));
686 3 : connection_free_minimal(ENTRY_TO_CONN(ec3));
687 3 : }
688 :
689 : /* This time is the same, but we start with a mapping from a non-onion
690 : * address. */
691 : static void
692 1 : test_entryconn_rewrite_mapaddress_automap_onion2(void *arg)
693 : {
694 1 : char *msg = NULL;
695 1 : get_options_mutable()->AutomapHostsOnResolve = 1;
696 1 : smartlist_add_strdup(get_options_mutable()->AutomapHostsSuffixes,
697 : ".onion");
698 1 : parse_virtual_addr_network("192.168.0.0/16", AF_INET, 0, &msg);
699 1 : config_line_append(&get_options_mutable()->AddressMap,
700 : "MapAddress", "irc.example.com abcdefghijklmnop.onion");
701 1 : config_register_addressmaps(get_options());
702 :
703 1 : test_entryconn_rewrite_mapaddress_automap_onion_common(arg, 1, 1);
704 1 : }
705 :
706 : /* Same as above, with automapped turned off */
707 : static void
708 1 : test_entryconn_rewrite_mapaddress_automap_onion3(void *arg)
709 : {
710 1 : config_line_append(&get_options_mutable()->AddressMap,
711 : "MapAddress", "irc.example.com abcdefghijklmnop.onion");
712 1 : config_register_addressmaps(get_options());
713 :
714 1 : test_entryconn_rewrite_mapaddress_automap_onion_common(arg, 1, 0);
715 1 : }
716 :
717 : /* As above, with no mapping. */
718 : static void
719 1 : test_entryconn_rewrite_mapaddress_automap_onion4(void *arg)
720 : {
721 1 : char *msg = NULL;
722 1 : get_options_mutable()->AutomapHostsOnResolve = 1;
723 1 : smartlist_add_strdup(get_options_mutable()->AutomapHostsSuffixes,
724 : ".onion");
725 1 : parse_virtual_addr_network("192.168.0.0/16", AF_INET, 0, &msg);
726 :
727 1 : test_entryconn_rewrite_mapaddress_automap_onion_common(arg, 0, 1);
728 1 : }
729 :
730 : /** Test that rewrite functions can handle v3 onion addresses */
731 : static void
732 1 : test_entryconn_rewrite_onion_v3(void *arg)
733 : {
734 1 : int retval;
735 1 : entry_connection_t *conn = arg;
736 :
737 1 : (void) arg;
738 :
739 1 : hs_cache_init();
740 :
741 : /* Make a SOCKS request */
742 1 : conn->socks_request->command = SOCKS_COMMAND_CONNECT;
743 1 : strlcpy(conn->socks_request->address,
744 : "git.25njqamcweflpvkl73j4szahhihoc4xt3ktcgjnpaingr5yhkenl5sid.onion",
745 : sizeof(conn->socks_request->address));
746 :
747 : /* Make an onion connection using the SOCKS request */
748 1 : conn->entry_cfg.onion_traffic = 1;
749 1 : ENTRY_TO_CONN(conn)->state = AP_CONN_STATE_SOCKS_WAIT;
750 1 : tt_assert(!ENTRY_TO_EDGE_CONN(conn)->hs_ident);
751 :
752 : /* Handle SOCKS and rewrite! */
753 1 : retval = connection_ap_handshake_rewrite_and_attach(conn, NULL, NULL);
754 1 : tt_int_op(retval, OP_EQ, 0);
755 :
756 : /* Check connection state after rewrite. It should be in waiting for
757 : * descriptor state. */
758 1 : tt_int_op(ENTRY_TO_CONN(conn)->state, OP_EQ, AP_CONN_STATE_RENDDESC_WAIT);
759 : /* check that the address got rewritten */
760 1 : tt_str_op(conn->socks_request->address, OP_EQ,
761 : "25njqamcweflpvkl73j4szahhihoc4xt3ktcgjnpaingr5yhkenl5sid");
762 : /* check that HS information got attached to the connection */
763 1 : tt_assert(ENTRY_TO_EDGE_CONN(conn)->hs_ident);
764 :
765 1 : done:
766 1 : hs_free_all();
767 : /* 'conn' is cleaned by handler */
768 1 : }
769 :
770 : #define REWRITE(name) \
771 : { #name, test_entryconn_##name, TT_FORK, &test_rewrite_setup, NULL }
772 :
773 : struct testcase_t entryconn_tests[] = {
774 : REWRITE(rewrite_basic),
775 : REWRITE(rewrite_bad_dotexit),
776 : REWRITE(rewrite_automap_ipv4),
777 : REWRITE(rewrite_automap_ipv6),
778 : // REWRITE(rewrite_automap_reverse),
779 : REWRITE(rewrite_cached_dns_ipv4),
780 : REWRITE(rewrite_cached_dns_ipv6),
781 : REWRITE(rewrite_unmapped_virtual),
782 : REWRITE(rewrite_mapaddress),
783 : REWRITE(rewrite_reject_internal_reverse),
784 : REWRITE(rewrite_automap_exit),
785 : REWRITE(rewrite_mapaddress_exit),
786 : REWRITE(rewrite_mapaddress_automap_onion),
787 : REWRITE(rewrite_mapaddress_automap_onion2),
788 : REWRITE(rewrite_mapaddress_automap_onion3),
789 : REWRITE(rewrite_mapaddress_automap_onion4),
790 : REWRITE(rewrite_onion_v3),
791 :
792 : END_OF_TESTCASES
793 : };
|