test_dir.c 210 KB
Newer Older
1
2
/* Copyright (c) 2001-2004, Roger Dingledine.
 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
Nick Mathewson's avatar
Nick Mathewson committed
3
 * Copyright (c) 2007-2018, The Tor Project, Inc. */
4
5
6
/* See LICENSE for licensing information */

#include "orconfig.h"
7
8
#include <math.h>

Ola Bini's avatar
Ola Bini committed
9
#define CONFIG_PRIVATE
Taylor Yu's avatar
Taylor Yu committed
10
#define CONTROL_PRIVATE
11
12
13
#define DIRSERV_PRIVATE
#define DIRVOTE_PRIVATE
#define ROUTER_PRIVATE
14
#define ROUTERLIST_PRIVATE
15
#define ROUTERPARSE_PRIVATE
16
#define HIBERNATE_PRIVATE
Nick Mathewson's avatar
Nick Mathewson committed
17
#define NETWORKSTATUS_PRIVATE
18
19
#define RELAY_PRIVATE

20
21
22
23
24
25
#include "core/or/or.h"
#include "feature/client/bridges.h"
#include "core/mainloop/connection.h"
#include "app/config/confparse.h"
#include "app/config/config.h"
#include "feature/control/control.h"
26
#include "lib/crypt_ops/crypto_ed25519.h"
27
#include "lib/crypt_ops/crypto_format.h"
28
#include "lib/crypt_ops/crypto_rand.h"
29
30
31
32
33
34
#include "feature/dircache/directory.h"
#include "feature/dircache/dirserv.h"
#include "feature/dirauth/dirvote.h"
#include "feature/client/entrynodes.h"
#include "feature/dircommon/fp_pair.h"
#include "feature/hibernate/hibernate.h"
35
#include "lib/memarea/memarea.h"
36
#include "lib/osinfo/uname.h"
37
38
39
40
41
42
43
#include "feature/nodelist/networkstatus.h"
#include "feature/relay/router.h"
#include "feature/relay/routerkeys.h"
#include "feature/nodelist/routerlist.h"
#include "feature/nodelist/routerparse.h"
#include "feature/nodelist/routerset.h"
#include "feature/dirauth/shared_random_state.h"
Nick Mathewson's avatar
Nick Mathewson committed
44
45
#include "test/test.h"
#include "test/test_dir_common.h"
46
47
#include "feature/nodelist/torcert.h"
#include "core/or/relay.h"
Nick Mathewson's avatar
Nick Mathewson committed
48
#include "test/log_test_helpers.h"
49
#include "feature/dircommon/voting_schedule.h"
50
#include "lib/compress/compress.h"
51

52
53
54
55
56
57
58
59
60
61
62
63
64
#include "core/or/addr_policy_st.h"
#include "feature/nodelist/authority_cert_st.h"
#include "feature/nodelist/document_signature_st.h"
#include "feature/nodelist/extrainfo_st.h"
#include "feature/nodelist/networkstatus_st.h"
#include "feature/nodelist/networkstatus_voter_info_st.h"
#include "feature/dirauth/ns_detached_signatures_st.h"
#include "core/or/port_cfg_st.h"
#include "feature/nodelist/routerinfo_st.h"
#include "feature/nodelist/routerlist_st.h"
#include "core/or/tor_version_st.h"
#include "feature/dirauth/vote_microdesc_hash_st.h"
#include "feature/nodelist/vote_routerstatus_st.h"
65

66
67
68
69
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif

70
#define NS_MODULE dir
71
72

