tor
master
|
The hidden-service side of rendezvous functionality. More...
#include "or.h"
#include "circpathbias.h"
#include "circuitbuild.h"
#include "circuitlist.h"
#include "circuituse.h"
#include "config.h"
#include "control.h"
#include "crypto_rand.h"
#include "crypto_util.h"
#include "directory.h"
#include "hs_common.h"
#include "hs_config.h"
#include "main.h"
#include "networkstatus.h"
#include "nodelist.h"
#include "policies.h"
#include "rendclient.h"
#include "rendcommon.h"
#include "rendservice.h"
#include "router.h"
#include "relay.h"
#include "rephist.h"
#include "replaycache.h"
#include "routerlist.h"
#include "routerparse.h"
#include "routerset.h"
Functions | |
int | rend_num_services (void) |
void | rend_authorized_client_free_ (rend_authorized_client_t *client) |
STATIC void | rend_service_free_ (rend_service_t *service) |
void | rend_service_free_staging_list (void) |
void | rend_service_free_all (void) |
void | rend_service_init (void) |
rend_service_port_config_t * | rend_service_parse_port_config (const char *string, const char *sep, char **err_msg_out) |
void | rend_service_port_config_free_ (rend_service_port_config_t *p) |
STATIC void | rend_service_prune_list_impl_ (void) |
void | rend_service_prune_list (void) |
int | rend_config_service (const config_line_t *line_, const or_options_t *options, hs_service_config_t *config) |
hs_service_add_ephemeral_status_t | rend_service_add_ephemeral (crypto_pk_t *pk, smartlist_t *ports, int max_streams_per_circuit, int max_streams_close_circuit, rend_auth_type_t auth_type, smartlist_t *auth_clients, char **service_id_out) |
int | rend_service_del_ephemeral (const char *service_id) |
STATIC char * | rend_service_sos_poison_path (const rend_service_t *service) |
STATIC int | rend_service_verify_single_onion_poison (const rend_service_t *s, const or_options_t *options) |
STATIC int | rend_service_poison_new_single_onion_dir (const rend_service_t *s, const or_options_t *options) |
int | rend_service_load_all_keys (const smartlist_t *service_list) |
void | rend_services_add_filenames_to_lists (smartlist_t *open_lst, smartlist_t *stat_lst) |
int | rend_service_receive_introduction (origin_circuit_t *circuit, const uint8_t *request, size_t request_len) |
void | rend_service_free_intro_ (rend_intro_cell_t *request) |
rend_intro_cell_t * | rend_service_begin_parse_intro (const uint8_t *request, size_t request_len, uint8_t type, char **err_msg_out) |
int | rend_service_decrypt_intro (rend_intro_cell_t *intro, crypto_pk_t *key, char **err_msg_out) |
int | rend_service_parse_intro_plaintext (rend_intro_cell_t *intro, char **err_msg_out) |
int | rend_service_validate_intro_late (const rend_intro_cell_t *intro, char **err_msg_out) |
void | rend_service_relaunch_rendezvous (origin_circuit_t *oldcirc) |
ssize_t | rend_service_encode_establish_intro_cell (char *cell_body_out, size_t cell_body_out_len, crypto_pk_t *intro_key, const char *rend_circ_nonce) |
void | rend_service_intro_has_opened (origin_circuit_t *circuit) |
int | rend_service_intro_established (origin_circuit_t *circuit, const uint8_t *request, size_t request_len) |
void | rend_service_rendezvous_has_opened (origin_circuit_t *circuit) |
void | directory_post_to_hs_dir (rend_service_descriptor_t *renddesc, smartlist_t *descs, smartlist_t *hs_dirs, const char *service_id, int seconds_valid) |
void | rend_service_desc_has_uploaded (const rend_data_t *rend_data) |
void | rend_consider_services_intro_points (time_t now) |
void | rend_consider_services_upload (time_t now) |
void | rend_hsdir_routers_changed (void) |
void | rend_consider_descriptor_republication (void) |
void | rend_service_dump_stats (int severity) |
int | rend_service_set_connection_addr_port (edge_connection_t *conn, origin_circuit_t *circ) |
int | rend_service_allow_non_anonymous_connection (const or_options_t *options) |
int | rend_service_reveal_startup_time (const or_options_t *options) |
int | rend_service_non_anonymous_mode_enabled (const or_options_t *options) |
The hidden-service side of rendezvous functionality.
void directory_post_to_hs_dir | ( | rend_service_descriptor_t * | renddesc, |
smartlist_t * | descs, | ||
smartlist_t * | hs_dirs, | ||
const char * | service_id, | ||
int | seconds_valid | ||
) |
Upload the rend_encoded_v2_service_descriptor_t's in descs associated with the rend_service_descriptor_t renddesc to the responsible hidden service directories OR the hidden service directories specified by hs_dirs; service_id and seconds_valid are only passed for logging purposes.
If any HSDirs are specified, they should be used instead of the responsible directories
void rend_authorized_client_free_ | ( | rend_authorized_client_t * | client | ) |
Helper: free storage held by a single service authorized client entry.
void rend_consider_descriptor_republication | ( | void | ) |
Consider republication of v2 rendezvous service descriptors that failed previously, but without regenerating descriptor contents.
void rend_consider_services_intro_points | ( | time_t | now | ) |
For every service, check how many intro points it currently has, and:
This is called once a second by the main loop.
void rend_consider_services_upload | ( | time_t | now | ) |
Regenerate and upload rendezvous service descriptors for all services, if necessary. If the descriptor has been dirty enough for long enough, definitely upload; else only upload when the periodic timeout has expired.
For the first upload, pick a random time between now and two periods from now, and pick it independently for each service.
void rend_hsdir_routers_changed | ( | void | ) |
Called when our internal view of the directory has changed, so that we might have router descriptors of hidden service directories available that we did not have before.
int rend_num_services | ( | void | ) |
Return the number of rendezvous services we have configured.
hs_service_add_ephemeral_status_t rend_service_add_ephemeral | ( | crypto_pk_t * | pk, |
smartlist_t * | ports, | ||
int | max_streams_per_circuit, | ||
int | max_streams_close_circuit, | ||
rend_auth_type_t | auth_type, | ||
smartlist_t * | auth_clients, | ||
char ** | service_id_out | ||
) |
Add the ephemeral service pk/ports if possible, using client authorization auth_type and an optional list of rend_authorized_client_t in auth_clients, with max_streams_per_circuit streams allowed per rendezvous circuit, and circuit closure on max streams being exceeded set by max_streams_close_circuit.
Ownership of pk, ports, and auth_clients is passed to this routine. Regardless of success/failure, callers should not touch these values after calling this routine, and may assume that correct cleanup has been done on failure.
Return an appropriate hs_service_add_ephemeral_status_t.
rend_intro_cell_t* rend_service_begin_parse_intro | ( | const uint8_t * | request, |
size_t | request_len, | ||
uint8_t | type, | ||
char ** | err_msg_out | ||
) |
Parse an INTRODUCE1 or INTRODUCE2 cell into a newly allocated rend_intro_cell_t structure. Free it with rend_service_free_intro() when finished. The type parameter should be 1 or 2 to indicate whether this is INTRODUCE1 or INTRODUCE2. This parses only the non-encrypted parts; after this, call rend_service_decrypt_intro() with a key, then rend_service_parse_intro_plaintext() to finish parsing. The optional err_msg_out parameter is set to a string suitable for log output if parsing fails. This function does some validation, but only that which depends solely on the contents of the cell and the key; it can be unit-tested. Further validation is done in rend_service_validate_intro().
int rend_service_decrypt_intro | ( | rend_intro_cell_t * | intro, |
crypto_pk_t * | key, | ||
char ** | err_msg_out | ||
) |
Decrypt the encrypted part of an INTRODUCE1 or INTRODUCE2 cell, return 0 if successful, or < 0 and write an error message to *err_msg_out if provided.
int rend_service_del_ephemeral | ( | const char * | service_id | ) |
Remove the ephemeral service service_id if possible. Returns 0 on success, and -1 on failure.
void rend_service_desc_has_uploaded | ( | const rend_data_t * | rend_data | ) |
A new descriptor has been successfully uploaded for the given rend_data. Remove and free the expiring nodes from the associated service.
void rend_service_dump_stats | ( | int | severity | ) |
Log the status of introduction points for all rendezvous services at log severity severity.
STATIC void rend_service_free_ | ( | rend_service_t * | service | ) |
Release the storage held by service.
void rend_service_free_all | ( | void | ) |
Release all the storage held in both rend_service_list and rend_service_staging_list.
void rend_service_free_intro_ | ( | rend_intro_cell_t * | request | ) |
Free a parsed INTRODUCE1 or INTRODUCE2 cell that was allocated by rend_service_parse_intro().
int rend_service_intro_established | ( | origin_circuit_t * | circuit, |
const uint8_t * | request, | ||
size_t | request_len | ||
) |
Called when we get an INTRO_ESTABLISHED cell; mark the circuit as a live introduction point, and note that the service descriptor is now out-of-date.
void rend_service_intro_has_opened | ( | origin_circuit_t * | circuit | ) |
Called when we're done building a circuit to an introduction point: sends a RELAY_ESTABLISH_INTRO cell.
int rend_service_load_all_keys | ( | const smartlist_t * | service_list | ) |
Load and/or generate private keys for all hidden services, possibly including keys for client authorization. If a service_list is provided, treat it as the list of hidden services (used in unittests). Otherwise, require that rend_service_list is not NULL. Return 0 on success, -1 on failure.
int rend_service_parse_intro_plaintext | ( | rend_intro_cell_t * | intro, |
char ** | err_msg_out | ||
) |
Parse the plaintext of the encrypted part of an INTRODUCE1 or INTRODUCE2 cell, return 0 if successful, or < 0 and write an error message to *err_msg_out if provided.
The rendezvous cookie and Diffie-Hellman stuff are version-invariant and at the end of the plaintext of the encrypted part of the cell.
rend_service_port_config_t* rend_service_parse_port_config | ( | const char * | string, |
const char * | sep, | ||
char ** | err_msg_out | ||
) |
Parses a virtual-port to real-port/socket mapping separated by the provided separator and returns a new rend_service_port_config_t, or NULL and an optional error string on failure.
The format is: VirtualPort SEP (IP|RealPort|IP:RealPort|'socket':path)?
IP defaults to 127.0.0.1; RealPort defaults to VirtualPort.
STATIC int rend_service_poison_new_single_onion_dir | ( | const rend_service_t * | s, |
const or_options_t * | options | ||
) |
We just got launched in Single Onion Mode. That's a non-anonymous mode for hidden services. If s is new, we should mark its hidden service directory appropriately so that it is never launched as a location-private hidden service. (New directories don't have private key files.) Return 0 on success, -1 on fail.
void rend_service_port_config_free_ | ( | rend_service_port_config_t * | p | ) |
Release all storage held in a rend_service_port_config_t.
int rend_service_receive_introduction | ( | origin_circuit_t * | circuit, |
const uint8_t * | request, | ||
size_t | request_len | ||
) |
Respond to an INTRODUCE2 cell by launching a circuit to the chosen rendezvous point.
void rend_service_relaunch_rendezvous | ( | origin_circuit_t * | oldcirc | ) |
Called when we fail building a rendezvous circuit at some point other than the last hop: launches a new circuit to the same rendezvous point.
void rend_service_rendezvous_has_opened | ( | origin_circuit_t * | circuit | ) |
Called once a circuit to a rendezvous point is established: sends a RELAY_COMMAND_RENDEZVOUS1 cell.
int rend_service_set_connection_addr_port | ( | edge_connection_t * | conn, |
origin_circuit_t * | circ | ||
) |
Given conn, a rendezvous exit stream, look up the hidden service for circ, and look up the port and address based on conn->port. Assign the actual conn->addr and conn->port. Return -2 on failure for which the circuit should be closed, -1 on other failure, or 0 for success.
int rend_service_validate_intro_late | ( | const rend_intro_cell_t * | intro, |
char ** | err_msg_out | ||
) |
Do validity checks on a parsed intro cell after decryption; some of these are not done in rend_service_parse_intro_plaintext() itself because they depend on a lot of other state and would make it hard to unit test. Returns >= 0 if successful or < 0 if the intro cell is invalid, and optionally writes out an error message for logging. If an err_msg pointer is provided, it is the caller's responsibility to free any provided message.
STATIC int rend_service_verify_single_onion_poison | ( | const rend_service_t * | s, |
const or_options_t * | options | ||
) |
Check the single onion service poison state of the directory for s:
void rend_services_add_filenames_to_lists | ( | smartlist_t * | open_lst, |
smartlist_t * | stat_lst | ||
) |
Add to open_lst every filename used by a configured hidden service, and to stat_lst every directory used by a configured hidden service