Line data Source code
1 : /* Copyright (c) 2001-2004, Roger Dingledine.
2 : * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 : * Copyright (c) 2007-2021, The Tor Project, Inc. */
4 : /* See LICENSE for licensing information */
5 :
6 : #include "orconfig.h"
7 : #include <math.h>
8 :
9 : #define BWAUTH_PRIVATE
10 : #define CONFIG_PRIVATE
11 : #define CONTROL_GETINFO_PRIVATE
12 : #define DIRAUTH_SYS_PRIVATE
13 : #define DIRCACHE_PRIVATE
14 : #define DIRCLIENT_PRIVATE
15 : #define DIRVOTE_PRIVATE
16 : #define DLSTATUS_PRIVATE
17 : #define HIBERNATE_PRIVATE
18 : #define NETWORKSTATUS_PRIVATE
19 : #define NS_PARSE_PRIVATE
20 : #define NODE_SELECT_PRIVATE
21 : #define RELAY_PRIVATE
22 : #define ROUTERLIST_PRIVATE
23 : #define ROUTER_PRIVATE
24 : #define UNPARSEABLE_PRIVATE
25 : #define VOTEFLAGS_PRIVATE
26 :
27 : #include "core/or/or.h"
28 : #include "app/config/config.h"
29 : #include "lib/confmgt/confmgt.h"
30 : #include "core/mainloop/connection.h"
31 : #include "core/or/relay.h"
32 : #include "core/or/protover.h"
33 : #include "core/or/versions.h"
34 : #include "feature/client/bridges.h"
35 : #include "feature/client/entrynodes.h"
36 : #include "feature/control/control_getinfo.h"
37 : #include "feature/dirauth/bwauth.h"
38 : #include "feature/dirauth/dirauth_sys.h"
39 : #include "feature/dirauth/dirvote.h"
40 : #include "feature/dirauth/dsigs_parse.h"
41 : #include "feature/dirauth/process_descs.h"
42 : #include "feature/dirauth/recommend_pkg.h"
43 : #include "feature/dirauth/shared_random_state.h"
44 : #include "feature/dirauth/voteflags.h"
45 : #include "feature/dircache/dircache.h"
46 : #include "feature/dircache/dirserv.h"
47 : #include "feature/dirclient/dirclient.h"
48 : #include "feature/dirclient/dlstatus.h"
49 : #include "feature/dircommon/directory.h"
50 : #include "feature/dircommon/fp_pair.h"
51 : #include "feature/dirauth/voting_schedule.h"
52 : #include "feature/hibernate/hibernate.h"
53 : #include "feature/nodelist/authcert.h"
54 : #include "feature/nodelist/dirlist.h"
55 : #include "feature/nodelist/microdesc.h"
56 : #include "feature/nodelist/networkstatus.h"
57 : #include "feature/nodelist/nickname.h"
58 : #include "feature/nodelist/node_select.h"
59 : #include "feature/nodelist/routerlist.h"
60 : #include "feature/dirparse/authcert_parse.h"
61 : #include "feature/dirparse/ns_parse.h"
62 : #include "feature/dirparse/routerparse.h"
63 : #include "feature/dirparse/unparseable.h"
64 : #include "feature/nodelist/routerset.h"
65 : #include "feature/nodelist/torcert.h"
66 : #include "feature/relay/router.h"
67 : #include "feature/relay/routerkeys.h"
68 : #include "feature/relay/routermode.h"
69 : #include "lib/compress/compress.h"
70 : #include "lib/crypt_ops/crypto_ed25519.h"
71 : #include "lib/crypt_ops/crypto_format.h"
72 : #include "lib/crypt_ops/crypto_rand.h"
73 : #include "lib/encoding/confline.h"
74 : #include "lib/memarea/memarea.h"
75 : #include "lib/osinfo/uname.h"
76 : #include "test/log_test_helpers.h"
77 : #include "test/opts_test_helpers.h"
78 : #include "test/test.h"
79 : #include "test/test_dir_common.h"
80 :
81 : #include "core/or/addr_policy_st.h"
82 : #include "feature/dirauth/dirauth_options_st.h"
83 : #include "feature/nodelist/authority_cert_st.h"
84 : #include "feature/nodelist/document_signature_st.h"
85 : #include "feature/nodelist/extrainfo_st.h"
86 : #include "feature/nodelist/microdesc_st.h"
87 : #include "feature/nodelist/networkstatus_st.h"
88 : #include "feature/nodelist/networkstatus_voter_info_st.h"
89 : #include "feature/dirauth/ns_detached_signatures_st.h"
90 : #include "core/or/port_cfg_st.h"
91 : #include "feature/nodelist/routerinfo_st.h"
92 : #include "feature/nodelist/routerlist_st.h"
93 : #include "core/or/tor_version_st.h"
94 : #include "feature/dirauth/vote_microdesc_hash_st.h"
95 : #include "feature/nodelist/vote_routerstatus_st.h"
96 :
97 : #ifdef HAVE_SYS_STAT_H
98 : #include <sys/stat.h>
99 : #endif
100 : #ifdef HAVE_UNISTD_H
101 : #include <unistd.h>
102 : #endif
103 :
104 : static void setup_ei_digests(void);
105 : static uint8_t digest_ei_minimal[20];
106 : static uint8_t digest_ei_bad_nickname[20];
107 : static uint8_t digest_ei_maximal[20];
108 : static uint8_t digest_ei_bad_tokens[20];
109 : static uint8_t digest_ei_bad_sig2[20];
110 : static uint8_t digest_ei_bad_published[20];
111 :
112 : static networkstatus_t *
113 18 : networkstatus_parse_vote_from_string_(const char *s,
114 : const char **eos_out,
115 : enum networkstatus_type_t ns_type)
116 : {
117 18 : size_t len = strlen(s);
118 : // memdup so that it won't be nul-terminated.
119 18 : char *tmp = tor_memdup(s, len);
120 18 : networkstatus_t *result =
121 18 : networkstatus_parse_vote_from_string(tmp, len, eos_out, ns_type);
122 18 : if (eos_out && *eos_out) {
123 0 : *eos_out = s + (*eos_out - tmp);
124 : }
125 18 : tor_free(tmp);
126 18 : return result;
127 : }
128 :
129 : static void
130 1 : test_dir_nicknames(void *arg)
131 : {
132 1 : (void)arg;
133 1 : tt_assert( is_legal_nickname("a"));
134 1 : tt_assert(!is_legal_nickname(""));
135 1 : tt_assert(!is_legal_nickname("abcdefghijklmnopqrst")); /* 20 chars */
136 1 : tt_assert(!is_legal_nickname("hyphen-")); /* bad char */
137 1 : tt_assert( is_legal_nickname("abcdefghijklmnopqrs")); /* 19 chars */
138 1 : tt_assert(!is_legal_nickname("$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA"));
139 : /* valid */
140 1 : tt_assert( is_legal_nickname_or_hexdigest(
141 : "$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA"));
142 1 : tt_assert( is_legal_nickname_or_hexdigest(
143 : "$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA=fred"));
144 1 : tt_assert( is_legal_nickname_or_hexdigest(
145 : "$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA~fred"));
146 : /* too short */
147 1 : tt_assert(!is_legal_nickname_or_hexdigest(
148 : "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
149 : /* illegal char */
150 1 : tt_assert(!is_legal_nickname_or_hexdigest(
151 : "$AAAAAAzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
152 : /* hex part too long */
153 1 : tt_assert(!is_legal_nickname_or_hexdigest(
154 : "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
155 1 : tt_assert(!is_legal_nickname_or_hexdigest(
156 : "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=fred"));
157 : /* Bad nickname */
158 1 : tt_assert(!is_legal_nickname_or_hexdigest(
159 : "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="));
160 1 : tt_assert(!is_legal_nickname_or_hexdigest(
161 : "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~"));
162 1 : tt_assert(!is_legal_nickname_or_hexdigest(
163 : "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~hyphen-"));
164 1 : tt_assert(!is_legal_nickname_or_hexdigest(
165 : "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~"
166 : "abcdefghijklmnoppqrst"));
167 : /* Bad extra char. */
168 1 : tt_assert(!is_legal_nickname_or_hexdigest(
169 : "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!"));
170 1 : tt_assert(is_legal_nickname_or_hexdigest("xyzzy"));
171 1 : tt_assert(is_legal_nickname_or_hexdigest("abcdefghijklmnopqrs"));
172 1 : tt_assert(!is_legal_nickname_or_hexdigest("abcdefghijklmnopqrst"));
173 1 : done:
174 1 : ;
175 1 : }
176 :
177 : /* Allocate and return a new routerinfo, with the fields set from the
178 : * arguments to this function.
179 : *
180 : * Also sets:
181 : * - random RSA identity and onion keys,
182 : * - the platform field using get_platform_str(), and
183 : * - supports_tunnelled_dir_requests to 1.
184 : *
185 : * If rsa_onion_keypair_out is not NULL, it is set to the onion keypair.
186 : * The caller must free this keypair.
187 : */
188 : static routerinfo_t *
189 6 : basic_routerinfo_new(const char *nickname, uint32_t ipv4_addr,
190 : uint16_t or_port, uint16_t dir_port,
191 : uint32_t bandwidthrate, uint32_t bandwidthburst,
192 : uint32_t bandwidthcapacity,
193 : time_t published_on,
194 : crypto_pk_t **rsa_onion_keypair_out)
195 : {
196 6 : char platform[256];
197 :
198 6 : tor_assert(nickname);
199 :
200 6 : crypto_pk_t *pk1 = NULL, *pk2 = NULL;
201 : /* These keys are random: idx is ignored. */
202 6 : pk1 = pk_generate(0);
203 6 : pk2 = pk_generate(1);
204 :
205 6 : tor_assert(pk1);
206 6 : tor_assert(pk2);
207 :
208 6 : get_platform_str(platform, sizeof(platform));
209 :
210 6 : routerinfo_t *r1 = tor_malloc_zero(sizeof(routerinfo_t));
211 :
212 6 : r1->nickname = tor_strdup(nickname);
213 6 : r1->platform = tor_strdup(platform);
214 :
215 6 : tor_addr_from_ipv4h(&r1->ipv4_addr, ipv4_addr);
216 6 : r1->ipv4_orport = or_port;
217 6 : r1->ipv4_dirport = dir_port;
218 6 : r1->supports_tunnelled_dir_requests = 1;
219 :
220 6 : router_set_rsa_onion_pkey(pk1, &r1->onion_pkey, &r1->onion_pkey_len);
221 6 : r1->identity_pkey = pk2;
222 :
223 6 : r1->bandwidthrate = bandwidthrate;
224 6 : r1->bandwidthburst = bandwidthburst;
225 6 : r1->bandwidthcapacity = bandwidthcapacity;
226 :
227 6 : r1->cache_info.published_on = published_on;
228 6 : r1->protocol_list = tor_strdup(protover_get_supported_protocols());
229 :
230 6 : if (rsa_onion_keypair_out) {
231 6 : *rsa_onion_keypair_out = pk1;
232 : } else {
233 0 : crypto_pk_free(pk1);
234 : }
235 :
236 6 : return r1;
237 : }
238 :
239 : /* Allocate and return a new string containing a "router" line for r1. */
240 : static char *
241 6 : get_new_router_line(const routerinfo_t *r1)
242 : {
243 6 : char *line = NULL;
244 :
245 6 : tor_assert(r1);
246 :
247 12 : tor_asprintf(&line,
248 : "router %s %s %d 0 %d\n",
249 6 : r1->nickname, fmt_addr(&r1->ipv4_addr),
250 6 : r1->ipv4_orport, r1->ipv4_dirport);
251 6 : tor_assert(line);
252 :
253 6 : return line;
254 : }
255 :
256 : /* Allocate and return a new string containing a "platform" line for the
257 : * current Tor version and OS. */
258 : static char *
259 6 : get_new_platform_line(void)
260 : {
261 6 : char *line = NULL;
262 :
263 6 : tor_asprintf(&line,
264 : "platform Tor %s on %s\n",
265 : VERSION, get_uname());
266 6 : tor_assert(line);
267 :
268 6 : return line;
269 : }
270 :
271 : /* Allocate and return a new string containing a "published" line for r1.
272 : * r1->cache_info.published_on must be between 0 and 59 seconds. */
273 : static char *
274 6 : get_new_published_line(const routerinfo_t *r1)
275 : {
276 6 : char *line = NULL;
277 :
278 6 : tor_assert(r1);
279 :
280 6 : tor_assert(r1->cache_info.published_on >= 0);
281 6 : tor_assert(r1->cache_info.published_on <= 59);
282 :
283 6 : tor_asprintf(&line,
284 : "published 1970-01-01 00:00:%02u\n",
285 : (unsigned)r1->cache_info.published_on);
286 6 : tor_assert(line);
287 :
288 6 : return line;
289 : }
290 :
291 : /* Allocate and return a new string containing a "fingerprint" line for r1. */
292 : static char *
293 6 : get_new_fingerprint_line(const routerinfo_t *r1)
294 : {
295 6 : char *line = NULL;
296 6 : char fingerprint[FINGERPRINT_LEN+1];
297 :
298 6 : tor_assert(r1);
299 :
300 6 : tor_assert(!crypto_pk_get_fingerprint(r1->identity_pkey, fingerprint, 1));
301 6 : tor_assert(strlen(fingerprint) > 0);
302 :
303 6 : tor_asprintf(&line,
304 : "fingerprint %s\n",
305 : fingerprint);
306 6 : tor_assert(line);
307 :
308 6 : return line;
309 : }
310 :
311 : /* Allocate and return a new string containing an "uptime" line with uptime t.
312 : *
313 : * You should pass a hard-coded value to this function, because even if we made
314 : * it reflect uptime, that still wouldn't make it right, because the two
315 : * descriptors might be made on different seconds.
316 : */
317 : static char *
318 6 : get_new_uptime_line(time_t t)
319 : {
320 6 : char *line = NULL;
321 :
322 6 : tor_asprintf(&line,
323 : "uptime %u\n",
324 : (unsigned)t);
325 6 : tor_assert(line);
326 :
327 6 : return line;
328 : }
329 :
330 : /* Allocate and return a new string containing an "bandwidth" line for r1.
331 : */
332 : static char *
333 6 : get_new_bandwidth_line(const routerinfo_t *r1)
334 : {
335 6 : char *line = NULL;
336 :
337 6 : tor_assert(r1);
338 :
339 6 : tor_asprintf(&line,
340 : "bandwidth %u %u %u\n",
341 6 : r1->bandwidthrate,
342 6 : r1->bandwidthburst,
343 6 : r1->bandwidthcapacity);
344 6 : tor_assert(line);
345 :
346 6 : return line;
347 : }
348 :
349 : /* Allocate and return a new string containing a key_name block for the
350 : * RSA key pk1.
351 : */
352 : static char *
353 12 : get_new_rsa_key_block(const char *key_name, crypto_pk_t *pk1)
354 : {
355 12 : char *block = NULL;
356 12 : char *pk1_str = NULL;
357 12 : size_t pk1_str_len = 0;
358 :
359 12 : tor_assert(key_name);
360 12 : tor_assert(pk1);
361 :
362 12 : tor_assert(!crypto_pk_write_public_key_to_string(pk1, &pk1_str,
363 : &pk1_str_len));
364 12 : tor_assert(pk1_str);
365 12 : tor_assert(pk1_str_len);
366 :
367 12 : tor_asprintf(&block,
368 : "%s\n%s",
369 : key_name,
370 : pk1_str);
371 12 : tor_free(pk1_str);
372 :
373 12 : tor_assert(block);
374 12 : return block;
375 : }
376 :
377 : /* Allocate and return a new string containing an "onion-key" block for the
378 : * router r1.
379 : */
380 : static char *
381 6 : get_new_onion_key_block(const routerinfo_t *r1)
382 : {
383 6 : char *block = NULL;
384 6 : tor_assert(r1);
385 12 : crypto_pk_t *pk_tmp = router_get_rsa_onion_pkey(r1->onion_pkey,
386 6 : r1->onion_pkey_len);
387 6 : block = get_new_rsa_key_block("onion-key", pk_tmp);
388 6 : crypto_pk_free(pk_tmp);
389 6 : return block;
390 : }
391 :
392 : /* Allocate and return a new string containing an "signing-key" block for the
393 : * router r1.
394 : */
395 : static char *
396 6 : get_new_signing_key_block(const routerinfo_t *r1)
397 : {
398 6 : tor_assert(r1);
399 6 : return get_new_rsa_key_block("signing-key", r1->identity_pkey);
400 : }
401 :
402 : /* Allocate and return a new string containing an "ntor-onion-key" line for
403 : * the curve25519 public key ntor_onion_pubkey.
404 : */
405 : static char *
406 6 : get_new_ntor_onion_key_line(const curve25519_public_key_t *ntor_onion_pubkey)
407 : {
408 6 : char *line = NULL;
409 6 : char cert_buf[256];
410 :
411 6 : tor_assert(ntor_onion_pubkey);
412 :
413 6 : curve25519_public_to_base64(cert_buf, ntor_onion_pubkey, false);
414 6 : tor_assert(strlen(cert_buf) > 0);
415 :
416 6 : tor_asprintf(&line,
417 : "ntor-onion-key %s\n",
418 : cert_buf);
419 6 : tor_assert(line);
420 :
421 6 : return line;
422 : }
423 :
424 : /* Allocate and return a new string containing a "bridge-distribution-request"
425 : * line for options.
426 : */
427 : static char *
428 6 : get_new_bridge_distribution_request_line(const or_options_t *options)
429 : {
430 6 : if (options->BridgeRelay) {
431 3 : return tor_strdup("bridge-distribution-request any\n");
432 : } else {
433 3 : return tor_strdup("");
434 : }
435 : }
436 :
437 : static smartlist_t *mocked_configured_ports = NULL;
438 :
439 : /** Returns mocked_configured_ports */
440 : static const smartlist_t *
441 18 : mock_get_configured_ports(void)
442 : {
443 18 : return mocked_configured_ports;
444 : }
445 :
446 : static crypto_pk_t *mocked_server_identitykey = NULL;
447 :
448 : /* Returns mocked_server_identitykey with no checks. */
449 : static crypto_pk_t *
450 12 : mock_get_server_identity_key(void)
451 : {
452 12 : return mocked_server_identitykey;
453 : }
454 :
455 : static crypto_pk_t *mocked_onionkey = NULL;
456 :
457 : /* Returns mocked_onionkey with no checks. */
458 : static crypto_pk_t *
459 6 : mock_get_onion_key(void)
460 : {
461 6 : return mocked_onionkey;
462 : }
463 :
464 : static routerinfo_t *mocked_routerinfo = NULL;
465 :
466 : /* Returns 0 and sets ri_out to mocked_routerinfo.
467 : * ri_out must not be NULL. There are no other checks. */
468 : static int
469 6 : mock_router_build_fresh_unsigned_routerinfo(routerinfo_t **ri_out)
470 : {
471 6 : tor_assert(ri_out);
472 6 : *ri_out = mocked_routerinfo;
473 6 : return 0;
474 : }
475 :
476 : static ed25519_keypair_t *mocked_master_signing_key = NULL;
477 :
478 : /* Returns mocked_master_signing_key with no checks. */
479 : static const ed25519_keypair_t *
480 12 : mock_get_master_signing_keypair(void)
481 : {
482 12 : return mocked_master_signing_key;
483 : }
484 :
485 : static struct tor_cert_st *mocked_signing_key_cert = NULL;
486 :
487 : /* Returns mocked_signing_key_cert with no checks. */
488 : static const struct tor_cert_st *
489 6 : mock_get_master_signing_key_cert(void)
490 : {
491 6 : return mocked_signing_key_cert;
492 : }
493 :
494 : static curve25519_keypair_t *mocked_curve25519_onion_key = NULL;
495 :
496 : /* Returns mocked_curve25519_onion_key with no checks. */
497 : static const curve25519_keypair_t *
498 6 : mock_get_current_curve25519_keypair(void)
499 : {
500 6 : return mocked_curve25519_onion_key;
501 : }
502 :
503 : /* Unmock get_configured_ports() and free mocked_configured_ports. */
504 : static void
505 42 : cleanup_mock_configured_ports(void)
506 : {
507 42 : UNMOCK(get_configured_ports);
508 :
509 42 : if (mocked_configured_ports) {
510 36 : SMARTLIST_FOREACH(mocked_configured_ports, port_cfg_t *, p, tor_free(p));
511 18 : smartlist_free(mocked_configured_ports);
512 : }
513 42 : }
514 :
515 : /* Mock get_configured_ports() with a list containing or_port and dir_port.
516 : * If a port is 0, don't set it.
517 : * Only sets the minimal data required for the tests to pass. */
518 : static void
519 18 : setup_mock_configured_ports(uint16_t or_port, uint16_t dir_port)
520 : {
521 18 : cleanup_mock_configured_ports();
522 :
523 : /* Fake just enough of an ORPort and DirPort to get by */
524 18 : MOCK(get_configured_ports, mock_get_configured_ports);
525 18 : mocked_configured_ports = smartlist_new();
526 :
527 18 : if (or_port) {
528 18 : port_cfg_t *or_port_cfg = tor_malloc_zero(sizeof(*or_port_cfg));
529 18 : or_port_cfg->type = CONN_TYPE_OR_LISTENER;
530 18 : or_port_cfg->addr.family = AF_INET;
531 18 : or_port_cfg->port = or_port;
532 18 : smartlist_add(mocked_configured_ports, or_port_cfg);
533 : }
534 :
535 18 : if (dir_port) {
536 0 : port_cfg_t *dir_port_cfg = tor_malloc_zero(sizeof(*dir_port_cfg));
537 0 : dir_port_cfg->type = CONN_TYPE_DIR_LISTENER;
538 0 : dir_port_cfg->addr.family = AF_INET;
539 0 : dir_port_cfg->port = dir_port;
540 0 : smartlist_add(mocked_configured_ports, dir_port_cfg);
541 : }
542 18 : }
543 :
544 : /* Clean up the data structures and unmock the functions needed for generating
545 : * a fresh descriptor. */
546 : static void
547 18 : cleanup_mocks_for_fresh_descriptor(void)
548 : {
549 18 : tor_free(get_options_mutable()->Nickname);
550 :
551 18 : mocked_server_identitykey = NULL;
552 18 : UNMOCK(get_server_identity_key);
553 :
554 18 : crypto_pk_free(mocked_onionkey);
555 18 : UNMOCK(get_onion_key);
556 18 : }
557 :
558 : /* Mock the data structures and functions needed for generating a fresh
559 : * descriptor.
560 : *
561 : * Sets options->Nickname from r1->nickname.
562 : * Mocks get_server_identity_key() with r1->identity_pkey.
563 : *
564 : * If rsa_onion_keypair is not NULL, it is used to mock get_onion_key().
565 : * Otherwise, the public key in r1->onion_pkey is used to mock get_onion_key().
566 : */
567 : static void
568 6 : setup_mocks_for_fresh_descriptor(const routerinfo_t *r1,
569 : crypto_pk_t *rsa_onion_keypair)
570 : {
571 6 : cleanup_mocks_for_fresh_descriptor();
572 :
573 6 : tor_assert(r1);
574 :
575 : /* router_build_fresh_signed_extrainfo() requires options->Nickname */
576 6 : get_options_mutable()->Nickname = tor_strdup(r1->nickname);
577 :
578 : /* router_build_fresh_signed_extrainfo() requires get_server_identity_key().
579 : * Use the same one as the call to router_dump_router_to_string() above.
580 : */
581 6 : mocked_server_identitykey = r1->identity_pkey;
582 6 : MOCK(get_server_identity_key, mock_get_server_identity_key);
583 :
584 : /* router_dump_and_sign_routerinfo_descriptor_body() requires
585 : * get_onion_key(). Use the same one as r1.
586 : */
587 6 : if (rsa_onion_keypair) {
588 6 : mocked_onionkey = crypto_pk_dup_key(rsa_onion_keypair);
589 : } else {
590 0 : mocked_onionkey = router_get_rsa_onion_pkey(r1->onion_pkey,
591 0 : r1->onion_pkey_len);
592 : }
593 6 : MOCK(get_onion_key, mock_get_onion_key);
594 6 : }
595 :
596 : /* Set options based on arg.
597 : *
598 : * b: BridgeRelay 1
599 : * e: ExtraInfoStatistics 1
600 : * s: sets all the individual statistics options to 1
601 : *
602 : * Always sets AssumeReachable to 1.
603 : *
604 : * Does not set ServerTransportPlugin, because it's parsed before use.
605 : *
606 : * Does not set BridgeRecordUsageByCountry, because the tests don't have access
607 : * to a GeoIPFile or GeoIPv6File. */
608 : static void
609 6 : setup_dir_formats_options(const char *arg, or_options_t *options)
610 : {
611 : /* Skip reachability checks for DirPort, ORPort, and tunnelled-dir-server */
612 6 : options->AssumeReachable = 1;
613 :
614 6 : if (strchr(arg, 'b')) {
615 3 : options->BridgeRelay = 1;
616 : }
617 :
618 6 : if (strchr(arg, 'e')) {
619 4 : options->ExtraInfoStatistics = 1;
620 : }
621 :
622 6 : if (strchr(arg, 's')) {
623 2 : options->DirReqStatistics = 1;
624 2 : options->HiddenServiceStatistics = 1;
625 2 : options->EntryStatistics = 1;
626 2 : options->CellStatistics = 1;
627 2 : options->ExitPortStatistics = 1;
628 2 : options->ConnDirectionStatistics = 1;
629 2 : options->PaddingStatistics = 1;
630 : }
631 6 : }
632 :
633 : /* Check that routerinfos r1 and rp1 are consistent.
634 : * Only performs some basic checks.
635 : */
636 : #define CHECK_ROUTERINFO_CONSISTENCY(r1, rp1) \
637 : STMT_BEGIN \
638 : tt_assert(r1); \
639 : tt_assert(rp1); \
640 : tt_assert(tor_addr_eq(&rp1->ipv4_addr, &r1->ipv4_addr)); \
641 : tt_int_op(rp1->ipv4_orport,OP_EQ, r1->ipv4_orport); \
642 : tt_int_op(rp1->ipv4_dirport,OP_EQ, r1->ipv4_dirport); \
643 : tt_int_op(rp1->bandwidthrate,OP_EQ, r1->bandwidthrate); \
644 : tt_int_op(rp1->bandwidthburst,OP_EQ, r1->bandwidthburst); \
645 : tt_int_op(rp1->bandwidthcapacity,OP_EQ, r1->bandwidthcapacity); \
646 : crypto_pk_t *rp1_onion_pkey = router_get_rsa_onion_pkey(rp1->onion_pkey, \
647 : rp1->onion_pkey_len); \
648 : crypto_pk_t *r1_onion_pkey = router_get_rsa_onion_pkey(r1->onion_pkey, \
649 : r1->onion_pkey_len); \
650 : tt_int_op(crypto_pk_cmp_keys(rp1_onion_pkey, r1_onion_pkey), OP_EQ, 0); \
651 : crypto_pk_free(rp1_onion_pkey); \
652 : crypto_pk_free(r1_onion_pkey); \
653 : tt_int_op(crypto_pk_cmp_keys(rp1->identity_pkey, r1->identity_pkey), \
654 : OP_EQ, 0); \
655 : tt_int_op(rp1->supports_tunnelled_dir_requests, OP_EQ, \
656 : r1->supports_tunnelled_dir_requests); \
657 : STMT_END
658 :
659 : /* Check that routerinfo r1 and extrainfo e1 are consistent.
660 : * Only performs some basic checks.
661 : */
662 : #define CHECK_EXTRAINFO_CONSISTENCY(r1, e1) \
663 : STMT_BEGIN \
664 : tt_assert(r1); \
665 : tt_assert(e1); \
666 : \
667 : tt_str_op(e1->nickname, OP_EQ, r1->nickname); \
668 : STMT_END
669 :
670 : /* Check that the exit policy in rp2 is as expected. */
671 : #define CHECK_PARSED_EXIT_POLICY(rp2) \
672 : STMT_BEGIN \
673 : tt_int_op(smartlist_len(rp2->exit_policy),OP_EQ, 2); \
674 : \
675 : p = smartlist_get(rp2->exit_policy, 0); \
676 : tt_int_op(p->policy_type,OP_EQ, ADDR_POLICY_ACCEPT); \
677 : tt_assert(tor_addr_is_null(&p->addr)); \
678 : tt_int_op(p->maskbits,OP_EQ, 0); \
679 : tt_int_op(p->prt_min,OP_EQ, 80); \
680 : tt_int_op(p->prt_max,OP_EQ, 80); \
681 : \
682 : p = smartlist_get(rp2->exit_policy, 1); \
683 : tt_int_op(p->policy_type,OP_EQ, ADDR_POLICY_REJECT); \
684 : tt_assert(tor_addr_eq(&p->addr, &ex2->addr)); \
685 : tt_int_op(p->maskbits,OP_EQ, 8); \
686 : tt_int_op(p->prt_min,OP_EQ, 24); \
687 : tt_int_op(p->prt_max,OP_EQ, 24); \
688 : STMT_END
689 :
690 : /** Run unit tests for router descriptor generation logic for a RSA + ed25519
691 : * router.
692 : */
693 : static void
694 6 : test_dir_formats_rsa_ed25519(void *arg)
695 : {
696 6 : char *buf = NULL;
697 6 : char *buf2 = NULL;
698 6 : char *cp = NULL;
699 :
700 6 : crypto_pk_t *r2_onion_pkey = NULL;
701 6 : char cert_buf[256];
702 6 : uint8_t *rsa_cc = NULL;
703 6 : time_t now = time(NULL);
704 :
705 6 : routerinfo_t *r2 = NULL;
706 6 : extrainfo_t *e2 = NULL;
707 6 : routerinfo_t *r2_out = NULL;
708 6 : routerinfo_t *rp2 = NULL;
709 6 : extrainfo_t *ep2 = NULL;
710 6 : addr_policy_t *ex1, *ex2;
711 6 : const addr_policy_t *p;
712 :
713 6 : smartlist_t *chunks = NULL;
714 6 : int rv = -1;
715 :
716 6 : or_options_t *options = get_options_mutable();
717 6 : setup_dir_formats_options((const char *)arg, options);
718 :
719 6 : hibernate_set_state_for_testing_(HIBERNATE_STATE_LIVE);
720 :
721 : /* r2 is a RSA + ed25519 descriptor, with an exit policy, but no DirPort or
722 : * IPv6 */
723 6 : r2 = basic_routerinfo_new("Fred", 0x0a030201u /* 10.3.2.1 */,
724 : 9005, 0,
725 : 3000, 3000, 3000,
726 : 5,
727 : &r2_onion_pkey);
728 :
729 : /* Fake just enough of an ntor key to get by */
730 6 : curve25519_keypair_t r2_onion_keypair;
731 6 : curve25519_keypair_generate(&r2_onion_keypair, 0);
732 6 : r2->onion_curve25519_pkey = tor_memdup(&r2_onion_keypair.pubkey,
733 : sizeof(curve25519_public_key_t));
734 :
735 : /* Now add relay ed25519 keys
736 : * We can't use init_mock_ed_keys() here, because the keys are seeded */
737 6 : ed25519_keypair_t kp1, kp2;
738 6 : ed25519_secret_key_from_seed(&kp1.seckey,
739 : (const uint8_t*)"YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY");
740 6 : ed25519_public_key_generate(&kp1.pubkey, &kp1.seckey);
741 6 : ed25519_secret_key_from_seed(&kp2.seckey,
742 : (const uint8_t*)"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
743 6 : ed25519_public_key_generate(&kp2.pubkey, &kp2.seckey);
744 6 : r2->cache_info.signing_key_cert = tor_cert_create_ed25519(&kp1,
745 : CERT_TYPE_ID_SIGNING,
746 : &kp2.pubkey,
747 : now, 86400,
748 : CERT_FLAG_INCLUDE_SIGNING_KEY);
749 :
750 : /* Now add an exit policy */
751 6 : ex1 = tor_malloc_zero(sizeof(addr_policy_t));
752 6 : ex2 = tor_malloc_zero(sizeof(addr_policy_t));
753 6 : ex1->policy_type = ADDR_POLICY_ACCEPT;
754 6 : tor_addr_from_ipv4h(&ex1->addr, 0);
755 6 : ex1->maskbits = 0;
756 6 : ex1->prt_min = ex1->prt_max = 80;
757 6 : ex2->policy_type = ADDR_POLICY_REJECT;
758 6 : tor_addr_from_ipv4h(&ex2->addr, 18<<24);
759 6 : ex2->maskbits = 8;
760 6 : ex2->prt_min = ex2->prt_max = 24;
761 :
762 6 : r2->exit_policy = smartlist_new();
763 6 : smartlist_add(r2->exit_policy, ex1);
764 6 : smartlist_add(r2->exit_policy, ex2);
765 :
766 : /* Fake just enough of an ORPort to get by */
767 6 : setup_mock_configured_ports(r2->ipv4_orport, 0);
768 :
769 12 : buf = router_dump_router_to_string(r2,
770 6 : r2->identity_pkey, r2_onion_pkey,
771 : &r2_onion_keypair, &kp2);
772 6 : tt_assert(buf);
773 :
774 6 : cleanup_mock_configured_ports();
775 :
776 6 : chunks = smartlist_new();
777 :
778 : /* Synthesise a router descriptor, without the signatures */
779 6 : smartlist_add(chunks, get_new_router_line(r2));
780 :
781 6 : smartlist_add_strdup(chunks,
782 : "identity-ed25519\n"
783 : "-----BEGIN ED25519 CERT-----\n");
784 6 : base64_encode(cert_buf, sizeof(cert_buf),
785 6 : (const char*)r2->cache_info.signing_key_cert->encoded,
786 6 : r2->cache_info.signing_key_cert->encoded_len,
787 : BASE64_ENCODE_MULTILINE);
788 6 : smartlist_add_strdup(chunks, cert_buf);
789 6 : smartlist_add_strdup(chunks, "-----END ED25519 CERT-----\n");
790 :
791 6 : smartlist_add_strdup(chunks, "master-key-ed25519 ");
792 : {
793 6 : char k[ED25519_BASE64_LEN+1];
794 6 : ed25519_public_to_base64(k, &r2->cache_info.signing_key_cert->signing_key);
795 6 : smartlist_add_strdup(chunks, k);
796 6 : smartlist_add_strdup(chunks, "\n");
797 : }
798 :
799 6 : smartlist_add(chunks, get_new_platform_line());
800 6 : smartlist_add_asprintf(chunks,
801 : "proto %s\n", protover_get_supported_protocols());
802 6 : smartlist_add(chunks, get_new_published_line(r2));
803 6 : smartlist_add(chunks, get_new_fingerprint_line(r2));
804 :
805 6 : smartlist_add(chunks, get_new_uptime_line(0));
806 6 : smartlist_add(chunks, get_new_bandwidth_line(r2));
807 :
808 6 : smartlist_add(chunks, get_new_onion_key_block(r2));
809 6 : smartlist_add(chunks, get_new_signing_key_block(r2));
810 :
811 6 : int rsa_cc_len;
812 12 : rsa_cc = make_tap_onion_key_crosscert(r2_onion_pkey,
813 : &kp1.pubkey,
814 6 : r2->identity_pkey,
815 : &rsa_cc_len);
816 6 : tt_assert(rsa_cc);
817 6 : base64_encode(cert_buf, sizeof(cert_buf), (char*)rsa_cc, rsa_cc_len,
818 : BASE64_ENCODE_MULTILINE);
819 6 : smartlist_add_strdup(chunks, "onion-key-crosscert\n"
820 : "-----BEGIN CROSSCERT-----\n");
821 6 : smartlist_add_strdup(chunks, cert_buf);
822 6 : smartlist_add_strdup(chunks, "-----END CROSSCERT-----\n");
823 6 : int ntor_cc_sign;
824 : {
825 6 : tor_cert_t *ntor_cc = NULL;
826 6 : ntor_cc = make_ntor_onion_key_crosscert(&r2_onion_keypair,
827 : &kp1.pubkey,
828 : r2->cache_info.published_on,
829 6 : get_onion_key_lifetime(),
830 : &ntor_cc_sign);
831 6 : tt_assert(ntor_cc);
832 6 : base64_encode(cert_buf, sizeof(cert_buf),
833 6 : (char*)ntor_cc->encoded, ntor_cc->encoded_len,
834 : BASE64_ENCODE_MULTILINE);
835 6 : tor_cert_free(ntor_cc);
836 : }
837 6 : smartlist_add_asprintf(chunks,
838 : "ntor-onion-key-crosscert %d\n"
839 : "-----BEGIN ED25519 CERT-----\n"
840 : "%s"
841 : "-----END ED25519 CERT-----\n", ntor_cc_sign, cert_buf);
842 :
843 6 : smartlist_add_strdup(chunks, "hidden-service-dir\n");
844 :
845 6 : smartlist_add(chunks, get_new_bridge_distribution_request_line(options));
846 6 : smartlist_add(chunks, get_new_ntor_onion_key_line(&r2_onion_keypair.pubkey));
847 6 : smartlist_add_strdup(chunks, "accept *:80\nreject 18.0.0.0/8:24\n");
848 6 : smartlist_add_strdup(chunks, "tunnelled-dir-server\n");
849 :
850 6 : smartlist_add_strdup(chunks, "router-sig-ed25519 ");
851 :
852 6 : size_t len_out = 0;
853 6 : buf2 = smartlist_join_strings(chunks, "", 0, &len_out);
854 156 : SMARTLIST_FOREACH(chunks, char *, s, tor_free(s));
855 6 : smartlist_free(chunks);
856 :
857 6 : tt_assert(len_out > 0);
858 :
859 6 : buf[strlen(buf2)] = '\0'; /* Don't compare either sig; they're never the same
860 : * twice */
861 :
862 6 : tt_str_op(buf, OP_EQ, buf2);
863 6 : tor_free(buf);
864 :
865 6 : setup_mock_configured_ports(r2->ipv4_orport, 0);
866 :
867 6 : buf = router_dump_router_to_string(r2, r2->identity_pkey,
868 : r2_onion_pkey,
869 : &r2_onion_keypair, &kp2);
870 6 : tt_assert(buf);
871 :
872 6 : cleanup_mock_configured_ports();
873 :
874 : /* Now, try to parse buf */
875 6 : cp = buf;
876 6 : rp2 = router_parse_entry_from_string((const char*)cp,NULL,1,0,NULL,NULL);
877 :
878 6 : CHECK_ROUTERINFO_CONSISTENCY(r2, rp2);
879 :
880 6 : tt_mem_op(rp2->onion_curve25519_pkey->public_key,OP_EQ,
881 : r2->onion_curve25519_pkey->public_key,
882 6 : CURVE25519_PUBKEY_LEN);
883 :
884 6 : CHECK_PARSED_EXIT_POLICY(rp2);
885 :
886 6 : tor_free(buf);
887 6 : routerinfo_free(rp2);
888 :
889 : /* Test extrainfo creation. */
890 :
891 : /* Set up standard mocks and data */
892 6 : setup_mocks_for_fresh_descriptor(r2, r2_onion_pkey);
893 :
894 : /* router_build_fresh_descriptor() requires
895 : * router_build_fresh_unsigned_routerinfo(), but the implementation is
896 : * too complex. Instead, we re-use r2.
897 : */
898 6 : mocked_routerinfo = r2;
899 6 : MOCK(router_build_fresh_unsigned_routerinfo,
900 : mock_router_build_fresh_unsigned_routerinfo);
901 :
902 : /* r2 uses ed25519, so we need to mock the ed key functions */
903 6 : mocked_master_signing_key = &kp2;
904 6 : MOCK(get_master_signing_keypair, mock_get_master_signing_keypair);
905 :
906 6 : mocked_signing_key_cert = r2->cache_info.signing_key_cert;
907 6 : MOCK(get_master_signing_key_cert, mock_get_master_signing_key_cert);
908 :
909 6 : mocked_curve25519_onion_key = &r2_onion_keypair;
910 6 : MOCK(get_current_curve25519_keypair, mock_get_current_curve25519_keypair);
911 :
912 : /* Fake just enough of an ORPort to get by */
913 6 : setup_mock_configured_ports(r2->ipv4_orport, 0);
914 :
915 : /* Test the high-level interface. */
916 6 : rv = router_build_fresh_descriptor(&r2_out, &e2);
917 6 : if (rv < 0) {
918 : /* router_build_fresh_descriptor() frees r2 on failure. */
919 0 : r2 = NULL;
920 : /* Get rid of an alias to rp2 */
921 0 : r2_out = NULL;
922 : }
923 6 : tt_assert(rv == 0);
924 6 : tt_assert(r2_out);
925 6 : tt_assert(e2);
926 : /* Guaranteed by mock_router_build_fresh_unsigned_routerinfo() */
927 6 : tt_ptr_op(r2_out, OP_EQ, r2);
928 : /* Get rid of an alias to r2 */
929 6 : r2_out = NULL;
930 :
931 : /* Now cleanup */
932 6 : cleanup_mocks_for_fresh_descriptor();
933 :
934 6 : mocked_routerinfo = NULL;
935 6 : UNMOCK(router_build_fresh_unsigned_routerinfo);
936 6 : mocked_master_signing_key = NULL;
937 6 : UNMOCK(get_master_signing_keypair);
938 6 : mocked_signing_key_cert = NULL;
939 6 : UNMOCK(get_master_signing_key_cert);
940 6 : mocked_curve25519_onion_key = NULL;
941 6 : UNMOCK(get_current_curve25519_keypair);
942 :
943 6 : cleanup_mock_configured_ports();
944 :
945 6 : CHECK_EXTRAINFO_CONSISTENCY(r2, e2);
946 :
947 : /* Test that the signed ri is parseable */
948 6 : tt_assert(r2->cache_info.signed_descriptor_body);
949 6 : cp = r2->cache_info.signed_descriptor_body;
950 6 : rp2 = router_parse_entry_from_string((const char*)cp,NULL,1,0,NULL,NULL);
951 :
952 6 : CHECK_ROUTERINFO_CONSISTENCY(r2, rp2);
953 :
954 6 : tt_mem_op(rp2->onion_curve25519_pkey->public_key,OP_EQ,
955 : r2->onion_curve25519_pkey->public_key,
956 6 : CURVE25519_PUBKEY_LEN);
957 :
958 6 : CHECK_PARSED_EXIT_POLICY(rp2);
959 :
960 6 : routerinfo_free(rp2);
961 :
962 : /* Test that the signed ei is parseable */
963 6 : tt_assert(e2->cache_info.signed_descriptor_body);
964 6 : cp = e2->cache_info.signed_descriptor_body;
965 6 : ep2 = extrainfo_parse_entry_from_string((const char*)cp,NULL,1,NULL,NULL);
966 :
967 6 : CHECK_EXTRAINFO_CONSISTENCY(r2, ep2);
968 :
969 : /* In future tests, we could check the actual extrainfo statistics. */
970 :
971 6 : extrainfo_free(ep2);
972 :
973 6 : done:
974 6 : dirserv_free_fingerprint_list();
975 :
976 6 : tor_free(options->Nickname);
977 :
978 6 : cleanup_mock_configured_ports();
979 6 : cleanup_mocks_for_fresh_descriptor();
980 :
981 6 : if (chunks) {
982 0 : SMARTLIST_FOREACH(chunks, char *, s, tor_free(s));
983 0 : smartlist_free(chunks);
984 : }
985 :
986 6 : routerinfo_free(r2);
987 6 : routerinfo_free(r2_out);
988 6 : routerinfo_free(rp2);
989 :
990 6 : extrainfo_free(e2);
991 6 : extrainfo_free(ep2);
992 :
993 6 : tor_free(rsa_cc);
994 6 : crypto_pk_free(r2_onion_pkey);
995 :
996 6 : tor_free(buf);
997 6 : tor_free(buf2);
998 6 : }
999 :
1000 : #include "failing_routerdescs.inc"
1001 :
1002 : static void
1003 1 : test_dir_routerinfo_parsing(void *arg)
1004 : {
1005 1 : (void) arg;
1006 :
1007 1 : int again;
1008 1 : routerinfo_t *ri = NULL;
1009 :
1010 : #define CHECK_OK(s) \
1011 : do { \
1012 : routerinfo_free(ri); \
1013 : ri = router_parse_entry_from_string((s), NULL, 0, 0, NULL, NULL); \
1014 : tt_assert(ri); \
1015 : } while (0)
1016 : #define CHECK_FAIL(s, againval) \
1017 : do { \
1018 : routerinfo_free(ri); \
1019 : again = 999; \
1020 : ri = router_parse_entry_from_string((s), NULL, 0, 0, NULL, &again); \
1021 : tt_assert(ri == NULL); \
1022 : tt_int_op(again, OP_EQ, (againval)); \
1023 : } while (0)
1024 :
1025 1 : CHECK_OK(EX_RI_MINIMAL);
1026 1 : CHECK_OK(EX_RI_MAXIMAL);
1027 :
1028 : /* good annotations prepended */
1029 1 : routerinfo_free(ri);
1030 1 : ri = router_parse_entry_from_string(EX_RI_MINIMAL, NULL, 0, 0,
1031 : "@purpose bridge\n", NULL);
1032 1 : tt_ptr_op(ri, OP_NE, NULL);
1033 1 : tt_assert(ri->purpose == ROUTER_PURPOSE_BRIDGE);
1034 1 : routerinfo_free(ri);
1035 :
1036 : /* bad annotations prepended. */
1037 1 : ri = router_parse_entry_from_string(EX_RI_MINIMAL,
1038 : NULL, 0, 0, "@purpose\n", NULL);
1039 1 : tt_ptr_op(ri, OP_EQ, NULL);
1040 :
1041 : /* bad annotations on router. */
1042 1 : ri = router_parse_entry_from_string("@purpose\nrouter x\n", NULL, 0, 1,
1043 : NULL, NULL);
1044 1 : tt_ptr_op(ri, OP_EQ, NULL);
1045 :
1046 : /* unwanted annotations on router. */
1047 1 : ri = router_parse_entry_from_string("@purpose foo\nrouter x\n", NULL, 0, 0,
1048 : NULL, NULL);
1049 1 : tt_ptr_op(ri, OP_EQ, NULL);
1050 :
1051 : /* No signature. */
1052 1 : ri = router_parse_entry_from_string("router x\n", NULL, 0, 0,
1053 : NULL, NULL);
1054 1 : tt_ptr_op(ri, OP_EQ, NULL);
1055 :
1056 : /* Not a router */
1057 1 : routerinfo_free(ri);
1058 1 : ri = router_parse_entry_from_string("hello\n", NULL, 0, 0, NULL, NULL);
1059 1 : tt_ptr_op(ri, OP_EQ, NULL);
1060 :
1061 1 : CHECK_FAIL(EX_RI_BAD_SIG1, 1);
1062 1 : CHECK_FAIL(EX_RI_BAD_TOKENS, 0);
1063 1 : CHECK_FAIL(EX_RI_BAD_PUBLISHED, 0);
1064 1 : CHECK_FAIL(EX_RI_NEG_BANDWIDTH, 0);
1065 1 : CHECK_FAIL(EX_RI_BAD_BANDWIDTH, 0);
1066 1 : CHECK_FAIL(EX_RI_BAD_BANDWIDTH2, 0);
1067 1 : CHECK_FAIL(EX_RI_BAD_BANDWIDTH3, 0);
1068 1 : CHECK_FAIL(EX_RI_BAD_ONIONKEY, 0);
1069 1 : CHECK_FAIL(EX_RI_BAD_PORTS, 0);
1070 1 : CHECK_FAIL(EX_RI_BAD_IP, 0);
1071 1 : CHECK_FAIL(EX_RI_BAD_DIRPORT, 0);
1072 1 : CHECK_FAIL(EX_RI_BAD_NAME2, 0);
1073 1 : CHECK_FAIL(EX_RI_BAD_UPTIME, 0);
1074 :
1075 1 : CHECK_FAIL(EX_RI_BAD_BANDWIDTH3, 0);
1076 1 : CHECK_FAIL(EX_RI_BAD_NTOR_KEY, 0);
1077 1 : CHECK_FAIL(EX_RI_BAD_FINGERPRINT, 0);
1078 1 : CHECK_FAIL(EX_RI_MISMATCHED_FINGERPRINT, 0);
1079 1 : CHECK_FAIL(EX_RI_BAD_HAS_ACCEPT6, 0);
1080 1 : CHECK_FAIL(EX_RI_BAD_NO_EXIT_POLICY, 0);
1081 1 : CHECK_FAIL(EX_RI_BAD_IPV6_EXIT_POLICY, 0);
1082 1 : CHECK_FAIL(EX_RI_BAD_FAMILY, 0);
1083 1 : CHECK_FAIL(EX_RI_ZERO_ORPORT, 0);
1084 :
1085 1 : CHECK_FAIL(EX_RI_ED_MISSING_CROSSCERT, 0);
1086 1 : CHECK_FAIL(EX_RI_ED_MISSING_CROSSCERT2, 0);
1087 1 : CHECK_FAIL(EX_RI_ED_MISSING_CROSSCERT_SIGN, 0);
1088 1 : CHECK_FAIL(EX_RI_ED_BAD_SIG1, 0);
1089 1 : CHECK_FAIL(EX_RI_ED_BAD_SIG2, 0);
1090 1 : CHECK_FAIL(EX_RI_ED_BAD_SIG3, 0);
1091 1 : CHECK_FAIL(EX_RI_ED_BAD_CROSSCERT1, 0);
1092 1 : CHECK_FAIL(EX_RI_ED_MISPLACED1, 0);
1093 1 : CHECK_FAIL(EX_RI_ED_MISPLACED2, 0);
1094 1 : CHECK_FAIL(EX_RI_ED_BAD_CERT1, 0);
1095 :
1096 : #undef CHECK_FAIL
1097 : #undef CHECK_OK
1098 1 : done:
1099 1 : routerinfo_free(ri);
1100 1 : }
1101 :
1102 : #include "example_extrainfo.inc"
1103 :
1104 : static void
1105 17 : routerinfo_free_wrapper_(void *arg)
1106 : {
1107 17 : routerinfo_free_(arg);
1108 17 : }
1109 :
1110 : static void
1111 1 : test_dir_extrainfo_parsing(void *arg)
1112 : {
1113 1 : (void) arg;
1114 :
1115 : #define CHECK_OK(s) \
1116 : do { \
1117 : extrainfo_free(ei); \
1118 : ei = extrainfo_parse_entry_from_string((s), NULL, 0, map, NULL); \
1119 : tt_assert(ei); \
1120 : } while (0)
1121 : #define CHECK_FAIL(s, againval) \
1122 : do { \
1123 : extrainfo_free(ei); \
1124 : again = 999; \
1125 : ei = extrainfo_parse_entry_from_string((s), NULL, 0, map, &again); \
1126 : tt_assert(ei == NULL); \
1127 : tt_int_op(again, OP_EQ, (againval)); \
1128 : } while (0)
1129 : #define ADD(name) \
1130 : do { \
1131 : ri = tor_malloc_zero(sizeof(routerinfo_t)); \
1132 : crypto_pk_t *pk = ri->identity_pkey = crypto_pk_new(); \
1133 : tt_assert(! crypto_pk_read_public_key_from_string(pk, \
1134 : name##_KEY, strlen(name##_KEY))); \
1135 : tt_int_op(20,OP_EQ,base16_decode(d, 20, name##_FP, strlen(name##_FP))); \
1136 : digestmap_set((digestmap_t*)map, d, ri); \
1137 : ri = NULL; \
1138 : } while (0)
1139 :
1140 1 : routerinfo_t *ri = NULL;
1141 1 : char d[20];
1142 1 : struct digest_ri_map_t *map = NULL;
1143 1 : extrainfo_t *ei = NULL;
1144 1 : int again;
1145 :
1146 1 : CHECK_OK(EX_EI_MINIMAL);
1147 1 : tt_assert(ei->pending_sig);
1148 1 : CHECK_OK(EX_EI_MAXIMAL);
1149 1 : tt_assert(ei->pending_sig);
1150 :
1151 1 : map = (struct digest_ri_map_t *)digestmap_new();
1152 1 : ADD(EX_EI_MINIMAL);
1153 1 : ADD(EX_EI_MAXIMAL);
1154 1 : ADD(EX_EI_BAD_NICKNAME);
1155 1 : ADD(EX_EI_BAD_TOKENS);
1156 1 : ADD(EX_EI_BAD_START);
1157 1 : ADD(EX_EI_BAD_PUBLISHED);
1158 :
1159 1 : ADD(EX_EI_ED_MISSING_SIG);
1160 1 : ADD(EX_EI_ED_MISSING_CERT);
1161 1 : ADD(EX_EI_ED_BAD_CERT1);
1162 1 : ADD(EX_EI_ED_BAD_CERT2);
1163 1 : ADD(EX_EI_ED_MISPLACED_CERT);
1164 1 : ADD(EX_EI_ED_MISPLACED_SIG);
1165 :
1166 1 : CHECK_OK(EX_EI_MINIMAL);
1167 1 : tt_ptr_op(ei->pending_sig, OP_EQ, NULL);
1168 1 : CHECK_OK(EX_EI_MAXIMAL);
1169 1 : tt_ptr_op(ei->pending_sig, OP_EQ, NULL);
1170 :
1171 1 : CHECK_FAIL(EX_EI_BAD_SIG1,1);
1172 1 : CHECK_FAIL(EX_EI_BAD_SIG2,0);
1173 1 : CHECK_FAIL(EX_EI_BAD_NICKNAME,0);
1174 1 : CHECK_FAIL(EX_EI_BAD_TOKENS,0);
1175 1 : CHECK_FAIL(EX_EI_BAD_START,0);
1176 1 : CHECK_FAIL(EX_EI_BAD_PUBLISHED,0);
1177 :
1178 1 : CHECK_FAIL(EX_EI_ED_MISSING_SIG,0);
1179 1 : CHECK_FAIL(EX_EI_ED_MISSING_CERT,0);
1180 1 : CHECK_FAIL(EX_EI_ED_BAD_CERT1,0);
1181 1 : CHECK_FAIL(EX_EI_ED_BAD_CERT2,0);
1182 1 : CHECK_FAIL(EX_EI_ED_MISPLACED_CERT,0);
1183 1 : CHECK_FAIL(EX_EI_ED_MISPLACED_SIG,0);
1184 :
1185 : #undef CHECK_OK
1186 : #undef CHECK_FAIL
1187 :
1188 1 : done:
1189 1 : escaped(NULL);
1190 1 : extrainfo_free(ei);
1191 1 : routerinfo_free(ri);
1192 1 : digestmap_free_((digestmap_t*)map, routerinfo_free_wrapper_);
1193 1 : }
1194 :
1195 : static void
1196 1 : test_dir_parse_router_list(void *arg)
1197 : {
1198 1 : (void) arg;
1199 1 : smartlist_t *invalid = smartlist_new();
1200 1 : smartlist_t *dest = smartlist_new();
1201 1 : smartlist_t *chunks = smartlist_new();
1202 1 : int dest_has_ri = 1;
1203 1 : char *list = NULL;
1204 1 : const char *cp;
1205 1 : digestmap_t *map = NULL;
1206 1 : char *mem_op_hex_tmp = NULL;
1207 1 : routerinfo_t *ri = NULL;
1208 1 : char d[DIGEST_LEN];
1209 :
1210 1 : smartlist_add_strdup(chunks, EX_RI_MINIMAL); // ri 0
1211 1 : smartlist_add_strdup(chunks, EX_RI_BAD_PORTS); // bad ri 0
1212 1 : smartlist_add_strdup(chunks, EX_EI_MAXIMAL); // ei 0
1213 1 : smartlist_add_strdup(chunks, EX_EI_BAD_SIG2); // bad ei --
1214 1 : smartlist_add_strdup(chunks, EX_EI_BAD_NICKNAME);// bad ei 0
1215 1 : smartlist_add_strdup(chunks, EX_RI_BAD_SIG1); // bad ri --
1216 1 : smartlist_add_strdup(chunks, EX_EI_BAD_PUBLISHED); // bad ei 1
1217 1 : smartlist_add_strdup(chunks, EX_RI_MAXIMAL); // ri 1
1218 1 : smartlist_add_strdup(chunks, EX_RI_BAD_FAMILY); // bad ri 1
1219 1 : smartlist_add_strdup(chunks, EX_EI_MINIMAL); // ei 1
1220 :
1221 1 : list = smartlist_join_strings(chunks, "", 0, NULL);
1222 :
1223 : /* First, parse the routers. */
1224 1 : cp = list;
1225 1 : tt_int_op(0,OP_EQ,
1226 : router_parse_list_from_string(&cp, NULL, dest, SAVED_NOWHERE,
1227 : 0, 0, NULL, invalid));
1228 1 : tt_int_op(2, OP_EQ, smartlist_len(dest));
1229 1 : tt_ptr_op(cp, OP_EQ, list + strlen(list));
1230 :
1231 1 : routerinfo_t *r = smartlist_get(dest, 0);
1232 1 : tt_mem_op(r->cache_info.signed_descriptor_body, OP_EQ,
1233 1 : EX_RI_MINIMAL, strlen(EX_RI_MINIMAL));
1234 1 : r = smartlist_get(dest, 1);
1235 1 : tt_mem_op(r->cache_info.signed_descriptor_body, OP_EQ,
1236 1 : EX_RI_MAXIMAL, strlen(EX_RI_MAXIMAL));
1237 :
1238 1 : setup_ei_digests();
1239 :
1240 1 : tt_int_op(2, OP_EQ, smartlist_len(invalid));
1241 :
1242 1 : test_memeq_hex(smartlist_get(invalid, 0),
1243 : "10F951AF93AED0D3BC7FA5FFA232EB8C17747ACE");
1244 1 : test_memeq_hex(smartlist_get(invalid, 1),
1245 : "41D8723CDD4B1AADCCE538C28CDE7F69828C73D0");
1246 :
1247 : /* Now tidy up */
1248 3 : SMARTLIST_FOREACH(dest, routerinfo_t *, rinfo, routerinfo_free(rinfo));
1249 3 : SMARTLIST_FOREACH(invalid, uint8_t *, dig, tor_free(dig));
1250 1 : smartlist_clear(dest);
1251 1 : smartlist_clear(invalid);
1252 :
1253 : /* And check extrainfos. */
1254 1 : dest_has_ri = 0;
1255 1 : map = (digestmap_t*)router_get_routerlist()->identity_map;
1256 1 : ADD(EX_EI_MINIMAL);
1257 1 : ADD(EX_EI_MAXIMAL);
1258 1 : ADD(EX_EI_BAD_NICKNAME);
1259 1 : ADD(EX_EI_BAD_PUBLISHED);
1260 1 : ADD(EX_EI_BAD_SIG2);
1261 1 : cp = list;
1262 1 : tt_int_op(0,OP_EQ,
1263 : router_parse_list_from_string(&cp, NULL, dest, SAVED_NOWHERE,
1264 : 1, 0, NULL, invalid));
1265 1 : tt_int_op(2, OP_EQ, smartlist_len(dest));
1266 1 : extrainfo_t *e = smartlist_get(dest, 0);
1267 1 : tt_mem_op(e->cache_info.signed_descriptor_body, OP_EQ,
1268 1 : EX_EI_MAXIMAL, strlen(EX_EI_MAXIMAL));
1269 1 : e = smartlist_get(dest, 1);
1270 1 : tt_mem_op(e->cache_info.signed_descriptor_body, OP_EQ,
1271 1 : EX_EI_MINIMAL, strlen(EX_EI_MINIMAL));
1272 :
1273 1 : tt_int_op(3, OP_EQ, smartlist_len(invalid));
1274 1 : tt_mem_op(smartlist_get(invalid, 0),
1275 : OP_EQ,
1276 1 : digest_ei_bad_sig2, DIGEST_LEN);
1277 1 : tt_mem_op(smartlist_get(invalid, 1),
1278 : OP_EQ,
1279 1 : digest_ei_bad_nickname, DIGEST_LEN);
1280 1 : tt_mem_op(smartlist_get(invalid, 2),
1281 : OP_EQ,
1282 1 : digest_ei_bad_published, DIGEST_LEN);
1283 :
1284 1 : done:
1285 1 : tor_free(list);
1286 1 : if (dest_has_ri)
1287 0 : SMARTLIST_FOREACH(dest, routerinfo_t *, rt, routerinfo_free(rt));
1288 : else
1289 3 : SMARTLIST_FOREACH(dest, extrainfo_t *, ei, extrainfo_free(ei));
1290 1 : smartlist_free(dest);
1291 4 : SMARTLIST_FOREACH(invalid, uint8_t *, dig, tor_free(dig));
1292 1 : smartlist_free(invalid);
1293 11 : SMARTLIST_FOREACH(chunks, char *, chunk, tor_free(chunk));
1294 1 : smartlist_free(chunks);
1295 1 : routerinfo_free(ri);
1296 1 : if (map) {
1297 1 : digestmap_free_((digestmap_t*)map, routerinfo_free_wrapper_);
1298 1 : router_get_routerlist()->identity_map =
1299 1 : (struct digest_ri_map_t*)digestmap_new();
1300 : }
1301 1 : tor_free(mem_op_hex_tmp);
1302 :
1303 : #undef ADD
1304 1 : }
1305 :
1306 : static download_status_t dls_minimal;
1307 : static download_status_t dls_maximal;
1308 : static download_status_t dls_bad_fingerprint;
1309 : static download_status_t dls_bad_sig1;
1310 : static download_status_t dls_bad_ports;
1311 : static download_status_t dls_bad_tokens;
1312 :
1313 : static uint8_t digest_minimal[20];
1314 : static uint8_t digest_maximal[20];
1315 : static uint8_t digest_bad_fingerprint[20];
1316 : static uint8_t digest_bad_sig1[20];
1317 : static uint8_t digest_bad_ports[20];
1318 : static uint8_t digest_bad_tokens[20];
1319 :
1320 : static void
1321 1 : setup_dls_digests(void)
1322 : {
1323 : #define SETUP(string, name) \
1324 : do { \
1325 : router_get_router_hash(string, strlen(string), (char*)digest_##name); \
1326 : } while (0)
1327 :
1328 1 : SETUP(EX_RI_MINIMAL, minimal);
1329 1 : SETUP(EX_RI_MAXIMAL, maximal);
1330 1 : SETUP(EX_RI_BAD_FINGERPRINT, bad_fingerprint);
1331 1 : SETUP(EX_RI_BAD_SIG1, bad_sig1);
1332 1 : SETUP(EX_RI_BAD_PORTS, bad_ports);
1333 1 : SETUP(EX_RI_BAD_TOKENS, bad_tokens);
1334 : #undef SETUP
1335 1 : }
1336 :
1337 : static int mock_router_get_dl_status_unrecognized = 0;
1338 : static int mock_router_get_dl_status_calls = 0;
1339 :
1340 : static download_status_t *
1341 2 : mock_router_get_dl_status(const char *d)
1342 : {
1343 2 : ++mock_router_get_dl_status_calls;
1344 : #define CHECK(name) \
1345 : do { \
1346 : if (fast_memeq(d, digest_##name, DIGEST_LEN)) \
1347 : return &dls_##name; \
1348 : } while (0)
1349 :
1350 2 : CHECK(minimal);
1351 2 : CHECK(maximal);
1352 2 : CHECK(bad_fingerprint);
1353 1 : CHECK(bad_sig1);
1354 1 : CHECK(bad_ports);
1355 1 : CHECK(bad_tokens);
1356 :
1357 0 : ++mock_router_get_dl_status_unrecognized;
1358 0 : return NULL;
1359 : #undef CHECK
1360 : }
1361 :
1362 : static void
1363 1 : test_dir_load_routers(void *arg)
1364 : {
1365 1 : (void) arg;
1366 1 : smartlist_t *chunks = smartlist_new();
1367 1 : smartlist_t *wanted = smartlist_new();
1368 1 : char buf[DIGEST_LEN];
1369 1 : char *mem_op_hex_tmp = NULL;
1370 1 : char *list = NULL;
1371 :
1372 : #define ADD(str) \
1373 : do { \
1374 : tt_int_op(0,OP_EQ,router_get_router_hash(str, strlen(str), buf)); \
1375 : smartlist_add_strdup(wanted, hex_str(buf, DIGEST_LEN)); \
1376 : } while (0)
1377 :
1378 1 : setup_dls_digests();
1379 :
1380 1 : MOCK(router_get_dl_status_by_descriptor_digest, mock_router_get_dl_status);
1381 :
1382 1 : update_approx_time(1412510400);
1383 :
1384 1 : smartlist_add_strdup(chunks, EX_RI_MINIMAL);
1385 1 : smartlist_add_strdup(chunks, EX_RI_BAD_FINGERPRINT);
1386 1 : smartlist_add_strdup(chunks, EX_RI_BAD_SIG1);
1387 1 : smartlist_add_strdup(chunks, EX_RI_MAXIMAL);
1388 1 : smartlist_add_strdup(chunks, EX_RI_BAD_PORTS);
1389 1 : smartlist_add_strdup(chunks, EX_RI_BAD_TOKENS);
1390 :
1391 : /* not ADDing MINIMAL */
1392 1 : ADD(EX_RI_MAXIMAL);
1393 1 : ADD(EX_RI_BAD_FINGERPRINT);
1394 1 : ADD(EX_RI_BAD_SIG1);
1395 : /* Not ADDing BAD_PORTS */
1396 1 : ADD(EX_RI_BAD_TOKENS);
1397 :
1398 1 : list = smartlist_join_strings(chunks, "", 0, NULL);
1399 1 : tt_int_op(1, OP_EQ,
1400 : router_load_routers_from_string(list, NULL, SAVED_IN_JOURNAL,
1401 : wanted, 1, NULL));
1402 :
1403 : /* The "maximal" router was added. */
1404 : /* "minimal" was not. */
1405 1 : tt_int_op(smartlist_len(router_get_routerlist()->routers),OP_EQ,1);
1406 1 : routerinfo_t *r = smartlist_get(router_get_routerlist()->routers, 0);
1407 1 : test_memeq_hex(r->cache_info.signed_descriptor_digest,
1408 : "1F437798ACD1FC9CBD1C3C04DBF80F7E9F819C3F");
1409 1 : tt_int_op(dls_minimal.n_download_failures, OP_EQ, 0);
1410 1 : tt_int_op(dls_maximal.n_download_failures, OP_EQ, 0);
1411 :
1412 : /* "Bad fingerprint" and "Bad tokens" should have gotten marked
1413 : * non-retriable. */
1414 1 : tt_want_int_op(mock_router_get_dl_status_calls, OP_EQ, 2);
1415 1 : tt_want_int_op(mock_router_get_dl_status_unrecognized, OP_EQ, 0);
1416 1 : tt_int_op(dls_bad_fingerprint.n_download_failures, OP_EQ, 255);
1417 1 : tt_int_op(dls_bad_tokens.n_download_failures, OP_EQ, 255);
1418 :
1419 : /* bad_sig2 and bad ports" are retriable -- one since only the signature
1420 : * was bad, and one because we didn't ask for it. */
1421 1 : tt_int_op(dls_bad_sig1.n_download_failures, OP_EQ, 0);
1422 1 : tt_int_op(dls_bad_ports.n_download_failures, OP_EQ, 0);
1423 :
1424 1 : tt_int_op(smartlist_len(wanted), OP_EQ, 1);
1425 1 : tt_str_op(smartlist_get(wanted, 0), OP_EQ,
1426 : "3BB7D03C1C4DBC1DDE840096FF3C330914757B77");
1427 :
1428 : #undef ADD
1429 :
1430 1 : done:
1431 1 : tor_free(mem_op_hex_tmp);
1432 1 : UNMOCK(router_get_dl_status_by_descriptor_digest);
1433 7 : SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
1434 1 : smartlist_free(chunks);
1435 2 : SMARTLIST_FOREACH(wanted, char *, cp, tor_free(cp));
1436 1 : smartlist_free(wanted);
1437 1 : tor_free(list);
1438 1 : }
1439 :
1440 : static int mock_get_by_ei_dd_calls = 0;
1441 : static int mock_get_by_ei_dd_unrecognized = 0;
1442 :
1443 : static signed_descriptor_t sd_ei_minimal;
1444 : static signed_descriptor_t sd_ei_bad_nickname;
1445 : static signed_descriptor_t sd_ei_maximal;
1446 : static signed_descriptor_t sd_ei_bad_tokens;
1447 : static signed_descriptor_t sd_ei_bad_sig2;
1448 :
1449 : static void
1450 3 : setup_ei_digests(void)
1451 : {
1452 : #define SETUP(string, name) \
1453 : do { \
1454 : router_get_extrainfo_hash(string, strlen(string), \
1455 : (char*)digest_ei_##name); \
1456 : } while (0)
1457 :
1458 3 : SETUP(EX_EI_MINIMAL, minimal);
1459 3 : SETUP(EX_EI_MAXIMAL, maximal);
1460 3 : SETUP(EX_EI_BAD_NICKNAME, bad_nickname);
1461 3 : SETUP(EX_EI_BAD_TOKENS, bad_tokens);
1462 3 : SETUP(EX_EI_BAD_SIG2, bad_sig2);
1463 3 : SETUP(EX_EI_BAD_PUBLISHED, bad_published);
1464 :
1465 : #undef SETUP
1466 3 : }
1467 :
1468 : static signed_descriptor_t *
1469 2 : mock_get_by_ei_desc_digest(const char *d)
1470 : {
1471 2 : ++mock_get_by_ei_dd_calls;
1472 : #define CHECK(name) \
1473 : do { \
1474 : if (fast_memeq(d, digest_ei_##name, DIGEST_LEN)) \
1475 : return &sd_ei_##name; \
1476 : } while (0)
1477 :
1478 2 : CHECK(minimal);
1479 2 : CHECK(maximal);
1480 2 : CHECK(bad_nickname);
1481 1 : CHECK(bad_sig2);
1482 1 : CHECK(bad_tokens);
1483 0 : ++mock_get_by_ei_dd_unrecognized;
1484 0 : return NULL;
1485 : #undef CHECK
1486 : }
1487 :
1488 : static signed_descriptor_t *
1489 1 : mock_ei_get_by_ei_digest(const char *d)
1490 : {
1491 1 : signed_descriptor_t *sd = &sd_ei_minimal;
1492 :
1493 1 : if (fast_memeq(d, digest_ei_minimal, DIGEST_LEN)) {
1494 1 : sd->signed_descriptor_body = (char *)EX_EI_MINIMAL;
1495 1 : sd->signed_descriptor_len = sizeof(EX_EI_MINIMAL);
1496 1 : sd->annotations_len = 0;
1497 1 : sd->saved_location = SAVED_NOWHERE;
1498 1 : return sd;
1499 : }
1500 : return NULL;
1501 : }
1502 :
1503 : static smartlist_t *mock_ei_insert_list = NULL;
1504 : static was_router_added_t
1505 2 : mock_ei_insert(routerlist_t *rl, extrainfo_t *ei, int warn_if_incompatible)
1506 : {
1507 2 : (void) rl;
1508 2 : (void) warn_if_incompatible;
1509 2 : smartlist_add(mock_ei_insert_list, ei);
1510 2 : return ROUTER_ADDED_SUCCESSFULLY;
1511 : }
1512 :
1513 : static void
1514 1 : test_dir_load_extrainfo(void *arg)
1515 : {
1516 1 : (void) arg;
1517 1 : smartlist_t *chunks = smartlist_new();
1518 1 : smartlist_t *wanted = smartlist_new();
1519 1 : char buf[DIGEST_LEN];
1520 1 : char *mem_op_hex_tmp = NULL;
1521 1 : char *list = NULL;
1522 :
1523 : #define ADD(str) \
1524 : do { \
1525 : tt_int_op(0,OP_EQ,router_get_extrainfo_hash(str, strlen(str), buf)); \
1526 : smartlist_add_strdup(wanted, hex_str(buf, DIGEST_LEN)); \
1527 : } while (0)
1528 :
1529 1 : setup_ei_digests();
1530 1 : mock_ei_insert_list = smartlist_new();
1531 1 : MOCK(router_get_by_extrainfo_digest, mock_get_by_ei_desc_digest);
1532 1 : MOCK(extrainfo_insert, mock_ei_insert);
1533 :
1534 1 : smartlist_add_strdup(chunks, EX_EI_MINIMAL);
1535 1 : smartlist_add_strdup(chunks, EX_EI_BAD_NICKNAME);
1536 1 : smartlist_add_strdup(chunks, EX_EI_MAXIMAL);
1537 1 : smartlist_add_strdup(chunks, EX_EI_BAD_PUBLISHED);
1538 1 : smartlist_add_strdup(chunks, EX_EI_BAD_TOKENS);
1539 :
1540 : /* not ADDing MINIMAL */
1541 1 : ADD(EX_EI_MAXIMAL);
1542 1 : ADD(EX_EI_BAD_NICKNAME);
1543 : /* Not ADDing BAD_PUBLISHED */
1544 1 : ADD(EX_EI_BAD_TOKENS);
1545 1 : ADD(EX_EI_BAD_SIG2);
1546 :
1547 1 : list = smartlist_join_strings(chunks, "", 0, NULL);
1548 1 : router_load_extrainfo_from_string(list, NULL, SAVED_IN_JOURNAL, wanted, 1);
1549 :
1550 : /* The "maximal" router was added. */
1551 : /* "minimal" was also added, even though we didn't ask for it, since
1552 : * that's what we do with extrainfos. */
1553 1 : tt_int_op(smartlist_len(mock_ei_insert_list),OP_EQ,2);
1554 :
1555 1 : extrainfo_t *e = smartlist_get(mock_ei_insert_list, 0);
1556 1 : tt_mem_op(e->cache_info.signed_descriptor_digest, OP_EQ,
1557 1 : digest_ei_minimal, DIGEST_LEN);
1558 :
1559 1 : e = smartlist_get(mock_ei_insert_list, 1);
1560 1 : tt_mem_op(e->cache_info.signed_descriptor_digest, OP_EQ,
1561 1 : digest_ei_maximal, DIGEST_LEN);
1562 1 : tt_int_op(dls_minimal.n_download_failures, OP_EQ, 0);
1563 1 : tt_int_op(dls_maximal.n_download_failures, OP_EQ, 0);
1564 :
1565 : /* "Bad nickname" and "Bad tokens" should have gotten marked
1566 : * non-retriable. */
1567 1 : tt_want_int_op(mock_get_by_ei_dd_calls, OP_EQ, 2);
1568 1 : tt_want_int_op(mock_get_by_ei_dd_unrecognized, OP_EQ, 0);
1569 1 : tt_int_op(sd_ei_bad_nickname.ei_dl_status.n_download_failures, OP_EQ, 255);
1570 1 : tt_int_op(sd_ei_bad_tokens.ei_dl_status.n_download_failures, OP_EQ, 255);
1571 :
1572 : /* bad_ports is retriable -- because we didn't ask for it. */
1573 1 : tt_int_op(dls_bad_ports.n_download_failures, OP_EQ, 0);
1574 :
1575 : /* Wanted still contains "BAD_SIG2" */
1576 1 : tt_int_op(smartlist_len(wanted), OP_EQ, 1);
1577 1 : const char *got_wanted =smartlist_get(wanted, 0);
1578 1 : tt_int_op(strlen(got_wanted), OP_EQ, HEX_DIGEST_LEN);
1579 1 : char d[DIGEST_LEN];
1580 1 : base16_decode(d, DIGEST_LEN, got_wanted, strlen(got_wanted));
1581 1 : tt_mem_op(d, OP_EQ, digest_ei_bad_sig2, DIGEST_LEN);
1582 :
1583 : #undef ADD
1584 :
1585 1 : done:
1586 1 : tor_free(mem_op_hex_tmp);
1587 1 : UNMOCK(router_get_by_extrainfo_digest);
1588 6 : SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
1589 1 : smartlist_free(chunks);
1590 2 : SMARTLIST_FOREACH(wanted, char *, cp, tor_free(cp));
1591 1 : smartlist_free(wanted);
1592 1 : tor_free(list);
1593 1 : }
1594 :
1595 : static void
1596 1 : test_dir_getinfo_extra(void *arg)
1597 : {
1598 1 : int r;
1599 1 : char *answer = NULL;
1600 1 : const char *errmsg = NULL;
1601 1 : char buf[128];
1602 1 : char hexdigest[HEX_DIGEST_LEN+1];
1603 1 : (void)arg;
1604 :
1605 1 : setup_ei_digests();
1606 1 : base16_encode(hexdigest, sizeof(hexdigest),
1607 : (const char*)digest_ei_minimal, DIGEST_LEN);
1608 1 : tor_snprintf(buf, sizeof(buf), "extra-info/digest/%s", hexdigest);
1609 :
1610 1 : MOCK(extrainfo_get_by_descriptor_digest, mock_ei_get_by_ei_digest);
1611 1 : r = getinfo_helper_dir(NULL, buf, &answer, &errmsg);
1612 1 : tt_int_op(0, OP_EQ, r);
1613 1 : tt_ptr_op(NULL, OP_EQ, errmsg);
1614 1 : tt_str_op(answer, OP_EQ, EX_EI_MINIMAL);
1615 1 : tor_free(answer);
1616 :
1617 1 : answer = NULL;
1618 1 : r = getinfo_helper_dir(NULL, "extra-info/digest/"
1619 : "NOTAVALIDHEXSTRINGNOTAVALIDHEXSTRINGNOTA", &answer,
1620 : &errmsg);
1621 1 : tt_int_op(0, OP_EQ, r);
1622 : /* getinfo_helper_dir() should maybe return an error here but doesn't */
1623 1 : tt_ptr_op(NULL, OP_EQ, errmsg);
1624 : /* In any case, there should be no answer for an invalid hex string. */
1625 1 : tt_ptr_op(NULL, OP_EQ, answer);
1626 :
1627 1 : done:
1628 1 : UNMOCK(extrainfo_get_by_descriptor_digest);
1629 1 : }
1630 :
1631 : static void
1632 1 : test_dir_versions(void *arg)
1633 : {
1634 1 : tor_version_t ver1;
1635 :
1636 : /* Try out version parsing functionality */
1637 1 : (void)arg;
1638 1 : tt_int_op(0,OP_EQ, tor_version_parse("0.3.4pre2-cvs", &ver1));
1639 1 : tt_int_op(0,OP_EQ, ver1.major);
1640 1 : tt_int_op(3,OP_EQ, ver1.minor);
1641 1 : tt_int_op(4,OP_EQ, ver1.micro);
1642 1 : tt_int_op(VER_PRE,OP_EQ, ver1.status);
1643 1 : tt_int_op(2,OP_EQ, ver1.patchlevel);
1644 1 : tt_int_op(0,OP_EQ, tor_version_parse("0.3.4rc1", &ver1));
1645 1 : tt_int_op(0,OP_EQ, ver1.major);
1646 1 : tt_int_op(3,OP_EQ, ver1.minor);
1647 1 : tt_int_op(4,OP_EQ, ver1.micro);
1648 1 : tt_int_op(VER_RC,OP_EQ, ver1.status);
1649 1 : tt_int_op(1,OP_EQ, ver1.patchlevel);
1650 1 : tt_int_op(0,OP_EQ, tor_version_parse("1.3.4", &ver1));
1651 1 : tt_int_op(1,OP_EQ, ver1.major);
1652 1 : tt_int_op(3,OP_EQ, ver1.minor);
1653 1 : tt_int_op(4,OP_EQ, ver1.micro);
1654 1 : tt_int_op(VER_RELEASE,OP_EQ, ver1.status);
1655 1 : tt_int_op(0,OP_EQ, ver1.patchlevel);
1656 1 : tt_int_op(0,OP_EQ, tor_version_parse("1.3.4.999", &ver1));
1657 1 : tt_int_op(1,OP_EQ, ver1.major);
1658 1 : tt_int_op(3,OP_EQ, ver1.minor);
1659 1 : tt_int_op(4,OP_EQ, ver1.micro);
1660 1 : tt_int_op(VER_RELEASE,OP_EQ, ver1.status);
1661 1 : tt_int_op(999,OP_EQ, ver1.patchlevel);
1662 1 : tt_int_op(0,OP_EQ, tor_version_parse("0.1.2.4-alpha", &ver1));
1663 1 : tt_int_op(0,OP_EQ, ver1.major);
1664 1 : tt_int_op(1,OP_EQ, ver1.minor);
1665 1 : tt_int_op(2,OP_EQ, ver1.micro);
1666 1 : tt_int_op(4,OP_EQ, ver1.patchlevel);
1667 1 : tt_int_op(VER_RELEASE,OP_EQ, ver1.status);
1668 1 : tt_str_op("alpha",OP_EQ, ver1.status_tag);
1669 1 : tt_int_op(0,OP_EQ, tor_version_parse("0.1.2.4", &ver1));
1670 1 : tt_int_op(0,OP_EQ, ver1.major);
1671 1 : tt_int_op(1,OP_EQ, ver1.minor);
1672 1 : tt_int_op(2,OP_EQ, ver1.micro);
1673 1 : tt_int_op(4,OP_EQ, ver1.patchlevel);
1674 1 : tt_int_op(VER_RELEASE,OP_EQ, ver1.status);
1675 1 : tt_str_op("",OP_EQ, ver1.status_tag);
1676 :
1677 1 : tt_int_op(0, OP_EQ, tor_version_parse("10.1", &ver1));
1678 1 : tt_int_op(10, OP_EQ, ver1.major);
1679 1 : tt_int_op(1, OP_EQ, ver1.minor);
1680 1 : tt_int_op(0, OP_EQ, ver1.micro);
1681 1 : tt_int_op(0, OP_EQ, ver1.patchlevel);
1682 1 : tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1683 1 : tt_str_op("", OP_EQ, ver1.status_tag);
1684 1 : tt_int_op(0, OP_EQ, tor_version_parse("5.99.999", &ver1));
1685 1 : tt_int_op(5, OP_EQ, ver1.major);
1686 1 : tt_int_op(99, OP_EQ, ver1.minor);
1687 1 : tt_int_op(999, OP_EQ, ver1.micro);
1688 1 : tt_int_op(0, OP_EQ, ver1.patchlevel);
1689 1 : tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1690 1 : tt_str_op("", OP_EQ, ver1.status_tag);
1691 1 : tt_int_op(0, OP_EQ, tor_version_parse("10.1-alpha", &ver1));
1692 1 : tt_int_op(10, OP_EQ, ver1.major);
1693 1 : tt_int_op(1, OP_EQ, ver1.minor);
1694 1 : tt_int_op(0, OP_EQ, ver1.micro);
1695 1 : tt_int_op(0, OP_EQ, ver1.patchlevel);
1696 1 : tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1697 1 : tt_str_op("alpha", OP_EQ, ver1.status_tag);
1698 : /* Go through the full set of status tags */
1699 1 : tt_int_op(0, OP_EQ, tor_version_parse("2.1.700-alpha", &ver1));
1700 1 : tt_int_op(2, OP_EQ, ver1.major);
1701 1 : tt_int_op(1, OP_EQ, ver1.minor);
1702 1 : tt_int_op(700, OP_EQ, ver1.micro);
1703 1 : tt_int_op(0, OP_EQ, ver1.patchlevel);
1704 1 : tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1705 1 : tt_str_op("alpha", OP_EQ, ver1.status_tag);
1706 1 : tt_int_op(0, OP_EQ, tor_version_parse("1.6.8-alpha-dev", &ver1));
1707 1 : tt_int_op(1, OP_EQ, ver1.major);
1708 1 : tt_int_op(6, OP_EQ, ver1.minor);
1709 1 : tt_int_op(8, OP_EQ, ver1.micro);
1710 1 : tt_int_op(0, OP_EQ, ver1.patchlevel);
1711 1 : tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1712 1 : tt_str_op("alpha-dev", OP_EQ, ver1.status_tag);
1713 1 : tt_int_op(0, OP_EQ, tor_version_parse("0.2.9.5-rc", &ver1));
1714 1 : tt_int_op(0, OP_EQ, ver1.major);
1715 1 : tt_int_op(2, OP_EQ, ver1.minor);
1716 1 : tt_int_op(9, OP_EQ, ver1.micro);
1717 1 : tt_int_op(5, OP_EQ, ver1.patchlevel);
1718 1 : tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1719 1 : tt_str_op("rc", OP_EQ, ver1.status_tag);
1720 1 : tt_int_op(0, OP_EQ, tor_version_parse("0.2.9.6-rc-dev", &ver1));
1721 1 : tt_int_op(0, OP_EQ, ver1.major);
1722 1 : tt_int_op(2, OP_EQ, ver1.minor);
1723 1 : tt_int_op(9, OP_EQ, ver1.micro);
1724 1 : tt_int_op(6, OP_EQ, ver1.patchlevel);
1725 1 : tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1726 1 : tt_str_op("rc-dev", OP_EQ, ver1.status_tag);
1727 1 : tt_int_op(0, OP_EQ, tor_version_parse("0.2.9.8", &ver1));
1728 1 : tt_int_op(0, OP_EQ, ver1.major);
1729 1 : tt_int_op(2, OP_EQ, ver1.minor);
1730 1 : tt_int_op(9, OP_EQ, ver1.micro);
1731 1 : tt_int_op(8, OP_EQ, ver1.patchlevel);
1732 1 : tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1733 1 : tt_str_op("", OP_EQ, ver1.status_tag);
1734 1 : tt_int_op(0, OP_EQ, tor_version_parse("0.2.9.9-dev", &ver1));
1735 1 : tt_int_op(0, OP_EQ, ver1.major);
1736 1 : tt_int_op(2, OP_EQ, ver1.minor);
1737 1 : tt_int_op(9, OP_EQ, ver1.micro);
1738 1 : tt_int_op(9, OP_EQ, ver1.patchlevel);
1739 1 : tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1740 1 : tt_str_op("dev", OP_EQ, ver1.status_tag);
1741 : /* In #21450, we fixed an inconsistency in parsing versions > INT32_MAX
1742 : * between i386 and x86_64, as we used tor_parse_long, and then cast to int
1743 : */
1744 1 : tt_int_op(0, OP_EQ, tor_version_parse("0.2147483647.0", &ver1));
1745 1 : tt_int_op(0, OP_EQ, ver1.major);
1746 1 : tt_int_op(2147483647, OP_EQ, ver1.minor);
1747 1 : tt_int_op(0, OP_EQ, ver1.micro);
1748 1 : tt_int_op(0, OP_EQ, ver1.patchlevel);
1749 1 : tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
1750 1 : tt_str_op("", OP_EQ, ver1.status_tag);
1751 1 : tt_int_op(-1, OP_EQ, tor_version_parse("0.2147483648.0", &ver1));
1752 1 : tt_int_op(-1, OP_EQ, tor_version_parse("0.4294967295.0", &ver1));
1753 : /* In #21278, we reject negative version components */
1754 1 : tt_int_op(-1, OP_EQ, tor_version_parse("0.-1.0", &ver1));
1755 1 : tt_int_op(-1, OP_EQ, tor_version_parse("0.-2147483648.0", &ver1));
1756 1 : tt_int_op(-1, OP_EQ, tor_version_parse("0.-4294967295.0", &ver1));
1757 : /* In #21507, we reject version components with non-numeric prefixes */
1758 1 : tt_int_op(-1, OP_EQ, tor_version_parse("0.-0.0", &ver1));
1759 1 : tt_int_op(-1, OP_EQ, tor_version_parse("+1.0.0", &ver1));
1760 : /* use the list in isspace() */
1761 1 : tt_int_op(-1, OP_EQ, tor_version_parse("0.\t0.0", &ver1));
1762 1 : tt_int_op(-1, OP_EQ, tor_version_parse("0.\n0.0", &ver1));
1763 1 : tt_int_op(-1, OP_EQ, tor_version_parse("0.\v0.0", &ver1));
1764 1 : tt_int_op(-1, OP_EQ, tor_version_parse("0.\f0.0", &ver1));
1765 1 : tt_int_op(-1, OP_EQ, tor_version_parse("0.\r0.0", &ver1));
1766 1 : tt_int_op(-1, OP_EQ, tor_version_parse("0. 0.0", &ver1));
1767 :
1768 : #define tt_versionstatus_op(vs1, op, vs2) \
1769 : tt_assert_test_type(vs1,vs2,#vs1" "#op" "#vs2,version_status_t, \
1770 : (val1_ op val2_),"%d",TT_EXIT_TEST_FUNCTION)
1771 : #define test_v_i_o(val, ver, lst) \
1772 : tt_versionstatus_op(val, OP_EQ, tor_version_is_obsolete(ver, lst))
1773 :
1774 : /* make sure tor_version_is_obsolete() works */
1775 1 : test_v_i_o(VS_OLD, "0.0.1", "Tor 0.0.2");
1776 1 : test_v_i_o(VS_OLD, "0.0.1", "0.0.2, Tor 0.0.3");
1777 1 : test_v_i_o(VS_OLD, "0.0.1", "0.0.2,Tor 0.0.3");
1778 1 : test_v_i_o(VS_OLD, "0.0.1","0.0.3,BetterTor 0.0.1");
1779 1 : test_v_i_o(VS_RECOMMENDED, "0.0.2", "Tor 0.0.2,Tor 0.0.3");
1780 1 : test_v_i_o(VS_NEW_IN_SERIES, "0.0.2", "Tor 0.0.2pre1,Tor 0.0.3");
1781 1 : test_v_i_o(VS_OLD, "0.0.2", "Tor 0.0.2.1,Tor 0.0.3");
1782 1 : test_v_i_o(VS_NEW, "0.1.0", "Tor 0.0.2,Tor 0.0.3");
1783 1 : test_v_i_o(VS_RECOMMENDED, "0.0.7rc2", "0.0.7,Tor 0.0.7rc2,Tor 0.0.8");
1784 1 : test_v_i_o(VS_OLD, "0.0.5.0", "0.0.5.1-cvs");
1785 1 : test_v_i_o(VS_NEW_IN_SERIES, "0.0.5.1-cvs", "0.0.5, 0.0.6");
1786 1 : test_v_i_o(VS_NEW, "0.2.9.9-dev", "0.2.9.9");
1787 : /* Not on list, but newer than any in same series. */
1788 1 : test_v_i_o(VS_NEW_IN_SERIES, "0.1.0.3",
1789 : "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
1790 : /* Series newer than any on list. */
1791 1 : test_v_i_o(VS_NEW, "0.1.2.3", "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
1792 : /* Series older than any on list. */
1793 1 : test_v_i_o(VS_OLD, "0.0.1.3", "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
1794 : /* Not on list, not newer than any on same series. */
1795 1 : test_v_i_o(VS_UNRECOMMENDED, "0.1.0.1",
1796 : "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
1797 : /* On list, not newer than any on same series. */
1798 1 : test_v_i_o(VS_UNRECOMMENDED,
1799 : "0.1.0.1", "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
1800 1 : tt_int_op(0,OP_EQ, tor_version_as_new_as("Tor 0.0.5", "0.0.9pre1-cvs"));
1801 1 : tt_int_op(1,OP_EQ, tor_version_as_new_as(
1802 : "Tor 0.0.8 on Darwin 64-121-192-100.c3-0."
1803 : "sfpo-ubr1.sfrn-sfpo.ca.cable.rcn.com Power Macintosh",
1804 : "0.0.8rc2"));
1805 1 : tt_int_op(0,OP_EQ, tor_version_as_new_as(
1806 : "Tor 0.0.8 on Darwin 64-121-192-100.c3-0."
1807 : "sfpo-ubr1.sfrn-sfpo.ca.cable.rcn.com Power Macintosh", "0.0.8.2"));
1808 :
1809 : /* Now try svn revisions. */
1810 1 : tt_int_op(1,OP_EQ, tor_version_as_new_as("Tor 0.2.1.0-dev (r100)",
1811 : "Tor 0.2.1.0-dev (r99)"));
1812 1 : tt_int_op(1,OP_EQ, tor_version_as_new_as(
1813 : "Tor 0.2.1.0-dev (r100) on Banana Jr",
1814 : "Tor 0.2.1.0-dev (r99) on Hal 9000"));
1815 1 : tt_int_op(1,OP_EQ, tor_version_as_new_as("Tor 0.2.1.0-dev (r100)",
1816 : "Tor 0.2.1.0-dev on Colossus"));
1817 1 : tt_int_op(0,OP_EQ, tor_version_as_new_as("Tor 0.2.1.0-dev (r99)",
1818 : "Tor 0.2.1.0-dev (r100)"));
1819 1 : tt_int_op(0,OP_EQ, tor_version_as_new_as("Tor 0.2.1.0-dev (r99) on MCP",
1820 : "Tor 0.2.1.0-dev (r100) on AM"));
1821 1 : tt_int_op(0,OP_EQ, tor_version_as_new_as("Tor 0.2.1.0-dev",
1822 : "Tor 0.2.1.0-dev (r99)"));
1823 1 : tt_int_op(1,OP_EQ, tor_version_as_new_as("Tor 0.2.1.1",
1824 : "Tor 0.2.1.0-dev (r99)"));
1825 : /* And git revisions */
1826 1 : tt_int_op(1,OP_EQ, tor_version_as_new_as(
1827 : "Tor 0.2.9.9 (git-56788a2489127072)",
1828 : "Tor 0.2.9.9 (git-56788a2489127072)"));
1829 : /* a git revision is newer than no git revision */
1830 1 : tt_int_op(1,OP_EQ, tor_version_as_new_as(
1831 : "Tor 0.2.9.9 (git-56788a2489127072)",
1832 : "Tor 0.2.9.9"));
1833 : /* a longer git revision is newer than a shorter git revision
1834 : * this should be true if they prefix-match, but if they don't, they are
1835 : * incomparable, because hashes aren't ordered (but we compare their bytes
1836 : * anyway) */
1837 1 : tt_int_op(1,OP_EQ, tor_version_as_new_as(
1838 : "Tor 0.2.9.9 (git-56788a2489127072d513cf4baf35a8ff475f3c7b)",
1839 : "Tor 0.2.9.9 (git-56788a2489127072)"));
1840 1 : tt_int_op(1,OP_EQ, tor_version_as_new_as(
1841 : "Tor 0.2.9.9 (git-0102)",
1842 : "Tor 0.2.9.9 (git-03)"));
1843 1 : tt_int_op(1,OP_EQ, tor_version_as_new_as(
1844 : "Tor 0.2.9.9 (git-0102)",
1845 : "Tor 0.2.9.9 (git-00)"));
1846 1 : tt_int_op(1,OP_EQ, tor_version_as_new_as(
1847 : "Tor 0.2.9.9 (git-01)",
1848 : "Tor 0.2.9.9 (git-00)"));
1849 1 : tt_int_op(0,OP_EQ, tor_version_as_new_as(
1850 : "Tor 0.2.9.9 (git-00)",
1851 : "Tor 0.2.9.9 (git-01)"));
1852 : /* In #21278, we compare without integer overflows.
1853 : * But since #21450 limits version components to [0, INT32_MAX], it is no
1854 : * longer possible to cause an integer overflow in tor_version_compare() */
1855 1 : tt_int_op(0,OP_EQ, tor_version_as_new_as(
1856 : "Tor 0.0.0.0",
1857 : "Tor 2147483647.0.0.0"));
1858 1 : tt_int_op(1,OP_EQ, tor_version_as_new_as(
1859 : "Tor 2147483647.0.0.0",
1860 : "Tor 0.0.0.0"));
1861 : /* These versions used to cause an overflow, now they don't parse
1862 : * (and authorities reject their descriptors), and log a BUG message */
1863 1 : setup_full_capture_of_logs(LOG_WARN);
1864 1 : tt_int_op(0,OP_EQ, tor_version_as_new_as(
1865 : "Tor 0.0.0.0",
1866 : "Tor 0.-2147483648.0.0"));
1867 1 : expect_single_log_msg_containing("unparseable");
1868 1 : mock_clean_saved_logs();
1869 1 : tt_int_op(0,OP_EQ, tor_version_as_new_as(
1870 : "Tor 0.2147483647.0.0",
1871 : "Tor 0.-1.0.0"));
1872 1 : expect_single_log_msg_containing("unparseable");
1873 1 : mock_clean_saved_logs();
1874 1 : tt_int_op(0,OP_EQ, tor_version_as_new_as(
1875 : "Tor 0.2147483647.0.0",
1876 : "Tor 0.-2147483648.0.0"));
1877 1 : expect_single_log_msg_containing("unparseable");
1878 1 : mock_clean_saved_logs();
1879 1 : tt_int_op(1,OP_EQ, tor_version_as_new_as(
1880 : "Tor 4294967295.0.0.0",
1881 : "Tor 0.0.0.0"));
1882 1 : expect_no_log_entry();
1883 1 : tt_int_op(0,OP_EQ, tor_version_as_new_as(
1884 : "Tor 0.4294967295.0.0",
1885 : "Tor 0.-4294967295.0.0"));
1886 1 : expect_single_log_msg_containing("unparseable");
1887 1 : mock_clean_saved_logs();
1888 1 : teardown_capture_of_logs();
1889 :
1890 : /* Now try git revisions */
1891 1 : tt_int_op(0,OP_EQ, tor_version_parse("0.5.6.7 (git-ff00ff)", &ver1));
1892 1 : tt_int_op(0,OP_EQ, ver1.major);
1893 1 : tt_int_op(5,OP_EQ, ver1.minor);
1894 1 : tt_int_op(6,OP_EQ, ver1.micro);
1895 1 : tt_int_op(7,OP_EQ, ver1.patchlevel);
1896 1 : tt_int_op(3,OP_EQ, ver1.git_tag_len);
1897 1 : tt_mem_op(ver1.git_tag,OP_EQ, "\xff\x00\xff", 3);
1898 : /* reject bad hex digits */
1899 1 : tt_int_op(-1,OP_EQ, tor_version_parse("0.5.6.7 (git-ff00xx)", &ver1));
1900 : /* reject odd hex digit count */
1901 1 : tt_int_op(-1,OP_EQ, tor_version_parse("0.5.6.7 (git-ff00fff)", &ver1));
1902 : /* ignore "git " */
1903 1 : tt_int_op(0,OP_EQ, tor_version_parse("0.5.6.7 (git ff00fff)", &ver1));
1904 : /* standard length is 16 hex digits */
1905 1 : tt_int_op(0,OP_EQ, tor_version_parse("0.5.6.7 (git-0010203040506070)",
1906 : &ver1));
1907 : /* length limit is 40 hex digits */
1908 1 : tt_int_op(0,OP_EQ, tor_version_parse(
1909 : "0.5.6.7 (git-000102030405060708090a0b0c0d0e0f10111213)",
1910 : &ver1));
1911 1 : tt_int_op(-1,OP_EQ, tor_version_parse(
1912 : "0.5.6.7 (git-000102030405060708090a0b0c0d0e0f1011121314)",
1913 : &ver1));
1914 1 : done:
1915 1 : teardown_capture_of_logs();
1916 1 : }
1917 :
1918 : /** Run unit tests for directory fp_pair functions. */
1919 : static void
1920 1 : test_dir_fp_pairs(void *arg)
1921 : {
1922 1 : smartlist_t *sl = smartlist_new();
1923 1 : fp_pair_t *pair;
1924 :
1925 1 : (void)arg;
1926 1 : dir_split_resource_into_fingerprint_pairs(
1927 : /* Two pairs, out of order, with one duplicate. */
1928 : "73656372657420646174612E0000000000FFFFFF-"
1929 : "557365204145532d32353620696e73746561642e+"
1930 : "73656372657420646174612E0000000000FFFFFF-"
1931 : "557365204145532d32353620696e73746561642e+"
1932 : "48657861646563696d616c2069736e277420736f-"
1933 : "676f6f6420666f7220686964696e6720796f7572.z", sl);
1934 :
1935 1 : tt_int_op(smartlist_len(sl),OP_EQ, 2);
1936 1 : pair = smartlist_get(sl, 0);
1937 1 : tt_mem_op(pair->first,OP_EQ, "Hexadecimal isn't so", DIGEST_LEN);
1938 1 : tt_mem_op(pair->second,OP_EQ, "good for hiding your", DIGEST_LEN);
1939 1 : pair = smartlist_get(sl, 1);
1940 1 : tt_mem_op(pair->first,OP_EQ, "secret data.\0\0\0\0\0\xff\xff\xff",
1941 1 : DIGEST_LEN);
1942 1 : tt_mem_op(pair->second,OP_EQ, "Use AES-256 instead.", DIGEST_LEN);
1943 :
1944 1 : done:
1945 3 : SMARTLIST_FOREACH(sl, fp_pair_t *, pair_to_free, tor_free(pair_to_free));
1946 1 : smartlist_free(sl);
1947 1 : }
1948 :
1949 : static void
1950 1 : test_dir_split_fps(void *testdata)
1951 : {
1952 1 : smartlist_t *sl = smartlist_new();
1953 1 : char *mem_op_hex_tmp = NULL;
1954 1 : (void)testdata;
1955 :
1956 : /* Some example hex fingerprints and their base64 equivalents */
1957 : #define HEX1 "Fe0daff89127389bc67558691231234551193EEE"
1958 : #define HEX2 "Deadbeef99999991111119999911111111f00ba4"
1959 : #define HEX3 "b33ff00db33ff00db33ff00db33ff00db33ff00d"
1960 : #define HEX256_1 \
1961 : "f3f3f3f3fbbbbf3f3f3f3fbbbf3f3f3f3fbbbbf3f3f3f3fbbbf3f3f3f3fbbbbf"
1962 : #define HEX256_2 \
1963 : "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccCCc"
1964 : #define HEX256_3 \
1965 : "0123456789ABCdef0123456789ABCdef0123456789ABCdef0123456789ABCdef"
1966 : #define B64_1 "/g2v+JEnOJvGdVhpEjEjRVEZPu4"
1967 : #define B64_2 "3q2+75mZmZERERmZmRERERHwC6Q"
1968 : #define B64_256_1 "8/Pz8/u7vz8/Pz+7vz8/Pz+7u/Pz8/P7u/Pz8/P7u78"
1969 : #define B64_256_2 "zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMw"
1970 :
1971 : /* no flags set */
1972 1 : dir_split_resource_into_fingerprints("A+C+B", sl, NULL, 0);
1973 1 : tt_int_op(smartlist_len(sl), OP_EQ, 3);
1974 1 : tt_str_op(smartlist_get(sl, 0), OP_EQ, "A");
1975 1 : tt_str_op(smartlist_get(sl, 1), OP_EQ, "C");
1976 1 : tt_str_op(smartlist_get(sl, 2), OP_EQ, "B");
1977 4 : SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
1978 1 : smartlist_clear(sl);
1979 :
1980 : /* uniq strings. */
1981 1 : dir_split_resource_into_fingerprints("A+C+B+A+B+B", sl, NULL, DSR_SORT_UNIQ);
1982 1 : tt_int_op(smartlist_len(sl), OP_EQ, 3);
1983 1 : tt_str_op(smartlist_get(sl, 0), OP_EQ, "A");
1984 1 : tt_str_op(smartlist_get(sl, 1), OP_EQ, "B");
1985 1 : tt_str_op(smartlist_get(sl, 2), OP_EQ, "C");
1986 4 : SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
1987 1 : smartlist_clear(sl);
1988 :
1989 : /* Decode hex. */
1990 1 : dir_split_resource_into_fingerprints(HEX1"+"HEX2, sl, NULL, DSR_HEX);
1991 1 : tt_int_op(smartlist_len(sl), OP_EQ, 2);
1992 1 : test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX1);
1993 1 : test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX2);
1994 3 : SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
1995 1 : smartlist_clear(sl);
1996 :
1997 : /* decode hex and drop weirdness. */
1998 1 : dir_split_resource_into_fingerprints(HEX1"+bogus+"HEX2"+"HEX256_1,
1999 : sl, NULL, DSR_HEX);
2000 1 : tt_int_op(smartlist_len(sl), OP_EQ, 2);
2001 1 : test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX1);
2002 1 : test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX2);
2003 3 : SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
2004 1 : smartlist_clear(sl);
2005 :
2006 : /* Decode long hex */
2007 1 : dir_split_resource_into_fingerprints(HEX256_1"+"HEX256_2"+"HEX2"+"HEX256_3,
2008 : sl, NULL, DSR_HEX|DSR_DIGEST256);
2009 1 : tt_int_op(smartlist_len(sl), OP_EQ, 3);
2010 1 : test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX256_1);
2011 1 : test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX256_2);
2012 1 : test_mem_op_hex(smartlist_get(sl, 2), OP_EQ, HEX256_3);
2013 4 : SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
2014 1 : smartlist_clear(sl);
2015 :
2016 : /* Decode hex and sort. */
2017 1 : dir_split_resource_into_fingerprints(HEX1"+"HEX2"+"HEX3"+"HEX2,
2018 : sl, NULL, DSR_HEX|DSR_SORT_UNIQ);
2019 1 : tt_int_op(smartlist_len(sl), OP_EQ, 3);
2020 1 : test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX3);
2021 1 : test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX2);
2022 1 : test_mem_op_hex(smartlist_get(sl, 2), OP_EQ, HEX1);
2023 4 : SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
2024 1 : smartlist_clear(sl);
2025 :
2026 : /* Decode long hex and sort */
2027 1 : dir_split_resource_into_fingerprints(HEX256_1"+"HEX256_2"+"HEX256_3
2028 : "+"HEX256_1,
2029 : sl, NULL,
2030 : DSR_HEX|DSR_DIGEST256|DSR_SORT_UNIQ);
2031 1 : tt_int_op(smartlist_len(sl), OP_EQ, 3);
2032 1 : test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX256_3);
2033 1 : test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX256_2);
2034 1 : test_mem_op_hex(smartlist_get(sl, 2), OP_EQ, HEX256_1);
2035 4 : SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
2036 1 : smartlist_clear(sl);
2037 :
2038 : /* Decode base64 */
2039 1 : dir_split_resource_into_fingerprints(B64_1"-"B64_2, sl, NULL, DSR_BASE64);
2040 1 : tt_int_op(smartlist_len(sl), OP_EQ, 2);
2041 1 : test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX1);
2042 1 : test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX2);
2043 3 : SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
2044 1 : smartlist_clear(sl);
2045 :
2046 : /* Decode long base64 */
2047 1 : dir_split_resource_into_fingerprints(B64_256_1"-"B64_256_2,
2048 : sl, NULL, DSR_BASE64|DSR_DIGEST256);
2049 1 : tt_int_op(smartlist_len(sl), OP_EQ, 2);
2050 1 : test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX256_1);
2051 1 : test_mem_op_hex(smartlist_get(sl, 1), OP_EQ, HEX256_2);
2052 3 : SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
2053 1 : smartlist_clear(sl);
2054 :
2055 1 : dir_split_resource_into_fingerprints(B64_256_1,
2056 : sl, NULL, DSR_BASE64|DSR_DIGEST256);
2057 1 : tt_int_op(smartlist_len(sl), OP_EQ, 1);
2058 1 : test_mem_op_hex(smartlist_get(sl, 0), OP_EQ, HEX256_1);
2059 2 : SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
2060 1 : smartlist_clear(sl);
2061 :
2062 1 : done:
2063 1 : SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
2064 1 : smartlist_free(sl);
2065 1 : tor_free(mem_op_hex_tmp);
2066 1 : }
2067 :
2068 : static void
2069 1 : test_dir_measured_bw_kb(void *arg)
2070 : {
2071 1 : measured_bw_line_t mbwl;
2072 1 : int i;
2073 1 : const char *lines_pass[] = {
2074 : "node_id=$557365204145532d32353620696e73746561642e bw=1024\n",
2075 : "node_id=$557365204145532d32353620696e73746561642e\t bw=1024 \n",
2076 : " node_id=$557365204145532d32353620696e73746561642e bw=1024\n",
2077 : "\tnoise\tnode_id=$557365204145532d32353620696e73746561642e "
2078 : "bw=1024 junk=007\n",
2079 : "misc=junk node_id=$557365204145532d32353620696e73746561642e "
2080 : "bw=1024 junk=007\n",
2081 : /* check whether node_id can be at the end */
2082 : "bw=1024 node_id=$557365204145532d32353620696e73746561642e\n",
2083 : /* check whether node_id can be at the end and bw has something in front*/
2084 : "foo=bar bw=1024 node_id=$557365204145532d32353620696e73746561642e\n",
2085 : /* check whether node_id can be at the end and something in the
2086 : * in the middle of bw and node_id */
2087 : "bw=1024 foo=bar node_id=$557365204145532d32353620696e73746561642e\n",
2088 :
2089 : /* Test that a line with vote=1 will pass. */
2090 : "node_id=$557365204145532d32353620696e73746561642e bw=1024 vote=1\n",
2091 : /* Test that a line with unmeasured=1 will pass. */
2092 : "node_id=$557365204145532d32353620696e73746561642e bw=1024 unmeasured=1\n",
2093 : /* Test that a line with vote=1 and unmeasured=1 will pass. */
2094 : "node_id=$557365204145532d32353620696e73746561642e bw=1024 vote=1"
2095 : "unmeasured=1\n",
2096 : /* Test that a line with unmeasured=0 will pass. */
2097 : "node_id=$557365204145532d32353620696e73746561642e bw=1024 unmeasured=0\n",
2098 : /* Test that a line with vote=1 and unmeasured=0 will pass. */
2099 : "node_id=$557365204145532d32353620696e73746561642e bw=1024 vote=1"
2100 : "unmeasured=0\n",
2101 : "end"
2102 : };
2103 1 : const char *lines_fail[] = {
2104 : /* Test possible python stupidity on input */
2105 : "node_id=None bw=1024\n",
2106 : "node_id=$None bw=1024\n",
2107 : "node_id=$557365204145532d32353620696e73746561642e bw=None\n",
2108 : "node_id=$557365204145532d32353620696e73746561642e bw=1024.0\n",
2109 : "node_id=$557365204145532d32353620696e73746561642e bw=.1024\n",
2110 : "node_id=$557365204145532d32353620696e73746561642e bw=1.024\n",
2111 : "node_id=$557365204145532d32353620696e73746561642e bw=1024 bw=0\n",
2112 : "node_id=$557365204145532d32353620696e73746561642e bw=1024 bw=None\n",
2113 : "node_id=$557365204145532d32353620696e73746561642e bw=-1024\n",
2114 : /* Test incomplete writes due to race conditions, partial copies, etc */
2115 : "node_i",
2116 : "node_i\n",
2117 : "node_id=",
2118 : "node_id=\n",
2119 : "node_id=$557365204145532d32353620696e73746561642e bw=",
2120 : "node_id=$557365204145532d32353620696e73746561642e bw=1024",
2121 : "node_id=$557365204145532d32353620696e73746561642e bw=\n",
2122 : "node_id=$557365204145532d32353620696e7374",
2123 : "node_id=$557365204145532d32353620696e7374\n",
2124 : "",
2125 : "\n",
2126 : " \n ",
2127 : " \n\n",
2128 : /* Test assorted noise */
2129 : " node_id= ",
2130 : "node_id==$557365204145532d32353620696e73746561642e bw==1024\n",
2131 : "node_id=$55736520414552d32353620696e73746561642e bw=1024\n",
2132 : "node_id=557365204145532d32353620696e73746561642e bw=1024\n",
2133 : "node_id= $557365204145532d32353620696e73746561642e bw=0.23\n",
2134 :
2135 : /* Test that a line with vote=0 will fail too, so that it is ignored. */
2136 : "node_id=$557365204145532d32353620696e73746561642e bw=1024 vote=0\n",
2137 : /* Test that a line with vote=0 will fail even if unmeasured=0. */
2138 : "node_id=$557365204145532d32353620696e73746561642e bw=1024 vote=0 "
2139 : "unmeasured=0\n",
2140 : "end"
2141 : };
2142 :
2143 1 : (void)arg;
2144 30 : for (i = 0; strcmp(lines_fail[i], "end"); i++) {
2145 : //fprintf(stderr, "Testing: %s\n", lines_fail[i]);
2146 : /* Testing only with line_is_after_headers = 1. Tests with
2147 : * line_is_after_headers = 0 in
2148 : * test_dir_measured_bw_kb_line_is_after_headers */
2149 29 : tt_assert(measured_bw_line_parse(&mbwl, lines_fail[i], 1) == -1);
2150 : }
2151 :
2152 14 : for (i = 0; strcmp(lines_pass[i], "end"); i++) {
2153 : //fprintf(stderr, "Testing: %s %d\n", lines_pass[i], TOR_ISSPACE('\n'));
2154 : /* Testing only with line_is_after_headers = 1. Tests with
2155 : * line_is_after_headers = 0 in
2156 : * test_dir_measured_bw_kb_line_is_after_headers */
2157 13 : tt_assert(measured_bw_line_parse(&mbwl, lines_pass[i], 1) == 0);
2158 13 : tt_assert(mbwl.bw_kb == 1024);
2159 13 : tt_assert(strcmp(mbwl.node_hex,
2160 : "557365204145532d32353620696e73746561642e") == 0);
2161 : }
2162 :
2163 1 : done:
2164 1 : return;
2165 : }
2166 :
2167 : /* Unit tests for measured_bw_line_parse using line_is_after_headers flag.
2168 : * When the end of the header is detected (a first complete bw line is parsed),
2169 : * incomplete lines fail and give warnings, but do not give warnings if
2170 : * the header is not ended, allowing to ignore additional header lines. */
2171 : static void
2172 1 : test_dir_measured_bw_kb_line_is_after_headers(void *arg)
2173 : {
2174 1 : (void)arg;
2175 1 : measured_bw_line_t mbwl;
2176 1 : const char *line_pass = \
2177 : "node_id=$557365204145532d32353620696e73746561642e bw=1024\n";
2178 1 : int i;
2179 1 : const char *lines_fail[] = {
2180 : "node_id=$557365204145532d32353620696e73746561642e \n",
2181 : "bw=1024\n",
2182 : "rtt=300\n",
2183 : "end"
2184 : };
2185 :
2186 1 : setup_capture_of_logs(LOG_DEBUG);
2187 :
2188 : /* Test bw lines when header has ended */
2189 5 : for (i = 0; strcmp(lines_fail[i], "end"); i++) {
2190 3 : tt_assert(measured_bw_line_parse(&mbwl, lines_fail[i], 1) == -1);
2191 3 : expect_log_msg_containing("Incomplete line in bandwidth file:");
2192 3 : mock_clean_saved_logs();
2193 : }
2194 :
2195 1 : tt_assert(measured_bw_line_parse(&mbwl, line_pass, 1) == 0);
2196 :
2197 : /* Test bw lines when header has not ended */
2198 4 : for (i = 0; strcmp(lines_fail[i], "end"); i++) {
2199 3 : tt_assert(measured_bw_line_parse(&mbwl, lines_fail[i], 0) == -1);
2200 3 : expect_log_msg_containing("Missing bw or node_id in bandwidth file line:");
2201 3 : mock_clean_saved_logs();
2202 : }
2203 :
2204 1 : tt_assert(measured_bw_line_parse(&mbwl, line_pass, 0) == 0);
2205 :
2206 1 : done:
2207 1 : teardown_capture_of_logs();
2208 1 : }
2209 :
2210 : /* Test dirserv_read_measured_bandwidths with headers and complete files. */
2211 : static void
2212 1 : test_dir_dirserv_read_measured_bandwidths(void *arg)
2213 : {
2214 1 : (void)arg;
2215 1 : char *content = NULL;
2216 1 : time_t timestamp = time(NULL);
2217 1 : char *fname = tor_strdup(get_fname("V3BandwidthsFile"));
2218 1 : smartlist_t *bw_file_headers = smartlist_new();
2219 : /* bw file strings in vote */
2220 1 : char *bw_file_headers_str = NULL;
2221 1 : char *bw_file_headers_str_v100 = NULL;
2222 1 : char *bw_file_headers_str_v110 = NULL;
2223 1 : char *bw_file_headers_str_bad = NULL;
2224 1 : char *bw_file_headers_str_extra = NULL;
2225 1 : char bw_file_headers_str_long[MAX_BW_FILE_HEADER_COUNT_IN_VOTE * 8 + 1] = "";
2226 : /* string header lines in bw file */
2227 1 : char *header_lines_v100 = NULL;
2228 1 : char *header_lines_v110_no_terminator = NULL;
2229 1 : char *header_lines_v110 = NULL;
2230 1 : char header_lines_long[MAX_BW_FILE_HEADER_COUNT_IN_VOTE * 8 + 1] = "";
2231 1 : int i;
2232 1 : const char *header_lines_v110_no_terminator_no_timestamp =
2233 : "version=1.1.0\n"
2234 : "software=sbws\n"
2235 : "software_version=0.1.0\n"
2236 : "earliest_bandwidth=2018-05-08T16:13:26\n"
2237 : "file_created=2018-04-16T21:49:18\n"
2238 : "generator_started=2018-05-08T16:13:25\n"
2239 : "latest_bandwidth=2018-04-16T20:49:18\n";
2240 1 : const char *bw_file_headers_str_v110_no_timestamp =
2241 : "version=1.1.0 software=sbws "
2242 : "software_version=0.1.0 "
2243 : "earliest_bandwidth=2018-05-08T16:13:26 "
2244 : "file_created=2018-04-16T21:49:18 "
2245 : "generator_started=2018-05-08T16:13:25 "
2246 : "latest_bandwidth=2018-04-16T20:49:18";
2247 1 : const char *relay_lines_v100 =
2248 : "node_id=$557365204145532d32353620696e73746561642e bw=1024 "
2249 : "nick=Test measured_at=1523911725 updated_at=1523911725 "
2250 : "pid_error=4.11374090719 pid_error_sum=4.11374090719 "
2251 : "pid_bw=57136645 pid_delta=2.12168374577 circ_fail=0.2 "
2252 : "scanner=/filepath\n";
2253 1 : const char *relay_lines_v110 =
2254 : "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 "
2255 : "master_key_ed25519=YaqV4vbvPYKucElk297eVdNArDz9HtIwUoIeo0+cVIpQ "
2256 : "bw=760 nick=Test rtt=380 time=2018-05-08T16:13:26\n";
2257 1 : const char *relay_lines_bad =
2258 : "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A\n";
2259 :
2260 1 : tor_asprintf(&header_lines_v100, "%ld\n", (long)timestamp);
2261 1 : tor_asprintf(&header_lines_v110_no_terminator, "%ld\n%s", (long)timestamp,
2262 : header_lines_v110_no_terminator_no_timestamp);
2263 1 : tor_asprintf(&header_lines_v110, "%s%s",
2264 : header_lines_v110_no_terminator, BW_FILE_HEADERS_TERMINATOR);
2265 :
2266 1 : tor_asprintf(&bw_file_headers_str_v100, "timestamp=%ld",(long)timestamp);
2267 1 : tor_asprintf(&bw_file_headers_str_v110, "timestamp=%ld %s",
2268 : (long)timestamp, bw_file_headers_str_v110_no_timestamp);
2269 1 : tor_asprintf(&bw_file_headers_str_bad, "%s "
2270 : "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A",
2271 : bw_file_headers_str_v110);
2272 :
2273 52 : for (i=0; i<MAX_BW_FILE_HEADER_COUNT_IN_VOTE; i++) {
2274 50 : strlcat(header_lines_long, "foo=bar\n",
2275 : sizeof(header_lines_long));
2276 : }
2277 : /* 8 is the number of v110 lines in header_lines_v110 */
2278 42 : for (i=0; i<MAX_BW_FILE_HEADER_COUNT_IN_VOTE - 8 - 1; i++) {
2279 41 : strlcat(bw_file_headers_str_long, "foo=bar ",
2280 : sizeof(bw_file_headers_str_long));
2281 : }
2282 1 : strlcat(bw_file_headers_str_long, "foo=bar",
2283 : sizeof(bw_file_headers_str_long));
2284 1 : tor_asprintf(&bw_file_headers_str_extra,
2285 : "%s %s",
2286 : bw_file_headers_str_v110,
2287 : bw_file_headers_str_long);
2288 :
2289 : /* Test an empty bandwidth file. bw_file_headers will be empty string */
2290 1 : write_str_to_file(fname, "", 0);
2291 1 : setup_capture_of_logs(LOG_WARN);
2292 1 : tt_int_op(-1, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2293 : bw_file_headers,
2294 : NULL));
2295 1 : expect_log_msg("Empty bandwidth file\n");
2296 1 : teardown_capture_of_logs();
2297 1 : bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2298 1 : tt_str_op("", OP_EQ, bw_file_headers_str);
2299 1 : SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2300 1 : smartlist_free(bw_file_headers);
2301 1 : tor_free(bw_file_headers_str);
2302 :
2303 : /* Test bandwidth file with only timestamp.
2304 : * bw_file_headers will be empty string */
2305 1 : bw_file_headers = smartlist_new();
2306 1 : tor_asprintf(&content, "%ld", (long)timestamp);
2307 1 : write_str_to_file(fname, content, 0);
2308 1 : tor_free(content);
2309 1 : tt_int_op(-1, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2310 : bw_file_headers,
2311 : NULL));
2312 :
2313 1 : bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2314 1 : tt_str_op("", OP_EQ, bw_file_headers_str);
2315 1 : SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2316 1 : smartlist_free(bw_file_headers);
2317 1 : tor_free(bw_file_headers_str);
2318 :
2319 : /* Test v1.0.0 bandwidth file headers */
2320 1 : write_str_to_file(fname, header_lines_v100, 0);
2321 1 : bw_file_headers = smartlist_new();
2322 1 : tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2323 : bw_file_headers,
2324 : NULL));
2325 :
2326 1 : bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2327 1 : tt_str_op(bw_file_headers_str_v100, OP_EQ, bw_file_headers_str);
2328 2 : SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2329 1 : smartlist_free(bw_file_headers);
2330 1 : tor_free(bw_file_headers_str);
2331 :
2332 : /* Test v1.0.0 complete bandwidth file */
2333 1 : bw_file_headers = smartlist_new();
2334 1 : tor_asprintf(&content, "%s%s", header_lines_v100, relay_lines_v100);
2335 1 : write_str_to_file(fname, content, 0);
2336 1 : tor_free(content);
2337 1 : tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2338 : bw_file_headers,
2339 : NULL));
2340 :
2341 1 : bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2342 1 : tt_str_op(bw_file_headers_str_v100, OP_EQ, bw_file_headers_str);
2343 2 : SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2344 1 : smartlist_free(bw_file_headers);
2345 1 : tor_free(bw_file_headers_str);
2346 :
2347 : /* Test v1.0.0 complete bandwidth file with NULL bw_file_headers. */
2348 1 : tor_asprintf(&content, "%s%s", header_lines_v100, relay_lines_v100);
2349 1 : write_str_to_file(fname, content, 0);
2350 1 : tor_free(content);
2351 1 : tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL, NULL,
2352 : NULL));
2353 :
2354 : /* Test bandwidth file including v1.1.0 bandwidth headers and
2355 : * v1.0.0 relay lines. bw_file_headers will contain the v1.1.0 headers. */
2356 1 : bw_file_headers = smartlist_new();
2357 1 : tor_asprintf(&content, "%s%s%s", header_lines_v100, header_lines_v110,
2358 : relay_lines_v100);
2359 1 : write_str_to_file(fname, content, 0);
2360 1 : tor_free(content);
2361 1 : tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2362 : bw_file_headers,
2363 : NULL));
2364 :
2365 1 : bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2366 1 : tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str);
2367 9 : SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2368 1 : smartlist_free(bw_file_headers);
2369 1 : tor_free(bw_file_headers_str);
2370 :
2371 : /* Test v1.0.0 complete bandwidth file with v1.1.0 headers at the end.
2372 : * bw_file_headers will contain only v1.0.0 headers and the additional
2373 : * headers will be interpreted as malformed relay lines. */
2374 1 : bw_file_headers = smartlist_new();
2375 1 : tor_asprintf(&content, "%s%s%s", header_lines_v100, relay_lines_v100,
2376 : header_lines_v110);
2377 1 : write_str_to_file(fname, content, 0);
2378 1 : tor_free(content);
2379 1 : tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2380 : bw_file_headers,
2381 : NULL));
2382 :
2383 1 : bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2384 1 : tt_str_op(bw_file_headers_str_v100, OP_EQ, bw_file_headers_str);
2385 2 : SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2386 1 : smartlist_free(bw_file_headers);
2387 1 : tor_free(bw_file_headers_str);
2388 :
2389 : /* Test v1.0.0 complete bandwidth file, the v1.1.0 headers and more relay
2390 : * lines. bw_file_headers will contain only v1.0.0 headers, the additional
2391 : * headers will be interpreted as malformed relay lines and the last relay
2392 : * lines will be correctly interpreted as relay lines. */
2393 1 : bw_file_headers = smartlist_new();
2394 1 : tor_asprintf(&content, "%s%s%s%s", header_lines_v100, relay_lines_v100,
2395 : header_lines_v110, relay_lines_v100);
2396 1 : write_str_to_file(fname, content, 0);
2397 1 : tor_free(content);
2398 1 : tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2399 : bw_file_headers,
2400 : NULL));
2401 :
2402 1 : bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2403 1 : tt_str_op(bw_file_headers_str_v100, OP_EQ, bw_file_headers_str);
2404 2 : SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2405 1 : smartlist_free(bw_file_headers);
2406 1 : tor_free(bw_file_headers_str);
2407 :
2408 : /* Test v1.1.0 bandwidth headers without terminator */
2409 1 : bw_file_headers = smartlist_new();
2410 1 : write_str_to_file(fname, header_lines_v110_no_terminator, 0);
2411 1 : tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2412 : bw_file_headers,
2413 : NULL));
2414 :
2415 1 : bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2416 1 : tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str);
2417 9 : SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2418 1 : smartlist_free(bw_file_headers);
2419 1 : tor_free(bw_file_headers_str);
2420 :
2421 : /* Test v1.1.0 bandwidth headers with terminator */
2422 1 : bw_file_headers = smartlist_new();
2423 1 : write_str_to_file(fname, header_lines_v110, 0);
2424 1 : tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2425 : bw_file_headers,
2426 : NULL));
2427 :
2428 1 : bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2429 1 : tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str);
2430 9 : SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2431 1 : smartlist_free(bw_file_headers);
2432 1 : tor_free(bw_file_headers_str);
2433 :
2434 : /* Test v1.1.0 bandwidth file without terminator, then relay lines.
2435 : * bw_file_headers will contain the v1.1.0 headers. */
2436 1 : bw_file_headers = smartlist_new();
2437 1 : tor_asprintf(&content, "%s%s",
2438 : header_lines_v110_no_terminator, relay_lines_v110);
2439 1 : write_str_to_file(fname, content, 0);
2440 1 : tor_free(content);
2441 1 : tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2442 : bw_file_headers,
2443 : NULL));
2444 :
2445 1 : bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2446 1 : tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str);
2447 9 : SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2448 1 : smartlist_free(bw_file_headers);
2449 1 : tor_free(bw_file_headers_str);
2450 :
2451 : /* Test v1.1.0 bandwidth headers with terminator, then relay lines
2452 : * bw_file_headers will contain the v1.1.0 headers. */
2453 1 : bw_file_headers = smartlist_new();
2454 1 : tor_asprintf(&content, "%s%s",
2455 : header_lines_v110, relay_lines_v110);
2456 1 : write_str_to_file(fname, content, 0);
2457 1 : tor_free(content);
2458 1 : tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2459 : bw_file_headers,
2460 : NULL));
2461 :
2462 1 : bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2463 1 : tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str);
2464 9 : SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2465 1 : smartlist_free(bw_file_headers);
2466 1 : tor_free(bw_file_headers_str);
2467 :
2468 : /* Test v1.1.0 bandwidth headers with terminator, then bad relay lines,
2469 : * then terminator, then relay_lines_bad.
2470 : * bw_file_headers will contain the v1.1.0 headers. */
2471 1 : bw_file_headers = smartlist_new();
2472 1 : tor_asprintf(&content, "%s%s%s%s", header_lines_v110, relay_lines_bad,
2473 : BW_FILE_HEADERS_TERMINATOR, relay_lines_bad);
2474 1 : write_str_to_file(fname, content, 0);
2475 1 : tor_free(content);
2476 1 : tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2477 : bw_file_headers,
2478 : NULL));
2479 :
2480 1 : bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2481 1 : tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str);
2482 9 : SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2483 1 : smartlist_free(bw_file_headers);
2484 1 : tor_free(bw_file_headers_str);
2485 :
2486 : /* Test v1.1.0 bandwidth headers without terminator, then bad relay lines,
2487 : * then relay lines. bw_file_headers will contain the v1.1.0 headers and
2488 : * the bad relay lines. */
2489 1 : bw_file_headers = smartlist_new();
2490 1 : tor_asprintf(&content, "%s%s%s",
2491 : header_lines_v110_no_terminator, relay_lines_bad,
2492 : relay_lines_v110);
2493 1 : write_str_to_file(fname, content, 0);
2494 1 : tor_free(content);
2495 1 : tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2496 : bw_file_headers,
2497 : NULL));
2498 :
2499 1 : bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2500 1 : tt_str_op(bw_file_headers_str_bad, OP_EQ, bw_file_headers_str);
2501 10 : SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2502 1 : smartlist_free(bw_file_headers);
2503 1 : tor_free(bw_file_headers_str);
2504 :
2505 : /* Test v1.1.0 bandwidth headers without terminator,
2506 : * then many bad relay lines, then relay lines.
2507 : * bw_file_headers will contain the v1.1.0 headers and the bad relay lines
2508 : * to a maximum of MAX_BW_FILE_HEADER_COUNT_IN_VOTE header lines. */
2509 1 : bw_file_headers = smartlist_new();
2510 1 : tor_asprintf(&content, "%s%s%s",
2511 : header_lines_v110_no_terminator, header_lines_long,
2512 : relay_lines_v110);
2513 1 : write_str_to_file(fname, content, 0);
2514 1 : tor_free(content);
2515 1 : tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2516 : bw_file_headers,
2517 : NULL));
2518 :
2519 1 : tt_int_op(MAX_BW_FILE_HEADER_COUNT_IN_VOTE, OP_EQ,
2520 : smartlist_len(bw_file_headers));
2521 1 : bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
2522 1 : tt_str_op(bw_file_headers_str_extra, OP_EQ, bw_file_headers_str);
2523 51 : SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2524 1 : smartlist_free(bw_file_headers);
2525 1 : tor_free(bw_file_headers_str);
2526 :
2527 : /* Test v1.1.0 bandwidth headers without terminator,
2528 : * then many bad relay lines, then relay lines.
2529 : * bw_file_headers will contain the v1.1.0 headers and the bad relay lines.
2530 : * Force bw_file_headers to have more than MAX_BW_FILE_HEADER_COUNT_IN_VOTE
2531 : * This test is needed while there is not dirvote test. */
2532 1 : bw_file_headers = smartlist_new();
2533 1 : tor_asprintf(&content, "%s%s%s",
2534 : header_lines_v110_no_terminator, header_lines_long,
2535 : relay_lines_v110);
2536 1 : write_str_to_file(fname, content, 0);
2537 1 : tor_free(content);
2538 1 : tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
2539 : bw_file_headers,
2540 : NULL));
2541 :
2542 1 : tt_int_op(MAX_BW_FILE_HEADER_COUNT_IN_VOTE, OP_EQ,
2543 : smartlist_len(bw_file_headers));
2544 : /* force bw_file_headers to be bigger than
2545 : * MAX_BW_FILE_HEADER_COUNT_IN_VOTE */
2546 1 : char line[8] = "foo=bar\0";
2547 1 : smartlist_add_strdup(bw_file_headers, line);
2548 1 : tt_int_op(MAX_BW_FILE_HEADER_COUNT_IN_VOTE, OP_LT,
2549 : smartlist_len(bw_file_headers));
2550 52 : SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
2551 1 : smartlist_free(bw_file_headers);
2552 1 : tor_free(bw_file_headers_str);
2553 :
2554 : /* Test v1.x.x bandwidth line with vote=0.
2555 : * It will be ignored it and logged it at debug level. */
2556 1 : const char *relay_lines_ignore =
2557 : "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 bw=1024 vote=0\n"
2558 : "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 bw=1024 vote=0"
2559 : "unmeasured=1\n"
2560 : "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 bw=1024 vote=0"
2561 : "unmeasured=0\n";
2562 :
2563 : /* Create the bandwidth file */
2564 1 : tor_asprintf(&content, "%ld\n%s", (long)timestamp, relay_lines_ignore);
2565 1 : write_str_to_file(fname, content, 0);
2566 1 : tor_free(content);
2567 :
2568 : /* Read the bandwidth file */
2569 1 : setup_full_capture_of_logs(LOG_DEBUG);
2570 1 : tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL, NULL,
2571 : NULL));
2572 1 : expect_log_msg_containing("Ignoring bandwidth file line");
2573 1 : teardown_capture_of_logs();
2574 :
2575 : /* Test v1.x.x bandwidth line with "vote=1" or "unmeasured=1" or
2576 : * "unmeasured=0".
2577 : * They will not be ignored. */
2578 : /* Create the bandwidth file */
2579 1 : const char *relay_lines_vote =
2580 : "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 bw=1024 vote=1\n"
2581 : "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 bw=1024 unmeasured=0\n"
2582 : "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 bw=1024 unmeasured=1\n";
2583 1 : tor_asprintf(&content, "%ld\n%s", (long)timestamp, relay_lines_vote);
2584 1 : write_str_to_file(fname, content, 0);
2585 1 : tor_free(content);
2586 :
2587 : /* Read the bandwidth file */
2588 1 : setup_full_capture_of_logs(LOG_DEBUG);
2589 1 : tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL, NULL,
2590 : NULL));
2591 1 : expect_log_msg_not_containing("Ignoring bandwidth file line");
2592 1 : teardown_capture_of_logs();
2593 :
2594 1 : done:
2595 1 : unlink(fname);
2596 1 : tor_free(fname);
2597 1 : tor_free(header_lines_v100);
2598 1 : tor_free(header_lines_v110_no_terminator);
2599 1 : tor_free(header_lines_v110);
2600 1 : tor_free(bw_file_headers_str_v100);
2601 1 : tor_free(bw_file_headers_str_v110);
2602 1 : tor_free(bw_file_headers_str_bad);
2603 1 : tor_free(bw_file_headers_str_extra);
2604 1 : }
2605 :
2606 : #define MBWC_INIT_TIME 1000
2607 :
2608 : /** Do the measured bandwidth cache unit test */
2609 : static void
2610 1 : test_dir_measured_bw_kb_cache(void *arg)
2611 : {
2612 : /* Initial fake time_t for testing */
2613 1 : time_t curr = MBWC_INIT_TIME;
2614 : /* Some measured_bw_line_ts */
2615 1 : measured_bw_line_t mbwl[3];
2616 : /* For receiving output on cache queries */
2617 1 : long bw;
2618 1 : time_t as_of;
2619 :
2620 : /* First, clear the cache and assert that it's empty */
2621 1 : (void)arg;
2622 1 : dirserv_clear_measured_bw_cache();
2623 1 : tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 0);
2624 : /*
2625 : * Set up test mbwls; none of the dirserv_cache_*() functions care about
2626 : * the node_hex field.
2627 : */
2628 1 : memset(mbwl[0].node_id, 0x01, DIGEST_LEN);
2629 1 : mbwl[0].bw_kb = 20;
2630 1 : memset(mbwl[1].node_id, 0x02, DIGEST_LEN);
2631 1 : mbwl[1].bw_kb = 40;
2632 1 : memset(mbwl[2].node_id, 0x03, DIGEST_LEN);
2633 1 : mbwl[2].bw_kb = 80;
2634 : /* Try caching something */
2635 1 : dirserv_cache_measured_bw(&(mbwl[0]), curr);
2636 1 : tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 1);
2637 : /* Okay, let's see if we can retrieve it */
2638 1 : tt_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,&bw, &as_of));
2639 1 : tt_int_op(bw,OP_EQ, 20);
2640 1 : tt_int_op(as_of,OP_EQ, MBWC_INIT_TIME);
2641 : /* Try retrieving it without some outputs */
2642 1 : tt_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,NULL, NULL));
2643 1 : tt_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,&bw, NULL));
2644 1 : tt_int_op(bw,OP_EQ, 20);
2645 1 : tt_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,NULL,&as_of));
2646 1 : tt_int_op(as_of,OP_EQ, MBWC_INIT_TIME);
2647 : /* Now expire it */
2648 1 : curr += MAX_MEASUREMENT_AGE + 1;
2649 1 : dirserv_expire_measured_bw_cache(curr);
2650 : /* Check that the cache is empty */
2651 1 : tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 0);
2652 : /* Check that we can't retrieve it */
2653 1 : tt_assert(!dirserv_query_measured_bw_cache_kb(mbwl[0].node_id, NULL,NULL));
2654 : /* Try caching a few things now */
2655 1 : dirserv_cache_measured_bw(&(mbwl[0]), curr);
2656 1 : tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 1);
2657 1 : curr += MAX_MEASUREMENT_AGE / 4;
2658 1 : dirserv_cache_measured_bw(&(mbwl[1]), curr);
2659 1 : tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 2);
2660 1 : curr += MAX_MEASUREMENT_AGE / 4;
2661 1 : dirserv_cache_measured_bw(&(mbwl[2]), curr);
2662 1 : tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 3);
2663 1 : curr += MAX_MEASUREMENT_AGE / 4 + 1;
2664 : /* Do an expire that's too soon to get any of them */
2665 1 : dirserv_expire_measured_bw_cache(curr);
2666 1 : tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 3);
2667 : /* Push the oldest one off the cliff */
2668 1 : curr += MAX_MEASUREMENT_AGE / 4;
2669 1 : dirserv_expire_measured_bw_cache(curr);
2670 1 : tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 2);
2671 : /* And another... */
2672 1 : curr += MAX_MEASUREMENT_AGE / 4;
2673 1 : dirserv_expire_measured_bw_cache(curr);
2674 1 : tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 1);
2675 : /* This should empty it out again */
2676 1 : curr += MAX_MEASUREMENT_AGE / 4;
2677 1 : dirserv_expire_measured_bw_cache(curr);
2678 1 : tt_int_op(dirserv_get_measured_bw_cache_size(),OP_EQ, 0);
2679 :
2680 1 : done:
2681 1 : return;
2682 : }
2683 :
2684 : static char *
2685 12 : my_dirvote_compute_params(smartlist_t *votes, int method,
2686 : int total_authorities)
2687 : {
2688 12 : smartlist_t *s = dirvote_compute_params(votes, method, total_authorities);
2689 12 : tor_assert(s);
2690 12 : char *res = smartlist_join_strings(s, " ", 0, NULL);
2691 46 : SMARTLIST_FOREACH(s, char *, cp, tor_free(cp));
2692 12 : smartlist_free(s);
2693 12 : return res;
2694 : }
2695 :
2696 : #define dirvote_compute_params my_dirvote_compute_params
2697 :
2698 : static void
2699 1 : test_dir_param_voting(void *arg)
2700 : {
2701 1 : networkstatus_t vote1, vote2, vote3, vote4;
2702 1 : smartlist_t *votes = smartlist_new();
2703 1 : char *res = NULL;
2704 :
2705 : /* dirvote_compute_params only looks at the net_params field of the votes,
2706 : so that's all we need to set.
2707 : */
2708 1 : (void)arg;
2709 1 : memset(&vote1, 0, sizeof(vote1));
2710 1 : memset(&vote2, 0, sizeof(vote2));
2711 1 : memset(&vote3, 0, sizeof(vote3));
2712 1 : memset(&vote4, 0, sizeof(vote4));
2713 1 : vote1.net_params = smartlist_new();
2714 1 : vote2.net_params = smartlist_new();
2715 1 : vote3.net_params = smartlist_new();
2716 1 : vote4.net_params = smartlist_new();
2717 1 : smartlist_split_string(vote1.net_params,
2718 : "ab=90 abcd=20 cw=50 x-yz=-99", NULL, 0, 0);
2719 1 : smartlist_split_string(vote2.net_params,
2720 : "ab=27 cw=5 x-yz=88", NULL, 0, 0);
2721 1 : smartlist_split_string(vote3.net_params,
2722 : "abcd=20 c=60 cw=500 x-yz=-9 zzzzz=101", NULL, 0, 0);
2723 1 : smartlist_split_string(vote4.net_params,
2724 : "ab=900 abcd=200 c=1 cw=51 x-yz=100", NULL, 0, 0);
2725 1 : tt_int_op(100,OP_EQ, networkstatus_get_param(&vote4, "x-yz", 50, 0, 300));
2726 1 : tt_int_op(222,OP_EQ, networkstatus_get_param(&vote4, "foobar", 222, 0, 300));
2727 1 : tt_int_op(80,OP_EQ, networkstatus_get_param(&vote4, "ab", 12, 0, 80));
2728 1 : tt_int_op(-8,OP_EQ, networkstatus_get_param(&vote4, "ab", -12, -100, -8));
2729 1 : tt_int_op(0,OP_EQ, networkstatus_get_param(&vote4, "foobar", 0, -100, 8));
2730 :
2731 1 : tt_int_op(100,OP_EQ, networkstatus_get_overridable_param(
2732 : &vote4, -1, "x-yz", 50, 0, 300));
2733 1 : tt_int_op(30,OP_EQ, networkstatus_get_overridable_param(
2734 : &vote4, 30, "x-yz", 50, 0, 300));
2735 1 : tt_int_op(0,OP_EQ, networkstatus_get_overridable_param(
2736 : &vote4, -101, "foobar", 0, -100, 8));
2737 1 : tt_int_op(-99,OP_EQ, networkstatus_get_overridable_param(
2738 : &vote4, -99, "foobar", 0, -100, 8));
2739 :
2740 1 : smartlist_add(votes, &vote1);
2741 :
2742 : /* Do the first tests without adding all the other votes, for
2743 : * networks without many dirauths. */
2744 :
2745 1 : res = dirvote_compute_params(votes, 12, 2);
2746 1 : tt_str_op(res,OP_EQ, "");
2747 1 : tor_free(res);
2748 :
2749 1 : res = dirvote_compute_params(votes, 12, 1);
2750 1 : tt_str_op(res,OP_EQ, "ab=90 abcd=20 cw=50 x-yz=-99");
2751 1 : tor_free(res);
2752 :
2753 1 : smartlist_add(votes, &vote2);
2754 :
2755 1 : res = dirvote_compute_params(votes, 12, 2);
2756 1 : tt_str_op(res,OP_EQ, "ab=27 cw=5 x-yz=-99");
2757 1 : tor_free(res);
2758 :
2759 1 : res = dirvote_compute_params(votes, 12, 3);
2760 1 : tt_str_op(res,OP_EQ, "ab=27 cw=5 x-yz=-99");
2761 1 : tor_free(res);
2762 :
2763 1 : res = dirvote_compute_params(votes, 12, 6);
2764 1 : tt_str_op(res,OP_EQ, "");
2765 1 : tor_free(res);
2766 :
2767 1 : smartlist_add(votes, &vote3);
2768 :
2769 1 : res = dirvote_compute_params(votes, 12, 3);
2770 1 : tt_str_op(res,OP_EQ, "ab=27 abcd=20 cw=50 x-yz=-9");
2771 1 : tor_free(res);
2772 :
2773 1 : res = dirvote_compute_params(votes, 12, 5);
2774 1 : tt_str_op(res,OP_EQ, "cw=50 x-yz=-9");
2775 1 : tor_free(res);
2776 :
2777 1 : res = dirvote_compute_params(votes, 12, 9);
2778 1 : tt_str_op(res,OP_EQ, "cw=50 x-yz=-9");
2779 1 : tor_free(res);
2780 :
2781 1 : smartlist_add(votes, &vote4);
2782 :
2783 1 : res = dirvote_compute_params(votes, 12, 4);
2784 1 : tt_str_op(res,OP_EQ, "ab=90 abcd=20 cw=50 x-yz=-9");
2785 1 : tor_free(res);
2786 :
2787 1 : res = dirvote_compute_params(votes, 12, 5);
2788 1 : tt_str_op(res,OP_EQ, "ab=90 abcd=20 cw=50 x-yz=-9");
2789 1 : tor_free(res);
2790 :
2791 : /* Test that the special-cased "at least three dirauths voted for
2792 : * this param" logic works as expected. */
2793 1 : res = dirvote_compute_params(votes, 12, 6);
2794 1 : tt_str_op(res,OP_EQ, "ab=90 abcd=20 cw=50 x-yz=-9");
2795 1 : tor_free(res);
2796 :
2797 1 : res = dirvote_compute_params(votes, 12, 10);
2798 1 : tt_str_op(res,OP_EQ, "ab=90 abcd=20 cw=50 x-yz=-9");
2799 1 : tor_free(res);
2800 :
2801 1 : done:
2802 1 : tor_free(res);
2803 5 : SMARTLIST_FOREACH(vote1.net_params, char *, cp, tor_free(cp));
2804 4 : SMARTLIST_FOREACH(vote2.net_params, char *, cp, tor_free(cp));
2805 6 : SMARTLIST_FOREACH(vote3.net_params, char *, cp, tor_free(cp));
2806 6 : SMARTLIST_FOREACH(vote4.net_params, char *, cp, tor_free(cp));
2807 1 : smartlist_free(vote1.net_params);
2808 1 : smartlist_free(vote2.net_params);
2809 1 : smartlist_free(vote3.net_params);
2810 1 : smartlist_free(vote4.net_params);
2811 1 : smartlist_free(votes);
2812 :
2813 1 : return;
2814 : }
2815 :
2816 : static void
2817 1 : test_dir_param_voting_lookup(void *arg)
2818 : {
2819 1 : (void)arg;
2820 1 : smartlist_t *lst = smartlist_new();
2821 :
2822 1 : smartlist_split_string(lst,
2823 : "moomin=9 moomin=10 moomintroll=5 fred "
2824 : "jack= electricity=sdk opa=6z abc=9 abcd=99",
2825 : NULL, 0, 0);
2826 :
2827 1 : tt_int_op(1000,
2828 : OP_EQ, dirvote_get_intermediate_param_value(lst, "ab", 1000));
2829 1 : tt_int_op(9, OP_EQ, dirvote_get_intermediate_param_value(lst, "abc", 1000));
2830 1 : tt_int_op(99, OP_EQ,
2831 : dirvote_get_intermediate_param_value(lst, "abcd", 1000));
2832 :
2833 : #ifndef ALL_BUGS_ARE_FATAL
2834 : /* moomin appears twice. That's a bug. */
2835 1 : tor_capture_bugs_(1);
2836 1 : tt_int_op(-100, OP_EQ,
2837 : dirvote_get_intermediate_param_value(lst, "moomin", -100));
2838 1 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
2839 1 : tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
2840 : "n_found == 0");
2841 1 : tor_end_capture_bugs_();
2842 : /* There is no 'fred=', so that is treated as not existing. */
2843 1 : tt_int_op(-100, OP_EQ,
2844 : dirvote_get_intermediate_param_value(lst, "fred", -100));
2845 : /* jack is truncated */
2846 1 : tor_capture_bugs_(1);
2847 1 : tt_int_op(-100, OP_EQ,
2848 : dirvote_get_intermediate_param_value(lst, "jack", -100));
2849 1 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
2850 1 : tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
2851 : "!(!ok)");
2852 1 : tor_end_capture_bugs_();
2853 : /* electricity and opa aren't integers. */
2854 1 : tor_capture_bugs_(1);
2855 1 : tt_int_op(-100, OP_EQ,
2856 : dirvote_get_intermediate_param_value(lst, "electricity", -100));
2857 1 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
2858 1 : tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
2859 : "!(!ok)");
2860 1 : tor_end_capture_bugs_();
2861 :
2862 1 : tor_capture_bugs_(1);
2863 1 : tt_int_op(-100, OP_EQ,
2864 : dirvote_get_intermediate_param_value(lst, "opa", -100));
2865 1 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
2866 1 : tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
2867 : "!(!ok)");
2868 1 : tor_end_capture_bugs_();
2869 : #endif /* !defined(ALL_BUGS_ARE_FATAL) */
2870 :
2871 1 : done:
2872 10 : SMARTLIST_FOREACH(lst, char *, cp, tor_free(cp));
2873 1 : smartlist_free(lst);
2874 1 : tor_end_capture_bugs_();
2875 1 : }
2876 :
2877 : #undef dirvote_compute_params
2878 :
2879 : /** Helper: Test that two networkstatus_voter_info_t do in fact represent the
2880 : * same voting authority, and that they do in fact have all the same
2881 : * information. */
2882 : static void
2883 9 : test_same_voter(networkstatus_voter_info_t *v1,
2884 : networkstatus_voter_info_t *v2)
2885 : {
2886 9 : tt_str_op(v1->nickname,OP_EQ, v2->nickname);
2887 9 : tt_mem_op(v1->identity_digest,OP_EQ, v2->identity_digest, DIGEST_LEN);
2888 9 : tt_str_op(v1->address,OP_EQ, v2->address);
2889 9 : tt_assert(tor_addr_eq(&v1->ipv4_addr, &v2->ipv4_addr));
2890 9 : tt_int_op(v1->ipv4_dirport,OP_EQ, v2->ipv4_dirport);
2891 9 : tt_int_op(v1->ipv4_orport,OP_EQ, v2->ipv4_orport);
2892 9 : tt_str_op(v1->contact,OP_EQ, v2->contact);
2893 9 : tt_mem_op(v1->vote_digest,OP_EQ, v2->vote_digest, DIGEST_LEN);
2894 9 : done:
2895 9 : ;
2896 9 : }
2897 :
2898 : /** Helper: get a detached signatures document for one or two
2899 : * consensuses. */
2900 : static char *
2901 9 : get_detached_sigs(networkstatus_t *ns, networkstatus_t *ns2)
2902 : {
2903 9 : char *r;
2904 9 : smartlist_t *sl;
2905 9 : tor_assert(ns && ns->flavor == FLAV_NS);
2906 9 : sl = smartlist_new();
2907 9 : smartlist_add(sl,ns);
2908 9 : if (ns2)
2909 9 : smartlist_add(sl,ns2);
2910 9 : r = networkstatus_get_detached_signatures(sl);
2911 9 : smartlist_free(sl);
2912 9 : return r;
2913 : }
2914 :
2915 : /** Apply tweaks to the vote list for each voter */
2916 : static int
2917 3 : vote_tweaks_for_v3ns(networkstatus_t *v, int voter, time_t now)
2918 : {
2919 3 : vote_routerstatus_t *vrs;
2920 3 : const char *msg = NULL;
2921 :
2922 3 : tt_assert(v);
2923 3 : (void)now;
2924 :
2925 3 : if (voter == 1) {
2926 1 : measured_bw_line_t mbw;
2927 1 : memset(mbw.node_id, 33, sizeof(mbw.node_id));
2928 1 : mbw.bw_kb = 1024;
2929 1 : tt_int_op(measured_bw_line_apply(&mbw, v->routerstatus_list), OP_EQ, 1);
2930 2 : } else if (voter == 2 || voter == 3) {
2931 : /* Monkey around with the list a bit */
2932 2 : vrs = smartlist_get(v->routerstatus_list, 2);
2933 2 : smartlist_del_keeporder(v->routerstatus_list, 2);
2934 2 : vote_routerstatus_free(vrs);
2935 2 : vrs = smartlist_get(v->routerstatus_list, 0);
2936 2 : vrs->status.is_fast = 1;
2937 :
2938 2 : if (voter == 3) {
2939 1 : vrs = smartlist_get(v->routerstatus_list, 0);
2940 1 : smartlist_del_keeporder(v->routerstatus_list, 0);
2941 1 : vote_routerstatus_free(vrs);
2942 1 : vrs = smartlist_get(v->routerstatus_list, 0);
2943 1 : memset(vrs->status.descriptor_digest, (int)'Z', DIGEST_LEN);
2944 1 : tt_assert(router_add_to_routerlist(
2945 : dir_common_generate_ri_from_rs(vrs), &msg,0,0) >= 0);
2946 : }
2947 : }
2948 :
2949 2 : done:
2950 3 : return 0;
2951 : }
2952 :
2953 : /**
2954 : * Test a parsed vote_routerstatus_t for v3_networkstatus test
2955 : */
2956 : static void
2957 7 : test_vrs_for_v3ns(vote_routerstatus_t *vrs, int voter, time_t now)
2958 : {
2959 7 : routerstatus_t *rs;
2960 7 : tor_addr_t addr_ipv6;
2961 :
2962 7 : tt_assert(vrs);
2963 7 : rs = &(vrs->status);
2964 7 : tt_assert(rs);
2965 :
2966 : /* Split out by digests to test */
2967 7 : if (tor_memeq(rs->identity_digest,
2968 : "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
2969 : "\x3\x3\x3\x3",
2970 2 : DIGEST_LEN) &&
2971 : (voter == 1)) {
2972 : /* Check the first routerstatus. */
2973 1 : tt_str_op(vrs->version,OP_EQ, "0.1.2.14");
2974 1 : tt_int_op(rs->published_on,OP_EQ, now-1500);
2975 1 : tt_str_op(rs->nickname,OP_EQ, "router2");
2976 1 : tt_mem_op(rs->identity_digest,OP_EQ,
2977 : "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
2978 : "\x3\x3\x3\x3",
2979 1 : DIGEST_LEN);
2980 1 : tt_mem_op(rs->descriptor_digest,OP_EQ, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
2981 1 : tt_assert(tor_addr_eq_ipv4h(&rs->ipv4_addr, 0x99008801));
2982 1 : tt_int_op(rs->ipv4_orport,OP_EQ, 443);
2983 1 : tt_int_op(rs->ipv4_dirport,OP_EQ, 8000);
2984 : /* no flags except "running" (16) and "v2dir" (64) and "valid" (128) */
2985 1 : tt_u64_op(vrs->flags, OP_EQ, UINT64_C(0xd0));
2986 6 : } else if (tor_memeq(rs->identity_digest,
2987 : "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
2988 : "\x5\x5\x5\x5",
2989 2 : DIGEST_LEN) &&
2990 2 : (voter == 1 || voter == 2)) {
2991 2 : tt_mem_op(rs->identity_digest,OP_EQ,
2992 : "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
2993 : "\x5\x5\x5\x5",
2994 2 : DIGEST_LEN);
2995 :
2996 2 : if (voter == 1) {
2997 : /* Check the second routerstatus. */
2998 1 : tt_str_op(vrs->version,OP_EQ, "0.2.0.5");
2999 1 : tt_int_op(rs->published_on,OP_EQ, now-1000);
3000 1 : tt_str_op(rs->nickname,OP_EQ, "router1");
3001 : }
3002 2 : tt_mem_op(rs->descriptor_digest,OP_EQ, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
3003 2 : tt_assert(tor_addr_eq_ipv4h(&rs->ipv4_addr, 0x99009901));
3004 2 : tt_int_op(rs->ipv4_orport,OP_EQ, 443);
3005 2 : tt_int_op(rs->ipv4_dirport,OP_EQ, 0);
3006 2 : tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
3007 2 : tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
3008 2 : tt_int_op(rs->ipv6_orport,OP_EQ, 4711);
3009 2 : if (voter == 1) {
3010 : /* all except "authority" (1) */
3011 1 : tt_u64_op(vrs->flags, OP_EQ, UINT64_C(254));
3012 : } else {
3013 : /* 1023 - authority(1) - madeofcheese(16) - madeoftin(32) */
3014 1 : tt_u64_op(vrs->flags, OP_EQ, UINT64_C(974));
3015 : }
3016 4 : } else if (tor_memeq(rs->identity_digest,
3017 : "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33"
3018 : "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33",
3019 0 : DIGEST_LEN) &&
3020 0 : (voter == 1 || voter == 2)) {
3021 : /* Check the measured bandwidth bits */
3022 0 : tt_assert(vrs->has_measured_bw &&
3023 : vrs->measured_bw_kb == 1024);
3024 : } else {
3025 : /*
3026 : * Didn't expect this, but the old unit test only checked some of them,
3027 : * so don't assert.
3028 : */
3029 : /* tt_assert(0); */
3030 7 : }
3031 :
3032 4 : done:
3033 7 : return;
3034 : }
3035 :
3036 : /**
3037 : * Test a consensus for v3_networkstatus_test
3038 : */
3039 : static void
3040 1 : test_consensus_for_v3ns(networkstatus_t *con, time_t now)
3041 : {
3042 1 : (void)now;
3043 :
3044 1 : tt_assert(con);
3045 1 : tt_ptr_op(con->cert, OP_EQ, NULL);
3046 1 : tt_int_op(2,OP_EQ, smartlist_len(con->routerstatus_list));
3047 : /* There should be two listed routers: one with identity 3, one with
3048 : * identity 5. */
3049 :
3050 1 : done:
3051 1 : return;
3052 : }
3053 :
3054 : /**
3055 : * Test a router list entry for v3_networkstatus test
3056 : */
3057 : static void
3058 2 : test_routerstatus_for_v3ns(routerstatus_t *rs, time_t now)
3059 : {
3060 2 : tor_addr_t addr_ipv6;
3061 :
3062 2 : tt_assert(rs);
3063 :
3064 : /* There should be two listed routers: one with identity 3, one with
3065 : * identity 5. */
3066 : /* This one showed up in 2 digests. */
3067 2 : if (tor_memeq(rs->identity_digest,
3068 : "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
3069 : "\x3\x3",
3070 : DIGEST_LEN)) {
3071 1 : tt_mem_op(rs->identity_digest,OP_EQ,
3072 : "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
3073 1 : DIGEST_LEN);
3074 1 : tt_mem_op(rs->descriptor_digest,OP_EQ, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
3075 1 : tt_assert(!rs->is_authority);
3076 1 : tt_assert(!rs->is_exit);
3077 1 : tt_assert(!rs->is_fast);
3078 1 : tt_assert(!rs->is_possible_guard);
3079 1 : tt_assert(!rs->is_stable);
3080 : /* (If it wasn't running it wouldn't be here) */
3081 1 : tt_assert(rs->is_flagged_running);
3082 1 : tt_assert(rs->is_valid);
3083 1 : tt_assert(!rs->is_named);
3084 1 : tt_assert(rs->is_v2_dir);
3085 : /* XXXX check version */
3086 1 : } else if (tor_memeq(rs->identity_digest,
3087 : "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
3088 : "\x5\x5\x5\x5",
3089 : DIGEST_LEN)) {
3090 : /* This one showed up in 3 digests. Twice with ID 'M', once with 'Z'. */
3091 1 : tt_mem_op(rs->identity_digest,OP_EQ,
3092 : "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
3093 1 : DIGEST_LEN);
3094 1 : tt_str_op(rs->nickname,OP_EQ, "router1");
3095 1 : tt_mem_op(rs->descriptor_digest,OP_EQ, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
3096 1 : tt_int_op(rs->published_on,OP_EQ, now-1000);
3097 1 : tt_assert(tor_addr_eq_ipv4h(&rs->ipv4_addr, 0x99009901));
3098 1 : tt_int_op(rs->ipv4_orport,OP_EQ, 443);
3099 1 : tt_int_op(rs->ipv4_dirport,OP_EQ, 0);
3100 1 : tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
3101 1 : tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
3102 1 : tt_int_op(rs->ipv6_orport,OP_EQ, 4711);
3103 1 : tt_assert(!rs->is_authority);
3104 1 : tt_assert(rs->is_exit);
3105 1 : tt_assert(rs->is_fast);
3106 1 : tt_assert(rs->is_possible_guard);
3107 1 : tt_assert(rs->is_stable);
3108 1 : tt_assert(rs->is_flagged_running);
3109 1 : tt_assert(rs->is_valid);
3110 1 : tt_assert(rs->is_v2_dir);
3111 1 : tt_assert(!rs->is_named);
3112 : /* XXXX check version */
3113 : } else {
3114 : /* Weren't expecting this... */
3115 0 : tt_abort();
3116 : }
3117 :
3118 2 : done:
3119 2 : return;
3120 : }
3121 :
3122 : static void
3123 1 : test_dir_networkstatus_compute_bw_weights_v10(void *arg)
3124 : {
3125 1 : (void) arg;
3126 1 : smartlist_t *chunks = smartlist_new();
3127 1 : int64_t G, M, E, D, T, weight_scale;
3128 1 : int ret;
3129 1 : weight_scale = 10000;
3130 :
3131 : /* no case. one or more of the values is 0 */
3132 1 : G = M = E = D = 0;
3133 1 : T = G + M + E + D;
3134 1 : ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3135 : weight_scale);
3136 1 : tt_int_op(ret, OP_EQ, 0);
3137 1 : tt_int_op(smartlist_len(chunks), OP_EQ, 0);
3138 :
3139 : /* case 1 */
3140 : /* XXX dir-spec not followed? See #20272. If it isn't closed, then this is
3141 : * testing current behavior, not spec. */
3142 1 : G = E = 10;
3143 1 : M = D = 1;
3144 1 : T = G + M + E + D;
3145 1 : ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3146 : weight_scale);
3147 1 : tt_int_op(ret, OP_EQ, 1);
3148 1 : tt_int_op(smartlist_len(chunks), OP_EQ, 1);
3149 1 : tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=3333 "
3150 : "Wbe=3000 Wbg=3000 Wbm=10000 Wdb=10000 Web=10000 Wed=3333 Wee=7000 "
3151 : "Weg=3333 Wem=7000 Wgb=10000 Wgd=3333 Wgg=7000 Wgm=7000 Wmb=10000 "
3152 : "Wmd=3333 Wme=3000 Wmg=3000 Wmm=10000\n");
3153 2 : SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3154 1 : smartlist_clear(chunks);
3155 :
3156 : /* case 2a E scarce */
3157 1 : M = 100;
3158 1 : G = 20;
3159 1 : E = D = 5;
3160 1 : T = G + M + E + D;
3161 1 : ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3162 : weight_scale);
3163 1 : tt_int_op(ret, OP_EQ, 1);
3164 1 : tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 "
3165 : "Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=10000 Wee=10000 Weg=10000 "
3166 : "Wem=10000 Wgb=10000 Wgd=0 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=0 Wme=0 "
3167 : "Wmg=0 Wmm=10000\n");
3168 2 : SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3169 1 : smartlist_clear(chunks);
3170 :
3171 : /* case 2a G scarce */
3172 1 : M = 100;
3173 1 : E = 20;
3174 1 : G = D = 5;
3175 1 : T = G + M + E + D;
3176 1 : ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3177 : weight_scale);
3178 1 : tt_int_op(ret, OP_EQ, 1);
3179 1 : tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 "
3180 : "Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=0 Wee=10000 Weg=0 Wem=10000 "
3181 : "Wgb=10000 Wgd=10000 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=0 Wme=0 Wmg=0 "
3182 : "Wmm=10000\n");
3183 2 : SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3184 1 : smartlist_clear(chunks);
3185 :
3186 : /* case 2b1 (Wgg=1, Wmd=Wgd) */
3187 1 : M = 10;
3188 1 : E = 30;
3189 1 : G = 10;
3190 1 : D = 100;
3191 1 : T = G + M + E + D;
3192 1 : ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3193 : weight_scale);
3194 1 : tt_int_op(ret, OP_EQ, 1);
3195 1 : tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=4000 "
3196 : "Wbe=0 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=2000 Wee=10000 Weg=2000 "
3197 : "Wem=10000 Wgb=10000 Wgd=4000 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=4000 "
3198 : "Wme=0 Wmg=0 Wmm=10000\n");
3199 2 : SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3200 1 : smartlist_clear(chunks);
3201 :
3202 : /* case 2b2 */
3203 1 : M = 60;
3204 1 : E = 30;
3205 1 : G = 10;
3206 1 : D = 100;
3207 1 : T = G + M + E + D;
3208 1 : ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3209 : weight_scale);
3210 1 : tt_int_op(ret, OP_EQ, 1);
3211 1 : tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=666 Wbe=0 "
3212 : "Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=3666 Wee=10000 Weg=3666 "
3213 : "Wem=10000 Wgb=10000 Wgd=5668 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=666 "
3214 : "Wme=0 Wmg=0 Wmm=10000\n");
3215 2 : SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3216 1 : smartlist_clear(chunks);
3217 :
3218 : /* case 2b3 */
3219 : /* XXX I can't get a combination of values that hits this case without error,
3220 : * so this just tests that it fails. See #20285. Also see #20284 as 2b3 does
3221 : * not follow dir-spec. */
3222 : /* (E < T/3 && G < T/3) && (E+D>=G || G+D>=E) && (M > T/3) */
3223 1 : M = 80;
3224 1 : E = 30;
3225 1 : G = 30;
3226 1 : D = 30;
3227 1 : T = G + M + E + D;
3228 1 : ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3229 : weight_scale);
3230 1 : tt_int_op(ret, OP_EQ, 0);
3231 1 : SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3232 1 : smartlist_clear(chunks);
3233 :
3234 : /* case 3a G scarce */
3235 1 : M = 10;
3236 1 : E = 30;
3237 1 : G = 10;
3238 1 : D = 5;
3239 1 : T = G + M + E + D;
3240 1 : ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3241 : weight_scale);
3242 1 : tt_int_op(ret, OP_EQ, 1);
3243 1 : tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 "
3244 : "Wbe=3333 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=0 Wee=6667 Weg=0 "
3245 : "Wem=6667 Wgb=10000 Wgd=10000 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=0 "
3246 : "Wme=3333 Wmg=0 Wmm=10000\n");
3247 2 : SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3248 1 : smartlist_clear(chunks);
3249 :
3250 : /* case 3a E scarce */
3251 1 : M = 10;
3252 1 : E = 10;
3253 1 : G = 30;
3254 1 : D = 5;
3255 1 : T = G + M + E + D;
3256 1 : ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3257 : weight_scale);
3258 1 : tt_int_op(ret, OP_EQ, 1);
3259 1 : tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 "
3260 : "Wbg=3333 Wbm=10000 Wdb=10000 Web=10000 Wed=10000 Wee=10000 Weg=10000 "
3261 : "Wem=10000 Wgb=10000 Wgd=0 Wgg=6667 Wgm=6667 Wmb=10000 Wmd=0 Wme=0 "
3262 : "Wmg=3333 Wmm=10000\n");
3263 2 : SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3264 1 : smartlist_clear(chunks);
3265 :
3266 : /* case 3bg */
3267 1 : M = 10;
3268 1 : E = 30;
3269 1 : G = 10;
3270 1 : D = 10;
3271 1 : T = G + M + E + D;
3272 1 : ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3273 : weight_scale);
3274 1 : tt_int_op(ret, OP_EQ, 1);
3275 1 : tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 "
3276 : "Wbe=3334 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=0 Wee=6666 Weg=0 "
3277 : "Wem=6666 Wgb=10000 Wgd=10000 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=0 "
3278 : "Wme=3334 Wmg=0 Wmm=10000\n");
3279 2 : SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3280 1 : smartlist_clear(chunks);
3281 :
3282 : /* case 3be */
3283 1 : M = 10;
3284 1 : E = 10;
3285 1 : G = 30;
3286 1 : D = 10;
3287 1 : T = G + M + E + D;
3288 1 : ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3289 : weight_scale);
3290 1 : tt_int_op(ret, OP_EQ, 1);
3291 1 : tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 "
3292 : "Wbg=3334 Wbm=10000 Wdb=10000 Web=10000 Wed=10000 Wee=10000 Weg=10000 "
3293 : "Wem=10000 Wgb=10000 Wgd=0 Wgg=6666 Wgm=6666 Wmb=10000 Wmd=0 Wme=0 "
3294 : "Wmg=3334 Wmm=10000\n");
3295 2 : SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3296 1 : smartlist_clear(chunks);
3297 :
3298 : /* case from 21 Jul 2013 (3be) */
3299 1 : G = 5483409;
3300 1 : M = 1455379;
3301 1 : E = 980834;
3302 1 : D = 3385803;
3303 1 : T = 11305425;
3304 1 : tt_i64_op(G+M+E+D, OP_EQ, T);
3305 1 : ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3306 : weight_scale);
3307 1 : tt_assert(ret);
3308 1 : tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=883 Wbe=0 "
3309 : "Wbg=3673 Wbm=10000 Wdb=10000 Web=10000 Wed=8233 Wee=10000 Weg=8233 "
3310 : "Wem=10000 Wgb=10000 Wgd=883 Wgg=6327 Wgm=6327 Wmb=10000 Wmd=883 Wme=0 "
3311 : "Wmg=3673 Wmm=10000\n");
3312 2 : SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3313 1 : smartlist_clear(chunks);
3314 :
3315 : /* case from 04 Oct 2016 (3a E scarce) */
3316 1 : G=29322240;
3317 1 : M=4721546;
3318 1 : E=1522058;
3319 1 : D=9273571;
3320 1 : T=44839415;
3321 1 : tt_i64_op(G+M+E+D, OP_EQ, T);
3322 1 : ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3323 : weight_scale);
3324 1 : tt_assert(ret);
3325 1 : tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 "
3326 : "Wbg=4194 Wbm=10000 Wdb=10000 Web=10000 Wed=10000 Wee=10000 Weg=10000 "
3327 : "Wem=10000 Wgb=10000 Wgd=0 Wgg=5806 Wgm=5806 Wmb=10000 Wmd=0 Wme=0 "
3328 : "Wmg=4194 Wmm=10000\n");
3329 2 : SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3330 1 : smartlist_clear(chunks);
3331 :
3332 : /* case from 04 Sep 2013 (2b1) */
3333 1 : G=3091352;
3334 1 : M=1838837;
3335 1 : E=2109300;
3336 1 : D=2469369;
3337 1 : T=9508858;
3338 1 : tt_i64_op(G+M+E+D, OP_EQ, T);
3339 1 : ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3340 : weight_scale);
3341 1 : tt_assert(ret);
3342 1 : tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=317 "
3343 : "Wbe=5938 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=9366 Wee=4061 "
3344 : "Weg=9366 Wem=4061 Wgb=10000 Wgd=317 Wgg=10000 Wgm=10000 Wmb=10000 "
3345 : "Wmd=317 Wme=5938 Wmg=0 Wmm=10000\n");
3346 2 : SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3347 1 : smartlist_clear(chunks);
3348 :
3349 : /* explicitly test initializing weights to 1*/
3350 1 : G=1;
3351 1 : M=1;
3352 1 : E=1;
3353 1 : D=1;
3354 1 : T=4;
3355 1 : tt_i64_op(G+M+E+D, OP_EQ, T);
3356 1 : ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
3357 : weight_scale);
3358 1 : tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=3333 "
3359 : "Wbe=0 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=3333 Wee=10000 Weg=3333 "
3360 : "Wem=10000 Wgb=10000 Wgd=3333 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=3333 "
3361 : "Wme=0 Wmg=0 Wmm=10000\n");
3362 1 : tt_assert(ret);
3363 :
3364 1 : done:
3365 2 : SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
3366 1 : smartlist_free(chunks);
3367 1 : }
3368 :
3369 : static authority_cert_t *mock_cert;
3370 :
3371 : static authority_cert_t *
3372 3 : get_my_v3_authority_cert_m(void)
3373 : {
3374 3 : tor_assert(mock_cert);
3375 3 : return mock_cert;
3376 : }
3377 :
3378 : /** Run a unit tests for generating and parsing networkstatuses, with
3379 : * the supply test fns. */
3380 : static void
3381 3 : test_a_networkstatus(
3382 : vote_routerstatus_t * (*vrs_gen)(int idx, time_t now),
3383 : int (*vote_tweaks)(networkstatus_t *v, int voter, time_t now),
3384 : void (*vrs_test)(vote_routerstatus_t *vrs, int voter, time_t now),
3385 : void (*consensus_test)(networkstatus_t *con, time_t now),
3386 : void (*rs_test)(routerstatus_t *rs, time_t now))
3387 : {
3388 3 : authority_cert_t *cert1=NULL, *cert2=NULL, *cert3=NULL;
3389 3 : crypto_pk_t *sign_skey_1=NULL, *sign_skey_2=NULL, *sign_skey_3=NULL;
3390 3 : crypto_pk_t *sign_skey_leg1=NULL;
3391 : /*
3392 : * Sum the non-zero returns from vote_tweaks() we've seen; if vote_tweaks()
3393 : * returns non-zero, it changed net_params and we should skip the tests for
3394 : * that later as they will fail.
3395 : */
3396 3 : int params_tweaked = 0;
3397 :
3398 3 : time_t now = time(NULL);
3399 3 : networkstatus_voter_info_t *voter;
3400 3 : document_signature_t *sig;
3401 3 : networkstatus_t *vote=NULL, *v1=NULL, *v2=NULL, *v3=NULL, *con=NULL,
3402 3 : *con_md=NULL;
3403 3 : vote_routerstatus_t *vrs;
3404 3 : routerstatus_t *rs;
3405 3 : int idx, n_rs, n_vrs;
3406 3 : char *consensus_text=NULL, *cp=NULL;
3407 3 : smartlist_t *votes = smartlist_new();
3408 :
3409 : /* For generating the two other consensuses. */
3410 3 : char *detached_text1=NULL, *detached_text2=NULL;
3411 3 : char *consensus_text2=NULL, *consensus_text3=NULL;
3412 3 : char *consensus_text_md2=NULL, *consensus_text_md3=NULL;
3413 3 : char *consensus_text_md=NULL;
3414 3 : networkstatus_t *con2=NULL, *con_md2=NULL, *con3=NULL, *con_md3=NULL;
3415 3 : ns_detached_signatures_t *dsig1=NULL, *dsig2=NULL;
3416 :
3417 3 : tt_assert(vrs_gen);
3418 3 : tt_assert(rs_test);
3419 3 : tt_assert(vrs_test);
3420 :
3421 3 : MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m);
3422 :
3423 : /* Parse certificates and keys. */
3424 3 : cert1 = mock_cert = authority_cert_parse_from_string(AUTHORITY_CERT_1,
3425 : strlen(AUTHORITY_CERT_1),
3426 : NULL);
3427 3 : tt_assert(cert1);
3428 3 : cert2 = authority_cert_parse_from_string(AUTHORITY_CERT_2,
3429 : strlen(AUTHORITY_CERT_2),
3430 : NULL);
3431 3 : tt_assert(cert2);
3432 3 : cert3 = authority_cert_parse_from_string(AUTHORITY_CERT_3,
3433 : strlen(AUTHORITY_CERT_3),
3434 : NULL);
3435 3 : tt_assert(cert3);
3436 3 : sign_skey_1 = crypto_pk_new();
3437 3 : sign_skey_2 = crypto_pk_new();
3438 3 : sign_skey_3 = crypto_pk_new();
3439 3 : sign_skey_leg1 = pk_generate(4);
3440 3 : dirauth_sched_recalculate_timing(get_options(), now);
3441 3 : sr_state_init(0, 0);
3442 :
3443 3 : tt_assert(!crypto_pk_read_private_key_from_string(sign_skey_1,
3444 : AUTHORITY_SIGNKEY_1, -1));
3445 3 : tt_assert(!crypto_pk_read_private_key_from_string(sign_skey_2,
3446 : AUTHORITY_SIGNKEY_2, -1));
3447 3 : tt_assert(!crypto_pk_read_private_key_from_string(sign_skey_3,
3448 : AUTHORITY_SIGNKEY_3, -1));
3449 :
3450 3 : tt_assert(!crypto_pk_cmp_keys(sign_skey_1, cert1->signing_key));
3451 3 : tt_assert(!crypto_pk_cmp_keys(sign_skey_2, cert2->signing_key));
3452 :
3453 3 : tt_assert(!dir_common_construct_vote_1(&vote, cert1, sign_skey_1, vrs_gen,
3454 : &v1, &n_vrs, now, 1));
3455 3 : tt_assert(v1);
3456 :
3457 : /* Make sure the parsed thing was right. */
3458 3 : tt_int_op(v1->type,OP_EQ, NS_TYPE_VOTE);
3459 3 : tt_int_op(v1->published,OP_EQ, vote->published);
3460 3 : tt_int_op(v1->valid_after,OP_EQ, vote->valid_after);
3461 3 : tt_int_op(v1->fresh_until,OP_EQ, vote->fresh_until);
3462 3 : tt_int_op(v1->valid_until,OP_EQ, vote->valid_until);
3463 3 : tt_int_op(v1->vote_seconds,OP_EQ, vote->vote_seconds);
3464 3 : tt_int_op(v1->dist_seconds,OP_EQ, vote->dist_seconds);
3465 3 : tt_str_op(v1->client_versions,OP_EQ, vote->client_versions);
3466 3 : tt_str_op(v1->server_versions,OP_EQ, vote->server_versions);
3467 3 : tt_assert(v1->voters && smartlist_len(v1->voters));
3468 3 : voter = smartlist_get(v1->voters, 0);
3469 3 : tt_str_op(voter->nickname,OP_EQ, "Voter1");
3470 3 : tt_str_op(voter->address,OP_EQ, "1.2.3.4");
3471 3 : tt_assert(tor_addr_eq_ipv4h(&voter->ipv4_addr, 0x01020304));
3472 3 : tt_int_op(voter->ipv4_dirport,OP_EQ, 80);
3473 3 : tt_int_op(voter->ipv4_orport,OP_EQ, 9000);
3474 3 : tt_str_op(voter->contact,OP_EQ, "voter@example.com");
3475 3 : tt_assert(v1->cert);
3476 3 : tt_assert(!crypto_pk_cmp_keys(sign_skey_1, v1->cert->signing_key));
3477 3 : cp = smartlist_join_strings(v1->known_flags, ":", 0, NULL);
3478 3 : tt_str_op(cp,OP_EQ, "Authority:Exit:Fast:Guard:Running:Stable:V2Dir:Valid");
3479 3 : tor_free(cp);
3480 3 : tt_int_op(smartlist_len(v1->routerstatus_list),OP_EQ, n_vrs);
3481 3 : networkstatus_vote_free(vote);
3482 3 : vote = NULL;
3483 :
3484 3 : if (vote_tweaks) params_tweaked += vote_tweaks(v1, 1, now);
3485 :
3486 : /* Check the routerstatuses. */
3487 15 : for (idx = 0; idx < n_vrs; ++idx) {
3488 12 : vrs = smartlist_get(v1->routerstatus_list, idx);
3489 12 : tt_assert(vrs);
3490 12 : vrs_test(vrs, 1, now);
3491 : }
3492 :
3493 : /* Generate second vote. It disagrees on some of the times,
3494 : * and doesn't list versions, and knows some crazy flags.
3495 : * Generate and parse v2. */
3496 3 : tt_assert(!dir_common_construct_vote_2(&vote, cert2, sign_skey_2, vrs_gen,
3497 : &v2, &n_vrs, now, 1));
3498 3 : tt_assert(v2);
3499 :
3500 3 : if (vote_tweaks) params_tweaked += vote_tweaks(v2, 2, now);
3501 :
3502 : /* Check that flags come out right.*/
3503 3 : cp = smartlist_join_strings(v2->known_flags, ":", 0, NULL);
3504 3 : tt_str_op(cp,OP_EQ, "Authority:Exit:Fast:Guard:MadeOfCheese:MadeOfTin:"
3505 : "Running:Stable:V2Dir:Valid");
3506 3 : tor_free(cp);
3507 :
3508 : /* Check the routerstatuses. */
3509 3 : n_vrs = smartlist_len(v2->routerstatus_list);
3510 14 : for (idx = 0; idx < n_vrs; ++idx) {
3511 11 : vrs = smartlist_get(v2->routerstatus_list, idx);
3512 11 : tt_assert(vrs);
3513 11 : vrs_test(vrs, 2, now);
3514 : }
3515 3 : networkstatus_vote_free(vote);
3516 3 : vote = NULL;
3517 :
3518 : /* Generate the third vote with a legacy id. */
3519 3 : tt_assert(!dir_common_construct_vote_3(&vote, cert3, sign_skey_3, vrs_gen,
3520 : &v3, &n_vrs, now, 1));
3521 3 : tt_assert(v3);
3522 :
3523 3 : if (vote_tweaks) params_tweaked += vote_tweaks(v3, 3, now);
3524 :
3525 : /* Compute a consensus as voter 3. */
3526 3 : smartlist_add(votes, v3);
3527 3 : smartlist_add(votes, v1);
3528 3 : smartlist_add(votes, v2);
3529 3 : consensus_text = networkstatus_compute_consensus(votes, 3,
3530 : cert3->identity_key,
3531 : sign_skey_3,
3532 : "AAAAAAAAAAAAAAAAAAAA",
3533 : sign_skey_leg1,
3534 : FLAV_NS);
3535 3 : tt_assert(consensus_text);
3536 3 : con = networkstatus_parse_vote_from_string_(consensus_text, NULL,
3537 : NS_TYPE_CONSENSUS);
3538 3 : tt_assert(con);
3539 : //log_notice(LD_GENERAL, "<<%s>>\n<<%s>>\n<<%s>>\n",
3540 : // v1_text, v2_text, v3_text);
3541 3 : consensus_text_md = networkstatus_compute_consensus(votes, 3,
3542 : cert3->identity_key,
3543 : sign_skey_3,
3544 : "AAAAAAAAAAAAAAAAAAAA",
3545 : sign_skey_leg1,
3546 : FLAV_MICRODESC);
3547 3 : tt_assert(consensus_text_md);
3548 3 : con_md = networkstatus_parse_vote_from_string_(consensus_text_md, NULL,
3549 : NS_TYPE_CONSENSUS);
3550 3 : tt_assert(con_md);
3551 3 : tt_int_op(con_md->flavor,OP_EQ, FLAV_MICRODESC);
3552 :
3553 : /* Check consensus contents. */
3554 3 : tt_assert(con->type == NS_TYPE_CONSENSUS);
3555 3 : tt_int_op(con->published,OP_EQ, 0); /* this field only appears in votes. */
3556 3 : tt_int_op(con->valid_after,OP_EQ, now+1000);
3557 3 : tt_int_op(con->fresh_until,OP_EQ, now+2003); /* median */
3558 3 : tt_int_op(con->valid_until,OP_EQ, now+3000);
3559 3 : tt_int_op(con->vote_seconds,OP_EQ, 100);
3560 3 : tt_int_op(con->dist_seconds,OP_EQ, 250); /* median */
3561 3 : tt_str_op(con->client_versions,OP_EQ, "0.1.2.14");
3562 3 : tt_str_op(con->server_versions,OP_EQ, "0.1.2.15,0.1.2.16");
3563 3 : cp = smartlist_join_strings(v2->known_flags, ":", 0, NULL);
3564 3 : tt_str_op(cp,OP_EQ, "Authority:Exit:Fast:Guard:MadeOfCheese:MadeOfTin:"
3565 : "Running:Stable:V2Dir:Valid");
3566 3 : tor_free(cp);
3567 3 : if (!params_tweaked) {
3568 : /* Skip this one if vote_tweaks() messed with the param lists */
3569 2 : cp = smartlist_join_strings(con->net_params, ":", 0, NULL);
3570 2 : tt_str_op(cp,OP_EQ, "circuitwindow=80:foo=660");
3571 2 : tor_free(cp);
3572 : }
3573 :
3574 3 : tt_int_op(4,OP_EQ, smartlist_len(con->voters)); /*3 voters, 1 legacy key.*/
3575 : /* The voter id digests should be in this order. */
3576 3 : tt_assert(fast_memcmp(cert2->cache_info.identity_digest,
3577 : cert1->cache_info.identity_digest,DIGEST_LEN)<0);
3578 3 : tt_assert(fast_memcmp(cert1->cache_info.identity_digest,
3579 : cert3->cache_info.identity_digest,DIGEST_LEN)<0);
3580 3 : test_same_voter(smartlist_get(con->voters, 1),
3581 3 : smartlist_get(v2->voters, 0));
3582 3 : test_same_voter(smartlist_get(con->voters, 2),
3583 3 : smartlist_get(v1->voters, 0));
3584 3 : test_same_voter(smartlist_get(con->voters, 3),
3585 3 : smartlist_get(v3->voters, 0));
3586 :
3587 3 : consensus_test(con, now);
3588 :
3589 : /* Check the routerstatuses. */
3590 3 : n_rs = smartlist_len(con->routerstatus_list);
3591 3 : tt_assert(n_rs);
3592 13 : for (idx = 0; idx < n_rs; ++idx) {
3593 10 : rs = smartlist_get(con->routerstatus_list, idx);
3594 10 : tt_assert(rs);
3595 10 : rs_test(rs, now);
3596 : }
3597 :
3598 3 : n_rs = smartlist_len(con_md->routerstatus_list);
3599 3 : tt_assert(n_rs);
3600 13 : for (idx = 0; idx < n_rs; ++idx) {
3601 10 : rs = smartlist_get(con_md->routerstatus_list, idx);
3602 10 : tt_assert(rs);
3603 : }
3604 :
3605 : /* Check signatures. the first voter is a pseudo-entry with a legacy key.
3606 : * The second one hasn't signed. The fourth one has signed: validate it. */
3607 3 : voter = smartlist_get(con->voters, 1);
3608 3 : tt_int_op(smartlist_len(voter->sigs),OP_EQ, 0);
3609 :
3610 3 : voter = smartlist_get(con->voters, 3);
3611 3 : tt_int_op(smartlist_len(voter->sigs),OP_EQ, 1);
3612 3 : sig = smartlist_get(voter->sigs, 0);
3613 3 : tt_assert(sig->signature);
3614 3 : tt_assert(!sig->good_signature);
3615 3 : tt_assert(!sig->bad_signature);
3616 :
3617 3 : tt_assert(!networkstatus_check_document_signature(con, sig, cert3));
3618 3 : tt_assert(sig->signature);
3619 3 : tt_assert(sig->good_signature);
3620 3 : tt_assert(!sig->bad_signature);
3621 :
3622 : {
3623 3 : const char *msg=NULL;
3624 : /* Compute the other two signed consensuses. */
3625 3 : smartlist_shuffle(votes);
3626 3 : consensus_text2 = networkstatus_compute_consensus(votes, 3,
3627 : cert2->identity_key,
3628 : sign_skey_2, NULL,NULL,
3629 : FLAV_NS);
3630 3 : consensus_text_md2 = networkstatus_compute_consensus(votes, 3,
3631 : cert2->identity_key,
3632 : sign_skey_2, NULL,NULL,
3633 : FLAV_MICRODESC);
3634 3 : smartlist_shuffle(votes);
3635 3 : consensus_text3 = networkstatus_compute_consensus(votes, 3,
3636 : cert1->identity_key,
3637 : sign_skey_1, NULL,NULL,
3638 : FLAV_NS);
3639 3 : consensus_text_md3 = networkstatus_compute_consensus(votes, 3,
3640 : cert1->identity_key,
3641 : sign_skey_1, NULL,NULL,
3642 : FLAV_MICRODESC);
3643 3 : tt_assert(consensus_text2);
3644 3 : tt_assert(consensus_text3);
3645 3 : tt_assert(consensus_text_md2);
3646 3 : tt_assert(consensus_text_md3);
3647 3 : con2 = networkstatus_parse_vote_from_string_(consensus_text2, NULL,
3648 : NS_TYPE_CONSENSUS);
3649 3 : con3 = networkstatus_parse_vote_from_string_(consensus_text3, NULL,
3650 : NS_TYPE_CONSENSUS);
3651 3 : con_md2 = networkstatus_parse_vote_from_string_(consensus_text_md2, NULL,
3652 : NS_TYPE_CONSENSUS);
3653 3 : con_md3 = networkstatus_parse_vote_from_string_(consensus_text_md3, NULL,
3654 : NS_TYPE_CONSENSUS);
3655 3 : tt_assert(con2);
3656 3 : tt_assert(con3);
3657 3 : tt_assert(con_md2);
3658 3 : tt_assert(con_md3);
3659 :
3660 : /* All three should have the same digest. */
3661 3 : tt_mem_op(&con->digests,OP_EQ, &con2->digests, sizeof(common_digests_t));
3662 3 : tt_mem_op(&con->digests,OP_EQ, &con3->digests, sizeof(common_digests_t));
3663 :
3664 3 : tt_mem_op(&con_md->digests,OP_EQ, &con_md2->digests,
3665 3 : sizeof(common_digests_t));
3666 3 : tt_mem_op(&con_md->digests,OP_EQ, &con_md3->digests,
3667 3 : sizeof(common_digests_t));
3668 :
3669 : /* Extract a detached signature from con3. */
3670 3 : detached_text1 = get_detached_sigs(con3, con_md3);
3671 3 : tt_assert(detached_text1);
3672 : /* Try to parse it. */
3673 3 : dsig1 = networkstatus_parse_detached_signatures(detached_text1, NULL);
3674 3 : tt_assert(dsig1);
3675 :
3676 : /* Are parsed values as expected? */
3677 3 : tt_int_op(dsig1->valid_after,OP_EQ, con3->valid_after);
3678 3 : tt_int_op(dsig1->fresh_until,OP_EQ, con3->fresh_until);
3679 3 : tt_int_op(dsig1->valid_until,OP_EQ, con3->valid_until);
3680 : {
3681 3 : common_digests_t *dsig_digests = strmap_get(dsig1->digests, "ns");
3682 3 : tt_assert(dsig_digests);
3683 3 : tt_mem_op(dsig_digests->d[DIGEST_SHA1], OP_EQ,
3684 3 : con3->digests.d[DIGEST_SHA1], DIGEST_LEN);
3685 3 : dsig_digests = strmap_get(dsig1->digests, "microdesc");
3686 3 : tt_assert(dsig_digests);
3687 3 : tt_mem_op(dsig_digests->d[DIGEST_SHA256],OP_EQ,
3688 : con_md3->digests.d[DIGEST_SHA256],
3689 3 : DIGEST256_LEN);
3690 : }
3691 : {
3692 3 : smartlist_t *dsig_signatures = strmap_get(dsig1->signatures, "ns");
3693 3 : tt_assert(dsig_signatures);
3694 3 : tt_int_op(1,OP_EQ, smartlist_len(dsig_signatures));
3695 3 : sig = smartlist_get(dsig_signatures, 0);
3696 3 : tt_mem_op(sig->identity_digest,OP_EQ, cert1->cache_info.identity_digest,
3697 3 : DIGEST_LEN);
3698 3 : tt_int_op(sig->alg,OP_EQ, DIGEST_SHA1);
3699 :
3700 3 : dsig_signatures = strmap_get(dsig1->signatures, "microdesc");
3701 3 : tt_assert(dsig_signatures);
3702 3 : tt_int_op(1,OP_EQ, smartlist_len(dsig_signatures));
3703 3 : sig = smartlist_get(dsig_signatures, 0);
3704 3 : tt_mem_op(sig->identity_digest,OP_EQ, cert1->cache_info.identity_digest,
3705 3 : DIGEST_LEN);
3706 3 : tt_int_op(sig->alg,OP_EQ, DIGEST_SHA256);
3707 : }
3708 :
3709 : /* Try adding it to con2. */
3710 3 : detached_text2 = get_detached_sigs(con2,con_md2);
3711 3 : tt_int_op(1,OP_EQ, networkstatus_add_detached_signatures(con2, dsig1,
3712 : "test", LOG_INFO, &msg));
3713 3 : tor_free(detached_text2);
3714 3 : tt_int_op(1,OP_EQ,
3715 : networkstatus_add_detached_signatures(con_md2, dsig1, "test",
3716 : LOG_INFO, &msg));
3717 3 : tor_free(detached_text2);
3718 3 : detached_text2 = get_detached_sigs(con2,con_md2);
3719 : //printf("\n<%s>\n", detached_text2);
3720 3 : dsig2 = networkstatus_parse_detached_signatures(detached_text2, NULL);
3721 3 : tt_assert(dsig2);
3722 : /*
3723 : printf("\n");
3724 : SMARTLIST_FOREACH(dsig2->signatures, networkstatus_voter_info_t *, vi, {
3725 : char hd[64];
3726 : base16_encode(hd, sizeof(hd), vi->identity_digest, DIGEST_LEN);
3727 : printf("%s\n", hd);
3728 : });
3729 : */
3730 3 : tt_int_op(2,OP_EQ,
3731 : smartlist_len((smartlist_t*)strmap_get(dsig2->signatures, "ns")));
3732 3 : tt_int_op(2,OP_EQ,
3733 : smartlist_len((smartlist_t*)strmap_get(dsig2->signatures,
3734 : "microdesc")));
3735 :
3736 : /* Try adding to con2 twice; verify that nothing changes. */
3737 3 : tt_int_op(0,OP_EQ, networkstatus_add_detached_signatures(con2, dsig1,
3738 : "test", LOG_INFO, &msg));
3739 :
3740 : /* Add to con. */
3741 3 : tt_int_op(2,OP_EQ, networkstatus_add_detached_signatures(con, dsig2,
3742 : "test", LOG_INFO, &msg));
3743 : /* Check signatures */
3744 3 : voter = smartlist_get(con->voters, 1);
3745 3 : sig = smartlist_get(voter->sigs, 0);
3746 3 : tt_assert(sig);
3747 3 : tt_assert(!networkstatus_check_document_signature(con, sig, cert2));
3748 3 : voter = smartlist_get(con->voters, 2);
3749 3 : sig = smartlist_get(voter->sigs, 0);
3750 3 : tt_assert(sig);
3751 3 : tt_assert(!networkstatus_check_document_signature(con, sig, cert1));
3752 : }
3753 :
3754 3 : done:
3755 3 : tor_free(cp);
3756 3 : smartlist_free(votes);
3757 3 : tor_free(consensus_text);
3758 3 : tor_free(consensus_text_md);
3759 :
3760 3 : networkstatus_vote_free(vote);
3761 3 : networkstatus_vote_free(v1);
3762 3 : networkstatus_vote_free(v2);
3763 3 : networkstatus_vote_free(v3);
3764 3 : networkstatus_vote_free(con);
3765 3 : networkstatus_vote_free(con_md);
3766 3 : crypto_pk_free(sign_skey_1);
3767 3 : crypto_pk_free(sign_skey_2);
3768 3 : crypto_pk_free(sign_skey_3);
3769 3 : crypto_pk_free(sign_skey_leg1);
3770 3 : authority_cert_free(cert1);
3771 3 : authority_cert_free(cert2);
3772 3 : authority_cert_free(cert3);
3773 :
3774 3 : tor_free(consensus_text2);
3775 3 : tor_free(consensus_text3);
3776 3 : tor_free(consensus_text_md2);
3777 3 : tor_free(consensus_text_md3);
3778 3 : tor_free(detached_text1);
3779 3 : tor_free(detached_text2);
3780 :
3781 3 : networkstatus_vote_free(con2);
3782 3 : networkstatus_vote_free(con3);
3783 3 : networkstatus_vote_free(con_md2);
3784 3 : networkstatus_vote_free(con_md3);
3785 3 : ns_detached_signatures_free(dsig1);
3786 3 : ns_detached_signatures_free(dsig2);
3787 3 : }
3788 :
3789 : /** Run unit tests for generating and parsing V3 consensus networkstatus
3790 : * documents. */
3791 : static void
3792 1 : test_dir_v3_networkstatus(void *arg)
3793 : {
3794 1 : (void)arg;
3795 1 : test_a_networkstatus(dir_common_gen_routerstatus_for_v3ns,
3796 : vote_tweaks_for_v3ns,
3797 : test_vrs_for_v3ns,
3798 : test_consensus_for_v3ns,
3799 : test_routerstatus_for_v3ns);
3800 1 : }
3801 :
3802 : static void
3803 1 : test_dir_scale_bw(void *testdata)
3804 : {
3805 1 : double v[8] = { 2.0/3,
3806 : 7.0,
3807 : 1.0,
3808 : 3.0,
3809 : 1.0/5,
3810 : 1.0/7,
3811 : 12.0,
3812 : 24.0 };
3813 1 : double vals_dbl[8];
3814 1 : uint64_t vals_u64[8];
3815 1 : uint64_t total;
3816 1 : int i;
3817 :
3818 1 : (void) testdata;
3819 :
3820 9 : for (i=0; i<8; ++i)
3821 8 : vals_dbl[i] = v[i];
3822 :
3823 1 : scale_array_elements_to_u64(vals_u64, vals_dbl, 8, &total);
3824 :
3825 1 : tt_int_op((int)total, OP_EQ, 48);
3826 1 : total = 0;
3827 9 : for (i=0; i<8; ++i) {
3828 8 : total += vals_u64[i];
3829 : }
3830 1 : tt_assert(total >= (UINT64_C(1)<<60));
3831 1 : tt_assert(total <= (UINT64_C(1)<<62));
3832 :
3833 9 : for (i=0; i<8; ++i) {
3834 : /* vals[2].u64 is the scaled value of 1.0 */
3835 8 : double ratio = ((double)vals_u64[i]) / vals_u64[2];
3836 8 : tt_double_op(fabs(ratio - v[i]), OP_LT, .00001);
3837 : }
3838 :
3839 : /* test handling of no entries */
3840 1 : total = 1;
3841 1 : scale_array_elements_to_u64(vals_u64, vals_dbl, 0, &total);
3842 1 : tt_assert(total == 0);
3843 :
3844 : /* make sure we don't read the array when we have no entries
3845 : * may require compiler flags to catch NULL dereferences */
3846 1 : total = 1;
3847 1 : scale_array_elements_to_u64(NULL, NULL, 0, &total);
3848 1 : tt_assert(total == 0);
3849 :
3850 1 : scale_array_elements_to_u64(NULL, NULL, 0, NULL);
3851 :
3852 : /* test handling of zero totals */
3853 1 : total = 1;
3854 1 : vals_dbl[0] = 0.0;
3855 1 : scale_array_elements_to_u64(vals_u64, vals_dbl, 1, &total);
3856 1 : tt_assert(total == 0);
3857 1 : tt_assert(vals_u64[0] == 0);
3858 :
3859 1 : vals_dbl[0] = 0.0;
3860 1 : vals_dbl[1] = 0.0;
3861 1 : scale_array_elements_to_u64(vals_u64, vals_dbl, 2, NULL);
3862 1 : tt_assert(vals_u64[0] == 0);
3863 1 : tt_assert(vals_u64[1] == 0);
3864 :
3865 1 : done:
3866 1 : ;
3867 1 : }
3868 :
3869 : static void
3870 1 : test_dir_random_weighted(void *testdata)
3871 : {
3872 1 : int histogram[10];
3873 1 : uint64_t vals[10] = {3,1,2,4,6,0,7,5,8,9}, total=0;
3874 1 : uint64_t inp_u64[10];
3875 1 : int i, choice;
3876 1 : const int n = 50000;
3877 1 : double max_sq_error;
3878 1 : (void) testdata;
3879 :
3880 : /* Try a ten-element array with values from 0 through 10. The values are
3881 : * in a scrambled order to make sure we don't depend on order. */
3882 1 : memset(histogram,0,sizeof(histogram));
3883 11 : for (i=0; i<10; ++i) {
3884 10 : inp_u64[i] = vals[i];
3885 10 : total += vals[i];
3886 : }
3887 1 : tt_u64_op(total, OP_EQ, 45);
3888 50001 : for (i=0; i<n; ++i) {
3889 50000 : choice = choose_array_element_by_weight(inp_u64, 10);
3890 50000 : tt_int_op(choice, OP_GE, 0);
3891 50000 : tt_int_op(choice, OP_LT, 10);
3892 50000 : histogram[choice]++;
3893 : }
3894 :
3895 : /* Now see if we chose things about frequently enough. */
3896 : max_sq_error = 0;
3897 11 : for (i=0; i<10; ++i) {
3898 10 : int expected = (int)(n*vals[i]/total);
3899 10 : double frac_diff = 0, sq;
3900 10 : TT_BLATHER((" %d : %5d vs %5d\n", (int)vals[i], histogram[i], expected));
3901 10 : if (expected)
3902 9 : frac_diff = (histogram[i] - expected) / ((double)expected);
3903 : else
3904 1 : tt_int_op(histogram[i], OP_EQ, 0);
3905 :
3906 10 : sq = frac_diff * frac_diff;
3907 10 : if (sq > max_sq_error)
3908 2 : max_sq_error = sq;
3909 : }
3910 : /* It should almost always be much much less than this. If you want to
3911 : * figure out the odds, please feel free. */
3912 1 : tt_double_op(max_sq_error, OP_LT, .05);
3913 :
3914 : /* Now try a singleton; do we choose it? */
3915 101 : for (i = 0; i < 100; ++i) {
3916 100 : choice = choose_array_element_by_weight(inp_u64, 1);
3917 100 : tt_int_op(choice, OP_EQ, 0);
3918 : }
3919 :
3920 : /* Now try an array of zeros. We should choose randomly. */
3921 1 : memset(histogram,0,sizeof(histogram));
3922 6 : for (i = 0; i < 5; ++i)
3923 5 : inp_u64[i] = 0;
3924 50001 : for (i = 0; i < n; ++i) {
3925 50000 : choice = choose_array_element_by_weight(inp_u64, 5);
3926 50000 : tt_int_op(choice, OP_GE, 0);
3927 50000 : tt_int_op(choice, OP_LT, 5);
3928 50000 : histogram[choice]++;
3929 : }
3930 : /* Now see if we chose things about frequently enough. */
3931 : max_sq_error = 0;
3932 6 : for (i=0; i<5; ++i) {
3933 5 : int expected = n/5;
3934 5 : double frac_diff = 0, sq;
3935 5 : TT_BLATHER((" %d : %5d vs %5d\n", (int)vals[i], histogram[i], expected));
3936 5 : frac_diff = (histogram[i] - expected) / ((double)expected);
3937 5 : sq = frac_diff * frac_diff;
3938 5 : if (sq > max_sq_error)
3939 3 : max_sq_error = sq;
3940 : }
3941 : /* It should almost always be much much less than this. If you want to
3942 : * figure out the odds, please feel free. */
3943 1 : tt_double_op(max_sq_error, OP_LT, .05);
3944 1 : done:
3945 1 : ;
3946 1 : }
3947 :
3948 : /* Function pointers for test_dir_clip_unmeasured_bw_kb() */
3949 :
3950 : static uint32_t alternate_clip_bw = 0;
3951 :
3952 : /**
3953 : * Generate a routerstatus for clip_unmeasured_bw_kb test; based on the
3954 : * v3_networkstatus ones.
3955 : */
3956 : static vote_routerstatus_t *
3957 30 : gen_routerstatus_for_umbw(int idx, time_t now)
3958 : {
3959 30 : vote_routerstatus_t *vrs = NULL;
3960 30 : routerstatus_t *rs;
3961 30 : tor_addr_t addr_ipv6;
3962 60 : uint32_t max_unmeasured_bw_kb = (alternate_clip_bw > 0) ?
3963 30 : alternate_clip_bw : DEFAULT_MAX_UNMEASURED_BW_KB;
3964 :
3965 30 : switch (idx) {
3966 6 : case 0:
3967 : /* Generate the first routerstatus. */
3968 6 : vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
3969 6 : rs = &vrs->status;
3970 6 : vrs->version = tor_strdup("0.1.2.14");
3971 6 : rs->published_on = now-1500;
3972 6 : strlcpy(rs->nickname, "router2", sizeof(rs->nickname));
3973 6 : memset(rs->identity_digest, 3, DIGEST_LEN);
3974 6 : memset(rs->descriptor_digest, 78, DIGEST_LEN);
3975 6 : tor_addr_from_ipv4h(&rs->ipv4_addr, 0x99008801);
3976 6 : rs->ipv4_orport = 443;
3977 6 : rs->ipv4_dirport = 8000;
3978 : /* all flags but running and valid cleared */
3979 6 : rs->is_flagged_running = 1;
3980 6 : rs->is_valid = 1;
3981 : /*
3982 : * This one has measured bandwidth below the clip cutoff, and
3983 : * so shouldn't be clipped; we'll have to test that it isn't
3984 : * later.
3985 : */
3986 6 : vrs->has_measured_bw = 1;
3987 6 : rs->has_bandwidth = 1;
3988 6 : vrs->measured_bw_kb = rs->bandwidth_kb = max_unmeasured_bw_kb / 2;
3989 6 : vrs->protocols = tor_strdup("Link=2 Wombat=40");
3990 6 : break;
3991 6 : case 1:
3992 : /* Generate the second routerstatus. */
3993 6 : vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
3994 6 : rs = &vrs->status;
3995 6 : vrs->version = tor_strdup("0.2.0.5");
3996 6 : rs->published_on = now-1000;
3997 6 : strlcpy(rs->nickname, "router1", sizeof(rs->nickname));
3998 6 : memset(rs->identity_digest, 5, DIGEST_LEN);
3999 6 : memset(rs->descriptor_digest, 77, DIGEST_LEN);
4000 6 : tor_addr_from_ipv4h(&rs->ipv4_addr, 0x99009901);
4001 6 : rs->ipv4_orport = 443;
4002 6 : rs->ipv4_dirport = 0;
4003 6 : tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
4004 6 : tor_addr_copy(&rs->ipv6_addr, &addr_ipv6);
4005 6 : rs->ipv6_orport = 4711;
4006 6 : rs->is_exit = rs->is_stable = rs->is_fast = rs->is_flagged_running =
4007 6 : rs->is_valid = rs->is_possible_guard = 1;
4008 : /*
4009 : * This one has measured bandwidth above the clip cutoff, and
4010 : * so shouldn't be clipped; we'll have to test that it isn't
4011 : * later.
4012 : */
4013 6 : vrs->has_measured_bw = 1;
4014 6 : rs->has_bandwidth = 1;
4015 6 : vrs->measured_bw_kb = rs->bandwidth_kb = 2 * max_unmeasured_bw_kb;
4016 6 : vrs->protocols = tor_strdup("Link=2 Wombat=40");
4017 6 : break;
4018 6 : case 2:
4019 : /* Generate the third routerstatus. */
4020 6 : vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
4021 6 : rs = &vrs->status;
4022 6 : vrs->version = tor_strdup("0.1.0.3");
4023 6 : rs->published_on = now-1000;
4024 6 : strlcpy(rs->nickname, "router3", sizeof(rs->nickname));
4025 6 : memset(rs->identity_digest, 0x33, DIGEST_LEN);
4026 6 : memset(rs->descriptor_digest, 79, DIGEST_LEN);
4027 6 : tor_addr_from_ipv4h(&rs->ipv4_addr, 0xAA009901);
4028 6 : rs->ipv4_orport = 400;
4029 6 : rs->ipv4_dirport = 9999;
4030 6 : rs->is_authority = rs->is_exit = rs->is_stable = rs->is_fast =
4031 6 : rs->is_flagged_running = rs->is_valid =
4032 6 : rs->is_possible_guard = 1;
4033 : /*
4034 : * This one has unmeasured bandwidth above the clip cutoff, and
4035 : * so should be clipped; we'll have to test that it isn't
4036 : * later.
4037 : */
4038 6 : vrs->has_measured_bw = 0;
4039 6 : rs->has_bandwidth = 1;
4040 6 : vrs->measured_bw_kb = 0;
4041 6 : rs->bandwidth_kb = 2 * max_unmeasured_bw_kb;
4042 6 : vrs->protocols = tor_strdup("Link=2 Wombat=40");
4043 6 : break;
4044 6 : case 3:
4045 : /* Generate a fourth routerstatus that is not running. */
4046 6 : vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
4047 6 : rs = &vrs->status;
4048 6 : vrs->version = tor_strdup("0.1.6.3");
4049 6 : rs->published_on = now-1000;
4050 6 : strlcpy(rs->nickname, "router4", sizeof(rs->nickname));
4051 6 : memset(rs->identity_digest, 0x34, DIGEST_LEN);
4052 6 : memset(rs->descriptor_digest, 47, DIGEST_LEN);
4053 6 : tor_addr_from_ipv4h(&rs->ipv4_addr, 0xC0000203);
4054 6 : rs->ipv4_orport = 500;
4055 6 : rs->ipv4_dirport = 1999;
4056 : /* all flags but running and valid cleared */
4057 6 : rs->is_flagged_running = 1;
4058 6 : rs->is_valid = 1;
4059 : /*
4060 : * This one has unmeasured bandwidth below the clip cutoff, and
4061 : * so shouldn't be clipped; we'll have to test that it isn't
4062 : * later.
4063 : */
4064 6 : vrs->has_measured_bw = 0;
4065 6 : rs->has_bandwidth = 1;
4066 6 : vrs->measured_bw_kb = 0;
4067 6 : rs->bandwidth_kb = max_unmeasured_bw_kb / 2;
4068 6 : vrs->protocols = tor_strdup("Link=2 Wombat=40");
4069 6 : break;
4070 : case 4:
4071 : /* No more for this test; return NULL */
4072 : vrs = NULL;
4073 : break;
4074 0 : default:
4075 : /* Shouldn't happen */
4076 0 : tt_abort();
4077 : }
4078 24 : if (vrs) {
4079 24 : vrs->microdesc = tor_malloc_zero(sizeof(vote_microdesc_hash_t));
4080 24 : tor_asprintf(&vrs->microdesc->microdesc_hash_line,
4081 : "m 25,26,27,28 "
4082 : "sha256=xyzajkldsdsajdadlsdjaslsdksdjlsdjsdaskdaaa%d\n",
4083 : idx);
4084 : }
4085 :
4086 30 : done:
4087 30 : return vrs;
4088 : }
4089 :
4090 : /** Apply tweaks to the vote list for each voter; for the umbw test this is
4091 : * just adding the right consensus methods to let clipping happen */
4092 : static int
4093 6 : vote_tweaks_for_umbw(networkstatus_t *v, int voter, time_t now)
4094 : {
4095 6 : char *maxbw_param = NULL;
4096 6 : int rv = 0;
4097 :
4098 6 : tt_assert(v);
4099 6 : (void)voter;
4100 6 : (void)now;
4101 :
4102 6 : tt_assert(v->supported_methods);
4103 30 : SMARTLIST_FOREACH(v->supported_methods, char *, c, tor_free(c));
4104 6 : smartlist_clear(v->supported_methods);
4105 : /* Method 17 is MIN_METHOD_TO_CLIP_UNMEASURED_BW_KB */
4106 6 : smartlist_split_string(v->supported_methods,
4107 : "25 26 27 28",
4108 : NULL, 0, -1);
4109 : /* If we're using a non-default clip bandwidth, add it to net_params */
4110 6 : if (alternate_clip_bw > 0) {
4111 3 : tor_asprintf(&maxbw_param, "maxunmeasuredbw=%u", alternate_clip_bw);
4112 3 : tt_assert(maxbw_param);
4113 3 : if (maxbw_param) {
4114 3 : smartlist_add(v->net_params, maxbw_param);
4115 3 : rv = 1;
4116 : }
4117 : }
4118 :
4119 3 : done:
4120 6 : return rv;
4121 : }
4122 :
4123 : /**
4124 : * Test a parsed vote_routerstatus_t for umbw test.
4125 : */
4126 : static void
4127 16 : test_vrs_for_umbw(vote_routerstatus_t *vrs, int voter, time_t now)
4128 : {
4129 16 : routerstatus_t *rs;
4130 16 : tor_addr_t addr_ipv6;
4131 32 : uint32_t max_unmeasured_bw_kb = (alternate_clip_bw > 0) ?
4132 16 : alternate_clip_bw : DEFAULT_MAX_UNMEASURED_BW_KB;
4133 :
4134 16 : (void)voter;
4135 16 : tt_assert(vrs);
4136 16 : rs = &(vrs->status);
4137 16 : tt_assert(rs);
4138 :
4139 : /* Split out by digests to test */
4140 16 : if (tor_memeq(rs->identity_digest,
4141 : "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
4142 : "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
4143 : DIGEST_LEN)) {
4144 : /*
4145 : * Check the first routerstatus - measured bandwidth below the clip
4146 : * cutoff.
4147 : */
4148 4 : tt_str_op(vrs->version,OP_EQ, "0.1.2.14");
4149 4 : tt_int_op(rs->published_on,OP_EQ, now-1500);
4150 4 : tt_str_op(rs->nickname,OP_EQ, "router2");
4151 4 : tt_mem_op(rs->identity_digest,OP_EQ,
4152 : "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
4153 : "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
4154 4 : DIGEST_LEN);
4155 4 : tt_mem_op(rs->descriptor_digest,OP_EQ, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
4156 4 : tt_assert(tor_addr_eq_ipv4h(&rs->ipv4_addr, 0x99008801));
4157 4 : tt_int_op(rs->ipv4_orport,OP_EQ, 443);
4158 4 : tt_int_op(rs->ipv4_dirport,OP_EQ, 8000);
4159 4 : tt_assert(rs->has_bandwidth);
4160 4 : tt_assert(vrs->has_measured_bw);
4161 4 : tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb / 2);
4162 4 : tt_int_op(vrs->measured_bw_kb,OP_EQ, max_unmeasured_bw_kb / 2);
4163 12 : } else if (tor_memeq(rs->identity_digest,
4164 : "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
4165 : "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
4166 : DIGEST_LEN)) {
4167 :
4168 : /*
4169 : * Check the second routerstatus - measured bandwidth above the clip
4170 : * cutoff.
4171 : */
4172 4 : tt_str_op(vrs->version,OP_EQ, "0.2.0.5");
4173 4 : tt_int_op(rs->published_on,OP_EQ, now-1000);
4174 4 : tt_str_op(rs->nickname,OP_EQ, "router1");
4175 4 : tt_mem_op(rs->identity_digest,OP_EQ,
4176 : "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
4177 : "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
4178 4 : DIGEST_LEN);
4179 4 : tt_mem_op(rs->descriptor_digest,OP_EQ, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
4180 4 : tt_assert(tor_addr_eq_ipv4h(&rs->ipv4_addr, 0x99009901));
4181 4 : tt_int_op(rs->ipv4_orport,OP_EQ, 443);
4182 4 : tt_int_op(rs->ipv4_dirport,OP_EQ, 0);
4183 4 : tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
4184 4 : tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
4185 4 : tt_int_op(rs->ipv6_orport,OP_EQ, 4711);
4186 4 : tt_assert(rs->has_bandwidth);
4187 4 : tt_assert(vrs->has_measured_bw);
4188 4 : tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb * 2);
4189 4 : tt_int_op(vrs->measured_bw_kb,OP_EQ, max_unmeasured_bw_kb * 2);
4190 8 : } else if (tor_memeq(rs->identity_digest,
4191 : "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33"
4192 : "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33",
4193 : DIGEST_LEN)) {
4194 : /*
4195 : * Check the third routerstatus - unmeasured bandwidth above the clip
4196 : * cutoff; this one should be clipped later on in the consensus, but
4197 : * appears unclipped in the vote.
4198 : */
4199 4 : tt_assert(rs->has_bandwidth);
4200 4 : tt_assert(!(vrs->has_measured_bw));
4201 4 : tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb * 2);
4202 4 : tt_int_op(vrs->measured_bw_kb,OP_EQ, 0);
4203 4 : } else if (tor_memeq(rs->identity_digest,
4204 : "\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34"
4205 : "\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34",
4206 : DIGEST_LEN)) {
4207 : /*
4208 : * Check the fourth routerstatus - unmeasured bandwidth below the clip
4209 : * cutoff; this one should not be clipped.
4210 : */
4211 4 : tt_assert(rs->has_bandwidth);
4212 4 : tt_assert(!(vrs->has_measured_bw));
4213 4 : tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb / 2);
4214 4 : tt_int_op(vrs->measured_bw_kb,OP_EQ, 0);
4215 : } else {
4216 0 : tt_abort();
4217 : }
4218 :
4219 16 : done:
4220 16 : return;
4221 : }
4222 :
4223 : /**
4224 : * Test a consensus for v3_networkstatus_test
4225 : */
4226 : static void
4227 2 : test_consensus_for_umbw(networkstatus_t *con, time_t now)
4228 : {
4229 2 : (void)now;
4230 :
4231 2 : tt_assert(con);
4232 2 : tt_ptr_op(con->cert, OP_EQ, NULL);
4233 : // tt_assert(con->consensus_method >= MIN_METHOD_TO_CLIP_UNMEASURED_BW_KB);
4234 2 : tt_int_op(con->consensus_method, OP_GE, 16);
4235 2 : tt_int_op(4,OP_EQ, smartlist_len(con->routerstatus_list));
4236 : /* There should be four listed routers; all voters saw the same in this */
4237 :
4238 2 : done:
4239 2 : return;
4240 : }
4241 :
4242 : /**
4243 : * Test a router list entry for umbw test
4244 : */
4245 : static void
4246 8 : test_routerstatus_for_umbw(routerstatus_t *rs, time_t now)
4247 : {
4248 8 : tor_addr_t addr_ipv6;
4249 16 : uint32_t max_unmeasured_bw_kb = (alternate_clip_bw > 0) ?
4250 8 : alternate_clip_bw : DEFAULT_MAX_UNMEASURED_BW_KB;
4251 :
4252 8 : tt_assert(rs);
4253 :
4254 : /* There should be four listed routers, as constructed above */
4255 8 : if (tor_memeq(rs->identity_digest,
4256 : "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
4257 : "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
4258 : DIGEST_LEN)) {
4259 2 : tt_mem_op(rs->identity_digest,OP_EQ,
4260 : "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
4261 : "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
4262 2 : DIGEST_LEN);
4263 2 : tt_mem_op(rs->descriptor_digest,OP_EQ, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
4264 2 : tt_assert(!rs->is_authority);
4265 2 : tt_assert(!rs->is_exit);
4266 2 : tt_assert(!rs->is_fast);
4267 2 : tt_assert(!rs->is_possible_guard);
4268 2 : tt_assert(!rs->is_stable);
4269 : /* (If it wasn't running and valid it wouldn't be here) */
4270 2 : tt_assert(rs->is_flagged_running);
4271 2 : tt_assert(rs->is_valid);
4272 2 : tt_assert(!rs->is_named);
4273 : /* This one should have measured bandwidth below the clip cutoff */
4274 2 : tt_assert(rs->has_bandwidth);
4275 2 : tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb / 2);
4276 2 : tt_assert(!(rs->bw_is_unmeasured));
4277 6 : } else if (tor_memeq(rs->identity_digest,
4278 : "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
4279 : "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
4280 : DIGEST_LEN)) {
4281 : /* This one showed up in 3 digests. Twice with ID 'M', once with 'Z'. */
4282 2 : tt_mem_op(rs->identity_digest,OP_EQ,
4283 : "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
4284 : "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
4285 2 : DIGEST_LEN);
4286 2 : tt_str_op(rs->nickname,OP_EQ, "router1");
4287 2 : tt_mem_op(rs->descriptor_digest,OP_EQ, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
4288 2 : tt_int_op(rs->published_on,OP_EQ, now-1000);
4289 2 : tt_assert(tor_addr_eq_ipv4h(&rs->ipv4_addr, 0x99009901));
4290 2 : tt_int_op(rs->ipv4_orport,OP_EQ, 443);
4291 2 : tt_int_op(rs->ipv4_dirport,OP_EQ, 0);
4292 2 : tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
4293 2 : tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
4294 2 : tt_int_op(rs->ipv6_orport,OP_EQ, 4711);
4295 2 : tt_assert(!rs->is_authority);
4296 2 : tt_assert(rs->is_exit);
4297 2 : tt_assert(rs->is_fast);
4298 2 : tt_assert(rs->is_possible_guard);
4299 2 : tt_assert(rs->is_stable);
4300 2 : tt_assert(rs->is_flagged_running);
4301 2 : tt_assert(rs->is_valid);
4302 2 : tt_assert(!rs->is_named);
4303 : /* This one should have measured bandwidth above the clip cutoff */
4304 2 : tt_assert(rs->has_bandwidth);
4305 2 : tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb * 2);
4306 2 : tt_assert(!(rs->bw_is_unmeasured));
4307 4 : } else if (tor_memeq(rs->identity_digest,
4308 : "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33"
4309 : "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33",
4310 : DIGEST_LEN)) {
4311 : /*
4312 : * This one should have unmeasured bandwidth above the clip cutoff,
4313 : * and so should be clipped
4314 : */
4315 2 : tt_assert(rs->has_bandwidth);
4316 2 : tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb);
4317 2 : tt_assert(rs->bw_is_unmeasured);
4318 2 : } else if (tor_memeq(rs->identity_digest,
4319 : "\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34"
4320 : "\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34",
4321 : DIGEST_LEN)) {
4322 : /*
4323 : * This one should have unmeasured bandwidth below the clip cutoff,
4324 : * and so should not be clipped
4325 : */
4326 2 : tt_assert(rs->has_bandwidth);
4327 2 : tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb / 2);
4328 2 : tt_assert(rs->bw_is_unmeasured);
4329 : } else {
4330 : /* Weren't expecting this... */
4331 0 : tt_abort();
4332 : }
4333 :
4334 8 : done:
4335 8 : return;
4336 : }
4337 :
4338 : /**
4339 : * Compute a consensus involving clipping unmeasured bandwidth with consensus
4340 : * method 17; this uses the same test_a_networkstatus() function that the
4341 : * v3_networkstatus test uses.
4342 : */
4343 :
4344 : static void
4345 1 : test_dir_clip_unmeasured_bw_kb(void *arg)
4346 : {
4347 : /* Run the test with the default clip bandwidth */
4348 1 : (void)arg;
4349 1 : alternate_clip_bw = 0;
4350 1 : test_a_networkstatus(gen_routerstatus_for_umbw,
4351 : vote_tweaks_for_umbw,
4352 : test_vrs_for_umbw,
4353 : test_consensus_for_umbw,
4354 : test_routerstatus_for_umbw);
4355 1 : }
4356 :
4357 : /**
4358 : * This version of test_dir_clip_unmeasured_bw_kb() uses a non-default choice
4359 : * of clip bandwidth.
4360 : */
4361 :
4362 : static void
4363 1 : test_dir_clip_unmeasured_bw_kb_alt(void *arg)
4364 : {
4365 : /*
4366 : * Try a different one; this value is chosen so that the below-the-cutoff
4367 : * unmeasured nodes the test uses, at alternate_clip_bw / 2, will be above
4368 : * DEFAULT_MAX_UNMEASURED_BW_KB and if the consensus incorrectly uses that
4369 : * cutoff it will fail the test.
4370 : */
4371 1 : (void)arg;
4372 1 : alternate_clip_bw = 3 * DEFAULT_MAX_UNMEASURED_BW_KB;
4373 1 : test_a_networkstatus(gen_routerstatus_for_umbw,
4374 : vote_tweaks_for_umbw,
4375 : test_vrs_for_umbw,
4376 : test_consensus_for_umbw,
4377 : test_routerstatus_for_umbw);
4378 1 : }
4379 :
4380 : static void
4381 1 : test_dir_fmt_control_ns(void *arg)
4382 : {
4383 1 : char *s = NULL;
4384 1 : routerstatus_t rs;
4385 1 : (void)arg;
4386 :
4387 1 : memset(&rs, 0, sizeof(rs));
4388 1 : rs.published_on = 1364925198;
4389 1 : strlcpy(rs.nickname, "TetsuoMilk", sizeof(rs.nickname));
4390 1 : memcpy(rs.identity_digest, "Stately, plump Buck ", DIGEST_LEN);
4391 1 : memcpy(rs.descriptor_digest, "Mulligan came up fro", DIGEST_LEN);
4392 1 : tor_addr_from_ipv4h(&rs.ipv4_addr, 0x20304050);
4393 1 : rs.ipv4_orport = 9001;
4394 1 : rs.ipv4_dirport = 9002;
4395 1 : rs.is_exit = 1;
4396 1 : rs.is_fast = 1;
4397 1 : rs.is_flagged_running = 1;
4398 1 : rs.has_bandwidth = 1;
4399 1 : rs.is_v2_dir = 1;
4400 1 : rs.bandwidth_kb = 1000;
4401 :
4402 1 : s = networkstatus_getinfo_helper_single(&rs);
4403 1 : tt_assert(s);
4404 1 : tt_str_op(s, OP_EQ,
4405 : "r TetsuoMilk U3RhdGVseSwgcGx1bXAgQnVjayA "
4406 : "TXVsbGlnYW4gY2FtZSB1cCBmcm8 2013-04-02 17:53:18 "
4407 : "32.48.64.80 9001 9002\n"
4408 : "s Exit Fast Running V2Dir\n"
4409 : "w Bandwidth=1000\n");
4410 :
4411 1 : done:
4412 1 : tor_free(s);
4413 1 : }
4414 :
4415 : static int mock_get_options_calls = 0;
4416 : static or_options_t *mock_options = NULL;
4417 :
4418 : static void
4419 18 : reset_options(or_options_t *options, int *get_options_calls)
4420 : {
4421 18 : memset(options, 0, sizeof(or_options_t));
4422 18 : options->TestingTorNetwork = 1;
4423 :
4424 18 : *get_options_calls = 0;
4425 18 : }
4426 :
4427 : static const or_options_t *
4428 91 : mock_get_options(void)
4429 : {
4430 91 : ++mock_get_options_calls;
4431 91 : tor_assert(mock_options);
4432 91 : return mock_options;
4433 : }
4434 :
4435 : /**
4436 : * Test dirauth_get_b64_digest_bw_file.
4437 : * This function should be near the other bwauth functions, but it needs
4438 : * mock_get_options, that is only defined here.
4439 : */
4440 :
4441 : static void
4442 1 : test_dir_bwauth_bw_file_digest256(void *arg)
4443 : {
4444 1 : (void)arg;
4445 1 : const char *content =
4446 : "1541171221\n"
4447 : "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 "
4448 : "master_key_ed25519=YaqV4vbvPYKucElk297eVdNArDz9HtIwUoIeo0+cVIpQ "
4449 : "bw=760 nick=Test time=2018-05-08T16:13:26\n";
4450 :
4451 1 : char *fname = tor_strdup(get_fname("V3BandwidthsFile"));
4452 : /* Initialize to a wrong digest. */
4453 1 : uint8_t digest[DIGEST256_LEN] = "01234567890123456789abcdefghijkl";
4454 :
4455 : /* Digest of an empty string. Initialize to a wrong digest. */
4456 1 : char digest_empty_str[DIGEST256_LEN] = "01234567890123456789abcdefghijkl";
4457 1 : crypto_digest256(digest_empty_str, "", 0, DIGEST_SHA256);
4458 :
4459 : /* Digest of the content. Initialize to a wrong digest. */
4460 1 : char digest_expected[DIGEST256_LEN] = "01234567890123456789abcdefghijkl";
4461 1 : crypto_digest256(digest_expected, content, strlen(content), DIGEST_SHA256);
4462 :
4463 : /* When the bandwidth file can not be found. */
4464 1 : tt_int_op(-1, OP_EQ,
4465 : dirserv_read_measured_bandwidths(fname,
4466 : NULL, NULL, digest));
4467 1 : tt_mem_op(digest, OP_EQ, digest_empty_str, DIGEST256_LEN);
4468 :
4469 : /* When there is a timestamp but it is too old. */
4470 1 : write_str_to_file(fname, content, 0);
4471 1 : tt_int_op(-1, OP_EQ,
4472 : dirserv_read_measured_bandwidths(fname,
4473 : NULL, NULL, digest));
4474 : /* The digest will be correct. */
4475 1 : tt_mem_op(digest, OP_EQ, digest_expected, DIGEST256_LEN);
4476 :
4477 1 : update_approx_time(1541171221);
4478 :
4479 : /* When there is a bandwidth file and it can be read. */
4480 1 : tt_int_op(0, OP_EQ,
4481 : dirserv_read_measured_bandwidths(fname,
4482 : NULL, NULL, digest));
4483 1 : tt_mem_op(digest, OP_EQ, digest_expected, DIGEST256_LEN);
4484 :
4485 1 : done:
4486 1 : unlink(fname);
4487 1 : tor_free(fname);
4488 1 : update_approx_time(time(NULL));
4489 1 : }
4490 :
4491 : static void
4492 13 : reset_routerstatus(routerstatus_t *rs,
4493 : const char *hex_identity_digest,
4494 : uint32_t ipv4_addr)
4495 : {
4496 13 : memset(rs, 0, sizeof(routerstatus_t));
4497 13 : base16_decode(rs->identity_digest, sizeof(rs->identity_digest),
4498 : hex_identity_digest, HEX_DIGEST_LEN);
4499 : /* A zero address matches everything, so the address needs to be set.
4500 : * But the specific value is irrelevant. */
4501 13 : tor_addr_from_ipv4h(&rs->ipv4_addr, ipv4_addr);
4502 13 : }
4503 :
4504 : #define ROUTER_A_ID_STR "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
4505 : #define ROUTER_A_IPV4 0xAA008801
4506 : #define ROUTER_B_ID_STR "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
4507 : #define ROUTER_B_IPV4 0xBB008801
4508 :
4509 : #define ROUTERSET_ALL_STR "*"
4510 : #define ROUTERSET_A_STR ROUTER_A_ID_STR
4511 : #define ROUTERSET_NONE_STR ""
4512 :
4513 : /*
4514 : * Test that dirserv_set_routerstatus_testing sets router flags correctly
4515 : * Using "*" sets flags on A and B
4516 : * Using "A" sets flags on A
4517 : * Using "" sets flags on Neither
4518 : * If the router is not included:
4519 : * - if *Strict is set, the flag is set to 0,
4520 : * - otherwise, the flag is not modified. */
4521 : static void
4522 1 : test_dir_dirserv_set_routerstatus_testing(void *arg)
4523 : {
4524 1 : (void)arg;
4525 :
4526 : /* Init options */
4527 2 : dirauth_options_t *dirauth_options =
4528 1 : tor_malloc_zero(sizeof(dirauth_options_t));
4529 :
4530 1 : mock_options = tor_malloc(sizeof(or_options_t));
4531 1 : reset_options(mock_options, &mock_get_options_calls);
4532 1 : MOCK(get_options, mock_get_options);
4533 1 : dirauth_set_options(dirauth_options);
4534 :
4535 : /* Init routersets */
4536 1 : routerset_t *routerset_all = routerset_new();
4537 1 : routerset_parse(routerset_all, ROUTERSET_ALL_STR, "All routers");
4538 :
4539 1 : routerset_t *routerset_a = routerset_new();
4540 1 : routerset_parse(routerset_a, ROUTERSET_A_STR, "Router A only");
4541 :
4542 1 : routerset_t *routerset_none = routerset_new();
4543 : /* Routersets are empty when provided by routerset_new(),
4544 : * so this is not strictly necessary */
4545 1 : routerset_parse(routerset_none, ROUTERSET_NONE_STR, "No routers");
4546 :
4547 : /* Init routerstatuses */
4548 1 : routerstatus_t *rs_a = tor_malloc(sizeof(routerstatus_t));
4549 1 : reset_routerstatus(rs_a, ROUTER_A_ID_STR, ROUTER_A_IPV4);
4550 :
4551 1 : routerstatus_t *rs_b = tor_malloc(sizeof(routerstatus_t));
4552 1 : reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
4553 :
4554 : /* Sanity check that routersets correspond to routerstatuses.
4555 : * Return values are {2, 3, 4} */
4556 :
4557 : /* We want 3 ("*" means match all addresses) */
4558 1 : tt_int_op(routerset_contains_routerstatus(routerset_all, rs_a, 0), OP_EQ, 3);
4559 1 : tt_int_op(routerset_contains_routerstatus(routerset_all, rs_b, 0), OP_EQ, 3);
4560 :
4561 : /* We want 4 (match id_digest [or nickname]) */
4562 1 : tt_int_op(routerset_contains_routerstatus(routerset_a, rs_a, 0), OP_EQ, 4);
4563 1 : tt_int_op(routerset_contains_routerstatus(routerset_a, rs_b, 0), OP_EQ, 0);
4564 :
4565 1 : tt_int_op(routerset_contains_routerstatus(routerset_none, rs_a, 0), OP_EQ,
4566 : 0);
4567 1 : tt_int_op(routerset_contains_routerstatus(routerset_none, rs_b, 0), OP_EQ,
4568 : 0);
4569 :
4570 : /* Check that "*" sets flags on all routers: Exit
4571 : * Check the flags aren't being confused with each other */
4572 1 : reset_options(mock_options, &mock_get_options_calls);
4573 1 : memset(dirauth_options, 0, sizeof(*dirauth_options));
4574 1 : reset_routerstatus(rs_a, ROUTER_A_ID_STR, ROUTER_A_IPV4);
4575 1 : reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
4576 :
4577 1 : dirauth_options->TestingDirAuthVoteExit = routerset_all;
4578 1 : dirauth_options->TestingDirAuthVoteExitIsStrict = 0;
4579 :
4580 1 : dirserv_set_routerstatus_testing(rs_a);
4581 1 : dirserv_set_routerstatus_testing(rs_b);
4582 :
4583 1 : tt_uint_op(rs_a->is_exit, OP_EQ, 1);
4584 1 : tt_uint_op(rs_b->is_exit, OP_EQ, 1);
4585 : /* Be paranoid - check no other flags are set */
4586 1 : tt_uint_op(rs_a->is_possible_guard, OP_EQ, 0);
4587 1 : tt_uint_op(rs_b->is_possible_guard, OP_EQ, 0);
4588 1 : tt_uint_op(rs_a->is_hs_dir, OP_EQ, 0);
4589 1 : tt_uint_op(rs_b->is_hs_dir, OP_EQ, 0);
4590 :
4591 : /* Check that "*" sets flags on all routers: Guard & HSDir
4592 : * Cover the remaining flags in one test */
4593 1 : reset_options(mock_options, &mock_get_options_calls);
4594 1 : memset(dirauth_options, 0, sizeof(*dirauth_options));
4595 1 : reset_routerstatus(rs_a, ROUTER_A_ID_STR, ROUTER_A_IPV4);
4596 1 : reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
4597 :
4598 1 : dirauth_options->TestingDirAuthVoteGuard = routerset_all;
4599 1 : dirauth_options->TestingDirAuthVoteGuardIsStrict = 0;
4600 1 : dirauth_options->TestingDirAuthVoteHSDir = routerset_all;
4601 1 : dirauth_options->TestingDirAuthVoteHSDirIsStrict = 0;
4602 :
4603 1 : dirserv_set_routerstatus_testing(rs_a);
4604 1 : dirserv_set_routerstatus_testing(rs_b);
4605 :
4606 1 : tt_uint_op(rs_a->is_possible_guard, OP_EQ, 1);
4607 1 : tt_uint_op(rs_b->is_possible_guard, OP_EQ, 1);
4608 1 : tt_uint_op(rs_a->is_hs_dir, OP_EQ, 1);
4609 1 : tt_uint_op(rs_b->is_hs_dir, OP_EQ, 1);
4610 : /* Be paranoid - check exit isn't set */
4611 1 : tt_uint_op(rs_a->is_exit, OP_EQ, 0);
4612 1 : tt_uint_op(rs_b->is_exit, OP_EQ, 0);
4613 :
4614 : /* Check routerset A sets all flags on router A,
4615 : * but leaves router B unmodified */
4616 1 : reset_options(mock_options, &mock_get_options_calls);
4617 1 : memset(dirauth_options, 0, sizeof(*dirauth_options));
4618 1 : reset_routerstatus(rs_a, ROUTER_A_ID_STR, ROUTER_A_IPV4);
4619 1 : reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
4620 :
4621 1 : dirauth_options->TestingDirAuthVoteExit = routerset_a;
4622 1 : dirauth_options->TestingDirAuthVoteExitIsStrict = 0;
4623 1 : dirauth_options->TestingDirAuthVoteGuard = routerset_a;
4624 1 : dirauth_options->TestingDirAuthVoteGuardIsStrict = 0;
4625 1 : dirauth_options->TestingDirAuthVoteHSDir = routerset_a;
4626 1 : dirauth_options->TestingDirAuthVoteHSDirIsStrict = 0;
4627 :
4628 1 : dirserv_set_routerstatus_testing(rs_a);
4629 1 : dirserv_set_routerstatus_testing(rs_b);
4630 :
4631 1 : tt_uint_op(rs_a->is_exit, OP_EQ, 1);
4632 1 : tt_uint_op(rs_b->is_exit, OP_EQ, 0);
4633 1 : tt_uint_op(rs_a->is_possible_guard, OP_EQ, 1);
4634 1 : tt_uint_op(rs_b->is_possible_guard, OP_EQ, 0);
4635 1 : tt_uint_op(rs_a->is_hs_dir, OP_EQ, 1);
4636 1 : tt_uint_op(rs_b->is_hs_dir, OP_EQ, 0);
4637 :
4638 : /* Check routerset A unsets all flags on router B when Strict is set */
4639 1 : reset_options(mock_options, &mock_get_options_calls);
4640 1 : memset(dirauth_options, 0, sizeof(*dirauth_options));
4641 1 : reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
4642 :
4643 1 : dirauth_options->TestingDirAuthVoteExit = routerset_a;
4644 1 : dirauth_options->TestingDirAuthVoteExitIsStrict = 1;
4645 1 : dirauth_options->TestingDirAuthVoteGuard = routerset_a;
4646 1 : dirauth_options->TestingDirAuthVoteGuardIsStrict = 1;
4647 1 : dirauth_options->TestingDirAuthVoteHSDir = routerset_a;
4648 1 : dirauth_options->TestingDirAuthVoteHSDirIsStrict = 1;
4649 :
4650 1 : rs_b->is_exit = 1;
4651 1 : rs_b->is_possible_guard = 1;
4652 1 : rs_b->is_hs_dir = 1;
4653 :
4654 1 : dirserv_set_routerstatus_testing(rs_b);
4655 :
4656 1 : tt_uint_op(rs_b->is_exit, OP_EQ, 0);
4657 1 : tt_uint_op(rs_b->is_possible_guard, OP_EQ, 0);
4658 1 : tt_uint_op(rs_b->is_hs_dir, OP_EQ, 0);
4659 :
4660 : /* Check routerset A doesn't modify flags on router B without Strict set */
4661 1 : reset_options(mock_options, &mock_get_options_calls);
4662 1 : memset(dirauth_options, 0, sizeof(*dirauth_options));
4663 1 : reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
4664 :
4665 1 : dirauth_options->TestingDirAuthVoteExit = routerset_a;
4666 1 : dirauth_options->TestingDirAuthVoteExitIsStrict = 0;
4667 1 : dirauth_options->TestingDirAuthVoteGuard = routerset_a;
4668 1 : dirauth_options->TestingDirAuthVoteGuardIsStrict = 0;
4669 1 : dirauth_options->TestingDirAuthVoteHSDir = routerset_a;
4670 1 : dirauth_options->TestingDirAuthVoteHSDirIsStrict = 0;
4671 :
4672 1 : rs_b->is_exit = 1;
4673 1 : rs_b->is_possible_guard = 1;
4674 1 : rs_b->is_hs_dir = 1;
4675 :
4676 1 : dirserv_set_routerstatus_testing(rs_b);
4677 :
4678 1 : tt_uint_op(rs_b->is_exit, OP_EQ, 1);
4679 1 : tt_uint_op(rs_b->is_possible_guard, OP_EQ, 1);
4680 1 : tt_uint_op(rs_b->is_hs_dir, OP_EQ, 1);
4681 :
4682 : /* Check the empty routerset zeroes all flags
4683 : * on routers A & B with Strict set */
4684 1 : reset_options(mock_options, &mock_get_options_calls);
4685 1 : memset(dirauth_options, 0, sizeof(*dirauth_options));
4686 1 : reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
4687 :
4688 1 : dirauth_options->TestingDirAuthVoteExit = routerset_none;
4689 1 : dirauth_options->TestingDirAuthVoteExitIsStrict = 1;
4690 1 : dirauth_options->TestingDirAuthVoteGuard = routerset_none;
4691 1 : dirauth_options->TestingDirAuthVoteGuardIsStrict = 1;
4692 1 : dirauth_options->TestingDirAuthVoteHSDir = routerset_none;
4693 1 : dirauth_options->TestingDirAuthVoteHSDirIsStrict = 1;
4694 :
4695 1 : rs_b->is_exit = 1;
4696 1 : rs_b->is_possible_guard = 1;
4697 1 : rs_b->is_hs_dir = 1;
4698 :
4699 1 : dirserv_set_routerstatus_testing(rs_b);
4700 :
4701 1 : tt_uint_op(rs_b->is_exit, OP_EQ, 0);
4702 1 : tt_uint_op(rs_b->is_possible_guard, OP_EQ, 0);
4703 1 : tt_uint_op(rs_b->is_hs_dir, OP_EQ, 0);
4704 :
4705 : /* Check the empty routerset doesn't modify any flags
4706 : * on A or B without Strict set */
4707 1 : reset_options(mock_options, &mock_get_options_calls);
4708 1 : memset(dirauth_options, 0, sizeof(*dirauth_options));
4709 1 : reset_routerstatus(rs_a, ROUTER_A_ID_STR, ROUTER_A_IPV4);
4710 1 : reset_routerstatus(rs_b, ROUTER_B_ID_STR, ROUTER_B_IPV4);
4711 :
4712 1 : dirauth_options->TestingDirAuthVoteExit = routerset_none;
4713 1 : dirauth_options->TestingDirAuthVoteExitIsStrict = 0;
4714 1 : dirauth_options->TestingDirAuthVoteGuard = routerset_none;
4715 1 : dirauth_options->TestingDirAuthVoteGuardIsStrict = 0;
4716 1 : dirauth_options->TestingDirAuthVoteHSDir = routerset_none;
4717 1 : dirauth_options->TestingDirAuthVoteHSDirIsStrict = 0;
4718 :
4719 1 : rs_b->is_exit = 1;
4720 1 : rs_b->is_possible_guard = 1;
4721 1 : rs_b->is_hs_dir = 1;
4722 :
4723 1 : dirserv_set_routerstatus_testing(rs_a);
4724 1 : dirserv_set_routerstatus_testing(rs_b);
4725 :
4726 1 : tt_uint_op(rs_a->is_exit, OP_EQ, 0);
4727 1 : tt_uint_op(rs_a->is_possible_guard, OP_EQ, 0);
4728 1 : tt_uint_op(rs_a->is_hs_dir, OP_EQ, 0);
4729 1 : tt_uint_op(rs_b->is_exit, OP_EQ, 1);
4730 1 : tt_uint_op(rs_b->is_possible_guard, OP_EQ, 1);
4731 1 : tt_uint_op(rs_b->is_hs_dir, OP_EQ, 1);
4732 :
4733 1 : done:
4734 1 : tor_free(mock_options);
4735 1 : tor_free(dirauth_options);
4736 1 : mock_options = NULL;
4737 :
4738 1 : UNMOCK(get_options);
4739 :
4740 1 : routerset_free(routerset_all);
4741 1 : routerset_free(routerset_a);
4742 1 : routerset_free(routerset_none);
4743 :
4744 1 : tor_free(rs_a);
4745 1 : tor_free(rs_b);
4746 1 : }
4747 :
4748 : static void
4749 1 : test_dir_http_handling(void *args)
4750 : {
4751 1 : char *url = NULL;
4752 1 : (void)args;
4753 :
4754 : /* Parse http url tests: */
4755 : /* Good headers */
4756 1 : tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.1\r\n"
4757 : "Host: example.com\r\n"
4758 : "User-Agent: Mozilla/5.0 (Windows;"
4759 : " U; Windows NT 6.1; en-US; rv:1.9.1.5)\r\n",
4760 : &url),OP_EQ, 0);
4761 1 : tt_str_op(url,OP_EQ, "/tor/a/b/c.txt");
4762 1 : tor_free(url);
4763 :
4764 1 : tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.0\r\n", &url),OP_EQ, 0);
4765 1 : tt_str_op(url,OP_EQ, "/tor/a/b/c.txt");
4766 1 : tor_free(url);
4767 :
4768 1 : tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.600\r\n", &url),
4769 : OP_EQ, 0);
4770 1 : tt_str_op(url,OP_EQ, "/tor/a/b/c.txt");
4771 1 : tor_free(url);
4772 :
4773 : /* Should prepend '/tor/' to url if required */
4774 1 : tt_int_op(parse_http_url("GET /a/b/c.txt HTTP/1.1\r\n"
4775 : "Host: example.com\r\n"
4776 : "User-Agent: Mozilla/5.0 (Windows;"
4777 : " U; Windows NT 6.1; en-US; rv:1.9.1.5)\r\n",
4778 : &url),OP_EQ, 0);
4779 1 : tt_str_op(url,OP_EQ, "/tor/a/b/c.txt");
4780 1 : tor_free(url);
4781 :
4782 : /* Bad headers -- no HTTP/1.x*/
4783 1 : tt_int_op(parse_http_url("GET /a/b/c.txt\r\n"
4784 : "Host: example.com\r\n"
4785 : "User-Agent: Mozilla/5.0 (Windows;"
4786 : " U; Windows NT 6.1; en-US; rv:1.9.1.5)\r\n",
4787 : &url),OP_EQ, -1);
4788 1 : tt_ptr_op(url, OP_EQ, NULL);
4789 :
4790 : /* Bad headers */
4791 1 : tt_int_op(parse_http_url("GET /a/b/c.txt\r\n"
4792 : "Host: example.com\r\n"
4793 : "User-Agent: Mozilla/5.0 (Windows;"
4794 : " U; Windows NT 6.1; en-US; rv:1.9.1.5)\r\n",
4795 : &url),OP_EQ, -1);
4796 1 : tt_ptr_op(url, OP_EQ, NULL);
4797 :
4798 1 : tt_int_op(parse_http_url("GET /tor/a/b/c.txt", &url),OP_EQ, -1);
4799 1 : tt_ptr_op(url, OP_EQ, NULL);
4800 :
4801 1 : tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.1", &url),OP_EQ, -1);
4802 1 : tt_ptr_op(url, OP_EQ, NULL);
4803 :
4804 1 : tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.1x\r\n", &url),
4805 : OP_EQ, -1);
4806 1 : tt_ptr_op(url, OP_EQ, NULL);
4807 :
4808 1 : tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.", &url),OP_EQ, -1);
4809 1 : tt_ptr_op(url, OP_EQ, NULL);
4810 :
4811 1 : tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.\r", &url),OP_EQ, -1);
4812 1 : tt_ptr_op(url, OP_EQ, NULL);
4813 :
4814 1 : done:
4815 1 : tor_free(url);
4816 1 : }
4817 :
4818 : static void
4819 1 : test_dir_purpose_needs_anonymity_returns_true_by_default(void *arg)
4820 : {
4821 1 : (void)arg;
4822 :
4823 : #ifdef ALL_BUGS_ARE_FATAL
4824 : /* Coverity (and maybe clang analyser) complain that the code following
4825 : * tt_skip() is unconditionally unreachable. */
4826 : #if !defined(__COVERITY__) && !defined(__clang_analyzer__)
4827 : tt_skip();
4828 : #endif
4829 : #endif /* defined(ALL_BUGS_ARE_FATAL) */
4830 :
4831 1 : tor_capture_bugs_(1);
4832 1 : setup_full_capture_of_logs(LOG_WARN);
4833 1 : tt_int_op(1, OP_EQ, purpose_needs_anonymity(0, 0, NULL));
4834 1 : tt_int_op(1, OP_EQ, smartlist_len(tor_get_captured_bug_log_()));
4835 1 : expect_single_log_msg_containing("Called with dir_purpose=0");
4836 :
4837 1 : tor_end_capture_bugs_();
4838 1 : done:
4839 1 : tor_end_capture_bugs_();
4840 1 : teardown_capture_of_logs();
4841 1 : }
4842 :
4843 : static void
4844 1 : test_dir_purpose_needs_anonymity_returns_true_for_bridges(void *arg)
4845 : {
4846 1 : (void)arg;
4847 :
4848 1 : tt_int_op(1, OP_EQ, purpose_needs_anonymity(0, ROUTER_PURPOSE_BRIDGE, NULL));
4849 1 : tt_int_op(1, OP_EQ, purpose_needs_anonymity(0, ROUTER_PURPOSE_BRIDGE,
4850 : "foobar"));
4851 1 : done: ;
4852 1 : }
4853 :
4854 : static void
4855 1 : test_dir_purpose_needs_anonymity_returns_false_for_own_bridge_desc(void *arg)
4856 : {
4857 1 : (void)arg;
4858 1 : tt_int_op(0, OP_EQ, purpose_needs_anonymity(DIR_PURPOSE_FETCH_SERVERDESC,
4859 : ROUTER_PURPOSE_BRIDGE,
4860 : "authority.z"));
4861 1 : done: ;
4862 1 : }
4863 :
4864 : static void
4865 1 : test_dir_purpose_needs_anonymity_ret_false_for_non_sensitive_conn(void *arg)
4866 : {
4867 1 : (void)arg;
4868 :
4869 1 : tt_int_op(0, OP_EQ, purpose_needs_anonymity(DIR_PURPOSE_UPLOAD_DIR,
4870 : ROUTER_PURPOSE_GENERAL, NULL));
4871 1 : tt_int_op(0, OP_EQ,
4872 : purpose_needs_anonymity(DIR_PURPOSE_UPLOAD_VOTE, 0, NULL));
4873 1 : tt_int_op(0, OP_EQ,
4874 : purpose_needs_anonymity(DIR_PURPOSE_UPLOAD_SIGNATURES, 0, NULL));
4875 1 : tt_int_op(0, OP_EQ,
4876 : purpose_needs_anonymity(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL));
4877 1 : tt_int_op(0, OP_EQ, purpose_needs_anonymity(
4878 : DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0, NULL));
4879 1 : tt_int_op(0, OP_EQ,
4880 : purpose_needs_anonymity(DIR_PURPOSE_FETCH_CONSENSUS, 0, NULL));
4881 1 : tt_int_op(0, OP_EQ,
4882 : purpose_needs_anonymity(DIR_PURPOSE_FETCH_CERTIFICATE, 0, NULL));
4883 1 : tt_int_op(0, OP_EQ,
4884 : purpose_needs_anonymity(DIR_PURPOSE_FETCH_SERVERDESC, 0, NULL));
4885 1 : tt_int_op(0, OP_EQ,
4886 : purpose_needs_anonymity(DIR_PURPOSE_FETCH_EXTRAINFO, 0, NULL));
4887 1 : tt_int_op(0, OP_EQ,
4888 : purpose_needs_anonymity(DIR_PURPOSE_FETCH_MICRODESC, 0, NULL));
4889 1 : done: ;
4890 1 : }
4891 :
4892 : static void
4893 1 : test_dir_fetch_type(void *arg)
4894 : {
4895 1 : (void)arg;
4896 :
4897 1 : tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_EXTRAINFO, ROUTER_PURPOSE_BRIDGE,
4898 : NULL), OP_EQ, EXTRAINFO_DIRINFO | BRIDGE_DIRINFO);
4899 1 : tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_EXTRAINFO, ROUTER_PURPOSE_GENERAL,
4900 : NULL), OP_EQ, EXTRAINFO_DIRINFO | V3_DIRINFO);
4901 :
4902 1 : tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_SERVERDESC, ROUTER_PURPOSE_BRIDGE,
4903 : NULL), OP_EQ, BRIDGE_DIRINFO);
4904 1 : tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_SERVERDESC,
4905 : ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, V3_DIRINFO);
4906 :
4907 1 : tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_STATUS_VOTE,
4908 : ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, V3_DIRINFO);
4909 1 : tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES,
4910 : ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, V3_DIRINFO);
4911 1 : tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_CERTIFICATE,
4912 : ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, V3_DIRINFO);
4913 :
4914 1 : tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_CONSENSUS, ROUTER_PURPOSE_GENERAL,
4915 : "microdesc"), OP_EQ, V3_DIRINFO|MICRODESC_DIRINFO);
4916 1 : tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_CONSENSUS, ROUTER_PURPOSE_GENERAL,
4917 : NULL), OP_EQ, V3_DIRINFO);
4918 :
4919 1 : tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_MICRODESC, ROUTER_PURPOSE_GENERAL,
4920 : NULL), OP_EQ, MICRODESC_DIRINFO);
4921 :
4922 1 : done:
4923 1 : teardown_capture_of_logs();
4924 1 : }
4925 :
4926 : static void
4927 1 : test_dir_packages(void *arg)
4928 : {
4929 1 : smartlist_t *votes = smartlist_new();
4930 1 : char *res = NULL;
4931 1 : (void)arg;
4932 :
4933 : #define BAD(s) \
4934 : tt_int_op(0, OP_EQ, validate_recommended_package_line(s));
4935 : #define GOOD(s) \
4936 : tt_int_op(1, OP_EQ, validate_recommended_package_line(s));
4937 1 : GOOD("tor 0.2.6.3-alpha "
4938 : "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz "
4939 1 : "sha256=sssdlkfjdsklfjdskfljasdklfj");
4940 1 : GOOD("tor 0.2.6.3-alpha "
4941 : "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz "
4942 1 : "sha256=sssdlkfjdsklfjdskfljasdklfj blake2b=fred");
4943 1 : BAD("tor 0.2.6.3-alpha "
4944 : "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz "
4945 1 : "sha256=sssdlkfjdsklfjdskfljasdklfj=");
4946 1 : BAD("tor 0.2.6.3-alpha "
4947 : "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz "
4948 1 : "sha256=sssdlkfjdsklfjdskfljasdklfj blake2b");
4949 1 : BAD("tor 0.2.6.3-alpha "
4950 1 : "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz ");
4951 1 : BAD("tor 0.2.6.3-alpha "
4952 1 : "http://torproject.example.com/dist/tor-0.2.6.3-alpha.tar.gz");
4953 1 : BAD("tor 0.2.6.3-alpha ");
4954 1 : BAD("tor 0.2.6.3-alpha");
4955 1 : BAD("tor ");
4956 1 : BAD("tor");
4957 1 : BAD("");
4958 1 : BAD("=foobar sha256="
4959 1 : "3c179f46ca77069a6a0bac70212a9b3b838b2f66129cb52d568837fc79d8fcc7");
4960 1 : BAD("= = sha256="
4961 1 : "3c179f46ca77069a6a0bac70212a9b3b838b2f66129cb52d568837fc79d8fcc7");
4962 :
4963 1 : BAD("sha512= sha256="
4964 1 : "3c179f46ca77069a6a0bac70212a9b3b838b2f66129cb52d568837fc79d8fcc7");
4965 :
4966 1 : smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
4967 1 : smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
4968 1 : smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
4969 1 : smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
4970 1 : smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
4971 1 : smartlist_add(votes, tor_malloc_zero(sizeof(networkstatus_t)));
4972 7 : SMARTLIST_FOREACH(votes, networkstatus_t *, ns,
4973 : ns->package_lines = smartlist_new());
4974 :
4975 : #define ADD(i, s) \
4976 : smartlist_add(((networkstatus_t*)smartlist_get(votes, (i)))->package_lines, \
4977 : (void*)(s));
4978 :
4979 : /* Only one vote for this one. */
4980 1 : ADD(4, "cisco 99z http://foobar.example.com/ sha256=blahblah");
4981 :
4982 : /* Only two matching entries for this one, but 3 voters */
4983 1 : ADD(1, "mystic 99y http://barfoo.example.com/ sha256=blahblah");
4984 1 : ADD(3, "mystic 99y http://foobar.example.com/ sha256=blahblah");
4985 1 : ADD(4, "mystic 99y http://foobar.example.com/ sha256=blahblah");
4986 :
4987 : /* Only two matching entries for this one, but at least 4 voters */
4988 1 : ADD(1, "mystic 99p http://barfoo.example.com/ sha256=ggggggg");
4989 1 : ADD(3, "mystic 99p http://foobar.example.com/ sha256=blahblah");
4990 1 : ADD(4, "mystic 99p http://foobar.example.com/ sha256=blahblah");
4991 1 : ADD(5, "mystic 99p http://foobar.example.com/ sha256=ggggggg");
4992 :
4993 : /* This one has only invalid votes. */
4994 1 : ADD(0, "haffenreffer 1.2 http://foobar.example.com/ sha256");
4995 1 : ADD(1, "haffenreffer 1.2 http://foobar.example.com/ ");
4996 1 : ADD(2, "haffenreffer 1.2 ");
4997 1 : ADD(3, "haffenreffer ");
4998 1 : ADD(4, "haffenreffer");
4999 :
5000 : /* Three matching votes for this; it should actually go in! */
5001 1 : ADD(2, "element 0.66.1 http://quux.example.com/ sha256=abcdef");
5002 1 : ADD(3, "element 0.66.1 http://quux.example.com/ sha256=abcdef");
5003 1 : ADD(4, "element 0.66.1 http://quux.example.com/ sha256=abcdef");
5004 1 : ADD(1, "element 0.66.1 http://quum.example.com/ sha256=abcdef");
5005 1 : ADD(0, "element 0.66.1 http://quux.example.com/ sha256=abcde");
5006 :
5007 : /* Three votes for A, three votes for B */
5008 1 : ADD(0, "clownshoes 22alpha1 http://quumble.example.com/ blake2=foob");
5009 1 : ADD(1, "clownshoes 22alpha1 http://quumble.example.com/ blake2=foob");
5010 1 : ADD(2, "clownshoes 22alpha1 http://quumble.example.com/ blake2=foob");
5011 1 : ADD(3, "clownshoes 22alpha1 http://quumble.example.com/ blake2=fooz");
5012 1 : ADD(4, "clownshoes 22alpha1 http://quumble.example.com/ blake2=fooz");
5013 1 : ADD(5, "clownshoes 22alpha1 http://quumble.example.com/ blake2=fooz");
5014 :
5015 : /* Three votes for A, two votes for B */
5016 1 : ADD(1, "clownshoes 22alpha3 http://quumble.example.com/ blake2=foob");
5017 1 : ADD(2, "clownshoes 22alpha3 http://quumble.example.com/ blake2=foob");
5018 1 : ADD(3, "clownshoes 22alpha3 http://quumble.example.com/ blake2=fooz");
5019 1 : ADD(4, "clownshoes 22alpha3 http://quumble.example.com/ blake2=fooz");
5020 1 : ADD(5, "clownshoes 22alpha3 http://quumble.example.com/ blake2=fooz");
5021 :
5022 : /* Four votes for A, two for B. */
5023 1 : ADD(0, "clownshoes 22alpha4 http://quumble.example.com/ blake2=foob");
5024 1 : ADD(1, "clownshoes 22alpha4 http://quumble.example.com/ blake2=foob");
5025 1 : ADD(2, "clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa");
5026 1 : ADD(3, "clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa");
5027 1 : ADD(4, "clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa");
5028 1 : ADD(5, "clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa");
5029 :
5030 : /* Five votes for A ... all from the same authority. Three for B. */
5031 1 : ADD(0, "cbc 99.1.11.1.1 http://example.com/cbc/ cubehash=ahooy sha512=m");
5032 1 : ADD(1, "cbc 99.1.11.1.1 http://example.com/cbc/ cubehash=ahooy sha512=m");
5033 1 : ADD(3, "cbc 99.1.11.1.1 http://example.com/cbc/ cubehash=ahooy sha512=m");
5034 1 : ADD(2, "cbc 99.1.11.1.1 http://example.com/ cubehash=ahooy");
5035 1 : ADD(2, "cbc 99.1.11.1.1 http://example.com/ cubehash=ahooy");
5036 1 : ADD(2, "cbc 99.1.11.1.1 http://example.com/ cubehash=ahooy");
5037 1 : ADD(2, "cbc 99.1.11.1.1 http://example.com/ cubehash=ahooy");
5038 1 : ADD(2, "cbc 99.1.11.1.1 http://example.com/ cubehash=ahooy");
5039 :
5040 : /* As above but new replaces old: no two match. */
5041 1 : ADD(0, "cbc 99.1.11.1.2 http://example.com/cbc/ cubehash=ahooy sha512=m");
5042 1 : ADD(1, "cbc 99.1.11.1.2 http://example.com/cbc/ cubehash=ahooy sha512=m");
5043 1 : ADD(1, "cbc 99.1.11.1.2 http://example.com/cbc/x cubehash=ahooy sha512=m");
5044 1 : ADD(2, "cbc 99.1.11.1.2 http://example.com/cbc/ cubehash=ahooy sha512=m");
5045 1 : ADD(2, "cbc 99.1.11.1.2 http://example.com/ cubehash=ahooy");
5046 1 : ADD(2, "cbc 99.1.11.1.2 http://example.com/ cubehash=ahooy");
5047 1 : ADD(2, "cbc 99.1.11.1.2 http://example.com/ cubehash=ahooy");
5048 1 : ADD(2, "cbc 99.1.11.1.2 http://example.com/ cubehash=ahooy");
5049 1 : ADD(2, "cbc 99.1.11.1.2 http://example.com/ cubehash=ahooy");
5050 :
5051 1 : res = compute_consensus_package_lines(votes);
5052 1 : tt_assert(res);
5053 1 : tt_str_op(res, OP_EQ,
5054 : "package cbc 99.1.11.1.1 http://example.com/cbc/ cubehash=ahooy sha512=m\n"
5055 : "package clownshoes 22alpha3 http://quumble.example.com/ blake2=fooz\n"
5056 : "package clownshoes 22alpha4 http://quumble.example.cam/ blake2=fooa\n"
5057 : "package element 0.66.1 http://quux.example.com/ sha256=abcdef\n"
5058 : "package mystic 99y http://foobar.example.com/ sha256=blahblah\n"
5059 : );
5060 :
5061 : #undef ADD
5062 : #undef BAD
5063 : #undef GOOD
5064 1 : done:
5065 7 : SMARTLIST_FOREACH(votes, networkstatus_t *, ns,
5066 : { smartlist_free(ns->package_lines); tor_free(ns); });
5067 1 : smartlist_free(votes);
5068 1 : tor_free(res);
5069 1 : }
5070 :
5071 : static void
5072 4 : download_status_random_backoff_helper(int min_delay)
5073 : {
5074 4 : download_status_t dls_random =
5075 : { 0, 0, 0, DL_SCHED_GENERIC, DL_WANT_AUTHORITY,
5076 : DL_SCHED_INCREMENT_FAILURE, 0, 0 };
5077 4 : int increment = -1;
5078 4 : int old_increment = -1;
5079 4 : time_t current_time = time(NULL);
5080 :
5081 : /* Check the random backoff cases */
5082 4 : int n_attempts = 0;
5083 4000 : do {
5084 4000 : increment = download_status_schedule_get_delay(&dls_random,
5085 : min_delay,
5086 : current_time);
5087 :
5088 4000 : log_debug(LD_DIR, "Min: %d, Inc: %d, Old Inc: %d",
5089 : min_delay, increment, old_increment);
5090 :
5091 : /* Regression test for 20534 and friends
5092 : * increment must always increase after the first */
5093 4000 : if (dls_random.last_backoff_position > 0) {
5094 : /* Always increment the exponential backoff */
5095 3996 : tt_int_op(increment, OP_GE, 1);
5096 : }
5097 :
5098 : /* Test */
5099 4000 : tt_int_op(increment, OP_GE, min_delay);
5100 :
5101 : /* Advance */
5102 4000 : if (dls_random.n_download_attempts < IMPOSSIBLE_TO_DOWNLOAD - 1) {
5103 1016 : ++(dls_random.n_download_attempts);
5104 1016 : ++(dls_random.n_download_failures);
5105 : }
5106 :
5107 : /* Try another maybe */
5108 4000 : old_increment = increment;
5109 4000 : } while (++n_attempts < 1000);
5110 :
5111 4 : done:
5112 4 : return;
5113 : }
5114 :
5115 : static void
5116 1 : test_dir_download_status_random_backoff(void *arg)
5117 : {
5118 1 : (void)arg;
5119 :
5120 : /* Do a standard test */
5121 1 : download_status_random_backoff_helper(0);
5122 : /* regression tests for 17750: initial delay */
5123 1 : download_status_random_backoff_helper(10);
5124 1 : download_status_random_backoff_helper(20);
5125 :
5126 : /* Pathological cases */
5127 1 : download_status_random_backoff_helper(INT_MAX/2);
5128 1 : }
5129 :
5130 : static void
5131 1 : test_dir_download_status_random_backoff_ranges(void *arg)
5132 : {
5133 1 : (void)arg;
5134 1 : int lo, hi;
5135 1 : next_random_exponential_delay_range(&lo, &hi, 0, 10);
5136 1 : tt_int_op(lo, OP_EQ, 10);
5137 1 : tt_int_op(hi, OP_EQ, 11);
5138 :
5139 1 : next_random_exponential_delay_range(&lo, &hi, 6, 10);
5140 1 : tt_int_op(lo, OP_EQ, 10);
5141 1 : tt_int_op(hi, OP_EQ, 6*3);
5142 :
5143 1 : next_random_exponential_delay_range(&lo, &hi, 13, 10);
5144 1 : tt_int_op(lo, OP_EQ, 10);
5145 1 : tt_int_op(hi, OP_EQ, 13 * 3);
5146 :
5147 1 : next_random_exponential_delay_range(&lo, &hi, 37, 10);
5148 1 : tt_int_op(lo, OP_EQ, 10);
5149 1 : tt_int_op(hi, OP_EQ, 111);
5150 :
5151 1 : next_random_exponential_delay_range(&lo, &hi, 123, 10);
5152 1 : tt_int_op(lo, OP_EQ, 10);
5153 1 : tt_int_op(hi, OP_EQ, 369);
5154 :
5155 1 : next_random_exponential_delay_range(&lo, &hi, INT_MAX-5, 10);
5156 1 : tt_int_op(lo, OP_EQ, 10);
5157 1 : tt_int_op(hi, OP_EQ, INT_MAX);
5158 1 : done:
5159 1 : ;
5160 1 : }
5161 :
5162 : static void
5163 1 : test_dir_download_status_increment(void *arg)
5164 : {
5165 1 : (void)arg;
5166 1 : download_status_t dls_exp = { 0, 0, 0, DL_SCHED_GENERIC,
5167 : DL_WANT_ANY_DIRSERVER,
5168 : DL_SCHED_INCREMENT_ATTEMPT,
5169 : 0, 0 };
5170 1 : or_options_t test_options;
5171 1 : time_t current_time = time(NULL);
5172 :
5173 1 : const int delay0 = 10;
5174 1 : const int no_delay = 0;
5175 1 : const int schedule = 10;
5176 1 : const int schedule_no_initial_delay = 0;
5177 :
5178 : /* Put it in the options */
5179 1 : mock_options = &test_options;
5180 1 : reset_options(mock_options, &mock_get_options_calls);
5181 1 : mock_options->TestingBridgeBootstrapDownloadInitialDelay = schedule;
5182 1 : mock_options->TestingClientDownloadInitialDelay = schedule;
5183 :
5184 1 : MOCK(get_options, mock_get_options);
5185 :
5186 : /* Check that the initial value of the schedule is the first value used,
5187 : * whether or not it was reset before being used */
5188 :
5189 : /* regression test for 17750: no initial delay */
5190 1 : mock_options->TestingClientDownloadInitialDelay = schedule_no_initial_delay;
5191 1 : mock_get_options_calls = 0;
5192 : /* we really want to test that it's equal to time(NULL) + delay0, but that's
5193 : * an unrealiable test, because time(NULL) might change. */
5194 :
5195 : /* regression test for 17750: exponential, no initial delay */
5196 1 : mock_options->TestingClientDownloadInitialDelay = schedule_no_initial_delay;
5197 1 : mock_get_options_calls = 0;
5198 : /* we really want to test that it's equal to time(NULL) + delay0, but that's
5199 : * an unrealiable test, because time(NULL) might change. */
5200 1 : tt_assert(download_status_get_next_attempt_at(&dls_exp)
5201 : >= current_time + no_delay);
5202 1 : tt_assert(download_status_get_next_attempt_at(&dls_exp)
5203 : != TIME_MAX);
5204 1 : tt_int_op(download_status_get_n_failures(&dls_exp), OP_EQ, 0);
5205 1 : tt_int_op(download_status_get_n_attempts(&dls_exp), OP_EQ, 0);
5206 1 : tt_int_op(mock_get_options_calls, OP_GE, 1);
5207 :
5208 : /* regression test for 17750: exponential, initial delay */
5209 1 : mock_options->TestingClientDownloadInitialDelay = schedule;
5210 1 : mock_get_options_calls = 0;
5211 : /* we really want to test that it's equal to time(NULL) + delay0, but that's
5212 : * an unrealiable test, because time(NULL) might change. */
5213 1 : tt_assert(download_status_get_next_attempt_at(&dls_exp)
5214 : >= current_time + delay0);
5215 1 : tt_assert(download_status_get_next_attempt_at(&dls_exp)
5216 : != TIME_MAX);
5217 1 : tt_int_op(download_status_get_n_failures(&dls_exp), OP_EQ, 0);
5218 1 : tt_int_op(download_status_get_n_attempts(&dls_exp), OP_EQ, 0);
5219 1 : tt_int_op(mock_get_options_calls, OP_GE, 1);
5220 :
5221 1 : done:
5222 1 : UNMOCK(get_options);
5223 1 : mock_options = NULL;
5224 1 : mock_get_options_calls = 0;
5225 1 : teardown_capture_of_logs();
5226 1 : }
5227 :
5228 : static void
5229 1 : test_dir_authdir_type_to_string(void *data)
5230 : {
5231 1 : (void)data;
5232 1 : char *res;
5233 :
5234 1 : tt_str_op(res = authdir_type_to_string(NO_DIRINFO), OP_EQ,
5235 : "[Not an authority]");
5236 1 : tor_free(res);
5237 :
5238 1 : tt_str_op(res = authdir_type_to_string(EXTRAINFO_DIRINFO), OP_EQ,
5239 : "[Not an authority]");
5240 1 : tor_free(res);
5241 :
5242 1 : tt_str_op(res = authdir_type_to_string(MICRODESC_DIRINFO), OP_EQ,
5243 : "[Not an authority]");
5244 1 : tor_free(res);
5245 :
5246 1 : tt_str_op(res = authdir_type_to_string(V3_DIRINFO), OP_EQ, "V3");
5247 1 : tor_free(res);
5248 :
5249 1 : tt_str_op(res = authdir_type_to_string(BRIDGE_DIRINFO), OP_EQ, "Bridge");
5250 1 : tor_free(res);
5251 :
5252 1 : tt_str_op(res = authdir_type_to_string(
5253 : V3_DIRINFO | BRIDGE_DIRINFO | EXTRAINFO_DIRINFO), OP_EQ,
5254 : "V3, Bridge");
5255 1 : done:
5256 1 : tor_free(res);
5257 1 : }
5258 :
5259 : static void
5260 1 : test_dir_conn_purpose_to_string(void *data)
5261 : {
5262 1 : (void)data;
5263 :
5264 : #define EXPECT_CONN_PURPOSE(purpose, expected) \
5265 : tt_str_op(dir_conn_purpose_to_string(purpose), OP_EQ, expected);
5266 :
5267 1 : EXPECT_CONN_PURPOSE(DIR_PURPOSE_UPLOAD_DIR, "server descriptor upload");
5268 1 : EXPECT_CONN_PURPOSE(DIR_PURPOSE_UPLOAD_VOTE, "server vote upload");
5269 1 : EXPECT_CONN_PURPOSE(DIR_PURPOSE_UPLOAD_SIGNATURES,
5270 1 : "consensus signature upload");
5271 1 : EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_SERVERDESC, "server descriptor fetch");
5272 1 : EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_EXTRAINFO, "extra-info fetch");
5273 1 : EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_CONSENSUS,
5274 1 : "consensus network-status fetch");
5275 1 : EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_CERTIFICATE, "authority cert fetch");
5276 1 : EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_STATUS_VOTE, "status vote fetch");
5277 1 : EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES,
5278 1 : "consensus signature fetch");
5279 1 : EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_MICRODESC, "microdescriptor fetch");
5280 :
5281 : /* This will give a warning, because there is no purpose 1024. */
5282 1 : setup_full_capture_of_logs(LOG_WARN);
5283 1 : EXPECT_CONN_PURPOSE(1024, "(unknown)");
5284 1 : expect_single_log_msg_containing("Called with unknown purpose 1024");
5285 :
5286 1 : done:
5287 1 : teardown_capture_of_logs();
5288 1 : }
5289 :
5290 : static int dir_tests_public_server_mode(const or_options_t *options);
5291 : ATTR_UNUSED static int dir_tests_public_server_mode_called = 0;
5292 :
5293 : static int
5294 7 : dir_tests_public_server_mode(const or_options_t *options)
5295 : {
5296 7 : (void)options;
5297 :
5298 7 : if (dir_tests_public_server_mode_called++ == 0) {
5299 1 : return 1;
5300 : }
5301 :
5302 : return 0;
5303 : }
5304 :
5305 : static void
5306 1 : test_dir_should_use_directory_guards(void *data)
5307 : {
5308 1 : or_options_t *options;
5309 1 : char *errmsg = NULL;
5310 1 : (void)data;
5311 :
5312 1 : MOCK(public_server_mode,
5313 : dir_tests_public_server_mode);
5314 :
5315 1 : options = options_new();
5316 1 : options_init(options);
5317 :
5318 1 : tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
5319 1 : tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 1);
5320 :
5321 1 : options->UseEntryGuards = 1;
5322 1 : options->DownloadExtraInfo = 0;
5323 1 : options->FetchDirInfoEarly = 0;
5324 1 : options->FetchDirInfoExtraEarly = 0;
5325 1 : options->FetchUselessDescriptors = 0;
5326 1 : tt_int_op(should_use_directory_guards(options), OP_EQ, 1);
5327 1 : tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 2);
5328 :
5329 1 : options->UseEntryGuards = 0;
5330 1 : tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
5331 1 : tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 3);
5332 1 : options->UseEntryGuards = 1;
5333 :
5334 1 : options->DownloadExtraInfo = 1;
5335 1 : tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
5336 1 : tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 4);
5337 1 : options->DownloadExtraInfo = 0;
5338 :
5339 1 : options->FetchDirInfoEarly = 1;
5340 1 : tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
5341 1 : tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 5);
5342 1 : options->FetchDirInfoEarly = 0;
5343 :
5344 1 : options->FetchDirInfoExtraEarly = 1;
5345 1 : tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
5346 1 : tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 6);
5347 1 : options->FetchDirInfoExtraEarly = 0;
5348 :
5349 1 : options->FetchUselessDescriptors = 1;
5350 1 : tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
5351 1 : tt_int_op(dir_tests_public_server_mode_called, OP_EQ, 7);
5352 1 : options->FetchUselessDescriptors = 0;
5353 :
5354 1 : done:
5355 1 : UNMOCK(public_server_mode);
5356 1 : or_options_free(options);
5357 1 : tor_free(errmsg);
5358 1 : }
5359 :
5360 : static void dir_tests_directory_initiate_request(directory_request_t *req);
5361 : ATTR_UNUSED static int dir_tests_directory_initiate_request_called = 0;
5362 :
5363 : static void
5364 1 : test_dir_should_not_init_request_to_ourselves(void *data)
5365 : {
5366 1 : char digest[DIGEST_LEN];
5367 1 : dir_server_t *ourself = NULL;
5368 1 : crypto_pk_t *key = pk_generate(2);
5369 1 : (void) data;
5370 :
5371 1 : MOCK(directory_initiate_request,
5372 : dir_tests_directory_initiate_request);
5373 :
5374 1 : clear_dir_servers();
5375 1 : routerlist_free_all();
5376 :
5377 1 : set_server_identity_key(key);
5378 1 : crypto_pk_get_digest(key, (char*) &digest);
5379 1 : ourself = trusted_dir_server_new("ourself", "127.0.0.1", 9059, 9060,
5380 : NULL, digest,
5381 : NULL, V3_DIRINFO, 1.0);
5382 :
5383 1 : tt_assert(ourself);
5384 1 : dir_server_add(ourself);
5385 :
5386 1 : directory_get_from_all_authorities(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL);
5387 1 : tt_int_op(dir_tests_directory_initiate_request_called, OP_EQ, 0);
5388 :
5389 1 : directory_get_from_all_authorities(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0,
5390 : NULL);
5391 :
5392 1 : tt_int_op(dir_tests_directory_initiate_request_called, OP_EQ, 0);
5393 :
5394 1 : done:
5395 1 : UNMOCK(directory_initiate_request);
5396 1 : clear_dir_servers();
5397 1 : routerlist_free_all();
5398 1 : crypto_pk_free(key);
5399 1 : }
5400 :
5401 : static void
5402 1 : test_dir_should_not_init_request_to_dir_auths_without_v3_info(void *data)
5403 : {
5404 1 : dir_server_t *ds = NULL;
5405 1 : dirinfo_type_t dirinfo_type = BRIDGE_DIRINFO | EXTRAINFO_DIRINFO \
5406 : | MICRODESC_DIRINFO;
5407 1 : (void) data;
5408 :
5409 1 : MOCK(directory_initiate_request,
5410 : dir_tests_directory_initiate_request);
5411 :
5412 1 : clear_dir_servers();
5413 1 : routerlist_free_all();
5414 :
5415 1 : ds = trusted_dir_server_new("ds", "10.0.0.1", 9059, 9060, NULL,
5416 : "12345678901234567890", NULL, dirinfo_type, 1.0);
5417 1 : tt_assert(ds);
5418 1 : dir_server_add(ds);
5419 :
5420 1 : directory_get_from_all_authorities(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL);
5421 1 : tt_int_op(dir_tests_directory_initiate_request_called, OP_EQ, 0);
5422 :
5423 1 : directory_get_from_all_authorities(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0,
5424 : NULL);
5425 1 : tt_int_op(dir_tests_directory_initiate_request_called, OP_EQ, 0);
5426 :
5427 1 : done:
5428 1 : UNMOCK(directory_initiate_request);
5429 1 : clear_dir_servers();
5430 1 : routerlist_free_all();
5431 1 : }
5432 :
5433 : static void
5434 1 : test_dir_should_init_request_to_dir_auths(void *data)
5435 : {
5436 1 : dir_server_t *ds = NULL;
5437 1 : (void) data;
5438 :
5439 1 : MOCK(directory_initiate_request,
5440 : dir_tests_directory_initiate_request);
5441 :
5442 1 : clear_dir_servers();
5443 1 : routerlist_free_all();
5444 :
5445 1 : ds = trusted_dir_server_new("ds", "10.0.0.1", 9059, 9060, NULL,
5446 : "12345678901234567890", NULL, V3_DIRINFO, 1.0);
5447 1 : tt_assert(ds);
5448 1 : dir_server_add(ds);
5449 :
5450 1 : directory_get_from_all_authorities(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL);
5451 1 : tt_int_op(dir_tests_directory_initiate_request_called, OP_EQ, 1);
5452 :
5453 1 : directory_get_from_all_authorities(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0,
5454 : NULL);
5455 1 : tt_int_op(dir_tests_directory_initiate_request_called, OP_EQ, 2);
5456 :
5457 1 : done:
5458 1 : UNMOCK(directory_initiate_request);
5459 1 : clear_dir_servers();
5460 1 : routerlist_free_all();
5461 1 : }
5462 :
5463 : void
5464 2 : dir_tests_directory_initiate_request(directory_request_t *req)
5465 : {
5466 2 : (void)req;
5467 2 : dir_tests_directory_initiate_request_called++;
5468 2 : }
5469 :
5470 : /*
5471 : * Mock check_private_dir(), and always succeed - no need to actually
5472 : * look at or create anything on the filesystem.
5473 : */
5474 :
5475 : static int
5476 0 : mock_check_private_dir(const char *dirname, cpd_check_t check,
5477 : const char *effective_user)
5478 : {
5479 0 : (void)dirname;
5480 0 : (void)check;
5481 0 : (void)effective_user;
5482 :
5483 0 : return 0;
5484 : }
5485 :
5486 : /*
5487 : * This really mocks options_get_datadir_fname2_suffix(), but for testing
5488 : * dump_desc(), we only care about get_datadir_fname(sub1), which is defined
5489 : * in config.h as:
5490 : *
5491 : * options_get_datadir_fname2_suffix(get_options(), sub1, NULL, NULL)
5492 : */
5493 :
5494 : static char *
5495 20 : mock_get_datadir_fname(const or_options_t *options,
5496 : directory_root_t roottype,
5497 : const char *sub1, const char *sub2,
5498 : const char *suffix)
5499 : {
5500 20 : (void) roottype;
5501 20 : char *rv = NULL;
5502 :
5503 : /*
5504 : * Assert we were called like get_datadir_fname2() or get_datadir_fname(),
5505 : * since that's all we implement here.
5506 : */
5507 20 : tt_ptr_op(options, OP_NE, NULL);
5508 20 : tt_ptr_op(sub1, OP_NE, NULL);
5509 : /*
5510 : * No particular assertions about sub2, since we could be in the
5511 : * get_datadir_fname() or get_datadir_fname2() case.
5512 : */
5513 20 : tt_ptr_op(suffix, OP_EQ, NULL);
5514 :
5515 : /* Just duplicate the basename and return it for this mock */
5516 20 : if (sub2) {
5517 : /* If we have sub2, it's the basename, otherwise sub1 */
5518 20 : rv = tor_strdup(sub2);
5519 : } else {
5520 0 : rv = tor_strdup(sub1);
5521 : }
5522 :
5523 20 : done:
5524 20 : return rv;
5525 : }
5526 :
5527 : static char *last_unlinked_path = NULL;
5528 : static int unlinked_count = 0;
5529 :
5530 : static void
5531 12 : mock_unlink_reset(void)
5532 : {
5533 12 : tor_free(last_unlinked_path);
5534 12 : unlinked_count = 0;
5535 12 : }
5536 :
5537 : static int
5538 11 : mock_unlink(const char *path)
5539 : {
5540 11 : tt_ptr_op(path, OP_NE, NULL);
5541 :
5542 11 : tor_free(last_unlinked_path);
5543 11 : last_unlinked_path = tor_strdup(path);
5544 11 : ++unlinked_count;
5545 :
5546 11 : done:
5547 11 : return 0;
5548 : }
5549 :
5550 : static char *last_write_str_path = NULL;
5551 : static uint8_t last_write_str_hash[DIGEST256_LEN];
5552 : static int write_str_count = 0;
5553 :
5554 : static void
5555 9 : mock_write_str_to_file_reset(void)
5556 : {
5557 9 : tor_free(last_write_str_path);
5558 9 : write_str_count = 0;
5559 9 : }
5560 :
5561 : static int
5562 16 : mock_write_str_to_file(const char *path, const char *str, int bin)
5563 : {
5564 16 : size_t len;
5565 16 : uint8_t hash[DIGEST256_LEN];
5566 :
5567 16 : (void)bin;
5568 :
5569 16 : tt_ptr_op(path, OP_NE, NULL);
5570 16 : tt_ptr_op(str, OP_NE, NULL);
5571 :
5572 16 : len = strlen(str);
5573 16 : crypto_digest256((char *)hash, str, len, DIGEST_SHA256);
5574 :
5575 16 : tor_free(last_write_str_path);
5576 16 : last_write_str_path = tor_strdup(path);
5577 16 : memcpy(last_write_str_hash, hash, sizeof(last_write_str_hash));
5578 16 : ++write_str_count;
5579 :
5580 16 : done:
5581 16 : return 0;
5582 : }
5583 :
5584 : static void
5585 1 : test_dir_dump_unparseable_descriptors(void *data)
5586 : {
5587 : /*
5588 : * These bogus descriptors look nothing at all like real bogus descriptors
5589 : * we might see, but we're only testing dump_desc() here, not the parser.
5590 : */
5591 1 : const char *test_desc_type = "squamous";
5592 : /* strlen(test_desc_1) = 583 bytes */
5593 1 : const char *test_desc_1 =
5594 : "The most merciful thing in the world, I think, is the inability of the "
5595 : "human mind to correlate all its contents. We live on a placid island of"
5596 : " ignorance in the midst of black seas of infinity, and it was not meant"
5597 : " that we should voyage far. The sciences, each straining in its own dir"
5598 : "ection, have hitherto harmed us little; but some day the piecing togeth"
5599 : "er of dissociated knowledge will open up such terrifying vistas of real"
5600 : "ity, and of our frightful position therein, that we shall either go mad"
5601 : "from the revelation or flee from the light into the peace and safety of"
5602 : "a new dark age.";
5603 1 : uint8_t test_desc_1_hash[DIGEST256_LEN];
5604 1 : char test_desc_1_hash_str[HEX_DIGEST256_LEN+1];
5605 : /* strlen(test_desc_2) = 650 bytes */
5606 1 : const char *test_desc_2 =
5607 : "I think their predominant colour was a greyish-green, though they had w"
5608 : "hite bellies. They were mostly shiny and slippery, but the ridges of th"
5609 : "eir backs were scaly. Their forms vaguely suggested the anthropoid, whi"
5610 : "le their heads were the heads of fish, with prodigious bulging eyes tha"
5611 : "t never closed. At the sides of their necks were palpitating gills, and"
5612 : "their long paws were webbed. They hopped irregularly, sometimes on two "
5613 : "legs and sometimes on four. I was somehow glad that they had no more th"
5614 : "an four limbs. Their croaking, baying voices, clearly wed tar articulat"
5615 : "e speech, held all the dark shades of expression which their staring fa"
5616 : "ces lacked.";
5617 1 : uint8_t test_desc_2_hash[DIGEST256_LEN];
5618 1 : char test_desc_2_hash_str[HEX_DIGEST256_LEN+1];
5619 : /* strlen(test_desc_3) = 700 bytes */
5620 1 : const char *test_desc_3 =
5621 : "Without knowing what futurism is like, Johansen achieved something very"
5622 : "close to it when he spoke of the city; for instead of describing any de"
5623 : "finite structure or building, he dwells only on broad impressions of va"
5624 : "st angles and stone surfaces - surfaces too great to belong to anything"
5625 : "right or proper for this earth, and impious with horrible images and hi"
5626 : "eroglyphs. I mention his talk about angles because it suggests somethin"
5627 : "g Wilcox had told me of his awful dreams. He said that the geometry of "
5628 : "the dream-place he saw was abnormal, non-Euclidean, and loathsomely red"
5629 : "olent of spheres and dimensions apart from ours. Now an unlettered seam"
5630 : "an felt the same thing whilst gazing at the terrible reality.";
5631 1 : uint8_t test_desc_3_hash[DIGEST256_LEN];
5632 1 : char test_desc_3_hash_str[HEX_DIGEST256_LEN+1];
5633 : /* strlen(test_desc_3) = 604 bytes */
5634 1 : const char *test_desc_4 =
5635 : "So we glanced back simultaneously, it would appear; though no doubt the"
5636 : "incipient motion of one prompted the imitation of the other. As we did "
5637 : "so we flashed both torches full strength at the momentarily thinned mis"
5638 : "t; either from sheer primitive anxiety to see all we could, or in a les"
5639 : "s primitive but equally unconscious effort to dazzle the entity before "
5640 : "we dimmed our light and dodged among the penguins of the labyrinth cent"
5641 : "er ahead. Unhappy act! Not Orpheus himself, or Lot's wife, paid much mo"
5642 : "re dearly for a backward glance. And again came that shocking, wide-ran"
5643 : "ged piping - \"Tekeli-li! Tekeli-li!\"";
5644 1 : uint8_t test_desc_4_hash[DIGEST256_LEN];
5645 1 : char test_desc_4_hash_str[HEX_DIGEST256_LEN+1];
5646 1 : (void)data;
5647 :
5648 : /*
5649 : * Set up options mock so we can force a tiny FIFO size and generate
5650 : * cleanups.
5651 : */
5652 1 : mock_options = tor_malloc(sizeof(or_options_t));
5653 1 : reset_options(mock_options, &mock_get_options_calls);
5654 1 : mock_options->MaxUnparseableDescSizeToLog = 1536;
5655 1 : MOCK(get_options, mock_get_options);
5656 1 : MOCK(check_private_dir, mock_check_private_dir);
5657 1 : MOCK(options_get_dir_fname2_suffix,
5658 : mock_get_datadir_fname);
5659 :
5660 : /*
5661 : * Set up unlink and write mocks
5662 : */
5663 1 : MOCK(tor_unlink, mock_unlink);
5664 1 : mock_unlink_reset();
5665 1 : MOCK(write_str_to_file, mock_write_str_to_file);
5666 1 : mock_write_str_to_file_reset();
5667 :
5668 : /*
5669 : * Compute hashes we'll need to recognize which descriptor is which
5670 : */
5671 1 : crypto_digest256((char *)test_desc_1_hash, test_desc_1,
5672 : strlen(test_desc_1), DIGEST_SHA256);
5673 1 : base16_encode(test_desc_1_hash_str, sizeof(test_desc_1_hash_str),
5674 : (const char *)test_desc_1_hash,
5675 : sizeof(test_desc_1_hash));
5676 1 : crypto_digest256((char *)test_desc_2_hash, test_desc_2,
5677 : strlen(test_desc_2), DIGEST_SHA256);
5678 1 : base16_encode(test_desc_2_hash_str, sizeof(test_desc_2_hash_str),
5679 : (const char *)test_desc_2_hash,
5680 : sizeof(test_desc_2_hash));
5681 1 : crypto_digest256((char *)test_desc_3_hash, test_desc_3,
5682 : strlen(test_desc_3), DIGEST_SHA256);
5683 1 : base16_encode(test_desc_3_hash_str, sizeof(test_desc_3_hash_str),
5684 : (const char *)test_desc_3_hash,
5685 : sizeof(test_desc_3_hash));
5686 1 : crypto_digest256((char *)test_desc_4_hash, test_desc_4,
5687 : strlen(test_desc_4), DIGEST_SHA256);
5688 1 : base16_encode(test_desc_4_hash_str, sizeof(test_desc_4_hash_str),
5689 : (const char *)test_desc_4_hash,
5690 : sizeof(test_desc_4_hash));
5691 :
5692 : /*
5693 : * Reset the FIFO and check its state
5694 : */
5695 1 : dump_desc_fifo_cleanup();
5696 1 : tt_u64_op(len_descs_dumped, OP_EQ, 0);
5697 1 : tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
5698 :
5699 : /*
5700 : * (1) Fire off dump_desc() once; these descriptors should all be safely
5701 : * smaller than configured FIFO size.
5702 : */
5703 :
5704 1 : dump_desc(test_desc_1, test_desc_type);
5705 :
5706 : /*
5707 : * Assert things about the FIFO state
5708 : */
5709 1 : tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_1));
5710 1 : tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
5711 :
5712 : /*
5713 : * Assert things about the mocks
5714 : */
5715 1 : tt_int_op(unlinked_count, OP_EQ, 0);
5716 1 : tt_int_op(write_str_count, OP_EQ, 1);
5717 1 : tt_mem_op(last_write_str_hash, OP_EQ, test_desc_1_hash, DIGEST_SHA256);
5718 :
5719 : /*
5720 : * Reset the FIFO and check its state
5721 : */
5722 1 : dump_desc_fifo_cleanup();
5723 1 : tt_u64_op(len_descs_dumped, OP_EQ, 0);
5724 1 : tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
5725 :
5726 : /*
5727 : * Reset the mocks and check their state
5728 : */
5729 1 : mock_unlink_reset();
5730 1 : mock_write_str_to_file_reset();
5731 1 : tt_int_op(unlinked_count, OP_EQ, 0);
5732 1 : tt_int_op(write_str_count, OP_EQ, 0);
5733 :
5734 : /*
5735 : * (2) Fire off dump_desc() twice; this still should trigger no cleanup.
5736 : */
5737 :
5738 : /* First time */
5739 1 : dump_desc(test_desc_2, test_desc_type);
5740 :
5741 : /*
5742 : * Assert things about the FIFO state
5743 : */
5744 1 : tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_2));
5745 1 : tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
5746 :
5747 : /*
5748 : * Assert things about the mocks
5749 : */
5750 1 : tt_int_op(unlinked_count, OP_EQ, 0);
5751 1 : tt_int_op(write_str_count, OP_EQ, 1);
5752 1 : tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256);
5753 :
5754 : /* Second time */
5755 1 : dump_desc(test_desc_3, test_desc_type);
5756 :
5757 : /*
5758 : * Assert things about the FIFO state
5759 : */
5760 1 : tt_u64_op(len_descs_dumped, OP_EQ,
5761 : strlen(test_desc_2) + strlen(test_desc_3));
5762 1 : tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
5763 :
5764 : /*
5765 : * Assert things about the mocks
5766 : */
5767 1 : tt_int_op(unlinked_count, OP_EQ, 0);
5768 1 : tt_int_op(write_str_count, OP_EQ, 2);
5769 1 : tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256);
5770 :
5771 : /*
5772 : * Reset the FIFO and check its state
5773 : */
5774 1 : dump_desc_fifo_cleanup();
5775 1 : tt_u64_op(len_descs_dumped, OP_EQ, 0);
5776 1 : tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
5777 :
5778 : /*
5779 : * Reset the mocks and check their state
5780 : */
5781 1 : mock_unlink_reset();
5782 1 : mock_write_str_to_file_reset();
5783 1 : tt_int_op(unlinked_count, OP_EQ, 0);
5784 1 : tt_int_op(write_str_count, OP_EQ, 0);
5785 :
5786 : /*
5787 : * (3) Three calls to dump_desc cause a FIFO cleanup
5788 : */
5789 :
5790 : /* First time */
5791 1 : dump_desc(test_desc_4, test_desc_type);
5792 :
5793 : /*
5794 : * Assert things about the FIFO state
5795 : */
5796 1 : tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_4));
5797 1 : tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
5798 :
5799 : /*
5800 : * Assert things about the mocks
5801 : */
5802 1 : tt_int_op(unlinked_count, OP_EQ, 0);
5803 1 : tt_int_op(write_str_count, OP_EQ, 1);
5804 1 : tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
5805 :
5806 : /* Second time */
5807 1 : dump_desc(test_desc_1, test_desc_type);
5808 :
5809 : /*
5810 : * Assert things about the FIFO state
5811 : */
5812 1 : tt_u64_op(len_descs_dumped, OP_EQ,
5813 : strlen(test_desc_4) + strlen(test_desc_1));
5814 1 : tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
5815 :
5816 : /*
5817 : * Assert things about the mocks
5818 : */
5819 1 : tt_int_op(unlinked_count, OP_EQ, 0);
5820 1 : tt_int_op(write_str_count, OP_EQ, 2);
5821 1 : tt_mem_op(last_write_str_hash, OP_EQ, test_desc_1_hash, DIGEST_SHA256);
5822 :
5823 : /* Third time - we should unlink the dump of test_desc_4 here */
5824 1 : dump_desc(test_desc_2, test_desc_type);
5825 :
5826 : /*
5827 : * Assert things about the FIFO state
5828 : */
5829 1 : tt_u64_op(len_descs_dumped, OP_EQ,
5830 : strlen(test_desc_1) + strlen(test_desc_2));
5831 1 : tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
5832 :
5833 : /*
5834 : * Assert things about the mocks
5835 : */
5836 1 : tt_int_op(unlinked_count, OP_EQ, 1);
5837 1 : tt_int_op(write_str_count, OP_EQ, 3);
5838 1 : tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256);
5839 :
5840 : /*
5841 : * Reset the FIFO and check its state
5842 : */
5843 1 : dump_desc_fifo_cleanup();
5844 1 : tt_u64_op(len_descs_dumped, OP_EQ, 0);
5845 1 : tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
5846 :
5847 : /*
5848 : * Reset the mocks and check their state
5849 : */
5850 1 : mock_unlink_reset();
5851 1 : mock_write_str_to_file_reset();
5852 1 : tt_int_op(unlinked_count, OP_EQ, 0);
5853 1 : tt_int_op(write_str_count, OP_EQ, 0);
5854 :
5855 : /*
5856 : * (4) But repeating one (A B B) doesn't overflow and cleanup
5857 : */
5858 :
5859 : /* First time */
5860 1 : dump_desc(test_desc_3, test_desc_type);
5861 :
5862 : /*
5863 : * Assert things about the FIFO state
5864 : */
5865 1 : tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_3));
5866 1 : tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
5867 :
5868 : /*
5869 : * Assert things about the mocks
5870 : */
5871 1 : tt_int_op(unlinked_count, OP_EQ, 0);
5872 1 : tt_int_op(write_str_count, OP_EQ, 1);
5873 1 : tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256);
5874 :
5875 : /* Second time */
5876 1 : dump_desc(test_desc_4, test_desc_type);
5877 :
5878 : /*
5879 : * Assert things about the FIFO state
5880 : */
5881 1 : tt_u64_op(len_descs_dumped, OP_EQ,
5882 : strlen(test_desc_3) + strlen(test_desc_4));
5883 1 : tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
5884 :
5885 : /*
5886 : * Assert things about the mocks
5887 : */
5888 1 : tt_int_op(unlinked_count, OP_EQ, 0);
5889 1 : tt_int_op(write_str_count, OP_EQ, 2);
5890 1 : tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
5891 :
5892 : /* Third time */
5893 1 : dump_desc(test_desc_4, test_desc_type);
5894 :
5895 : /*
5896 : * Assert things about the FIFO state
5897 : */
5898 1 : tt_u64_op(len_descs_dumped, OP_EQ,
5899 : strlen(test_desc_3) + strlen(test_desc_4));
5900 1 : tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
5901 :
5902 : /*
5903 : * Assert things about the mocks
5904 : */
5905 1 : tt_int_op(unlinked_count, OP_EQ, 0);
5906 1 : tt_int_op(write_str_count, OP_EQ, 2);
5907 1 : tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
5908 :
5909 : /*
5910 : * Reset the FIFO and check its state
5911 : */
5912 1 : dump_desc_fifo_cleanup();
5913 1 : tt_u64_op(len_descs_dumped, OP_EQ, 0);
5914 1 : tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
5915 :
5916 : /*
5917 : * Reset the mocks and check their state
5918 : */
5919 1 : mock_unlink_reset();
5920 1 : mock_write_str_to_file_reset();
5921 1 : tt_int_op(unlinked_count, OP_EQ, 0);
5922 1 : tt_int_op(write_str_count, OP_EQ, 0);
5923 :
5924 : /*
5925 : * (5) Same for the (A B A) repetition
5926 : */
5927 :
5928 : /* First time */
5929 1 : dump_desc(test_desc_1, test_desc_type);
5930 :
5931 : /*
5932 : * Assert things about the FIFO state
5933 : */
5934 1 : tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_1));
5935 1 : tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
5936 :
5937 : /*
5938 : * Assert things about the mocks
5939 : */
5940 1 : tt_int_op(unlinked_count, OP_EQ, 0);
5941 1 : tt_int_op(write_str_count, OP_EQ, 1);
5942 1 : tt_mem_op(last_write_str_hash, OP_EQ, test_desc_1_hash, DIGEST_SHA256);
5943 :
5944 : /* Second time */
5945 1 : dump_desc(test_desc_2, test_desc_type);
5946 :
5947 : /*
5948 : * Assert things about the FIFO state
5949 : */
5950 1 : tt_u64_op(len_descs_dumped, OP_EQ,
5951 : strlen(test_desc_1) + strlen(test_desc_2));
5952 1 : tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
5953 :
5954 : /*
5955 : * Assert things about the mocks
5956 : */
5957 1 : tt_int_op(unlinked_count, OP_EQ, 0);
5958 1 : tt_int_op(write_str_count, OP_EQ, 2);
5959 1 : tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256);
5960 :
5961 : /* Third time */
5962 1 : dump_desc(test_desc_1, test_desc_type);
5963 :
5964 : /*
5965 : * Assert things about the FIFO state
5966 : */
5967 1 : tt_u64_op(len_descs_dumped, OP_EQ,
5968 : strlen(test_desc_1) + strlen(test_desc_2));
5969 1 : tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
5970 :
5971 : /*
5972 : * Assert things about the mocks
5973 : */
5974 1 : tt_int_op(unlinked_count, OP_EQ, 0);
5975 1 : tt_int_op(write_str_count, OP_EQ, 2);
5976 1 : tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256);
5977 :
5978 : /*
5979 : * Reset the FIFO and check its state
5980 : */
5981 1 : dump_desc_fifo_cleanup();
5982 1 : tt_u64_op(len_descs_dumped, OP_EQ, 0);
5983 1 : tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
5984 :
5985 : /*
5986 : * Reset the mocks and check their state
5987 : */
5988 1 : mock_unlink_reset();
5989 1 : mock_write_str_to_file_reset();
5990 1 : tt_int_op(unlinked_count, OP_EQ, 0);
5991 1 : tt_int_op(write_str_count, OP_EQ, 0);
5992 :
5993 : /*
5994 : * (6) (A B B C) triggering overflow on C causes A, not B to be unlinked
5995 : */
5996 :
5997 : /* First time */
5998 1 : dump_desc(test_desc_3, test_desc_type);
5999 :
6000 : /*
6001 : * Assert things about the FIFO state
6002 : */
6003 1 : tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_3));
6004 1 : tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
6005 :
6006 : /*
6007 : * Assert things about the mocks
6008 : */
6009 1 : tt_int_op(unlinked_count, OP_EQ, 0);
6010 1 : tt_int_op(write_str_count, OP_EQ, 1);
6011 1 : tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256);
6012 :
6013 : /* Second time */
6014 1 : dump_desc(test_desc_4, test_desc_type);
6015 :
6016 : /*
6017 : * Assert things about the FIFO state
6018 : */
6019 1 : tt_u64_op(len_descs_dumped, OP_EQ,
6020 : strlen(test_desc_3) + strlen(test_desc_4));
6021 1 : tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
6022 :
6023 : /*
6024 : * Assert things about the mocks
6025 : */
6026 1 : tt_int_op(unlinked_count, OP_EQ, 0);
6027 1 : tt_int_op(write_str_count, OP_EQ, 2);
6028 1 : tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
6029 :
6030 : /* Third time */
6031 1 : dump_desc(test_desc_4, test_desc_type);
6032 :
6033 : /*
6034 : * Assert things about the FIFO state
6035 : */
6036 1 : tt_u64_op(len_descs_dumped, OP_EQ,
6037 : strlen(test_desc_3) + strlen(test_desc_4));
6038 1 : tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
6039 :
6040 : /*
6041 : * Assert things about the mocks
6042 : */
6043 1 : tt_int_op(unlinked_count, OP_EQ, 0);
6044 1 : tt_int_op(write_str_count, OP_EQ, 2);
6045 1 : tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
6046 :
6047 : /* Fourth time - we should unlink the dump of test_desc_3 here */
6048 1 : dump_desc(test_desc_1, test_desc_type);
6049 :
6050 : /*
6051 : * Assert things about the FIFO state
6052 : */
6053 1 : tt_u64_op(len_descs_dumped, OP_EQ,
6054 : strlen(test_desc_4) + strlen(test_desc_1));
6055 1 : tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
6056 :
6057 : /*
6058 : * Assert things about the mocks
6059 : */
6060 1 : tt_int_op(unlinked_count, OP_EQ, 1);
6061 1 : tt_int_op(write_str_count, OP_EQ, 3);
6062 1 : tt_mem_op(last_write_str_hash, OP_EQ, test_desc_1_hash, DIGEST_SHA256);
6063 :
6064 : /*
6065 : * Reset the FIFO and check its state
6066 : */
6067 1 : dump_desc_fifo_cleanup();
6068 1 : tt_u64_op(len_descs_dumped, OP_EQ, 0);
6069 1 : tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
6070 :
6071 : /*
6072 : * Reset the mocks and check their state
6073 : */
6074 1 : mock_unlink_reset();
6075 1 : mock_write_str_to_file_reset();
6076 1 : tt_int_op(unlinked_count, OP_EQ, 0);
6077 1 : tt_int_op(write_str_count, OP_EQ, 0);
6078 :
6079 : /*
6080 : * (7) (A B A C) triggering overflow on C causes B, not A to be unlinked
6081 : */
6082 :
6083 : /* First time */
6084 1 : dump_desc(test_desc_2, test_desc_type);
6085 :
6086 : /*
6087 : * Assert things about the FIFO state
6088 : */
6089 1 : tt_u64_op(len_descs_dumped, OP_EQ, strlen(test_desc_2));
6090 1 : tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 1);
6091 :
6092 : /*
6093 : * Assert things about the mocks
6094 : */
6095 1 : tt_int_op(unlinked_count, OP_EQ, 0);
6096 1 : tt_int_op(write_str_count, OP_EQ, 1);
6097 1 : tt_mem_op(last_write_str_hash, OP_EQ, test_desc_2_hash, DIGEST_SHA256);
6098 :
6099 : /* Second time */
6100 1 : dump_desc(test_desc_3, test_desc_type);
6101 :
6102 : /*
6103 : * Assert things about the FIFO state
6104 : */
6105 1 : tt_u64_op(len_descs_dumped, OP_EQ,
6106 : strlen(test_desc_2) + strlen(test_desc_3));
6107 1 : tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
6108 :
6109 : /*
6110 : * Assert things about the mocks
6111 : */
6112 1 : tt_int_op(unlinked_count, OP_EQ, 0);
6113 1 : tt_int_op(write_str_count, OP_EQ, 2);
6114 1 : tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256);
6115 :
6116 : /* Third time */
6117 1 : dump_desc(test_desc_2, test_desc_type);
6118 :
6119 : /*
6120 : * Assert things about the FIFO state
6121 : */
6122 1 : tt_u64_op(len_descs_dumped, OP_EQ,
6123 : strlen(test_desc_2) + strlen(test_desc_3));
6124 1 : tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
6125 :
6126 : /*
6127 : * Assert things about the mocks
6128 : */
6129 1 : tt_int_op(unlinked_count, OP_EQ, 0);
6130 1 : tt_int_op(write_str_count, OP_EQ, 2);
6131 1 : tt_mem_op(last_write_str_hash, OP_EQ, test_desc_3_hash, DIGEST_SHA256);
6132 :
6133 : /* Fourth time - we should unlink the dump of test_desc_3 here */
6134 1 : dump_desc(test_desc_4, test_desc_type);
6135 :
6136 : /*
6137 : * Assert things about the FIFO state
6138 : */
6139 1 : tt_u64_op(len_descs_dumped, OP_EQ,
6140 : strlen(test_desc_2) + strlen(test_desc_4));
6141 1 : tt_assert(descs_dumped != NULL && smartlist_len(descs_dumped) == 2);
6142 :
6143 : /*
6144 : * Assert things about the mocks
6145 : */
6146 1 : tt_int_op(unlinked_count, OP_EQ, 1);
6147 1 : tt_int_op(write_str_count, OP_EQ, 3);
6148 1 : tt_mem_op(last_write_str_hash, OP_EQ, test_desc_4_hash, DIGEST_SHA256);
6149 :
6150 : /*
6151 : * Reset the FIFO and check its state
6152 : */
6153 1 : dump_desc_fifo_cleanup();
6154 1 : tt_u64_op(len_descs_dumped, OP_EQ, 0);
6155 1 : tt_assert(descs_dumped == NULL || smartlist_len(descs_dumped) == 0);
6156 :
6157 : /*
6158 : * Reset the mocks and check their state
6159 : */
6160 1 : mock_unlink_reset();
6161 1 : mock_write_str_to_file_reset();
6162 1 : tt_int_op(unlinked_count, OP_EQ, 0);
6163 1 : tt_int_op(write_str_count, OP_EQ, 0);
6164 :
6165 1 : done:
6166 :
6167 : /* Clean up the fifo */
6168 1 : dump_desc_fifo_cleanup();
6169 :
6170 : /* Remove mocks */
6171 1 : UNMOCK(tor_unlink);
6172 1 : mock_unlink_reset();
6173 1 : UNMOCK(write_str_to_file);
6174 1 : mock_write_str_to_file_reset();
6175 1 : UNMOCK(options_get_dir_fname2_suffix);
6176 1 : UNMOCK(check_private_dir);
6177 1 : UNMOCK(get_options);
6178 1 : tor_free(mock_options);
6179 1 : mock_options = NULL;
6180 :
6181 1 : return;
6182 : }
6183 :
6184 : /* Variables for reset_read_file_to_str_mock() */
6185 :
6186 : static int enforce_expected_filename = 0;
6187 : static char *expected_filename = NULL;
6188 : static char *file_content = NULL;
6189 : static size_t file_content_len = 0;
6190 : static struct stat file_stat;
6191 : static int read_count = 0, read_call_count = 0;
6192 :
6193 : static void
6194 3 : reset_read_file_to_str_mock(void)
6195 : {
6196 3 : tor_free(expected_filename);
6197 3 : tor_free(file_content);
6198 3 : file_content_len = 0;
6199 3 : memset(&file_stat, 0, sizeof(file_stat));
6200 3 : read_count = 0;
6201 3 : read_call_count = 0;
6202 3 : }
6203 :
6204 : static char *
6205 3 : read_file_to_str_mock(const char *filename, int flags,
6206 : struct stat *stat_out) {
6207 3 : char *result = NULL;
6208 :
6209 : /* Insist we got a filename */
6210 3 : tt_ptr_op(filename, OP_NE, NULL);
6211 :
6212 : /* We ignore flags */
6213 3 : (void)flags;
6214 :
6215 : /* Bump the call count */
6216 3 : ++read_call_count;
6217 :
6218 3 : if (enforce_expected_filename) {
6219 1 : tt_assert(expected_filename);
6220 1 : tt_str_op(filename, OP_EQ, expected_filename);
6221 : }
6222 :
6223 3 : if (expected_filename != NULL &&
6224 2 : file_content != NULL &&
6225 2 : strcmp(filename, expected_filename) == 0) {
6226 : /* You asked for it, you got it */
6227 :
6228 : /*
6229 : * This is the same behavior as the real read_file_to_str();
6230 : * if there's a NUL, the real size ends up in stat_out.
6231 : */
6232 2 : result = tor_malloc(file_content_len + 1);
6233 2 : if (file_content_len > 0) {
6234 2 : memcpy(result, file_content, file_content_len);
6235 : }
6236 2 : result[file_content_len] = '\0';
6237 :
6238 : /* Do we need to set up stat_out? */
6239 2 : if (stat_out != NULL) {
6240 2 : memcpy(stat_out, &file_stat, sizeof(file_stat));
6241 : /* We always return the correct length here */
6242 2 : stat_out->st_size = file_content_len;
6243 : }
6244 :
6245 : /* Wooo, we have a return value - bump the counter */
6246 2 : ++read_count;
6247 : }
6248 : /* else no match, return NULL */
6249 :
6250 1 : done:
6251 3 : return result;
6252 : }
6253 :
6254 : /* This one tests dump_desc_populate_one_file() */
6255 : static void
6256 1 : test_dir_populate_dump_desc_fifo(void *data)
6257 : {
6258 1 : const char *dirname = "foo";
6259 1 : const char *fname = NULL;
6260 1 : dumped_desc_t *ent;
6261 :
6262 1 : (void)data;
6263 :
6264 : /*
6265 : * Set up unlink and read_file_to_str mocks
6266 : */
6267 1 : MOCK(tor_unlink, mock_unlink);
6268 1 : mock_unlink_reset();
6269 1 : MOCK(read_file_to_str, read_file_to_str_mock);
6270 1 : reset_read_file_to_str_mock();
6271 :
6272 : /* Check state of unlink mock */
6273 1 : tt_int_op(unlinked_count, OP_EQ, 0);
6274 :
6275 : /* Some cases that should fail before trying to read the file */
6276 1 : ent = dump_desc_populate_one_file(dirname, "bar");
6277 1 : tt_ptr_op(ent, OP_EQ, NULL);
6278 1 : tt_int_op(unlinked_count, OP_EQ, 1);
6279 1 : tt_int_op(read_count, OP_EQ, 0);
6280 1 : tt_int_op(read_call_count, OP_EQ, 0);
6281 :
6282 1 : ent = dump_desc_populate_one_file(dirname, "unparseable-desc");
6283 1 : tt_ptr_op(ent, OP_EQ, NULL);
6284 1 : tt_int_op(unlinked_count, OP_EQ, 2);
6285 1 : tt_int_op(read_count, OP_EQ, 0);
6286 1 : tt_int_op(read_call_count, OP_EQ, 0);
6287 :
6288 1 : ent = dump_desc_populate_one_file(dirname, "unparseable-desc.baz");
6289 1 : tt_ptr_op(ent, OP_EQ, NULL);
6290 1 : tt_int_op(unlinked_count, OP_EQ, 3);
6291 1 : tt_int_op(read_count, OP_EQ, 0);
6292 1 : tt_int_op(read_call_count, OP_EQ, 0);
6293 :
6294 1 : ent = dump_desc_populate_one_file(
6295 : dirname,
6296 : "unparseable-desc.08AE85E90461F59E");
6297 1 : tt_ptr_op(ent, OP_EQ, NULL);
6298 1 : tt_int_op(unlinked_count, OP_EQ, 4);
6299 1 : tt_int_op(read_count, OP_EQ, 0);
6300 1 : tt_int_op(read_call_count, OP_EQ, 0);
6301 :
6302 1 : ent = dump_desc_populate_one_file(
6303 : dirname,
6304 : "unparseable-desc.08AE85E90461F59EDF0981323F3A70D02B55AB54B44B04F"
6305 : "287D72F7B72F242E85C8CB0EDA8854A99");
6306 1 : tt_ptr_op(ent, OP_EQ, NULL);
6307 1 : tt_int_op(unlinked_count, OP_EQ, 5);
6308 1 : tt_int_op(read_count, OP_EQ, 0);
6309 1 : tt_int_op(read_call_count, OP_EQ, 0);
6310 :
6311 : /* This is a correct-length digest but base16_decode() will fail */
6312 1 : ent = dump_desc_populate_one_file(
6313 : dirname,
6314 : "unparseable-desc.68219B8BGE64B705A6FFC728C069DC596216D60A7D7520C"
6315 : "D5ECE250D912E686B");
6316 1 : tt_ptr_op(ent, OP_EQ, NULL);
6317 1 : tt_int_op(unlinked_count, OP_EQ, 6);
6318 1 : tt_int_op(read_count, OP_EQ, 0);
6319 1 : tt_int_op(read_call_count, OP_EQ, 0);
6320 :
6321 : /* This one has a correctly formed filename and should try reading */
6322 :
6323 : /* Read fails */
6324 1 : ent = dump_desc_populate_one_file(
6325 : dirname,
6326 : "unparseable-desc.DF0981323F3A70D02B55AB54B44B04F287D72F7B72F242E"
6327 : "85C8CB0EDA8854A99");
6328 1 : tt_ptr_op(ent, OP_EQ, NULL);
6329 1 : tt_int_op(unlinked_count, OP_EQ, 7);
6330 1 : tt_int_op(read_count, OP_EQ, 0);
6331 1 : tt_int_op(read_call_count, OP_EQ, 1);
6332 :
6333 : /* This read will succeed but the digest won't match the file content */
6334 1 : fname =
6335 : "unparseable-desc."
6336 : "DF0981323F3A70D02B55AB54B44B04F287D72F7B72F242E85C8CB0EDA8854A99";
6337 1 : enforce_expected_filename = 1;
6338 1 : tor_asprintf(&expected_filename, "%s%s%s", dirname, PATH_SEPARATOR, fname);
6339 1 : file_content = tor_strdup("hanc culpam maiorem an illam dicam?");
6340 1 : file_content_len = strlen(file_content);
6341 1 : file_stat.st_mtime = 123456;
6342 1 : ent = dump_desc_populate_one_file(dirname, fname);
6343 1 : enforce_expected_filename = 0;
6344 1 : tt_ptr_op(ent, OP_EQ, NULL);
6345 1 : tt_int_op(unlinked_count, OP_EQ, 8);
6346 1 : tt_int_op(read_count, OP_EQ, 1);
6347 1 : tt_int_op(read_call_count, OP_EQ, 2);
6348 1 : tor_free(expected_filename);
6349 1 : tor_free(file_content);
6350 :
6351 : /* This one will match */
6352 1 : fname =
6353 : "unparseable-desc."
6354 : "0786C7173447B7FB033FFCA2FC47C3CF71C30DD47CA8236D3FC7FF35853271C6";
6355 1 : tor_asprintf(&expected_filename, "%s%s%s", dirname, PATH_SEPARATOR, fname);
6356 1 : file_content = tor_strdup("hanc culpam maiorem an illam dicam?");
6357 1 : file_content_len = strlen(file_content);
6358 1 : file_stat.st_mtime = 789012;
6359 1 : ent = dump_desc_populate_one_file(dirname, fname);
6360 1 : tt_ptr_op(ent, OP_NE, NULL);
6361 1 : tt_int_op(unlinked_count, OP_EQ, 8);
6362 1 : tt_int_op(read_count, OP_EQ, 2);
6363 1 : tt_int_op(read_call_count, OP_EQ, 3);
6364 1 : tt_str_op(ent->filename, OP_EQ, expected_filename);
6365 1 : tt_int_op(ent->len, OP_EQ, file_content_len);
6366 1 : tt_int_op(ent->when, OP_EQ, file_stat.st_mtime);
6367 1 : tor_free(ent->filename);
6368 1 : tor_free(ent);
6369 1 : tor_free(expected_filename);
6370 :
6371 : /*
6372 : * Reset the mocks and check their state
6373 : */
6374 1 : mock_unlink_reset();
6375 1 : tt_int_op(unlinked_count, OP_EQ, 0);
6376 1 : reset_read_file_to_str_mock();
6377 1 : tt_int_op(read_count, OP_EQ, 0);
6378 :
6379 1 : done:
6380 :
6381 1 : UNMOCK(tor_unlink);
6382 1 : mock_unlink_reset();
6383 1 : UNMOCK(read_file_to_str);
6384 1 : reset_read_file_to_str_mock();
6385 :
6386 1 : tor_free(file_content);
6387 :
6388 1 : return;
6389 : }
6390 :
6391 : static smartlist_t *
6392 1 : listdir_mock(const char *dname)
6393 : {
6394 1 : smartlist_t *l;
6395 :
6396 : /* Ignore the name, always return this list */
6397 1 : (void)dname;
6398 :
6399 1 : l = smartlist_new();
6400 1 : smartlist_add_strdup(l, "foo");
6401 1 : smartlist_add_strdup(l, "bar");
6402 1 : smartlist_add_strdup(l, "baz");
6403 :
6404 1 : return l;
6405 : }
6406 :
6407 : static dumped_desc_t *
6408 3 : pop_one_mock(const char *dirname, const char *f)
6409 : {
6410 3 : dumped_desc_t *ent = NULL;
6411 :
6412 3 : if (dirname != NULL && strcmp(dirname, "d") == 0) {
6413 3 : if (f != NULL && strcmp(f, "foo") == 0) {
6414 1 : ent = tor_malloc_zero(sizeof(*ent));
6415 1 : ent->filename = tor_strdup("d/foo");
6416 1 : ent->len = 123;
6417 1 : ent->digest_sha256[0] = 1;
6418 1 : ent->when = 1024;
6419 2 : } else if (f != NULL && strcmp(f, "bar") == 0) {
6420 1 : ent = tor_malloc_zero(sizeof(*ent));
6421 1 : ent->filename = tor_strdup("d/bar");
6422 1 : ent->len = 456;
6423 1 : ent->digest_sha256[0] = 2;
6424 : /*
6425 : * Note that the timestamps are in a different order than
6426 : * listdir_mock() returns; we're testing the sort order.
6427 : */
6428 1 : ent->when = 512;
6429 1 : } else if (f != NULL && strcmp(f, "baz") == 0) {
6430 1 : ent = tor_malloc_zero(sizeof(*ent));
6431 1 : ent->filename = tor_strdup("d/baz");
6432 1 : ent->len = 789;
6433 1 : ent->digest_sha256[0] = 3;
6434 1 : ent->when = 768;
6435 : }
6436 : }
6437 :
6438 3 : return ent;
6439 : }
6440 :
6441 : /* This one tests dump_desc_populate_fifo_from_directory() */
6442 : static void
6443 1 : test_dir_populate_dump_desc_fifo_2(void *data)
6444 : {
6445 1 : dumped_desc_t *ent = NULL;
6446 :
6447 1 : (void)data;
6448 :
6449 : /* Set up the mocks */
6450 1 : MOCK(tor_listdir, listdir_mock);
6451 1 : MOCK(dump_desc_populate_one_file, pop_one_mock);
6452 :
6453 : /* Run dump_desc_populate_fifo_from_directory() */
6454 1 : descs_dumped = NULL;
6455 1 : len_descs_dumped = 0;
6456 1 : dump_desc_populate_fifo_from_directory("d");
6457 1 : tt_assert(descs_dumped != NULL);
6458 1 : tt_int_op(smartlist_len(descs_dumped), OP_EQ, 3);
6459 1 : tt_u64_op(len_descs_dumped, OP_EQ, 1368);
6460 1 : ent = smartlist_get(descs_dumped, 0);
6461 1 : tt_str_op(ent->filename, OP_EQ, "d/bar");
6462 1 : tt_int_op(ent->len, OP_EQ, 456);
6463 1 : tt_int_op(ent->when, OP_EQ, 512);
6464 1 : ent = smartlist_get(descs_dumped, 1);
6465 1 : tt_str_op(ent->filename, OP_EQ, "d/baz");
6466 1 : tt_int_op(ent->len, OP_EQ, 789);
6467 1 : tt_int_op(ent->when, OP_EQ, 768);
6468 1 : ent = smartlist_get(descs_dumped, 2);
6469 1 : tt_str_op(ent->filename, OP_EQ, "d/foo");
6470 1 : tt_int_op(ent->len, OP_EQ, 123);
6471 1 : tt_int_op(ent->when, OP_EQ, 1024);
6472 :
6473 1 : done:
6474 1 : dump_desc_fifo_cleanup();
6475 :
6476 1 : UNMOCK(dump_desc_populate_one_file);
6477 1 : UNMOCK(tor_listdir);
6478 :
6479 1 : return;
6480 : }
6481 :
6482 : static int mock_networkstatus_consensus_is_bootstrapping_value = 0;
6483 : static int
6484 28 : mock_networkstatus_consensus_is_bootstrapping(time_t now)
6485 : {
6486 28 : (void)now;
6487 28 : return mock_networkstatus_consensus_is_bootstrapping_value;
6488 : }
6489 :
6490 : static int mock_networkstatus_consensus_can_use_extra_fallbacks_value = 0;
6491 : static int
6492 16 : mock_networkstatus_consensus_can_use_extra_fallbacks(
6493 : const or_options_t *options)
6494 : {
6495 16 : (void)options;
6496 16 : return mock_networkstatus_consensus_can_use_extra_fallbacks_value;
6497 : }
6498 :
6499 : static int mock_num_bridges_usable_value = 0;
6500 : static int
6501 16 : mock_num_bridges_usable(int use_maybe_reachable)
6502 : {
6503 16 : (void)use_maybe_reachable;
6504 16 : return mock_num_bridges_usable_value;
6505 : }
6506 :
6507 : /* data is a 3 character nul-terminated string.
6508 : * If data[0] is 'b', set bootstrapping, anything else means not bootstrapping
6509 : * If data[1] is 'f', set extra fallbacks, anything else means no extra
6510 : * If data[2] is 'f', set running bridges, anything else means no extra
6511 : * fallbacks.
6512 : */
6513 : static void
6514 8 : test_dir_find_dl_min_delay(void* data)
6515 : {
6516 8 : const char *str = (const char *)data;
6517 :
6518 8 : tt_assert(strlen(data) == 3);
6519 :
6520 8 : if (str[0] == 'b') {
6521 4 : mock_networkstatus_consensus_is_bootstrapping_value = 1;
6522 : } else {
6523 4 : mock_networkstatus_consensus_is_bootstrapping_value = 0;
6524 : }
6525 :
6526 8 : if (str[1] == 'f') {
6527 4 : mock_networkstatus_consensus_can_use_extra_fallbacks_value = 1;
6528 : } else {
6529 4 : mock_networkstatus_consensus_can_use_extra_fallbacks_value = 0;
6530 : }
6531 :
6532 8 : if (str[2] == 'r') {
6533 : /* Any positive, non-zero value should work */
6534 4 : mock_num_bridges_usable_value = 2;
6535 : } else {
6536 4 : mock_num_bridges_usable_value = 0;
6537 : }
6538 :
6539 8 : MOCK(networkstatus_consensus_is_bootstrapping,
6540 : mock_networkstatus_consensus_is_bootstrapping);
6541 8 : MOCK(networkstatus_consensus_can_use_extra_fallbacks,
6542 : mock_networkstatus_consensus_can_use_extra_fallbacks);
6543 8 : MOCK(num_bridges_usable,
6544 : mock_num_bridges_usable);
6545 :
6546 8 : download_status_t dls;
6547 :
6548 8 : const int server=10, client=20, server_cons=30, client_cons=40;
6549 8 : const int client_boot_auth_only_cons=50, client_boot_auth_cons=60;
6550 8 : const int client_boot_fallback_cons=70, bridge=80, bridge_bootstrap=90;
6551 :
6552 8 : mock_options = tor_malloc(sizeof(or_options_t));
6553 8 : reset_options(mock_options, &mock_get_options_calls);
6554 8 : MOCK(get_options, mock_get_options);
6555 :
6556 8 : mock_options->TestingServerDownloadInitialDelay = server;
6557 8 : mock_options->TestingClientDownloadInitialDelay = client;
6558 8 : mock_options->TestingServerConsensusDownloadInitialDelay = server_cons;
6559 8 : mock_options->TestingClientConsensusDownloadInitialDelay = client_cons;
6560 8 : mock_options->ClientBootstrapConsensusAuthorityOnlyDownloadInitialDelay =
6561 : client_boot_auth_only_cons;
6562 8 : mock_options->ClientBootstrapConsensusAuthorityDownloadInitialDelay =
6563 : client_boot_auth_cons;
6564 8 : mock_options->ClientBootstrapConsensusFallbackDownloadInitialDelay =
6565 : client_boot_fallback_cons;
6566 8 : mock_options->TestingBridgeDownloadInitialDelay = bridge;
6567 8 : mock_options->TestingBridgeBootstrapDownloadInitialDelay = bridge_bootstrap;
6568 :
6569 8 : dls.schedule = DL_SCHED_GENERIC;
6570 : /* client */
6571 8 : mock_options->ClientOnly = 1;
6572 8 : tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, client);
6573 8 : mock_options->ClientOnly = 0;
6574 :
6575 : /* dir mode */
6576 8 : mock_options->DirPort_set = 1;
6577 8 : mock_options->DirCache = 1;
6578 8 : tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, server);
6579 8 : mock_options->DirPort_set = 0;
6580 8 : mock_options->DirCache = 0;
6581 :
6582 8 : dls.schedule = DL_SCHED_CONSENSUS;
6583 : /* public server mode */
6584 8 : mock_options->ORPort_set = 1;
6585 8 : tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, server_cons);
6586 8 : mock_options->ORPort_set = 0;
6587 :
6588 : /* client and bridge modes */
6589 8 : if (networkstatus_consensus_is_bootstrapping(time(NULL))) {
6590 4 : if (networkstatus_consensus_can_use_extra_fallbacks(mock_options)) {
6591 2 : dls.want_authority = 1;
6592 : /* client */
6593 2 : mock_options->ClientOnly = 1;
6594 2 : tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6595 : client_boot_auth_cons);
6596 2 : mock_options->ClientOnly = 0;
6597 :
6598 : /* bridge relay */
6599 2 : mock_options->ORPort_set = 1;
6600 2 : mock_options->BridgeRelay = 1;
6601 2 : tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6602 : client_boot_auth_cons);
6603 2 : mock_options->ORPort_set = 0;
6604 2 : mock_options->BridgeRelay = 0;
6605 :
6606 2 : dls.want_authority = 0;
6607 : /* client */
6608 2 : mock_options->ClientOnly = 1;
6609 2 : tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6610 : client_boot_fallback_cons);
6611 2 : mock_options->ClientOnly = 0;
6612 :
6613 : /* bridge relay */
6614 2 : mock_options->ORPort_set = 1;
6615 2 : mock_options->BridgeRelay = 1;
6616 2 : tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6617 : client_boot_fallback_cons);
6618 2 : mock_options->ORPort_set = 0;
6619 2 : mock_options->BridgeRelay = 0;
6620 :
6621 : } else {
6622 : /* dls.want_authority is ignored */
6623 : /* client */
6624 2 : mock_options->ClientOnly = 1;
6625 2 : tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6626 : client_boot_auth_only_cons);
6627 2 : mock_options->ClientOnly = 0;
6628 :
6629 : /* bridge relay */
6630 2 : mock_options->ORPort_set = 1;
6631 2 : mock_options->BridgeRelay = 1;
6632 2 : tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6633 : client_boot_auth_only_cons);
6634 2 : mock_options->ORPort_set = 0;
6635 2 : mock_options->BridgeRelay = 0;
6636 : }
6637 : } else {
6638 : /* client */
6639 4 : mock_options->ClientOnly = 1;
6640 4 : tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6641 : client_cons);
6642 4 : mock_options->ClientOnly = 0;
6643 :
6644 : /* bridge relay */
6645 4 : mock_options->ORPort_set = 1;
6646 4 : mock_options->BridgeRelay = 1;
6647 4 : tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
6648 : client_cons);
6649 4 : mock_options->ORPort_set = 0;
6650 4 : mock_options->BridgeRelay = 0;
6651 : }
6652 :
6653 8 : dls.schedule = DL_SCHED_BRIDGE;
6654 : /* client */
6655 8 : mock_options->ClientOnly = 1;
6656 8 : mock_options->UseBridges = 1;
6657 8 : if (num_bridges_usable(0) > 0) {
6658 4 : tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, bridge);
6659 : } else {
6660 4 : tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, bridge_bootstrap);
6661 : }
6662 :
6663 4 : done:
6664 8 : UNMOCK(networkstatus_consensus_is_bootstrapping);
6665 8 : UNMOCK(networkstatus_consensus_can_use_extra_fallbacks);
6666 8 : UNMOCK(num_bridges_usable);
6667 8 : UNMOCK(get_options);
6668 8 : tor_free(mock_options);
6669 8 : mock_options = NULL;
6670 8 : }
6671 :
6672 : static void
6673 1 : test_dir_matching_flags(void *arg)
6674 : {
6675 1 : (void) arg;
6676 1 : routerstatus_t *rs_noflags = NULL;
6677 1 : routerstatus_t *rs = NULL;
6678 1 : char *s = NULL;
6679 :
6680 1 : smartlist_t *tokens = smartlist_new();
6681 1 : memarea_t *area = memarea_new();
6682 :
6683 1 : int expected_val_when_unused = 0;
6684 :
6685 1 : const char *ex_noflags =
6686 : "r example hereiswhereyouridentitygoes 2015-08-30 12:00:00 "
6687 : "192.168.0.1 9001 0\n"
6688 : "m thisoneislongerbecauseitisa256bitmddigest33\n"
6689 : "s\n"
6690 : "pr Link=4\n";
6691 1 : const char *cp = ex_noflags;
6692 1 : rs_noflags = routerstatus_parse_entry_from_string(
6693 : area, &cp,
6694 : cp + strlen(cp),
6695 : tokens, NULL, NULL,
6696 : MAX_SUPPORTED_CONSENSUS_METHOD, FLAV_MICRODESC);
6697 1 : tt_assert(rs_noflags);
6698 :
6699 : #define FLAG(string, field) STMT_BEGIN { \
6700 : tor_asprintf(&s,\
6701 : "r example hereiswhereyouridentitygoes 2015-08-30 12:00:00 " \
6702 : "192.168.0.1 9001 0\n" \
6703 : "m thisoneislongerbecauseitisa256bitmddigest33\n" \
6704 : "pr Link=4\n" \
6705 : "s %s\n", string); \
6706 : cp = s; \
6707 : rs = routerstatus_parse_entry_from_string( \
6708 : area, &cp, \
6709 : cp + strlen(cp), \
6710 : tokens, NULL, NULL, \
6711 : MAX_SUPPORTED_CONSENSUS_METHOD, FLAV_MICRODESC); \
6712 : /* the field should usually be 0 when no flags are listed */ \
6713 : tt_int_op(rs_noflags->field, OP_EQ, expected_val_when_unused); \
6714 : /* the field should be 1 when this flags islisted */ \
6715 : tt_int_op(rs->field, OP_EQ, 1); \
6716 : tor_free(s); \
6717 : routerstatus_free(rs); \
6718 : } STMT_END
6719 :
6720 1 : FLAG("Authority", is_authority);
6721 1 : FLAG("BadExit", is_bad_exit);
6722 1 : FLAG("Exit", is_exit);
6723 1 : FLAG("Fast", is_fast);
6724 1 : FLAG("Guard", is_possible_guard);
6725 1 : FLAG("HSDir", is_hs_dir);
6726 1 : FLAG("Stable", is_stable);
6727 1 : FLAG("StaleDesc", is_staledesc);
6728 1 : FLAG("V2Dir", is_v2_dir);
6729 :
6730 : // These flags are assumed to be set whether they're declared or not.
6731 1 : expected_val_when_unused = 1;
6732 1 : FLAG("Running", is_flagged_running);
6733 1 : FLAG("Valid", is_valid);
6734 1 : expected_val_when_unused = 0;
6735 :
6736 : // These flags are no longer used, but still parsed.
6737 1 : FLAG("Named", is_named);
6738 1 : FLAG("Unnamed", is_unnamed);
6739 :
6740 1 : done:
6741 1 : tor_free(s);
6742 1 : routerstatus_free(rs);
6743 1 : routerstatus_free(rs_noflags);
6744 1 : memarea_drop_all(area);
6745 1 : smartlist_free(tokens);
6746 1 : }
6747 :
6748 : static void
6749 1 : test_dir_assumed_flags(void *arg)
6750 : {
6751 1 : (void)arg;
6752 1 : smartlist_t *tokens = smartlist_new();
6753 1 : memarea_t *area = memarea_new();
6754 1 : routerstatus_t *rs = NULL;
6755 :
6756 : /* We can assume that consensus method is higher than 24, so Running and
6757 : * Valid are always implicitly set */
6758 1 : const char *str1 =
6759 : "r example hereiswhereyouridentitygoes 2015-08-30 12:00:00 "
6760 : "192.168.0.1 9001 0\n"
6761 : "m thisoneislongerbecauseitisa256bitmddigest33\n"
6762 : "s Fast Guard Stable\n"
6763 : "pr Link=4\n";
6764 1 : const char *eos = str1 + strlen(str1);
6765 :
6766 1 : const char *cp = str1;
6767 1 : rs = routerstatus_parse_entry_from_string(area, &cp, eos, tokens, NULL, NULL,
6768 : 24, FLAV_MICRODESC);
6769 1 : tt_assert(rs);
6770 1 : tt_assert(rs->is_flagged_running);
6771 1 : tt_assert(rs->is_valid);
6772 1 : tt_assert(! rs->is_exit);
6773 1 : tt_assert(rs->is_fast);
6774 :
6775 1 : done:
6776 1 : smartlist_free(tokens);
6777 1 : memarea_drop_all(area);
6778 1 : routerstatus_free(rs);
6779 1 : }
6780 :
6781 : static void
6782 1 : test_dir_post_parsing(void *arg)
6783 : {
6784 1 : (void) arg;
6785 :
6786 : /* Test the version parsing from an HS descriptor publish request. */
6787 : {
6788 1 : const char *end;
6789 1 : const char *prefix = "/tor/hs/";
6790 1 : int version = parse_hs_version_from_post("/tor/hs//publish", prefix, &end);
6791 1 : tt_int_op(version, OP_EQ, -1);
6792 1 : tt_ptr_op(end, OP_EQ, NULL);
6793 1 : version = parse_hs_version_from_post("/tor/hs/a/publish", prefix, &end);
6794 1 : tt_int_op(version, OP_EQ, -1);
6795 1 : tt_ptr_op(end, OP_EQ, NULL);
6796 1 : version = parse_hs_version_from_post("/tor/hs/3/publish", prefix, &end);
6797 1 : tt_int_op(version, OP_EQ, 3);
6798 1 : tt_str_op(end, OP_EQ, "/publish");
6799 1 : version = parse_hs_version_from_post("/tor/hs/42/publish", prefix, &end);
6800 1 : tt_int_op(version, OP_EQ, 42);
6801 1 : tt_str_op(end, OP_EQ, "/publish");
6802 1 : version = parse_hs_version_from_post("/tor/hs/18163/publish",prefix, &end);
6803 1 : tt_int_op(version, OP_EQ, 18163);
6804 1 : tt_str_op(end, OP_EQ, "/publish");
6805 1 : version = parse_hs_version_from_post("JUNKJUNKJUNK", prefix, &end);
6806 1 : tt_int_op(version, OP_EQ, -1);
6807 1 : tt_ptr_op(end, OP_EQ, NULL);
6808 1 : version = parse_hs_version_from_post("/tor/hs/3/publish", "blah", &end);
6809 1 : tt_int_op(version, OP_EQ, -1);
6810 1 : tt_ptr_op(end, OP_EQ, NULL);
6811 : /* Missing the '/' at the end of the prefix. */
6812 1 : version = parse_hs_version_from_post("/tor/hs/3/publish", "/tor/hs", &end);
6813 1 : tt_int_op(version, OP_EQ, -1);
6814 1 : tt_ptr_op(end, OP_EQ, NULL);
6815 1 : version = parse_hs_version_from_post("/random/blah/tor/hs/3/publish",
6816 : prefix, &end);
6817 1 : tt_int_op(version, OP_EQ, -1);
6818 1 : tt_ptr_op(end, OP_EQ, NULL);
6819 1 : version = parse_hs_version_from_post("/tor/hs/3/publish/random/junk",
6820 : prefix, &end);
6821 1 : tt_int_op(version, OP_EQ, 3);
6822 1 : tt_str_op(end, OP_EQ, "/publish/random/junk");
6823 1 : version = parse_hs_version_from_post("/tor/hs/-1/publish", prefix, &end);
6824 1 : tt_int_op(version, OP_EQ, -1);
6825 1 : tt_ptr_op(end, OP_EQ, NULL);
6826 : /* INT_MAX */
6827 1 : version = parse_hs_version_from_post("/tor/hs/2147483647/publish",
6828 : prefix, &end);
6829 1 : tt_int_op(version, OP_EQ, INT_MAX);
6830 1 : tt_str_op(end, OP_EQ, "/publish");
6831 : /* INT_MAX + 1*/
6832 1 : version = parse_hs_version_from_post("/tor/hs/2147483648/publish",
6833 : prefix, &end);
6834 1 : tt_int_op(version, OP_EQ, -1);
6835 1 : tt_ptr_op(end, OP_EQ, NULL);
6836 : }
6837 :
6838 1 : done:
6839 1 : ;
6840 1 : }
6841 :
6842 : static void
6843 1 : test_dir_platform_str(void *arg)
6844 : {
6845 1 : char platform[256];
6846 1 : (void)arg;
6847 1 : platform[0] = 0;
6848 1 : get_platform_str(platform, sizeof(platform));
6849 1 : tt_int_op((int)strlen(platform), OP_GT, 0);
6850 1 : tt_assert(!strcmpstart(platform, "Tor "));
6851 :
6852 1 : tor_version_t ver;
6853 : // make sure this is a tor version, a real actual tor version.
6854 1 : tt_int_op(tor_version_parse_platform(platform, &ver, 1), OP_EQ, 1);
6855 :
6856 1 : TT_BLATHER(("%d.%d.%d.%d", ver.major, ver.minor, ver.micro, ver.patchlevel));
6857 :
6858 : // Handle an example version.
6859 1 : tt_int_op(tor_version_parse_platform(
6860 : "Tor 0.3.3.3 (foo) (git-xyzzy) on a potato", &ver, 1), OP_EQ, 1);
6861 1 : done:
6862 1 : ;
6863 1 : }
6864 :
6865 : static void
6866 1 : test_dir_format_versions_list(void *arg)
6867 : {
6868 1 : (void)arg;
6869 1 : char *s = NULL;
6870 1 : config_line_t *lines = NULL;
6871 :
6872 1 : setup_capture_of_logs(LOG_WARN);
6873 1 : s = format_recommended_version_list(lines, 1);
6874 1 : tt_str_op(s, OP_EQ, "");
6875 :
6876 1 : tor_free(s);
6877 1 : config_line_append(&lines, "ignored", "0.3.4.1, 0.2.9.111-alpha, 4.4.4-rc");
6878 1 : s = format_recommended_version_list(lines, 1);
6879 1 : tt_str_op(s, OP_EQ, "0.2.9.111-alpha,0.3.4.1,4.4.4-rc");
6880 :
6881 1 : tor_free(s);
6882 1 : config_line_append(&lines, "ignored", "0.1.2.3,0.2.9.10 ");
6883 1 : s = format_recommended_version_list(lines, 1);
6884 1 : tt_str_op(s, OP_EQ, "0.1.2.3,0.2.9.10,0.2.9.111-alpha,0.3.4.1,4.4.4-rc");
6885 :
6886 : /* There should be no warnings so far. */
6887 1 : expect_no_log_entry();
6888 :
6889 : /* Now try a line with a space in it. */
6890 1 : tor_free(s);
6891 1 : config_line_append(&lines, "ignored", "1.3.3.8 1.3.3.7");
6892 1 : s = format_recommended_version_list(lines, 1);
6893 1 : tt_str_op(s, OP_EQ, "0.1.2.3,0.2.9.10,0.2.9.111-alpha,0.3.4.1,"
6894 : "1.3.3.7,1.3.3.8,4.4.4-rc");
6895 :
6896 1 : expect_single_log_msg_containing(
6897 : "Unexpected space in versions list member \"1.3.3.8 1.3.3.7\"." );
6898 :
6899 : /* Start over, with a line containing a bogus version */
6900 1 : config_free_lines(lines);
6901 1 : lines = NULL;
6902 1 : tor_free(s);
6903 1 : mock_clean_saved_logs();
6904 1 : config_line_append(&lines, "ignored", "0.1.2.3, alpha-complex, 0.1.1.8-rc");
6905 1 : s = format_recommended_version_list(lines,1);
6906 1 : tt_str_op(s, OP_EQ, "0.1.1.8-rc,0.1.2.3,alpha-complex");
6907 1 : expect_single_log_msg_containing(
6908 : "Recommended version \"alpha-complex\" does not look valid.");
6909 :
6910 1 : done:
6911 1 : tor_free(s);
6912 1 : config_free_lines(lines);
6913 1 : teardown_capture_of_logs();
6914 1 : }
6915 :
6916 : static void
6917 1 : test_dir_add_fingerprint(void *arg)
6918 : {
6919 1 : (void)arg;
6920 1 : authdir_config_t *list;
6921 1 : int ret;
6922 1 : ed25519_secret_key_t seckey;
6923 1 : ed25519_public_key_t pubkey_good, pubkey_bad;
6924 :
6925 1 : authdir_init_fingerprint_list();
6926 1 : list = authdir_return_fingerprint_list();
6927 :
6928 1 : setup_capture_of_logs(LOG_WARN);
6929 :
6930 : /* RSA test - successful */
6931 1 : ret = add_rsa_fingerprint_to_dir("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
6932 : list, 0);
6933 1 : tt_int_op(ret, OP_EQ, 0);
6934 :
6935 : /* RSA test - failure */
6936 1 : ret = add_rsa_fingerprint_to_dir("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ",
6937 : list, 0);
6938 1 : tt_int_op(ret, OP_EQ, -1);
6939 :
6940 : /* ed25519 test - successful */
6941 1 : ed25519_secret_key_generate(&seckey, 0);
6942 1 : ed25519_public_key_generate(&pubkey_good, &seckey);
6943 :
6944 1 : ret = add_ed25519_to_dir(&pubkey_good, list, 0);
6945 1 : tt_int_op(ret, OP_EQ, 0);
6946 :
6947 : /* ed25519 test - failure */
6948 1 : digest256_from_base64((char *) pubkey_bad.pubkey, "gibberish");
6949 :
6950 1 : ret = add_ed25519_to_dir(&pubkey_bad, list, 0);
6951 1 : tt_int_op(ret, OP_EQ, -1);
6952 :
6953 1 : done:
6954 1 : teardown_capture_of_logs();
6955 1 : dirserv_free_fingerprint_list();
6956 1 : }
6957 :
6958 : static void
6959 1 : test_dir_dirserv_load_fingerprint_file(void *arg)
6960 : {
6961 1 : (void)arg;
6962 1 : char *fname = tor_strdup(get_fname("approved-routers"));
6963 :
6964 : // Neither RSA nor ed25519
6965 1 : const char *router_lines_invalid =
6966 : "!badexit notafingerprint";
6967 1 : const char *router_lines_too_long =
6968 : "!badexit thisisareallylongstringthatislongerthanafingerprint\n";
6969 1 : const char *router_lines_bad_fmt_str =
6970 : "!badexit ABCDEFGH|%1$p|%2$p|%3$p|%4$p|%5$p|%6$p\n";
6971 1 : const char *router_lines_valid_rsa =
6972 : "!badexit AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n";
6973 1 : const char *router_lines_invalid_rsa =
6974 : "!badexit ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ\n";
6975 1 : const char *router_lines_valid_ed25519 =
6976 : "!badexit wqfLzgfCtRfYNg88LsL1QpzxS0itapJ1aj6TbnByx/Q\n";
6977 1 : const char *router_lines_invalid_ed25519 =
6978 : "!badexit --fLzgfCtRfYNg88LsL1QpzxS0itapJ1aj6TbnByx--\n";
6979 :
6980 : // Test: Invalid Fingerprint (not RSA or ed25519)
6981 1 : setup_capture_of_logs(LOG_NOTICE);
6982 1 : write_str_to_file(fname, router_lines_invalid, 0);
6983 1 : tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
6984 1 : expect_log_msg_containing("Invalid fingerprint");
6985 1 : teardown_capture_of_logs();
6986 :
6987 : // Test: Very long string (longer than RSA or ed25519 key)
6988 1 : setup_capture_of_logs(LOG_NOTICE);
6989 1 : write_str_to_file(fname, router_lines_too_long, 0);
6990 1 : tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
6991 1 : expect_log_msg_containing("Invalid fingerprint");
6992 1 : teardown_capture_of_logs();
6993 :
6994 : // Test: Format string exploit
6995 1 : setup_capture_of_logs(LOG_NOTICE);
6996 1 : write_str_to_file(fname, router_lines_bad_fmt_str, 0);
6997 1 : tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
6998 1 : expect_log_msg_containing("Invalid fingerprint");
6999 1 : teardown_capture_of_logs();
7000 :
7001 : // Test: Valid RSA
7002 1 : setup_capture_of_logs(LOG_NOTICE);
7003 1 : write_str_to_file(fname, router_lines_valid_rsa, 0);
7004 1 : tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
7005 1 : teardown_capture_of_logs();
7006 :
7007 : // Test: Invalid RSA
7008 1 : setup_capture_of_logs(LOG_NOTICE);
7009 1 : write_str_to_file(fname, router_lines_invalid_rsa, 0);
7010 1 : tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
7011 1 : expect_log_msg_containing("Invalid fingerprint");
7012 1 : teardown_capture_of_logs();
7013 :
7014 : // Test: Valid ed25519
7015 1 : setup_capture_of_logs(LOG_NOTICE);
7016 1 : write_str_to_file(fname, router_lines_valid_ed25519, 0);
7017 1 : tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
7018 1 : teardown_capture_of_logs();
7019 :
7020 : // Test: Invalid ed25519
7021 1 : setup_capture_of_logs(LOG_NOTICE);
7022 1 : write_str_to_file(fname, router_lines_invalid_ed25519, 0);
7023 1 : tt_int_op(dirserv_load_fingerprint_file(), OP_EQ, 0);
7024 1 : expect_log_msg_containing("Invalid fingerprint");
7025 1 : teardown_capture_of_logs();
7026 :
7027 1 : done:
7028 1 : tor_free(fname);
7029 1 : dirserv_free_fingerprint_list();
7030 1 : }
7031 :
7032 : #define RESET_FP_LIST(list) STMT_BEGIN \
7033 : dirserv_free_fingerprint_list(); \
7034 : authdir_init_fingerprint_list(); \
7035 : list = authdir_return_fingerprint_list(); \
7036 : STMT_END
7037 :
7038 : static void
7039 1 : test_dir_dirserv_router_get_status(void *arg)
7040 : {
7041 1 : authdir_config_t *list;
7042 1 : routerinfo_t *ri = NULL;
7043 1 : ed25519_keypair_t kp1, kp2;
7044 1 : char d[DIGEST_LEN];
7045 1 : char fp[HEX_DIGEST_LEN+1];
7046 1 : int ret;
7047 1 : const char *msg;
7048 1 : time_t now = time(NULL);
7049 :
7050 1 : (void)arg;
7051 :
7052 1 : crypto_pk_t *pk = pk_generate(0);
7053 :
7054 1 : authdir_init_fingerprint_list();
7055 1 : list = authdir_return_fingerprint_list();
7056 :
7057 : /* Set up the routerinfo */
7058 1 : ri = tor_malloc_zero(sizeof(routerinfo_t));
7059 1 : tor_addr_from_ipv4h(&ri->ipv4_addr, 0xc0a80001u);
7060 1 : ri->ipv4_orport = 9001;
7061 1 : ri->platform = tor_strdup("0.4.0.1-alpha");
7062 1 : ri->nickname = tor_strdup("Jessica");
7063 1 : ri->identity_pkey = crypto_pk_dup_key(pk);
7064 :
7065 1 : curve25519_keypair_t ri_onion_keypair;
7066 1 : curve25519_keypair_generate(&ri_onion_keypair, 0);
7067 1 : ri->onion_curve25519_pkey = tor_memdup(&ri_onion_keypair.pubkey,
7068 : sizeof(curve25519_public_key_t));
7069 :
7070 1 : ed25519_secret_key_from_seed(&kp1.seckey,
7071 : (const uint8_t*)"YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY");
7072 1 : ed25519_public_key_generate(&kp1.pubkey, &kp1.seckey);
7073 1 : ed25519_secret_key_from_seed(&kp2.seckey,
7074 : (const uint8_t*)"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
7075 1 : ed25519_public_key_generate(&kp2.pubkey, &kp2.seckey);
7076 1 : ri->cache_info.signing_key_cert = tor_cert_create_ed25519(&kp1,
7077 : CERT_TYPE_ID_SIGNING,
7078 : &kp2.pubkey,
7079 : now, 86400,
7080 : CERT_FLAG_INCLUDE_SIGNING_KEY);
7081 :
7082 1 : crypto_pk_get_digest(ri->identity_pkey, d);
7083 1 : base16_encode(fp, HEX_DIGEST_LEN + 1, d, DIGEST_LEN);
7084 :
7085 : /* Try on an empty fingerprint list */
7086 1 : ret = dirserv_router_get_status(ri, &msg, LOG_INFO);
7087 1 : tt_int_op(ret, OP_EQ, 0);
7088 1 : RESET_FP_LIST(list);
7089 :
7090 1 : ret = dirserv_router_get_status(ri, &msg, LOG_INFO);
7091 1 : tt_int_op(ret, OP_EQ, 0);
7092 1 : RESET_FP_LIST(list);
7093 :
7094 : /* Try an accepted router */
7095 1 : add_rsa_fingerprint_to_dir(fp, list, 0);
7096 1 : ret = dirserv_router_get_status(ri, &msg, LOG_INFO);
7097 1 : tt_int_op(ret, OP_EQ, 0);
7098 1 : RESET_FP_LIST(list);
7099 :
7100 1 : add_ed25519_to_dir(&kp1.pubkey, list, 0);
7101 1 : ret = dirserv_router_get_status(ri, &msg, LOG_INFO);
7102 1 : tt_int_op(ret, OP_EQ, 0);
7103 1 : RESET_FP_LIST(list);
7104 :
7105 : /* Try a rejected router */
7106 1 : add_rsa_fingerprint_to_dir(fp, list, RTR_REJECT);
7107 1 : ret = dirserv_router_get_status(ri, &msg, LOG_INFO);
7108 1 : tt_int_op(ret, OP_EQ, RTR_REJECT);
7109 1 : RESET_FP_LIST(list);
7110 :
7111 1 : add_ed25519_to_dir(&kp1.pubkey, list, RTR_REJECT);
7112 1 : ret = dirserv_router_get_status(ri, &msg, LOG_INFO);
7113 1 : tt_int_op(ret, OP_EQ, RTR_REJECT);
7114 1 : RESET_FP_LIST(list);
7115 :
7116 1 : done:
7117 1 : dirserv_free_fingerprint_list();
7118 1 : routerinfo_free(ri);
7119 1 : crypto_pk_free(pk);
7120 1 : }
7121 :
7122 : static void
7123 1 : test_dir_dirserv_would_reject_router(void *arg)
7124 : {
7125 1 : authdir_config_t *list;
7126 1 : routerstatus_t rs;
7127 1 : vote_routerstatus_t vrs;
7128 1 : ed25519_keypair_t kp;
7129 1 : char fp[HEX_DIGEST_LEN+1];
7130 :
7131 1 : (void)arg;
7132 :
7133 1 : authdir_init_fingerprint_list();
7134 1 : list = authdir_return_fingerprint_list();
7135 :
7136 : /* Set up the routerstatus */
7137 1 : memset(&rs, 0, sizeof(rs));
7138 1 : tor_addr_from_ipv4h(&rs.ipv4_addr, 0xc0a80001u);
7139 1 : rs.ipv4_orport = 9001;
7140 1 : strlcpy(rs.nickname, "Nicole", sizeof(rs.nickname));
7141 1 : memcpy(rs.identity_digest, "Cloud nine is great ", DIGEST_LEN);
7142 :
7143 1 : ed25519_secret_key_from_seed(&kp.seckey,
7144 : (const uint8_t*)"YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY");
7145 1 : ed25519_public_key_generate(&kp.pubkey, &kp.seckey);
7146 :
7147 1 : base16_encode(fp, HEX_DIGEST_LEN + 1, rs.identity_digest, DIGEST_LEN);
7148 :
7149 : /* Setup the vote_routerstatus_t. */
7150 1 : memcpy(vrs.ed25519_id, &kp.pubkey, ED25519_PUBKEY_LEN);
7151 :
7152 : /* Try an empty fingerprint list */
7153 1 : tt_assert(!dirserv_would_reject_router(&rs, &vrs));
7154 1 : RESET_FP_LIST(list);
7155 :
7156 1 : tt_assert(!dirserv_would_reject_router(&rs, &vrs));
7157 1 : RESET_FP_LIST(list);
7158 :
7159 : /* Try an accepted router */
7160 1 : add_rsa_fingerprint_to_dir(fp, list, 0);
7161 1 : tt_assert(!dirserv_would_reject_router(&rs, &vrs));
7162 1 : RESET_FP_LIST(list);
7163 :
7164 1 : add_ed25519_to_dir(&kp.pubkey, list, 0);
7165 1 : tt_assert(!dirserv_would_reject_router(&rs, &vrs));
7166 1 : RESET_FP_LIST(list);
7167 :
7168 : /* Try a rejected router */
7169 1 : add_rsa_fingerprint_to_dir(fp, list, RTR_REJECT);
7170 1 : tt_assert(dirserv_would_reject_router(&rs, &vrs));
7171 1 : RESET_FP_LIST(list);
7172 :
7173 1 : add_ed25519_to_dir(&kp.pubkey, list, RTR_REJECT);
7174 1 : tt_assert(dirserv_would_reject_router(&rs, &vrs));
7175 1 : RESET_FP_LIST(list);
7176 :
7177 1 : done:
7178 1 : dirserv_free_fingerprint_list();
7179 1 : }
7180 :
7181 : static void
7182 1 : test_dir_dirserv_add_own_fingerprint(void *arg)
7183 : {
7184 1 : authdir_config_t *list;
7185 1 : char digest[DIGEST_LEN];
7186 1 : crypto_pk_t *pk = pk_generate(0);
7187 :
7188 1 : (void)arg;
7189 :
7190 1 : init_mock_ed_keys(pk);
7191 1 : authdir_init_fingerprint_list();
7192 1 : list = authdir_return_fingerprint_list();
7193 1 : dirserv_add_own_fingerprint(pk, get_master_identity_key());
7194 :
7195 : /* Check if we have a RSA key. */
7196 1 : crypto_pk_get_digest(pk, digest);
7197 1 : tt_assert(digestmap_get(list->status_by_digest, digest));
7198 :
7199 : /* Check if we have a ed25519 key. */
7200 1 : tt_assert(digest256map_get(list->status_by_digest256,
7201 : get_master_identity_key()->pubkey));
7202 :
7203 1 : RESET_FP_LIST(list);
7204 :
7205 1 : done:
7206 1 : dirserv_free_fingerprint_list();
7207 1 : crypto_pk_free(pk);
7208 1 : }
7209 :
7210 : #ifndef COCCI
7211 : #define DIR_LEGACY(name) \
7212 : { #name, test_dir_ ## name , TT_FORK, NULL, NULL }
7213 :
7214 : #define DIR(name,flags) \
7215 : { #name, test_dir_##name, (flags), NULL, NULL }
7216 :
7217 : /* where arg is a string constant */
7218 : #define DIR_ARG(name,flags,arg) \
7219 : { #name "_" arg, test_dir_##name, (flags), &passthrough_setup, (void*) arg }
7220 : #endif /* !defined(COCCI) */
7221 :
7222 : struct testcase_t dir_tests[] = {
7223 : DIR_LEGACY(nicknames),
7224 : /* extrainfo without any stats */
7225 : DIR_ARG(formats_rsa_ed25519, TT_FORK, ""),
7226 : /* on a bridge */
7227 : DIR_ARG(formats_rsa_ed25519, TT_FORK, "b"),
7228 : /* extrainfo with basic stats */
7229 : DIR_ARG(formats_rsa_ed25519, TT_FORK, "e"),
7230 : DIR_ARG(formats_rsa_ed25519, TT_FORK, "be"),
7231 : /* extrainfo with all stats */
7232 : DIR_ARG(formats_rsa_ed25519, TT_FORK, "es"),
7233 : DIR_ARG(formats_rsa_ed25519, TT_FORK, "bes"),
7234 : DIR(routerinfo_parsing, 0),
7235 : DIR(extrainfo_parsing, 0),
7236 : DIR(parse_router_list, TT_FORK),
7237 : DIR(load_routers, TT_FORK),
7238 : DIR(load_extrainfo, TT_FORK),
7239 : DIR(getinfo_extra, 0),
7240 : DIR_LEGACY(versions),
7241 : DIR_LEGACY(fp_pairs),
7242 : DIR(split_fps, 0),
7243 : DIR_LEGACY(measured_bw_kb),
7244 : DIR_LEGACY(measured_bw_kb_line_is_after_headers),
7245 : DIR_LEGACY(measured_bw_kb_cache),
7246 : DIR_LEGACY(dirserv_read_measured_bandwidths),
7247 : DIR(bwauth_bw_file_digest256, 0),
7248 : DIR_LEGACY(param_voting),
7249 : DIR(param_voting_lookup, 0),
7250 : DIR_LEGACY(v3_networkstatus),
7251 : DIR(random_weighted, 0),
7252 : DIR(scale_bw, 0),
7253 : DIR_LEGACY(clip_unmeasured_bw_kb),
7254 : DIR_LEGACY(clip_unmeasured_bw_kb_alt),
7255 : DIR(fmt_control_ns, 0),
7256 : DIR(dirserv_set_routerstatus_testing, TT_FORK),
7257 : DIR(http_handling, 0),
7258 : DIR(purpose_needs_anonymity_returns_true_for_bridges, 0),
7259 : DIR(purpose_needs_anonymity_returns_false_for_own_bridge_desc, 0),
7260 : DIR(purpose_needs_anonymity_returns_true_by_default, 0),
7261 : DIR(purpose_needs_anonymity_ret_false_for_non_sensitive_conn, 0),
7262 : DIR(post_parsing, 0),
7263 : DIR(fetch_type, 0),
7264 : DIR(packages, 0),
7265 : DIR(download_status_random_backoff, 0),
7266 : DIR(download_status_random_backoff_ranges, 0),
7267 : DIR(download_status_increment, TT_FORK),
7268 : DIR(authdir_type_to_string, 0),
7269 : DIR(conn_purpose_to_string, 0),
7270 : DIR(should_use_directory_guards, 0),
7271 : DIR(should_not_init_request_to_ourselves, TT_FORK),
7272 : DIR(should_not_init_request_to_dir_auths_without_v3_info, 0),
7273 : DIR(should_init_request_to_dir_auths, 0),
7274 : DIR(dump_unparseable_descriptors, 0),
7275 : DIR(populate_dump_desc_fifo, 0),
7276 : DIR(populate_dump_desc_fifo_2, 0),
7277 : DIR_ARG(find_dl_min_delay, TT_FORK, "bfd"),
7278 : DIR_ARG(find_dl_min_delay, TT_FORK, "bad"),
7279 : DIR_ARG(find_dl_min_delay, TT_FORK, "cfd"),
7280 : DIR_ARG(find_dl_min_delay, TT_FORK, "cad"),
7281 : DIR_ARG(find_dl_min_delay, TT_FORK, "bfr"),
7282 : DIR_ARG(find_dl_min_delay, TT_FORK, "bar"),
7283 : DIR_ARG(find_dl_min_delay, TT_FORK, "cfr"),
7284 : DIR_ARG(find_dl_min_delay, TT_FORK, "car"),
7285 : DIR(assumed_flags, 0),
7286 : DIR(matching_flags, 0),
7287 : DIR(networkstatus_compute_bw_weights_v10, 0),
7288 : DIR(platform_str, 0),
7289 : DIR(format_versions_list, TT_FORK),
7290 : DIR(add_fingerprint, TT_FORK),
7291 : DIR(dirserv_load_fingerprint_file, TT_FORK),
7292 : DIR(dirserv_router_get_status, TT_FORK),
7293 : DIR(dirserv_would_reject_router, TT_FORK),
7294 : DIR(dirserv_add_own_fingerprint, TT_FORK),
7295 : END_OF_TESTCASES
7296 : };
|