Tor  0.4.3.0-alpha-dev
Macros | Functions | Variables
hs_client.c File Reference

Implement next generation hidden service client functionality. More...

#include "core/or/or.h"
#include "app/config/config.h"
#include "core/crypto/hs_ntor.h"
#include "core/mainloop/connection.h"
#include "core/or/circuitbuild.h"
#include "core/or/circuitlist.h"
#include "core/or/circuituse.h"
#include "core/or/connection_edge.h"
#include "core/or/reasons.h"
#include "feature/client/circpathbias.h"
#include "feature/dirclient/dirclient.h"
#include "feature/dircommon/directory.h"
#include "feature/hs/hs_cache.h"
#include "feature/hs/hs_cell.h"
#include "feature/hs/hs_circuit.h"
#include "feature/hs/hs_circuitmap.h"
#include "feature/hs/hs_client.h"
#include "feature/hs/hs_control.h"
#include "feature/hs/hs_descriptor.h"
#include "feature/hs/hs_ident.h"
#include "feature/nodelist/describe.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/nodelist.h"
#include "feature/nodelist/routerset.h"
#include "feature/rend/rendclient.h"
#include "lib/crypt_ops/crypto_format.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "lib/crypt_ops/crypto_util.h"
#include "core/or/cpath_build_state_st.h"
#include "feature/dircommon/dir_connection_st.h"
#include "core/or/entry_connection_st.h"
#include "core/or/extend_info_st.h"
#include "core/or/origin_circuit_st.h"
#include "trunnel/hs/cell_introduce1.h"

Go to the source code of this file.

Macros

#define HS_CLIENT_PRIVATE
 
#define client_service_authorization_free(auth)
 

Functions

static const char * fetch_status_to_string (hs_client_fetch_status_t status)
 
static int fetch_status_should_close_socks (hs_client_fetch_status_t status)
 
static void cancel_descriptor_fetches (void)
 
static void flag_all_conn_wait_desc (const ed25519_public_key_t *service_identity_pk)
 
static void purge_hid_serv_request (const ed25519_public_key_t *identity_pk)
 
static int directory_request_is_pending (const ed25519_public_key_t *identity_pk)
 
static void mark_conn_as_waiting_for_circuit (connection_t *conn, time_t now)
 
static void close_all_socks_conns_waiting_for_desc (const ed25519_public_key_t *identity_pk, hs_client_fetch_status_t status, int reason)
 
STATIC void retry_all_socks_conn_waiting_for_desc (void)
 
static void note_connection_attempt_succeeded (const hs_ident_edge_conn_t *hs_conn_ident)
 
static hs_client_fetch_status_t directory_launch_v3_desc_fetch (const ed25519_public_key_t *onion_identity_pk, const routerstatus_t *hsdir)
 
STATIC routerstatus_tpick_hsdir_v3 (const ed25519_public_key_t *onion_identity_pk)
 
STATIC hs_client_fetch_status_t fetch_v3_desc (const ed25519_public_key_t *onion_identity_pk)
 
void hs_client_launch_v3_desc_fetch (const ed25519_public_key_t *onion_identity_pk, const smartlist_t *hsdirs)
 
static int intro_circ_is_ok (const origin_circuit_t *circ)
 
static const hs_desc_intro_point_tfind_desc_intro_point_by_ident (const hs_ident_circuit_t *ident, const hs_descriptor_t *desc)
 
static hs_desc_intro_point_tfind_desc_intro_point_by_legacy_id (const char *legacy_id, const hs_descriptor_t *desc)
 
static int send_introduce1 (origin_circuit_t *intro_circ, origin_circuit_t *rend_circ)
 
static void setup_intro_circ_auth_key (origin_circuit_t *circ)
 
static void client_intro_circ_has_opened (origin_circuit_t *circ)
 
static void client_rendezvous_circ_has_opened (origin_circuit_t *circ)
 
STATIC extend_info_tdesc_intro_point_to_extend_info (const hs_desc_intro_point_t *ip)
 
static int intro_point_is_usable (const ed25519_public_key_t *service_pk, const hs_desc_intro_point_t *ip)
 
STATIC extend_info_tclient_get_random_intro (const ed25519_public_key_t *service_pk)
 