static void
73
test_dir_nicknames(void *arg)
74
{
75
  (void)arg;
76
77
78
79
80
81
  tt_assert( is_legal_nickname("a"));
  tt_assert(!is_legal_nickname(""));
  tt_assert(!is_legal_nickname("abcdefghijklmnopqrst")); /* 20 chars */
  tt_assert(!is_legal_nickname("hyphen-")); /* bad char */
  tt_assert( is_legal_nickname("abcdefghijklmnopqrs")); /* 19 chars */
  tt_assert(!is_legal_nickname("$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA"));
82
  /* valid */
83
  tt_assert( is_legal_nickname_or_hexdigest(
84
                                 "$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA"));
85
  tt_assert( is_legal_nickname_or_hexdigest(
86
                         "$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA=fred"));
87
  tt_assert( is_legal_nickname_or_hexdigest(
88
89
                         "$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA~fred"));
  /* too short */
90
  tt_assert(!is_legal_nickname_or_hexdigest(
91
92
                                 "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
  /* illegal char */
93
  tt_assert(!is_legal_nickname_or_hexdigest(
94
95
                                 "$AAAAAAzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
  /* hex part too long */
96
  tt_assert(!is_legal_nickname_or_hexdigest(
97
                         "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
98
  tt_assert(!is_legal_nickname_or_hexdigest(
99
100
                         "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=fred"));
  /* Bad nickname */
101
  tt_assert(!is_legal_nickname_or_hexdigest(
102
                         "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="));
103
  tt_assert(!is_legal_nickname_or_hexdigest(
104
                         "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~"));
105
  tt_assert(!is_legal_nickname_or_hexdigest(
106
                       "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~hyphen-"));
107
  tt_assert(!is_legal_nickname_or_hexdigest(
108
109
110
                       "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~"
                       "abcdefghijklmnoppqrst"));
  /* Bad extra char. */
111
  tt_assert(!is_legal_nickname_or_hexdigest(
112
                         "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!"));
113
114
115
  tt_assert(is_legal_nickname_or_hexdigest("xyzzy"));
  tt_assert(is_legal_nickname_or_hexdigest("abcdefghijklmnopqrs"));
  tt_assert(!is_legal_nickname_or_hexdigest("abcdefghijklmnopqrst"));
116
117
118
119
 done:
  ;
}

120
121
122
123
124
125
126
127
128
static smartlist_t *mocked_configured_ports = NULL;

/** Returns mocked_configured_ports */
static const smartlist_t *
mock_get_configured_ports(void)
{
  return mocked_configured_ports;
}

129
130
/** Run unit tests for router descriptor generation logic. */
static void
131
test_dir_formats(void *arg)
132
{
133
134
  char *buf = NULL;
  char buf2[8192];
135
136
  char platform[256];
  char fingerprint[FINGERPRINT_LEN+1];
137
138
  char *pk1_str = NULL, *pk2_str = NULL, *cp;
  size_t pk1_str_len, pk2_str_len;
139
  routerinfo_t *r1=NULL, *r2=NULL;
140
  crypto_pk_t *pk1 = NULL, *pk2 = NULL;
141
  routerinfo_t *rp1 = NULL, *rp2 = NULL;
142
143
  addr_policy_t *ex1, *ex2;
  routerlist_t *dir1 = NULL, *dir2 = NULL;
144
  uint8_t *rsa_cc = NULL;
145
146
  or_options_t *options = get_options_mutable();
  const addr_policy_t *p;
147
  time_t now = time(NULL);
148
  port_cfg_t orport, dirport;
149
  char cert_buf[256];
150

151
  (void)arg;
152
153
  pk1 = pk_generate(0);
  pk2 = pk_generate(1);
154

155
  tt_assert(pk1 && pk2);
156

157
158
  hibernate_set_state_for_testing_(HIBERNATE_STATE_LIVE);

159
160
161
162
163
164
  get_platform_str(platform, sizeof(platform));
  r1 = tor_malloc_zero(sizeof(routerinfo_t));
  r1->addr = 0xc0a80001u; /* 192.168.0.1 */
  r1->cache_info.published_on = 0;
  r1->or_port = 9000;
  r1->dir_port = 9003;
165
  r1->supports_tunnelled_dir_requests = 1;
166
167
  tor_addr_parse(&r1->ipv6_addr, "1:2:3:4::");
  r1->ipv6_orport = 9999;
168
  r1->onion_pkey = crypto_pk_dup_key(pk1);
169
170
171
172
173
  /* Fake just enough of an ntor key to get by */
  curve25519_keypair_t r1_onion_keypair;
  curve25519_keypair_generate(&r1_onion_keypair, 0);
  r1->onion_curve25519_pkey = tor_memdup(&r1_onion_keypair.pubkey,
                                         sizeof(curve25519_public_key_t));
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
  r1->identity_pkey = crypto_pk_dup_key(pk2);
  r1->bandwidthrate = 1000;
  r1->bandwidthburst = 5000;
  r1->bandwidthcapacity = 10000;
  r1->exit_policy = NULL;
  r1->nickname = tor_strdup("Magri");
  r1->platform = tor_strdup(platform);

  ex1 = tor_malloc_zero(sizeof(addr_policy_t));
  ex2 = tor_malloc_zero(sizeof(addr_policy_t));
  ex1->policy_type = ADDR_POLICY_ACCEPT;
  tor_addr_from_ipv4h(&ex1->addr, 0);
  ex1->maskbits = 0;
  ex1->prt_min = ex1->prt_max = 80;
  ex2->policy_type = ADDR_POLICY_REJECT;
  tor_addr_from_ipv4h(&ex2->addr, 18<<24);
  ex2->maskbits = 8;
  ex2->prt_min = ex2->prt_max = 24;
  r2 = tor_malloc_zero(sizeof(routerinfo_t));
  r2->addr = 0x0a030201u; /* 10.3.2.1 */
194
195
196
197
198
199
200
  ed25519_keypair_t kp1, kp2;
  ed25519_secret_key_from_seed(&kp1.seckey,
                          (const uint8_t*)"YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY");
  ed25519_public_key_generate(&kp1.pubkey, &kp1.seckey);
  ed25519_secret_key_from_seed(&kp2.seckey,
                          (const uint8_t*)"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
  ed25519_public_key_generate(&kp2.pubkey, &kp2.seckey);
201
  r2->cache_info.signing_key_cert = tor_cert_create(&kp1,
202
203
204
205
                                         CERT_TYPE_ID_SIGNING,
                                         &kp2.pubkey,
                                         now, 86400,
                                         CERT_FLAG_INCLUDE_SIGNING_KEY);
206
207
208
209
  r2->platform = tor_strdup(platform);
  r2->cache_info.published_on = 5;
  r2->or_port = 9005;
  r2->dir_port = 0;
210
  r2->supports_tunnelled_dir_requests = 1;
211
  r2->onion_pkey = crypto_pk_dup_key(pk2);
212
213
214
215
  curve25519_keypair_t r2_onion_keypair;
  curve25519_keypair_generate(&r2_onion_keypair, 0);
  r2->onion_curve25519_pkey = tor_memdup(&r2_onion_keypair.pubkey,
                                         sizeof(curve25519_public_key_t));
216
217
  r2->identity_pkey = crypto_pk_dup_key(pk1);
  r2->bandwidthrate = r2->bandwidthburst = r2->bandwidthcapacity = 3000;
218
  r2->exit_policy = smartlist_new();
219
  smartlist_add(r2->exit_policy, ex1);
220
  smartlist_add(r2->exit_policy, ex2);
221
222
  r2->nickname = tor_strdup("Fred");

223
  tt_assert(!crypto_pk_write_public_key_to_string(pk1, &pk1_str,
224
                                                    &pk1_str_len));
225
  tt_assert(!crypto_pk_write_public_key_to_string(pk2 , &pk2_str,
226
227
                                                    &pk2_str_len));

228
  /* XXXX+++ router_dump_to_string should really take this from ri.*/
229
230
  options->ContactInfo = tor_strdup("Magri White "
                                    "<magri@elsewhere.example.com>");
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
  /* Skip reachability checks for DirPort and tunnelled-dir-server */
  options->AssumeReachable = 1;

  /* Fake just enough of an ORPort and DirPort to get by */
  MOCK(get_configured_ports, mock_get_configured_ports);
  mocked_configured_ports = smartlist_new();

  memset(&orport, 0, sizeof(orport));
  orport.type = CONN_TYPE_OR_LISTENER;
  orport.addr.family = AF_INET;
  orport.port = 9000;
  smartlist_add(mocked_configured_ports, &orport);

  memset(&dirport, 0, sizeof(dirport));
  dirport.type = CONN_TYPE_DIR_LISTENER;
  dirport.addr.family = AF_INET;
  dirport.port = 9003;
  smartlist_add(mocked_configured_ports, &dirport);
249

250
  buf = router_dump_router_to_string(r1, pk2, NULL, NULL, NULL);
251

252
253
254
255
  UNMOCK(get_configured_ports);
  smartlist_free(mocked_configured_ports);
  mocked_configured_ports = NULL;

256
  tor_free(options->ContactInfo);
257
  tt_assert(buf);
258

259
  strlcpy(buf2, "router Magri 192.168.0.1 9000 0 9003\n"
260
          "or-address [1:2:3:4::]:9999\n"
261
262
263
264
          "platform Tor "VERSION" on ", sizeof(buf2));
  strlcat(buf2, get_uname(), sizeof(buf2));
  strlcat(buf2, "\n"
          "published 1970-01-01 00:00:00\n"
265
          "fingerprint ", sizeof(buf2));
266
  tt_assert(!crypto_pk_get_fingerprint(pk2, fingerprint, 1));
267
268
269
270
271
272
273
274
275
276
  strlcat(buf2, fingerprint, sizeof(buf2));
  strlcat(buf2, "\nuptime 0\n"
  /* XXX the "0" above is hard-coded, but even if we made it reflect
   * uptime, that still wouldn't make it right, because the two
   * descriptors might be made on different seconds... hm. */
         "bandwidth 1000 5000 10000\n"
          "onion-key\n", sizeof(buf2));
  strlcat(buf2, pk1_str, sizeof(buf2));
  strlcat(buf2, "signing-key\n", sizeof(buf2));
  strlcat(buf2, pk2_str, sizeof(buf2));
277
  strlcat(buf2, "hidden-service-dir\n", sizeof(buf2));
278
279
  strlcat(buf2, "contact Magri White <magri@elsewhere.example.com>\n",
          sizeof(buf2));
280
281
282
283
284
  strlcat(buf2, "ntor-onion-key ", sizeof(buf2));
  base64_encode(cert_buf, sizeof(cert_buf),
                (const char*)r1_onion_keypair.pubkey.public_key, 32,
                BASE64_ENCODE_MULTILINE);
  strlcat(buf2, cert_buf, sizeof(buf2));
285
286
  strlcat(buf2, "reject *:*\n", sizeof(buf2));
  strlcat(buf2, "tunnelled-dir-server\nrouter-signature\n", sizeof(buf2));
287
288
289
  buf[strlen(buf2)] = '\0'; /* Don't compare the sig; it's never the same
                             * twice */

290
  tt_str_op(buf,OP_EQ, buf2);
291
  tor_free(buf);
292

293
  buf = router_dump_router_to_string(r1, pk2, NULL, NULL, NULL);
294
  tt_assert(buf);
295
  cp = buf;
296
  rp1 = router_parse_entry_from_string((const char*)cp,NULL,1,0,NULL,NULL);
297
  tt_assert(rp1);
298
299
  tt_int_op(rp1->addr,OP_EQ, r1->addr);
  tt_int_op(rp1->or_port,OP_EQ, r1->or_port);
300
  tt_int_op(rp1->dir_port,OP_EQ, r1->dir_port);
301
302
303
  tt_int_op(rp1->bandwidthrate,OP_EQ, r1->bandwidthrate);
  tt_int_op(rp1->bandwidthburst,OP_EQ, r1->bandwidthburst);
  tt_int_op(rp1->bandwidthcapacity,OP_EQ, r1->bandwidthcapacity);
304
305
  tt_int_op(crypto_pk_cmp_keys(rp1->onion_pkey, pk1), OP_EQ, 0);
  tt_int_op(crypto_pk_cmp_keys(rp1->identity_pkey, pk2), OP_EQ, 0);
306
  tt_assert(rp1->supports_tunnelled_dir_requests);
307
  //tt_assert(rp1->exit_policy == NULL);
Nick Mathewson's avatar
Nick Mathewson committed
308
  tor_free(buf);
309

310
  strlcpy(buf2,
311
          "router Fred 10.3.2.1 9005 0 0\n"
312
313
          "identity-ed25519\n"
          "-----BEGIN ED25519 CERT-----\n", sizeof(buf2));
314
315
316
317
  base64_encode(cert_buf, sizeof(cert_buf),
                (const char*)r2->cache_info.signing_key_cert->encoded,
                r2->cache_info.signing_key_cert->encoded_len,
                BASE64_ENCODE_MULTILINE);
318
  strlcat(buf2, cert_buf, sizeof(buf2));
319
320
321
322
  strlcat(buf2, "-----END ED25519 CERT-----\n", sizeof(buf2));
  strlcat(buf2, "master-key-ed25519 ", sizeof(buf2));
  {
    char k[ED25519_BASE64_LEN+1];
323
324
    tt_int_op(ed25519_public_to_base64(k,
                          &r2->cache_info.signing_key_cert->signing_key),
325
              OP_GE, 0);
326
327
328
329
    strlcat(buf2, k, sizeof(buf2));
    strlcat(buf2, "\n", sizeof(buf2));
  }
  strlcat(buf2, "platform Tor "VERSION" on ", sizeof(buf2));
330
331
332
333
  strlcat(buf2, get_uname(), sizeof(buf2));
  strlcat(buf2, "\n"
          "published 1970-01-01 00:00:05\n"
          "fingerprint ", sizeof(buf2));
334
  tt_assert(!crypto_pk_get_fingerprint(pk1, fingerprint, 1));
335
336
337
338
  strlcat(buf2, fingerprint, sizeof(buf2));
  strlcat(buf2, "\nuptime 0\n"
          "bandwidth 3000 3000 3000\n", sizeof(buf2));
  strlcat(buf2, "onion-key\n", sizeof(buf2));
339
340
341
  strlcat(buf2, pk2_str, sizeof(buf2));
  strlcat(buf2, "signing-key\n", sizeof(buf2));
  strlcat(buf2, pk1_str, sizeof(buf2));
342
343
344
345
346
347
  int rsa_cc_len;
  rsa_cc = make_tap_onion_key_crosscert(pk2,
                                        &kp1.pubkey,
                                        pk1,
                                        &rsa_cc_len);
  tt_assert(rsa_cc);
348
349
  base64_encode(cert_buf, sizeof(cert_buf), (char*)rsa_cc, rsa_cc_len,
                BASE64_ENCODE_MULTILINE);
350
351
352
353
354
  strlcat(buf2, "onion-key-crosscert\n"
          "-----BEGIN CROSSCERT-----\n", sizeof(buf2));
  strlcat(buf2, cert_buf, sizeof(buf2));
  strlcat(buf2, "-----END CROSSCERT-----\n", sizeof(buf2));
  int ntor_cc_sign;
355
356
357
  {
    tor_cert_t *ntor_cc = NULL;
    ntor_cc = make_ntor_onion_key_crosscert(&r2_onion_keypair,
358
359
                                          &kp1.pubkey,
                                          r2->cache_info.published_on,
360
                                          get_onion_key_lifetime(),
361
                                          &ntor_cc_sign);
362
363
    tt_assert(ntor_cc);
    base64_encode(cert_buf, sizeof(cert_buf),
364
365
                (char*)ntor_cc->encoded, ntor_cc->encoded_len,
                BASE64_ENCODE_MULTILINE);
366
367
    tor_cert_free(ntor_cc);
  }
368
369
370
371
372
373
  tor_snprintf(buf2+strlen(buf2), sizeof(buf2)-strlen(buf2),
               "ntor-onion-key-crosscert %d\n"
               "-----BEGIN ED25519 CERT-----\n"
               "%s"
               "-----END ED25519 CERT-----\n", ntor_cc_sign, cert_buf);

374
  strlcat(buf2, "hidden-service-dir\n", sizeof(buf2));
375
376
  strlcat(buf2, "ntor-onion-key ", sizeof(buf2));
  base64_encode(cert_buf, sizeof(cert_buf),
377
378
                (const char*)r2_onion_keypair.pubkey.public_key, 32,
                BASE64_ENCODE_MULTILINE);
379
  strlcat(buf2, cert_buf, sizeof(buf2));
380
  strlcat(buf2, "accept *:80\nreject 18.0.0.0/8:24\n", sizeof(buf2));
381
  strlcat(buf2, "tunnelled-dir-server\n", sizeof(buf2));
382
  strlcat(buf2, "router-sig-ed25519 ", sizeof(buf2));
383

384
385
386
387
388
389
390
391
392
393
  /* Fake just enough of an ORPort to get by */
  MOCK(get_configured_ports, mock_get_configured_ports);
  mocked_configured_ports = smartlist_new();

  memset(&orport, 0, sizeof(orport));
  orport.type = CONN_TYPE_OR_LISTENER;
  orport.addr.family = AF_INET;
  orport.port = 9005;
  smartlist_add(mocked_configured_ports, &orport);

394
  buf = router_dump_router_to_string(r2, pk1, pk2, &r2_onion_keypair, &kp2);
395
  tt_assert(buf);
396
397
  buf[strlen(buf2)] = '\0'; /* Don't compare the sig; it's never the same
                             * twice */
398
399

  tt_str_op(buf, OP_EQ, buf2);
400
  tor_free(buf);
401

402
  buf = router_dump_router_to_string(r2, pk1, NULL, NULL, NULL);
403

404
405
406
407
  UNMOCK(get_configured_ports);
  smartlist_free(mocked_configured_ports);
  mocked_configured_ports = NULL;

408
  /* Reset for later */
409
  cp = buf;
410
  rp2 = router_parse_entry_from_string((const char*)cp,NULL,1,0,NULL,NULL);
411
  tt_assert(rp2);
412
413
414
415
416
417
418
  tt_int_op(rp2->addr,OP_EQ, r2->addr);
  tt_int_op(rp2->or_port,OP_EQ, r2->or_port);
  tt_int_op(rp2->dir_port,OP_EQ, r2->dir_port);
  tt_int_op(rp2->bandwidthrate,OP_EQ, r2->bandwidthrate);
  tt_int_op(rp2->bandwidthburst,OP_EQ, r2->bandwidthburst);
  tt_int_op(rp2->bandwidthcapacity,OP_EQ, r2->bandwidthcapacity);
  tt_mem_op(rp2->onion_curve25519_pkey->public_key,OP_EQ,
419
420
             r2->onion_curve25519_pkey->public_key,
             CURVE25519_PUBKEY_LEN);
421
422
  tt_int_op(crypto_pk_cmp_keys(rp2->onion_pkey, pk2), OP_EQ, 0);
  tt_int_op(crypto_pk_cmp_keys(rp2->identity_pkey, pk1), OP_EQ, 0);
423
  tt_assert(rp2->supports_tunnelled_dir_requests);
424

425
  tt_int_op(smartlist_len(rp2->exit_policy),OP_EQ, 2);
426
427

  p = smartlist_get(rp2->exit_policy, 0);
428
  tt_int_op(p->policy_type,OP_EQ, ADDR_POLICY_ACCEPT);
429
  tt_assert(tor_addr_is_null(&p->addr));
430
431
432
  tt_int_op(p->maskbits,OP_EQ, 0);
  tt_int_op(p->prt_min,OP_EQ, 80);
  tt_int_op(p->prt_max,OP_EQ, 80);
433
434

  p = smartlist_get(rp2->exit_policy, 1);
435
  tt_int_op(p->policy_type,OP_EQ, ADDR_POLICY_REJECT);
436
  tt_assert(tor_addr_eq(&p->addr, &ex2->addr));
437
438
439
  tt_int_op(p->maskbits,OP_EQ, 8);
  tt_int_op(p->prt_min,OP_EQ, 24);
  tt_int_op(p->prt_max,OP_EQ, 24);
440
441

#if 0
442
443
  /* Okay, now for the directories. */
  {
444
    fingerprint_list = smartlist_new();
445
    crypto_pk_get_fingerprint(pk2, buf, 1);
446
    add_fingerprint_to_dir(buf, fingerprint_list, 0);
447
    crypto_pk_get_fingerprint(pk1, buf, 1);
448
    add_fingerprint_to_dir(buf, fingerprint_list, 0);
449
450
  }

451
#endif /* 0 */
452
453
  dirserv_free_fingerprint_list();

454
455
456
457
458
 done:
  if (r1)
    routerinfo_free(r1);
  if (r2)
    routerinfo_free(r2);
Nick Mathewson's avatar
Nick Mathewson committed
459
460
  if (rp2)
    routerinfo_free(rp2);
461

462
  tor_free(rsa_cc);
463
  tor_free(buf);
464
465
  tor_free(pk1_str);
  tor_free(pk2_str);
466
467
  if (pk1) crypto_pk_free(pk1);
  if (pk2) crypto_pk_free(pk2);
468
469
470
471
472
  if (rp1) routerinfo_free(rp1);
  tor_free(dir1); /* XXXX And more !*/
  tor_free(dir2); /* And more !*/
}

473
474
475
#include "failing_routerdescs.inc"

static void
476
test_dir_routerinfo_parsing(void *arg)
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
{
  (void) arg;

  int again;
  routerinfo_t *ri = NULL;

#define CHECK_OK(s)                                                     \
  do {                                                                  \
    routerinfo_free(ri);                                                \
    ri = router_parse_entry_from_string((s), NULL, 0, 0, NULL, NULL);   \
    tt_assert(ri);                                                      \
  } while (0)
#define CHECK_FAIL(s, againval)                                         \
  do {                                                                  \
    routerinfo_free(ri);                                                \
    again = 999;                                                        \
    ri = router_parse_entry_from_string((s), NULL, 0, 0, NULL, &again); \
    tt_assert(ri == NULL);                                              \
495
    tt_int_op(again, OP_EQ, (againval));                                   \
496
497
498
499
500
  } while (0)

  CHECK_OK(EX_RI_MINIMAL);
  CHECK_OK(EX_RI_MAXIMAL);

501
502
  CHECK_OK(EX_RI_MINIMAL_ED);

503
504
505
506
  /* good annotations prepended */
  routerinfo_free(ri);
  ri = router_parse_entry_from_string(EX_RI_MINIMAL, NULL, 0, 0,
                                      "@purpose bridge\n", NULL);
507
  tt_ptr_op(ri, OP_NE, NULL);
508
509
510
511
512
513
  tt_assert(ri->purpose == ROUTER_PURPOSE_BRIDGE);
  routerinfo_free(ri);

  /* bad annotations prepended. */
  ri = router_parse_entry_from_string(EX_RI_MINIMAL,
                                      NULL, 0, 0, "@purpose\n", NULL);
514
  tt_ptr_op(ri, OP_EQ, NULL);
515
516
517
518

  /* bad annotations on router. */
  ri = router_parse_entry_from_string("@purpose\nrouter x\n", NULL, 0, 1,
                                      NULL, NULL);
519
  tt_ptr_op(ri, OP_EQ, NULL);
520
521
522
523

  /* unwanted annotations on router. */
  ri = router_parse_entry_from_string("@purpose foo\nrouter x\n", NULL, 0, 0,
                                      NULL, NULL);
524
  tt_ptr_op(ri, OP_EQ, NULL);
525
526
527
528

  /* No signature. */
  ri = router_parse_entry_from_string("router x\n", NULL, 0, 0,
                                      NULL, NULL);
529
  tt_ptr_op(ri, OP_EQ, NULL);
530
531
532
533

  /* Not a router */
  routerinfo_free(ri);
  ri = router_parse_entry_from_string("hello\n", NULL, 0, 0, NULL, NULL);
534
  tt_ptr_op(ri, OP_EQ, NULL);
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560

  CHECK_FAIL(EX_RI_BAD_SIG1, 1);
  CHECK_FAIL(EX_RI_BAD_SIG2, 1);
  CHECK_FAIL(EX_RI_BAD_TOKENS, 0);
  CHECK_FAIL(EX_RI_BAD_PUBLISHED, 0);
  CHECK_FAIL(EX_RI_NEG_BANDWIDTH, 0);
  CHECK_FAIL(EX_RI_BAD_BANDWIDTH, 0);
  CHECK_FAIL(EX_RI_BAD_BANDWIDTH2, 0);
  CHECK_FAIL(EX_RI_BAD_ONIONKEY1, 0);
  CHECK_FAIL(EX_RI_BAD_ONIONKEY2, 0);
  CHECK_FAIL(EX_RI_BAD_PORTS, 0);
  CHECK_FAIL(EX_RI_BAD_IP, 0);
  CHECK_FAIL(EX_RI_BAD_DIRPORT, 0);
  CHECK_FAIL(EX_RI_BAD_NAME2, 0);
  CHECK_FAIL(EX_RI_BAD_UPTIME, 0);

  CHECK_FAIL(EX_RI_BAD_BANDWIDTH3, 0);
  CHECK_FAIL(EX_RI_BAD_NTOR_KEY, 0);
  CHECK_FAIL(EX_RI_BAD_FINGERPRINT, 0);
  CHECK_FAIL(EX_RI_MISMATCHED_FINGERPRINT, 0);
  CHECK_FAIL(EX_RI_BAD_HAS_ACCEPT6, 0);
  CHECK_FAIL(EX_RI_BAD_NO_EXIT_POLICY, 0);
  CHECK_FAIL(EX_RI_BAD_IPV6_EXIT_POLICY, 0);
  CHECK_FAIL(EX_RI_BAD_FAMILY, 0);
  CHECK_FAIL(EX_RI_ZERO_ORPORT, 0);

561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
  CHECK_FAIL(EX_RI_ED_MISSING_CROSSCERT, 0);
  CHECK_FAIL(EX_RI_ED_MISSING_CROSSCERT2, 0);
  CHECK_FAIL(EX_RI_ED_MISSING_CROSSCERT_SIGN, 0);
  CHECK_FAIL(EX_RI_ED_BAD_SIG1, 0);
  CHECK_FAIL(EX_RI_ED_BAD_SIG2, 0);
  CHECK_FAIL(EX_RI_ED_BAD_SIG3, 0);
  CHECK_FAIL(EX_RI_ED_BAD_SIG4, 0);
  CHECK_FAIL(EX_RI_ED_BAD_CROSSCERT1, 0);
  CHECK_FAIL(EX_RI_ED_BAD_CROSSCERT3, 0);
  CHECK_FAIL(EX_RI_ED_BAD_CROSSCERT4, 0);
  CHECK_FAIL(EX_RI_ED_BAD_CROSSCERT5, 0);
  CHECK_FAIL(EX_RI_ED_BAD_CROSSCERT6, 0);
  CHECK_FAIL(EX_RI_ED_BAD_CROSSCERT7, 0);
  CHECK_FAIL(EX_RI_ED_MISPLACED1, 0);
  CHECK_FAIL(EX_RI_ED_MISPLACED2, 0);
  CHECK_FAIL(EX_RI_ED_BAD_CERT1, 0);
  CHECK_FAIL(EX_RI_ED_BAD_CERT2, 0);
  CHECK_FAIL(EX_RI_ED_BAD_CERT3, 0);

580
581
  /* This is allowed; we just ignore it. */
  CHECK_OK(EX_RI_BAD_EI_DIGEST);
582
  CHECK_OK(EX_RI_BAD_EI_DIGEST2);
583
584
585
586
587
588
589
590
591

#undef CHECK_FAIL
#undef CHECK_OK
 done:
  routerinfo_free(ri);
}

#include "example_extrainfo.inc"

592
593
594
static void
routerinfo_free_wrapper_(void *arg)
{
595
  routerinfo_free_(arg);
596
597
}

598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
static void
test_dir_extrainfo_parsing(void *arg)
{
  (void) arg;

#define CHECK_OK(s)                                                     \
  do {                                                                  \
    extrainfo_free(ei);                                                 \
    ei = extrainfo_parse_entry_from_string((s), NULL, 0, map, NULL);    \
    tt_assert(ei);                                                      \
  } while (0)
#define CHECK_FAIL(s, againval)                                         \
  do {                                                                  \
    extrainfo_free(ei);                                                 \
    again = 999;                                                        \
    ei = extrainfo_parse_entry_from_string((s), NULL, 0, map, &again);  \
    tt_assert(ei == NULL);                                              \
615
    tt_int_op(again, OP_EQ, (againval));                                   \
616
617
618
619
620
621
622
  } while (0)
#define ADD(name)                                                       \
  do {                                                                  \
    ri = tor_malloc_zero(sizeof(routerinfo_t));                         \
    crypto_pk_t *pk = ri->identity_pkey = crypto_pk_new();              \
    tt_assert(! crypto_pk_read_public_key_from_string(pk,               \
                                      name##_KEY, strlen(name##_KEY))); \
623
    tt_int_op(20,OP_EQ,base16_decode(d, 20, name##_FP, strlen(name##_FP))); \
624
625
626
627
628
629
630
631
632
633
634
635
636
637
    digestmap_set((digestmap_t*)map, d, ri);                            \
    ri = NULL;                                                          \
  } while (0)

  routerinfo_t *ri = NULL;
  char d[20];
  struct digest_ri_map_t *map = NULL;
  extrainfo_t *ei = NULL;
  int again;

  CHECK_OK(EX_EI_MINIMAL);
  tt_assert(ei->pending_sig);
  CHECK_OK(EX_EI_MAXIMAL);
  tt_assert(ei->pending_sig);
638
639
  CHECK_OK(EX_EI_GOOD_ED_EI);
  tt_assert(ei->pending_sig);
640
641
642
643

  map = (struct digest_ri_map_t *)digestmap_new();
  ADD(EX_EI_MINIMAL);
  ADD(EX_EI_MAXIMAL);
644
  ADD(EX_EI_GOOD_ED_EI);
645
646
647
648
649
650
  ADD(EX_EI_BAD_FP);
  ADD(EX_EI_BAD_NICKNAME);
  ADD(EX_EI_BAD_TOKENS);
  ADD(EX_EI_BAD_START);
  ADD(EX_EI_BAD_PUBLISHED);

651
652
653
654
655
656
657
658
659
  ADD(EX_EI_ED_MISSING_SIG);
  ADD(EX_EI_ED_MISSING_CERT);
  ADD(EX_EI_ED_BAD_CERT1);
  ADD(EX_EI_ED_BAD_CERT2);
  ADD(EX_EI_ED_BAD_SIG1);
  ADD(EX_EI_ED_BAD_SIG2);
  ADD(EX_EI_ED_MISPLACED_CERT);
  ADD(EX_EI_ED_MISPLACED_SIG);

660
  CHECK_OK(EX_EI_MINIMAL);
661
  tt_ptr_op(ei->pending_sig, OP_EQ, NULL);
662
  CHECK_OK(EX_EI_MAXIMAL);
663
  tt_ptr_op(ei->pending_sig, OP_EQ, NULL);
664
  CHECK_OK(EX_EI_GOOD_ED_EI);
665
  tt_ptr_op(ei->pending_sig, OP_EQ, NULL);
666
667
668
669
670
671
672
673
674
675

  CHECK_FAIL(EX_EI_BAD_SIG1,1);
  CHECK_FAIL(EX_EI_BAD_SIG2,1);
  CHECK_FAIL(EX_EI_BAD_SIG3,1);
  CHECK_FAIL(EX_EI_BAD_FP,0);
  CHECK_FAIL(EX_EI_BAD_NICKNAME,0);
  CHECK_FAIL(EX_EI_BAD_TOKENS,0);
  CHECK_FAIL(EX_EI_BAD_START,0);
  CHECK_FAIL(EX_EI_BAD_PUBLISHED,0);

676
677
678
679
680
681
682
683
684
  CHECK_FAIL(EX_EI_ED_MISSING_SIG,0);
  CHECK_FAIL(EX_EI_ED_MISSING_CERT,0);
  CHECK_FAIL(EX_EI_ED_BAD_CERT1,0);
  CHECK_FAIL(EX_EI_ED_BAD_CERT2,0);
  CHECK_FAIL(EX_EI_ED_BAD_SIG1,0);
  CHECK_FAIL(EX_EI_ED_BAD_SIG2,0);
  CHECK_FAIL(EX_EI_ED_MISPLACED_CERT,0);
  CHECK_FAIL(EX_EI_ED_MISPLACED_SIG,0);

685
686
687
688
#undef CHECK_OK
#undef CHECK_FAIL

 done:
Ola Bini's avatar
Ola Bini committed
689
  escaped(NULL);
690
  extrainfo_free(ei);
691
  routerinfo_free(ri);
692
  digestmap_free_((digestmap_t*)map, routerinfo_free_wrapper_);
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
}

static void
test_dir_parse_router_list(void *arg)
{
  (void) arg;
  smartlist_t *invalid = smartlist_new();
  smartlist_t *dest = smartlist_new();
  smartlist_t *chunks = smartlist_new();
  int dest_has_ri = 1;
  char *list = NULL;
  const char *cp;
  digestmap_t *map = NULL;
  char *mem_op_hex_tmp = NULL;
  routerinfo_t *ri = NULL;
  char d[DIGEST_LEN];

710
711
712
713
714
715
716
717
718
719
  smartlist_add_strdup(chunks, EX_RI_MINIMAL);     // ri 0
  smartlist_add_strdup(chunks, EX_RI_BAD_PORTS);   // bad ri 0
  smartlist_add_strdup(chunks, EX_EI_MAXIMAL);     // ei 0
  smartlist_add_strdup(chunks, EX_EI_BAD_SIG2);    // bad ei --
  smartlist_add_strdup(chunks, EX_EI_BAD_NICKNAME);// bad ei 0
  smartlist_add_strdup(chunks, EX_RI_BAD_SIG1);    // bad ri --
  smartlist_add_strdup(chunks, EX_EI_BAD_PUBLISHED);  // bad ei 1
  smartlist_add_strdup(chunks, EX_RI_MAXIMAL);     // ri 1
  smartlist_add_strdup(chunks, EX_RI_BAD_FAMILY);  // bad ri 1
  smartlist_add_strdup(chunks, EX_EI_MINIMAL);     // ei 1
720
721
722
723
724

  list = smartlist_join_strings(chunks, "", 0, NULL);

  /* First, parse the routers. */
  cp = list;
725
  tt_int_op(0,OP_EQ,
726
727
            router_parse_list_from_string(&cp, NULL, dest, SAVED_NOWHERE,
                                          0, 0, NULL, invalid));
728
729
  tt_int_op(2, OP_EQ, smartlist_len(dest));
  tt_ptr_op(cp, OP_EQ, list + strlen(list));
730
731

  routerinfo_t *r = smartlist_get(dest, 0);
732
  tt_mem_op(r->cache_info.signed_descriptor_body, OP_EQ,
733
734
            EX_RI_MINIMAL, strlen(EX_RI_MINIMAL));
  r = smartlist_get(dest, 1);
735
  tt_mem_op(r->cache_info.signed_descriptor_body, OP_EQ,
736
737
            EX_RI_MAXIMAL, strlen(EX_RI_MAXIMAL));

738
  tt_int_op(2, OP_EQ, smartlist_len(invalid));
739
740
741
742
743
744
  test_memeq_hex(smartlist_get(invalid, 0),
                 "ab9eeaa95e7d45740185b4e519c76ead756277a9");
  test_memeq_hex(smartlist_get(invalid, 1),
                 "9a651ee03b64325959e8f1b46f2b689b30750b4c");

  /* Now tidy up */
745
746
  SMARTLIST_FOREACH(dest, routerinfo_t *, rinfo, routerinfo_free(rinfo));
  SMARTLIST_FOREACH(invalid, uint8_t *, dig, tor_free(dig));
747
748
749
750
751
752
753
754
755
756
757
  smartlist_clear(dest);
  smartlist_clear(invalid);

  /* And check extrainfos. */
  dest_has_ri = 0;
  map = (digestmap_t*)router_get_routerlist()->identity_map;
  ADD(EX_EI_MINIMAL);
  ADD(EX_EI_MAXIMAL);
  ADD(EX_EI_BAD_NICKNAME);
  ADD(EX_EI_BAD_PUBLISHED);
  cp = list;
758
  tt_int_op(0,OP_EQ,
759
760
            router_parse_list_from_string(&cp, NULL, dest, SAVED_NOWHERE,
                                          1, 0, NULL, invalid));
761
  tt_int_op(2, OP_EQ, smartlist_len(dest));
762
  extrainfo_t *e = smartlist_get(dest, 0);
763
  tt_mem_op(e->cache_info.signed_descriptor_body, OP_EQ,
764
765
            EX_EI_MAXIMAL, strlen(EX_EI_MAXIMAL));
  e = smartlist_get(dest, 1);
766
  tt_mem_op(e->cache_info.signed_descriptor_body, OP_EQ,
767
768
            EX_EI_MINIMAL, strlen(EX_EI_MINIMAL));

769
  tt_int_op(2, OP_EQ, smartlist_len(invalid));
770
771
772
773
774
775
776
777
778
779
780
781
  test_memeq_hex(smartlist_get(invalid, 0),
                 "d5df4aa62ee9ffc9543d41150c9864908e0390af");
  test_memeq_hex(smartlist_get(invalid, 1),
                 "f61efd2a7f4531f3687a9043e0de90a862ec64ba");

 done:
  tor_free(list);
  if (dest_has_ri)
    SMARTLIST_FOREACH(dest, routerinfo_t *, rt, routerinfo_free(rt));
  else
    SMARTLIST_FOREACH(dest, extrainfo_t *, ei, extrainfo_free(ei));
  smartlist_free(dest);
782
  SMARTLIST_FOREACH(invalid, uint8_t *, dig, tor_free(dig));
783
  smartlist_free(invalid);
784
  SMARTLIST_FOREACH(chunks, char *, chunk, tor_free(chunk));
785
786
787
  smartlist_free(chunks);
  routerinfo_free(ri);
  if (map) {
788
    digestmap_free_((digestmap_t*)map, routerinfo_free_wrapper_);
789
790
791
792
793
794
795
796
    router_get_routerlist()->identity_map =
      (struct digest_ri_map_t*)digestmap_new();
  }
  tor_free(mem_op_hex_tmp);

#undef ADD
}

797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
static download_status_t dls_minimal;
static download_status_t dls_maximal;
static download_status_t dls_bad_fingerprint;
static download_status_t dls_bad_sig2;
static download_status_t dls_bad_ports;
static download_status_t dls_bad_tokens;

static int mock_router_get_dl_status_unrecognized = 0;
static int mock_router_get_dl_status_calls = 0;

static download_status_t *
mock_router_get_dl_status(const char *d)
{
  ++mock_router_get_dl_status_calls;
  char hex[HEX_DIGEST_LEN+1];
  base16_encode(hex, sizeof(hex), d, DIGEST_LEN);
  if (!strcmp(hex, "3E31D19A69EB719C00B02EC60D13356E3F7A3452")) {
    return &dls_minimal;
  } else if (!strcmp(hex, "581D8A368A0FA854ECDBFAB841D88B3F1B004038")) {
    return &dls_maximal;
  } else if (!strcmp(hex, "2578AE227C6116CDE29B3F0E95709B9872DEE5F1")) {
    return &dls_bad_fingerprint;
  } else if (!strcmp(hex, "16D387D3A58F7DB3CF46638F8D0B90C45C7D769C")) {
    return &dls_bad_sig2;
  } else if (!strcmp(hex, "AB9EEAA95E7D45740185B4E519C76EAD756277A9")) {
    return &dls_bad_ports;
  } else if (!strcmp(hex, "A0CC2CEFAD59DBF19F468BFEE60E0868C804B422")) {
    return &dls_bad_tokens;
  } else {
    ++mock_router_get_dl_status_unrecognized;
    return NULL;
  }
}

static void
test_dir_load_routers(void *arg)
{
  (void) arg;
  smartlist_t *chunks = smartlist_new();
  smartlist_t *wanted = smartlist_new();
  char buf[DIGEST_LEN];
  char *mem_op_hex_tmp = NULL;
839
  char *list = NULL;
840
841
842

#define ADD(str)                                                        \
  do {                                                                  \
843
    tt_int_op(0,OP_EQ,router_get_router_hash(str, strlen(str), buf));      \
844
    smartlist_add_strdup(wanted, hex_str(buf, DIGEST_LEN));        \
845
846
847
848
  } while (0)

  MOCK(router_get_dl_status_by_descriptor_digest, mock_router_get_dl_status);

849
850
  update_approx_time(1412510400);

851
852
853
854
855
856
  smartlist_add_strdup(chunks, EX_RI_MINIMAL);
  smartlist_add_strdup(chunks, EX_RI_BAD_FINGERPRINT);
  smartlist_add_strdup(chunks, EX_RI_BAD_SIG2);
  smartlist_add_strdup(chunks, EX_RI_MAXIMAL);
  smartlist_add_strdup(chunks, EX_RI_BAD_PORTS);
  smartlist_add_strdup(chunks, EX_RI_BAD_TOKENS);
857
858
859
860
861
862
863
864

  /* not ADDing MINIMIAL */
  ADD(EX_RI_MAXIMAL);
  ADD(EX_RI_BAD_FINGERPRINT);
  ADD(EX_RI_BAD_SIG2);
  /* Not ADDing BAD_PORTS */
  ADD(EX_RI_BAD_TOKENS);

865
  list = smartlist_join_strings(chunks, "", 0, NULL);
866
  tt_int_op(1, OP_EQ,
867
868
869
870
871
            router_load_routers_from_string(list, NULL, SAVED_IN_JOURNAL,
                                            wanted, 1, NULL));

  /* The "maximal" router was added. */
  /* "minimal" was not. */
872
  tt_int_op(smartlist_len(router_get_routerlist()->routers),OP_EQ,1);
873
874
875
  routerinfo_t *r = smartlist_get(router_get_routerlist()->routers, 0);
  test_memeq_hex(r->cache_info.signed_descriptor_digest,
                 "581D8A368A0FA854ECDBFAB841D88B3F1B004038");
876
877
  tt_int_op(dls_minimal.n_download_failures, OP_EQ, 0);
  tt_int_op(dls_maximal.n_download_failures, OP_EQ, 0);
878
879
880

  /* "Bad fingerprint" and "Bad tokens" should have gotten marked
   * non-retriable. */
881
882
883
884
  tt_want_int_op(mock_router_get_dl_status_calls, OP_EQ, 2);
  tt_want_int_op(mock_router_get_dl_status_unrecognized, OP_EQ, 0);
  tt_int_op(dls_bad_fingerprint.n_download_failures, OP_EQ, 255);
  tt_int_op(dls_bad_tokens.n_download_failures, OP_EQ, 255);
885
886
887

  /* bad_sig2 and bad ports" are retriable -- one since only the signature
   * was bad, and one because we didn't ask for it. */
888
889
  tt_int_op(dls_bad_sig2.n_download_failures, OP_EQ, 0);
  tt_int_op(dls_bad_ports.n_download_failures, OP_EQ, 0);
890
891

  /* Wanted still contains "BAD_SIG2" */
892
893
  tt_int_op(smartlist_len(wanted), OP_EQ, 1);
  tt_str_op(smartlist_get(wanted, 0), OP_EQ,
894
895
896
897
898
899
900
901
902
903
904
            "E0A3753CEFD54128EAB239F294954121DB23D2EF");

#undef ADD

 done:
  tor_free(mem_op_hex_tmp);
  UNMOCK(router_get_dl_status_by_descriptor_digest);
  SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
  smartlist_free(chunks);
  SMARTLIST_FOREACH(wanted, char *, cp, tor_free(cp));
  smartlist_free(wanted);
905
  tor_free(list);
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
}

static int mock_get_by_ei_dd_calls = 0;
static int mock_get_by_ei_dd_unrecognized = 0;

static signed_descriptor_t sd_ei_minimal;
static signed_descriptor_t sd_ei_bad_nickname;
static signed_descriptor_t sd_ei_maximal;
static signed_descriptor_t sd_ei_bad_tokens;
static signed_descriptor_t sd_ei_bad_sig2;

static signed_descriptor_t *
mock_get_by_ei_desc_digest(const char *d)
{

  ++mock_get_by_ei_dd_calls;
  char hex[HEX_DIGEST_LEN+1];
  base16_encode(hex, sizeof(hex), d, DIGEST_LEN);

  if (!strcmp(hex, "11E0EDF526950739F7769810FCACAB8C882FAEEE")) {
    return &sd_ei_minimal;
  } else if (!strcmp(hex, "47803B02A0E70E9E8BDA226CB1D74DE354D67DFF")) {
    return &sd_ei_maximal;
  } else if (!strcmp(hex, "D5DF4AA62EE9FFC9543D41150C9864908E0390AF")) {
    return &sd_ei_bad_nickname;
  } else if (!strcmp(hex, "16D387D3A58F7DB3CF46638F8D0B90C45C7D769C")) {
    return &sd_ei_bad_sig2;
  } else if (!strcmp(hex, "9D90F8C42955BBC57D54FB05E54A3F083AF42E8B")) {
    return &sd_ei_bad_tokens;
  } else {
    ++mock_get_by_ei_dd_unrecognized;
    return NULL;
  }
}

Taylor Yu's avatar
Taylor Yu committed
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
static signed_descriptor_t *
mock_ei_get_by_ei_digest(const char *d)
{
  char hex[HEX_DIGEST_LEN+1];
  base16_encode(hex, sizeof(hex), d, DIGEST_LEN);
  signed_descriptor_t *sd = &sd_ei_minimal;

  if (!strcmp(hex, "11E0EDF526950739F7769810FCACAB8C882FAEEE")) {
    sd->signed_descriptor_body = (char *)EX_EI_MINIMAL;
    sd->signed_descriptor_len = sizeof(EX_EI_MINIMAL);
    sd->annotations_len = 0;
    sd->saved_location = SAVED_NOWHERE;
    return sd;
  }
  return NULL;
}

958
static smartlist_t *mock_ei_insert_list = NULL;
959
static was_router_added_t
960
mock_ei_insert(routerlist_t *rl, extrainfo_t *ei, int warn_if_incompatible)
961
962
{
  (void) rl;
963
  (void) warn_if_incompatible;
964
  smartlist_add(mock_ei_insert_list, ei);
965
  return ROUTER_ADDED_SUCCESSFULLY;
966
967
968
969
970
971
972
973
974
975
}

static void
test_dir_load_extrainfo(void *arg)
{
  (void) arg;
  smartlist_t *chunks = smartlist_new();
  smartlist_t *wanted = smartlist_new();
  char buf[DIGEST_LEN];
  char *mem_op_hex_tmp = NULL;
976
  char *list = NULL;
977
978
979

#define ADD(str)                                                        \
  do {                                                                  \
980
    tt_int_op(0,OP_EQ,router_get_extrainfo_hash(str, strlen(str), buf));   \
981
    smartlist_add_strdup(wanted, hex_str(buf, DIGEST_LEN));        \
982
983
984
985
986
987
  } while (0)

  mock_ei_insert_list = smartlist_new();
  MOCK(router_get_by_extrainfo_digest, mock_get_by_ei_desc_digest);
  MOCK(extrainfo_insert, mock_ei_insert);

988
989
990
991
992
  smartlist_add_strdup(chunks, EX_EI_MINIMAL);
  smartlist_add_strdup(chunks, EX_EI_BAD_NICKNAME);
  smartlist_add_strdup(chunks, EX_EI_MAXIMAL);
  smartlist_add_strdup(chunks, EX_EI_BAD_PUBLISHED);
  smartlist_add_strdup(chunks, EX_EI_BAD_TOKENS);
993
994
995
996
997
998
999
1000

  /* not ADDing MINIMIAL */
  ADD(EX_EI_MAXIMAL);
  ADD(EX_EI_BAD_NICKNAME);
  /* Not ADDing BAD_PUBLISHED */
  ADD(EX_EI_BAD_TOKENS);
  ADD(EX_EI_BAD_SIG2);

For faster browsing, not all history is shown. View entire blame