tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

test_hs_service.c (98431B)


      1 /* Copyright (c) 2016-2021, The Tor Project, Inc. */
      2 /* See LICENSE for licensing information */
      3 
      4 /**
      5 * \file test_hs_service.c
      6 * \brief Test hidden service functionality.
      7 */
      8 
      9 #define CIRCUITBUILD_PRIVATE
     10 #define CIRCUITLIST_PRIVATE
     11 #define CONFIG_PRIVATE
     12 #define CONNECTION_PRIVATE
     13 #define CONNECTION_EDGE_PRIVATE
     14 #define CRYPTO_PRIVATE
     15 #define HS_COMMON_PRIVATE
     16 #define HS_SERVICE_PRIVATE
     17 #define HS_INTROPOINT_PRIVATE
     18 #define HS_CIRCUIT_PRIVATE
     19 #define MAINLOOP_PRIVATE
     20 #define NETWORKSTATUS_PRIVATE
     21 #define STATEFILE_PRIVATE
     22 #define CHANNEL_OBJECT_PRIVATE
     23 #define HS_CLIENT_PRIVATE
     24 #define CRYPT_PATH_PRIVATE
     25 
     26 #include "test/test.h"
     27 #include "test/test_helpers.h"
     28 #include "test/log_test_helpers.h"
     29 #include "test/hs_test_helpers.h"
     30 
     31 #include "core/or/or.h"
     32 #include "app/config/config.h"
     33 #include "app/config/statefile.h"
     34 #include "core/crypto/hs_ntor.h"
     35 #include "core/mainloop/connection.h"
     36 #include "core/mainloop/mainloop.h"
     37 #include "core/or/circuitbuild.h"
     38 #include "core/or/circuitlist.h"
     39 #include "core/or/circuituse.h"
     40 #include "core/or/connection_edge.h"
     41 #include "core/or/edge_connection_st.h"
     42 #include "core/or/relay.h"
     43 #include "core/or/versions.h"
     44 #include "feature/dirauth/dirvote.h"
     45 #include "feature/dirauth/shared_random_state.h"
     46 #include "feature/dirauth/voting_schedule.h"
     47 #include "feature/hs/hs_circuit.h"
     48 #include "feature/hs/hs_circuitmap.h"
     49 #include "feature/hs/hs_client.h"
     50 #include "feature/hs/hs_common.h"
     51 #include "feature/hs/hs_config.h"
     52 #include "feature/hs/hs_ident.h"
     53 #include "feature/hs/hs_ob.h"
     54 #include "feature/hs/hs_cell.h"
     55 #include "feature/hs/hs_intropoint.h"
     56 #include "feature/hs/hs_metrics.h"
     57 #include "feature/hs/hs_service.h"
     58 #include "feature/nodelist/networkstatus.h"
     59 #include "feature/nodelist/nodelist.h"
     60 #include "lib/crypt_ops/crypto_rand.h"
     61 #include "lib/fs/dir.h"
     62 
     63 #include "core/or/cpath_build_state_st.h"
     64 #include "core/or/crypt_path_st.h"
     65 #include "core/or/crypt_path.h"
     66 #include "feature/nodelist/networkstatus_st.h"
     67 #include "feature/nodelist/node_st.h"
     68 #include "core/or/origin_circuit_st.h"
     69 #include "app/config/or_state_st.h"
     70 #include "feature/nodelist/routerinfo_st.h"
     71 
     72 /* Trunnel */
     73 #include "trunnel/hs/cell_establish_intro.h"
     74 
     75 #ifdef HAVE_SYS_STAT_H
     76 #include <sys/stat.h>
     77 #endif
     78 #ifdef HAVE_UNISTD_H
     79 #include <unistd.h>
     80 #endif
     81 
     82 static networkstatus_t mock_ns;
     83 
     84 static networkstatus_t *
     85 mock_networkstatus_get_reasonably_live_consensus(time_t now, int flavor)
     86 {
     87  (void) now;
     88  (void) flavor;
     89  return &mock_ns;
     90 }
     91 
     92 static networkstatus_t *
     93 mock_networkstatus_get_reasonably_live_consensus_null(time_t now, int flavor)
     94 {
     95  (void) now;
     96  (void) flavor;
     97  return NULL;
     98 }
     99 
    100 static or_state_t *dummy_state = NULL;
    101 
    102 /* Mock function to get fake or state (used for rev counters) */
    103 static or_state_t *
    104 get_or_state_replacement(void)
    105 {
    106  return dummy_state;
    107 }
    108 
    109 /* Mock function because we are not trying to test the close circuit that does
    110 * an awful lot of checks on the circuit object. */
    111 static void
    112 mock_circuit_mark_for_close(circuit_t *circ, int reason, int line,
    113                            const char *file)
    114 {
    115  (void) circ;
    116  (void) reason;
    117  (void) line;
    118  (void) file;
    119  return;
    120 }
    121 
    122 static size_t relay_payload_len;
    123 static char relay_payload[RELAY_PAYLOAD_SIZE];
    124 
    125 static int
    126 mock_relay_send_command_from_edge(streamid_t stream_id, circuit_t *circ,
    127                                  uint8_t relay_command, const char *payload,
    128                                  size_t payload_len,
    129                                  crypt_path_t *cpath_layer,
    130                                  const char *filename, int lineno)
    131 {
    132  (void) stream_id;
    133  (void) circ;
    134  (void) relay_command;
    135  (void) payload;
    136  (void) payload_len;
    137  (void) cpath_layer;
    138  (void) filename;
    139  (void) lineno;
    140 
    141  memcpy(relay_payload, payload, payload_len);
    142  relay_payload_len = payload_len;
    143 
    144  return 0;
    145 }
    146 
    147 static unsigned int num_intro_points = 0;
    148 static unsigned int
    149 mock_count_desc_circuit_established(const hs_service_descriptor_t *desc)
    150 {
    151  (void) desc;
    152  return num_intro_points;
    153 }
    154 
    155 static int
    156 mock_router_have_minimum_dir_info_false(void)
    157 {
    158  return 0;
    159 }
    160 
    161 /* Helper: from a set of options in conf, configure a service which will add
    162 * it to the staging list of the HS subsystem. */
    163 static int
    164 helper_config_service(const char *conf)
    165 {
    166  int ret = 0;
    167  or_options_t *options = NULL;
    168  tt_assert(conf);
    169  options = helper_parse_options(conf);
    170  tt_assert(options);
    171  ret = hs_config_service_all(options, 0);
    172 done:
    173  or_options_free(options);
    174  return ret;
    175 }
    176 
    177 /* Test: Ensure that setting up rendezvous circuits works correctly. */
    178 static void
    179 test_e2e_rend_circuit_setup(void *arg)
    180 {
    181  ed25519_public_key_t service_pk;
    182  origin_circuit_t *or_circ;
    183  int retval;
    184 
    185  /** In this test we create a v3 prop224 service-side rendezvous circuit.
    186   *  We simulate an HS ntor key exchange with a client, and check that
    187   *  the circuit was setup correctly and is ready to accept rendezvous data */
    188 
    189  (void) arg;
    190 
    191  /* Now make dummy circuit */
    192  {
    193    or_circ = origin_circuit_new();
    194 
    195    or_circ->base_.purpose = CIRCUIT_PURPOSE_S_CONNECT_REND;
    196 
    197    or_circ->build_state = tor_malloc_zero(sizeof(cpath_build_state_t));
    198    or_circ->build_state->is_internal = 1;
    199 
    200    /* prop224: Setup hs conn identifier on the stream */
    201    ed25519_secret_key_t sk;
    202    tt_int_op(0, OP_EQ, ed25519_secret_key_generate(&sk, 0));
    203    tt_int_op(0, OP_EQ, ed25519_public_key_generate(&service_pk, &sk));
    204 
    205    or_circ->hs_ident = hs_ident_circuit_new(&service_pk);
    206 
    207    TO_CIRCUIT(or_circ)->state = CIRCUIT_STATE_OPEN;
    208  }
    209 
    210  /* Check number of hops */
    211  retval = cpath_get_n_hops(&or_circ->cpath);
    212  tt_int_op(retval, OP_EQ, 0);
    213 
    214  /* Setup the circuit: do the ntor key exchange */
    215  {
    216    uint8_t ntor_key_seed[DIGEST256_LEN] = {2};
    217    retval = hs_circuit_setup_e2e_rend_circ(or_circ, ntor_key_seed,
    218                                            sizeof(ntor_key_seed), 1);
    219    tt_int_op(retval, OP_EQ, 0);
    220  }
    221 
    222  /* See that a hop was added to the circuit's cpath */
    223  retval = cpath_get_n_hops(&or_circ->cpath);
    224  tt_int_op(retval, OP_EQ, 1);
    225 
    226  /* Check the digest algo */
    227  tt_int_op(crypto_digest_get_algorithm(
    228                              or_circ->cpath->pvt_crypto.c.tor1.f_digest),
    229            OP_EQ, DIGEST_SHA3_256);
    230  tt_int_op(crypto_digest_get_algorithm(
    231                              or_circ->cpath->pvt_crypto.c.tor1.b_digest),
    232            OP_EQ, DIGEST_SHA3_256);
    233  tt_assert(or_circ->cpath->pvt_crypto.c.tor1.f_crypto);
    234  tt_assert(or_circ->cpath->pvt_crypto.c.tor1.b_crypto);
    235 
    236  /* Ensure that circ purpose was changed */
    237  tt_int_op(or_circ->base_.purpose, OP_EQ, CIRCUIT_PURPOSE_S_REND_JOINED);
    238 
    239 done:
    240  circuit_free_(TO_CIRCUIT(or_circ));
    241 }
    242 
    243 /* Helper: Return a newly allocated and initialized origin circuit with
    244 * purpose and flags. A default HS identifier is set to an ed25519
    245 * authentication key for introduction point. */
    246 static origin_circuit_t *
    247 helper_create_origin_circuit(int purpose, int flags)
    248 {
    249  origin_circuit_t *circ = NULL;
    250 
    251  circ = origin_circuit_init(purpose, flags);
    252  tor_assert(circ);
    253  circ->cpath = tor_malloc_zero(sizeof(crypt_path_t));
    254  circ->cpath->magic = CRYPT_PATH_MAGIC;
    255  circ->cpath->state = CPATH_STATE_OPEN;
    256  circ->cpath->package_window = circuit_initial_package_window();
    257  circ->cpath->deliver_window = CIRCWINDOW_START;
    258  circ->cpath->prev = circ->cpath;
    259  /* Random nonce. */
    260  crypto_rand(circ->cpath->prev->rend_circ_nonce, DIGEST_LEN);
    261  /* Create a default HS identifier. */
    262  circ->hs_ident = tor_malloc_zero(sizeof(hs_ident_circuit_t));
    263 
    264  return circ;
    265 }
    266 
    267 /* Helper: Return a newly allocated authorized client object with
    268 * and a newly generated public key. */
    269 static hs_service_authorized_client_t *
    270 helper_create_authorized_client(void)
    271 {
    272  int ret;
    273  hs_service_authorized_client_t *client;
    274  curve25519_secret_key_t seckey;
    275  client = tor_malloc_zero(sizeof(hs_service_authorized_client_t));
    276 
    277  ret = curve25519_secret_key_generate(&seckey, 0);
    278  tt_int_op(ret, OP_EQ, 0);
    279  curve25519_public_key_generate(&client->client_pk, &seckey);
    280 
    281 done:
    282  return client;
    283 }
    284 
    285 /* Helper: Return a newly allocated authorized client object with the
    286 * same client name and the same public key as the given client. */
    287 static hs_service_authorized_client_t *
    288 helper_clone_authorized_client(const hs_service_authorized_client_t *client)
    289 {
    290  hs_service_authorized_client_t *client_out;
    291 
    292  tor_assert(client);
    293 
    294  client_out = tor_malloc_zero(sizeof(hs_service_authorized_client_t));
    295  memcpy(client_out->client_pk.public_key,
    296         client->client_pk.public_key, CURVE25519_PUBKEY_LEN);
    297 
    298  return client_out;
    299 }
    300 
    301 /* Helper: Return a newly allocated service object with the identity keypair
    302 * sets and the current descriptor. Then register it to the global map.
    303 * Caller should use hs_free_all() to free this service or remove it from the
    304 * global map before freeing. */
    305 static hs_service_t *
    306 helper_create_service(void)
    307 {
    308  /* Set a service for this circuit. */
    309  hs_service_t *service = hs_service_new(get_options());
    310  tor_assert(service);
    311  service->config.version = HS_VERSION_THREE;
    312  ed25519_secret_key_generate(&service->keys.identity_sk, 0);
    313  ed25519_public_key_generate(&service->keys.identity_pk,
    314                              &service->keys.identity_sk);
    315  service->desc_current = service_descriptor_new();
    316  tt_assert(service->desc_current);
    317  /* Register service to global map. */
    318  int ret = register_service(get_hs_service_map(), service);
    319  tt_int_op(ret, OP_EQ, 0);
    320 
    321 done:
    322  return service;
    323 }
    324 
    325 /* Helper: Deallocate a given service object, its child objects and
    326 * remove it from onion service map.
    327 * */
    328 static void
    329 helper_destroy_service(hs_service_t *service)
    330 {
    331  if (!service)
    332    return;
    333 
    334  remove_service(get_hs_service_map(), service);
    335 
    336  hs_service_free(service);
    337 }
    338 
    339 /* Helper: Return a newly allocated service object with clients. */
    340 static hs_service_t *
    341 helper_create_service_with_clients(int num_clients)
    342 {
    343  int i;
    344  hs_service_t *service = helper_create_service();
    345  tt_assert(service);
    346  service->config.clients = smartlist_new();
    347 
    348  for (i = 0; i < num_clients; i++) {
    349    hs_service_authorized_client_t *client;
    350    client = helper_create_authorized_client();
    351    smartlist_add(service->config.clients, client);
    352  }
    353 
    354 done:
    355  return service;
    356 }
    357 
    358 /* Helper: Return a newly allocated service intro point with two link
    359 * specifiers, one IPv4 and one legacy ID set to As. */
    360 static hs_service_intro_point_t *
    361 helper_create_service_ip(void)
    362 {
    363  link_specifier_t *ls;
    364  hs_service_intro_point_t *ip = service_intro_point_new(NULL);
    365  tor_assert(ip);
    366  /* Add a first unused link specifier. */
    367  ls = link_specifier_new();
    368  link_specifier_set_ls_type(ls, LS_IPV4);
    369  smartlist_add(ip->base.link_specifiers, ls);
    370  /* Add a second link specifier used by a test. */
    371  ls = link_specifier_new();
    372  link_specifier_set_ls_type(ls, LS_LEGACY_ID);
    373  memset(link_specifier_getarray_un_legacy_id(ls), 'A',
    374         link_specifier_getlen_un_legacy_id(ls));
    375  smartlist_add(ip->base.link_specifiers, ls);
    376 
    377  return ip;
    378 }
    379 
    380 static void
    381 test_load_keys(void *arg)
    382 {
    383  int ret;
    384  char *conf = NULL;
    385  char *hsdir_v3 = tor_strdup(get_fname("hs3"));
    386  char addr[HS_SERVICE_ADDR_LEN_BASE32 + 1];
    387 
    388  (void) arg;
    389 
    390  /* We'll register one service then we'll load keys and validate that both
    391   * are in a correct state. */
    392 
    393  hs_init();
    394 
    395 #define conf_fmt \
    396  "HiddenServiceDir %s\n" \
    397  "HiddenServiceVersion %d\n" \
    398  "HiddenServicePort 65535\n"
    399 
    400  /* v3 service. */
    401  tor_asprintf(&conf, conf_fmt, hsdir_v3, HS_VERSION_THREE);
    402  ret = helper_config_service(conf);
    403  tor_free(conf);
    404  tt_int_op(ret, OP_EQ, 0);
    405  /* It's in staging? */
    406  tt_int_op(get_hs_service_staging_list_size(), OP_EQ, 1);
    407 
    408 #undef conf_fmt
    409 
    410  /* Load the keys for these. After that, the v3 service should be registered
    411   * in the global map. */
    412  hs_service_load_all_keys();
    413  tt_int_op(get_hs_service_map_size(), OP_EQ, 1);
    414  hs_service_t *s = get_first_service();
    415  tt_assert(s);
    416 
    417  /* Ok we have the service object. Validate few things. */
    418  tt_assert(!fast_mem_is_zero(s->onion_address, sizeof(s->onion_address)));
    419  tt_int_op(hs_address_is_valid(s->onion_address), OP_EQ, 1);
    420  tt_assert(!fast_mem_is_zero((char *) s->keys.identity_sk.seckey,
    421                             ED25519_SECKEY_LEN));
    422  tt_assert(!fast_mem_is_zero((char *) s->keys.identity_pk.pubkey,
    423                             ED25519_PUBKEY_LEN));
    424  /* Check onion address from identity key. */
    425  hs_build_address(&s->keys.identity_pk, s->config.version, addr);
    426  tt_int_op(hs_address_is_valid(addr), OP_EQ, 1);
    427  tt_str_op(addr, OP_EQ, s->onion_address);
    428 
    429 done:
    430  tor_free(hsdir_v3);
    431  hs_free_all();
    432 }
    433 
    434 static void
    435 test_client_filename_is_valid(void *arg)
    436 {
    437  (void) arg;
    438 
    439  /* Valid file name. */
    440  tt_assert(client_filename_is_valid("a.auth"));
    441  /* Valid file name with special character. */
    442  tt_assert(client_filename_is_valid("a-.auth"));
    443  /* Invalid extension. */
    444  tt_assert(!client_filename_is_valid("a.ath"));
    445  /* Nothing before the extension. */
    446  tt_assert(!client_filename_is_valid(".auth"));
    447 
    448 done:
    449  ;
    450 }
    451 
    452 static void
    453 test_parse_authorized_client(void *arg)
    454 {
    455  hs_service_authorized_client_t *client = NULL;
    456 
    457  (void) arg;
    458 
    459  /* Valid authorized client. */
    460  client = parse_authorized_client(
    461    "descriptor:x25519:dz4q5xqlb4ldnbs72iarrml4ephk3du4i7o2cgiva5lwr6wkquja");
    462  tt_assert(client);
    463 
    464  /* Wrong number of fields. */
    465  tt_assert(!parse_authorized_client("a:b:c:d:e"));
    466  /* Wrong auth type. */
    467  tt_assert(!parse_authorized_client(
    468    "x:x25519:dz4q5xqlb4ldnbs72iarrml4ephk3du4i7o2cgiva5lwr6wkquja"));
    469  /* Wrong key type. */
    470  tt_assert(!parse_authorized_client(
    471    "descriptor:x:dz4q5xqlb4ldnbs72iarrml4ephk3du4i7o2cgiva5lwr6wkquja"));
    472  /* Some malformed string. */
    473  tt_assert(!parse_authorized_client("descriptor:x25519:aa=="));
    474  tt_assert(!parse_authorized_client("descriptor:"));
    475  tt_assert(!parse_authorized_client("descriptor:x25519"));
    476  tt_assert(!parse_authorized_client("descriptor:x25519:"));
    477  tt_assert(!parse_authorized_client(""));
    478 
    479 done:
    480  service_authorized_client_free(client);
    481 }
    482 
    483 static char *
    484 mock_read_file_to_str(const char *filename, int flags, struct stat *stat_out)
    485 {
    486  char *ret = NULL;
    487 
    488  (void) flags;
    489  (void) stat_out;
    490 
    491  if (!strcmp(filename, get_fname("hs3" PATH_SEPARATOR
    492                                  "authorized_clients" PATH_SEPARATOR
    493                                  "client1.auth"))) {
    494    ret = tor_strdup("descriptor:x25519:"
    495                  "dz4q5xqlb4ldnbs72iarrml4ephk3du4i7o2cgiva5lwr6wkquja");
    496    goto done;
    497  }
    498 
    499  if (!strcmp(filename, get_fname("hs3" PATH_SEPARATOR
    500                                  "authorized_clients" PATH_SEPARATOR
    501                                  "dummy.xxx"))) {
    502    ret = tor_strdup("descriptor:x25519:"
    503                  "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
    504    goto done;
    505  }
    506 
    507  if (!strcmp(filename, get_fname("hs3" PATH_SEPARATOR
    508                                  "authorized_clients" PATH_SEPARATOR
    509                                  "client2.auth"))) {
    510    ret = tor_strdup("descriptor:x25519:"
    511                  "okoi2gml3wd6x7jganlk5d66xxyjgg24sxw4y7javx4giqr66zta");
    512    goto done;
    513  }
    514 
    515 done:
    516  return ret;
    517 }
    518 
    519 static smartlist_t *
    520 mock_tor_listdir(const char *dirname)
    521 {
    522  smartlist_t *file_list = smartlist_new();
    523 
    524  (void) dirname;
    525 
    526  smartlist_add(file_list, tor_strdup("client1.auth"));
    527  smartlist_add(file_list, tor_strdup("dummy.xxx"));
    528  smartlist_add(file_list, tor_strdup("client2.auth"));
    529 
    530  return file_list;
    531 }
    532 
    533 static void
    534 test_load_keys_with_client_auth(void *arg)
    535 {
    536  int ret;
    537  char *conf = NULL;
    538  smartlist_t *pubkey_b32_list = smartlist_new();
    539  char *hsdir_v3 = tor_strdup(get_fname("hs3"));
    540  hs_service_t *service;
    541 
    542  (void) arg;
    543 
    544  hs_init();
    545  smartlist_add(pubkey_b32_list, tor_strdup(
    546                "dz4q5xqlb4ldnbs72iarrml4ephk3du4i7o2cgiva5lwr6wkquja"));
    547  smartlist_add(pubkey_b32_list, tor_strdup(
    548                "okoi2gml3wd6x7jganlk5d66xxyjgg24sxw4y7javx4giqr66zta"));
    549 
    550 #define conf_fmt \
    551  "HiddenServiceDir %s\n" \
    552  "HiddenServiceVersion %d\n" \
    553  "HiddenServicePort 65534\n"
    554 
    555  tor_asprintf(&conf, conf_fmt, hsdir_v3, HS_VERSION_THREE);
    556  ret = helper_config_service(conf);
    557  tor_free(conf);
    558  tt_int_op(ret, OP_EQ, 0);
    559  /* It's in staging? */
    560  tt_int_op(get_hs_service_staging_list_size(), OP_EQ, 1);
    561 
    562 #undef conf_fmt
    563 
    564  MOCK(read_file_to_str, mock_read_file_to_str);
    565  MOCK(tor_listdir, mock_tor_listdir);
    566 
    567  /* Load the keys for these. After that, the v3 service should be registered
    568   * in the global map. */
    569  hs_service_load_all_keys();
    570  tt_int_op(get_hs_service_map_size(), OP_EQ, 1);
    571 
    572  service = get_first_service();
    573  tt_assert(service);
    574  tt_assert(service->config.clients);
    575  tt_int_op(smartlist_len(service->config.clients), OP_EQ,
    576            smartlist_len(pubkey_b32_list));
    577 
    578  /* Test that the keys in clients are correct. */
    579  SMARTLIST_FOREACH_BEGIN(pubkey_b32_list, char *, pubkey_b32) {
    580 
    581    curve25519_public_key_t pubkey;
    582    /* This flag will be set if the key is found in clients. */
    583    int is_found = 0;
    584    base32_decode((char *) pubkey.public_key, sizeof(pubkey.public_key),
    585                  pubkey_b32, strlen(pubkey_b32));
    586 
    587    SMARTLIST_FOREACH_BEGIN(service->config.clients,
    588                            hs_service_authorized_client_t *, client) {
    589      if (tor_memeq(&pubkey, &client->client_pk, sizeof(pubkey))) {
    590        is_found = 1;
    591        break;
    592      }
    593    } SMARTLIST_FOREACH_END(client);
    594 
    595    tt_assert(is_found);
    596 
    597  } SMARTLIST_FOREACH_END(pubkey_b32);
    598 
    599 done:
    600  SMARTLIST_FOREACH(pubkey_b32_list, char *, s, tor_free(s));
    601  smartlist_free(pubkey_b32_list);
    602  tor_free(hsdir_v3);
    603  hs_free_all();
    604  UNMOCK(read_file_to_str);
    605  UNMOCK(tor_listdir);
    606 }
    607 
    608 static void
    609 test_access_service(void *arg)
    610 {
    611  int ret;
    612  char *conf = NULL;
    613  char *hsdir_v3 = tor_strdup(get_fname("hs3"));
    614  hs_service_ht *global_map;
    615  hs_service_t *s = NULL;
    616 
    617  (void) arg;
    618 
    619  /* We'll register one service then we'll load keys and validate that both
    620   * are in a correct state. */
    621 
    622  hs_init();
    623 
    624 #define conf_fmt \
    625  "HiddenServiceDir %s\n" \
    626  "HiddenServiceVersion %d\n" \
    627  "HiddenServicePort 65535\n"
    628 
    629  /* v3 service. */
    630  tor_asprintf(&conf, conf_fmt, hsdir_v3, HS_VERSION_THREE);
    631  ret = helper_config_service(conf);
    632  tor_free(conf);
    633  tt_int_op(ret, OP_EQ, 0);
    634  /* It's in staging? */
    635  tt_int_op(get_hs_service_staging_list_size(), OP_EQ, 1);
    636 
    637  /* Load the keys for these. After that, the v3 service should be registered
    638   * in the global map. */
    639  hs_service_load_all_keys();
    640  tt_int_op(get_hs_service_map_size(), OP_EQ, 1);
    641  s = get_first_service();
    642  tt_assert(s);
    643  global_map = get_hs_service_map();
    644  tt_assert(global_map);
    645 
    646  /* From here, we'll try the service accessors. */
    647  hs_service_t *query = find_service(global_map, &s->keys.identity_pk);
    648  tt_assert(query);
    649  tt_mem_op(query, OP_EQ, s, sizeof(hs_service_t));
    650  /* Remove service, check if it actually works and then put it back. */
    651  remove_service(global_map, s);
    652  hs_metrics_service_free(s);
    653  tt_int_op(get_hs_service_map_size(), OP_EQ, 0);
    654  query = find_service(global_map, &s->keys.identity_pk);
    655  tt_ptr_op(query, OP_EQ, NULL);
    656 
    657  /* Register back the service in the map. */
    658  ret = register_service(global_map, s);
    659  tt_int_op(ret, OP_EQ, 0);
    660  tt_int_op(get_hs_service_map_size(), OP_EQ, 1);
    661  /* Twice should fail. */
    662  hs_metrics_service_free(s); /* Avoid BUG() on metrics init. */
    663  ret = register_service(global_map, s);
    664  tt_int_op(ret, OP_EQ, -1);
    665  /* Remove service from map so we don't double free on cleanup. */
    666  remove_service(global_map, s);
    667  tt_int_op(get_hs_service_map_size(), OP_EQ, 0);
    668  query = find_service(global_map, &s->keys.identity_pk);
    669  tt_ptr_op(query, OP_EQ, NULL);
    670  /* Let's try to remove twice for fun. */
    671  setup_full_capture_of_logs(LOG_WARN);
    672  remove_service(global_map, s);
    673  expect_log_msg_containing("Could not find service in the global map");
    674  teardown_capture_of_logs();
    675 
    676 done:
    677  hs_service_free(s);
    678  tor_free(hsdir_v3);
    679  hs_free_all();
    680 }
    681 
    682 /** Test that we can create intro point objects, index them and find them */
    683 static void
    684 test_service_intro_point(void *arg)
    685 {
    686  hs_service_t *service = NULL;
    687  hs_service_intro_point_t *ip = NULL;
    688 
    689  (void) arg;
    690 
    691  update_approx_time(1481621834);
    692 
    693  /* Test simple creation of an object. */
    694  {
    695    time_t now = approx_time();
    696    ip = helper_create_service_ip();
    697    tt_assert(ip);
    698    /* Make sure the authentication keypair is not zeroes. */
    699    tt_int_op(fast_mem_is_zero((const char *) &ip->auth_key_kp,
    700                              sizeof(ed25519_keypair_t)), OP_EQ, 0);
    701    /* The introduce2_max MUST be in that range. */
    702    tt_u64_op(ip->introduce2_max, OP_GE,
    703              INTRO_POINT_MIN_LIFETIME_INTRODUCTIONS);
    704    tt_u64_op(ip->introduce2_max, OP_LE,
    705              INTRO_POINT_MAX_LIFETIME_INTRODUCTIONS);
    706    /* Time to expire MUST also be in that range. We subtract 500 seconds
    707     * because there could be a gap between setting now and the time taken in
    708     * service_intro_point_new. On ARM and other older CPUs, it can be
    709     * surprisingly slow... */
    710    tt_u64_op(ip->time_to_expire, OP_GE,
    711              now + INTRO_POINT_LIFETIME_MIN_SECONDS - 500);
    712    /* We add 500 seconds, because this time we're testing against the
    713     * maximum allowed time. */
    714    tt_u64_op(ip->time_to_expire, OP_LE,
    715              now + INTRO_POINT_LIFETIME_MAX_SECONDS + 500);
    716    tt_assert(ip->replay_cache);
    717    tt_assert(ip->base.link_specifiers);
    718    /* By default, this is NOT a legacy object. */
    719    tt_int_op(ip->base.is_only_legacy, OP_EQ, 0);
    720  }
    721 
    722  /* Test functions that uses a service intropoints map with that previously
    723   * created object (non legacy). */
    724  {
    725    ed25519_public_key_t garbage = { {0} };
    726    hs_service_intro_point_t *query;
    727 
    728    service = hs_service_new(get_options());
    729    tt_assert(service);
    730    service->desc_current = service_descriptor_new();
    731    tt_assert(service->desc_current);
    732    /* Add intropoint to descriptor map. */
    733    service_intro_point_add(service->desc_current->intro_points.map, ip);
    734    query = service_intro_point_find(service, &ip->auth_key_kp.pubkey);
    735    tt_mem_op(query, OP_EQ, ip, sizeof(hs_service_intro_point_t));
    736    query = service_intro_point_find(service, &garbage);
    737    tt_ptr_op(query, OP_EQ, NULL);
    738 
    739    /* While at it, can I find the descriptor with the intro point? */
    740    hs_service_descriptor_t *desc_lookup =
    741      service_desc_find_by_intro(service, ip);
    742    tt_mem_op(service->desc_current, OP_EQ, desc_lookup,
    743              sizeof(hs_service_descriptor_t));
    744 
    745    /* Remove object from service descriptor and make sure it is out. */
    746    service_intro_point_remove(service, ip);
    747    query = service_intro_point_find(service, &ip->auth_key_kp.pubkey);
    748    tt_ptr_op(query, OP_EQ, NULL);
    749  }
    750 
    751 done:
    752  /* If the test succeed, this object is no longer referenced in the service
    753   * so we can free it without use after free. Else, it might explode because
    754   * it's still in the service descriptor map. */
    755  service_intro_point_free(ip);
    756  hs_service_free(service);
    757 }
    758 
    759 static node_t mock_node;
    760 static const node_t *
    761 mock_node_get_by_id(const char *digest)
    762 {
    763  (void) digest;
    764  memset(mock_node.identity, 'A', DIGEST_LEN);
    765  /* Only return the matching identity of As */
    766  if (!tor_memcmp(mock_node.identity, digest, DIGEST_LEN)) {
    767    return &mock_node;
    768  }
    769  return NULL;
    770 }
    771 
    772 static void
    773 test_helper_functions(void *arg)
    774 {
    775  int ret;
    776  hs_service_t *service = NULL;
    777  hs_service_intro_point_t *ip = NULL;
    778  hs_ident_circuit_t ident;
    779 
    780  (void) arg;
    781 
    782  MOCK(node_get_by_id, mock_node_get_by_id);
    783 
    784  hs_service_init();
    785  time_t now = time(NULL);
    786  update_approx_time(now);
    787 
    788  service = helper_create_service();
    789 
    790  ip = helper_create_service_ip();
    791  /* Immediately add the intro point to the service so the free service at the
    792   * end cleans it as well. */
    793  service_intro_point_add(service->desc_current->intro_points.map, ip);
    794 
    795  /* Setup the circuit identifier. */
    796  ed25519_pubkey_copy(&ident.intro_auth_pk, &ip->auth_key_kp.pubkey);
    797  ed25519_pubkey_copy(&ident.identity_pk, &service->keys.identity_pk);
    798 
    799  /* Testing get_objects_from_ident(). */
    800  {
    801    hs_service_t *s_lookup = NULL;
    802    hs_service_intro_point_t *ip_lookup = NULL;
    803    hs_service_descriptor_t *desc_lookup = NULL;
    804 
    805    get_objects_from_ident(&ident, &s_lookup, &ip_lookup, &desc_lookup);
    806    tt_mem_op(s_lookup, OP_EQ, service, sizeof(hs_service_t));
    807    tt_mem_op(ip_lookup, OP_EQ, ip, sizeof(hs_service_intro_point_t));
    808    tt_mem_op(desc_lookup, OP_EQ, service->desc_current,
    809              sizeof(hs_service_descriptor_t));
    810    /* Reset */
    811    s_lookup = NULL; ip_lookup = NULL; desc_lookup = NULL;
    812 
    813    /* NULL parameter should work. */
    814    get_objects_from_ident(&ident, NULL, &ip_lookup, &desc_lookup);
    815    tt_mem_op(ip_lookup, OP_EQ, ip, sizeof(hs_service_intro_point_t));
    816    tt_mem_op(desc_lookup, OP_EQ, service->desc_current,
    817              sizeof(hs_service_descriptor_t));
    818    /* Reset. */
    819    s_lookup = NULL; ip_lookup = NULL; desc_lookup = NULL;
    820 
    821    /* Break the ident and we should find nothing. */
    822    memset(&ident, 0, sizeof(ident));
    823    get_objects_from_ident(&ident, &s_lookup, &ip_lookup, &desc_lookup);
    824    tt_ptr_op(s_lookup, OP_EQ, NULL);
    825    tt_ptr_op(ip_lookup, OP_EQ, NULL);
    826    tt_ptr_op(desc_lookup, OP_EQ, NULL);
    827  }
    828 
    829  /* Testing get_node_from_intro_point() */
    830  {
    831    const node_t *node = get_node_from_intro_point(ip);
    832    tt_ptr_op(node, OP_EQ, &mock_node);
    833    SMARTLIST_FOREACH_BEGIN(ip->base.link_specifiers,
    834                            link_specifier_t *, ls) {
    835      if (link_specifier_get_ls_type(ls) == LS_LEGACY_ID) {
    836        /* Change legacy id in link specifier which is not the mock node. */
    837        memset(link_specifier_getarray_un_legacy_id(ls), 'B',
    838               link_specifier_getlen_un_legacy_id(ls));
    839      }
    840    } SMARTLIST_FOREACH_END(ls);
    841    node = get_node_from_intro_point(ip);
    842    tt_ptr_op(node, OP_EQ, NULL);
    843  }
    844 
    845  /* Testing can_service_launch_intro_circuit() */
    846  {
    847    /* Put the start of the retry period back in time, we should be allowed.
    848     * to launch intro circuit. */
    849    service->state.num_intro_circ_launched = 2;
    850    service->state.intro_circ_retry_started_time =
    851      (now - INTRO_CIRC_RETRY_PERIOD - 1);
    852    ret = can_service_launch_intro_circuit(service, now);
    853    tt_int_op(ret, OP_EQ, 1);
    854    tt_u64_op(service->state.intro_circ_retry_started_time, OP_EQ, now);
    855    tt_u64_op(service->state.num_intro_circ_launched, OP_EQ, 0);
    856    /* Call it again, we should still be allowed because we are under
    857     * MAX_INTRO_CIRCS_PER_PERIOD which been set to 0 previously. */
    858    ret = can_service_launch_intro_circuit(service, now);
    859    tt_int_op(ret, OP_EQ, 1);
    860    tt_u64_op(service->state.intro_circ_retry_started_time, OP_EQ, now);
    861    tt_u64_op(service->state.num_intro_circ_launched, OP_EQ, 0);
    862    /* Too many intro circuit launched means we are not allowed. */
    863    service->state.num_intro_circ_launched = 20;
    864    ret = can_service_launch_intro_circuit(service, now);
    865    tt_int_op(ret, OP_EQ, 0);
    866  }
    867 
    868  /* Testing intro_point_should_expire(). */
    869  {
    870    /* Just some basic test of the current state. */
    871    tt_u64_op(ip->introduce2_max, OP_GE,
    872              INTRO_POINT_MIN_LIFETIME_INTRODUCTIONS);
    873    tt_u64_op(ip->introduce2_max, OP_LE,
    874              INTRO_POINT_MAX_LIFETIME_INTRODUCTIONS);
    875    tt_u64_op(ip->time_to_expire, OP_GE,
    876              now + INTRO_POINT_LIFETIME_MIN_SECONDS);
    877    tt_u64_op(ip->time_to_expire, OP_LE,
    878              now + INTRO_POINT_LIFETIME_MAX_SECONDS);
    879 
    880    /* This newly created IP from above shouldn't expire now. */
    881    ret = intro_point_should_expire(ip, now);
    882    tt_int_op(ret, OP_EQ, 0);
    883    /* Maximum number of INTRODUCE2 cell reached, it should expire. */
    884    ip->introduce2_count = INTRO_POINT_MAX_LIFETIME_INTRODUCTIONS + 1;
    885    ret = intro_point_should_expire(ip, now);
    886    tt_int_op(ret, OP_EQ, 1);
    887    ip->introduce2_count = 0;
    888    /* It should expire if time to expire has been reached. */
    889    ip->time_to_expire = now - 1000;
    890    ret = intro_point_should_expire(ip, now);
    891    tt_int_op(ret, OP_EQ, 1);
    892  }
    893 
    894 done:
    895  /* This will free the service and all objects associated to it. */
    896  if (service) {
    897    remove_service(get_hs_service_map(), service);
    898    hs_service_free(service);
    899  }
    900  hs_service_free_all();
    901  UNMOCK(node_get_by_id);
    902 }
    903 
    904 /** Test that we do the right operations when an intro circuit opens */
    905 static void
    906 test_intro_circuit_opened(void *arg)
    907 {
    908  int flags = CIRCLAUNCH_NEED_UPTIME | CIRCLAUNCH_IS_INTERNAL;
    909  hs_service_t *service = NULL;
    910  origin_circuit_t *circ = NULL;
    911 
    912  (void) arg;
    913 
    914  hs_init();
    915  MOCK(circuit_mark_for_close_, mock_circuit_mark_for_close);
    916  MOCK(relay_send_command_from_edge_, mock_relay_send_command_from_edge);
    917 
    918  circ = helper_create_origin_circuit(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO,
    919                                      flags);
    920 
    921  /* No service associated with this circuit. */
    922  setup_full_capture_of_logs(LOG_WARN);
    923  hs_service_circuit_has_opened(circ);
    924  expect_log_msg_containing("Unknown service identity key");
    925  teardown_capture_of_logs();
    926 
    927  /* Set a service for this circuit. */
    928  {
    929    service = helper_create_service();
    930    ed25519_pubkey_copy(&circ->hs_ident->identity_pk,
    931                        &service->keys.identity_pk);
    932 
    933    /* No intro point associated with this circuit. */
    934    setup_full_capture_of_logs(LOG_WARN);
    935    hs_service_circuit_has_opened(circ);
    936    expect_log_msg_containing("Unknown introduction point auth key");
    937    teardown_capture_of_logs();
    938  }
    939 
    940  /* Set an IP object now for this circuit. */
    941  {
    942    hs_service_intro_point_t *ip = helper_create_service_ip();
    943    service_intro_point_add(service->desc_current->intro_points.map, ip);
    944    /* Update ident to contain the intro point auth key. */
    945    ed25519_pubkey_copy(&circ->hs_ident->intro_auth_pk,
    946                        &ip->auth_key_kp.pubkey);
    947  }
    948 
    949  /* This one should go all the way. */
    950  setup_full_capture_of_logs(LOG_INFO);
    951  hs_service_circuit_has_opened(circ);
    952  expect_log_msg_containing("Introduction circuit 0 established for service");
    953  teardown_capture_of_logs();
    954 
    955 done:
    956  circuit_free_(TO_CIRCUIT(circ));
    957  if (service) {
    958    remove_service(get_hs_service_map(), service);
    959    hs_service_free(service);
    960  }
    961  hs_free_all();
    962  UNMOCK(circuit_mark_for_close_);
    963  UNMOCK(relay_send_command_from_edge_);
    964 }
    965 
    966 /** Test the operations we do on a circuit after we learn that we successfully
    967 *  established an intro point on it */
    968 static void
    969 test_intro_established(void *arg)
    970 {
    971  int ret;
    972  int flags = CIRCLAUNCH_NEED_UPTIME | CIRCLAUNCH_IS_INTERNAL;
    973  uint8_t payload[RELAY_PAYLOAD_SIZE] = {0};
    974  origin_circuit_t *circ = NULL;
    975  hs_service_t *service = NULL;
    976  hs_service_intro_point_t *ip = NULL;
    977 
    978  (void) arg;
    979 
    980  hs_init();
    981  MOCK(circuit_mark_for_close_, mock_circuit_mark_for_close);
    982 
    983  circ = helper_create_origin_circuit(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO,
    984                                      flags);
    985  tt_assert(circ);
    986 
    987  /* Test a wrong purpose. */
    988  TO_CIRCUIT(circ)->purpose = CIRCUIT_PURPOSE_S_INTRO;
    989  setup_full_capture_of_logs(LOG_WARN);
    990  ret = hs_service_receive_intro_established(circ, payload, sizeof(payload));
    991  tt_int_op(ret, OP_EQ, -1);
    992  expect_log_msg_containing("Received an INTRO_ESTABLISHED cell on a "
    993                            "non introduction circuit of purpose");
    994  teardown_capture_of_logs();
    995 
    996  /* Back to normal. */
    997  TO_CIRCUIT(circ)->purpose = CIRCUIT_PURPOSE_S_ESTABLISH_INTRO;
    998 
    999  /* No service associated to it. */
   1000  setup_full_capture_of_logs(LOG_WARN);
   1001  ret = hs_service_receive_intro_established(circ, payload, sizeof(payload));
   1002  tt_int_op(ret, OP_EQ, -1);
   1003  expect_log_msg_containing("Unknown service identity key");
   1004  teardown_capture_of_logs();
   1005 
   1006  /* Set a service for this circuit. */
   1007  service = helper_create_service();
   1008  ed25519_pubkey_copy(&circ->hs_ident->identity_pk,
   1009                      &service->keys.identity_pk);
   1010  /* No introduction point associated to it. */
   1011  setup_full_capture_of_logs(LOG_WARN);
   1012  ret = hs_service_receive_intro_established(circ, payload, sizeof(payload));
   1013  tt_int_op(ret, OP_EQ, -1);
   1014  expect_log_msg_containing("Introduction circuit established without an "
   1015                            "intro point object on circuit");
   1016  teardown_capture_of_logs();
   1017 
   1018  /* Set an IP object now for this circuit. */
   1019  {
   1020    ip = helper_create_service_ip();
   1021    service_intro_point_add(service->desc_current->intro_points.map, ip);
   1022    /* Update ident to contain the intro point auth key. */
   1023    ed25519_pubkey_copy(&circ->hs_ident->intro_auth_pk,
   1024                        &ip->auth_key_kp.pubkey);
   1025  }
   1026 
   1027  /* Send an empty payload. INTRO_ESTABLISHED cells are basically zeroes. */
   1028  ret = hs_service_receive_intro_established(circ, payload, sizeof(payload));
   1029  tt_int_op(ret, OP_EQ, 0);
   1030  tt_int_op(TO_CIRCUIT(circ)->purpose, OP_EQ, CIRCUIT_PURPOSE_S_INTRO);
   1031 
   1032 done:
   1033  if (circ)
   1034    circuit_free_(TO_CIRCUIT(circ));
   1035  if (service) {
   1036    remove_service(get_hs_service_map(), service);
   1037    hs_service_free(service);
   1038  }
   1039  hs_free_all();
   1040  UNMOCK(circuit_mark_for_close_);
   1041 }
   1042 
   1043 /** Check the operations we do on a rendezvous circuit after we learn it's
   1044 *  open */
   1045 static void
   1046 test_rdv_circuit_opened(void *arg)
   1047 {
   1048  int flags = CIRCLAUNCH_NEED_UPTIME | CIRCLAUNCH_IS_INTERNAL;
   1049  origin_circuit_t *circ = NULL;
   1050  hs_service_t *service = NULL;
   1051 
   1052  (void) arg;
   1053 
   1054  hs_init();
   1055  MOCK(circuit_mark_for_close_, mock_circuit_mark_for_close);
   1056  MOCK(relay_send_command_from_edge_, mock_relay_send_command_from_edge);
   1057 
   1058  circ = helper_create_origin_circuit(CIRCUIT_PURPOSE_S_CONNECT_REND, flags);
   1059  crypto_rand((char *) circ->hs_ident->rendezvous_cookie, REND_COOKIE_LEN);
   1060  crypto_rand((char *) circ->hs_ident->rendezvous_handshake_info,
   1061              sizeof(circ->hs_ident->rendezvous_handshake_info));
   1062 
   1063  /* No service associated with this circuit. */
   1064  setup_full_capture_of_logs(LOG_WARN);
   1065  hs_service_circuit_has_opened(circ);
   1066  expect_log_msg_containing("Unknown service identity key");
   1067  teardown_capture_of_logs();
   1068  /* This should be set to a non zero timestamp. */
   1069  tt_u64_op(TO_CIRCUIT(circ)->timestamp_dirty, OP_NE, 0);
   1070 
   1071  /* Set a service for this circuit. */
   1072  service = helper_create_service();
   1073  ed25519_pubkey_copy(&circ->hs_ident->identity_pk,
   1074                      &service->keys.identity_pk);
   1075  /* Should be all good. */
   1076  hs_service_circuit_has_opened(circ);
   1077  tt_int_op(TO_CIRCUIT(circ)->purpose, OP_EQ, CIRCUIT_PURPOSE_S_REND_JOINED);
   1078 
   1079 done:
   1080  circuit_free_(TO_CIRCUIT(circ));
   1081  if (service) {
   1082    remove_service(get_hs_service_map(), service);
   1083    hs_service_free(service);
   1084  }
   1085  hs_free_all();
   1086  UNMOCK(circuit_mark_for_close_);
   1087  UNMOCK(relay_send_command_from_edge_);
   1088 }
   1089 
   1090 static void
   1091 mock_assert_circuit_ok(const circuit_t *c)
   1092 {
   1093  (void) c;
   1094  return;
   1095 }
   1096 
   1097 /** Test for the general mechanism for closing intro circs.
   1098 *  Also a way to identify that #23603 has been fixed. */
   1099 static void
   1100 test_closing_intro_circs(void *arg)
   1101 {
   1102  hs_service_t *service = NULL;
   1103  hs_service_intro_point_t *ip = NULL, *entry = NULL;
   1104  origin_circuit_t *intro_circ = NULL, *tmp_circ;
   1105  int flags = CIRCLAUNCH_NEED_UPTIME | CIRCLAUNCH_IS_INTERNAL;
   1106 
   1107  (void) arg;
   1108 
   1109  MOCK(assert_circuit_ok, mock_assert_circuit_ok);
   1110 
   1111  hs_init();
   1112 
   1113  /* Initialize service */
   1114  service = helper_create_service();
   1115  /* Initialize intro point */
   1116  ip = helper_create_service_ip();
   1117  tt_assert(ip);
   1118  service_intro_point_add(service->desc_current->intro_points.map, ip);
   1119 
   1120  /* Initialize intro circuit */
   1121  intro_circ = origin_circuit_init(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO, flags);
   1122  intro_circ->hs_ident = hs_ident_circuit_new(&service->keys.identity_pk);
   1123  /* Register circuit in the circuitmap . */
   1124  hs_circuitmap_register_intro_circ_v3_service_side(intro_circ,
   1125                                                    &ip->auth_key_kp.pubkey);
   1126  tmp_circ =
   1127    hs_circuitmap_get_intro_circ_v3_service_side(&ip->auth_key_kp.pubkey);
   1128  tt_ptr_op(tmp_circ, OP_EQ, intro_circ);
   1129 
   1130  /* Pretend that intro point has failed too much */
   1131  ip->circuit_retries = MAX_INTRO_POINT_CIRCUIT_RETRIES+1;
   1132 
   1133  /* Now pretend we are freeing this intro circuit. We want to see that our
   1134   * destructor is not gonna kill our intro point structure since that's the
   1135   * job of the cleanup routine. */
   1136  circuit_free_(TO_CIRCUIT(intro_circ));
   1137  intro_circ = NULL;
   1138  entry = service_intro_point_find(service, &ip->auth_key_kp.pubkey);
   1139  tt_assert(entry);
   1140  /* The free should also remove the circuit from the circuitmap. */
   1141  tmp_circ =
   1142    hs_circuitmap_get_intro_circ_v3_service_side(&ip->auth_key_kp.pubkey);
   1143  tt_assert(!tmp_circ);
   1144 
   1145  /* Now pretend that a new intro point circ was launched and opened. Check
   1146   * that the intro point will be established correctly. */
   1147  intro_circ = origin_circuit_init(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO, flags);
   1148  intro_circ->hs_ident = hs_ident_circuit_new(&service->keys.identity_pk);
   1149  ed25519_pubkey_copy(&intro_circ->hs_ident->intro_auth_pk,
   1150                      &ip->auth_key_kp.pubkey);
   1151  /* Register circuit in the circuitmap . */
   1152  hs_circuitmap_register_intro_circ_v3_service_side(intro_circ,
   1153                                                    &ip->auth_key_kp.pubkey);
   1154  tmp_circ =
   1155    hs_circuitmap_get_intro_circ_v3_service_side(&ip->auth_key_kp.pubkey);
   1156  tt_ptr_op(tmp_circ, OP_EQ, intro_circ);
   1157  tt_int_op(TO_CIRCUIT(intro_circ)->marked_for_close, OP_EQ, 0);
   1158  circuit_mark_for_close(TO_CIRCUIT(intro_circ), END_CIRC_REASON_INTERNAL);
   1159  tt_int_op(TO_CIRCUIT(intro_circ)->marked_for_close, OP_NE, 0);
   1160  /* At this point, we should not be able to find it in the circuitmap. */
   1161  tmp_circ =
   1162    hs_circuitmap_get_intro_circ_v3_service_side(&ip->auth_key_kp.pubkey);
   1163  tt_assert(!tmp_circ);
   1164 
   1165 done:
   1166  if (intro_circ) {
   1167    circuit_free_(TO_CIRCUIT(intro_circ));
   1168  }
   1169  /* Frees the service object. */
   1170  if (service) {
   1171    remove_service(get_hs_service_map(), service);
   1172    hs_service_free(service);
   1173  }
   1174  hs_free_all();
   1175  UNMOCK(assert_circuit_ok);
   1176 }
   1177 
   1178 /** Test sending and receiving introduce2 cells */
   1179 static void
   1180 test_bad_introduce2(void *arg)
   1181 {
   1182  int ret;
   1183  int flags = CIRCLAUNCH_NEED_UPTIME | CIRCLAUNCH_IS_INTERNAL;
   1184  uint8_t payload[RELAY_PAYLOAD_SIZE] = {0};
   1185  origin_circuit_t *circ = NULL;
   1186  hs_service_t *service = NULL;
   1187  hs_service_intro_point_t *ip = NULL;
   1188  const smartlist_t *entries = NULL;
   1189  const metrics_store_entry_t *entry = NULL;
   1190 
   1191  (void) arg;
   1192 
   1193  hs_init();
   1194  MOCK(circuit_mark_for_close_, mock_circuit_mark_for_close);
   1195  MOCK(get_or_state,
   1196       get_or_state_replacement);
   1197 
   1198  dummy_state = or_state_new();
   1199 
   1200  circ = helper_create_origin_circuit(CIRCUIT_PURPOSE_S_INTRO, flags);
   1201  tt_assert(circ);
   1202 
   1203  /* Test a wrong purpose. */
   1204  TO_CIRCUIT(circ)->purpose = CIRCUIT_PURPOSE_S_ESTABLISH_INTRO;
   1205  setup_full_capture_of_logs(LOG_WARN);
   1206  ret = hs_service_receive_introduce2(circ, payload, sizeof(payload));
   1207  tt_int_op(ret, OP_EQ, -1);
   1208  expect_log_msg_containing("Received an INTRODUCE2 cell on a "
   1209                            "non introduction circuit of purpose");
   1210  teardown_capture_of_logs();
   1211 
   1212  /* Back to normal. */
   1213  TO_CIRCUIT(circ)->purpose = CIRCUIT_PURPOSE_S_INTRO;
   1214 
   1215  /* No service associated to it. */
   1216  setup_full_capture_of_logs(LOG_WARN);
   1217  ret = hs_service_receive_introduce2(circ, payload, sizeof(payload));
   1218  tt_int_op(ret, OP_EQ, -1);
   1219  expect_log_msg_containing("Unknown service identity key");
   1220  teardown_capture_of_logs();
   1221 
   1222  /* Set a service for this circuit. */
   1223  service = helper_create_service();
   1224  ed25519_pubkey_copy(&circ->hs_ident->identity_pk,
   1225                      &service->keys.identity_pk);
   1226  /* No introduction point associated to it. */
   1227  setup_full_capture_of_logs(LOG_WARN);
   1228  ret = hs_service_receive_introduce2(circ, payload, sizeof(payload));
   1229  tt_int_op(ret, OP_EQ, -1);
   1230  expect_log_msg_containing("Unknown introduction auth key when handling "
   1231                            "an INTRODUCE2 cell on circuit");
   1232  teardown_capture_of_logs();
   1233 
   1234  entries = metrics_store_get_all(service->metrics.store,
   1235                                  "tor_hs_intro_rejected_intro_req_count");
   1236 
   1237  tt_assert(entries);
   1238  /* There are `hs_metrics_intro_req_size` entries (one for each
   1239   * possible `reason` label value). */
   1240  tt_int_op(smartlist_len(entries), OP_EQ,
   1241            hs_metrics_intro_req_error_reasons_size);
   1242 
   1243  /* Make sure the tor_hs_intro_rejected_intro_req_count metric was
   1244   * only incremented for reason HS_METRICS_ERR_INTRO_REQ_BAD_AUTH_KEY. */
   1245  for (size_t i = 0; i < hs_metrics_intro_req_error_reasons_size; ++i) {
   1246    const char *reason = hs_metrics_intro_req_error_reasons[i];
   1247 
   1248    if (!strcmp(reason, HS_METRICS_ERR_INTRO_REQ_BAD_AUTH_KEY)) {
   1249      continue;
   1250    }
   1251 
   1252    entry = metrics_store_find_entry_with_label(
   1253        entries,
   1254        metrics_format_label("reason", reason));
   1255    tt_assert(entry);
   1256    tt_int_op(metrics_store_entry_get_value(entry), OP_EQ, 0);
   1257  }
   1258 
   1259  entry = metrics_store_find_entry_with_label(
   1260      entries,
   1261      metrics_format_label("reason", HS_METRICS_ERR_INTRO_REQ_BAD_AUTH_KEY));
   1262  tt_assert(entry);
   1263  tt_int_op(metrics_store_entry_get_value(entry), OP_EQ, 1);
   1264 
   1265  /* Set an IP object now for this circuit. */
   1266  {
   1267    ip = helper_create_service_ip();
   1268    service_intro_point_add(service->desc_current->intro_points.map, ip);
   1269    /* Update ident to contain the intro point auth key. */
   1270    ed25519_pubkey_copy(&circ->hs_ident->intro_auth_pk,
   1271                        &ip->auth_key_kp.pubkey);
   1272  }
   1273 
   1274  /* This will fail because receiving an INTRODUCE2 cell implies a valid cell
   1275   * and then launching circuits so let's not do that and instead test that
   1276   * behaviour differently. */
   1277  ret = hs_service_receive_introduce2(circ, payload, sizeof(payload));
   1278  tt_int_op(ret, OP_EQ, -1);
   1279  tt_u64_op(ip->introduce2_count, OP_EQ, 0);
   1280 
   1281  /* Make sure the tor_hs_intro_rejected_intro_req_count metric was incremented
   1282   * a second time, this time, with reason="invalid_introduce2_cell". */
   1283  entry = metrics_store_find_entry_with_label(
   1284      entries,
   1285      metrics_format_label("reason", HS_METRICS_ERR_INTRO_REQ_INTRODUCE2));
   1286  tt_assert(entry);
   1287  tt_int_op(metrics_store_entry_get_value(entry), OP_EQ, 1);
   1288 
   1289  /* The metric entries with other reason labels are unaffected */
   1290  entry = metrics_store_find_entry_with_label(
   1291      entries,
   1292      metrics_format_label("reason", HS_METRICS_ERR_INTRO_REQ_SUBCREDENTIAL));
   1293  tt_assert(entry);
   1294  tt_int_op(metrics_store_entry_get_value(entry), OP_EQ, 0);
   1295 
   1296  entry = metrics_store_find_entry_with_label(
   1297      entries, metrics_format_label(
   1298                   "reason", HS_METRICS_ERR_INTRO_REQ_INTRODUCE2_REPLAY));
   1299  tt_assert(entry);
   1300  tt_int_op(metrics_store_entry_get_value(entry), OP_EQ, 0);
   1301 
   1302  entry = metrics_store_find_entry_with_label(
   1303      entries,
   1304      metrics_format_label("reason", HS_METRICS_ERR_INTRO_REQ_BAD_AUTH_KEY));
   1305  tt_assert(entry);
   1306  tt_int_op(metrics_store_entry_get_value(entry), OP_EQ, 1);
   1307 
   1308 done:
   1309  or_state_free(dummy_state);
   1310  dummy_state = NULL;
   1311  if (circ)
   1312    circuit_free_(TO_CIRCUIT(circ));
   1313  if (service) {
   1314    remove_service(get_hs_service_map(), service);
   1315    hs_service_free(service);
   1316  }
   1317  hs_free_all();
   1318  UNMOCK(circuit_mark_for_close_);
   1319 }
   1320 
   1321 /** Test basic hidden service housekeeping operations (maintaining intro
   1322 *  points, etc) */
   1323 static void
   1324 test_service_event(void *arg)
   1325 {
   1326  int flags = CIRCLAUNCH_NEED_UPTIME | CIRCLAUNCH_IS_INTERNAL;
   1327  time_t now = time(NULL);
   1328  hs_service_t *service;
   1329  origin_circuit_t *circ = NULL;
   1330 
   1331  (void) arg;
   1332 
   1333  hs_init();
   1334  MOCK(circuit_mark_for_close_, mock_circuit_mark_for_close);
   1335 
   1336  circ = helper_create_origin_circuit(CIRCUIT_PURPOSE_S_INTRO, flags);
   1337 
   1338  /* Set a service for this circuit. */
   1339  service = helper_create_service();
   1340  tt_assert(service);
   1341  ed25519_pubkey_copy(&circ->hs_ident->identity_pk,
   1342                      &service->keys.identity_pk);
   1343 
   1344  /* Currently this consists of cleaning invalid intro points. So adding IPs
   1345   * here that should get cleaned up. */
   1346  {
   1347    hs_service_intro_point_t *ip = helper_create_service_ip();
   1348    service_intro_point_add(service->desc_current->intro_points.map, ip);
   1349    /* This run will remove the IP because we have no circuits nor node_t
   1350     * associated with it. */
   1351    run_housekeeping_event(now);
   1352    tt_int_op(digest256map_size(service->desc_current->intro_points.map),
   1353              OP_EQ, 0);
   1354    /* We'll trigger a removal because we've reached our maximum amount of
   1355     * times we should retry a circuit. For this, we need to have a node_t
   1356     * that matches the identity of this IP. */
   1357    routerinfo_t ri;
   1358    memset(&ri, 0, sizeof(ri));
   1359    ip = helper_create_service_ip();
   1360    service_intro_point_add(service->desc_current->intro_points.map, ip);
   1361    memset(ri.cache_info.identity_digest, 'A', DIGEST_LEN);
   1362    /* This triggers a node_t creation. */
   1363    tt_assert(nodelist_set_routerinfo(&ri, NULL));
   1364    ip->circuit_retries = MAX_INTRO_POINT_CIRCUIT_RETRIES + 1;
   1365    run_housekeeping_event(now);
   1366    tt_int_op(digest256map_size(service->desc_current->intro_points.map),
   1367              OP_EQ, 0);
   1368    /* No removal but no circuit so this means the IP object will stay in the
   1369     * descriptor map so we can retry it. */
   1370    ip = helper_create_service_ip();
   1371    service_intro_point_add(service->desc_current->intro_points.map, ip);
   1372    run_housekeeping_event(now);
   1373    tt_int_op(digest256map_size(service->desc_current->intro_points.map),
   1374              OP_EQ, 1);
   1375    /* Remove the IP object at once for the next test. */
   1376    ip->circuit_retries = MAX_INTRO_POINT_CIRCUIT_RETRIES + 1;
   1377    run_housekeeping_event(now);
   1378    tt_int_op(digest256map_size(service->desc_current->intro_points.map),
   1379              OP_EQ, 0);
   1380    /* Now, we'll create an IP with a registered circuit. The IP object
   1381     * shouldn't go away. */
   1382    ip = helper_create_service_ip();
   1383    service_intro_point_add(service->desc_current->intro_points.map, ip);
   1384    ed25519_pubkey_copy(&circ->hs_ident->intro_auth_pk,
   1385                        &ip->auth_key_kp.pubkey);
   1386    hs_circuitmap_register_intro_circ_v3_service_side(
   1387                                         circ, &ip->auth_key_kp.pubkey);
   1388    run_housekeeping_event(now);
   1389    tt_int_op(digest256map_size(service->desc_current->intro_points.map),
   1390              OP_EQ, 1);
   1391    /* We'll mangle the IP object to expire. */
   1392    ip->time_to_expire = now;
   1393    run_housekeeping_event(now);
   1394    tt_int_op(digest256map_size(service->desc_current->intro_points.map),
   1395              OP_EQ, 0);
   1396  }
   1397 
   1398 done:
   1399  hs_circuitmap_remove_circuit(TO_CIRCUIT(circ));
   1400  circuit_free_(TO_CIRCUIT(circ));
   1401  if (service) {
   1402    remove_service(get_hs_service_map(), service);
   1403    hs_service_free(service);
   1404  }
   1405  hs_free_all();
   1406  UNMOCK(circuit_mark_for_close_);
   1407 }
   1408 
   1409 /** Test that we rotate descriptors correctly. */
   1410 static void
   1411 test_rotate_descriptors(void *arg)
   1412 {
   1413  int ret;
   1414  time_t next_rotation_time, now;
   1415  hs_service_t *service = NULL;
   1416  hs_service_descriptor_t *desc_next;
   1417 
   1418  (void) arg;
   1419 
   1420  dummy_state = or_state_new();
   1421 
   1422  hs_init();
   1423  MOCK(get_or_state, get_or_state_replacement);
   1424  MOCK(circuit_mark_for_close_, mock_circuit_mark_for_close);
   1425  MOCK(networkstatus_get_reasonably_live_consensus,
   1426       mock_networkstatus_get_reasonably_live_consensus);
   1427 
   1428  /* Descriptor rotation happens with a consensus with a new SRV. */
   1429 
   1430  ret = parse_rfc1123_time("Sat, 26 Oct 1985 13:00:00 UTC",
   1431                           &mock_ns.valid_after);
   1432  tt_int_op(ret, OP_EQ, 0);
   1433  ret = parse_rfc1123_time("Sat, 26 Oct 1985 14:00:00 UTC",
   1434                           &mock_ns.fresh_until);
   1435  tt_int_op(ret, OP_EQ, 0);
   1436  dirauth_sched_recalculate_timing(get_options(), mock_ns.valid_after);
   1437 
   1438  update_approx_time(mock_ns.valid_after+1);
   1439  now = mock_ns.valid_after+1;
   1440 
   1441  /* Create a service with a default descriptor and state. It's added to the
   1442   * global map. */
   1443  service = helper_create_service();
   1444  service_descriptor_free(service->desc_current);
   1445  service->desc_current = NULL;
   1446  /* This triggers a build for both descriptors. The time now is only used in
   1447   * the descriptor certificate which is important to be now else the decoding
   1448   * will complain that the cert has expired if we use valid_after. */
   1449  build_all_descriptors(now);
   1450  tt_assert(service->desc_current);
   1451  tt_assert(service->desc_next);
   1452 
   1453  /* Tweak our service next rotation time so we can use a custom time. */
   1454  service->state.next_rotation_time = next_rotation_time =
   1455    mock_ns.valid_after + (11 * 60 * 60);
   1456 
   1457  /* Nothing should happen, we are not at a new SRV. Our next rotation time
   1458   * should be untouched. */
   1459  rotate_all_descriptors(mock_ns.valid_after);
   1460  tt_u64_op(service->state.next_rotation_time, OP_EQ, next_rotation_time);
   1461  tt_assert(service->desc_current);
   1462  tt_assert(service->desc_next);
   1463  tt_u64_op(service->desc_current->time_period_num, OP_EQ,
   1464            hs_get_previous_time_period_num(0));
   1465  tt_u64_op(service->desc_next->time_period_num, OP_EQ,
   1466            hs_get_time_period_num(0));
   1467  /* Keep a reference so we can compare it after rotation to the current. */
   1468  desc_next = service->desc_next;
   1469 
   1470  /* Going right after a new SRV. */
   1471  ret = parse_rfc1123_time("Sat, 27 Oct 1985 01:00:00 UTC",
   1472                           &mock_ns.valid_after);
   1473  tt_int_op(ret, OP_EQ, 0);
   1474  ret = parse_rfc1123_time("Sat, 27 Oct 1985 02:00:00 UTC",
   1475                           &mock_ns.fresh_until);
   1476  tt_int_op(ret, OP_EQ, 0);
   1477  dirauth_sched_recalculate_timing(get_options(), mock_ns.valid_after);
   1478 
   1479  update_approx_time(mock_ns.valid_after+1);
   1480  now = mock_ns.valid_after+1;
   1481 
   1482  /* Note down what to expect for the next rotation time which is 01:00 + 23h
   1483   * meaning 00:00:00. */
   1484  next_rotation_time = mock_ns.valid_after + (23 * 60 * 60);
   1485  /* We should have our next rotation time modified, our current descriptor
   1486   * cleaned up and the next descriptor becoming the current. */
   1487  rotate_all_descriptors(mock_ns.valid_after);
   1488  tt_u64_op(service->state.next_rotation_time, OP_EQ, next_rotation_time);
   1489  tt_mem_op(service->desc_current, OP_EQ, desc_next, sizeof(*desc_next));
   1490  tt_assert(service->desc_next == NULL);
   1491 
   1492  /* A second time should do nothing. */
   1493  rotate_all_descriptors(mock_ns.valid_after);
   1494  tt_u64_op(service->state.next_rotation_time, OP_EQ, next_rotation_time);
   1495  tt_mem_op(service->desc_current, OP_EQ, desc_next, sizeof(*desc_next));
   1496  tt_assert(service->desc_next == NULL);
   1497 
   1498  build_all_descriptors(now);
   1499  tt_mem_op(service->desc_current, OP_EQ, desc_next, sizeof(*desc_next));
   1500  tt_u64_op(service->desc_current->time_period_num, OP_EQ,
   1501            hs_get_time_period_num(0));
   1502  tt_u64_op(service->desc_next->time_period_num, OP_EQ,
   1503            hs_get_next_time_period_num(0));
   1504  tt_assert(service->desc_next);
   1505 
   1506 done:
   1507  if (service) {
   1508    remove_service(get_hs_service_map(), service);
   1509    hs_service_free(service);
   1510  }
   1511  hs_free_all();
   1512  UNMOCK(get_or_state);
   1513  UNMOCK(circuit_mark_for_close_);
   1514  UNMOCK(networkstatus_get_reasonably_live_consensus);
   1515 }
   1516 
   1517 /** Test building descriptors: picking intro points, setting up their link
   1518 *  specifiers, etc. */
   1519 static void
   1520 test_build_update_descriptors(void *arg)
   1521 {
   1522  int ret;
   1523  node_t *node;
   1524  hs_service_t *service = NULL;
   1525  hs_service_intro_point_t *ip_cur, *ip_next;
   1526  routerinfo_t ri;
   1527 
   1528  (void) arg;
   1529 
   1530  hs_init();
   1531 
   1532  MOCK(get_or_state,
   1533       get_or_state_replacement);
   1534  MOCK(networkstatus_get_reasonably_live_consensus,
   1535       mock_networkstatus_get_reasonably_live_consensus);
   1536 
   1537  dummy_state = or_state_new();
   1538 
   1539  ret = parse_rfc1123_time("Sat, 26 Oct 1985 03:00:00 UTC",
   1540                           &mock_ns.valid_after);
   1541  tt_int_op(ret, OP_EQ, 0);
   1542  ret = parse_rfc1123_time("Sat, 26 Oct 1985 04:00:00 UTC",
   1543                           &mock_ns.fresh_until);
   1544  tt_int_op(ret, OP_EQ, 0);
   1545  dirauth_sched_recalculate_timing(get_options(), mock_ns.valid_after);
   1546 
   1547  update_approx_time(mock_ns.valid_after+1);
   1548 
   1549  time_t now = mock_ns.valid_after+1;
   1550 
   1551  /* Create a service without a current descriptor to trigger a build. */
   1552  service = helper_create_service();
   1553  tt_assert(service);
   1554  /* Unfortunately, the helper creates a dummy descriptor so get rid of it. */
   1555  service_descriptor_free(service->desc_current);
   1556  service->desc_current = NULL;
   1557 
   1558  /* We have a fresh service so this should trigger a build for both
   1559   * descriptors for specific time period that we'll test. */
   1560  build_all_descriptors(now);
   1561  /* Check *current* descriptor. */
   1562  tt_assert(service->desc_current);
   1563  tt_assert(service->desc_current->desc);
   1564  tt_assert(service->desc_current->intro_points.map);
   1565  /* The current time period is the one expected when starting at 03:00. */
   1566  tt_u64_op(service->desc_current->time_period_num, OP_EQ,
   1567            hs_get_time_period_num(0));
   1568  /* This should be untouched, the update descriptor process changes it. */
   1569  tt_u64_op(service->desc_current->next_upload_time, OP_EQ, 0);
   1570 
   1571  /* Check *next* descriptor. */
   1572  tt_assert(service->desc_next);
   1573  tt_assert(service->desc_next->desc);
   1574  tt_assert(service->desc_next->intro_points.map);
   1575  tt_assert(service->desc_current != service->desc_next);
   1576  tt_u64_op(service->desc_next->time_period_num, OP_EQ,
   1577            hs_get_next_time_period_num(0));
   1578  /* This should be untouched, the update descriptor process changes it. */
   1579  tt_u64_op(service->desc_next->next_upload_time, OP_EQ, 0);
   1580 
   1581  /* Time to test the update of those descriptors. At first, we have no node
   1582   * in the routerlist so this will find NO suitable node for the IPs. */
   1583  setup_full_capture_of_logs(LOG_INFO);
   1584  update_all_descriptors_intro_points(now);
   1585  expect_log_msg_containing("Unable to find a suitable node to be an "
   1586                            "introduction point for service");
   1587  teardown_capture_of_logs();
   1588  tt_int_op(digest256map_size(service->desc_current->intro_points.map),
   1589            OP_EQ, 0);
   1590  tt_int_op(digest256map_size(service->desc_next->intro_points.map),
   1591            OP_EQ, 0);
   1592 
   1593  /* Now, we'll setup a node_t. */
   1594  {
   1595    curve25519_secret_key_t curve25519_secret_key;
   1596 
   1597    memset(&ri, 0, sizeof(routerinfo_t));
   1598 
   1599    tor_addr_parse(&ri.ipv4_addr, "127.0.0.1");
   1600    ri.ipv4_orport = 1337;
   1601    ri.purpose = ROUTER_PURPOSE_GENERAL;
   1602    /* Ugly yes but we never free the "ri" object so this just makes things
   1603     * easier. */
   1604    ri.protocol_list = (char *) "HSDir=1-2 LinkAuth=3";
   1605    summarize_protover_flags(&ri.pv, ri.protocol_list, NULL);
   1606    ret = curve25519_secret_key_generate(&curve25519_secret_key, 0);
   1607    tt_int_op(ret, OP_EQ, 0);
   1608    ri.onion_curve25519_pkey =
   1609      tor_malloc_zero(sizeof(curve25519_public_key_t));
   1610    curve25519_public_key_generate(ri.onion_curve25519_pkey,
   1611                                   &curve25519_secret_key);
   1612    memset(ri.cache_info.identity_digest, 'A', DIGEST_LEN);
   1613    /* Setup ed25519 identity */
   1614    ed25519_keypair_t kp1;
   1615    ed25519_keypair_generate(&kp1, 0);
   1616    ri.cache_info.signing_key_cert = tor_malloc_zero(sizeof(tor_cert_t));
   1617    tt_assert(ri.cache_info.signing_key_cert);
   1618    ed25519_pubkey_copy(&ri.cache_info.signing_key_cert->signing_key,
   1619                        &kp1.pubkey);
   1620    nodelist_set_routerinfo(&ri, NULL);
   1621    node = node_get_mutable_by_id(ri.cache_info.identity_digest);
   1622    tt_assert(node);
   1623    node->is_running = node->is_valid = node->is_fast = node->is_stable = 1;
   1624  }
   1625 
   1626  /* We have to set this, or the lack of microdescriptors for these
   1627   * nodes will make them unusable. */
   1628  get_options_mutable()->UseMicrodescriptors = 0;
   1629 
   1630  /* We expect to pick only one intro point from the node above. */
   1631  setup_full_capture_of_logs(LOG_INFO);
   1632  update_all_descriptors_intro_points(now);
   1633  tor_free(node->ri->onion_curve25519_pkey); /* Avoid memleak. */
   1634  tor_free(node->ri->cache_info.signing_key_cert);
   1635  expect_log_msg_containing("just picked 1 intro points and wanted 3 for next "
   1636                            "descriptor. It currently has 0 intro points. "
   1637                            "Launching ESTABLISH_INTRO circuit shortly.");
   1638  teardown_capture_of_logs();
   1639  tt_int_op(digest256map_size(service->desc_current->intro_points.map),
   1640            OP_EQ, 1);
   1641  tt_int_op(digest256map_size(service->desc_next->intro_points.map),
   1642            OP_EQ, 1);
   1643  /* Get the IP object. Because we don't have the auth key of the IP, we can't
   1644   * query it so get the first element in the map. */
   1645  {
   1646    void *obj = NULL;
   1647    const uint8_t *key;
   1648    digest256map_iter_t *iter =
   1649      digest256map_iter_init(service->desc_current->intro_points.map);
   1650    digest256map_iter_get(iter, &key, &obj);
   1651    tt_assert(obj);
   1652    ip_cur = obj;
   1653    /* Get also the IP from the next descriptor. We'll make sure it's not the
   1654     * same object as in the current descriptor. */
   1655    iter = digest256map_iter_init(service->desc_next->intro_points.map);
   1656    digest256map_iter_get(iter, &key, &obj);
   1657    tt_assert(obj);
   1658    ip_next = obj;
   1659  }
   1660  tt_mem_op(ip_cur, OP_NE, ip_next, sizeof(hs_desc_intro_point_t));
   1661 
   1662  /* We won't test the service IP object because there is a specific test
   1663   * already for this but we'll make sure that the state is coherent.*/
   1664 
   1665  /* Three link specifiers are mandatory so make sure we do have them. */
   1666  tt_int_op(smartlist_len(ip_cur->base.link_specifiers), OP_EQ, 3);
   1667  /* Make sure we have a valid encryption keypair generated when we pick an
   1668   * intro point in the update process. */
   1669  tt_assert(!fast_mem_is_zero((char *) ip_cur->enc_key_kp.seckey.secret_key,
   1670                             CURVE25519_SECKEY_LEN));
   1671  tt_assert(!fast_mem_is_zero((char *) ip_cur->enc_key_kp.pubkey.public_key,
   1672                             CURVE25519_PUBKEY_LEN));
   1673  tt_u64_op(ip_cur->time_to_expire, OP_GE, now +
   1674            INTRO_POINT_LIFETIME_MIN_SECONDS);
   1675  tt_u64_op(ip_cur->time_to_expire, OP_LE, now +
   1676            INTRO_POINT_LIFETIME_MAX_SECONDS);
   1677 
   1678  /* Now, we will try to set up a service after a new time period has started
   1679   * and see if it behaves as expected. */
   1680 
   1681  ret = parse_rfc1123_time("Sat, 26 Oct 1985 13:00:00 UTC",
   1682                           &mock_ns.valid_after);
   1683  tt_int_op(ret, OP_EQ, 0);
   1684  ret = parse_rfc1123_time("Sat, 26 Oct 1985 14:00:00 UTC",
   1685                           &mock_ns.fresh_until);
   1686  tt_int_op(ret, OP_EQ, 0);
   1687 
   1688  update_approx_time(mock_ns.valid_after+1);
   1689  now = mock_ns.valid_after+1;
   1690 
   1691  /* Create a service without a current descriptor to trigger a build. */
   1692  service = helper_create_service();
   1693  tt_assert(service);
   1694  /* Unfortunately, the helper creates a dummy descriptor so get rid of it. */
   1695  service_descriptor_free(service->desc_current);
   1696  service->desc_current = NULL;
   1697 
   1698  /* We have a fresh service so this should trigger a build for both
   1699   * descriptors for specific time period that we'll test. */
   1700  build_all_descriptors(now);
   1701  /* Check *current* descriptor. */
   1702  tt_assert(service->desc_current);
   1703  tt_assert(service->desc_current->desc);
   1704  tt_assert(service->desc_current->intro_points.map);
   1705  /* This should be for the previous time period. */
   1706  tt_u64_op(service->desc_current->time_period_num, OP_EQ,
   1707            hs_get_previous_time_period_num(0));
   1708  /* This should be untouched, the update descriptor process changes it. */
   1709  tt_u64_op(service->desc_current->next_upload_time, OP_EQ, 0);
   1710 
   1711  /* Check *next* descriptor. */
   1712  tt_assert(service->desc_next);
   1713  tt_assert(service->desc_next->desc);
   1714  tt_assert(service->desc_next->intro_points.map);
   1715  tt_assert(service->desc_current != service->desc_next);
   1716  tt_u64_op(service->desc_next->time_period_num, OP_EQ,
   1717            hs_get_time_period_num(0));
   1718  /* This should be untouched, the update descriptor process changes it. */
   1719  tt_u64_op(service->desc_next->next_upload_time, OP_EQ, 0);
   1720 
   1721  /* Let's remove the next descriptor to simulate a rotation. */
   1722  service_descriptor_free(service->desc_next);
   1723  service->desc_next = NULL;
   1724 
   1725  build_all_descriptors(now);
   1726  /* Check *next* descriptor. */
   1727  tt_assert(service->desc_next);
   1728  tt_assert(service->desc_next->desc);
   1729  tt_assert(service->desc_next->intro_points.map);
   1730  tt_assert(service->desc_current != service->desc_next);
   1731  tt_u64_op(service->desc_next->time_period_num, OP_EQ,
   1732            hs_get_next_time_period_num(0));
   1733  /* This should be untouched, the update descriptor process changes it. */
   1734  tt_u64_op(service->desc_next->next_upload_time, OP_EQ, 0);
   1735 
   1736 done:
   1737  if (service) {
   1738    remove_service(get_hs_service_map(), service);
   1739    hs_service_free(service);
   1740  }
   1741  hs_free_all();
   1742  nodelist_free_all();
   1743 }
   1744 
   1745 /** Test building descriptors. We use this separate function instead of
   1746 *  using test_build_update_descriptors because that function is too complex
   1747 *  and also too interactive. */
   1748 static void
   1749 test_build_descriptors(void *arg)
   1750 {
   1751  int ret;
   1752  time_t now = time(NULL);
   1753  hs_service_t *last_service = NULL;
   1754 
   1755  (void) arg;
   1756 
   1757  hs_init();
   1758 
   1759  MOCK(get_or_state,
   1760       get_or_state_replacement);
   1761  MOCK(networkstatus_get_reasonably_live_consensus,
   1762       mock_networkstatus_get_reasonably_live_consensus);
   1763 
   1764  dummy_state = or_state_new();
   1765 
   1766  ret = parse_rfc1123_time("Sat, 26 Oct 1985 03:00:00 UTC",
   1767                           &mock_ns.valid_after);
   1768  tt_int_op(ret, OP_EQ, 0);
   1769  ret = parse_rfc1123_time("Sat, 26 Oct 1985 04:00:00 UTC",
   1770                           &mock_ns.fresh_until);
   1771  tt_int_op(ret, OP_EQ, 0);
   1772  dirauth_sched_recalculate_timing(get_options(), mock_ns.valid_after);
   1773 
   1774  /* Generate a valid number of fake auth clients when a client authorization
   1775   * is disabled. */
   1776  {
   1777    hs_service_t *service = helper_create_service();
   1778    last_service = service;
   1779    service_descriptor_free(service->desc_current);
   1780    service->desc_current = NULL;
   1781 
   1782    build_all_descriptors(now);
   1783    tt_assert(service->desc_current);
   1784    tt_assert(service->desc_current->desc);
   1785 
   1786    hs_desc_superencrypted_data_t *superencrypted;
   1787    superencrypted = &service->desc_current->desc->superencrypted_data;
   1788    tt_int_op(smartlist_len(superencrypted->clients), OP_EQ, 16);
   1789 
   1790    helper_destroy_service(service);
   1791    last_service = NULL;
   1792  }
   1793 
   1794  /* Generate a valid number of fake auth clients when the number of
   1795   * clients is zero. */
   1796  {
   1797    hs_service_t *service = helper_create_service_with_clients(0);
   1798    last_service = service;
   1799    service_descriptor_free(service->desc_current);
   1800    service->desc_current = NULL;
   1801 
   1802    build_all_descriptors(now);
   1803    hs_desc_superencrypted_data_t *superencrypted;
   1804    superencrypted = &service->desc_current->desc->superencrypted_data;
   1805    tt_int_op(smartlist_len(superencrypted->clients), OP_EQ, 16);
   1806 
   1807    helper_destroy_service(service);
   1808    last_service = NULL;
   1809  }
   1810 
   1811  /* Generate a valid number of fake auth clients when the number of
   1812   * clients is not a multiple of 16. */
   1813  {
   1814    hs_service_t *service = helper_create_service_with_clients(20);
   1815    last_service = service;
   1816    service_descriptor_free(service->desc_current);
   1817    service->desc_current = NULL;
   1818 
   1819    build_all_descriptors(now);
   1820    hs_desc_superencrypted_data_t *superencrypted;
   1821    superencrypted = &service->desc_current->desc->superencrypted_data;
   1822    tt_int_op(smartlist_len(superencrypted->clients), OP_EQ, 32);
   1823 
   1824    helper_destroy_service(service);
   1825    last_service = NULL;
   1826  }
   1827 
   1828  /* Do not generate any fake desc client when the number of clients is
   1829   * a multiple of 16 but not zero. */
   1830  {
   1831    hs_service_t *service = helper_create_service_with_clients(32);
   1832    last_service = service;
   1833    service_descriptor_free(service->desc_current);
   1834    service->desc_current = NULL;
   1835 
   1836    build_all_descriptors(now);
   1837    hs_desc_superencrypted_data_t *superencrypted;
   1838    superencrypted = &service->desc_current->desc->superencrypted_data;
   1839    tt_int_op(smartlist_len(superencrypted->clients), OP_EQ, 32);
   1840 
   1841    helper_destroy_service(service);
   1842    last_service = NULL;
   1843  }
   1844 
   1845 done:
   1846  helper_destroy_service(last_service);
   1847  hs_free_all();
   1848 }
   1849 
   1850 static void
   1851 test_upload_descriptors(void *arg)
   1852 {
   1853  int ret;
   1854  time_t now;
   1855  hs_service_t *service;
   1856 
   1857  (void) arg;
   1858 
   1859  hs_init();
   1860  MOCK(get_or_state,
   1861       get_or_state_replacement);
   1862  MOCK(networkstatus_get_reasonably_live_consensus,
   1863       mock_networkstatus_get_reasonably_live_consensus);
   1864 
   1865  dummy_state = or_state_new();
   1866 
   1867  ret = parse_rfc1123_time("Sat, 26 Oct 1985 13:00:00 UTC",
   1868                           &mock_ns.valid_after);
   1869  tt_int_op(ret, OP_EQ, 0);
   1870  ret = parse_rfc1123_time("Sat, 26 Oct 1985 14:00:00 UTC",
   1871                           &mock_ns.fresh_until);
   1872  tt_int_op(ret, OP_EQ, 0);
   1873  dirauth_sched_recalculate_timing(get_options(), mock_ns.valid_after);
   1874 
   1875  update_approx_time(mock_ns.valid_after+1);
   1876  now = mock_ns.valid_after+1;
   1877 
   1878  /* Create a service with no descriptor. It's added to the global map. */
   1879  service = hs_service_new(get_options());
   1880  tt_assert(service);
   1881  service->config.version = HS_VERSION_THREE;
   1882  ed25519_secret_key_generate(&service->keys.identity_sk, 0);
   1883  ed25519_public_key_generate(&service->keys.identity_pk,
   1884                              &service->keys.identity_sk);
   1885  /* Register service to global map. */
   1886  ret = register_service(get_hs_service_map(), service);
   1887  tt_int_op(ret, OP_EQ, 0);
   1888  /* But first, build our descriptor. */
   1889  build_all_descriptors(now);
   1890 
   1891  /* Nothing should happen because we have 0 introduction circuit established
   1892   * and we want (by default) 3 intro points. */
   1893  run_upload_descriptor_event(now);
   1894  /* If no upload happened, this should be untouched. */
   1895  tt_u64_op(service->desc_current->next_upload_time, OP_EQ, 0);
   1896  /* We'll simulate that we've opened our intro point circuit and that we only
   1897   * want one intro point. */
   1898  service->config.num_intro_points = 1;
   1899 
   1900  /* Set our next upload time after now which will skip the upload. */
   1901  service->desc_current->next_upload_time = now + 1000;
   1902  run_upload_descriptor_event(now);
   1903  /* If no upload happened, this should be untouched. */
   1904  tt_u64_op(service->desc_current->next_upload_time, OP_EQ, now + 1000);
   1905 
   1906 done:
   1907  hs_free_all();
   1908  UNMOCK(get_or_state);
   1909 }
   1910 
   1911 /** Global vars used by test_rendezvous1_parsing() */
   1912 static char rend1_payload[RELAY_PAYLOAD_SIZE];
   1913 static size_t rend1_payload_len = 0;
   1914 
   1915 /** Mock for relay_send_command_from_edge() to send a RENDEZVOUS1 cell. Instead
   1916 *  of sending it to the network, instead save it to the global `rend1_payload`
   1917 *  variable so that we can inspect it in the test_rendezvous1_parsing()
   1918 *  test. */
   1919 static int
   1920 mock_relay_send_rendezvous1(streamid_t stream_id, circuit_t *circ,
   1921                            uint8_t relay_command, const char *payload,
   1922                            size_t payload_len,
   1923                            crypt_path_t *cpath_layer,
   1924                            const char *filename, int lineno)
   1925 {
   1926  (void) stream_id;
   1927  (void) circ;
   1928  (void) relay_command;
   1929  (void) cpath_layer;
   1930  (void) filename;
   1931  (void) lineno;
   1932 
   1933  memcpy(rend1_payload, payload, payload_len);
   1934  rend1_payload_len = payload_len;
   1935 
   1936  return 0;
   1937 }
   1938 
   1939 /** Send a RENDEZVOUS1 as a service, and parse it as a client. */
   1940 static void
   1941 test_rendezvous1_parsing(void *arg)
   1942 {
   1943  int retval;
   1944  static const char *test_addr =
   1945    "4acth47i6kxnvkewtm6q7ib2s3ufpo5sqbsnzjpbi7utijcltosqemad.onion";
   1946  hs_service_t *service = NULL;
   1947  origin_circuit_t *service_circ = NULL;
   1948  origin_circuit_t *client_circ = NULL;
   1949  ed25519_keypair_t ip_auth_kp;
   1950  curve25519_keypair_t ephemeral_kp;
   1951  curve25519_keypair_t client_kp;
   1952  curve25519_keypair_t ip_enc_kp;
   1953  int flags = CIRCLAUNCH_NEED_UPTIME | CIRCLAUNCH_IS_INTERNAL;
   1954 
   1955  (void) arg;
   1956 
   1957  MOCK(relay_send_command_from_edge_, mock_relay_send_rendezvous1);
   1958 
   1959  {
   1960    /* Let's start by setting up the service that will start the rend */
   1961    service = tor_malloc_zero(sizeof(hs_service_t));
   1962    ed25519_secret_key_generate(&service->keys.identity_sk, 0);
   1963    ed25519_public_key_generate(&service->keys.identity_pk,
   1964                                &service->keys.identity_sk);
   1965    memcpy(service->onion_address, test_addr, sizeof(service->onion_address));
   1966    tt_assert(service);
   1967  }
   1968 
   1969  {
   1970    /* Now let's set up the service rendezvous circuit and its keys. */
   1971    service_circ = helper_create_origin_circuit(CIRCUIT_PURPOSE_S_CONNECT_REND,
   1972                                                flags);
   1973    tor_free(service_circ->hs_ident);
   1974    hs_ntor_rend_cell_keys_t hs_ntor_rend_cell_keys;
   1975    uint8_t rendezvous_cookie[HS_REND_COOKIE_LEN];
   1976    curve25519_keypair_generate(&ip_enc_kp, 0);
   1977    curve25519_keypair_generate(&ephemeral_kp, 0);
   1978    curve25519_keypair_generate(&client_kp, 0);
   1979    ed25519_keypair_generate(&ip_auth_kp, 0);
   1980    retval = hs_ntor_service_get_rendezvous1_keys(&ip_auth_kp.pubkey,
   1981                                                  &ip_enc_kp,
   1982                                                  &ephemeral_kp,
   1983                                                  &client_kp.pubkey,
   1984                                                  &hs_ntor_rend_cell_keys);
   1985    tt_int_op(retval, OP_EQ, 0);
   1986 
   1987    memset(rendezvous_cookie, 2, sizeof(rendezvous_cookie));
   1988    service_circ->hs_ident =
   1989      create_rp_circuit_identifier(service, rendezvous_cookie,
   1990                                   &ephemeral_kp.pubkey,
   1991                                   &hs_ntor_rend_cell_keys);
   1992  }
   1993 
   1994  /* Send out the RENDEZVOUS1 and make sure that our mock func worked */
   1995  tt_assert(fast_mem_is_zero(rend1_payload, 32));
   1996  hs_circ_service_rp_has_opened(service, service_circ);
   1997  tt_assert(!fast_mem_is_zero(rend1_payload, 32));
   1998  tt_int_op(rend1_payload_len, OP_EQ, HS_LEGACY_RENDEZVOUS_CELL_SIZE);
   1999 
   2000  /******************************/
   2001 
   2002  /** Now let's create the client rendezvous circuit */
   2003  client_circ =
   2004    helper_create_origin_circuit(CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED,
   2005                                 flags);
   2006  /* fix up its circ ident */
   2007  ed25519_pubkey_copy(&client_circ->hs_ident->intro_auth_pk,
   2008                      &ip_auth_kp.pubkey);
   2009  memcpy(&client_circ->hs_ident->rendezvous_client_kp,
   2010         &client_kp, sizeof(client_circ->hs_ident->rendezvous_client_kp));
   2011  memcpy(&client_circ->hs_ident->intro_enc_pk.public_key,
   2012         &ip_enc_kp.pubkey.public_key,
   2013         sizeof(client_circ->hs_ident->intro_enc_pk.public_key));
   2014 
   2015  /* Now parse the rendezvous2 circuit and make sure it was fine. We are
   2016   * skipping 20 bytes off its payload, since that's the rendezvous cookie
   2017   * which is only present in REND1. */
   2018  retval = handle_rendezvous2(client_circ,
   2019                              (uint8_t*)rend1_payload+20,
   2020                              rend1_payload_len-20);
   2021  tt_int_op(retval, OP_EQ, 0);
   2022 
   2023  /* TODO: We are only simulating client/service here. We could also simulate
   2024   * the rendezvous point by plugging in rend_mid_establish_rendezvous(). We
   2025   * would need an extra circuit and some more stuff but it's doable. */
   2026 
   2027 done:
   2028  circuit_free_(TO_CIRCUIT(service_circ));
   2029  circuit_free_(TO_CIRCUIT(client_circ));
   2030  hs_service_free(service);
   2031  hs_free_all();
   2032  UNMOCK(relay_send_command_from_edge_);
   2033 }
   2034 
   2035 static void
   2036 test_authorized_client_config_equal(void *arg)
   2037 {
   2038  int ret;
   2039  hs_service_config_t *config1, *config2;
   2040 
   2041  (void) arg;
   2042 
   2043  config1 = tor_malloc_zero(sizeof(*config1));
   2044  config2 = tor_malloc_zero(sizeof(*config2));
   2045 
   2046  /* Both configs are empty. */
   2047  {
   2048    config1->clients = smartlist_new();
   2049    config2->clients = smartlist_new();
   2050 
   2051    ret = service_authorized_client_config_equal(config1, config2);
   2052    tt_int_op(ret, OP_EQ, 1);
   2053 
   2054    service_clear_config(config1);
   2055    service_clear_config(config2);
   2056  }
   2057 
   2058  /* Both configs have exactly the same client config. */
   2059  {
   2060    config1->clients = smartlist_new();
   2061    config2->clients = smartlist_new();
   2062 
   2063    hs_service_authorized_client_t *client1, *client2;
   2064    client1 = helper_create_authorized_client();
   2065    client2 = helper_create_authorized_client();
   2066 
   2067    smartlist_add(config1->clients, client1);
   2068    smartlist_add(config1->clients, client2);
   2069 
   2070    /* We should swap the order of clients here to test that the order
   2071     * does not matter. */
   2072    smartlist_add(config2->clients, helper_clone_authorized_client(client2));
   2073    smartlist_add(config2->clients, helper_clone_authorized_client(client1));
   2074 
   2075    ret = service_authorized_client_config_equal(config1, config2);
   2076    tt_int_op(ret, OP_EQ, 1);
   2077 
   2078    service_clear_config(config1);
   2079    service_clear_config(config2);
   2080  }
   2081 
   2082  /* The numbers of clients in both configs are not equal. */
   2083  {
   2084    config1->clients = smartlist_new();
   2085    config2->clients = smartlist_new();
   2086 
   2087    hs_service_authorized_client_t *client1, *client2;
   2088    client1 = helper_create_authorized_client();
   2089    client2 = helper_create_authorized_client();
   2090 
   2091    smartlist_add(config1->clients, client1);
   2092    smartlist_add(config1->clients, client2);
   2093 
   2094    smartlist_add(config2->clients, helper_clone_authorized_client(client1));
   2095 
   2096    ret = service_authorized_client_config_equal(config1, config2);
   2097    tt_int_op(ret, OP_EQ, 0);
   2098 
   2099    service_clear_config(config1);
   2100    service_clear_config(config2);
   2101  }
   2102 
   2103  /* The first config has two distinct clients while the second config
   2104   * has two clients but they are duplicate. */
   2105  {
   2106    config1->clients = smartlist_new();
   2107    config2->clients = smartlist_new();
   2108 
   2109    hs_service_authorized_client_t *client1, *client2;
   2110    client1 = helper_create_authorized_client();
   2111    client2 = helper_create_authorized_client();
   2112 
   2113    smartlist_add(config1->clients, client1);
   2114    smartlist_add(config1->clients, client2);
   2115 
   2116    smartlist_add(config2->clients, helper_clone_authorized_client(client1));
   2117    smartlist_add(config2->clients, helper_clone_authorized_client(client1));
   2118 
   2119    ret = service_authorized_client_config_equal(config1, config2);
   2120    tt_int_op(ret, OP_EQ, 0);
   2121 
   2122    service_clear_config(config1);
   2123    service_clear_config(config2);
   2124  }
   2125 
   2126  /* Both configs have totally distinct clients. */
   2127  {
   2128    config1->clients = smartlist_new();
   2129    config2->clients = smartlist_new();
   2130 
   2131    hs_service_authorized_client_t *client1, *client2, *client3, *client4;
   2132    client1 = helper_create_authorized_client();
   2133    client2 = helper_create_authorized_client();
   2134    client3 = helper_create_authorized_client();
   2135    client4 = helper_create_authorized_client();
   2136 
   2137    smartlist_add(config1->clients, client1);
   2138    smartlist_add(config1->clients, client2);
   2139 
   2140    smartlist_add(config2->clients, client3);
   2141    smartlist_add(config2->clients, client4);
   2142 
   2143    ret = service_authorized_client_config_equal(config1, config2);
   2144    tt_int_op(ret, OP_EQ, 0);
   2145 
   2146    service_clear_config(config1);
   2147    service_clear_config(config2);
   2148  }
   2149 
   2150 done:
   2151  tor_free(config1);
   2152  tor_free(config2);
   2153 }
   2154 
   2155 /** Test that client circuit ID gets correctly exported */
   2156 static void
   2157 test_export_client_circuit_id(void *arg)
   2158 {
   2159  origin_circuit_t *or_circ = NULL;
   2160  size_t sz;
   2161  char *cp1=NULL, *cp2=NULL;
   2162  connection_t *conn = NULL;
   2163 
   2164  (void) arg;
   2165 
   2166  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
   2167 
   2168  hs_service_init();
   2169 
   2170  /* Create service */
   2171  hs_service_t *service = helper_create_service();
   2172  /* Check that export circuit ID detection works */
   2173  service->config.circuit_id_protocol = HS_CIRCUIT_ID_PROTOCOL_NONE;
   2174  tt_int_op(0, OP_EQ,
   2175            hs_service_exports_circuit_id(&service->keys.identity_pk));
   2176  service->config.circuit_id_protocol = HS_CIRCUIT_ID_PROTOCOL_HAPROXY;
   2177  tt_int_op(1, OP_EQ,
   2178            hs_service_exports_circuit_id(&service->keys.identity_pk));
   2179 
   2180  /* Create client connection */
   2181  conn = test_conn_get_connection(AP_CONN_STATE_CIRCUIT_WAIT, CONN_TYPE_AP, 0);
   2182 
   2183  /* Create client edge conn hs_ident */
   2184  edge_connection_t *edge_conn = TO_EDGE_CONN(conn);
   2185  edge_conn->hs_ident = hs_ident_edge_conn_new(&service->keys.identity_pk);
   2186  edge_conn->hs_ident->orig_virtual_port = 42;
   2187 
   2188  /* Create rend circuit */
   2189  or_circ = origin_circuit_new();
   2190  or_circ->base_.purpose = CIRCUIT_PURPOSE_C_REND_JOINED;
   2191  edge_conn->on_circuit = TO_CIRCUIT(or_circ);
   2192  or_circ->global_identifier = 666;
   2193 
   2194  /* Export circuit ID */
   2195  export_hs_client_circuit_id(edge_conn, service->config.circuit_id_protocol);
   2196 
   2197  /* Check contents */
   2198  cp1 = buf_get_contents(conn->outbuf, &sz);
   2199  tt_str_op(cp1, OP_EQ,
   2200            "PROXY TCP6 fc00:dead:beef:4dad::0:29a ::1 666 42\r\n");
   2201 
   2202  /* Change circ GID and see that the reported circuit ID also changes */
   2203  or_circ->global_identifier = 22;
   2204 
   2205  /* check changes */
   2206  export_hs_client_circuit_id(edge_conn, service->config.circuit_id_protocol);
   2207  cp2 = buf_get_contents(conn->outbuf, &sz);
   2208  tt_str_op(cp1, OP_NE, cp2);
   2209  tor_free(cp1);
   2210 
   2211  /* Check that GID with UINT32_MAX works. */
   2212  or_circ->global_identifier = UINT32_MAX;
   2213 
   2214  export_hs_client_circuit_id(edge_conn, service->config.circuit_id_protocol);
   2215  cp1 = buf_get_contents(conn->outbuf, &sz);
   2216  tt_str_op(cp1, OP_EQ,
   2217            "PROXY TCP6 fc00:dead:beef:4dad::ffff:ffff ::1 65535 42\r\n");
   2218  tor_free(cp1);
   2219 
   2220  /* Check that GID with UINT16_MAX works. */
   2221  or_circ->global_identifier = UINT16_MAX;
   2222 
   2223  export_hs_client_circuit_id(edge_conn, service->config.circuit_id_protocol);
   2224  cp1 = buf_get_contents(conn->outbuf, &sz);
   2225  tt_str_op(cp1, OP_EQ,
   2226            "PROXY TCP6 fc00:dead:beef:4dad::0:ffff ::1 65535 42\r\n");
   2227  tor_free(cp1);
   2228 
   2229  /* Check that GID with UINT16_MAX + 7 works. */
   2230  or_circ->global_identifier = UINT16_MAX + 7;
   2231 
   2232  export_hs_client_circuit_id(edge_conn, service->config.circuit_id_protocol);
   2233  cp1 = buf_get_contents(conn->outbuf, &sz);
   2234  tt_str_op(cp1, OP_EQ, "PROXY TCP6 fc00:dead:beef:4dad::1:6 ::1 6 42\r\n");
   2235 
   2236 done:
   2237  UNMOCK(connection_write_to_buf_impl_);
   2238  circuit_free_(TO_CIRCUIT(or_circ));
   2239  connection_free_minimal(conn);
   2240  hs_service_free(service);
   2241  tor_free(cp1);
   2242  tor_free(cp2);
   2243 }
   2244 
   2245 static smartlist_t *
   2246 mock_node_get_link_specifier_smartlist(const node_t *node, bool direct_conn)
   2247 {
   2248  (void) node;
   2249  (void) direct_conn;
   2250 
   2251  smartlist_t *lspecs = smartlist_new();
   2252  link_specifier_t *ls_legacy = link_specifier_new();
   2253  smartlist_add(lspecs, ls_legacy);
   2254 
   2255  return lspecs;
   2256 }
   2257 
   2258 static node_t *fake_node = NULL;
   2259 
   2260 static const node_t *
   2261 mock_build_state_get_exit_node(cpath_build_state_t *state)
   2262 {
   2263  (void) state;
   2264 
   2265  if (!fake_node) {
   2266    curve25519_secret_key_t seckey;
   2267    curve25519_secret_key_generate(&seckey, 0);
   2268 
   2269    fake_node = tor_malloc_zero(sizeof(node_t));
   2270    fake_node->ri = tor_malloc_zero(sizeof(routerinfo_t));
   2271    fake_node->ri->onion_curve25519_pkey =
   2272      tor_malloc_zero(sizeof(curve25519_public_key_t));
   2273    curve25519_public_key_generate(fake_node->ri->onion_curve25519_pkey,
   2274                                   &seckey);
   2275  }
   2276 
   2277  return fake_node;
   2278 }
   2279 
   2280 static void
   2281 mock_launch_rendezvous_point_circuit(const hs_service_t *service,
   2282                             const ed25519_public_key_t *ip_auth_pubkey,
   2283                             const curve25519_keypair_t *ip_enc_key_kp,
   2284                             const hs_cell_intro_rdv_data_t *rdv_data,
   2285                             time_t now)
   2286 {
   2287  (void) service;
   2288  (void) ip_auth_pubkey;
   2289  (void) ip_enc_key_kp;
   2290  (void) rdv_data;
   2291  (void) now;
   2292  return;
   2293 }
   2294 
   2295 /**
   2296 *  Test that INTRO2 cells are handled well by onion services in the normal
   2297 *  case and also when onionbalance is enabled.
   2298 */
   2299 static void
   2300 test_intro2_handling(void *arg)
   2301 {
   2302  (void)arg;
   2303 
   2304  MOCK(build_state_get_exit_node, mock_build_state_get_exit_node);
   2305  MOCK(relay_send_command_from_edge_, mock_relay_send_command_from_edge);
   2306  MOCK(node_get_link_specifier_smartlist,
   2307       mock_node_get_link_specifier_smartlist);
   2308  MOCK(launch_rendezvous_point_circuit, mock_launch_rendezvous_point_circuit);
   2309 
   2310  memset(relay_payload, 0, sizeof(relay_payload));
   2311 
   2312  int retval;
   2313  time_t now = 0101010101;
   2314  update_approx_time(now);
   2315 
   2316  /** OK this is the play:
   2317   *
   2318   *  In Act I, we have a standalone onion service X (without onionbalance
   2319   *  enabled). We test that X can properly handle INTRO2 cells sent by a
   2320   *  client Alice.
   2321   *
   2322   *  In Act II, we create an onionbalance setup with frontend being Z which
   2323   *  includes instances X and Y. We then setup onionbalance on X and test that
   2324   *  Alice who addresses Z can communicate with X through INTRO2 cells.
   2325   *
   2326   *  In Act III, we test that Alice can also communicate with X
   2327   *  directly even tho onionbalance is enabled.
   2328   *
   2329   *  And finally in Act IV, we check various cases where the INTRO2 cell
   2330   *  should not go through because the subcredentials don't line up
   2331   *  (e.g. Alice sends INTRO2 to X using Y's subcredential).
   2332   */
   2333 
   2334  /** Let's start with some setup! Create the instances and the frontend
   2335      service, create Alice, etc:  */
   2336 
   2337  /* Create instance X */
   2338  hs_service_t x_service;
   2339  memset(&x_service, 0, sizeof(hs_service_t));
   2340  /* Disable onionbalance */
   2341  x_service.config.ob_master_pubkeys = NULL;
   2342  x_service.state.replay_cache_rend_cookie = replaycache_new(0,0);
   2343  /* Initialize the metrics store */
   2344  hs_metrics_service_init(&x_service);
   2345 
   2346  /* Create subcredential for x: */
   2347  ed25519_keypair_t x_identity_keypair;
   2348  hs_subcredential_t x_subcred;
   2349  ed25519_keypair_generate(&x_identity_keypair, 0);
   2350  hs_helper_get_subcred_from_identity_keypair(&x_identity_keypair,
   2351                                              &x_subcred);
   2352 
   2353  /* Create the x instance's intro point */
   2354  hs_service_intro_point_t *x_ip = NULL;
   2355  {
   2356    curve25519_secret_key_t seckey;
   2357    curve25519_public_key_t pkey;
   2358    curve25519_secret_key_generate(&seckey, 0);
   2359    curve25519_public_key_generate(&pkey, &seckey);
   2360 
   2361    node_t intro_node;
   2362    memset(&intro_node, 0, sizeof(intro_node));
   2363    routerinfo_t ri;
   2364    memset(&ri, 0, sizeof(routerinfo_t));
   2365    ri.onion_curve25519_pkey = &pkey;
   2366    intro_node.ri = &ri;
   2367 
   2368    x_ip = service_intro_point_new(&intro_node);
   2369  }
   2370 
   2371  /* Create z frontend's subcredential */
   2372  ed25519_keypair_t z_identity_keypair;
   2373  hs_subcredential_t z_subcred;
   2374  ed25519_keypair_generate(&z_identity_keypair, 0);
   2375  hs_helper_get_subcred_from_identity_keypair(&z_identity_keypair,
   2376                                              &z_subcred);
   2377 
   2378  /* Create y instance's subcredential */
   2379  ed25519_keypair_t y_identity_keypair;
   2380  hs_subcredential_t y_subcred;
   2381  ed25519_keypair_generate(&y_identity_keypair, 0);
   2382  hs_helper_get_subcred_from_identity_keypair(&y_identity_keypair,
   2383                                              &y_subcred);
   2384 
   2385  /* Create Alice's intro point */
   2386  hs_desc_intro_point_t *alice_ip;
   2387  ed25519_keypair_t signing_kp;
   2388  ed25519_keypair_generate(&signing_kp, 0);
   2389  alice_ip = hs_helper_build_intro_point(&signing_kp, now, "1.2.3.4", 0,
   2390                                         &x_ip->auth_key_kp,
   2391                                         &x_ip->enc_key_kp);
   2392 
   2393  /* Create Alice's intro and rend circuits */
   2394  origin_circuit_t *intro_circ = origin_circuit_new();
   2395  intro_circ->cpath = tor_malloc_zero(sizeof(crypt_path_t));
   2396  intro_circ->cpath->prev = intro_circ->cpath;
   2397  intro_circ->hs_ident = tor_malloc_zero(sizeof(*intro_circ->hs_ident));
   2398  origin_circuit_t rend_circ;
   2399  TO_CIRCUIT(&rend_circ)->ccontrol = NULL;
   2400  rend_circ.hs_ident = tor_malloc_zero(sizeof(*rend_circ.hs_ident));
   2401  curve25519_keypair_generate(&rend_circ.hs_ident->rendezvous_client_kp, 0);
   2402  memset(rend_circ.hs_ident->rendezvous_cookie, 'r', HS_REND_COOKIE_LEN);
   2403 
   2404  /* ************************************************************ */
   2405 
   2406  /* Act I:
   2407   *
   2408   * Where Alice connects to X without onionbalance in the picture */
   2409 
   2410  /* Create INTRODUCE1 */
   2411  tt_assert(fast_mem_is_zero(relay_payload, sizeof(relay_payload)));
   2412  retval = hs_circ_send_introduce1(intro_circ, &rend_circ,
   2413                                   alice_ip, &x_subcred, NULL);
   2414 
   2415  /* Check that the payload was written successfully */
   2416  tt_int_op(retval, OP_EQ, 0);
   2417  tt_assert(!fast_mem_is_zero(relay_payload, sizeof(relay_payload)));
   2418  tt_int_op(relay_payload_len, OP_NE, 0);
   2419 
   2420  /* Handle the cell */
   2421  retval = hs_circ_handle_introduce2(&x_service,
   2422                                    intro_circ, x_ip,
   2423                                    &x_subcred,
   2424                                    (uint8_t*)relay_payload,relay_payload_len);
   2425  tt_int_op(retval, OP_EQ, 0);
   2426 
   2427  /* ************************************************************ */
   2428 
   2429  /* Act II:
   2430   *
   2431   * We now create an onionbalance setup with Z being the frontend and X and Y
   2432   * being the backend instances. Make sure that Alice can talk with the
   2433   * backend instance X even tho she thinks she is talking to the frontend Z.
   2434   */
   2435 
   2436  /* Now configure the X instance to do onionbalance with Z as the frontend */
   2437  x_service.config.ob_master_pubkeys = smartlist_new();
   2438  smartlist_add(x_service.config.ob_master_pubkeys,
   2439                &z_identity_keypair.pubkey);
   2440 
   2441  /* Create descriptors for x and load next descriptor with the x's
   2442   * subcredential so that it can accept connections for itself. */
   2443  x_service.desc_current = service_descriptor_new();
   2444  memset(x_service.desc_current->desc->subcredential.subcred, 'C',SUBCRED_LEN);
   2445  x_service.desc_next = service_descriptor_new();
   2446  memcpy(&x_service.desc_next->desc->subcredential, &x_subcred, SUBCRED_LEN);
   2447 
   2448  /* Refresh OB keys */
   2449  hs_ob_refresh_keys(&x_service);
   2450 
   2451  /* Create INTRODUCE1 from Alice to X through Z */
   2452  memset(relay_payload, 0, sizeof(relay_payload));
   2453  retval = hs_circ_send_introduce1(intro_circ, &rend_circ,
   2454                                   alice_ip, &z_subcred, NULL);
   2455 
   2456  /* Check that the payload was written successfully */
   2457  tt_int_op(retval, OP_EQ, 0);
   2458  tt_assert(!fast_mem_is_zero(relay_payload, sizeof(relay_payload)));
   2459  tt_int_op(relay_payload_len, OP_NE, 0);
   2460 
   2461  /* Deliver INTRODUCE1 to X even tho it carries Z's subcredential */
   2462  replaycache_free(x_service.state.replay_cache_rend_cookie);
   2463  x_service.state.replay_cache_rend_cookie = replaycache_new(0, 0);
   2464 
   2465  retval = hs_circ_handle_introduce2(&x_service,
   2466                                   intro_circ, x_ip,
   2467                                   &z_subcred,
   2468                                   (uint8_t*)relay_payload, relay_payload_len);
   2469  tt_int_op(retval, OP_EQ, 0);
   2470 
   2471  replaycache_free(x_ip->replay_cache);
   2472  x_ip->replay_cache = replaycache_new(0, 0);
   2473 
   2474  replaycache_free(x_service.state.replay_cache_rend_cookie);
   2475  x_service.state.replay_cache_rend_cookie = replaycache_new(0, 0);
   2476 
   2477  /* ************************************************************ */
   2478 
   2479  /* Act III:
   2480   *
   2481   * Now send a direct INTRODUCE cell from Alice to X using X's subcredential
   2482   * and check that it succeeds even with onionbalance enabled.
   2483   */
   2484 
   2485  /* Refresh OB keys (just to check for memleaks) */
   2486  hs_ob_refresh_keys(&x_service);
   2487 
   2488  /* Create INTRODUCE1 from Alice to X using X's subcred. */
   2489  memset(relay_payload, 0, sizeof(relay_payload));
   2490  retval = hs_circ_send_introduce1(intro_circ, &rend_circ,
   2491                                   alice_ip, &x_subcred, NULL);
   2492 
   2493  /* Check that the payload was written successfully */
   2494  tt_int_op(retval, OP_EQ, 0);
   2495  tt_assert(!fast_mem_is_zero(relay_payload, sizeof(relay_payload)));
   2496  tt_int_op(relay_payload_len, OP_NE, 0);
   2497 
   2498  /* Send INTRODUCE1 to X with X's subcredential (should succeed) */
   2499  replaycache_free(x_service.state.replay_cache_rend_cookie);
   2500  x_service.state.replay_cache_rend_cookie = replaycache_new(0, 0);
   2501 
   2502  retval = hs_circ_handle_introduce2(&x_service,
   2503                                   intro_circ, x_ip,
   2504                                   &x_subcred,
   2505                                   (uint8_t*)relay_payload, relay_payload_len);
   2506  tt_int_op(retval, OP_EQ, 0);
   2507 
   2508  /* We haven't encountered any errors yet, so all the introduction request
   2509   * error metrics should be 0 */
   2510  const smartlist_t *entries = metrics_store_get_all(
   2511      x_service.metrics.store, "tor_hs_intro_rejected_intro_req_count");
   2512  const metrics_store_entry_t *entry = NULL;
   2513 
   2514  for (size_t i = 0; i < hs_metrics_intro_req_error_reasons_size; ++i) {
   2515    entry = metrics_store_find_entry_with_label(
   2516        entries,
   2517        metrics_format_label("reason", hs_metrics_intro_req_error_reasons[i]));
   2518    tt_assert(entry);
   2519    tt_int_op(metrics_store_entry_get_value(entry), OP_EQ, 0);
   2520  }
   2521 
   2522  /* ************************************************************ */
   2523 
   2524  /* Act IV:
   2525   *
   2526   * Test cases where the INTRO2 cell should not be able to decode.
   2527   */
   2528 
   2529  /* Try sending the exact same INTRODUCE2 cell again and see that the intro
   2530   * point replay cache triggers: */
   2531  setup_full_capture_of_logs(LOG_WARN);
   2532  retval = hs_circ_handle_introduce2(&x_service,
   2533                                   intro_circ, x_ip,
   2534                                   &x_subcred,
   2535                                   (uint8_t*)relay_payload, relay_payload_len);
   2536  tt_int_op(retval, OP_EQ, -1);
   2537  expect_log_msg_containing("with the same ENCRYPTED section");
   2538  teardown_capture_of_logs();
   2539  entry = metrics_store_find_entry_with_label(
   2540      entries,
   2541      metrics_format_label("reason", HS_METRICS_ERR_INTRO_REQ_INTRODUCE2));
   2542  tt_assert(entry);
   2543  tt_int_op(metrics_store_entry_get_value(entry), OP_EQ, 1);
   2544 
   2545  /* Now cleanup the intro point replay cache but not the service replay cache
   2546     and see that this one triggers this time. */
   2547  replaycache_free(x_ip->replay_cache);
   2548  x_ip->replay_cache = replaycache_new(0, 0);
   2549  setup_full_capture_of_logs(LOG_INFO);
   2550  retval = hs_circ_handle_introduce2(&x_service,
   2551                                   intro_circ, x_ip,
   2552                                   &x_subcred,
   2553                                   (uint8_t*)relay_payload, relay_payload_len);
   2554  tt_int_op(retval, OP_EQ, -1);
   2555  expect_log_msg_containing("with same REND_COOKIE");
   2556  teardown_capture_of_logs();
   2557 
   2558  entry = metrics_store_find_entry_with_label(
   2559      entries, metrics_format_label(
   2560                   "reason", HS_METRICS_ERR_INTRO_REQ_INTRODUCE2_REPLAY));
   2561  tt_assert(entry);
   2562  tt_int_op(metrics_store_entry_get_value(entry), OP_EQ, 1);
   2563 
   2564  /* Now just to make sure cleanup both replay caches and make sure that the
   2565     cell gets through */
   2566  replaycache_free(x_ip->replay_cache);
   2567  x_ip->replay_cache = replaycache_new(0, 0);
   2568  replaycache_free(x_service.state.replay_cache_rend_cookie);
   2569  x_service.state.replay_cache_rend_cookie = replaycache_new(0, 0);
   2570  retval = hs_circ_handle_introduce2(&x_service,
   2571                                   intro_circ, x_ip,
   2572                                   &x_subcred,
   2573                                   (uint8_t*)relay_payload, relay_payload_len);
   2574  tt_int_op(retval, OP_EQ, 0);
   2575 
   2576  /* This time, the error metric was *not* incremented */
   2577  tt_int_op(metrics_store_entry_get_value(entry), OP_EQ, 1);
   2578 
   2579  /* As a final thing, create an INTRODUCE1 cell from Alice to X using Y's
   2580   * subcred (should fail since Y is just another instance and not the frontend
   2581   * service!) */
   2582  memset(relay_payload, 0, sizeof(relay_payload));
   2583  retval = hs_circ_send_introduce1(intro_circ, &rend_circ,
   2584                                   alice_ip, &y_subcred, NULL);
   2585  tt_int_op(retval, OP_EQ, 0);
   2586 
   2587  /* Check that the payload was written successfully */
   2588  tt_assert(!fast_mem_is_zero(relay_payload, sizeof(relay_payload)));
   2589  tt_int_op(relay_payload_len, OP_NE, 0);
   2590 
   2591  retval = hs_circ_handle_introduce2(&x_service,
   2592                                   intro_circ, x_ip,
   2593                                   &y_subcred,
   2594                                   (uint8_t*)relay_payload, relay_payload_len);
   2595 
   2596  tt_int_op(retval, OP_EQ, -1);
   2597  entry = metrics_store_find_entry_with_label(
   2598      entries,
   2599      metrics_format_label("reason", HS_METRICS_ERR_INTRO_REQ_INTRODUCE2));
   2600  tt_assert(entry);
   2601  tt_int_op(metrics_store_entry_get_value(entry), OP_EQ, 2);
   2602 
   2603 done:
   2604  /* Start cleaning up X */
   2605  replaycache_free(x_service.state.replay_cache_rend_cookie);
   2606  smartlist_free(x_service.config.ob_master_pubkeys);
   2607  tor_free(x_service.state.ob_subcreds);
   2608  service_descriptor_free(x_service.desc_current);
   2609  service_descriptor_free(x_service.desc_next);
   2610  hs_metrics_service_free(&x_service);
   2611  service_intro_point_free(x_ip);
   2612 
   2613  /* Clean up Alice */
   2614  hs_desc_intro_point_free(alice_ip);
   2615  tor_free(rend_circ.hs_ident);
   2616 
   2617  if (fake_node) {
   2618    tor_free(fake_node->ri->onion_curve25519_pkey);
   2619    tor_free(fake_node->ri);
   2620    tor_free(fake_node);
   2621  }
   2622 
   2623  UNMOCK(build_state_get_exit_node);
   2624  UNMOCK(relay_send_command_from_edge_);
   2625  UNMOCK(node_get_link_specifier_smartlist);
   2626  UNMOCK(launch_rendezvous_point_circuit);
   2627 }
   2628 
   2629 static void
   2630 test_cannot_upload_descriptors(void *arg)
   2631 {
   2632  int ret;
   2633  time_t now;
   2634  hs_service_t *service;
   2635 
   2636  (void) arg;
   2637 
   2638  hs_init();
   2639  MOCK(get_or_state,
   2640       get_or_state_replacement);
   2641  MOCK(networkstatus_get_reasonably_live_consensus,
   2642       mock_networkstatus_get_reasonably_live_consensus);
   2643 
   2644  dummy_state = or_state_new();
   2645 
   2646  ret = parse_rfc1123_time("Sat, 26 Oct 1985 13:00:00 UTC",
   2647                           &mock_ns.valid_after);
   2648  tt_int_op(ret, OP_EQ, 0);
   2649  ret = parse_rfc1123_time("Sat, 26 Oct 1985 14:00:00 UTC",
   2650                           &mock_ns.fresh_until);
   2651  tt_int_op(ret, OP_EQ, 0);
   2652  dirauth_sched_recalculate_timing(get_options(), mock_ns.valid_after);
   2653 
   2654  update_approx_time(mock_ns.valid_after + 1);
   2655  now = mock_ns.valid_after + 1;
   2656 
   2657  /* Create a service with no descriptor. It's added to the global map. */
   2658  service = hs_service_new(get_options());
   2659  tt_assert(service);
   2660  service->config.version = HS_VERSION_THREE;
   2661  ed25519_secret_key_generate(&service->keys.identity_sk, 0);
   2662  ed25519_public_key_generate(&service->keys.identity_pk,
   2663                              &service->keys.identity_sk);
   2664  /* Register service to global map. */
   2665  ret = register_service(get_hs_service_map(), service);
   2666  tt_int_op(ret, OP_EQ, 0);
   2667  /* But first, build our descriptor. */
   2668  build_all_descriptors(now);
   2669 
   2670  /* 1. Testing missing intro points reason. */
   2671  {
   2672    digest256map_t *cur = service->desc_current->intro_points.map;
   2673    digest256map_t *tmp = digest256map_new();
   2674    service->desc_current->intro_points.map = tmp;
   2675    service->desc_current->missing_intro_points = 1;
   2676    setup_full_capture_of_logs(LOG_INFO);
   2677    run_upload_descriptor_event(now);
   2678    digest256map_free(tmp, tor_free_);
   2679    service->desc_current->intro_points.map = cur;
   2680    expect_log_msg_containing(
   2681      "Service [scrubbed] can't upload its current descriptor: "
   2682      "Missing intro points");
   2683    teardown_capture_of_logs();
   2684    /* Reset. */
   2685    service->desc_current->missing_intro_points = 0;
   2686  }
   2687 
   2688  /* 2. Testing non established intro points. */
   2689  {
   2690    setup_full_capture_of_logs(LOG_INFO);
   2691    run_upload_descriptor_event(now);
   2692    expect_log_msg_containing(
   2693      "Service [scrubbed] can't upload its current descriptor: "
   2694      "Intro circuits aren't yet all established (0/3).");
   2695    teardown_capture_of_logs();
   2696  }
   2697 
   2698  /* We need to pass the established circuit tests and thus from now on, we
   2699   * MOCK this to return 3 intro points. */
   2700  MOCK(count_desc_circuit_established, mock_count_desc_circuit_established);
   2701  num_intro_points = 3;
   2702 
   2703  /* 3. Testing non established intro points. */
   2704  {
   2705    service->desc_current->next_upload_time = now + 1000;
   2706    setup_full_capture_of_logs(LOG_INFO);
   2707    run_upload_descriptor_event(now);
   2708    expect_log_msg_containing(
   2709      "Service [scrubbed] can't upload its current descriptor: "
   2710      "Next upload time is");
   2711    teardown_capture_of_logs();
   2712    /* Reset. */
   2713    service->desc_current->next_upload_time = 0;
   2714  }
   2715 
   2716  /* 4. Testing missing live consensus. */
   2717  {
   2718    MOCK(networkstatus_get_reasonably_live_consensus,
   2719         mock_networkstatus_get_reasonably_live_consensus_null);
   2720    setup_full_capture_of_logs(LOG_INFO);
   2721    run_upload_descriptor_event(now);
   2722    expect_log_msg_containing(
   2723      "Service [scrubbed] can't upload its current descriptor: "
   2724      "No reasonably live consensus");
   2725    teardown_capture_of_logs();
   2726    /* Reset. */
   2727    MOCK(networkstatus_get_reasonably_live_consensus,
   2728         mock_networkstatus_get_reasonably_live_consensus);
   2729  }
   2730 
   2731  /* 5. Test missing minimum directory information. */
   2732  {
   2733    MOCK(router_have_minimum_dir_info,
   2734         mock_router_have_minimum_dir_info_false);
   2735    setup_full_capture_of_logs(LOG_INFO);
   2736    run_upload_descriptor_event(now);
   2737    expect_log_msg_containing(
   2738      "Service [scrubbed] can't upload its current descriptor: "
   2739      "Not enough directory information");
   2740    teardown_capture_of_logs();
   2741 
   2742    /* Running it again shouldn't trigger anything due to rate limitation. */
   2743    setup_full_capture_of_logs(LOG_INFO);
   2744    run_upload_descriptor_event(now);
   2745    expect_no_log_entry();
   2746    teardown_capture_of_logs();
   2747    UNMOCK(router_have_minimum_dir_info);
   2748  }
   2749 
   2750  /* Increase time and redo test (5) in order to test the rate limiting. */
   2751  update_approx_time(mock_ns.valid_after + 61);
   2752  {
   2753    MOCK(router_have_minimum_dir_info,
   2754         mock_router_have_minimum_dir_info_false);
   2755    setup_full_capture_of_logs(LOG_INFO);
   2756    run_upload_descriptor_event(now);
   2757    expect_log_msg_containing(
   2758      "Service [scrubbed] can't upload its current descriptor: "
   2759      "Not enough directory information");
   2760    teardown_capture_of_logs();
   2761    UNMOCK(router_have_minimum_dir_info);
   2762  }
   2763 
   2764 done:
   2765  hs_free_all();
   2766  UNMOCK(count_desc_circuit_established);
   2767  UNMOCK(networkstatus_get_reasonably_live_consensus);
   2768  UNMOCK(get_or_state);
   2769 }
   2770 
   2771 struct testcase_t hs_service_tests[] = {
   2772  { "e2e_rend_circuit_setup", test_e2e_rend_circuit_setup, TT_FORK,
   2773    NULL, NULL },
   2774  { "load_keys", test_load_keys, TT_FORK,
   2775    NULL, NULL },
   2776  { "client_filename_is_valid", test_client_filename_is_valid, TT_FORK,
   2777    NULL, NULL },
   2778  { "parse_authorized_client", test_parse_authorized_client, TT_FORK,
   2779    NULL, NULL },
   2780  { "load_keys_with_client_auth", test_load_keys_with_client_auth, TT_FORK,
   2781    NULL, NULL },
   2782  { "access_service", test_access_service, TT_FORK,
   2783    NULL, NULL },
   2784  { "service_intro_point", test_service_intro_point, TT_FORK,
   2785    NULL, NULL },
   2786  { "helper_functions", test_helper_functions, TT_FORK,
   2787    NULL, NULL },
   2788  { "intro_circuit_opened", test_intro_circuit_opened, TT_FORK,
   2789    NULL, NULL },
   2790  { "intro_established", test_intro_established, TT_FORK,
   2791    NULL, NULL },
   2792  { "closing_intro_circs", test_closing_intro_circs, TT_FORK,
   2793    NULL, NULL },
   2794  { "rdv_circuit_opened", test_rdv_circuit_opened, TT_FORK,
   2795    NULL, NULL },
   2796  { "bad_introduce2", test_bad_introduce2, TT_FORK,
   2797    NULL, NULL },
   2798  { "service_event", test_service_event, TT_FORK,
   2799    NULL, NULL },
   2800  { "rotate_descriptors", test_rotate_descriptors, TT_FORK,
   2801    NULL, NULL },
   2802  { "build_update_descriptors", test_build_update_descriptors, TT_FORK,
   2803    NULL, NULL },
   2804  { "build_descriptors", test_build_descriptors, TT_FORK,
   2805    NULL, NULL },
   2806  { "upload_descriptors", test_upload_descriptors, TT_FORK,
   2807    NULL, NULL },
   2808  { "cannot_upload_descriptors", test_cannot_upload_descriptors, TT_FORK,
   2809    NULL, NULL },
   2810  { "rendezvous1_parsing", test_rendezvous1_parsing, TT_FORK,
   2811    NULL, NULL },
   2812  { "authorized_client_config_equal", test_authorized_client_config_equal,
   2813    TT_FORK, NULL, NULL },
   2814  { "export_client_circuit_id", test_export_client_circuit_id, TT_FORK,
   2815    NULL, NULL },
   2816  { "intro2_handling", test_intro2_handling, TT_FORK, NULL, NULL },
   2817 
   2818  END_OF_TESTCASES
   2819 };