static int close_or_reextend_intro_circ (origin_circuit_t *intro_circ)
 
static void handle_introduce_ack_success (origin_circuit_t *intro_circ)
 
static void handle_introduce_ack_bad (origin_circuit_t *circ, int status)
 
static int handle_introduce_ack (origin_circuit_t *circ, const uint8_t *payload, size_t payload_len)
 
STATIC int handle_rendezvous2 (origin_circuit_t *circ, const uint8_t *payload, size_t payload_len)
 
static unsigned int can_client_refetch_desc (const ed25519_public_key_t *identity_pk, hs_client_fetch_status_t *status_out)
 
static hs_client_service_authorization_tfind_client_auth (const ed25519_public_key_t *service_identity_pk)
 
void hs_client_note_connection_attempt_succeeded (const edge_connection_t *conn)
 
int hs_client_decode_descriptor (const char *desc_str, const ed25519_public_key_t *service_identity_pk, hs_descriptor_t **desc)
 
int hs_client_any_intro_points_usable (const ed25519_public_key_t *service_pk, const hs_descriptor_t *desc)
 
int hs_client_refetch_hsdesc (const ed25519_public_key_t *identity_pk)
 
int hs_client_send_introduce1 (origin_circuit_t *intro_circ, origin_circuit_t *rend_circ)
 
void hs_client_circuit_has_opened (origin_circuit_t *circ)
 
int hs_client_receive_rendezvous_acked (origin_circuit_t *circ, const uint8_t *payload, size_t payload_len)
 
static void client_service_authorization_free_ (hs_client_service_authorization_t *auth)
 
static void client_service_authorization_free_void (void *auth)
 
static void client_service_authorization_free_all (void)
 
STATIC int auth_key_filename_is_valid (const char *filename)
 
STATIC hs_client_service_authorization_tparse_auth_file_content (const char *client_key_str)
 
int hs_config_client_authorization (const or_options_t *options, int validate_only)
 
void hs_client_desc_has_arrived (const hs_ident_dir_conn_t *ident)
 
extend_info_ths_client_get_random_intro_from_edge (const edge_connection_t *edge_conn)
 
int hs_client_receive_introduce_ack (origin_circuit_t *circ, const uint8_t *payload, size_t payload_len)
 
int hs_client_receive_rendezvous2 (origin_circuit_t *circ, const uint8_t *payload, size_t payload_len)
 
int hs_client_reextend_intro_circuit (origin_circuit_t *circ)
 
void hs_client_close_intro_circuits_from_desc (const hs_descriptor_t *desc)
 
void hs_client_free_all (void)
 
void hs_client_purge_state (void)
 
void hs_client_dir_info_changed (void)
 

Variables

static digest256map_t * client_auths = NULL
 

Detailed Description

Implement next generation hidden service client functionality.

Definition in file hs_client.c.

Macro Definition Documentation

◆ client_service_authorization_free

#define client_service_authorization_free (   auth)
Value:
client_service_authorization_free_, (auth))

Definition at line 1459 of file hs_client.c.

Function Documentation

◆ auth_key_filename_is_valid()

STATIC int auth_key_filename_is_valid ( const char *  filename)

Check if the auth key file name is valid or not. Return 1 if valid, otherwise return 0.

Definition at line 1491 of file hs_client.c.

◆ can_client_refetch_desc()

static unsigned int can_client_refetch_desc ( const ed25519_public_key_t identity_pk,
hs_client_fetch_status_t status_out 
)
static

Return true iff the client can fetch a descriptor for this service public identity key and status_out if not NULL is untouched. If the client can not fetch the descriptor and if status_out is not NULL, it is set with the fetch status code.

Definition at line 1163 of file hs_client.c.

◆ cancel_descriptor_fetches()

static void cancel_descriptor_fetches ( void  )
static

Cancel all descriptor fetches currently in progress.

Definition at line 105 of file hs_client.c.

Referenced by hs_client_purge_state().

◆ client_get_random_intro()

STATIC extend_info_t* client_get_random_intro ( const ed25519_public_key_t service_pk)

Using a descriptor desc, return a newly allocated extend_info_t object of a randomly picked introduction point from its list. Return NULL if none are usable.

Definition at line 831 of file hs_client.c.

