tor

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

hs_client.c (100506B)


      1 /* Copyright (c) 2016-2021, The Tor Project, Inc. */
      2 /* See LICENSE for licensing information */
      3 
      4 /**
      5 * \file hs_client.c
      6 * \brief Implement next generation hidden service client functionality
      7 **/
      8 
      9 #define HS_CLIENT_PRIVATE
     10 
     11 #include "core/or/or.h"
     12 #include "app/config/config.h"
     13 #include "core/crypto/hs_ntor.h"
     14 #include "core/crypto/onion_crypto.h"
     15 #include "core/mainloop/connection.h"
     16 #include "core/or/circuitbuild.h"
     17 #include "core/or/circuitlist.h"
     18 #include "core/or/circuituse.h"
     19 #include "core/or/connection_edge.h"
     20 #include "core/or/congestion_control_common.h"
     21 #include "core/or/extendinfo.h"
     22 #include "core/or/protover.h"
     23 #include "core/or/reasons.h"
     24 #include "feature/client/circpathbias.h"
     25 #include "feature/dirclient/dirclient.h"
     26 #include "feature/dircommon/directory.h"
     27 #include "feature/hs/hs_cache.h"
     28 #include "feature/hs/hs_cell.h"
     29 #include "feature/hs/hs_circuit.h"
     30 #include "feature/hs/hs_circuitmap.h"
     31 #include "feature/hs/hs_client.h"
     32 #include "feature/hs/hs_control.h"
     33 #include "feature/hs/hs_descriptor.h"
     34 #include "feature/hs/hs_ident.h"
     35 #include "feature/nodelist/describe.h"
     36 #include "feature/nodelist/microdesc.h"
     37 #include "feature/nodelist/networkstatus.h"
     38 #include "feature/nodelist/nodelist.h"
     39 #include "feature/nodelist/routerset.h"
     40 #include "lib/crypt_ops/crypto_format.h"
     41 #include "lib/crypt_ops/crypto_rand.h"
     42 #include "lib/crypt_ops/crypto_util.h"
     43 #include "lib/evloop/compat_libevent.h"
     44 
     45 #include "core/or/cpath_build_state_st.h"
     46 #include "feature/dircommon/dir_connection_st.h"
     47 #include "core/or/entry_connection_st.h"
     48 #include "core/or/extend_info_st.h"
     49 #include "core/or/origin_circuit_st.h"
     50 #include "core/or/socks_request_st.h"
     51 
     52 #include "trunnel/hs/cell_introduce1.h"
     53 
     54 /** This event is activated when we are notified that directory information has
     55 * changed. It must be done asynchronous from the call due to possible
     56 * recursion from the caller of that notification. See #40579. */
     57 static struct mainloop_event_t *dir_info_changed_ev = NULL;
     58 
     59 /** Client-side authorizations for hidden services; map of service identity
     60 * public key to hs_client_service_authorization_t *. */
     61 static digest256map_t *client_auths = NULL;
     62 
     63 /** Mainloop callback. Scheduled to run when we are notified of a directory
     64 * info change. See hs_client_dir_info_changed(). */
     65 static void
     66 dir_info_changed_callback(mainloop_event_t *event, void *arg)
     67 {
     68  (void) event;
     69  (void) arg;
     70 
     71  /* We have possibly reached the minimum directory information or new
     72   * consensus so retry all pending SOCKS connection in
     73   * AP_CONN_STATE_RENDDESC_WAIT state in order to fetch the descriptor. */
     74  retry_all_socks_conn_waiting_for_desc();
     75 }
     76 
     77 /** Return a human-readable string for the client fetch status code. */
     78 static const char *
     79 fetch_status_to_string(hs_client_fetch_status_t status)
     80 {
     81  switch (status) {
     82  case HS_CLIENT_FETCH_ERROR:
     83    return "Internal error";
     84  case HS_CLIENT_FETCH_LAUNCHED:
     85    return "Descriptor fetch launched";
     86  case HS_CLIENT_FETCH_HAVE_DESC:
     87    return "Already have descriptor";
     88  case HS_CLIENT_FETCH_NO_HSDIRS:
     89    return "No more HSDir available to query";
     90  case HS_CLIENT_FETCH_NOT_ALLOWED:
     91    return "Fetching descriptors is not allowed";
     92  case HS_CLIENT_FETCH_MISSING_INFO:
     93    return "Missing directory information";
     94  case HS_CLIENT_FETCH_PENDING:
     95    return "Pending descriptor fetch";
     96  default:
     97    return "(Unknown client fetch status code)";
     98  }
     99 }
    100 
    101 /** Return true iff tor should close the SOCKS request(s) for the descriptor
    102 * fetch that ended up with this given status code. */
    103 static int
    104 fetch_status_should_close_socks(hs_client_fetch_status_t status)
    105 {
    106  switch (status) {
    107  case HS_CLIENT_FETCH_NO_HSDIRS:
    108    /* No more HSDir to query, we can't complete the SOCKS request(s). */
    109  case HS_CLIENT_FETCH_ERROR:
    110    /* The fetch triggered an internal error. */
    111  case HS_CLIENT_FETCH_NOT_ALLOWED:
    112    /* Client is not allowed to fetch (FetchHidServDescriptors 0). */
    113    goto close;
    114  case HS_CLIENT_FETCH_MISSING_INFO:
    115  case HS_CLIENT_FETCH_HAVE_DESC:
    116  case HS_CLIENT_FETCH_PENDING:
    117  case HS_CLIENT_FETCH_LAUNCHED:
    118    /* The rest doesn't require tor to close the SOCKS request(s). */
    119    goto no_close;
    120  }
    121 
    122 no_close:
    123  return 0;
    124 close:
    125  return 1;
    126 }
    127 
    128 /* Return a newly allocated list of all the entry connections that matches the
    129 * given service identity pk. If service_identity_pk is NULL, all entry
    130 * connections with an hs_ident are returned.
    131 *
    132 * Caller must free the returned list but does NOT have ownership of the
    133 * object inside thus they have to remain untouched. */
    134 static smartlist_t *
    135 find_entry_conns(const ed25519_public_key_t *service_identity_pk)
    136 {
    137  time_t now = time(NULL);
    138  smartlist_t *conns = NULL, *entry_conns = NULL;
    139 
    140  entry_conns = smartlist_new();
    141 
    142  conns = connection_list_by_type_state(CONN_TYPE_AP,
    143                                        AP_CONN_STATE_RENDDESC_WAIT);
    144  SMARTLIST_FOREACH_BEGIN(conns, connection_t *, base_conn) {
    145    entry_connection_t *entry_conn = TO_ENTRY_CONN(base_conn);
    146    const edge_connection_t *edge_conn = ENTRY_TO_EDGE_CONN(entry_conn);
    147 
    148    /* Only consider the entry connections that matches the service for which
    149     * we just fetched its descriptor. */
    150    if (!edge_conn->hs_ident ||
    151        (service_identity_pk &&
    152         !ed25519_pubkey_eq(service_identity_pk,
    153                            &edge_conn->hs_ident->identity_pk))) {
    154      continue;
    155    }
    156    assert_connection_ok(base_conn, now);
    157 
    158    /* Validated! Add the entry connection to the list. */
    159    smartlist_add(entry_conns, entry_conn);
    160  } SMARTLIST_FOREACH_END(base_conn);
    161 
    162  /* We don't have ownership of the objects in this list. */
    163  smartlist_free(conns);
    164  return entry_conns;
    165 }
    166 
    167 /* Cancel all descriptor fetches currently in progress. */
    168 static void
    169 cancel_descriptor_fetches(void)
    170 {
    171  smartlist_t *conns =
    172    connection_list_by_type_purpose(CONN_TYPE_DIR, DIR_PURPOSE_FETCH_HSDESC);
    173  SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) {
    174    const hs_ident_dir_conn_t *ident = TO_DIR_CONN(conn)->hs_ident;
    175    if (BUG(ident == NULL)) {
    176      /* A directory connection fetching a service descriptor can't have an
    177       * empty hidden service identifier. */
    178      continue;
    179    }
    180    log_debug(LD_REND, "Marking for close a directory connection fetching "
    181                       "a hidden service descriptor for service %s.",
    182              safe_str_client(ed25519_fmt(&ident->identity_pk)));
    183    connection_mark_for_close(conn);
    184  } SMARTLIST_FOREACH_END(conn);
    185 
    186  /* No ownership of the objects in this list. */
    187  smartlist_free(conns);
    188  log_info(LD_REND, "Hidden service client descriptor fetches cancelled.");
    189 }
    190 
    191 /** Get all connections that are waiting on a circuit and flag them back to
    192 * waiting for a hidden service descriptor for the given service key
    193 * service_identity_pk. */
    194 static void
    195 flag_all_conn_wait_desc(const ed25519_public_key_t *service_identity_pk)
    196 {
    197  tor_assert(service_identity_pk);
    198 
    199  smartlist_t *conns =
    200    connection_list_by_type_state(CONN_TYPE_AP, AP_CONN_STATE_CIRCUIT_WAIT);
    201 
    202  SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) {
    203    edge_connection_t *edge_conn;
    204    if (BUG(!CONN_IS_EDGE(conn))) {
    205      continue;
    206    }
    207    edge_conn = TO_EDGE_CONN(conn);
    208    if (edge_conn->hs_ident &&
    209        ed25519_pubkey_eq(&edge_conn->hs_ident->identity_pk,
    210                          service_identity_pk)) {
    211      connection_ap_mark_as_waiting_for_renddesc(TO_ENTRY_CONN(conn));
    212    }
    213  } SMARTLIST_FOREACH_END(conn);
    214 
    215  smartlist_free(conns);
    216 }
    217 
    218 /** Remove tracked HSDir requests from our history for this hidden service
    219 * identity public key. */
    220 static void
    221 purge_hid_serv_request(const ed25519_public_key_t *identity_pk)
    222 {
    223  char base64_blinded_pk[ED25519_BASE64_LEN + 1];
    224  ed25519_public_key_t blinded_pk;
    225 
    226  tor_assert(identity_pk);
    227 
    228  /* Get blinded pubkey of hidden service. It is possible that we just moved
    229   * to a new time period meaning that we won't be able to purge the request
    230   * from the previous time period. That is fine because they will expire at
    231   * some point and we don't care about those anymore. */
    232  hs_build_blinded_pubkey(identity_pk, NULL, 0,
    233                          hs_get_time_period_num(0), &blinded_pk);
    234  ed25519_public_to_base64(base64_blinded_pk, &blinded_pk);
    235  /* Purge last hidden service request from cache for this blinded key. */
    236  hs_purge_hid_serv_from_last_hid_serv_requests(base64_blinded_pk);
    237 }
    238 
    239 /** Return true iff there is at least one pending directory descriptor request
    240 * for the service identity_pk. */
    241 static int
    242 directory_request_is_pending(const ed25519_public_key_t *identity_pk)
    243 {
    244  int ret = 0;
    245  smartlist_t *conns =
    246    connection_list_by_type_purpose(CONN_TYPE_DIR, DIR_PURPOSE_FETCH_HSDESC);
    247 
    248  SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) {
    249    const hs_ident_dir_conn_t *ident = TO_DIR_CONN(conn)->hs_ident;
    250    if (BUG(ident == NULL)) {
    251      /* A directory connection fetching a service descriptor can't have an
    252       * empty hidden service identifier. */
    253      continue;
    254    }
    255    if (!ed25519_pubkey_eq(identity_pk, &ident->identity_pk)) {
    256      continue;
    257    }
    258    ret = 1;
    259    break;
    260  } SMARTLIST_FOREACH_END(conn);
    261 
    262  /* No ownership of the objects in this list. */
    263  smartlist_free(conns);
    264  return ret;
    265 }
    266 
    267 /** Helper function that changes the state of an entry connection to waiting
    268 * for a circuit. For this to work properly, the connection timestamps are set
    269 * to now and the connection is then marked as pending for a circuit. */
    270 static void
    271 mark_conn_as_waiting_for_circuit(connection_t *conn, time_t now)
    272 {
    273  tor_assert(conn);
    274 
    275  /* Because the connection can now proceed to opening circuit and ultimately
    276   * connect to the service, reset those timestamp so the connection is
    277   * considered "fresh" and can continue without being closed too early. */
    278  conn->timestamp_created = now;
    279  conn->timestamp_last_read_allowed = now;
    280  conn->timestamp_last_write_allowed = now;
    281  /* Change connection's state into waiting for a circuit. */
    282  conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
    283 
    284  connection_ap_mark_as_pending_circuit(TO_ENTRY_CONN(conn));
    285 }
    286 
    287 /** We failed to fetch a descriptor for the service with <b>identity_pk</b>
    288 * because of <b>status</b>. Find all pending SOCKS connections for this
    289 * service that are waiting on the descriptor and close them with
    290 * <b>reason</b>. */
    291 static void
    292 close_all_socks_conns_waiting_for_desc(const ed25519_public_key_t *identity_pk,
    293                                       hs_client_fetch_status_t status,
    294                                       int reason)
    295 {
    296  unsigned int count = 0;
    297  smartlist_t *entry_conns = find_entry_conns(identity_pk);
    298 
    299  SMARTLIST_FOREACH_BEGIN(entry_conns, entry_connection_t *, entry_conn) {
    300    /* Unattach the entry connection which will close for the reason. */
    301    connection_mark_unattached_ap(entry_conn, reason);
    302    count++;
    303  } SMARTLIST_FOREACH_END(entry_conn);
    304 
    305  if (count > 0) {
    306    char onion_address[HS_SERVICE_ADDR_LEN_BASE32 + 1];
    307    hs_build_address(identity_pk, HS_VERSION_THREE, onion_address);
    308    log_notice(LD_REND, "Closed %u streams for service %s.onion "
    309                        "for reason %s. Fetch status: %s.",
    310               count, safe_str_client(onion_address),
    311               stream_end_reason_to_string(reason),
    312               fetch_status_to_string(status));
    313  }
    314 
    315  /* No ownership of the object(s) in this list. */
    316  smartlist_free(entry_conns);
    317 }
    318 
    319 /** Find all pending SOCKS connection waiting for a descriptor and retry them
    320 * all. This is called when the directory information changed. */
    321 STATIC void
    322 retry_all_socks_conn_waiting_for_desc(void)
    323 {
    324  smartlist_t *entry_conns = find_entry_conns(NULL);
    325 
    326  SMARTLIST_FOREACH_BEGIN(entry_conns, entry_connection_t *, entry_conn) {
    327    hs_client_fetch_status_t status;
    328    edge_connection_t *edge_conn = ENTRY_TO_EDGE_CONN(entry_conn);
    329    connection_t *base_conn = &edge_conn->base_;
    330 
    331    /* Ignore non HS or non v3 connection. */
    332    if (edge_conn->hs_ident == NULL) {
    333      continue;
    334    }
    335 
    336    /* In this loop, we will possibly try to fetch a descriptor for the
    337     * pending connections because we just got more directory information.
    338     * However, the refetch process can cleanup all SOCKS request to the same
    339     * service if an internal error happens. Thus, we can end up with closed
    340     * connections in our list. */
    341    if (base_conn->marked_for_close) {
    342      continue;
    343    }
    344 
    345    /* XXX: There is an optimization we could do which is that for a service
    346     * key, we could check if we can fetch and remember that decision. */
    347 
    348    /* Order a refetch in case it works this time. */
    349    status = hs_client_refetch_hsdesc(&edge_conn->hs_ident->identity_pk);
    350    if (status == HS_CLIENT_FETCH_HAVE_DESC) {
    351      /* This is a rare case where a SOCKS connection is in state waiting for
    352       * a descriptor but we do have it in the cache.
    353       *
    354       * This can happen is tor comes back from suspend where it previously
    355       * had the descriptor but the intro points were not usable. Once it
    356       * came back to life, the intro point failure cache was cleaned up and
    357       * thus the descriptor became usable again leaving us in this code path.
    358       *
    359       * We'll mark the connection as waiting for a circuit so the descriptor
    360       * can be retried. This is safe because a connection in state waiting
    361       * for a descriptor can not be in the entry connection pending list. */
    362      mark_conn_as_waiting_for_circuit(base_conn, approx_time());
    363      continue;
    364    }
    365    /* In the case of an error, either all SOCKS connections have been
    366     * closed or we are still missing directory information. Leave the
    367     * connection in renddesc wait state so when we get more info, we'll be
    368     * able to try it again. */
    369  } SMARTLIST_FOREACH_END(entry_conn);
    370 
    371  /* We don't have ownership of those objects. */
    372  smartlist_free(entry_conns);
    373 }
    374 
    375 /** A v3 HS circuit successfully connected to the hidden service. Update the
    376 * stream state at <b>hs_conn_ident</b> appropriately. */
    377 static void
    378 note_connection_attempt_succeeded(const hs_ident_edge_conn_t *hs_conn_ident)
    379 {
    380  tor_assert(hs_conn_ident);
    381 
    382  /* Remove from the hid serv cache all requests for that service so we can
    383   * query the HSDir again later on for various reasons. */
    384  purge_hid_serv_request(&hs_conn_ident->identity_pk);
    385 }
    386 
    387 /** Given the pubkey of a hidden service in <b>onion_identity_pk</b>, fetch its
    388 * descriptor by launching a dir connection to <b>hsdir</b>. Return a
    389 * hs_client_fetch_status_t status code depending on how it went. */
    390 static hs_client_fetch_status_t
    391 directory_launch_v3_desc_fetch(const ed25519_public_key_t *onion_identity_pk,
    392                               const routerstatus_t *hsdir)
    393 {
    394  uint64_t current_time_period = hs_get_time_period_num(0);
    395  ed25519_public_key_t blinded_pubkey;
    396  char base64_blinded_pubkey[ED25519_BASE64_LEN + 1];
    397  hs_ident_dir_conn_t hs_conn_dir_ident;
    398 
    399  tor_assert(hsdir);
    400  tor_assert(onion_identity_pk);
    401 
    402  /* Get blinded pubkey */
    403  hs_build_blinded_pubkey(onion_identity_pk, NULL, 0,
    404                          current_time_period, &blinded_pubkey);
    405  /* ...and base64 it. */
    406  ed25519_public_to_base64(base64_blinded_pubkey, &blinded_pubkey);
    407 
    408  /* Copy onion pk to a dir_ident so that we attach it to the dir conn */
    409  hs_ident_dir_conn_init(onion_identity_pk, &blinded_pubkey,
    410                         &hs_conn_dir_ident);
    411 
    412  /* Setup directory request */
    413  directory_request_t *req =
    414    directory_request_new(DIR_PURPOSE_FETCH_HSDESC);
    415  directory_request_set_routerstatus(req, hsdir);
    416  directory_request_set_indirection(req, DIRIND_ANONYMOUS);
    417  directory_request_set_resource(req, base64_blinded_pubkey);
    418  directory_request_fetch_set_hs_ident(req, &hs_conn_dir_ident);
    419  directory_initiate_request(req);
    420  directory_request_free(req);
    421 
    422  log_info(LD_REND, "Descriptor fetch request for service %s with blinded "
    423                    "key %s to directory %s",
    424           safe_str_client(ed25519_fmt(onion_identity_pk)),
    425           safe_str_client(base64_blinded_pubkey),
    426           safe_str_client(routerstatus_describe(hsdir)));
    427 
    428  /* Fire a REQUESTED event on the control port. */
    429  hs_control_desc_event_requested(onion_identity_pk, base64_blinded_pubkey,
    430                                  hsdir);
    431 
    432  /* Cleanup memory. */
    433  memwipe(&blinded_pubkey, 0, sizeof(blinded_pubkey));
    434  memwipe(base64_blinded_pubkey, 0, sizeof(base64_blinded_pubkey));
    435  memwipe(&hs_conn_dir_ident, 0, sizeof(hs_conn_dir_ident));
    436 
    437  return HS_CLIENT_FETCH_LAUNCHED;
    438 }
    439 
    440 /** Return the HSDir we should use to fetch the descriptor of the hidden
    441 *  service with identity key <b>onion_identity_pk</b>. */
    442 STATIC routerstatus_t *
    443 pick_hsdir_v3(const ed25519_public_key_t *onion_identity_pk)
    444 {
    445  char base64_blinded_pubkey[ED25519_BASE64_LEN + 1];
    446  uint64_t current_time_period = hs_get_time_period_num(0);
    447  smartlist_t *responsible_hsdirs = NULL;
    448  ed25519_public_key_t blinded_pubkey;
    449  routerstatus_t *hsdir_rs = NULL;
    450 
    451  tor_assert(onion_identity_pk);
    452 
    453  /* Get blinded pubkey of hidden service */
    454  hs_build_blinded_pubkey(onion_identity_pk, NULL, 0,
    455                          current_time_period, &blinded_pubkey);
    456  /* ...and base64 it. */
    457  ed25519_public_to_base64(base64_blinded_pubkey, &blinded_pubkey);
    458 
    459  /* Get responsible hsdirs of service for this time period */
    460  responsible_hsdirs = smartlist_new();
    461 
    462  hs_get_responsible_hsdirs(&blinded_pubkey, current_time_period,
    463                            0, 1, responsible_hsdirs);
    464 
    465  log_debug(LD_REND, "Found %d responsible HSDirs and about to pick one.",
    466           smartlist_len(responsible_hsdirs));
    467 
    468  /* Pick an HSDir from the responsible ones. The ownership of
    469   * responsible_hsdirs is given to this function so no need to free it. */
    470  hsdir_rs = hs_pick_hsdir(responsible_hsdirs, base64_blinded_pubkey, NULL);
    471 
    472  return hsdir_rs;
    473 }
    474 
    475 /** Fetch a v3 descriptor using the given <b>onion_identity_pk</b>.
    476 *
    477 * On success, HS_CLIENT_FETCH_LAUNCHED is returned. Otherwise, an error from
    478 * hs_client_fetch_status_t is returned. */
    479 MOCK_IMPL(STATIC hs_client_fetch_status_t,
    480 fetch_v3_desc, (const ed25519_public_key_t *onion_identity_pk))
    481 {
    482  routerstatus_t *hsdir_rs =NULL;
    483 
    484  tor_assert(onion_identity_pk);
    485 
    486  hsdir_rs = pick_hsdir_v3(onion_identity_pk);
    487  if (!hsdir_rs) {
    488    log_info(LD_REND, "Couldn't pick a v3 hsdir.");
    489    return HS_CLIENT_FETCH_NO_HSDIRS;
    490  }
    491 
    492  return directory_launch_v3_desc_fetch(onion_identity_pk, hsdir_rs);
    493 }
    494 
    495 /** With a given <b>onion_identity_pk</b>, fetch its descriptor. If
    496 * <b>hsdirs</b> is specified, use the directory servers specified in the list.
    497 * Else, use a random server. */
    498 void
    499 hs_client_launch_v3_desc_fetch(const ed25519_public_key_t *onion_identity_pk,
    500                               const smartlist_t *hsdirs)
    501 {
    502  tor_assert(onion_identity_pk);
    503 
    504  if (hsdirs != NULL) {
    505    SMARTLIST_FOREACH_BEGIN(hsdirs, const routerstatus_t *, hsdir) {
    506      directory_launch_v3_desc_fetch(onion_identity_pk, hsdir);
    507    } SMARTLIST_FOREACH_END(hsdir);
    508  } else {
    509    fetch_v3_desc(onion_identity_pk);
    510  }
    511 }
    512 
    513 /** Make sure that the given v3 origin circuit circ is a valid correct
    514 * introduction circuit. This will BUG() on any problems and hard assert if
    515 * the anonymity of the circuit is not ok. Return 0 on success else -1 where
    516 * the circuit should be mark for closed immediately. */
    517 static int
    518 intro_circ_is_ok(const origin_circuit_t *circ)
    519 {
    520  int ret = 0;
    521 
    522  tor_assert(circ);
    523 
    524  if (BUG(TO_CIRCUIT(circ)->purpose != CIRCUIT_PURPOSE_C_INTRODUCING &&
    525          TO_CIRCUIT(circ)->purpose != CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT &&
    526          TO_CIRCUIT(circ)->purpose != CIRCUIT_PURPOSE_C_INTRODUCE_ACKED)) {
    527    ret = -1;
    528  }
    529  if (BUG(circ->hs_ident == NULL)) {
    530    ret = -1;
    531  }
    532  if (BUG(!hs_ident_intro_circ_is_valid(circ->hs_ident))) {
    533    ret = -1;
    534  }
    535 
    536  /* This can stop the tor daemon but we want that since if we don't have
    537   * anonymity on this circuit, something went really wrong. */
    538  assert_circ_anonymity_ok(circ, get_options());
    539  return ret;
    540 }
    541 
    542 /** Find a descriptor intro point object that matches the given ident in the
    543 * given descriptor desc. Return NULL if not found. */
    544 const hs_desc_intro_point_t *
    545 find_desc_intro_point_by_ident(const hs_ident_circuit_t *ident,
    546                               const hs_descriptor_t *desc)
    547 {
    548  const hs_desc_intro_point_t *intro_point = NULL;
    549 
    550  tor_assert(ident);
    551  tor_assert(desc);
    552  tor_assert_nonfatal(!ed25519_public_key_is_zero(&ident->intro_auth_pk));
    553 
    554  SMARTLIST_FOREACH_BEGIN(desc->encrypted_data.intro_points,
    555                          const hs_desc_intro_point_t *, ip) {
    556    if (ed25519_pubkey_eq(&ident->intro_auth_pk,
    557                          &ip->auth_key_cert->signed_key)) {
    558      intro_point = ip;
    559      break;
    560    }
    561  } SMARTLIST_FOREACH_END(ip);
    562 
    563  return intro_point;
    564 }
    565 
    566 /** Find a descriptor intro point object from the descriptor object desc that
    567 * matches the given legacy identity digest in legacy_id. Return NULL if not
    568 * found. */
    569 static hs_desc_intro_point_t *
    570 find_desc_intro_point_by_legacy_id(const char *legacy_id,
    571                                   const hs_descriptor_t *desc)
    572 {
    573  hs_desc_intro_point_t *ret_ip = NULL;
    574 
    575  tor_assert(legacy_id);
    576  tor_assert(desc);
    577 
    578  /* We will go over every intro point and try to find which one is linked to
    579   * that circuit. Those lists are small so it's not that expensive. */
    580  SMARTLIST_FOREACH_BEGIN(desc->encrypted_data.intro_points,
    581                          hs_desc_intro_point_t *, ip) {
    582    SMARTLIST_FOREACH_BEGIN(ip->link_specifiers,
    583                            const link_specifier_t *, lspec) {
    584      /* Not all tor node have an ed25519 identity key so we still rely on the
    585       * legacy identity digest. */
    586      if (link_specifier_get_ls_type(lspec) != LS_LEGACY_ID) {
    587        continue;
    588      }
    589      if (fast_memneq(legacy_id,
    590                      link_specifier_getconstarray_un_legacy_id(lspec),
    591                      DIGEST_LEN)) {
    592        break;
    593      }
    594      /* Found it. */
    595      ret_ip = ip;
    596      goto end;
    597    } SMARTLIST_FOREACH_END(lspec);
    598  } SMARTLIST_FOREACH_END(ip);
    599 
    600 end:
    601  return ret_ip;
    602 }
    603 
    604 /** Phase two for client-side introducing:
    605 * Send an INTRODUCE1 cell along the intro circuit and populate the rend
    606 * circuit identifier with the needed key material for the e2e encryption.
    607 */
    608 int
    609 send_introduce1(origin_circuit_t *intro_circ,
    610                origin_circuit_t *rend_circ,
    611                const hs_descriptor_t *desc,
    612                hs_pow_solution_t *pow_solution,
    613                const hs_desc_intro_point_t *ip)
    614 {
    615  const ed25519_public_key_t *service_identity_pk =
    616    &intro_circ->hs_ident->identity_pk;
    617 
    618  /* Send the INTRODUCE1 cell. */
    619  if (hs_circ_send_introduce1(intro_circ, rend_circ, ip,
    620                              &desc->subcredential, pow_solution) < 0) {
    621    if (TO_CIRCUIT(intro_circ)->marked_for_close) {
    622      /* If the introduction circuit was closed, we were unable to send the
    623       * cell for some reasons. In any case, the intro circuit has to be
    624       * closed by the above function. We'll return a transient error so tor
    625       * can recover and pick a new intro point. To avoid picking that same
    626       * intro point, we'll note down the intro point failure so it doesn't
    627       * get reused. */
    628      hs_cache_client_intro_state_note(service_identity_pk,
    629                                       &intro_circ->hs_ident->intro_auth_pk,
    630                                       INTRO_POINT_FAILURE_GENERIC);
    631    }
    632    /* It is also possible that the rendezvous circuit was closed due to being
    633     * unable to use the rendezvous point node_t so in that case, we also want
    634     * to recover and let tor pick a new one. */
    635    return -1; /* transient failure */
    636  }
    637 
    638  /* Cell has been sent successfully.
    639   * Now, we wait for an ACK or NAK on this circuit. */
    640  circuit_change_purpose(TO_CIRCUIT(intro_circ),
    641                         CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT);
    642  /* Set timestamp_dirty, because circuit_expire_building expects it to
    643   * specify when a circuit entered the _C_INTRODUCE_ACK_WAIT state. */
    644  TO_CIRCUIT(intro_circ)->timestamp_dirty = time(NULL);
    645  pathbias_count_use_attempt(intro_circ);
    646 
    647  return 0; /* Success. */
    648 }
    649 
    650 /** Set a client-side cap on the highest effort of PoW we will try to
    651 * tackle. If asked for higher, we solve it at this cap. */
    652 #define CLIENT_MAX_POW_EFFORT 10000
    653 
    654 /** Set a client-side minimum effort. If the client is choosing to increase
    655 * effort on retry, it will always pick a value >= this lower limit. */
    656 #define CLIENT_MIN_RETRY_POW_EFFORT 8
    657 
    658 /** Client effort will double on every retry until this level is hit */
    659 #define CLIENT_POW_EFFORT_DOUBLE_UNTIL 1000
    660 
    661 /** After we reach DOUBLE_UNTIL, client effort is multiplied by this amount
    662 * on every retry until we reach MAX_POW_EFFORT. */
    663 #define CLIENT_POW_RETRY_MULTIPLIER (1.5f)
    664 
    665 /** Send an INTRODUCE1 cell along the intro circuit and populate the rend
    666 * circuit identifier with the needed key material for the e2e encryption.
    667 * Return 0 on success, -1 if there is a transient error such that an action
    668 * has been taken to recover and -2 if there is a permanent error indicating
    669 * that both circuits were closed. */
    670 static int
    671 consider_sending_introduce1(origin_circuit_t *intro_circ,
    672                            origin_circuit_t *rend_circ)
    673 {
    674  int status;
    675  char onion_address[HS_SERVICE_ADDR_LEN_BASE32 + 1];
    676  const ed25519_public_key_t *service_identity_pk = NULL;
    677  const hs_desc_intro_point_t *ip;
    678 
    679  tor_assert(rend_circ);
    680  if (intro_circ_is_ok(intro_circ) < 0) {
    681    goto perm_err;
    682  }
    683 
    684  service_identity_pk = &intro_circ->hs_ident->identity_pk;
    685  /* For logging purposes. There will be a time where the hs_ident will have a
    686   * version number but for now there is none because it's all v3. */
    687  hs_build_address(service_identity_pk, HS_VERSION_THREE, onion_address);
    688 
    689  log_info(LD_REND, "Considering sending INTRODUCE1 cell to service %s "
    690           "on circuit %u",
    691           safe_str_client(onion_address), TO_CIRCUIT(intro_circ)->n_circ_id);
    692 
    693  /* if it's already waiting on the cpuworker farm, don't queue it again */
    694  if (intro_circ->hs_currently_solving_pow) {
    695    goto tran_err;
    696  }
    697 
    698  /* 1) Get descriptor from our cache. */
    699  const hs_descriptor_t *desc =
    700    hs_cache_lookup_as_client(service_identity_pk);
    701  if (desc == NULL || !hs_client_any_intro_points_usable(service_identity_pk,
    702                                                         desc)) {
    703    log_info(LD_REND, "Request to %s %s. Trying to fetch a new descriptor.",
    704             safe_str_client(onion_address),
    705             (desc) ? "didn't have usable intro points" :
    706             "didn't have a descriptor");
    707    hs_client_refetch_hsdesc(service_identity_pk);
    708    /* We just triggered a refetch, make sure every connections are back
    709     * waiting for that descriptor. */
    710    flag_all_conn_wait_desc(service_identity_pk);
    711    /* We just asked for a refetch so this is a transient error. */
    712    goto tran_err;
    713  }
    714 
    715  /* Check if the rendezvous circuit was setup WITHOUT congestion control,
    716   * but if it is enabled and the service supports it. This can happen, see
    717   * setup_rendezvous_circ_congestion_control() and so close rendezvous circuit
    718   * so another one can be created. */
    719  if (TO_CIRCUIT(rend_circ)->ccontrol == NULL && congestion_control_enabled()
    720      && hs_desc_supports_congestion_control(desc)) {
    721    circuit_mark_for_close(TO_CIRCUIT(rend_circ), END_CIRC_REASON_INTERNAL);
    722    goto tran_err;
    723  }
    724 
    725  /* We need to find which intro point in the descriptor we are connected to
    726   * on intro_circ. */
    727  ip = find_desc_intro_point_by_ident(intro_circ->hs_ident, desc);
    728  if (ip == NULL) {
    729    /* The following is possible if the descriptor was changed while we had
    730     * this introduction circuit open and waiting for the rendezvous circuit to
    731     * be ready. Which results in this situation where we can't find the
    732     * corresponding intro point within the descriptor of the service. */
    733    log_info(LD_REND, "Unable to find introduction point for service %s "
    734                      "while trying to send an INTRODUCE1 cell.",
    735             safe_str_client(onion_address));
    736    goto perm_err;
    737  }
    738 
    739  /* Copy the introduction point authentication and encryption key
    740   * in the rendezvous circuit identifier so we can compute the ntor keys
    741   * when we receive the RENDEZVOUS2 cell. */
    742  memcpy(&rend_circ->hs_ident->intro_enc_pk, &ip->enc_key,
    743         sizeof(rend_circ->hs_ident->intro_enc_pk));
    744 
    745  /* Optionally choose to solve a client puzzle for this connection. This
    746   * is only available if we have PoW support at compile time, and if the
    747   * service has provided a PoW seed in its descriptor. The puzzle is enabled
    748   * any time effort is nonzero, which can be recommended by the service or
    749   * self-imposed as a result of previous timeouts.
    750   */
    751  if (have_module_pow() && desc->encrypted_data.pow_params) {
    752    hs_pow_solver_inputs_t pow_inputs = {
    753      .effort = desc->encrypted_data.pow_params->suggested_effort,
    754      .CompiledProofOfWorkHash = get_options()->CompiledProofOfWorkHash
    755    };
    756    ed25519_pubkey_copy(&pow_inputs.service_blinded_id,
    757                        &desc->plaintext_data.blinded_pubkey);
    758    memcpy(pow_inputs.seed, desc->encrypted_data.pow_params->seed,
    759           sizeof pow_inputs.seed);
    760    log_debug(LD_REND, "PoW params present in descriptor, suggested_effort=%u",
    761              pow_inputs.effort);
    762 
    763    if (pow_inputs.effort > CLIENT_MAX_POW_EFFORT) {
    764      log_notice(LD_REND, "Onion service suggested effort %d which is "
    765                 "higher than we want to solve. Solving at %d instead.",
    766                 pow_inputs.effort, CLIENT_MAX_POW_EFFORT);
    767      pow_inputs.effort = CLIENT_MAX_POW_EFFORT;
    768    }
    769 
    770    const hs_cache_intro_state_t *state =
    771      hs_cache_client_intro_state_find(&intro_circ->hs_ident->identity_pk,
    772                                       &intro_circ->hs_ident->intro_auth_pk);
    773    uint32_t unreachable_count = state ? state->unreachable_count : 0;
    774    if (state) {
    775      log_debug(LD_REND, "hs_cache state during PoW consideration, "
    776                "error=%d timed_out=%d unreachable_count=%u",
    777                state->error, state->timed_out, state->unreachable_count);
    778    }
    779    uint64_t new_effort = pow_inputs.effort;
    780    for (unsigned n_retry = 0; n_retry < unreachable_count; n_retry++) {
    781      if (new_effort >= CLIENT_MAX_POW_EFFORT) {
    782        break;
    783      }
    784      if (new_effort < CLIENT_POW_EFFORT_DOUBLE_UNTIL) {
    785        new_effort <<= 1;
    786      } else {
    787        new_effort = (uint64_t) (CLIENT_POW_RETRY_MULTIPLIER * new_effort);
    788      }
    789      new_effort = MAX((uint64_t)CLIENT_MIN_RETRY_POW_EFFORT, new_effort);
    790      new_effort = MIN((uint64_t)CLIENT_MAX_POW_EFFORT, new_effort);
    791    }
    792    if (pow_inputs.effort != (uint32_t)new_effort) {
    793      log_info(LD_REND, "Increasing PoW effort from %d to %d after intro "
    794               "point unreachable_count=%d",
    795               pow_inputs.effort, (int)new_effort, unreachable_count);
    796      pow_inputs.effort = (uint32_t)new_effort;
    797    }
    798 
    799    if (pow_inputs.effort > 0) {
    800      /* send it to the client-side pow cpuworker for solving. */
    801      intro_circ->hs_currently_solving_pow = 1;
    802      if (hs_pow_queue_work(intro_circ->global_identifier,
    803                            rend_circ->hs_ident->rendezvous_cookie,
    804                            &pow_inputs) != 0) {
    805        log_warn(LD_REND, "Failed to enqueue PoW request");
    806      }
    807 
    808      /* can't proceed with the intro1 cell yet, so yield back to the
    809       * main loop */
    810      goto tran_err;
    811    }
    812  }
    813 
    814  /* move on to the next phase: actually try to send it */
    815  if (send_introduce1(intro_circ, rend_circ, desc, NULL, ip) < 0)
    816    goto tran_err;
    817 
    818  /* Success. */
    819  status = 0;
    820  goto end;
    821 
    822 perm_err:
    823  /* Permanent error: it is possible that the intro circuit was closed prior
    824   * because we weren't able to send the cell. Make sure we don't double close
    825   * it which would result in a warning. */
    826  if (!TO_CIRCUIT(intro_circ)->marked_for_close) {
    827    circuit_mark_for_close(TO_CIRCUIT(intro_circ), END_CIRC_REASON_INTERNAL);
    828  }
    829  circuit_mark_for_close(TO_CIRCUIT(rend_circ), END_CIRC_REASON_INTERNAL);
    830  status = -2;
    831  goto end;
    832 
    833 tran_err:
    834  status = -1;
    835 
    836 end:
    837  memwipe(onion_address, 0, sizeof(onion_address));
    838  return status;
    839 }
    840 
    841 /** Using the introduction circuit circ, setup the authentication key of the
    842 * intro point this circuit has extended to.
    843 *
    844 * Return 0 if everything went well, otherwise return -1 in the case of errors.
    845 */
    846 int
    847 hs_client_setup_intro_circ_auth_key(origin_circuit_t *circ)
    848 {
    849  const hs_descriptor_t *desc;
    850  const hs_desc_intro_point_t *ip;
    851 
    852  tor_assert(circ);
    853 
    854  desc = hs_cache_lookup_as_client(&circ->hs_ident->identity_pk);
    855  if (desc == NULL) {
    856    /* There is a very small race window between the opening of this circuit
    857     * and the client descriptor cache that gets purged (NEWNYM) or the
    858     * cleaned up because it expired. Mark the circuit for close so a new
    859     * descriptor fetch can occur. */
    860    goto err;
    861  }
    862 
    863  /* We will go over every intro point and try to find which one is linked to
    864   * that circuit. Those lists are small so it's not that expensive. */
    865  ip = find_desc_intro_point_by_legacy_id(
    866                       circ->build_state->chosen_exit->identity_digest, desc);
    867  if (!ip) {
    868    /* Reaching this point means we didn't find any intro point for this
    869     * circuit which is not supposed to happen. */
    870    log_info(LD_REND,"Could not match opened intro circuit with intro point.");
    871    goto err;
    872  }
    873 
    874  /* We got it, copy its authentication key to the identifier. */
    875  ed25519_pubkey_copy(&circ->hs_ident->intro_auth_pk,
    876                      &ip->auth_key_cert->signed_key);
    877  return 0;
    878 
    879 err:
    880  circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL);
    881  return -1;
    882 }
    883 
    884 /** Called when an introduction circuit has opened. */
    885 static void
    886 client_intro_circ_has_opened(origin_circuit_t *circ)
    887 {
    888  tor_assert(circ);
    889  tor_assert(TO_CIRCUIT(circ)->purpose == CIRCUIT_PURPOSE_C_INTRODUCING);
    890  log_info(LD_REND, "Introduction circuit %u has opened. Attaching streams.",
    891           (unsigned int) TO_CIRCUIT(circ)->n_circ_id);
    892 
    893  connection_ap_attach_pending(1);
    894 }
    895 
    896 /** Setup the congestion control parameters on the given rendezvous circuit.
    897 * This looks at the service descriptor flow control line (if any).
    898 *
    899 * It is possible that we are unable to set congestion control on the circuit
    900 * if the descriptor can't be found. In that case, the introduction circuit
    901 * can't be opened without it so a fetch will be triggered.
    902 *
    903 * However, if the descriptor asks for congestion control but the RP circuit
    904 * doesn't have it, it will be closed and a new circuit will be opened. */
    905 static void
    906 setup_rendezvous_circ_congestion_control(origin_circuit_t *circ)
    907 {
    908  tor_assert(circ);
    909 
    910  /* Setup congestion control parameters on the circuit. */
    911  const hs_descriptor_t *desc =
    912    hs_cache_lookup_as_client(&circ->hs_ident->identity_pk);
    913  if (desc == NULL) {
    914    /* This is possible because between launching the circuit and the circuit
    915     * ending in opened state, the descriptor could have been removed from the
    916     * cache. In this case, we just can't setup congestion control. */
    917    return;
    918  }
    919 
    920  /* Check if the service lists support for congestion control in its
    921   * descriptor. If not, we don't setup congestion control. */
    922  if (!hs_desc_supports_congestion_control(desc)) {
    923    return;
    924  }
    925 
    926  /* If network doesn't enable it, do not setup. */
    927  if (!congestion_control_enabled()) {
    928    return;
    929  }
    930 
    931  hs_circ_setup_congestion_control(circ, desc->encrypted_data.sendme_inc,
    932                                   desc->encrypted_data.single_onion_service);
    933 }
    934 
    935 /** Called when a rendezvous circuit has opened. */
    936 static void
    937 client_rendezvous_circ_has_opened(origin_circuit_t *circ)
    938 {
    939  tor_assert(circ);
    940  tor_assert(TO_CIRCUIT(circ)->purpose == CIRCUIT_PURPOSE_C_ESTABLISH_REND);
    941 
    942  const extend_info_t *rp_ei = circ->build_state->chosen_exit;
    943 
    944  /* Check that we didn't accidentally choose a node that does not understand
    945   * the v3 rendezvous protocol */
    946  if (rp_ei) {
    947    const node_t *rp_node = node_get_by_id(rp_ei->identity_digest);
    948    if (rp_node && !node_supports_v3_rendezvous_point(rp_node)) {
    949      /* Even tho we checked that this node supported v3 when we created the
    950         rendezvous circuit, there is a chance that we might think it does
    951         not support v3 anymore. This might happen if we got a new consensus
    952         in the meanwhile, where the relay is still listed but its listed
    953         descriptor digest has changed and hence we can't access its 'ri' or
    954         'md'. */
    955      log_info(LD_REND, "Rendezvous node %s did not support v3 after circuit "
    956               "has opened.", safe_str_client(extend_info_describe(rp_ei)));
    957      return;
    958    }
    959  }
    960 
    961  log_info(LD_REND, "Rendezvous circuit has opened to %s.",
    962           safe_str_client(extend_info_describe(rp_ei)));
    963 
    964  /* Setup congestion control parameters on the circuit. */
    965  setup_rendezvous_circ_congestion_control(circ);
    966 
    967  /* Ignore returned value, nothing we can really do. On failure, the circuit
    968   * will be marked for close. */
    969  hs_circ_send_establish_rendezvous(circ);
    970 
    971  /* Register rend circuit in circuitmap if it's still alive. */
    972  if (!TO_CIRCUIT(circ)->marked_for_close) {
    973    hs_circuitmap_register_rend_circ_client_side(circ,
    974                                     circ->hs_ident->rendezvous_cookie);
    975  }
    976 }
    977 
    978 /** This is an helper function that convert a descriptor intro point object ip
    979 * to a newly allocated extend_info_t object fully initialized. Return NULL if
    980 * we can't convert it for which chances are that we are missing or malformed
    981 * link specifiers. */
    982 STATIC extend_info_t *
    983 desc_intro_point_to_extend_info(const hs_desc_intro_point_t *ip)
    984 {
    985  extend_info_t *ei;
    986 
    987  tor_assert(ip);
    988 
    989  /* Explicitly put the direct connection option to 0 because this is client
    990   * side and there is no such thing as a non anonymous client. */
    991  ei = hs_get_extend_info_from_lspecs(ip->link_specifiers, &ip->onion_key, 0);
    992 
    993  return ei;
    994 }
    995 
    996 /** Return true iff the intro point ip for the service service_pk is usable.
    997 * This function checks if the intro point is in the client intro state cache
    998 * and checks at the failures. It is considered usable if:
    999 *   - No error happened (INTRO_POINT_FAILURE_GENERIC)
   1000 *   - It is not flagged as timed out (INTRO_POINT_FAILURE_TIMEOUT)
   1001 *   - The unreachable count is lower than
   1002 *     MAX_INTRO_POINT_REACHABILITY_FAILURES (INTRO_POINT_FAILURE_UNREACHABLE)
   1003 */
   1004 static int
   1005 intro_point_is_usable(const ed25519_public_key_t *service_pk,
   1006                      const hs_desc_intro_point_t *ip)
   1007 {
   1008  const hs_cache_intro_state_t *state;
   1009 
   1010  tor_assert(service_pk);
   1011  tor_assert(ip);
   1012 
   1013  state = hs_cache_client_intro_state_find(service_pk,
   1014                                           &ip->auth_key_cert->signed_key);
   1015  if (state == NULL) {
   1016    /* This means we've never encountered any problem thus usable. */
   1017    goto usable;
   1018  }
   1019  if (state->error) {
   1020    log_info(LD_REND, "Intro point with auth key %s had an error. Not usable",
   1021             safe_str_client(ed25519_fmt(&ip->auth_key_cert->signed_key)));
   1022    goto not_usable;
   1023  }
   1024  if (state->timed_out) {
   1025    log_info(LD_REND, "Intro point with auth key %s timed out. Not usable",
   1026             safe_str_client(ed25519_fmt(&ip->auth_key_cert->signed_key)));
   1027    goto not_usable;
   1028  }
   1029  if (state->unreachable_count >= MAX_INTRO_POINT_REACHABILITY_FAILURES) {
   1030    log_info(LD_REND, "Intro point with auth key %s unreachable. Not usable",
   1031             safe_str_client(ed25519_fmt(&ip->auth_key_cert->signed_key)));
   1032    goto not_usable;
   1033  }
   1034 
   1035 usable:
   1036  return 1;
   1037 not_usable:
   1038  return 0;
   1039 }
   1040 
   1041 /** Using a descriptor desc, return a newly allocated extend_info_t object of a
   1042 * randomly picked introduction point from its list. Return NULL if none are
   1043 * usable. */
   1044 STATIC extend_info_t *
   1045 client_get_random_intro(const ed25519_public_key_t *service_pk)
   1046 {
   1047  extend_info_t *ei = NULL, *ei_excluded = NULL;
   1048  smartlist_t *usable_ips = NULL;
   1049  const hs_descriptor_t *desc;
   1050  const hs_desc_encrypted_data_t *enc_data;
   1051  const or_options_t *options = get_options();
   1052  /* Calculate the onion address for logging purposes */
   1053  char onion_address[HS_SERVICE_ADDR_LEN_BASE32 + 1];
   1054 
   1055  tor_assert(service_pk);
   1056 
   1057  desc = hs_cache_lookup_as_client(service_pk);
   1058  /* Assume the service is v3 if the descriptor is missing. This is ok,
   1059   * because we only use the address in log messages */
   1060  hs_build_address(service_pk,
   1061                   desc ? desc->plaintext_data.version : HS_VERSION_THREE,
   1062                   onion_address);
   1063  if (desc == NULL || !hs_client_any_intro_points_usable(service_pk,
   1064                                                         desc)) {
   1065    log_info(LD_REND, "Unable to randomly select an introduction point "
   1066             "for service %s because descriptor %s. We can't connect.",
   1067             safe_str_client(onion_address),
   1068             (desc) ? "doesn't have any usable intro points"
   1069                    : "is missing (assuming v3 onion address)");
   1070    goto end;
   1071  }
   1072 
   1073  enc_data = &desc->encrypted_data;
   1074  usable_ips = smartlist_new();
   1075  smartlist_add_all(usable_ips, enc_data->intro_points);
   1076  while (smartlist_len(usable_ips) != 0) {
   1077    int idx;
   1078    const hs_desc_intro_point_t *ip;
   1079 
   1080    /* Pick a random intro point and immediately remove it from the usable
   1081     * list so we don't pick it again if we have to iterate more. */
   1082    idx = crypto_rand_int(smartlist_len(usable_ips));
   1083    ip = smartlist_get(usable_ips, idx);
   1084    smartlist_del(usable_ips, idx);
   1085 
   1086    /* We need to make sure we have a usable intro points which is in a good
   1087     * state in our cache. */
   1088    if (!intro_point_is_usable(service_pk, ip)) {
   1089      continue;
   1090    }
   1091 
   1092    /* Generate an extend info object from the intro point object. */
   1093    ei = desc_intro_point_to_extend_info(ip);
   1094    if (ei == NULL) {
   1095      /* We can get here for instance if the intro point is a private address
   1096       * and we aren't allowed to extend to those. */
   1097      log_info(LD_REND, "Unable to select introduction point with auth key %s "
   1098               "for service %s, because we could not extend to it.",
   1099               safe_str_client(ed25519_fmt(&ip->auth_key_cert->signed_key)),
   1100               safe_str_client(onion_address));
   1101      continue;
   1102    }
   1103 
   1104    /* Test the pick against ExcludeNodes. */
   1105    if (routerset_contains_extendinfo(options->ExcludeNodes, ei)) {
   1106      /* If this pick is in the ExcludeNodes list, we keep its reference so if
   1107       * we ever end up not being able to pick anything else and StrictNodes is
   1108       * unset, we'll use it. */
   1109      if (ei_excluded) {
   1110        /* If something was already here free it. After the loop is gone we
   1111         * will examine the last excluded intro point, and that's fine since
   1112         * that's random anyway */
   1113        extend_info_free(ei_excluded);
   1114      }
   1115      ei_excluded = ei;
   1116      continue;
   1117    }
   1118 
   1119    /* Good pick! Let's go with this. */
   1120    goto end;
   1121  }
   1122 
   1123  /* Reaching this point means a couple of things. Either we can't use any of
   1124   * the intro point listed because the IP address can't be extended to or it
   1125   * is listed in the ExcludeNodes list. In the later case, if StrictNodes is
   1126   * set, we are forced to not use anything. */
   1127  ei = ei_excluded;
   1128  if (options->StrictNodes) {
   1129    log_warn(LD_REND, "Every introduction point for service %s is in the "
   1130             "ExcludeNodes set and StrictNodes is set. We can't connect.",
   1131             safe_str_client(onion_address));
   1132    extend_info_free(ei);
   1133    ei = NULL;
   1134  } else {
   1135    log_fn(LOG_PROTOCOL_WARN, LD_REND, "Every introduction point for service "
   1136           "%s is unusable or we can't extend to it. We can't connect.",
   1137           safe_str_client(onion_address));
   1138  }
   1139 
   1140 end:
   1141  smartlist_free(usable_ips);
   1142  memwipe(onion_address, 0, sizeof(onion_address));
   1143  return ei;
   1144 }
   1145 
   1146 /** Return true iff all intro points for the given service have timed out. */
   1147 static bool
   1148 intro_points_all_timed_out(const ed25519_public_key_t *service_pk)
   1149 {
   1150  bool ret = false;
   1151 
   1152  tor_assert(service_pk);
   1153 
   1154  const hs_descriptor_t *desc = hs_cache_lookup_as_client(service_pk);
   1155  if (BUG(!desc)) {
   1156    /* We can't introduce without a descriptor so ending up here means somehow
   1157     * between the introduction failure and this, the cache entry was removed
   1158     * which shouldn't be possible in theory. */
   1159    goto end;
   1160  }
   1161 
   1162  SMARTLIST_FOREACH_BEGIN(desc->encrypted_data.intro_points,
   1163                          const hs_desc_intro_point_t *, ip) {
   1164    const hs_cache_intro_state_t *state =
   1165      hs_cache_client_intro_state_find(service_pk,
   1166                                       &ip->auth_key_cert->signed_key);
   1167    if (!state || !state->timed_out) {
   1168      /* No state or if this intro point has not timed out, we are done since
   1169       * clearly not all of them have timed out. */
   1170      goto end;
   1171    }
   1172  } SMARTLIST_FOREACH_END(ip);
   1173 
   1174  /* Exiting the loop here means that all intro points we've looked at have
   1175   * timed out. Note that we can _not_ have a descriptor without intro points
   1176   * in the client cache. */
   1177  ret = true;
   1178 
   1179 end:
   1180  return ret;
   1181 }
   1182 
   1183 /** Called when a rendezvous circuit has timed out. Every stream attached to
   1184 * the circuit will get set with the SOCKS5_HS_REND_FAILED (0xF3) extended
   1185 * error code so if the connection to the rendezvous point ends up not
   1186 * working, this code could be sent back as a reason. */
   1187 static void
   1188 socks_mark_rend_circuit_timed_out(const origin_circuit_t *rend_circ)
   1189 {
   1190  tor_assert(rend_circ);
   1191 
   1192  /* For each entry connection attached to this rendezvous circuit, report
   1193   * the error. */
   1194  for (edge_connection_t *edge = rend_circ->p_streams; edge;
   1195       edge = edge->next_stream) {
   1196     entry_connection_t *entry = EDGE_TO_ENTRY_CONN(edge);
   1197     if (entry->socks_request) {
   1198       entry->socks_request->socks_extended_error_code =
   1199         SOCKS5_HS_REND_FAILED;
   1200     }
   1201  }
   1202 }
   1203 
   1204 /** Called when introduction has failed meaning there is no more usable
   1205 * introduction points to be used (either NACKed or failed) for the given
   1206 * entry connection.
   1207 *
   1208 * This function only reports back the SOCKS5_HS_INTRO_FAILED (0xF2) code or
   1209 * SOCKS5_HS_INTRO_TIMEDOUT (0xF7) if all intros have timed out. The caller
   1210 * has to make sure to close the entry connections. */
   1211 static void
   1212 socks_mark_introduction_failed(entry_connection_t *conn,
   1213                                 const ed25519_public_key_t *identity_pk)
   1214 {
   1215  socks5_reply_status_t code = SOCKS5_HS_INTRO_FAILED;
   1216 
   1217  tor_assert(conn);
   1218  tor_assert(conn->socks_request);
   1219  tor_assert(identity_pk);
   1220 
   1221  if (intro_points_all_timed_out(identity_pk)) {
   1222    code = SOCKS5_HS_INTRO_TIMEDOUT;
   1223  }
   1224  conn->socks_request->socks_extended_error_code = code;
   1225 }
   1226 
   1227 /** For this introduction circuit, we'll look at if we have any usable
   1228 * introduction point left for this service. If so, we'll use the circuit to
   1229 * re-extend to a new intro point. Else, we'll close the circuit and its
   1230 * corresponding rendezvous circuit. Return 0 if we are re-extending else -1
   1231 * if we are closing the circuits.
   1232 *
   1233 * This is called when getting an INTRODUCE_ACK cell with a NACK. */
   1234 static int
   1235 close_or_reextend_intro_circ(origin_circuit_t *intro_circ)
   1236 {
   1237  int ret = -1;
   1238  const hs_descriptor_t *desc;
   1239  origin_circuit_t *rend_circ;
   1240 
   1241  tor_assert(intro_circ);
   1242 
   1243  desc = hs_cache_lookup_as_client(&intro_circ->hs_ident->identity_pk);
   1244  if (desc == NULL) {
   1245    /* We can't continue without a descriptor. This is possible if the cache
   1246     * was cleaned up between the intro point established and the reception of
   1247     * the introduce ack. */
   1248    goto close;
   1249  }
   1250  /* We still have the descriptor, great! Let's try to see if we can
   1251   * re-extend by looking up if there are any usable intro points. */
   1252  if (!hs_client_any_intro_points_usable(&intro_circ->hs_ident->identity_pk,
   1253                                         desc)) {
   1254    goto close;
   1255  }
   1256  /* Try to re-extend now. */
   1257  if (hs_client_reextend_intro_circuit(intro_circ) < 0) {
   1258    goto close;
   1259  }
   1260  /* Success on re-extending. Don't return an error. */
   1261  ret = 0;
   1262  goto end;
   1263 
   1264 close:
   1265  /* Change the intro circuit purpose before so we don't report an intro point
   1266   * failure again triggering an extra descriptor fetch. The circuit can
   1267   * already be closed on failure to re-extend. */
   1268  if (!TO_CIRCUIT(intro_circ)->marked_for_close) {
   1269    circuit_change_purpose(TO_CIRCUIT(intro_circ),
   1270                           CIRCUIT_PURPOSE_C_INTRODUCE_ACKED);
   1271    circuit_mark_for_close(TO_CIRCUIT(intro_circ), END_CIRC_REASON_FINISHED);
   1272  }
   1273  /* Close the related rendezvous circuit. */
   1274  rend_circ = hs_circuitmap_get_rend_circ_client_side(
   1275                                     intro_circ->hs_ident->rendezvous_cookie);
   1276  /* The rendezvous circuit might have collapsed while the INTRODUCE_ACK was
   1277   * inflight so we can't expect one every time. */
   1278  if (rend_circ) {
   1279    circuit_mark_for_close(TO_CIRCUIT(rend_circ), END_CIRC_REASON_FINISHED);
   1280  }
   1281 
   1282 end:
   1283  return ret;
   1284 }
   1285 
   1286 /** Called when we get an INTRODUCE_ACK success status code. Do the appropriate
   1287 * actions for the rendezvous point and finally close intro_circ. */
   1288 static void
   1289 handle_introduce_ack_success(origin_circuit_t *intro_circ)
   1290 {
   1291  origin_circuit_t *rend_circ = NULL;
   1292 
   1293  tor_assert(intro_circ);
   1294 
   1295  log_info(LD_REND, "Received INTRODUCE_ACK ack! Informing rendezvous");
   1296 
   1297  /* Get the rendezvous circuit for this rendezvous cookie. */
   1298  uint8_t *rendezvous_cookie = intro_circ->hs_ident->rendezvous_cookie;
   1299  rend_circ =
   1300  hs_circuitmap_get_established_rend_circ_client_side(rendezvous_cookie);
   1301  if (rend_circ == NULL) {
   1302    log_info(LD_REND, "Can't find any rendezvous circuit. Stopping");
   1303    goto end;
   1304  }
   1305 
   1306  assert_circ_anonymity_ok(rend_circ, get_options());
   1307 
   1308  /* It is possible to get a RENDEZVOUS2 cell before the INTRODUCE_ACK which
   1309   * means that the circuit will be joined and already transmitting data. In
   1310   * that case, simply skip the purpose change and close the intro circuit
   1311   * like it should be. */
   1312  if (TO_CIRCUIT(rend_circ)->purpose == CIRCUIT_PURPOSE_C_REND_JOINED) {
   1313    goto end;
   1314  }
   1315  circuit_change_purpose(TO_CIRCUIT(rend_circ),
   1316                         CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED);
   1317  /* Set timestamp_dirty, because circuit_expire_building expects it to
   1318   * specify when a circuit entered the
   1319   * CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED state. */
   1320  TO_CIRCUIT(rend_circ)->timestamp_dirty = time(NULL);
   1321 
   1322 end:
   1323  /* We don't need the intro circuit anymore. It did what it had to do! */
   1324  circuit_change_purpose(TO_CIRCUIT(intro_circ),
   1325                         CIRCUIT_PURPOSE_C_INTRODUCE_ACKED);
   1326  circuit_mark_for_close(TO_CIRCUIT(intro_circ), END_CIRC_REASON_FINISHED);
   1327 
   1328  /* XXX: Close pending intro circuits we might have in parallel. */
   1329  return;
   1330 }
   1331 
   1332 /** Called when we get an INTRODUCE_ACK failure status code. Depending on our
   1333 * failure cache status, either close the circuit or re-extend to a new
   1334 * introduction point. */
   1335 static void
   1336 handle_introduce_ack_bad(origin_circuit_t *circ, int status)
   1337 {
   1338  tor_assert(circ);
   1339 
   1340  log_info(LD_REND, "Received INTRODUCE_ACK nack by %s. Reason: %u",
   1341      safe_str_client(extend_info_describe(circ->build_state->chosen_exit)),
   1342      status);
   1343 
   1344  /* It's a NAK. The introduction point didn't relay our request. */
   1345  circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_C_INTRODUCING);
   1346 
   1347  /* Note down this failure in the intro point failure cache. Depending on how
   1348   * many times we've tried this intro point, close it or reextend. */
   1349  hs_cache_client_intro_state_note(&circ->hs_ident->identity_pk,
   1350                                   &circ->hs_ident->intro_auth_pk,
   1351                                   INTRO_POINT_FAILURE_GENERIC);
   1352 }
   1353 
   1354 /** Called when we get an INTRODUCE_ACK on the intro circuit circ. The encoded
   1355 * cell is in payload of length payload_len. Return 0 on success else a
   1356 * negative value. The circuit is either close or reuse to re-extend to a new
   1357 * introduction point. */
   1358 static int
   1359 handle_introduce_ack(origin_circuit_t *circ, const uint8_t *payload,
   1360                     size_t payload_len)
   1361 {
   1362  int status, ret = -1;
   1363 
   1364  tor_assert(circ);
   1365  tor_assert(circ->build_state);
   1366  tor_assert(circ->build_state->chosen_exit);
   1367  assert_circ_anonymity_ok(circ, get_options());
   1368  tor_assert(payload);
   1369 
   1370  status = hs_cell_parse_introduce_ack(payload, payload_len);
   1371  switch (status) {
   1372  case TRUNNEL_HS_INTRO_ACK_STATUS_SUCCESS:
   1373    ret = 0;
   1374    handle_introduce_ack_success(circ);
   1375    goto end;
   1376  case TRUNNEL_HS_INTRO_ACK_STATUS_UNKNOWN_ID:
   1377  case TRUNNEL_HS_INTRO_ACK_STATUS_BAD_FORMAT:
   1378  /* It is possible that the intro point can send us an unknown status code
   1379   * for the NACK that we do not know about like a new code for instance.
   1380   * Just fallthrough so we can note down the NACK and re-extend. */
   1381  default:
   1382    handle_introduce_ack_bad(circ, status);
   1383    /* We are going to see if we have to close the circuits (IP and RP) or we
   1384     * can re-extend to a new intro point. */
   1385    ret = close_or_reextend_intro_circ(circ);
   1386    break;
   1387  }
   1388 
   1389 end:
   1390  return ret;
   1391 }
   1392 
   1393 /** Called when we get a RENDEZVOUS2 cell on the rendezvous circuit circ. The
   1394 * encoded cell is in payload of length payload_len. Return 0 on success or a
   1395 * negative value on error. On error, the circuit is marked for close. */
   1396 STATIC int
   1397 handle_rendezvous2(origin_circuit_t *circ, const uint8_t *payload,
   1398                   size_t payload_len)
   1399 {
   1400  int ret = -1;
   1401  curve25519_public_key_t server_pk;
   1402  uint8_t auth_mac[DIGEST256_LEN] = {0};
   1403  uint8_t handshake_info[CURVE25519_PUBKEY_LEN + sizeof(auth_mac)] = {0};
   1404  hs_ntor_rend_cell_keys_t keys;
   1405  const hs_ident_circuit_t *ident;
   1406 
   1407  tor_assert(circ);
   1408  tor_assert(payload);
   1409 
   1410  /* Make things easier. */
   1411  ident = circ->hs_ident;
   1412  tor_assert(ident);
   1413 
   1414  if (hs_cell_parse_rendezvous2(payload, payload_len, handshake_info,
   1415                                sizeof(handshake_info)) < 0) {
   1416    goto err;
   1417  }
   1418  /* Get from the handshake info the SERVER_PK and AUTH_MAC. */
   1419  memcpy(&server_pk, handshake_info, CURVE25519_PUBKEY_LEN);
   1420  memcpy(auth_mac, handshake_info + CURVE25519_PUBKEY_LEN, sizeof(auth_mac));
   1421 
   1422  /* Generate the handshake info. */
   1423  if (hs_ntor_client_get_rendezvous1_keys(&ident->intro_auth_pk,
   1424                                          &ident->rendezvous_client_kp,
   1425                                          &ident->intro_enc_pk, &server_pk,
   1426                                          &keys) < 0) {
   1427    log_info(LD_REND, "Unable to compute the rendezvous keys.");
   1428    goto err;
   1429  }
   1430 
   1431  /* Critical check, make sure that the MAC matches what we got with what we
   1432   * computed just above. */
   1433  if (!hs_ntor_client_rendezvous2_mac_is_good(&keys, auth_mac)) {
   1434    log_info(LD_REND, "Invalid MAC in RENDEZVOUS2. Rejecting cell.");
   1435    goto err;
   1436  }
   1437 
   1438  /* Setup the e2e encryption on the circuit and finalize its state. */
   1439  if (hs_circuit_setup_e2e_rend_circ(circ, keys.ntor_key_seed,
   1440                                     sizeof(keys.ntor_key_seed), 0) < 0) {
   1441    log_info(LD_REND, "Unable to setup the e2e encryption.");
   1442    goto err;
   1443  }
   1444  /* Success. Hidden service connection finalized! */
   1445  ret = 0;
   1446  goto end;
   1447 
   1448 err:
   1449  circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_TORPROTOCOL);
   1450 end:
   1451  memwipe(&keys, 0, sizeof(keys));
   1452  return ret;
   1453 }
   1454 
   1455 /** Return true iff the client can fetch a descriptor for this service public
   1456 * identity key and status_out if not NULL is untouched. If the client can
   1457 * _not_ fetch the descriptor and if status_out is not NULL, it is set with
   1458 * the fetch status code. */
   1459 static unsigned int
   1460 can_client_refetch_desc(const ed25519_public_key_t *identity_pk,
   1461                        hs_client_fetch_status_t *status_out)
   1462 {
   1463  hs_client_fetch_status_t status;
   1464 
   1465  tor_assert(identity_pk);
   1466 
   1467  /* Are we configured to fetch descriptors? */
   1468  if (!get_options()->FetchHidServDescriptors) {
   1469    log_warn(LD_REND, "We received an onion address for a hidden service "
   1470                      "descriptor but we are configured to not fetch.");
   1471    status = HS_CLIENT_FETCH_NOT_ALLOWED;
   1472    goto cannot;
   1473  }
   1474 
   1475  /* Without a usable consensus we can't do any client actions. It is needed
   1476   * to compute the hashring for a service. */
   1477  if (!networkstatus_get_reasonably_live_consensus(approx_time(),
   1478                                         usable_consensus_flavor())) {
   1479    log_info(LD_REND, "Can't fetch descriptor for service %s because we "
   1480                      "are missing a live consensus. Stalling connection.",
   1481             safe_str_client(ed25519_fmt(identity_pk)));
   1482    status = HS_CLIENT_FETCH_MISSING_INFO;
   1483    goto cannot;
   1484  }
   1485 
   1486  if (!router_have_minimum_dir_info()) {
   1487    log_info(LD_REND, "Can't fetch descriptor for service %s because we "
   1488                      "dont have enough descriptors. Stalling connection.",
   1489             safe_str_client(ed25519_fmt(identity_pk)));
   1490    status = HS_CLIENT_FETCH_MISSING_INFO;
   1491    goto cannot;
   1492  }
   1493 
   1494  /* Check if fetching a desc for this HS is useful to us right now */
   1495  {
   1496    const hs_descriptor_t *cached_desc = NULL;
   1497    int has_usable_intro = false;
   1498    int has_expired_hs_pow = false;
   1499 
   1500    cached_desc = hs_cache_lookup_as_client(identity_pk);
   1501    if (cached_desc) {
   1502      has_usable_intro = hs_client_any_intro_points_usable(identity_pk,
   1503                                                           cached_desc);
   1504      if (cached_desc->encrypted_data.pow_params) {
   1505        has_expired_hs_pow =
   1506          cached_desc->encrypted_data.pow_params->expiration_time <
   1507          approx_time();
   1508      }
   1509    }
   1510    if (has_usable_intro && !has_expired_hs_pow) {
   1511      log_info(LD_GENERAL, "We would fetch a v3 hidden service descriptor "
   1512                           "but we already have a usable descriptor.");
   1513      status = HS_CLIENT_FETCH_HAVE_DESC;
   1514      goto cannot;
   1515    }
   1516  }
   1517 
   1518  /* Don't try to refetch while we have a pending request for it. */
   1519  if (directory_request_is_pending(identity_pk)) {
   1520    log_info(LD_REND, "Already a pending directory request. Waiting on it.");
   1521    status = HS_CLIENT_FETCH_PENDING;
   1522    goto cannot;
   1523  }
   1524 
   1525  /* Yes, client can fetch! */
   1526  return 1;
   1527 cannot:
   1528  if (status_out) {
   1529    *status_out = status;
   1530  }
   1531  return 0;
   1532 }
   1533 
   1534 /** Purge the client authorization cache of all ephemeral entries that is the
   1535 * entries that are not flagged with CLIENT_AUTH_FLAG_IS_PERMANENT.
   1536 *
   1537 * This is called from the hs_client_purge_state() used by a SIGNEWNYM. */
   1538 STATIC void
   1539 purge_ephemeral_client_auth(void)
   1540 {
   1541  DIGEST256MAP_FOREACH_MODIFY(client_auths, key,
   1542                              hs_client_service_authorization_t *, auth) {
   1543    /* Cleanup every entry that are _NOT_ permanent that is ephemeral. */
   1544    if (!(auth->flags & CLIENT_AUTH_FLAG_IS_PERMANENT)) {
   1545      MAP_DEL_CURRENT(key);
   1546      client_service_authorization_free(auth);
   1547    }
   1548  } DIGESTMAP_FOREACH_END;
   1549 
   1550  log_info(LD_REND, "Client onion service ephemeral authorization "
   1551                    "cache has been purged.");
   1552 }
   1553 
   1554 /** Return the client auth in the map using the service identity public key.
   1555 * Return NULL if it does not exist in the map. */
   1556 static hs_client_service_authorization_t *
   1557 find_client_auth(const ed25519_public_key_t *service_identity_pk)
   1558 {
   1559  /* If the map is not allocated, we can assume that we do not have any client
   1560   * auth information. */
   1561  if (!client_auths) {
   1562    return NULL;
   1563  }
   1564  return digest256map_get(client_auths, service_identity_pk->pubkey);
   1565 }
   1566 
   1567 /** This is called when a descriptor has arrived following a fetch request and
   1568 * has been stored in the client cache. The given entry connections, matching
   1569 * the service identity key, will get attached to the service circuit. */
   1570 static void
   1571 client_desc_has_arrived(const smartlist_t *entry_conns)
   1572 {
   1573  time_t now = time(NULL);
   1574 
   1575  tor_assert(entry_conns);
   1576 
   1577  SMARTLIST_FOREACH_BEGIN(entry_conns, entry_connection_t *, entry_conn) {
   1578    const hs_descriptor_t *desc;
   1579    edge_connection_t *edge_conn = ENTRY_TO_EDGE_CONN(entry_conn);
   1580    const ed25519_public_key_t *identity_pk =
   1581      &edge_conn->hs_ident->identity_pk;
   1582 
   1583    /* We were just called because we stored the descriptor for this service
   1584     * so not finding a descriptor means we have a bigger problem. */
   1585    desc = hs_cache_lookup_as_client(identity_pk);
   1586    if (BUG(desc == NULL)) {
   1587      goto end;
   1588    }
   1589 
   1590    if (!hs_client_any_intro_points_usable(identity_pk, desc)) {
   1591      log_info(LD_REND, "Hidden service descriptor is unusable. "
   1592                        "Closing streams.");
   1593      /* Report the extended socks error code that we were unable to introduce
   1594       * to the service. */
   1595      socks_mark_introduction_failed(entry_conn, identity_pk);
   1596 
   1597      connection_mark_unattached_ap(entry_conn,
   1598                                    END_STREAM_REASON_RESOLVEFAILED);
   1599      /* We are unable to use the descriptor so remove the directory request
   1600       * from the cache so the next connection can try again. */
   1601      note_connection_attempt_succeeded(edge_conn->hs_ident);
   1602      continue;
   1603    }
   1604 
   1605    log_info(LD_REND, "Descriptor has arrived. Launching circuits.");
   1606 
   1607    /* Mark connection as waiting for a circuit since we do have a usable
   1608     * descriptor now. */
   1609    mark_conn_as_waiting_for_circuit(&edge_conn->base_, now);
   1610  } SMARTLIST_FOREACH_END(entry_conn);
   1611 
   1612 end:
   1613  return;
   1614 }
   1615 
   1616 /** This is called when a descriptor fetch was successful but the descriptor
   1617 * couldn't be decrypted due to missing or bad client authorization. */
   1618 static void
   1619 client_desc_missing_bad_client_auth(const smartlist_t *entry_conns,
   1620                                    hs_desc_decode_status_t status)
   1621 {
   1622  tor_assert(entry_conns);
   1623 
   1624  SMARTLIST_FOREACH_BEGIN(entry_conns, entry_connection_t *, entry_conn) {
   1625    socks5_reply_status_t code;
   1626    if (status == HS_DESC_DECODE_BAD_CLIENT_AUTH) {
   1627      code = SOCKS5_HS_BAD_CLIENT_AUTH;
   1628    } else if (status == HS_DESC_DECODE_NEED_CLIENT_AUTH) {
   1629      code = SOCKS5_HS_MISSING_CLIENT_AUTH;
   1630    } else {
   1631      /* We should not be called with another type of status. Recover by
   1632       * sending a generic error. */
   1633      tor_assert_nonfatal_unreached();
   1634      code = SOCKS5_GENERAL_ERROR;
   1635    }
   1636    entry_conn->socks_request->socks_extended_error_code = code;
   1637    connection_mark_unattached_ap(entry_conn, END_STREAM_REASON_MISC);
   1638  } SMARTLIST_FOREACH_END(entry_conn);
   1639 }
   1640 
   1641 /** Called when we get a 200 directory fetch status code. */
   1642 static void
   1643 client_dir_fetch_200(dir_connection_t *dir_conn,
   1644                     const smartlist_t *entry_conns, const char *body)
   1645 {
   1646  hs_desc_decode_status_t decode_status;
   1647 
   1648  tor_assert(dir_conn);
   1649  tor_assert(entry_conns);
   1650  tor_assert(body);
   1651 
   1652  /* We got something: Try storing it in the cache. */
   1653  decode_status = hs_cache_store_as_client(body,
   1654                                           &dir_conn->hs_ident->identity_pk);
   1655  switch (decode_status) {
   1656  case HS_DESC_DECODE_OK:
   1657  case HS_DESC_DECODE_NEED_CLIENT_AUTH:
   1658  case HS_DESC_DECODE_BAD_CLIENT_AUTH:
   1659    log_info(LD_REND, "Stored hidden service descriptor successfully.");
   1660    TO_CONN(dir_conn)->purpose = DIR_PURPOSE_HAS_FETCHED_HSDESC;
   1661    if (decode_status == HS_DESC_DECODE_OK) {
   1662      client_desc_has_arrived(entry_conns);
   1663    } else {
   1664      /* This handles both client auth decode status. */
   1665      client_desc_missing_bad_client_auth(entry_conns, decode_status);
   1666      log_info(LD_REND, "Stored hidden service descriptor requires "
   1667                         "%s client authorization.",
   1668               decode_status == HS_DESC_DECODE_NEED_CLIENT_AUTH ? "missing"
   1669                                                                : "new");
   1670    }
   1671    /* Fire control port RECEIVED event. */
   1672    hs_control_desc_event_received(dir_conn->hs_ident,
   1673                                   dir_conn->identity_digest);
   1674    hs_control_desc_event_content(dir_conn->hs_ident,
   1675                                  dir_conn->identity_digest, body);
   1676    break;
   1677  case HS_DESC_DECODE_ENCRYPTED_ERROR:
   1678  case HS_DESC_DECODE_SUPERENC_ERROR:
   1679  case HS_DESC_DECODE_PLAINTEXT_ERROR:
   1680  case HS_DESC_DECODE_GENERIC_ERROR:
   1681  default:
   1682    log_info(LD_REND, "Failed to store hidden service descriptor. "
   1683                      "Descriptor decoding status: %d", decode_status);
   1684    /* Fire control port FAILED event. */
   1685    hs_control_desc_event_failed(dir_conn->hs_ident,
   1686                                 dir_conn->identity_digest, "BAD_DESC");
   1687    hs_control_desc_event_content(dir_conn->hs_ident,
   1688                                  dir_conn->identity_digest, NULL);
   1689    break;
   1690  }
   1691 }
   1692 
   1693 /** Called when we get a 404 directory fetch status code. */
   1694 static void
   1695 client_dir_fetch_404(dir_connection_t *dir_conn,
   1696                     const smartlist_t *entry_conns)
   1697 {
   1698  tor_assert(entry_conns);
   1699 
   1700  /* Not there. We'll retry when connection_about_to_close_connection() tries
   1701   * to clean this conn up. */
   1702  log_info(LD_REND, "Fetching hidden service v3 descriptor not found: "
   1703                    "Retrying at another directory.");
   1704  /* Fire control port FAILED event. */
   1705  hs_control_desc_event_failed(dir_conn->hs_ident, dir_conn->identity_digest,
   1706                               "NOT_FOUND");
   1707  hs_control_desc_event_content(dir_conn->hs_ident, dir_conn->identity_digest,
   1708                                NULL);
   1709 
   1710  /* Flag every entry connections that the descriptor was not found. */
   1711  SMARTLIST_FOREACH_BEGIN(entry_conns, entry_connection_t *, entry_conn) {
   1712    entry_conn->socks_request->socks_extended_error_code =
   1713      SOCKS5_HS_NOT_FOUND;
   1714  } SMARTLIST_FOREACH_END(entry_conn);
   1715 }
   1716 
   1717 /** Called when we get a 400 directory fetch status code. */
   1718 static void
   1719 client_dir_fetch_400(dir_connection_t *dir_conn, const char *reason)
   1720 {
   1721  tor_assert(dir_conn);
   1722 
   1723  log_warn(LD_REND, "Fetching v3 hidden service descriptor failed: "
   1724                    "http status 400 (%s). Dirserver didn't like our "
   1725                    "query? Retrying at another directory.",
   1726           escaped(reason));
   1727 
   1728  /* Fire control port FAILED event. */
   1729  hs_control_desc_event_failed(dir_conn->hs_ident, dir_conn->identity_digest,
   1730                               "QUERY_REJECTED");
   1731  hs_control_desc_event_content(dir_conn->hs_ident, dir_conn->identity_digest,
   1732                                NULL);
   1733 }
   1734 
   1735 /** Called when we get an unexpected directory fetch status code. */
   1736 static void
   1737 client_dir_fetch_unexpected(dir_connection_t *dir_conn, const char *reason,
   1738                            const int status_code)
   1739 {
   1740  tor_assert(dir_conn);
   1741 
   1742  log_warn(LD_REND, "Fetching v3 hidden service descriptor failed: "
   1743                    "http status %d (%s) response unexpected from HSDir "
   1744                    "server %s'. Retrying at another directory.",
   1745           status_code, escaped(reason),
   1746           connection_describe_peer(TO_CONN(dir_conn)));
   1747  /* Fire control port FAILED event. */
   1748  hs_control_desc_event_failed(dir_conn->hs_ident, dir_conn->identity_digest,
   1749                               "UNEXPECTED");
   1750  hs_control_desc_event_content(dir_conn->hs_ident, dir_conn->identity_digest,
   1751                                NULL);
   1752 }
   1753 
   1754 /** Get the full filename for storing the client auth credentials for the
   1755 *  service in <b>onion_address</b>. The base directory is <b>dir</b>.
   1756 *  This function never returns NULL. */
   1757 static char *
   1758 get_client_auth_creds_filename(const char *onion_address,
   1759                               const char *dir)
   1760 {
   1761  char *full_fname = NULL;
   1762  char *fname;
   1763 
   1764  tor_asprintf(&fname, "%s.auth_private", onion_address);
   1765  full_fname = hs_path_from_filename(dir, fname);
   1766  tor_free(fname);
   1767 
   1768  return full_fname;
   1769 }
   1770 
   1771 /** Permanently store the credentials in <b>creds</b> to disk.
   1772 *
   1773 *  Return -1 if there was an error while storing the credentials, otherwise
   1774 *  return 0.
   1775 */
   1776 static int
   1777 store_permanent_client_auth_credentials(
   1778                              const hs_client_service_authorization_t *creds)
   1779 {
   1780  const or_options_t *options = get_options();
   1781  char *full_fname = NULL;
   1782  char *file_contents = NULL;
   1783  char priv_key_b32[BASE32_NOPAD_LEN(CURVE25519_PUBKEY_LEN)+1];
   1784  int retval = -1;
   1785 
   1786  tor_assert(creds->flags & CLIENT_AUTH_FLAG_IS_PERMANENT);
   1787 
   1788  /* We need ClientOnionAuthDir to be set, otherwise we can't proceed */
   1789  if (!options->ClientOnionAuthDir) {
   1790    log_warn(LD_GENERAL, "Can't register permanent client auth credentials "
   1791             "for %s without ClientOnionAuthDir option. Discarding.",
   1792             creds->onion_address);
   1793    goto err;
   1794  }
   1795 
   1796  /* Make sure the directory exists and is private enough. */
   1797  if (check_private_dir(options->ClientOnionAuthDir, 0, options->User) < 0) {
   1798    goto err;
   1799  }
   1800 
   1801  /* Get filename that we should store the credentials */
   1802  full_fname = get_client_auth_creds_filename(creds->onion_address,
   1803                                              options->ClientOnionAuthDir);
   1804 
   1805  /* Encode client private key */
   1806  base32_encode(priv_key_b32, sizeof(priv_key_b32),
   1807                (char*)creds->enc_seckey.secret_key,
   1808                sizeof(creds->enc_seckey.secret_key));
   1809 
   1810  /* Get the full file contents and write it to disk! */
   1811  tor_asprintf(&file_contents, "%s:descriptor:x25519:%s",
   1812               creds->onion_address, priv_key_b32);
   1813  if (write_str_to_file(full_fname, file_contents, 0) < 0) {
   1814    log_warn(LD_GENERAL, "Failed to write client auth creds file for %s!",
   1815             creds->onion_address);
   1816    goto err;
   1817  }
   1818 
   1819  retval = 0;
   1820 
   1821 err:
   1822  tor_free(file_contents);
   1823  tor_free(full_fname);
   1824 
   1825  return retval;
   1826 }
   1827 
   1828 /** Register the credential <b>creds</b> as part of the client auth subsystem.
   1829 *
   1830 * Takes ownership of <b>creds</b>.
   1831 **/
   1832 hs_client_register_auth_status_t
   1833 hs_client_register_auth_credentials(hs_client_service_authorization_t *creds)
   1834 {
   1835  ed25519_public_key_t service_identity_pk;
   1836  hs_client_service_authorization_t *old_creds = NULL;
   1837  hs_client_register_auth_status_t retval = REGISTER_SUCCESS;
   1838 
   1839  tor_assert(creds);
   1840 
   1841  if (!client_auths) {
   1842    client_auths = digest256map_new();
   1843  }
   1844 
   1845  if (hs_parse_address(creds->onion_address, &service_identity_pk,
   1846                       NULL, NULL) < 0) {
   1847    client_service_authorization_free(creds);
   1848    return REGISTER_FAIL_BAD_ADDRESS;
   1849  }
   1850 
   1851  /* If we reach this point, the credentials will be stored one way or another:
   1852   * Make them permanent if the user asked us to. */
   1853  if (creds->flags & CLIENT_AUTH_FLAG_IS_PERMANENT) {
   1854    if (store_permanent_client_auth_credentials(creds) < 0) {
   1855      client_service_authorization_free(creds);
   1856      return REGISTER_FAIL_PERMANENT_STORAGE;
   1857    }
   1858  }
   1859 
   1860  old_creds = digest256map_get(client_auths, service_identity_pk.pubkey);
   1861  if (old_creds) {
   1862    digest256map_remove(client_auths, service_identity_pk.pubkey);
   1863    client_service_authorization_free(old_creds);
   1864    retval = REGISTER_SUCCESS_ALREADY_EXISTS;
   1865  }
   1866 
   1867  digest256map_set(client_auths, service_identity_pk.pubkey, creds);
   1868 
   1869  /** Now that we set the new credentials, also try to decrypt any cached
   1870   *  descriptors. */
   1871  if (hs_cache_client_new_auth_parse(&service_identity_pk)) {
   1872    retval = REGISTER_SUCCESS_AND_DECRYPTED;
   1873  }
   1874 
   1875  return retval;
   1876 }
   1877 
   1878 /** Load a client authorization file with <b>filename</b> that is stored under
   1879 *  the global client auth directory, and return a newly-allocated credentials
   1880 *  object if it parsed well. Otherwise, return NULL.
   1881 */
   1882 static hs_client_service_authorization_t *
   1883 get_creds_from_client_auth_filename(const char *filename,
   1884                                    const or_options_t *options)
   1885 {
   1886  hs_client_service_authorization_t *auth = NULL;
   1887  char *client_key_file_path = NULL;
   1888  char *client_key_str = NULL;
   1889 
   1890  log_info(LD_REND, "Loading a client authorization key file %s...",
   1891           filename);
   1892 
   1893  if (!auth_key_filename_is_valid(filename)) {
   1894    log_notice(LD_REND, "Client authorization unrecognized filename %s. "
   1895               "File must end in .auth_private. Ignoring.",
   1896               filename);
   1897    goto err;
   1898  }
   1899 
   1900  /* Create a full path for a file. */
   1901  client_key_file_path = hs_path_from_filename(options->ClientOnionAuthDir,
   1902                                               filename);
   1903 
   1904  client_key_str = read_file_to_str(client_key_file_path, 0, NULL);
   1905  if (!client_key_str) {
   1906    log_warn(LD_REND, "The file %s cannot be read.", filename);
   1907    goto err;
   1908  }
   1909 
   1910  auth = parse_auth_file_content(client_key_str);
   1911  if (!auth) {
   1912    goto err;
   1913  }
   1914 
   1915 err:
   1916  tor_free(client_key_str);
   1917  tor_free(client_key_file_path);
   1918 
   1919  return auth;
   1920 }
   1921 
   1922 /*
   1923 * Remove the file in <b>filename</b> under the global client auth credential
   1924 * storage.
   1925 */
   1926 static void
   1927 remove_client_auth_creds_file(const char *filename)
   1928 {
   1929  char *creds_file_path = NULL;
   1930  const or_options_t *options = get_options();
   1931 
   1932  creds_file_path = hs_path_from_filename(options->ClientOnionAuthDir,
   1933                                          filename);
   1934  if (tor_unlink(creds_file_path) != 0) {
   1935    log_warn(LD_REND, "Failed to remove client auth file (%s).",
   1936             creds_file_path);
   1937    goto end;
   1938  }
   1939 
   1940  log_warn(LD_REND, "Successfully removed client auth file (%s).",
   1941           creds_file_path);
   1942 
   1943 end:
   1944  tor_free(creds_file_path);
   1945 }
   1946 
   1947 /**
   1948 * Find the filesystem file corresponding to the permanent client auth
   1949 * credentials in <b>cred</b> and remove it.
   1950 */
   1951 static void
   1952 find_and_remove_client_auth_creds_file(
   1953                                 const hs_client_service_authorization_t *cred)
   1954 {
   1955  smartlist_t *file_list = NULL;
   1956  const or_options_t *options = get_options();
   1957 
   1958  tor_assert(cred->flags & CLIENT_AUTH_FLAG_IS_PERMANENT);
   1959 
   1960  if (!options->ClientOnionAuthDir) {
   1961    log_warn(LD_REND, "Found permanent credential but no ClientOnionAuthDir "
   1962             "configured. There is no file to be removed.");
   1963    goto end;
   1964  }
   1965 
   1966  file_list = tor_listdir(options->ClientOnionAuthDir);
   1967  if (file_list == NULL) {
   1968    log_warn(LD_REND, "Client authorization key directory %s can't be listed.",
   1969             options->ClientOnionAuthDir);
   1970    goto end;
   1971  }
   1972 
   1973  SMARTLIST_FOREACH_BEGIN(file_list, const char *, filename) {
   1974    hs_client_service_authorization_t *tmp_cred = NULL;
   1975 
   1976    tmp_cred = get_creds_from_client_auth_filename(filename, options);
   1977    if (!tmp_cred) {
   1978      continue;
   1979    }
   1980 
   1981    /* Find the right file for this credential */
   1982    if (!strcmp(tmp_cred->onion_address, cred->onion_address)) {
   1983      /* Found it! Remove the file! */
   1984      remove_client_auth_creds_file(filename);
   1985      /* cleanup and get out of here */
   1986      client_service_authorization_free(tmp_cred);
   1987      break;
   1988    }
   1989 
   1990    client_service_authorization_free(tmp_cred);
   1991  } SMARTLIST_FOREACH_END(filename);
   1992 
   1993 end:
   1994  if (file_list) {
   1995    SMARTLIST_FOREACH(file_list, char *, s, tor_free(s));
   1996    smartlist_free(file_list);
   1997  }
   1998 }
   1999 
   2000 /** Remove client auth credentials for the service <b>hs_address</b>. */
   2001 hs_client_removal_auth_status_t
   2002 hs_client_remove_auth_credentials(const char *hsaddress)
   2003 {
   2004  ed25519_public_key_t service_identity_pk;
   2005 
   2006  if (!client_auths) {
   2007    return REMOVAL_SUCCESS_NOT_FOUND;
   2008  }
   2009 
   2010  if (hs_parse_address(hsaddress, &service_identity_pk, NULL, NULL) < 0) {
   2011    return REMOVAL_BAD_ADDRESS;
   2012  }
   2013 
   2014  hs_client_service_authorization_t *cred = NULL;
   2015  cred = digest256map_remove(client_auths, service_identity_pk.pubkey);
   2016 
   2017  /* digestmap_remove() returns the previously stored data if there were any */
   2018  if (cred) {
   2019    if (cred->flags & CLIENT_AUTH_FLAG_IS_PERMANENT) {
   2020      /* These creds are stored on disk: remove the corresponding file. */
   2021      find_and_remove_client_auth_creds_file(cred);
   2022    }
   2023 
   2024    /* Remove associated descriptor if any. */
   2025    hs_cache_remove_as_client(&service_identity_pk);
   2026 
   2027    client_service_authorization_free(cred);
   2028    return REMOVAL_SUCCESS;
   2029  }
   2030 
   2031  return REMOVAL_SUCCESS_NOT_FOUND;
   2032 }
   2033 
   2034 /** Get the HS client auth map. */
   2035 digest256map_t *
   2036 get_hs_client_auths_map(void)
   2037 {
   2038  return client_auths;
   2039 }
   2040 
   2041 /* ========== */
   2042 /* Public API */
   2043 /* ========== */
   2044 
   2045 /** Called when a circuit was just cleaned up. This is done right before the
   2046 * circuit is marked for close. */
   2047 void
   2048 hs_client_circuit_cleanup_on_close(const circuit_t *circ)
   2049 {
   2050  bool has_timed_out;
   2051 
   2052  tor_assert(circ);
   2053  tor_assert(CIRCUIT_IS_ORIGIN(circ));
   2054 
   2055  has_timed_out =
   2056    (circ->marked_for_close_orig_reason == END_CIRC_REASON_TIMEOUT);
   2057 
   2058  switch (circ->purpose) {
   2059  case CIRCUIT_PURPOSE_C_ESTABLISH_REND:
   2060  case CIRCUIT_PURPOSE_C_REND_READY:
   2061  case CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED:
   2062  case CIRCUIT_PURPOSE_C_REND_JOINED:
   2063    /* Report extended SOCKS error code when a rendezvous circuit times out.
   2064     * This MUST be done on_close() because it is possible the entry
   2065     * connection would get closed before the circuit is freed and thus
   2066     * would fail to report the error code. */
   2067    if (has_timed_out) {
   2068      socks_mark_rend_circuit_timed_out(CONST_TO_ORIGIN_CIRCUIT(circ));
   2069    }
   2070    break;
   2071  default:
   2072    break;
   2073  }
   2074 }
   2075 
   2076 /** Called when a circuit was just cleaned up. This is done right before the
   2077 * circuit is freed. */
   2078 void
   2079 hs_client_circuit_cleanup_on_free(const circuit_t *circ)
   2080 {
   2081  bool has_timed_out;
   2082  rend_intro_point_failure_t failure = INTRO_POINT_FAILURE_UNREACHABLE;
   2083  const origin_circuit_t *orig_circ = NULL;
   2084 
   2085  tor_assert(circ);
   2086  tor_assert(CIRCUIT_IS_ORIGIN(circ));
   2087 
   2088  orig_circ = CONST_TO_ORIGIN_CIRCUIT(circ);
   2089  tor_assert(orig_circ->hs_ident);
   2090  const ed25519_public_key_t *intro_pk = &orig_circ->hs_ident->intro_auth_pk;
   2091 
   2092  has_timed_out =
   2093    (circ->marked_for_close_orig_reason == END_CIRC_REASON_TIMEOUT);
   2094  if (has_timed_out) {
   2095    failure = INTRO_POINT_FAILURE_TIMEOUT;
   2096  }
   2097 
   2098  switch (circ->purpose) {
   2099  case CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT:
   2100    log_info(LD_REND, "Failed v3 intro circ for service %s to intro point %s "
   2101                      "(awaiting ACK). Failure code: %d",
   2102        safe_str_client(ed25519_fmt(&orig_circ->hs_ident->identity_pk)),
   2103        safe_str_client(build_state_get_exit_nickname(orig_circ->build_state)),
   2104        failure);
   2105    tor_assert_nonfatal(!ed25519_public_key_is_zero(intro_pk));
   2106    hs_cache_client_intro_state_note(&orig_circ->hs_ident->identity_pk,
   2107                                     intro_pk, failure);
   2108    break;
   2109  case CIRCUIT_PURPOSE_C_INTRODUCING:
   2110    if (has_timed_out || !orig_circ->build_state) {
   2111      break;
   2112    }
   2113    tor_assert_nonfatal(!ed25519_public_key_is_zero(intro_pk));
   2114    failure = INTRO_POINT_FAILURE_UNREACHABLE;
   2115    log_info(LD_REND, "Failed v3 intro circ for service %s to intro point %s "
   2116                      "(while building circuit). Marking as unreachable.",
   2117       safe_str_client(ed25519_fmt(&orig_circ->hs_ident->identity_pk)),
   2118       safe_str_client(build_state_get_exit_nickname(orig_circ->build_state)));
   2119    hs_cache_client_intro_state_note(&orig_circ->hs_ident->identity_pk,
   2120                                     intro_pk, failure);
   2121    break;
   2122  default:
   2123    break;
   2124  }
   2125 }
   2126 
   2127 /** A circuit just finished connecting to a hidden service that the stream
   2128 *  <b>conn</b> has been waiting for. Let the HS subsystem know about this. */
   2129 void
   2130 hs_client_note_connection_attempt_succeeded(const edge_connection_t *conn)
   2131 {
   2132  tor_assert(connection_edge_is_rendezvous_stream(conn));
   2133 
   2134  if (conn->hs_ident) { /* It's v3: pass it to the prop224 handler */
   2135    note_connection_attempt_succeeded(conn->hs_ident);
   2136    return;
   2137  }
   2138 }
   2139 
   2140 /** With the given encoded descriptor in desc_str and the service key in
   2141 * service_identity_pk, decode the descriptor and set the desc pointer with a
   2142 * newly allocated descriptor object.
   2143 *
   2144 * On success, HS_DESC_DECODE_OK is returned and desc is set to the decoded
   2145 * descriptor. On error, desc is set to NULL and a decoding error status is
   2146 * returned depending on what was the issue. */
   2147 hs_desc_decode_status_t
   2148 hs_client_decode_descriptor(const char *desc_str,
   2149                            const ed25519_public_key_t *service_identity_pk,
   2150                            hs_descriptor_t **desc)
   2151 {
   2152  hs_desc_decode_status_t ret;
   2153  hs_subcredential_t subcredential;
   2154  ed25519_public_key_t blinded_pubkey;
   2155  hs_client_service_authorization_t *client_auth = NULL;
   2156  curve25519_secret_key_t *client_auth_sk = NULL;
   2157 
   2158  tor_assert(desc_str);
   2159  tor_assert(service_identity_pk);
   2160  tor_assert(desc);
   2161 
   2162  /* Check if we have a client authorization for this service in the map. */
   2163  client_auth = find_client_auth(service_identity_pk);
   2164  if (client_auth) {
   2165    client_auth_sk = &client_auth->enc_seckey;
   2166  }
   2167 
   2168  /* Create subcredential for this HS so that we can decrypt */
   2169  {
   2170    uint64_t current_time_period = hs_get_time_period_num(0);
   2171    hs_build_blinded_pubkey(service_identity_pk, NULL, 0, current_time_period,
   2172                            &blinded_pubkey);
   2173    hs_get_subcredential(service_identity_pk, &blinded_pubkey, &subcredential);
   2174  }
   2175 
   2176  /* Parse descriptor */
   2177  ret = hs_desc_decode_descriptor(desc_str, &subcredential,
   2178                                  client_auth_sk, desc);
   2179  memwipe(&subcredential, 0, sizeof(subcredential));
   2180  if (ret != HS_DESC_DECODE_OK) {
   2181    goto err;
   2182  }
   2183 
   2184  /* Make sure the descriptor signing key cross certifies with the computed
   2185   * blinded key. Without this validation, anyone knowing the subcredential
   2186   * and onion address can forge a descriptor. */
   2187  tor_cert_t *cert = (*desc)->plaintext_data.signing_key_cert;
   2188  if (tor_cert_checksig(cert,
   2189                        &blinded_pubkey, approx_time()) < 0) {
   2190    log_warn(LD_GENERAL, "Descriptor signing key certificate signature "
   2191             "doesn't validate with computed blinded key: %s",
   2192             tor_cert_describe_signature_status(cert));
   2193    ret = HS_DESC_DECODE_GENERIC_ERROR;
   2194    goto err;
   2195  }
   2196 
   2197  return HS_DESC_DECODE_OK;
   2198 err:
   2199  return ret;
   2200 }
   2201 
   2202 /** Return true iff there are at least one usable intro point in the service
   2203 * descriptor desc. */
   2204 int
   2205 hs_client_any_intro_points_usable(const ed25519_public_key_t *service_pk,
   2206                                  const hs_descriptor_t *desc)
   2207 {
   2208  tor_assert(service_pk);
   2209  tor_assert(desc);
   2210 
   2211  SMARTLIST_FOREACH_BEGIN(desc->encrypted_data.intro_points,
   2212                          const hs_desc_intro_point_t *, ip) {
   2213    if (intro_point_is_usable(service_pk, ip)) {
   2214      goto usable;
   2215    }
   2216  } SMARTLIST_FOREACH_END(ip);
   2217 
   2218  return 0;
   2219 usable:
   2220  return 1;
   2221 }
   2222 
   2223 /** Launch a connection to a hidden service directory to fetch a hidden
   2224 * service descriptor using <b>identity_pk</b> to get the necessary keys.
   2225 *
   2226 * A hs_client_fetch_status_t code is returned. */
   2227 int
   2228 hs_client_refetch_hsdesc(const ed25519_public_key_t *identity_pk)
   2229 {
   2230  hs_client_fetch_status_t status;
   2231 
   2232  tor_assert(identity_pk);
   2233 
   2234  if (!can_client_refetch_desc(identity_pk, &status)) {
   2235    return status;
   2236  }
   2237 
   2238  /* Try to fetch the desc and if we encounter an unrecoverable error, mark
   2239   * the desc as unavailable for now. */
   2240  status = fetch_v3_desc(identity_pk);
   2241  if (fetch_status_should_close_socks(status)) {
   2242    close_all_socks_conns_waiting_for_desc(identity_pk, status,
   2243                                           END_STREAM_REASON_RESOLVEFAILED);
   2244    /* Remove HSDir fetch attempts so that we can retry later if the user
   2245     * wants us to regardless of if we closed any connections. */
   2246    purge_hid_serv_request(identity_pk);
   2247  }
   2248  return status;
   2249 }
   2250 
   2251 /** This is called when we are trying to attach an AP connection to these
   2252 * hidden service circuits from connection_ap_handshake_attach_circuit().
   2253 * Return 0 on success, -1 for a transient error that is actions were
   2254 * triggered to recover or -2 for a permenent error where both circuits will
   2255 * marked for close.
   2256 *
   2257 * The following supports every hidden service version. */
   2258 int
   2259 hs_client_send_introduce1(origin_circuit_t *intro_circ,
   2260                          origin_circuit_t *rend_circ)
   2261 {
   2262  return consider_sending_introduce1(intro_circ, rend_circ);
   2263 }
   2264 
   2265 /** Called when the client circuit circ has been established. It can be either
   2266 * an introduction or rendezvous circuit. This function handles all hidden
   2267 * service versions. */
   2268 void
   2269 hs_client_circuit_has_opened(origin_circuit_t *circ)
   2270 {
   2271  tor_assert(circ);
   2272 
   2273  switch (TO_CIRCUIT(circ)->purpose) {
   2274  case CIRCUIT_PURPOSE_C_INTRODUCING:
   2275    if (circ->hs_ident) {
   2276      client_intro_circ_has_opened(circ);
   2277    }
   2278    break;
   2279  case CIRCUIT_PURPOSE_C_ESTABLISH_REND:
   2280    if (circ->hs_ident) {
   2281      client_rendezvous_circ_has_opened(circ);
   2282    }
   2283    break;
   2284  default:
   2285    tor_assert_nonfatal_unreached();
   2286  }
   2287 }
   2288 
   2289 /** Called when we receive a RENDEZVOUS_ESTABLISHED cell. Change the state of
   2290 * the circuit to CIRCUIT_PURPOSE_C_REND_READY. Return 0 on success else a
   2291 * negative value and the circuit marked for close. */
   2292 int
   2293 hs_client_receive_rendezvous_acked(origin_circuit_t *circ,
   2294                                   const uint8_t *payload, size_t payload_len)
   2295 {
   2296  tor_assert(circ);
   2297  tor_assert(payload);
   2298 
   2299  (void) payload_len;
   2300 
   2301  if (TO_CIRCUIT(circ)->purpose != CIRCUIT_PURPOSE_C_ESTABLISH_REND) {
   2302    log_warn(LD_PROTOCOL, "Got a RENDEZVOUS_ESTABLISHED but we were not "
   2303                          "expecting one. Closing circuit.");
   2304    goto err;
   2305  }
   2306 
   2307  log_info(LD_REND, "Received an RENDEZVOUS_ESTABLISHED. This circuit is "
   2308                    "now ready for rendezvous.");
   2309  circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_C_REND_READY);
   2310 
   2311  /* Set timestamp_dirty, because circuit_expire_building expects it to
   2312   * specify when a circuit entered the _C_REND_READY state. */
   2313  TO_CIRCUIT(circ)->timestamp_dirty = time(NULL);
   2314 
   2315  /* From a path bias point of view, this circuit is now successfully used.
   2316   * Waiting any longer opens us up to attacks from malicious hidden services.
   2317   * They could induce the client to attempt to connect to their hidden
   2318   * service and never reply to the client's rend requests */
   2319  pathbias_mark_use_success(circ);
   2320 
   2321  /* If we already have the introduction circuit built, make sure we send
   2322   * the INTRODUCE cell _now_ */
   2323  connection_ap_attach_pending(1);
   2324 
   2325  return 0;
   2326 err:
   2327  circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_TORPROTOCOL);
   2328  return -1;
   2329 }
   2330 
   2331 void
   2332 client_service_authorization_free_(hs_client_service_authorization_t *auth)
   2333 {
   2334  if (!auth) {
   2335    return;
   2336  }
   2337 
   2338  tor_free(auth->client_name);
   2339 
   2340  memwipe(auth, 0, sizeof(*auth));
   2341  tor_free(auth);
   2342 }
   2343 
   2344 /** Helper for digest256map_free. */
   2345 static void
   2346 client_service_authorization_free_void(void *auth)
   2347 {
   2348  client_service_authorization_free_(auth);
   2349 }
   2350 
   2351 static void
   2352 client_service_authorization_free_all(void)
   2353 {
   2354  if (!client_auths) {
   2355    return;
   2356  }
   2357  digest256map_free(client_auths, client_service_authorization_free_void);
   2358 }
   2359 
   2360 /** Check if the auth key file name is valid or not. Return 1 if valid,
   2361 * otherwise return 0. */
   2362 STATIC int
   2363 auth_key_filename_is_valid(const char *filename)
   2364 {
   2365  int ret = 1;
   2366  const char *valid_extension = ".auth_private";
   2367 
   2368  tor_assert(filename);
   2369 
   2370  /* The length of the filename must be greater than the length of the
   2371   * extension and the valid extension must be at the end of filename. */
   2372  if (!strcmpend(filename, valid_extension) &&
   2373      strlen(filename) != strlen(valid_extension)) {
   2374    ret = 1;
   2375  } else {
   2376    ret = 0;
   2377  }
   2378 
   2379  return ret;
   2380 }
   2381 
   2382 /** Parse the client auth credentials off a string in <b>client_key_str</b>
   2383 *  based on the file format documented in the "Client side configuration"
   2384 *  section of rend-spec-v3.txt.
   2385 *
   2386 *  Return NULL if there was an error, otherwise return a newly allocated
   2387 *  hs_client_service_authorization_t structure.
   2388 */
   2389 STATIC hs_client_service_authorization_t *
   2390 parse_auth_file_content(const char *client_key_str)
   2391 {
   2392  char *onion_address = NULL;
   2393  char *auth_type = NULL;
   2394  char *key_type = NULL;
   2395  char *seckey_b32 = NULL;
   2396  hs_client_service_authorization_t *auth = NULL;
   2397  smartlist_t *fields = smartlist_new();
   2398 
   2399  tor_assert(client_key_str);
   2400 
   2401  smartlist_split_string(fields, client_key_str, ":",
   2402                         SPLIT_SKIP_SPACE, 0);
   2403  /* Wrong number of fields. */
   2404  if (smartlist_len(fields) != 4) {
   2405    goto err;
   2406  }
   2407 
   2408  onion_address = smartlist_get(fields, 0);
   2409  auth_type = smartlist_get(fields, 1);
   2410  key_type = smartlist_get(fields, 2);
   2411  seckey_b32 = smartlist_get(fields, 3);
   2412 
   2413  /* Currently, the only supported auth type is "descriptor" and the only
   2414   * supported key type is "x25519". */
   2415  if (strcmp(auth_type, "descriptor") || strcmp(key_type, "x25519")) {
   2416    goto err;
   2417  }
   2418 
   2419  if (strlen(seckey_b32) != BASE32_NOPAD_LEN(CURVE25519_SECKEY_LEN)) {
   2420    log_warn(LD_REND, "Client authorization encoded base32 private key "
   2421                      "length is invalid: %s", seckey_b32);
   2422    goto err;
   2423  }
   2424 
   2425  auth = tor_malloc_zero(sizeof(hs_client_service_authorization_t));
   2426  if (base32_decode((char *) auth->enc_seckey.secret_key,
   2427                    sizeof(auth->enc_seckey.secret_key),
   2428                    seckey_b32, strlen(seckey_b32)) !=
   2429      sizeof(auth->enc_seckey.secret_key)) {
   2430    log_warn(LD_REND, "Client authorization encoded base32 private key "
   2431                      "can't be decoded: %s", seckey_b32);
   2432    goto err;
   2433  }
   2434 
   2435  if (fast_mem_is_zero((const char*)auth->enc_seckey.secret_key,
   2436                       sizeof(auth->enc_seckey.secret_key))) {
   2437    log_warn(LD_REND, "Client authorization private key can't be all-zeroes");
   2438    goto err;
   2439  }
   2440 
   2441  strncpy(auth->onion_address, onion_address, HS_SERVICE_ADDR_LEN_BASE32);
   2442 
   2443  /* We are reading this from the disk, so set the permanent flag anyway. */
   2444  auth->flags |= CLIENT_AUTH_FLAG_IS_PERMANENT;
   2445 
   2446  /* Success. */
   2447  goto done;
   2448 
   2449 err:
   2450  client_service_authorization_free(auth);
   2451 done:
   2452  /* It is also a good idea to wipe the private key. */
   2453  if (seckey_b32) {
   2454    memwipe(seckey_b32, 0, strlen(seckey_b32));
   2455  }
   2456  tor_assert(fields);
   2457  SMARTLIST_FOREACH(fields, char *, s, tor_free(s));
   2458  smartlist_free(fields);
   2459  return auth;
   2460 }
   2461 
   2462 /** From a set of <b>options</b>, setup every client authorization detail
   2463 * found. Return 0 on success or -1 on failure. If <b>validate_only</b>
   2464 * is set, parse, warn and return as normal, but don't actually change
   2465 * the configuration. */
   2466 int
   2467 hs_config_client_authorization(const or_options_t *options,
   2468                               int validate_only)
   2469 {
   2470  int ret = -1;
   2471  digest256map_t *auths = digest256map_new();
   2472  smartlist_t *file_list = NULL;
   2473 
   2474  tor_assert(options);
   2475 
   2476  /* There is no client auth configured. We can just silently ignore this
   2477   * function. */
   2478  if (!options->ClientOnionAuthDir) {
   2479    ret = 0;
   2480    goto end;
   2481  }
   2482 
   2483  /* Make sure the directory exists and is private enough. */
   2484  if (check_private_dir(options->ClientOnionAuthDir, 0, options->User) < 0) {
   2485    goto end;
   2486  }
   2487 
   2488  file_list = tor_listdir(options->ClientOnionAuthDir);
   2489  if (file_list == NULL) {
   2490    log_warn(LD_REND, "Client authorization key directory %s can't be listed.",
   2491             options->ClientOnionAuthDir);
   2492    goto end;
   2493  }
   2494 
   2495  SMARTLIST_FOREACH_BEGIN(file_list, const char *, filename) {
   2496    hs_client_service_authorization_t *auth = NULL;
   2497    ed25519_public_key_t identity_pk;
   2498 
   2499    auth = get_creds_from_client_auth_filename(filename, options);
   2500    if (!auth) {
   2501      continue;
   2502    }
   2503 
   2504    /* Parse the onion address to get an identity public key and use it
   2505     * as a key of global map in the future. */
   2506    if (hs_parse_address(auth->onion_address, &identity_pk,
   2507                         NULL, NULL) < 0) {
   2508      log_warn(LD_REND, "The onion address \"%s\" is invalid in "
   2509               "file %s", filename, auth->onion_address);
   2510      client_service_authorization_free(auth);
   2511      continue;
   2512    }
   2513 
   2514    if (digest256map_get(auths, identity_pk.pubkey)) {
   2515        log_warn(LD_REND, "Duplicate authorization for the same hidden "
   2516                 "service address %s.",
   2517                 safe_str_client_opts(options, auth->onion_address));
   2518        client_service_authorization_free(auth);
   2519        goto end;
   2520    }
   2521 
   2522    digest256map_set(auths, identity_pk.pubkey, auth);
   2523    log_info(LD_REND, "Loaded a client authorization key file %s.",
   2524             filename);
   2525  } SMARTLIST_FOREACH_END(filename);
   2526 
   2527  /* Success. */
   2528  ret = 0;
   2529 
   2530 end:
   2531  if (file_list) {
   2532    SMARTLIST_FOREACH(file_list, char *, s, tor_free(s));
   2533    smartlist_free(file_list);
   2534  }
   2535 
   2536  if (!validate_only && ret == 0) {
   2537    client_service_authorization_free_all();
   2538    client_auths = auths;
   2539  } else {
   2540    digest256map_free(auths, client_service_authorization_free_void);
   2541  }
   2542 
   2543  return ret;
   2544 }
   2545 
   2546 /** Called when a descriptor directory fetch is done.
   2547 *
   2548 * Act accordingly on all entry connections depending on the HTTP status code
   2549 * we got. In case of an error, the SOCKS error is set (if ExtendedErrors is
   2550 * set).
   2551 *
   2552 * The reason is a human readable string returned by the directory server
   2553 * which can describe the status of the request. The body is the response
   2554 * content, on 200 code it is the descriptor itself. Finally, the status_code
   2555 * is the HTTP code returned by the directory server. */
   2556 void
   2557 hs_client_dir_fetch_done(dir_connection_t *dir_conn, const char *reason,
   2558                         const char *body, const int status_code)
   2559 {
   2560  smartlist_t *entry_conns;
   2561 
   2562  tor_assert(dir_conn);
   2563  tor_assert(body);
   2564 
   2565  /* Get all related entry connections. */
   2566  entry_conns = find_entry_conns(&dir_conn->hs_ident->identity_pk);
   2567 
   2568  switch (status_code) {
   2569  case 200:
   2570    client_dir_fetch_200(dir_conn, entry_conns, body);
   2571    break;
   2572  case 404:
   2573    client_dir_fetch_404(dir_conn, entry_conns);
   2574    break;
   2575  case 400:
   2576    client_dir_fetch_400(dir_conn, reason);
   2577    break;
   2578  default:
   2579    client_dir_fetch_unexpected(dir_conn, reason, status_code);
   2580    break;
   2581  }
   2582 
   2583  /* We don't have ownership of the objects in this list. */
   2584  smartlist_free(entry_conns);
   2585 }
   2586 
   2587 /** Return a newly allocated extend_info_t for a randomly chosen introduction
   2588 * point for the given edge connection identifier ident. Return NULL if we
   2589 * can't pick any usable introduction points. */
   2590 extend_info_t *
   2591 hs_client_get_random_intro_from_edge(const edge_connection_t *edge_conn)
   2592 {
   2593  tor_assert(edge_conn);
   2594 
   2595  return client_get_random_intro(&edge_conn->hs_ident->identity_pk);
   2596 }
   2597 
   2598 /** Called when get an INTRODUCE_ACK cell on the introduction circuit circ.
   2599 * Return 0 on success else a negative value is returned. The circuit will be
   2600 * closed or reuse to extend again to another intro point. */
   2601 int
   2602 hs_client_receive_introduce_ack(origin_circuit_t *circ,
   2603                                const uint8_t *payload, size_t payload_len)
   2604 {
   2605  int ret = -1;
   2606 
   2607  tor_assert(circ);
   2608  tor_assert(payload);
   2609 
   2610  if (TO_CIRCUIT(circ)->purpose != CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT) {
   2611    log_warn(LD_PROTOCOL, "Unexpected INTRODUCE_ACK on circuit %u.",
   2612             (unsigned int) TO_CIRCUIT(circ)->n_circ_id);
   2613    circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_TORPROTOCOL);
   2614    goto end;
   2615  }
   2616 
   2617  ret = handle_introduce_ack(circ, payload, payload_len);
   2618  /* For path bias: This circuit was used successfully. NACK or ACK counts. */
   2619  pathbias_mark_use_success(circ);
   2620 
   2621 end:
   2622  return ret;
   2623 }
   2624 
   2625 /** Called when get a RENDEZVOUS2 cell on the rendezvous circuit circ.  Return
   2626 * 0 on success else a negative value is returned. The circuit will be closed
   2627 * on error. */
   2628 int
   2629 hs_client_receive_rendezvous2(origin_circuit_t *circ,
   2630                              const uint8_t *payload, size_t payload_len)
   2631 {
   2632  int ret = -1;
   2633 
   2634  tor_assert(circ);
   2635  tor_assert(payload);
   2636 
   2637  /* Circuit can possibly be in both state because we could receive a
   2638   * RENDEZVOUS2 cell before the INTRODUCE_ACK has been received. */
   2639  if (TO_CIRCUIT(circ)->purpose != CIRCUIT_PURPOSE_C_REND_READY &&
   2640      TO_CIRCUIT(circ)->purpose != CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED) {
   2641    log_warn(LD_PROTOCOL, "Unexpected RENDEZVOUS2 cell on circuit %u. "
   2642                          "Closing circuit.",
   2643             (unsigned int) TO_CIRCUIT(circ)->n_circ_id);
   2644    circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_TORPROTOCOL);
   2645    goto end;
   2646  }
   2647 
   2648  log_info(LD_REND, "Got RENDEZVOUS2 cell from hidden service on circuit %u.",
   2649           TO_CIRCUIT(circ)->n_circ_id);
   2650 
   2651  ret = handle_rendezvous2(circ, payload, payload_len);
   2652 
   2653 end:
   2654  return ret;
   2655 }
   2656 
   2657 /** Extend the introduction circuit circ to another valid introduction point
   2658 * for the hidden service it is trying to connect to, or mark it and launch a
   2659 * new circuit if we can't extend it.  Return 0 on success or possible
   2660 * success. Return -1 and mark the introduction circuit for close on permanent
   2661 * failure.
   2662 *
   2663 * On failure, the caller is responsible for marking the associated rendezvous
   2664 * circuit for close. */
   2665 int
   2666 hs_client_reextend_intro_circuit(origin_circuit_t *circ)
   2667 {
   2668  int ret = -1;
   2669  extend_info_t *ei;
   2670 
   2671  tor_assert(circ);
   2672 
   2673  ei = client_get_random_intro(&circ->hs_ident->identity_pk);
   2674  if (ei == NULL) {
   2675    log_warn(LD_REND, "No usable introduction points left. Closing.");
   2676    circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL);
   2677    goto end;
   2678  }
   2679 
   2680  if (circ->remaining_relay_early_cells) {
   2681    log_info(LD_REND, "Re-extending circ %u, this time to %s.",
   2682             (unsigned int) TO_CIRCUIT(circ)->n_circ_id,
   2683             safe_str_client(extend_info_describe(ei)));
   2684    ret = circuit_extend_to_new_exit(circ, ei);
   2685    if (ret == 0) {
   2686      /* We were able to extend so update the timestamp so we avoid expiring
   2687       * this circuit too early. The intro circuit is short live so the
   2688       * linkability issue is minimized, we just need the circuit to hold a
   2689       * bit longer so we can introduce. */
   2690      TO_CIRCUIT(circ)->timestamp_dirty = time(NULL);
   2691    }
   2692  } else {
   2693    log_info(LD_REND, "Closing intro circ %u (out of RELAY_EARLY cells).",
   2694             (unsigned int) TO_CIRCUIT(circ)->n_circ_id);
   2695    circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_FINISHED);
   2696    /* connection_ap_handshake_attach_circuit will launch a new intro circ. */
   2697    ret = 0;
   2698  }
   2699 
   2700 end:
   2701  extend_info_free(ei);
   2702  return ret;
   2703 }
   2704 
   2705 /** Close all client introduction circuits related to the given descriptor.
   2706 * This is called with a descriptor that is about to get replaced in the
   2707 * client cache.
   2708 *
   2709 * Even though the introduction point might be exactly the same, we'll rebuild
   2710 * them if needed but the odds are very low that an existing matching
   2711 * introduction circuit exists at that stage. */
   2712 void
   2713 hs_client_close_intro_circuits_from_desc(const hs_descriptor_t *desc)
   2714 {
   2715  origin_circuit_t *ocirc = NULL;
   2716 
   2717  tor_assert(desc);
   2718 
   2719  /* We iterate over all client intro circuits because they aren't kept in the
   2720   * HS circuitmap. That is probably something we want to do one day. */
   2721  while ((ocirc = circuit_get_next_intro_circ(ocirc, true))) {
   2722    if (ocirc->hs_ident == NULL) {
   2723      /* Not a v3 circuit, ignore it. */
   2724      continue;
   2725    }
   2726 
   2727    /* Does it match any IP in the given descriptor? If not, ignore. */
   2728    if (find_desc_intro_point_by_ident(ocirc->hs_ident, desc) == NULL) {
   2729      continue;
   2730    }
   2731 
   2732    /* We have a match. Close the circuit as consider it expired. */
   2733    circuit_mark_for_close(TO_CIRCUIT(ocirc), END_CIRC_REASON_FINISHED);
   2734  }
   2735 }
   2736 
   2737 /** Release all the storage held by the client subsystem. */
   2738 void
   2739 hs_client_free_all(void)
   2740 {
   2741  /* Purge the hidden service request cache. */
   2742  hs_purge_last_hid_serv_requests();
   2743  client_service_authorization_free_all();
   2744 
   2745  /* This is NULL safe. */
   2746  mainloop_event_free(dir_info_changed_ev);
   2747 }
   2748 
   2749 /** Purge all potentially remotely-detectable state held in the hidden
   2750 * service client code. Called on SIGNAL NEWNYM. */
   2751 void
   2752 hs_client_purge_state(void)
   2753 {
   2754  /* Cancel all descriptor fetches. Do this first so once done we are sure
   2755   * that our descriptor cache won't modified. */
   2756  cancel_descriptor_fetches();
   2757  /* Purge the introduction point state cache. */
   2758  hs_cache_client_intro_state_purge();
   2759  /* Purge the descriptor cache. */
   2760  hs_cache_purge_as_client();
   2761  /* Purge the last hidden service request cache. */
   2762  hs_purge_last_hid_serv_requests();
   2763  /* Purge ephemeral client authorization. */
   2764  purge_ephemeral_client_auth();
   2765 
   2766  log_info(LD_REND, "Hidden service client state has been purged.");
   2767 }
   2768 
   2769 /** Called when our directory information has changed.
   2770 *
   2771 * The work done in that function has to either be kept within the HS subsystem
   2772 * or else scheduled as a mainloop event. In other words, this function can't
   2773 * call outside to another subsystem to avoid risking recursion problems. */
   2774 void
   2775 hs_client_dir_info_changed(void)
   2776 {
   2777  /* Make sure the mainloop has been initialized. Code path exist that reaches
   2778   * this before it is. */
   2779  if (!tor_libevent_is_initialized()) {
   2780    return;
   2781  }
   2782 
   2783  /* Lazily create the event. HS Client subsystem doesn't have an init function
   2784   * and so we do it here before activating it. */
   2785  if (!dir_info_changed_ev) {
   2786    dir_info_changed_ev = mainloop_event_new(dir_info_changed_callback, NULL);
   2787  }
   2788  /* Activate it to run immediately. */
   2789  mainloop_event_activate(dir_info_changed_ev);
   2790 }
   2791 
   2792 #ifdef TOR_UNIT_TESTS
   2793 
   2794 STATIC void
   2795 set_hs_client_auths_map(digest256map_t *map)
   2796 {
   2797  client_auths = map;
   2798 }
   2799 
   2800 #endif /* defined(TOR_UNIT_TESTS) */