Tor 0.4.9.1-alpha-dev
|
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/crypto/onion_crypto.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/congestion_control_common.h"
#include "core/or/extendinfo.h"
#include "core/or/protover.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/microdesc.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/nodelist.h"
#include "feature/nodelist/routerset.h"
#include "lib/crypt_ops/crypto_format.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "lib/crypt_ops/crypto_util.h"
#include "lib/evloop/compat_libevent.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 "core/or/socks_request_st.h"
#include "trunnel/hs/cell_introduce1.h"
Go to the source code of this file.
Macros | |
#define | HS_CLIENT_PRIVATE |
#define | CLIENT_MAX_POW_EFFORT 10000 |
#define | CLIENT_MIN_RETRY_POW_EFFORT 8 |
#define | CLIENT_POW_EFFORT_DOUBLE_UNTIL 1000 |
#define | CLIENT_POW_RETRY_MULTIPLIER (1.5f) |
Variables | |
static struct mainloop_event_t * | dir_info_changed_ev = NULL |
static digest256map_t * | client_auths = NULL |
Implement next generation hidden service client functionality.
Definition in file hs_client.c.
#define CLIENT_MAX_POW_EFFORT 10000 |
Set a client-side cap on the highest effort of PoW we will try to tackle. If asked for higher, we solve it at this cap.
Definition at line 652 of file hs_client.c.
#define CLIENT_MIN_RETRY_POW_EFFORT 8 |
Set a client-side minimum effort. If the client is choosing to increase effort on retry, it will always pick a value >= this lower limit.
Definition at line 656 of file hs_client.c.
#define CLIENT_POW_EFFORT_DOUBLE_UNTIL 1000 |
Client effort will double on every retry until this level is hit
Definition at line 659 of file hs_client.c.
#define CLIENT_POW_RETRY_MULTIPLIER (1.5f) |
After we reach DOUBLE_UNTIL, client effort is multiplied by this amount on every retry until we reach MAX_POW_EFFORT.
Definition at line 663 of file hs_client.c.
#define HS_CLIENT_PRIVATE |
Definition at line 9 of file hs_client.c.
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 2363 of file hs_client.c.
|
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 1460 of file hs_client.c.
|
static |
Definition at line 169 of file hs_client.c.
|
static |
This is called when a descriptor has arrived following a fetch request and has been stored in the client cache. The given entry connections, matching the service identity key, will get attached to the service circuit.
Definition at line 1571 of file hs_client.c.
|
static |
This is called when a descriptor fetch was successful but the descriptor couldn't be decrypted due to missing or bad client authorization.
Definition at line 1619 of file hs_client.c.
|
static |
Called when we get a 200 directory fetch status code.
Definition at line 1643 of file hs_client.c.
|
static |
Called when we get a 400 directory fetch status code.
Definition at line 1719 of file hs_client.c.
|
static |
Called when we get a 404 directory fetch status code.
Definition at line 1695 of file hs_client.c.
|
static |
Called when we get an unexpected directory fetch status code.
Definition at line 1737 of file hs_client.c.
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 1045 of file hs_client.c.
Referenced by hs_client_get_random_intro_from_edge(), and hs_client_reextend_intro_circuit().
|
static |
Called when an introduction circuit has opened.
Definition at line 886 of file hs_client.c.
Referenced by hs_client_circuit_has_opened().
|
static |
Called when a rendezvous circuit has opened.
Definition at line 937 of file hs_client.c.
Referenced by hs_client_circuit_has_opened().
void client_service_authorization_free_ | ( | hs_client_service_authorization_t * | auth | ) |
Definition at line 2332 of file hs_client.c.
|
static |
Definition at line 2352 of file hs_client.c.
|
static |
Helper for digest256map_free.
Definition at line 2346 of file hs_client.c.
|
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 292 of file hs_client.c.
|
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 1235 of file hs_client.c.
|
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 671 of file hs_client.c.
Referenced by hs_client_send_introduce1().
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 983 of file hs_client.c.
|
static |
Mainloop callback. Scheduled to run when we are notified of a directory info change. See hs_client_dir_info_changed().
Definition at line 66 of file hs_client.c.
Referenced by hs_client_dir_info_changed().
|
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 391 of file hs_client.c.
Referenced by hs_client_launch_v3_desc_fetch().
|
static |
Return true iff there is at least one pending directory descriptor request for the service identity_pk.
Definition at line 242 of file hs_client.c.
|
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 104 of file hs_client.c.
|
static |
Return a human-readable string for the client fetch status code.
Definition at line 79 of file hs_client.c.
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 480 of file hs_client.c.
|
static |
Find the filesystem file corresponding to the permanent client auth credentials in cred and remove it.
Definition at line 1952 of file hs_client.c.
|
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 1557 of file hs_client.c.
Referenced by hs_client_decode_descriptor().
const hs_desc_intro_point_t * find_desc_intro_point_by_ident | ( | const hs_ident_circuit_t * | ident, |
const hs_descriptor_t * | desc | ||
) |
Find a descriptor intro point object that matches the given ident in the given descriptor desc. Return NULL if not found.
Definition at line 545 of file hs_client.c.
Referenced by hs_client_close_intro_circuits_from_desc(), and pow_worker_replyfn().
|
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 570 of file hs_client.c.
Referenced by hs_client_setup_intro_circ_auth_key().
|
static |
Definition at line 135 of file hs_client.c.
|
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 195 of file hs_client.c.
|
static |
Get the full filename for storing the client auth credentials for the service in onion_address. The base directory is dir. This function never returns NULL.
Definition at line 1758 of file hs_client.c.
|
static |
Load a client authorization file with filename that is stored under the global client auth directory, and return a newly-allocated credentials object if it parsed well. Otherwise, return NULL.
Definition at line 1883 of file hs_client.c.
digest256map_t * get_hs_client_auths_map | ( | void | ) |
Get the HS client auth map.
Definition at line 2036 of file hs_client.c.
|
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 1359 of file hs_client.c.
|
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 1336 of file hs_client.c.
|
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 1289 of file hs_client.c.
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 1397 of file hs_client.c.
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 2205 of file hs_client.c.
Referenced by client_get_random_intro(), and close_or_reextend_intro_circ().
void hs_client_circuit_cleanup_on_close | ( | const circuit_t * | circ | ) |
Called when a circuit was just cleaned up. This is done right before the circuit is marked for close.
Definition at line 2048 of file hs_client.c.
Referenced by cleanup_on_close_client_circ().
void hs_client_circuit_cleanup_on_free | ( | const circuit_t * | circ | ) |
Called when a circuit was just cleaned up. This is done right before the circuit is freed.
Definition at line 2079 of file hs_client.c.
Referenced by cleanup_on_free_client_circ().
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 2269 of file hs_client.c.
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 2713 of file hs_client.c.
Referenced by hs_cache_remove_as_client().
hs_desc_decode_status_t 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.
On success, HS_DESC_DECODE_OK is returned and desc is set to the decoded descriptor. On error, desc is set to NULL and a decoding error status is returned depending on what was the issue.
Definition at line 2148 of file hs_client.c.
Referenced by cache_client_desc_new().
void hs_client_dir_fetch_done | ( | dir_connection_t * | dir_conn, |
const char * | reason, | ||
const char * | body, | ||
const int | status_code | ||
) |
Called when a descriptor directory fetch is done.
Act accordingly on all entry connections depending on the HTTP status code we got. In case of an error, the SOCKS error is set (if ExtendedErrors is set).
The reason is a human readable string returned by the directory server which can describe the status of the request. The body is the response content, on 200 code it is the descriptor itself. Finally, the status_code is the HTTP code returned by the directory server.
Definition at line 2557 of file hs_client.c.
void hs_client_dir_info_changed | ( | void | ) |
Called when our directory information has changed.
The work done in that function has to either be kept within the HS subsystem or else scheduled as a mainloop event. In other words, this function can't call outside to another subsystem to avoid risking recursion problems.
Definition at line 2775 of file hs_client.c.
Referenced by router_dir_info_changed().
void hs_client_free_all | ( | void | ) |
Release all the storage held by the client subsystem.
Definition at line 2739 of file hs_client.c.
Referenced by hs_free_all().
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 2591 of file hs_client.c.
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 499 of file hs_client.c.
Referenced by hs_control_hsfetch_command().
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 2130 of file hs_client.c.
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 2752 of file hs_client.c.
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 2602 of file hs_client.c.
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 2629 of file hs_client.c.
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 2293 of file hs_client.c.
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 2666 of file hs_client.c.
Referenced by close_or_reextend_intro_circ().
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 2228 of file hs_client.c.
Referenced by connection_dir_client_refetch_hsdesc_if_needed().
hs_client_register_auth_status_t hs_client_register_auth_credentials | ( | hs_client_service_authorization_t * | creds | ) |
Register the credential creds as part of the client auth subsystem.
Takes ownership of creds.
Now that we set the new credentials, also try to decrypt any cached descriptors.
Definition at line 1833 of file hs_client.c.
hs_client_removal_auth_status_t hs_client_remove_auth_credentials | ( | const char * | hsaddress | ) |
Remove client auth credentials for the service hs_address.
Definition at line 2002 of file hs_client.c.
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 2259 of file hs_client.c.
int hs_client_setup_intro_circ_auth_key | ( | origin_circuit_t * | circ | ) |
Using the introduction circuit circ, setup the authentication key of the intro point this circuit has extended to.
Return 0 if everything went well, otherwise return -1 in the case of errors.
Definition at line 847 of file hs_client.c.
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 2467 of file hs_client.c.
Referenced by hs_config_client_auth_all().
|
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 518 of file hs_client.c.
|
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:
Definition at line 1005 of file hs_client.c.
Referenced by hs_client_any_intro_points_usable().
|
static |
Return true iff all intro points for the given service have timed out.
Definition at line 1148 of file hs_client.c.
|
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 271 of file hs_client.c.
|
static |
A v3 HS circuit successfully connected to the hidden service. Update the stream state at hs_conn_ident appropriately.
Definition at line 378 of file hs_client.c.
Referenced by hs_client_note_connection_attempt_succeeded().
STATIC hs_client_service_authorization_t * parse_auth_file_content | ( | const char * | client_key_str | ) |
Parse the client auth credentials off a string in client_key_str based on the file format documented in the "Client side configuration" section of rend-spec-v3.txt.
Return NULL if there was an error, otherwise return a newly allocated hs_client_service_authorization_t structure.
Definition at line 2390 of file hs_client.c.
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 443 of file hs_client.c.
Referenced by fetch_v3_desc().
STATIC void purge_ephemeral_client_auth | ( | void | ) |
Purge the client authorization cache of all ephemeral entries that is the entries that are not flagged with CLIENT_AUTH_FLAG_IS_PERMANENT.
This is called from the hs_client_purge_state() used by a SIGNEWNYM.
Definition at line 1539 of file hs_client.c.
|
static |
Remove tracked HSDir requests from our history for this hidden service identity public key.
Definition at line 221 of file hs_client.c.
Referenced by note_connection_attempt_succeeded().
|
static |
Definition at line 1927 of file hs_client.c.
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 322 of file hs_client.c.
Referenced by dir_info_changed_callback().
int send_introduce1 | ( | origin_circuit_t * | intro_circ, |
origin_circuit_t * | rend_circ, | ||
const hs_descriptor_t * | desc, | ||
hs_pow_solution_t * | pow_solution, | ||
const hs_desc_intro_point_t * | ip | ||
) |
Phase two for client-side introducing: Send an INTRODUCE1 cell along the intro circuit and populate the rend circuit identifier with the needed key material for the e2e encryption.
Definition at line 609 of file hs_client.c.
|
static |
Setup the congestion control parameters on the given rendezvous circuit. This looks at the service descriptor flow control line (if any).
It is possible that we are unable to set congestion control on the circuit if the descriptor can't be found. In that case, the introduction circuit can't be opened without it so a fetch will be triggered.
However, if the descriptor asks for congestion control but the RP circuit doesn't have it, it will be closed and a new circuit will be opened.
Definition at line 906 of file hs_client.c.
|
static |
Called when introduction has failed meaning there is no more usable introduction points to be used (either NACKed or failed) for the given entry connection.
This function only reports back the SOCKS5_HS_INTRO_FAILED (0xF2) code or SOCKS5_HS_INTRO_TIMEDOUT (0xF7) if all intros have timed out. The caller has to make sure to close the entry connections.
Definition at line 1212 of file hs_client.c.
|
static |
Called when a rendezvous circuit has timed out. Every stream attached to the circuit will get set with the SOCKS5_HS_REND_FAILED (0xF3) extended error code so if the connection to the rendezvous point ends up not working, this code could be sent back as a reason.
Definition at line 1188 of file hs_client.c.
|
static |
Permanently store the credentials in creds to disk.
Return -1 if there was an error while storing the credentials, otherwise return 0.
Definition at line 1777 of file hs_client.c.
|
static |
Client-side authorizations for hidden services; map of service identity public key to hs_client_service_authorization_t *.
Definition at line 61 of file hs_client.c.
Referenced by find_client_auth(), get_hs_client_auths_map(), and hs_client_remove_auth_credentials().
|
static |
This event is activated when we are notified that directory information has changed. It must be done asynchronous from the call due to possible recursion from the caller of that notification. See #40579.
Definition at line 57 of file hs_client.c.
Referenced by hs_client_dir_info_changed().