Referenced by hs_client_get_random_intro_from_edge(), and hs_client_reextend_intro_circuit().

◆ client_intro_circ_has_opened()

static void client_intro_circ_has_opened ( origin_circuit_t circ)
static

Called when an introduction circuit has opened.

Definition at line 715 of file hs_client.c.

Referenced by hs_client_circuit_has_opened().

◆ client_rendezvous_circ_has_opened()

static void client_rendezvous_circ_has_opened ( origin_circuit_t circ)
static

Called when a rendezvous circuit has opened.

Definition at line 732 of file hs_client.c.

Referenced by hs_client_circuit_has_opened().

◆ client_service_authorization_free_void()

static void client_service_authorization_free_void ( void *  auth)
static

Helper for digest256map_free.

Definition at line 1474 of file hs_client.c.

◆ close_all_socks_conns_waiting_for_desc()

static void close_all_socks_conns_waiting_for_desc ( const ed25519_public_key_t identity_pk,
hs_client_fetch_status_t  status,
int  reason 
)
static

We failed to fetch a descriptor for the service with identity_pk because of status. Find all pending SOCKS connections for this service that are waiting on the descriptor and close them with reason.

Definition at line 228 of file hs_client.c.

◆ close_or_reextend_intro_circ()

static int close_or_reextend_intro_circ ( origin_circuit_t intro_circ)
static

For this introduction circuit, we'll look at if we have any usable introduction point left for this service. If so, we'll use the circuit to re-extend to a new intro point. Else, we'll close the circuit and its corresponding rendezvous circuit. Return 0 if we are re-extending else -1 if we are closing the circuits.

This is called when getting an INTRODUCE_ACK cell with a NACK.

Definition at line 940 of file hs_client.c.

◆ desc_intro_point_to_extend_info()

STATIC extend_info_t* desc_intro_point_to_extend_info ( const hs_desc_intro_point_t ip)

This is an helper function that convert a descriptor intro point object ip to a newly allocated extend_info_t object fully initialized. Return NULL if we can't convert it for which chances are that we are missing or malformed link specifiers.

Definition at line 769 of file hs_client.c.

◆ directory_launch_v3_desc_fetch()

static hs_client_fetch_status_t directory_launch_v3_desc_fetch ( const ed25519_public_key_t onion_identity_pk,
const routerstatus_t hsdir 
)
static

Given the pubkey of a hidden service in onion_identity_pk, fetch its descriptor by launching a dir connection to hsdir. Return a hs_client_fetch_status_t status code depending on how it went.

Definition at line 350 of file hs_client.c.

Referenced by hs_client_launch_v3_desc_fetch().

◆ directory_request_is_pending()

static int directory_request_is_pending ( const ed25519_public_key_t identity_pk)
static

Return true iff there is at least one pending directory descriptor request for the service identity_pk.

Definition at line 178 of file hs_client.c.

◆ fetch_status_should_close_socks()

static int fetch_status_should_close_socks ( hs_client_fetch_status_t  status)
static

Return true iff tor should close the SOCKS request(s) for the descriptor fetch that ended up with this given status code.

Definition at line 79 of file hs_client.c.

◆ fetch_status_to_string()

static const char* fetch_status_to_string ( hs_client_fetch_status_t  status)
static

Return a human-readable string for the client fetch status code.

Definition at line 54 of file hs_client.c.

◆ fetch_v3_desc()

STATIC hs_client_fetch_status_t fetch_v3_desc ( const ed25519_public_key_t onion_identity_pk)

Fetch a v3 descriptor using the given onion_identity_pk.

On success, HS_CLIENT_FETCH_LAUNCHED is returned. Otherwise, an error from hs_client_fetch_status_t is returned.

Definition at line 439 of file hs_client.c.

◆ find_client_auth()

static hs_client_service_authorization_t* find_client_auth ( const ed25519_public_key_t service_identity_pk)
static

Return the client auth in the map using the service identity public key. Return NULL if it does not exist in the map.

Definition at line 1228 of file hs_client.c.

Referenced by hs_client_decode_descriptor().

◆ find_desc_intro_point_by_ident()

static const hs_desc_intro_point_t* find_desc_intro_point_by_ident ( const hs_ident_circuit_t ident,
const hs_descriptor_t desc 
)
static

