Split the authority-cert and signature/hash code from routerparse
[tor.git] / src / test / test_extorport.c
blob71be9131c7b04bf9dd71e960ef1b0e56213e5943
1 /* Copyright (c) 2013-2018, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
4 #define CONNECTION_PRIVATE
5 #define EXT_ORPORT_PRIVATE
6 #define MAINLOOP_PRIVATE
7 #include "core/or/or.h"
8 #include "lib/container/buffers.h"
9 #include "core/mainloop/connection.h"
10 #include "core/or/connection_or.h"
11 #include "app/config/config.h"
12 #include "feature/control/control.h"
13 #include "lib/crypt_ops/crypto_rand.h"
14 #include "feature/relay/ext_orport.h"
15 #include "core/mainloop/mainloop.h"
17 #include "core/or/or_connection_st.h"
19 #include "test/test.h"
20 #include "test/test_helpers.h"
22 #ifdef HAVE_SYS_STAT_H
23 #include <sys/stat.h>
24 #endif
26 /* Test connection_or_remove_from_ext_or_id_map and
27 * connection_or_set_ext_or_identifier */
28 static void
29 test_ext_or_id_map(void *arg)
31 or_connection_t *c1 = NULL, *c2 = NULL, *c3 = NULL;
32 char *idp = NULL, *idp2 = NULL;
33 (void)arg;
35 /* pre-initialization */
36 tt_ptr_op(NULL, OP_EQ,
37 connection_or_get_by_ext_or_id("xxxxxxxxxxxxxxxxxxxx"));
39 c1 = or_connection_new(CONN_TYPE_EXT_OR, AF_INET);
40 c2 = or_connection_new(CONN_TYPE_EXT_OR, AF_INET);
41 c3 = or_connection_new(CONN_TYPE_OR, AF_INET);
43 tt_ptr_op(c1->ext_or_conn_id, OP_NE, NULL);
44 tt_ptr_op(c2->ext_or_conn_id, OP_NE, NULL);
45 tt_ptr_op(c3->ext_or_conn_id, OP_EQ, NULL);
47 tt_ptr_op(c1, OP_EQ, connection_or_get_by_ext_or_id(c1->ext_or_conn_id));
48 tt_ptr_op(c2, OP_EQ, connection_or_get_by_ext_or_id(c2->ext_or_conn_id));
49 tt_ptr_op(NULL, OP_EQ,
50 connection_or_get_by_ext_or_id("xxxxxxxxxxxxxxxxxxxx"));
52 idp = tor_memdup(c2->ext_or_conn_id, EXT_OR_CONN_ID_LEN);
54 /* Give c2 a new ID. */
55 connection_or_set_ext_or_identifier(c2);
56 tt_mem_op(idp, OP_NE, c2->ext_or_conn_id, EXT_OR_CONN_ID_LEN);
57 idp2 = tor_memdup(c2->ext_or_conn_id, EXT_OR_CONN_ID_LEN);
58 tt_assert(!tor_digest_is_zero(idp2));
60 tt_ptr_op(NULL, OP_EQ, connection_or_get_by_ext_or_id(idp));
61 tt_ptr_op(c2, OP_EQ, connection_or_get_by_ext_or_id(idp2));
63 /* Now remove it. */
64 connection_or_remove_from_ext_or_id_map(c2);
65 tt_ptr_op(NULL, OP_EQ, connection_or_get_by_ext_or_id(idp));
66 tt_ptr_op(NULL, OP_EQ, connection_or_get_by_ext_or_id(idp2));
68 done:
69 if (c1)
70 connection_free_minimal(TO_CONN(c1));
71 if (c2)
72 connection_free_minimal(TO_CONN(c2));
73 if (c3)
74 connection_free_minimal(TO_CONN(c3));
75 tor_free(idp);
76 tor_free(idp2);
77 connection_or_clear_ext_or_id_map();
80 /* Simple connection_write_to_buf_impl_ replacement that unconditionally
81 * writes to outbuf. */
82 static void
83 connection_write_to_buf_impl_replacement(const char *string, size_t len,
84 connection_t *conn, int compressed)
86 (void) compressed;
88 tor_assert(string);
89 tor_assert(conn);
90 buf_add(conn->outbuf, string, len);
93 static void
94 test_ext_or_write_command(void *arg)
96 or_connection_t *c1;
97 char *cp = NULL;
98 char *buf = NULL;
99 size_t sz;
101 (void) arg;
102 MOCK(connection_write_to_buf_impl_,
103 connection_write_to_buf_impl_replacement);
105 c1 = or_connection_new(CONN_TYPE_EXT_OR, AF_INET);
106 tt_assert(c1);
108 /* Length too long */
109 tt_int_op(connection_write_ext_or_command(TO_CONN(c1), 100, "X", 100000),
110 OP_LT, 0);
112 /* Empty command */
113 tt_int_op(connection_write_ext_or_command(TO_CONN(c1), 0x99, NULL, 0),
114 OP_EQ, 0);
115 cp = buf_get_contents(TO_CONN(c1)->outbuf, &sz);
116 tt_int_op(sz, OP_EQ, 4);
117 tt_mem_op(cp, OP_EQ, "\x00\x99\x00\x00", 4);
118 tor_free(cp);
120 /* Medium command. */
121 tt_int_op(connection_write_ext_or_command(TO_CONN(c1), 0x99,
122 "Wai\0Hello", 9), OP_EQ, 0);
123 cp = buf_get_contents(TO_CONN(c1)->outbuf, &sz);
124 tt_int_op(sz, OP_EQ, 13);
125 tt_mem_op(cp, OP_EQ, "\x00\x99\x00\x09Wai\x00Hello", 13);
126 tor_free(cp);
128 /* Long command */
129 buf = tor_malloc(65535);
130 memset(buf, 'x', 65535);
131 tt_int_op(connection_write_ext_or_command(TO_CONN(c1), 0xf00d,
132 buf, 65535), OP_EQ, 0);
133 cp = buf_get_contents(TO_CONN(c1)->outbuf, &sz);
134 tt_int_op(sz, OP_EQ, 65539);
135 tt_mem_op(cp, OP_EQ, "\xf0\x0d\xff\xff", 4);
136 tt_mem_op(cp+4, OP_EQ, buf, 65535);
137 tor_free(cp);
139 done:
140 if (c1)
141 connection_free_minimal(TO_CONN(c1));
142 tor_free(cp);
143 tor_free(buf);
144 UNMOCK(connection_write_to_buf_impl_);
147 static int
148 write_bytes_to_file_fail(const char *fname, const char *str, size_t len,
149 int bin)
151 (void) fname;
152 (void) str;
153 (void) len;
154 (void) bin;
156 return -1;
159 static void
160 test_ext_or_init_auth(void *arg)
162 or_options_t *options = get_options_mutable();
163 const char *fn;
164 char *cp = NULL;
165 struct stat st;
166 char cookie0[32];
167 (void)arg;
169 /* Check default filename location */
170 tor_free(options->DataDirectory);
171 options->DataDirectory = tor_strdup("foo");
172 cp = get_ext_or_auth_cookie_file_name();
173 tt_str_op(cp, OP_EQ, "foo"PATH_SEPARATOR"extended_orport_auth_cookie");
174 tor_free(cp);
176 /* Shouldn't be initialized already, or our tests will be a bit
177 * meaningless */
178 ext_or_auth_cookie = tor_malloc_zero(32);
179 tt_assert(tor_mem_is_zero((char*)ext_or_auth_cookie, 32));
181 /* Now make sure we use a temporary file */
182 fn = get_fname("ext_cookie_file");
183 options->ExtORPortCookieAuthFile = tor_strdup(fn);
184 cp = get_ext_or_auth_cookie_file_name();
185 tt_str_op(cp, OP_EQ, fn);
186 tor_free(cp);
188 /* Test the initialization function with a broken
189 write_bytes_to_file(). See if the problem is handled properly. */
190 MOCK(write_bytes_to_file, write_bytes_to_file_fail);
191 tt_int_op(-1, OP_EQ, init_ext_or_cookie_authentication(1));
192 tt_int_op(ext_or_auth_cookie_is_set, OP_EQ, 0);
193 UNMOCK(write_bytes_to_file);
195 /* Now do the actual initialization. */
196 tt_int_op(0, OP_EQ, init_ext_or_cookie_authentication(1));
197 tt_int_op(ext_or_auth_cookie_is_set, OP_EQ, 1);
198 cp = read_file_to_str(fn, RFTS_BIN, &st);
199 tt_ptr_op(cp, OP_NE, NULL);
200 tt_u64_op((uint64_t)st.st_size, OP_EQ, 64);
201 tt_mem_op(cp,OP_EQ, "! Extended ORPort Auth Cookie !\x0a", 32);
202 tt_mem_op(cp+32,OP_EQ, ext_or_auth_cookie, 32);
203 memcpy(cookie0, ext_or_auth_cookie, 32);
204 tt_assert(!tor_mem_is_zero((char*)ext_or_auth_cookie, 32));
206 /* Operation should be idempotent. */
207 tt_int_op(0, OP_EQ, init_ext_or_cookie_authentication(1));
208 tt_mem_op(cookie0,OP_EQ, ext_or_auth_cookie, 32);
210 done:
211 tor_free(cp);
212 ext_orport_free_all();
215 static void
216 test_ext_or_cookie_auth(void *arg)
218 char *reply=NULL, *reply2=NULL, *client_hash=NULL, *client_hash2=NULL;
219 size_t reply_len=0;
220 char hmac1[32], hmac2[32];
222 const char client_nonce[32] =
223 "Who is the third who walks alway";
224 char server_hash_input[] =
225 "ExtORPort authentication server-to-client hash"
226 "Who is the third who walks alway"
227 "................................";
228 char client_hash_input[] =
229 "ExtORPort authentication client-to-server hash"
230 "Who is the third who walks alway"
231 "................................";
233 (void)arg;
235 tt_int_op(strlen(client_hash_input), OP_EQ, 46+32+32);
236 tt_int_op(strlen(server_hash_input), OP_EQ, 46+32+32);
238 ext_or_auth_cookie = tor_malloc_zero(32);
239 memcpy(ext_or_auth_cookie, "s beside you? When I count, ther", 32);
240 ext_or_auth_cookie_is_set = 1;
242 /* For this authentication, the client sends 32 random bytes (ClientNonce)
243 * The server replies with 32 byte ServerHash and 32 byte ServerNonce,
244 * where ServerHash is:
245 * HMAC-SHA256(CookieString,
246 * "ExtORPort authentication server-to-client hash" | ClientNonce |
247 * ServerNonce)"
248 * The client must reply with 32-byte ClientHash, which we compute as:
249 * ClientHash is computed as:
250 * HMAC-SHA256(CookieString,
251 * "ExtORPort authentication client-to-server hash" | ClientNonce |
252 * ServerNonce)
255 /* Wrong length */
256 tt_int_op(-1, OP_EQ,
257 handle_client_auth_nonce(client_nonce, 33, &client_hash, &reply,
258 &reply_len));
259 tt_int_op(-1, OP_EQ,
260 handle_client_auth_nonce(client_nonce, 31, &client_hash, &reply,
261 &reply_len));
263 /* Now let's try this for real! */
264 tt_int_op(0, OP_EQ,
265 handle_client_auth_nonce(client_nonce, 32, &client_hash, &reply,
266 &reply_len));
267 tt_int_op(reply_len, OP_EQ, 64);
268 tt_ptr_op(reply, OP_NE, NULL);
269 tt_ptr_op(client_hash, OP_NE, NULL);
270 /* Fill in the server nonce into the hash inputs... */
271 memcpy(server_hash_input+46+32, reply+32, 32);
272 memcpy(client_hash_input+46+32, reply+32, 32);
273 /* Check the HMACs are correct... */
274 crypto_hmac_sha256(hmac1, (char*)ext_or_auth_cookie, 32, server_hash_input,
275 46+32+32);
276 crypto_hmac_sha256(hmac2, (char*)ext_or_auth_cookie, 32, client_hash_input,
277 46+32+32);
278 tt_mem_op(hmac1,OP_EQ, reply, 32);
279 tt_mem_op(hmac2,OP_EQ, client_hash, 32);
281 /* Now do it again and make sure that the results are *different* */
282 tt_int_op(0, OP_EQ,
283 handle_client_auth_nonce(client_nonce, 32, &client_hash2, &reply2,
284 &reply_len));
285 tt_mem_op(reply2,OP_NE, reply, reply_len);
286 tt_mem_op(client_hash2,OP_NE, client_hash, 32);
287 /* But that this one checks out too. */
288 memcpy(server_hash_input+46+32, reply2+32, 32);
289 memcpy(client_hash_input+46+32, reply2+32, 32);
290 /* Check the HMACs are correct... */
291 crypto_hmac_sha256(hmac1, (char*)ext_or_auth_cookie, 32, server_hash_input,
292 46+32+32);
293 crypto_hmac_sha256(hmac2, (char*)ext_or_auth_cookie, 32, client_hash_input,
294 46+32+32);
295 tt_mem_op(hmac1,OP_EQ, reply2, 32);
296 tt_mem_op(hmac2,OP_EQ, client_hash2, 32);
298 done:
299 tor_free(reply);
300 tor_free(client_hash);
301 tor_free(reply2);
302 tor_free(client_hash2);
305 static void
306 crypto_rand_return_tse_str(char *to, size_t n)
308 if (n != 32) {
309 TT_FAIL(("Asked for %d bytes, not 32", (int)n));
310 return;
312 memcpy(to, "te road There is always another ", 32);
315 static void
316 test_ext_or_cookie_auth_testvec(void *arg)
318 char *reply=NULL, *client_hash=NULL;
319 size_t reply_len;
320 char *mem_op_hex_tmp=NULL;
322 const char client_nonce[] = "But when I look ahead up the whi";
323 (void)arg;
325 ext_or_auth_cookie = tor_malloc_zero(32);
326 memcpy(ext_or_auth_cookie, "Gliding wrapt in a brown mantle," , 32);
327 ext_or_auth_cookie_is_set = 1;
329 MOCK(crypto_rand, crypto_rand_return_tse_str);
331 tt_int_op(0, OP_EQ,
332 handle_client_auth_nonce(client_nonce, 32, &client_hash, &reply,
333 &reply_len));
334 tt_ptr_op(reply, OP_NE, NULL );
335 tt_uint_op(reply_len, OP_EQ, 64);
336 tt_mem_op(reply+32,OP_EQ, "te road There is always another ", 32);
337 /* HMACSHA256("Gliding wrapt in a brown mantle,"
338 * "ExtORPort authentication server-to-client hash"
339 * "But when I look ahead up the write road There is always another ");
341 test_memeq_hex(reply,
342 "ec80ed6e546d3b36fdfc22fe1315416b"
343 "029f1ade7610d910878b62eeb7403821");
344 /* HMACSHA256("Gliding wrapt in a brown mantle,"
345 * "ExtORPort authentication client-to-server hash"
346 * "But when I look ahead up the write road There is always another ");
347 * (Both values computed using Python CLI.)
349 test_memeq_hex(client_hash,
350 "ab391732dd2ed968cd40c087d1b1f25b"
351 "33b3cd77ff79bd80c2074bbf438119a2");
353 done:
354 UNMOCK(crypto_rand);
355 tor_free(reply);
356 tor_free(client_hash);
357 tor_free(mem_op_hex_tmp);
360 static void
361 ignore_bootstrap_problem(const char *warn, int reason,
362 or_connection_t *conn)
364 (void)warn;
365 (void)reason;
366 (void)conn;
369 static int is_reading = 1;
370 static int handshake_start_called = 0;
372 static void
373 note_read_stopped(connection_t *conn)
375 (void)conn;
376 is_reading=0;
378 static void
379 note_read_started(connection_t *conn)
381 (void)conn;
382 is_reading=1;
384 static int
385 handshake_start(or_connection_t *conn, int receiving)
387 if (!conn || !receiving)
388 TT_FAIL(("Bad arguments to handshake_start"));
389 handshake_start_called = 1;
390 return 0;
393 #define WRITE(s,n) \
394 do { \
395 buf_add(TO_CONN(conn)->inbuf, (s), (n)); \
396 } while (0)
397 #define CONTAINS(s,n) \
398 do { \
399 tt_int_op((n), OP_LE, sizeof(b)); \
400 tt_int_op(buf_datalen(TO_CONN(conn)->outbuf), OP_EQ, (n)); \
401 if ((n)) { \
402 buf_get_bytes(TO_CONN(conn)->outbuf, b, (n)); \
403 tt_mem_op(b, OP_EQ, (s), (n)); \
405 } while (0)
407 /* Helper: Do a successful Extended ORPort authentication handshake. */
408 static void
409 do_ext_or_handshake(or_connection_t *conn)
411 char b[256];
413 tt_int_op(0, OP_EQ, connection_ext_or_start_auth(conn));
414 CONTAINS("\x01\x00", 2);
415 WRITE("\x01", 1);
416 WRITE("But when I look ahead up the whi", 32);
417 MOCK(crypto_rand, crypto_rand_return_tse_str);
418 tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
419 UNMOCK(crypto_rand);
420 tt_int_op(TO_CONN(conn)->state, OP_EQ,
421 EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_HASH);
422 CONTAINS("\xec\x80\xed\x6e\x54\x6d\x3b\x36\xfd\xfc\x22\xfe\x13\x15\x41\x6b"
423 "\x02\x9f\x1a\xde\x76\x10\xd9\x10\x87\x8b\x62\xee\xb7\x40\x38\x21"
424 "te road There is always another ", 64);
425 /* Send the right response this time. */
426 WRITE("\xab\x39\x17\x32\xdd\x2e\xd9\x68\xcd\x40\xc0\x87\xd1\xb1\xf2\x5b"
427 "\x33\xb3\xcd\x77\xff\x79\xbd\x80\xc2\x07\x4b\xbf\x43\x81\x19\xa2",
428 32);
429 tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
430 CONTAINS("\x01", 1);
431 tt_assert(! TO_CONN(conn)->marked_for_close);
432 tt_int_op(TO_CONN(conn)->state, OP_EQ, EXT_OR_CONN_STATE_OPEN);
434 done: ;
437 static void
438 test_ext_or_handshake(void *arg)
440 or_connection_t *conn=NULL;
441 char b[256];
443 (void) arg;
444 MOCK(connection_write_to_buf_impl_,
445 connection_write_to_buf_impl_replacement);
446 /* Use same authenticators as for test_ext_or_cookie_auth_testvec */
447 ext_or_auth_cookie = tor_malloc_zero(32);
448 memcpy(ext_or_auth_cookie, "Gliding wrapt in a brown mantle," , 32);
449 ext_or_auth_cookie_is_set = 1;
451 tor_init_connection_lists();
453 conn = or_connection_new(CONN_TYPE_EXT_OR, AF_INET);
454 tt_int_op(0, OP_EQ, connection_ext_or_start_auth(conn));
455 /* The server starts by telling us about the one supported authtype. */
456 CONTAINS("\x01\x00", 2);
457 /* Say the client hasn't responded yet. */
458 tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
459 /* Let's say the client replies badly. */
460 WRITE("\x99", 1);
461 tt_int_op(-1, OP_EQ, connection_ext_or_process_inbuf(conn));
462 CONTAINS("", 0);
463 tt_assert(TO_CONN(conn)->marked_for_close);
464 close_closeable_connections();
465 conn = NULL;
467 /* Okay, try again. */
468 conn = or_connection_new(CONN_TYPE_EXT_OR, AF_INET);
469 tt_int_op(0, OP_EQ, connection_ext_or_start_auth(conn));
470 CONTAINS("\x01\x00", 2);
471 /* Let's say the client replies sensibly this time. "Yes, AUTHTYPE_COOKIE
472 * sounds delicious. Let's have some of that!" */
473 WRITE("\x01", 1);
474 /* Let's say that the client also sends part of a nonce. */
475 WRITE("But when I look ", 16);
476 tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
477 CONTAINS("", 0);
478 tt_int_op(TO_CONN(conn)->state, OP_EQ,
479 EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_NONCE);
480 /* Pump it again. Nothing should happen. */
481 tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
482 /* send the rest of the nonce. */
483 WRITE("ahead up the whi", 16);
484 MOCK(crypto_rand, crypto_rand_return_tse_str);
485 tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
486 UNMOCK(crypto_rand);
487 /* We should get the right reply from the server. */
488 CONTAINS("\xec\x80\xed\x6e\x54\x6d\x3b\x36\xfd\xfc\x22\xfe\x13\x15\x41\x6b"
489 "\x02\x9f\x1a\xde\x76\x10\xd9\x10\x87\x8b\x62\xee\xb7\x40\x38\x21"
490 "te road There is always another ", 64);
491 /* Send the wrong response. */
492 WRITE("not with a bang but a whimper...", 32);
493 MOCK(control_event_bootstrap_prob_or, ignore_bootstrap_problem);
494 tt_int_op(-1, OP_EQ, connection_ext_or_process_inbuf(conn));
495 CONTAINS("\x00", 1);
496 tt_assert(TO_CONN(conn)->marked_for_close);
497 /* XXXX Hold-open-until-flushed. */
498 close_closeable_connections();
499 conn = NULL;
500 UNMOCK(control_event_bootstrap_prob_or);
502 MOCK(connection_start_reading, note_read_started);
503 MOCK(connection_stop_reading, note_read_stopped);
504 MOCK(connection_tls_start_handshake, handshake_start);
506 /* Okay, this time let's succeed. */
507 conn = or_connection_new(CONN_TYPE_EXT_OR, AF_INET);
508 do_ext_or_handshake(conn);
510 /* Now let's run through some messages. */
511 /* First let's send some junk and make sure it's ignored. */
512 WRITE("\xff\xf0\x00\x03""ABC", 7);
513 tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
514 CONTAINS("", 0);
515 /* Now let's send a USERADDR command. */
516 WRITE("\x00\x01\x00\x0c""1.2.3.4:5678", 16);
517 tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
518 tt_int_op(TO_CONN(conn)->port, OP_EQ, 5678);
519 tt_int_op(tor_addr_to_ipv4h(&TO_CONN(conn)->addr), OP_EQ, 0x01020304);
520 /* Now let's send a TRANSPORT command. */
521 WRITE("\x00\x02\x00\x07""rfc1149", 11);
522 tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
523 tt_ptr_op(NULL, OP_NE, conn->ext_or_transport);
524 tt_str_op("rfc1149", OP_EQ, conn->ext_or_transport);
525 tt_int_op(is_reading,OP_EQ,1);
526 tt_int_op(TO_CONN(conn)->state, OP_EQ, EXT_OR_CONN_STATE_OPEN);
527 /* DONE */
528 WRITE("\x00\x00\x00\x00", 4);
529 tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
530 tt_int_op(TO_CONN(conn)->state, OP_EQ, EXT_OR_CONN_STATE_FLUSHING);
531 tt_int_op(is_reading,OP_EQ,0);
532 CONTAINS("\x10\x00\x00\x00", 4);
533 tt_int_op(handshake_start_called,OP_EQ,0);
534 tt_int_op(0, OP_EQ, connection_ext_or_finished_flushing(conn));
535 tt_int_op(is_reading,OP_EQ,1);
536 tt_int_op(handshake_start_called,OP_EQ,1);
537 tt_int_op(TO_CONN(conn)->type, OP_EQ, CONN_TYPE_OR);
538 tt_int_op(TO_CONN(conn)->state, OP_EQ, 0);
539 close_closeable_connections();
540 conn = NULL;
542 /* Okay, this time let's succeed the handshake but fail the USERADDR
543 command. */
544 conn = or_connection_new(CONN_TYPE_EXT_OR, AF_INET);
545 do_ext_or_handshake(conn);
546 /* USERADDR command with an extra NUL byte */
547 WRITE("\x00\x01\x00\x0d""1.2.3.4:5678\x00", 17);
548 MOCK(control_event_bootstrap_prob_or, ignore_bootstrap_problem);
549 tt_int_op(-1, OP_EQ, connection_ext_or_process_inbuf(conn));
550 CONTAINS("", 0);
551 tt_assert(TO_CONN(conn)->marked_for_close);
552 close_closeable_connections();
553 conn = NULL;
554 UNMOCK(control_event_bootstrap_prob_or);
556 /* Now fail the TRANSPORT command. */
557 conn = or_connection_new(CONN_TYPE_EXT_OR, AF_INET);
558 do_ext_or_handshake(conn);
559 /* TRANSPORT command with an extra NUL byte */
560 WRITE("\x00\x02\x00\x08""rfc1149\x00", 12);
561 MOCK(control_event_bootstrap_prob_or, ignore_bootstrap_problem);
562 tt_int_op(-1, OP_EQ, connection_ext_or_process_inbuf(conn));
563 CONTAINS("", 0);
564 tt_assert(TO_CONN(conn)->marked_for_close);
565 close_closeable_connections();
566 conn = NULL;
567 UNMOCK(control_event_bootstrap_prob_or);
569 /* Now fail the TRANSPORT command. */
570 conn = or_connection_new(CONN_TYPE_EXT_OR, AF_INET);
571 do_ext_or_handshake(conn);
572 /* TRANSPORT command with transport name with symbols (not a
573 C-identifier) */
574 WRITE("\x00\x02\x00\x07""rf*1149", 11);
575 MOCK(control_event_bootstrap_prob_or, ignore_bootstrap_problem);
576 tt_int_op(-1, OP_EQ, connection_ext_or_process_inbuf(conn));
577 CONTAINS("", 0);
578 tt_assert(TO_CONN(conn)->marked_for_close);
579 close_closeable_connections();
580 conn = NULL;
581 UNMOCK(control_event_bootstrap_prob_or);
583 done:
584 UNMOCK(connection_write_to_buf_impl_);
585 UNMOCK(crypto_rand);
586 if (conn)
587 connection_free_minimal(TO_CONN(conn));
588 #undef CONTAINS
589 #undef WRITE
592 struct testcase_t extorport_tests[] = {
593 { "id_map", test_ext_or_id_map, TT_FORK, NULL, NULL },
594 { "write_command", test_ext_or_write_command, TT_FORK, NULL, NULL },
595 { "init_auth", test_ext_or_init_auth, TT_FORK, NULL, NULL },
596 { "cookie_auth", test_ext_or_cookie_auth, TT_FORK, NULL, NULL },
597 { "cookie_auth_testvec", test_ext_or_cookie_auth_testvec, TT_FORK,
598 NULL, NULL },
599 { "handshake", test_ext_or_handshake, TT_FORK, NULL, NULL },
600 END_OF_TESTCASES