1 /* Copyright (c) 2014-2021, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
6 #define CONNECTION_PRIVATE
7 #define CONNECTION_EDGE_PRIVATE
9 #include "core/or/or.h"
10 #include "test/test.h"
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"
19 #include "feature/hs/hs_cache.h"
21 #include "core/or/entry_connection_st.h"
22 #include "core/or/socks_request_st.h"
24 #include "lib/encoding/confline.h"
27 entryconn_rewrite_setup(const struct testcase_t
*tc
)
30 entry_connection_t
*ec
= entry_connection_new(CONN_TYPE_AP
, AF_INET
);
36 entryconn_rewrite_teardown(const struct testcase_t
*tc
, void *arg
)
39 entry_connection_t
*ec
= arg
;
41 connection_free_minimal(ENTRY_TO_CONN(ec
));
42 addressmap_free_all();
46 static struct testcase_setup_t test_rewrite_setup
= {
47 entryconn_rewrite_setup
, entryconn_rewrite_teardown
50 /* Simple rewrite: no changes needed */
52 test_entryconn_rewrite_basic(void *arg
)
54 entry_connection_t
*ec
= arg
;
57 tt_assert(ec
->socks_request
);
58 strlcpy(ec
->socks_request
->address
, "www.TORproject.org",
59 sizeof(ec
->socks_request
->address
));
60 ec
->socks_request
->command
= SOCKS_COMMAND_CONNECT
;
61 connection_ap_handshake_rewrite(ec
, &rr
);
63 tt_int_op(rr
.should_close
, OP_EQ
, 0);
64 tt_int_op(rr
.end_reason
, OP_EQ
, 0);
65 tt_int_op(rr
.automap
, OP_EQ
, 0);
66 tt_i64_op(rr
.map_expires
, OP_EQ
, TIME_MAX
);
67 tt_int_op(rr
.exit_source
, OP_EQ
, ADDRMAPSRC_NONE
);
68 tt_str_op(rr
.orig_address
, OP_EQ
, "www.torproject.org");
69 tt_str_op(ec
->socks_request
->address
, OP_EQ
, "www.torproject.org");
70 tt_str_op(ec
->original_dest_address
, OP_EQ
, "www.torproject.org");
76 /* Rewrite but reject because of disallowed .exit */
78 test_entryconn_rewrite_bad_dotexit(void *arg
)
80 entry_connection_t
*ec
= arg
;
83 tt_assert(ec
->socks_request
);
84 strlcpy(ec
->socks_request
->address
, "www.TORproject.org.foo.exit",
85 sizeof(ec
->socks_request
->address
));
86 ec
->socks_request
->command
= SOCKS_COMMAND_CONNECT
;
87 connection_ap_handshake_rewrite(ec
, &rr
);
89 tt_int_op(rr
.should_close
, OP_EQ
, 1);
90 tt_int_op(rr
.end_reason
, OP_EQ
, END_STREAM_REASON_TORPROTOCOL
);
96 /* Automap on resolve, connect to automapped address, resolve again and get
97 * same answer. (IPv4) */
99 test_entryconn_rewrite_automap_ipv4(void *arg
)
101 entry_connection_t
*ec
= arg
;
102 entry_connection_t
*ec2
=NULL
, *ec3
=NULL
;
106 ec2
= entry_connection_new(CONN_TYPE_AP
, AF_INET
);
107 ec3
= entry_connection_new(CONN_TYPE_AP
, AF_INET
);
109 get_options_mutable()->AutomapHostsOnResolve
= 1;
110 smartlist_add_strdup(get_options_mutable()->AutomapHostsSuffixes
, ".");
111 parse_virtual_addr_network("127.202.0.0/16", AF_INET
, 0, &msg
);
113 /* Automap this on resolve. */
114 strlcpy(ec
->socks_request
->address
, "WWW.MIT.EDU",
115 sizeof(ec
->socks_request
->address
));
116 ec
->socks_request
->command
= SOCKS_COMMAND_RESOLVE
;
117 connection_ap_handshake_rewrite(ec
, &rr
);
119 tt_int_op(rr
.automap
, OP_EQ
, 1);
120 tt_int_op(rr
.should_close
, OP_EQ
, 0);
121 tt_int_op(rr
.end_reason
, OP_EQ
, 0);
122 tt_i64_op(rr
.map_expires
, OP_EQ
, TIME_MAX
);
123 tt_int_op(rr
.exit_source
, OP_EQ
, ADDRMAPSRC_NONE
);
124 tt_str_op(rr
.orig_address
, OP_EQ
, "www.mit.edu");
125 tt_str_op(ec
->original_dest_address
, OP_EQ
, "www.mit.edu");
127 tt_assert(!strcmpstart(ec
->socks_request
->address
,"127.202."));
129 /* Connect to it and make sure we get the original address back. */
130 strlcpy(ec2
->socks_request
->address
, ec
->socks_request
->address
,
131 sizeof(ec2
->socks_request
->address
));
133 ec2
->socks_request
->command
= SOCKS_COMMAND_CONNECT
;
134 connection_ap_handshake_rewrite(ec2
, &rr
);
136 tt_int_op(rr
.automap
, OP_EQ
, 0);
137 tt_int_op(rr
.should_close
, OP_EQ
, 0);
138 tt_int_op(rr
.end_reason
, OP_EQ
, 0);
139 tt_i64_op(rr
.map_expires
, OP_EQ
, TIME_MAX
);
140 tt_int_op(rr
.exit_source
, OP_EQ
, ADDRMAPSRC_NONE
);
141 tt_str_op(rr
.orig_address
, OP_EQ
, ec
->socks_request
->address
);
142 tt_str_op(ec2
->original_dest_address
, OP_EQ
, ec
->socks_request
->address
);
143 tt_str_op(ec2
->socks_request
->address
, OP_EQ
, "www.mit.edu");
145 /* Resolve it again, make sure the answer is the same. */
146 strlcpy(ec3
->socks_request
->address
, "www.MIT.EDU",
147 sizeof(ec3
->socks_request
->address
));
148 ec3
->socks_request
->command
= SOCKS_COMMAND_RESOLVE
;
149 connection_ap_handshake_rewrite(ec3
, &rr
);
151 tt_int_op(rr
.automap
, OP_EQ
, 1);
152 tt_int_op(rr
.should_close
, OP_EQ
, 0);
153 tt_int_op(rr
.end_reason
, OP_EQ
, 0);
154 tt_i64_op(rr
.map_expires
, OP_EQ
, TIME_MAX
);
155 tt_int_op(rr
.exit_source
, OP_EQ
, ADDRMAPSRC_NONE
);
156 tt_str_op(rr
.orig_address
, OP_EQ
, "www.mit.edu");
157 tt_str_op(ec3
->original_dest_address
, OP_EQ
, "www.mit.edu");
159 tt_str_op(ec3
->socks_request
->address
, OP_EQ
,
160 ec
->socks_request
->address
);
163 connection_free_minimal(ENTRY_TO_CONN(ec2
));
164 connection_free_minimal(ENTRY_TO_CONN(ec3
));
167 /* Automap on resolve, connect to automapped address, resolve again and get
168 * same answer. (IPv6) */
170 test_entryconn_rewrite_automap_ipv6(void *arg
)
173 entry_connection_t
*ec
=NULL
;
174 entry_connection_t
*ec2
=NULL
, *ec3
=NULL
;
178 ec
= entry_connection_new(CONN_TYPE_AP
, AF_INET6
);
179 ec2
= entry_connection_new(CONN_TYPE_AP
, AF_INET6
);
180 ec3
= entry_connection_new(CONN_TYPE_AP
, AF_INET6
);
182 get_options_mutable()->AutomapHostsOnResolve
= 1;
183 smartlist_add_strdup(get_options_mutable()->AutomapHostsSuffixes
, ".");
184 parse_virtual_addr_network("FE80::/32", AF_INET6
, 0, &msg
);
186 /* Automap this on resolve. */
187 strlcpy(ec
->socks_request
->address
, "WWW.MIT.EDU",
188 sizeof(ec
->socks_request
->address
));
189 ec
->socks_request
->command
= SOCKS_COMMAND_RESOLVE
;
190 connection_ap_handshake_rewrite(ec
, &rr
);
192 tt_int_op(rr
.automap
, OP_EQ
, 1);
193 tt_int_op(rr
.should_close
, OP_EQ
, 0);
194 tt_int_op(rr
.end_reason
, OP_EQ
, 0);
195 tt_i64_op(rr
.map_expires
, OP_EQ
, TIME_MAX
);
196 tt_int_op(rr
.exit_source
, OP_EQ
, ADDRMAPSRC_NONE
);
197 tt_str_op(rr
.orig_address
, OP_EQ
, "www.mit.edu");
198 tt_str_op(ec
->original_dest_address
, OP_EQ
, "www.mit.edu");
200 /* Yes, this [ should be here. */
201 tt_assert(!strcmpstart(ec
->socks_request
->address
,"[fe80:"));
203 /* Connect to it and make sure we get the original address back. */
204 strlcpy(ec2
->socks_request
->address
, ec
->socks_request
->address
,
205 sizeof(ec2
->socks_request
->address
));
207 ec2
->socks_request
->command
= SOCKS_COMMAND_CONNECT
;
208 connection_ap_handshake_rewrite(ec2
, &rr
);
210 tt_int_op(rr
.automap
, OP_EQ
, 0);
211 tt_int_op(rr
.should_close
, OP_EQ
, 0);
212 tt_int_op(rr
.end_reason
, OP_EQ
, 0);
213 tt_i64_op(rr
.map_expires
, OP_EQ
, TIME_MAX
);
214 tt_int_op(rr
.exit_source
, OP_EQ
, ADDRMAPSRC_NONE
);
215 tt_str_op(rr
.orig_address
, OP_EQ
, ec
->socks_request
->address
);
216 tt_str_op(ec2
->original_dest_address
, OP_EQ
, ec
->socks_request
->address
);
217 tt_str_op(ec2
->socks_request
->address
, OP_EQ
, "www.mit.edu");
219 /* Resolve it again, make sure the answer is the same. */
220 strlcpy(ec3
->socks_request
->address
, "www.MIT.EDU",
221 sizeof(ec3
->socks_request
->address
));
222 ec3
->socks_request
->command
= SOCKS_COMMAND_RESOLVE
;
223 connection_ap_handshake_rewrite(ec3
, &rr
);
225 tt_int_op(rr
.automap
, OP_EQ
, 1);
226 tt_int_op(rr
.should_close
, OP_EQ
, 0);
227 tt_int_op(rr
.end_reason
, OP_EQ
, 0);
228 tt_i64_op(rr
.map_expires
, OP_EQ
, TIME_MAX
);
229 tt_int_op(rr
.exit_source
, OP_EQ
, ADDRMAPSRC_NONE
);
230 tt_str_op(rr
.orig_address
, OP_EQ
, "www.mit.edu");
231 tt_str_op(ec3
->original_dest_address
, OP_EQ
, "www.mit.edu");
233 tt_str_op(ec3
->socks_request
->address
, OP_EQ
,
234 ec
->socks_request
->address
);
237 connection_free_minimal(ENTRY_TO_CONN(ec
));
238 connection_free_minimal(ENTRY_TO_CONN(ec2
));
239 connection_free_minimal(ENTRY_TO_CONN(ec3
));
243 /* FFFF not actually supported. */
244 /* automap on resolve, reverse lookup. */
246 test_entryconn_rewrite_automap_reverse(void *arg
)
248 entry_connection_t
*ec
= arg
;
249 entry_connection_t
*ec2
=NULL
;
253 ec2
= entry_connection_new(CONN_TYPE_AP
, AF_INET
);
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
);
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
);
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");
275 tt_assert(!strcmpstart(ec
->socks_request
->address
,"127.80."));
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
);
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
);
290 connection_free_minimal(ENTRY_TO_CONN(ec2
));
294 /* Rewrite because of cached DNS entry. */
296 test_entryconn_rewrite_cached_dns_ipv4(void *arg
)
298 entry_connection_t
*ec
= arg
;
300 time_t expires
= time(NULL
) + 3600;
301 entry_connection_t
*ec2
=NULL
;
303 ec2
= entry_connection_new(CONN_TYPE_AP
, AF_INET
);
305 addressmap_register("www.friendly.example.com",
306 tor_strdup("240.240.241.241"),
311 strlcpy(ec
->socks_request
->address
, "www.friendly.example.com",
312 sizeof(ec
->socks_request
->address
));
313 strlcpy(ec2
->socks_request
->address
, "www.friendly.example.com",
314 sizeof(ec2
->socks_request
->address
));
316 ec
->socks_request
->command
= SOCKS_COMMAND_CONNECT
;
317 ec2
->socks_request
->command
= SOCKS_COMMAND_CONNECT
;
319 ec2
->entry_cfg
.use_cached_ipv4_answers
= 1; /* only ec2 gets this flag */
320 connection_ap_handshake_rewrite(ec
, &rr
);
322 tt_int_op(rr
.automap
, OP_EQ
, 0);
323 tt_int_op(rr
.should_close
, OP_EQ
, 0);
324 tt_int_op(rr
.end_reason
, OP_EQ
, 0);
325 tt_i64_op(rr
.map_expires
, OP_EQ
, TIME_MAX
);
326 tt_int_op(rr
.exit_source
, OP_EQ
, ADDRMAPSRC_NONE
);
327 tt_str_op(rr
.orig_address
, OP_EQ
, "www.friendly.example.com");
328 tt_str_op(ec
->socks_request
->address
, OP_EQ
, "www.friendly.example.com");
330 connection_ap_handshake_rewrite(ec2
, &rr
);
331 tt_int_op(rr
.automap
, OP_EQ
, 0);
332 tt_int_op(rr
.should_close
, OP_EQ
, 0);
333 tt_int_op(rr
.end_reason
, OP_EQ
, 0);
334 tt_i64_op(rr
.map_expires
, OP_EQ
, expires
);
335 tt_int_op(rr
.exit_source
, OP_EQ
, ADDRMAPSRC_NONE
);
336 tt_str_op(rr
.orig_address
, OP_EQ
, "www.friendly.example.com");
337 tt_str_op(ec2
->socks_request
->address
, OP_EQ
, "240.240.241.241");
340 connection_free_minimal(ENTRY_TO_CONN(ec2
));
343 /* Rewrite because of cached DNS entry. */
345 test_entryconn_rewrite_cached_dns_ipv6(void *arg
)
347 entry_connection_t
*ec
= NULL
;
349 time_t expires
= time(NULL
) + 3600;
350 entry_connection_t
*ec2
=NULL
;
354 ec
= entry_connection_new(CONN_TYPE_AP
, AF_INET6
);
355 ec2
= entry_connection_new(CONN_TYPE_AP
, AF_INET6
);
357 addressmap_register("www.friendly.example.com",
358 tor_strdup("[::f00f]"),
363 strlcpy(ec
->socks_request
->address
, "www.friendly.example.com",
364 sizeof(ec
->socks_request
->address
));
365 strlcpy(ec2
->socks_request
->address
, "www.friendly.example.com",
366 sizeof(ec2
->socks_request
->address
));
368 ec
->socks_request
->command
= SOCKS_COMMAND_CONNECT
;
369 ec2
->socks_request
->command
= SOCKS_COMMAND_CONNECT
;
371 ec2
->entry_cfg
.use_cached_ipv6_answers
= 1; /* only ec2 gets this flag */
372 connection_ap_handshake_rewrite(ec
, &rr
);
374 tt_int_op(rr
.automap
, OP_EQ
, 0);
375 tt_int_op(rr
.should_close
, OP_EQ
, 0);
376 tt_int_op(rr
.end_reason
, OP_EQ
, 0);
377 tt_i64_op(rr
.map_expires
, OP_EQ
, TIME_MAX
);
378 tt_int_op(rr
.exit_source
, OP_EQ
, ADDRMAPSRC_NONE
);
379 tt_str_op(rr
.orig_address
, OP_EQ
, "www.friendly.example.com");
380 tt_str_op(ec
->socks_request
->address
, OP_EQ
, "www.friendly.example.com");
382 connection_ap_handshake_rewrite(ec2
, &rr
);
383 tt_int_op(rr
.automap
, OP_EQ
, 0);
384 tt_int_op(rr
.should_close
, OP_EQ
, 0);
385 tt_int_op(rr
.end_reason
, OP_EQ
, 0);
386 tt_i64_op(rr
.map_expires
, OP_EQ
, expires
);
387 tt_int_op(rr
.exit_source
, OP_EQ
, ADDRMAPSRC_NONE
);
388 tt_str_op(rr
.orig_address
, OP_EQ
, "www.friendly.example.com");
389 tt_str_op(ec2
->socks_request
->address
, OP_EQ
, "[::f00f]");
392 connection_free_minimal(ENTRY_TO_CONN(ec
));
393 connection_free_minimal(ENTRY_TO_CONN(ec2
));
396 /* Fail to connect to unmapped address in virtual range. */
398 test_entryconn_rewrite_unmapped_virtual(void *arg
)
400 entry_connection_t
*ec
= arg
;
402 entry_connection_t
*ec2
= NULL
;
405 ec2
= entry_connection_new(CONN_TYPE_AP
, AF_INET6
);
407 parse_virtual_addr_network("18.202.0.0/16", AF_INET
, 0, &msg
);
408 parse_virtual_addr_network("[ABCD::]/16", AF_INET6
, 0, &msg
);
410 strlcpy(ec
->socks_request
->address
, "18.202.5.5",
411 sizeof(ec
->socks_request
->address
));
412 ec
->socks_request
->command
= SOCKS_COMMAND_CONNECT
;
413 connection_ap_handshake_rewrite(ec
, &rr
);
415 tt_int_op(rr
.should_close
, OP_EQ
, 1);
416 tt_int_op(rr
.end_reason
, OP_EQ
, END_STREAM_REASON_INTERNAL
);
417 tt_int_op(rr
.automap
, OP_EQ
, 0);
418 tt_i64_op(rr
.map_expires
, OP_EQ
, TIME_MAX
);
419 tt_int_op(rr
.exit_source
, OP_EQ
, ADDRMAPSRC_NONE
);
421 strlcpy(ec2
->socks_request
->address
, "[ABCD:9::5314:9543]",
422 sizeof(ec2
->socks_request
->address
));
423 ec2
->socks_request
->command
= SOCKS_COMMAND_CONNECT
;
424 connection_ap_handshake_rewrite(ec2
, &rr
);
426 tt_int_op(rr
.should_close
, OP_EQ
, 1);
427 tt_int_op(rr
.end_reason
, OP_EQ
, END_STREAM_REASON_INTERNAL
);
428 tt_int_op(rr
.automap
, OP_EQ
, 0);
429 tt_i64_op(rr
.map_expires
, OP_EQ
, TIME_MAX
);
430 tt_int_op(rr
.exit_source
, OP_EQ
, ADDRMAPSRC_NONE
);
433 connection_free_minimal(ENTRY_TO_CONN(ec2
));
436 /* Rewrite because of mapaddress option */
438 test_entryconn_rewrite_mapaddress(void *arg
)
440 entry_connection_t
*ec
= arg
;
443 config_line_append(&get_options_mutable()->AddressMap
,
444 "MapAddress", "meta metaobjects.example");
445 config_register_addressmaps(get_options());
447 strlcpy(ec
->socks_request
->address
, "meta",
448 sizeof(ec
->socks_request
->address
));
449 ec
->socks_request
->command
= SOCKS_COMMAND_CONNECT
;
450 connection_ap_handshake_rewrite(ec
, &rr
);
452 tt_int_op(rr
.should_close
, OP_EQ
, 0);
453 tt_int_op(rr
.end_reason
, OP_EQ
, 0);
454 tt_int_op(rr
.automap
, OP_EQ
, 0);
455 tt_i64_op(rr
.map_expires
, OP_EQ
, TIME_MAX
);
456 tt_int_op(rr
.exit_source
, OP_EQ
, ADDRMAPSRC_NONE
);
457 tt_str_op(ec
->socks_request
->address
, OP_EQ
, "metaobjects.example");
463 /* Reject reverse lookups of internal address. */
465 test_entryconn_rewrite_reject_internal_reverse(void *arg
)
467 entry_connection_t
*ec
= arg
;
470 strlcpy(ec
->socks_request
->address
, "10.0.0.1",
471 sizeof(ec
->socks_request
->address
));
472 ec
->socks_request
->command
= SOCKS_COMMAND_RESOLVE_PTR
;
473 connection_ap_handshake_rewrite(ec
, &rr
);
475 tt_int_op(rr
.should_close
, OP_EQ
, 1);
476 tt_int_op(rr
.end_reason
, OP_EQ
, END_STREAM_REASON_SOCKSPROTOCOL
|
477 END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED
);
478 tt_int_op(rr
.automap
, OP_EQ
, 0);
479 tt_i64_op(rr
.map_expires
, OP_EQ
, TIME_MAX
);
480 tt_int_op(rr
.exit_source
, OP_EQ
, ADDRMAPSRC_NONE
);
486 /* Rewrite into .exit because of virtual address mapping. */
488 test_entryconn_rewrite_automap_exit(void *arg
)
490 entry_connection_t
*ec
= arg
;
491 entry_connection_t
*ec2
=NULL
;
495 ec2
= entry_connection_new(CONN_TYPE_AP
, AF_INET
);
497 smartlist_add_strdup(get_options_mutable()->AutomapHostsSuffixes
,
499 parse_virtual_addr_network("127.1.0.0/16", AF_INET
, 0, &msg
);
501 /* Try to automap this on resolve. */
502 strlcpy(ec
->socks_request
->address
, "website.example.exit",
503 sizeof(ec
->socks_request
->address
));
504 ec
->socks_request
->command
= SOCKS_COMMAND_RESOLVE
;
505 connection_ap_handshake_rewrite(ec
, &rr
);
507 /* Make sure it isn't allowed -- there is no longer an AllowDotExit
509 tt_int_op(rr
.automap
, OP_EQ
, 0);
510 tt_int_op(rr
.should_close
, OP_EQ
, 1);
511 tt_int_op(rr
.end_reason
, OP_EQ
, END_STREAM_REASON_TORPROTOCOL
);
514 connection_free_minimal(ENTRY_TO_CONN(ec2
));
517 /* Rewrite into .exit because of mapaddress */
519 test_entryconn_rewrite_mapaddress_exit(void *arg
)
521 entry_connection_t
*ec
= arg
;
524 config_line_append(&get_options_mutable()->AddressMap
,
525 "MapAddress", "*.example.com *.example.com.abc.exit");
526 config_register_addressmaps(get_options());
528 /* Automap this on resolve. */
529 strlcpy(ec
->socks_request
->address
, "abc.example.com",
530 sizeof(ec
->socks_request
->address
));
531 ec
->socks_request
->command
= SOCKS_COMMAND_CONNECT
;
532 connection_ap_handshake_rewrite(ec
, &rr
);
534 tt_int_op(rr
.automap
, OP_EQ
, 0);
535 tt_int_op(rr
.should_close
, OP_EQ
, 0);
536 tt_int_op(rr
.end_reason
, OP_EQ
, 0);
537 tt_i64_op(rr
.map_expires
, OP_EQ
, TIME_MAX
);
538 tt_int_op(rr
.exit_source
, OP_EQ
, ADDRMAPSRC_TORRC
);
539 tt_str_op(rr
.orig_address
, OP_EQ
, "abc.example.com");
540 tt_str_op(ec
->socks_request
->address
, OP_EQ
, "abc.example.com.abc.exit");
545 /* Map foo.onion to longthing.onion, and also automap. */
547 test_entryconn_rewrite_mapaddress_automap_onion(void *arg
)
549 entry_connection_t
*ec
= arg
;
550 entry_connection_t
*ec2
= NULL
;
551 entry_connection_t
*ec3
= NULL
;
552 entry_connection_t
*ec4
= NULL
;
556 ec2
= entry_connection_new(CONN_TYPE_AP
, AF_INET
);
557 ec3
= entry_connection_new(CONN_TYPE_AP
, AF_INET
);
558 ec4
= entry_connection_new(CONN_TYPE_AP
, AF_INET
);
560 get_options_mutable()->AutomapHostsOnResolve
= 1;
561 smartlist_add_strdup(get_options_mutable()->AutomapHostsSuffixes
,
563 parse_virtual_addr_network("192.168.0.0/16", AF_INET
, 0, &msg
);
564 config_line_append(&get_options_mutable()->AddressMap
,
565 "MapAddress", "foo.onion abcdefghijklmnop.onion");
566 config_register_addressmaps(get_options());
568 /* Connect to foo.onion. */
569 strlcpy(ec
->socks_request
->address
, "foo.onion",
570 sizeof(ec
->socks_request
->address
));
571 ec
->socks_request
->command
= SOCKS_COMMAND_CONNECT
;
572 connection_ap_handshake_rewrite(ec
, &rr
);
574 tt_int_op(rr
.automap
, OP_EQ
, 0);
575 tt_int_op(rr
.should_close
, OP_EQ
, 0);
576 tt_int_op(rr
.end_reason
, OP_EQ
, 0);
577 tt_i64_op(rr
.map_expires
, OP_EQ
, TIME_MAX
);
578 tt_int_op(rr
.exit_source
, OP_EQ
, ADDRMAPSRC_NONE
);
579 tt_str_op(rr
.orig_address
, OP_EQ
, "foo.onion");
580 tt_str_op(ec
->socks_request
->address
, OP_EQ
, "abcdefghijklmnop.onion");
582 /* Okay, resolve foo.onion */
583 strlcpy(ec2
->socks_request
->address
, "foo.onion",
584 sizeof(ec2
->socks_request
->address
));
585 ec2
->socks_request
->command
= SOCKS_COMMAND_RESOLVE
;
586 connection_ap_handshake_rewrite(ec2
, &rr
);
588 tt_int_op(rr
.automap
, OP_EQ
, 1);
589 tt_int_op(rr
.should_close
, OP_EQ
, 0);
590 tt_int_op(rr
.end_reason
, OP_EQ
, 0);
591 tt_i64_op(rr
.map_expires
, OP_EQ
, TIME_MAX
);
592 tt_int_op(rr
.exit_source
, OP_EQ
, ADDRMAPSRC_NONE
);
593 tt_str_op(rr
.orig_address
, OP_EQ
, "foo.onion");
594 tt_assert(!strcmpstart(ec2
->socks_request
->address
, "192.168."));
597 strlcpy(ec3
->socks_request
->address
, ec2
->socks_request
->address
,
598 sizeof(ec3
->socks_request
->address
));
599 ec3
->socks_request
->command
= SOCKS_COMMAND_CONNECT
;
600 connection_ap_handshake_rewrite(ec3
, &rr
);
601 tt_int_op(rr
.automap
, OP_EQ
, 0);
602 tt_int_op(rr
.should_close
, OP_EQ
, 0);
603 tt_int_op(rr
.end_reason
, OP_EQ
, 0);
604 tt_assert(!strcmpstart(ec3
->socks_request
->address
,
605 "abcdefghijklmnop.onion"));
607 /* Now resolve abcefghijklmnop.onion. */
608 strlcpy(ec4
->socks_request
->address
, "abcdefghijklmnop.onion",
609 sizeof(ec4
->socks_request
->address
));
610 ec4
->socks_request
->command
= SOCKS_COMMAND_RESOLVE
;
611 connection_ap_handshake_rewrite(ec4
, &rr
);
613 tt_int_op(rr
.automap
, OP_EQ
, 1);
614 tt_int_op(rr
.should_close
, OP_EQ
, 0);
615 tt_int_op(rr
.end_reason
, OP_EQ
, 0);
616 tt_i64_op(rr
.map_expires
, OP_EQ
, TIME_MAX
);
617 tt_int_op(rr
.exit_source
, OP_EQ
, ADDRMAPSRC_NONE
);
618 tt_str_op(rr
.orig_address
, OP_EQ
, "abcdefghijklmnop.onion");
619 tt_assert(!strcmpstart(ec4
->socks_request
->address
, "192.168."));
621 tt_str_op(ec4->socks_request->address, OP_EQ, ec2->socks_request->address);
625 connection_free_minimal(ENTRY_TO_CONN(ec2
));
626 connection_free_minimal(ENTRY_TO_CONN(ec3
));
627 connection_free_minimal(ENTRY_TO_CONN(ec4
));
631 test_entryconn_rewrite_mapaddress_automap_onion_common(entry_connection_t
*ec
,
635 entry_connection_t
*ec2
= NULL
;
636 entry_connection_t
*ec3
= NULL
;
639 ec2
= entry_connection_new(CONN_TYPE_AP
, AF_INET
);
640 ec3
= entry_connection_new(CONN_TYPE_AP
, AF_INET
);
642 /* Connect to irc.example.com */
643 strlcpy(ec
->socks_request
->address
, "irc.example.com",
644 sizeof(ec
->socks_request
->address
));
645 ec
->socks_request
->command
= SOCKS_COMMAND_CONNECT
;
646 connection_ap_handshake_rewrite(ec
, &rr
);
648 tt_int_op(rr
.automap
, OP_EQ
, 0);
649 tt_int_op(rr
.should_close
, OP_EQ
, 0);
650 tt_int_op(rr
.end_reason
, OP_EQ
, 0);
651 tt_i64_op(rr
.map_expires
, OP_EQ
, TIME_MAX
);
652 tt_int_op(rr
.exit_source
, OP_EQ
, ADDRMAPSRC_NONE
);
653 tt_str_op(rr
.orig_address
, OP_EQ
, "irc.example.com");
654 tt_str_op(ec
->socks_request
->address
, OP_EQ
,
655 map_to_onion
? "abcdefghijklmnop.onion" : "irc.example.com");
657 /* Okay, resolve irc.example.com */
658 strlcpy(ec2
->socks_request
->address
, "irc.example.com",
659 sizeof(ec2
->socks_request
->address
));
660 ec2
->socks_request
->command
= SOCKS_COMMAND_RESOLVE
;
661 connection_ap_handshake_rewrite(ec2
, &rr
);
663 tt_int_op(rr
.automap
, OP_EQ
, map_to_onion
&& map_to_address
);
664 tt_int_op(rr
.should_close
, OP_EQ
, 0);
665 tt_int_op(rr
.end_reason
, OP_EQ
, 0);
666 tt_i64_op(rr
.map_expires
, OP_EQ
, TIME_MAX
);
667 tt_int_op(rr
.exit_source
, OP_EQ
, ADDRMAPSRC_NONE
);
668 tt_str_op(rr
.orig_address
, OP_EQ
, "irc.example.com");
669 if (map_to_onion
&& map_to_address
)
670 tt_assert(!strcmpstart(ec2
->socks_request
->address
, "192.168."));
673 strlcpy(ec3
->socks_request
->address
, ec2
->socks_request
->address
,
674 sizeof(ec3
->socks_request
->address
));
675 ec3
->socks_request
->command
= SOCKS_COMMAND_CONNECT
;
676 connection_ap_handshake_rewrite(ec3
, &rr
);
677 tt_int_op(rr
.automap
, OP_EQ
, 0);
678 tt_int_op(rr
.should_close
, OP_EQ
, 0);
679 tt_int_op(rr
.end_reason
, OP_EQ
, 0);
681 tt_assert(!strcmpstart(ec3
->socks_request
->address
,
682 "abcdefghijklmnop.onion"));
685 connection_free_minimal(ENTRY_TO_CONN(ec2
));
686 connection_free_minimal(ENTRY_TO_CONN(ec3
));
689 /* This time is the same, but we start with a mapping from a non-onion
692 test_entryconn_rewrite_mapaddress_automap_onion2(void *arg
)
695 get_options_mutable()->AutomapHostsOnResolve
= 1;
696 smartlist_add_strdup(get_options_mutable()->AutomapHostsSuffixes
,
698 parse_virtual_addr_network("192.168.0.0/16", AF_INET
, 0, &msg
);
699 config_line_append(&get_options_mutable()->AddressMap
,
700 "MapAddress", "irc.example.com abcdefghijklmnop.onion");
701 config_register_addressmaps(get_options());
703 test_entryconn_rewrite_mapaddress_automap_onion_common(arg
, 1, 1);
706 /* Same as above, with automapped turned off */
708 test_entryconn_rewrite_mapaddress_automap_onion3(void *arg
)
710 config_line_append(&get_options_mutable()->AddressMap
,
711 "MapAddress", "irc.example.com abcdefghijklmnop.onion");
712 config_register_addressmaps(get_options());
714 test_entryconn_rewrite_mapaddress_automap_onion_common(arg
, 1, 0);
717 /* As above, with no mapping. */
719 test_entryconn_rewrite_mapaddress_automap_onion4(void *arg
)
722 get_options_mutable()->AutomapHostsOnResolve
= 1;
723 smartlist_add_strdup(get_options_mutable()->AutomapHostsSuffixes
,
725 parse_virtual_addr_network("192.168.0.0/16", AF_INET
, 0, &msg
);
727 test_entryconn_rewrite_mapaddress_automap_onion_common(arg
, 0, 1);
730 /** Test that rewrite functions can handle v3 onion addresses */
732 test_entryconn_rewrite_onion_v3(void *arg
)
735 entry_connection_t
*conn
= arg
;
741 /* Make a SOCKS request */
742 conn
->socks_request
->command
= SOCKS_COMMAND_CONNECT
;
743 strlcpy(conn
->socks_request
->address
,
744 "git.25njqamcweflpvkl73j4szahhihoc4xt3ktcgjnpaingr5yhkenl5sid.onion",
745 sizeof(conn
->socks_request
->address
));
747 /* Make an onion connection using the SOCKS request */
748 conn
->entry_cfg
.onion_traffic
= 1;
749 ENTRY_TO_CONN(conn
)->state
= AP_CONN_STATE_SOCKS_WAIT
;
750 tt_assert(!ENTRY_TO_EDGE_CONN(conn
)->hs_ident
);
752 /* Handle SOCKS and rewrite! */
753 retval
= connection_ap_handshake_rewrite_and_attach(conn
, NULL
, NULL
);
754 tt_int_op(retval
, OP_EQ
, 0);
756 /* Check connection state after rewrite. It should be in waiting for
757 * descriptor state. */
758 tt_int_op(ENTRY_TO_CONN(conn
)->state
, OP_EQ
, AP_CONN_STATE_RENDDESC_WAIT
);
759 /* check that the address got rewritten */
760 tt_str_op(conn
->socks_request
->address
, OP_EQ
,
761 "25njqamcweflpvkl73j4szahhihoc4xt3ktcgjnpaingr5yhkenl5sid");
762 /* check that HS information got attached to the connection */
763 tt_assert(ENTRY_TO_EDGE_CONN(conn
)->hs_ident
);
767 /* 'conn' is cleaned by handler */
770 #define REWRITE(name) \
771 { #name, test_entryconn_##name, TT_FORK, &test_rewrite_setup, NULL }
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
),