Find a descriptor intro point object that matches the given ident in the given descriptor desc. Return NULL if not found.

Definition at line 504 of file hs_client.c.

Referenced by hs_client_close_intro_circuits_from_desc().

◆ find_desc_intro_point_by_legacy_id()

static hs_desc_intro_point_t* find_desc_intro_point_by_legacy_id ( const char *  legacy_id,
const hs_descriptor_t desc 
)
static

Find a descriptor intro point object from the descriptor object desc that matches the given legacy identity digest in legacy_id. Return NULL if not found.

Definition at line 528 of file hs_client.c.

◆ flag_all_conn_wait_desc()

static void flag_all_conn_wait_desc ( const ed25519_public_key_t service_identity_pk)
static

Get all connections that are waiting on a circuit and flag them back to waiting for a hidden service descriptor for the given service key service_identity_pk.

Definition at line 131 of file hs_client.c.

◆ handle_introduce_ack()

static int handle_introduce_ack ( origin_circuit_t circ,
const uint8_t *  payload,
size_t  payload_len 
)
static

Called when we get an INTRODUCE_ACK on the intro circuit circ. The encoded cell is in payload of length payload_len. Return 0 on success else a negative value. The circuit is either close or reuse to re-extend to a new introduction point.

Definition at line 1062 of file hs_client.c.

◆ handle_introduce_ack_bad()

static void handle_introduce_ack_bad ( origin_circuit_t circ,
int  status 
)
static

Called when we get an INTRODUCE_ACK failure status code. Depending on our failure cache status, either close the circuit or re-extend to a new introduction point.

Definition at line 1039 of file hs_client.c.

◆ handle_introduce_ack_success()

static void handle_introduce_ack_success ( origin_circuit_t intro_circ)
static

Called when we get an INTRODUCE_ACK success status code. Do the appropriate actions for the rendezvous point and finally close intro_circ.

Definition at line 992 of file hs_client.c.

◆ handle_rendezvous2()

STATIC int handle_rendezvous2 ( origin_circuit_t circ,
const uint8_t *  payload,
size_t  payload_len 
)

Called when we get a RENDEZVOUS2 cell on the rendezvous circuit circ. The encoded cell is in payload of length payload_len. Return 0 on success or a negative value on error. On error, the circuit is marked for close.

Definition at line 1100 of file hs_client.c.

◆ hs_client_any_intro_points_usable()

int hs_client_any_intro_points_usable ( const ed25519_public_key_t service_pk,
const hs_descriptor_t desc 
)

Return true iff there are at least one usable intro point in the service descriptor desc.

Definition at line 1325 of file hs_client.c.

Referenced by client_get_random_intro().

◆ hs_client_circuit_has_opened()

void hs_client_circuit_has_opened ( origin_circuit_t circ)

Called when the client circuit circ has been established. It can be either an introduction or rendezvous circuit. This function handles all hidden service versions.

Definition at line 1391 of file hs_client.c.

◆ hs_client_close_intro_circuits_from_desc()

void hs_client_close_intro_circuits_from_desc ( const hs_descriptor_t desc)

Close all client introduction circuits related to the given descriptor. This is called with a descriptor that is about to get replaced in the client cache.

Even though the introduction point might be exactly the same, we'll rebuild them if needed but the odds are very low that an existing matching introduction circuit exists at that stage.

Definition at line 1879 of file hs_client.c.

◆ hs_client_decode_descriptor()

int hs_client_decode_descriptor ( const char *  desc_str,
const ed25519_public_key_t service_identity_pk,
hs_descriptor_t **  desc 
)

With the given encoded descriptor in desc_str and the service key in service_identity_pk, decode the descriptor and set the desc pointer with a newly allocated descriptor object.

Return 0 on success else a negative value and desc is set to NULL.

Definition at line 1269 of file hs_client.c.

Referenced by cache_client_desc_new().

◆ hs_client_desc_has_arrived()

void hs_client_desc_has_arrived ( const hs_ident_dir_conn_t ident)

This is called when a descriptor has arrived following a fetch request and has been stored in the client cache. Every entry connection that matches the service identity key in the ident will get attached to the hidden service circuit.

Definition at line 1693 of file hs_client.c.

◆ hs_client_dir_info_changed()

void hs_client_dir_info_changed ( void  )

Called when our directory information has changed.

Definition at line 1935 of file hs_client.c.

Referenced by router_dir_info_changed().

◆ hs_client_free_all()

void hs_client_free_all ( void  )

Release all the storage held by the client subsystem.

Definition at line 1905 of file hs_client.c.

Referenced by hs_free_all().

◆ hs_client_get_random_intro_from_edge()

extend_info_t* hs_client_get_random_intro_from_edge ( const edge_connection_t edge_conn)

Return a newly allocated extend_info_t for a randomly chosen introduction point for the given edge connection identifier ident. Return NULL if we can't pick any usable introduction points.

Definition at line 1750 of file hs_client.c.

◆ hs_client_launch_v3_desc_fetch()

void hs_client_launch_v3_desc_fetch ( const ed25519_public_key_t onion_identity_pk,
const smartlist_t hsdirs 
)

With a given onion_identity_pk, fetch its descriptor. If hsdirs is specified, use the directory servers specified in the list. Else, use a random server.

Definition at line 458 of file hs_client.c.

Referenced by hs_control_hsfetch_command().

◆ hs_client_note_connection_attempt_succeeded()

void hs_client_note_connection_attempt_succeeded ( const edge_connection_t conn)

A circuit just finished connecting to a hidden service that the stream conn has been waiting for. Let the HS subsystem know about this.

Definition at line 1245 of file hs_client.c.

◆ hs_client_purge_state()

void hs_client_purge_state ( void  )

Purge all potentially remotely-detectable state held in the hidden service client code. Called on SIGNAL NEWNYM.

Definition at line 1915 of file hs_client.c.

◆ hs_client_receive_introduce_ack()

int hs_client_receive_introduce_ack ( origin_circuit_t circ,
const uint8_t *  payload,
size_t  payload_len 
)

Called when get an INTRODUCE_ACK cell on the introduction circuit circ. Return 0 on success else a negative value is returned. The circuit will be closed or reuse to extend again to another intro point.

Definition at line 1763 of file hs_client.c.

◆ hs_client_receive_rendezvous2()

int hs_client_receive_rendezvous2 ( origin_circuit_t circ,
const uint8_t *  payload,
size_t  payload_len 
)

Called when get a RENDEZVOUS2 cell on the rendezvous circuit circ. Return 0 on success else a negative value is returned. The circuit will be closed on error.

Definition at line 1792 of file hs_client.c.

◆ hs_client_receive_rendezvous_acked()

int hs_client_receive_rendezvous_acked ( origin_circuit_t circ,
const uint8_t *  payload,
size_t  payload_len 
)

Called when we receive a RENDEZVOUS_ESTABLISHED cell. Change the state of the circuit to CIRCUIT_PURPOSE_C_REND_READY. Return 0 on success else a negative value and the circuit marked for close.

Definition at line 1421 of file hs_client.c.

◆ hs_client_reextend_intro_circuit()

int hs_client_reextend_intro_circuit ( origin_circuit_t circ)

Extend the introduction circuit circ to another valid introduction point for the hidden service it is trying to connect to, or mark it and launch a new circuit if we can't extend it. Return 0 on success or possible success. Return -1 and mark the introduction circuit for close on permanent failure.

On failure, the caller is responsible for marking the associated rendezvous circuit for close.

Definition at line 1830 of file hs_client.c.

◆ hs_client_refetch_hsdesc()

int hs_client_refetch_hsdesc ( const ed25519_public_key_t identity_pk)

Launch a connection to a hidden service directory to fetch a hidden service descriptor using identity_pk to get the necessary keys.

A hs_client_fetch_status_t code is returned.

Definition at line 1348 of file hs_client.c.

Referenced by connection_dir_client_refetch_hsdesc_if_needed().

◆ hs_client_send_introduce1()

int hs_client_send_introduce1 ( origin_circuit_t intro_circ,
origin_circuit_t rend_circ 
)

This is called when we are trying to attach an AP connection to these hidden service circuits from connection_ap_handshake_attach_circuit(). Return 0 on success, -1 for a transient error that is actions were triggered to recover or -2 for a permenent error where both circuits will marked for close.

The following supports every hidden service version.

Definition at line 1379 of file hs_client.c.

◆ hs_config_client_authorization()

int hs_config_client_authorization ( const or_options_t options,
int  validate_only 
)

From a set of options, setup every client authorization detail found. Return 0 on success or -1 on failure. If validate_only is set, parse, warn and return as normal, but don't actually change the configuration.

Definition at line 1578 of file hs_client.c.

Referenced by hs_config_client_auth_all().

◆ intro_circ_is_ok()

static int intro_circ_is_ok ( const origin_circuit_t circ)
static

Make sure that the given v3 origin circuit circ is a valid correct introduction circuit. This will BUG() on any problems and hard assert if the anonymity of the circuit is not ok. Return 0 on success else -1 where the circuit should be mark for closed immediately.

Definition at line 477 of file hs_client.c.

◆ intro_point_is_usable()

static int intro_point_is_usable ( const ed25519_public_key_t service_pk,
const hs_desc_intro_point_t ip 
)
static

Return true iff the intro point ip for the service service_pk is usable. This function checks if the intro point is in the client intro state cache and checks at the failures. It is considered usable if:

  • No error happened (INTRO_POINT_FAILURE_GENERIC)
  • It is not flagged as timed out (INTRO_POINT_FAILURE_TIMEOUT)
  • The unreachable count is lower than MAX_INTRO_POINT_REACHABILITY_FAILURES (INTRO_POINT_FAILURE_UNREACHABLE)

Definition at line 791 of file hs_client.c.

Referenced by hs_client_any_intro_points_usable().

◆ mark_conn_as_waiting_for_circuit()

static void mark_conn_as_waiting_for_circuit ( connection_t conn,
time_t  now 
)
static

Helper function that changes the state of an entry connection to waiting for a circuit. For this to work properly, the connection timestamps are set to now and the connection is then marked as pending for a circuit.

Definition at line 207 of file hs_client.c.

◆ note_connection_attempt_succeeded()

static void note_connection_attempt_succeeded ( const hs_ident_edge_conn_t hs_conn_ident)
static

A v3 HS circuit successfully connected to the hidden service. Update the stream state at hs_conn_ident appropriately.

Definition at line 327 of file hs_client.c.

◆ pick_hsdir_v3()

STATIC routerstatus_t* pick_hsdir_v3 ( const ed25519_public_key_t onion_identity_pk)

Return the HSDir we should use to fetch the descriptor of the hidden service with identity key onion_identity_pk.

Definition at line 402 of file hs_client.c.

Referenced by fetch_v3_desc().

◆ purge_hid_serv_request()

static void purge_hid_serv_request ( const ed25519_public_key_t identity_pk)
static

Remove tracked HSDir requests from our history for this hidden service identity public key.

Definition at line 157 of file hs_client.c.

Referenced by note_connection_attempt_succeeded().

◆ retry_all_socks_conn_waiting_for_desc()

STATIC void retry_all_socks_conn_waiting_for_desc ( void  )

Find all pending SOCKS connection waiting for a descriptor and retry them all. This is called when the directory information changed.

Definition at line 271 of file hs_client.c.

Referenced by hs_client_dir_info_changed().

◆ send_introduce1()

static int send_introduce1 ( origin_circuit_t intro_circ,
origin_circuit_t rend_circ 
)
static

Send an INTRODUCE1 cell along the intro circuit and populate the rend circuit identifier with the needed key material for the e2e encryption. Return 0 on success, -1 if there is a transient error such that an action has been taken to recover and -2 if there is a permanent error indicating that both circuits were closed.

Definition at line 568 of file hs_client.c.

Referenced by hs_client_send_introduce1().

◆ setup_intro_circ_auth_key()

static void setup_intro_circ_auth_key ( origin_circuit_t circ)
static

Using the introduction circuit circ, setup the authentication key of the intro point this circuit has extended to.

Definition at line 677 of file hs_client.c.

Variable Documentation

◆ client_auths

digest256map_t* client_auths = NULL
static

Client-side authorizations for hidden services; map of service identity public key to hs_client_service_authorization_t *.

Definition at line 48 of file hs_client.c.

Referenced by find_client_auth().