mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-28 14:23:30 +01:00
Next patch from Karsten: client-side configuration stuff for proposal 121.
svn:r16510
This commit is contained in:
parent
d84f5a986d
commit
97245376d9
@ -227,6 +227,7 @@ static config_var_t _option_vars[] = {
|
|||||||
VAR("HiddenServicePort", LINELIST_S, RendConfigLines, NULL),
|
VAR("HiddenServicePort", LINELIST_S, RendConfigLines, NULL),
|
||||||
VAR("HiddenServiceVersion",LINELIST_S, RendConfigLines, NULL),
|
VAR("HiddenServiceVersion",LINELIST_S, RendConfigLines, NULL),
|
||||||
VAR("HiddenServiceAuthorizeClient",LINELIST_S,RendConfigLines, NULL),
|
VAR("HiddenServiceAuthorizeClient",LINELIST_S,RendConfigLines, NULL),
|
||||||
|
V(HidServAuth, LINELIST, NULL),
|
||||||
V(HSAuthoritativeDir, BOOL, "0"),
|
V(HSAuthoritativeDir, BOOL, "0"),
|
||||||
V(HSAuthorityRecordStats, BOOL, "0"),
|
V(HSAuthorityRecordStats, BOOL, "0"),
|
||||||
V(HttpProxy, STRING, NULL),
|
V(HttpProxy, STRING, NULL),
|
||||||
@ -1191,6 +1192,12 @@ options_act(or_options_t *old_options)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (running_tor && rend_parse_service_authorization(options, 0) < 0) {
|
||||||
|
log_warn(LD_BUG, "Previously validated client authorization for "
|
||||||
|
"hidden services could not be added!");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (running_tor && directory_caches_v2_dir_info(options)) {
|
if (running_tor && directory_caches_v2_dir_info(options)) {
|
||||||
len = strlen(options->DataDirectory)+32;
|
len = strlen(options->DataDirectory)+32;
|
||||||
fn = tor_malloc(len);
|
fn = tor_malloc(len);
|
||||||
@ -3402,6 +3409,11 @@ options_validate(or_options_t *old_options, or_options_t *options,
|
|||||||
if (rend_config_services(options, 1) < 0)
|
if (rend_config_services(options, 1) < 0)
|
||||||
REJECT("Failed to configure rendezvous options. See logs for details.");
|
REJECT("Failed to configure rendezvous options. See logs for details.");
|
||||||
|
|
||||||
|
/* Parse client-side authorization for hidden services. */
|
||||||
|
if (rend_parse_service_authorization(options, 1) < 0)
|
||||||
|
REJECT("Failed to configure client authorization for hidden services. "
|
||||||
|
"See logs for details.");
|
||||||
|
|
||||||
if (parse_virtual_addr_network(options->VirtualAddrNetwork, 1, NULL)<0)
|
if (parse_virtual_addr_network(options->VirtualAddrNetwork, 1, NULL)<0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -1873,6 +1873,7 @@ tor_free_all(int postfork)
|
|||||||
dirserv_free_all();
|
dirserv_free_all();
|
||||||
rend_service_free_all();
|
rend_service_free_all();
|
||||||
rend_cache_free_all();
|
rend_cache_free_all();
|
||||||
|
rend_service_authorization_free_all();
|
||||||
rep_hist_free_all();
|
rep_hist_free_all();
|
||||||
hs_usage_free_all();
|
hs_usage_free_all();
|
||||||
dns_free_all();
|
dns_free_all();
|
||||||
|
25
src/or/or.h
25
src/or/or.h
@ -612,6 +612,9 @@ typedef enum {
|
|||||||
/** Length of 'y' portion of 'y.onion' URL. */
|
/** Length of 'y' portion of 'y.onion' URL. */
|
||||||
#define REND_SERVICE_ID_LEN_BASE32 16
|
#define REND_SERVICE_ID_LEN_BASE32 16
|
||||||
|
|
||||||
|
/** Length of 'y.onion' including '.onion' URL. */
|
||||||
|
#define REND_SERVICE_ADDRESS_LEN (16+1+5)
|
||||||
|
|
||||||
/** Length of a binary-encoded rendezvous service ID. */
|
/** Length of a binary-encoded rendezvous service ID. */
|
||||||
#define REND_SERVICE_ID_LEN 10
|
#define REND_SERVICE_ID_LEN 10
|
||||||
|
|
||||||
@ -2239,6 +2242,8 @@ typedef struct {
|
|||||||
* other ORs are running. */
|
* other ORs are running. */
|
||||||
config_line_t *RendConfigLines; /**< List of configuration lines
|
config_line_t *RendConfigLines; /**< List of configuration lines
|
||||||
* for rendezvous services. */
|
* for rendezvous services. */
|
||||||
|
config_line_t *HidServAuth; /**< List of configuration lines for client-side
|
||||||
|
* authorizations for hidden services */
|
||||||
char *ContactInfo; /**< Contact info to be published in the directory. */
|
char *ContactInfo; /**< Contact info to be published in the directory. */
|
||||||
|
|
||||||
char *HttpProxy; /**< hostname[:port] to use as http proxy, if any. */
|
char *HttpProxy; /**< hostname[:port] to use as http proxy, if any. */
|
||||||
@ -3806,6 +3811,26 @@ extend_info_t *rend_client_get_random_intro(const char *query);
|
|||||||
int rend_client_send_introduction(origin_circuit_t *introcirc,
|
int rend_client_send_introduction(origin_circuit_t *introcirc,
|
||||||
origin_circuit_t *rendcirc);
|
origin_circuit_t *rendcirc);
|
||||||
|
|
||||||
|
/** Client authorization type that a hidden service performs. */
|
||||||
|
typedef enum rend_auth_type_t {
|
||||||
|
REND_NO_AUTH = 0,
|
||||||
|
REND_BASIC_AUTH = 1,
|
||||||
|
REND_STEALTH_AUTH = 2,
|
||||||
|
} rend_auth_type_t;
|
||||||
|
|
||||||
|
/** Client-side configuration of authorization for a hidden service. */
|
||||||
|
typedef struct rend_service_authorization_t {
|
||||||
|
char descriptor_cookie[REND_DESC_COOKIE_LEN];
|
||||||
|
char onion_address[REND_SERVICE_ADDRESS_LEN+1];
|
||||||
|
rend_auth_type_t auth_type;
|
||||||
|
} rend_service_authorization_t;
|
||||||
|
|
||||||
|
int rend_parse_service_authorization(or_options_t *options,
|
||||||
|
int validate_only);
|
||||||
|
rend_service_authorization_t *rend_client_lookup_service_authorization(
|
||||||
|
const char *onion_address);
|
||||||
|
void rend_service_authorization_free_all(void);
|
||||||
|
|
||||||
/********************************* rendcommon.c ***************************/
|
/********************************* rendcommon.c ***************************/
|
||||||
|
|
||||||
/** Hidden-service side configuration of client authorization. */
|
/** Hidden-service side configuration of client authorization. */
|
||||||
|
@ -713,3 +713,136 @@ rend_client_get_random_intro(const char *query)
|
|||||||
return extend_info_dup(intro->extend_info);
|
return extend_info_dup(intro->extend_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Client-side authorizations for hidden services; map of onion address to
|
||||||
|
* rend_service_authorization_t*. */
|
||||||
|
static strmap_t *auth_hid_servs = NULL;
|
||||||
|
|
||||||
|
/** Look up the client-side authorization for the hidden service with
|
||||||
|
* <b>onion_address</b>. Return NULL if no authorization is available for
|
||||||
|
* that address. */
|
||||||
|
rend_service_authorization_t*
|
||||||
|
rend_client_lookup_service_authorization(const char *onion_address)
|
||||||
|
{
|
||||||
|
tor_assert(onion_address);
|
||||||
|
if (!auth_hid_servs) return NULL;
|
||||||
|
return strmap_get(auth_hid_servs, onion_address);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Helper: Free storage held by rend_service_authorization_t. */
|
||||||
|
static void
|
||||||
|
rend_service_authorization_free(rend_service_authorization_t *auth)
|
||||||
|
{
|
||||||
|
tor_free(auth);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Helper for strmap_free. */
|
||||||
|
static void
|
||||||
|
rend_service_authorization_strmap_item_free(void *service_auth)
|
||||||
|
{
|
||||||
|
rend_service_authorization_free(service_auth);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Release all the storage held in auth_hid_servs.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
rend_service_authorization_free_all(void)
|
||||||
|
{
|
||||||
|
if (!auth_hid_servs) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
strmap_free(auth_hid_servs, rend_service_authorization_strmap_item_free);
|
||||||
|
auth_hid_servs = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Parse <b>config_line</b> as a client-side authorization for a hidden
|
||||||
|
* service and add it to the local map of hidden service authorizations.
|
||||||
|
* Return 0 for success and -1 for failure. */
|
||||||
|
int
|
||||||
|
rend_parse_service_authorization(or_options_t *options, int validate_only)
|
||||||
|
{
|
||||||
|
config_line_t *line;
|
||||||
|
int res = -1;
|
||||||
|
strmap_t *parsed = strmap_new();
|
||||||
|
smartlist_t *sl = smartlist_create();
|
||||||
|
|
||||||
|
for (line = options->HidServAuth; line; line = line->next) {
|
||||||
|
char *onion_address, *descriptor_cookie;
|
||||||
|
char descriptor_cookie_tmp[REND_DESC_COOKIE_LEN+2];
|
||||||
|
char descriptor_cookie_base64ext[REND_DESC_COOKIE_LEN_BASE64+2+1];
|
||||||
|
rend_service_authorization_t *auth = NULL;
|
||||||
|
int auth_type_val = 0;
|
||||||
|
SMARTLIST_FOREACH(sl, char *, c, tor_free(c););
|
||||||
|
smartlist_clear(sl);
|
||||||
|
smartlist_split_string(sl, line->value, " ",
|
||||||
|
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 3);
|
||||||
|
if (smartlist_len(sl) < 2) {
|
||||||
|
log_warn(LD_CONFIG, "Configuration line does not consist of "
|
||||||
|
"\"onion-address authorization-cookie [service-name]\": "
|
||||||
|
"'%s'", line->value);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
auth = tor_malloc_zero(sizeof(rend_service_authorization_t));
|
||||||
|
/* Parse onion address. */
|
||||||
|
onion_address = smartlist_get(sl, 0);
|
||||||
|
if (strlen(onion_address) != REND_SERVICE_ADDRESS_LEN ||
|
||||||
|
strcmpend(onion_address, ".onion")) {
|
||||||
|
log_warn(LD_CONFIG, "Onion address has wrong format: '%s'",
|
||||||
|
onion_address);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
strlcpy(auth->onion_address, onion_address, REND_SERVICE_ID_LEN_BASE32+1);
|
||||||
|
if (!rend_valid_service_id(auth->onion_address)) {
|
||||||
|
log_warn(LD_CONFIG, "Onion address has wrong format: '%s'",
|
||||||
|
onion_address);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
/* Parse descriptor cookie. */
|
||||||
|
descriptor_cookie = smartlist_get(sl, 1);
|
||||||
|
if (strlen(descriptor_cookie) != REND_DESC_COOKIE_LEN_BASE64) {
|
||||||
|
log_warn(LD_CONFIG, "Authorization cookie has wrong length: '%s'",
|
||||||
|
descriptor_cookie);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
/* Add trailing zero bytes (AA) to make base64-decoding happy. */
|
||||||
|
tor_snprintf(descriptor_cookie_base64ext,
|
||||||
|
REND_DESC_COOKIE_LEN_BASE64+2+1,
|
||||||
|
"%sAA", descriptor_cookie);
|
||||||
|
if (base64_decode(descriptor_cookie_tmp, sizeof(descriptor_cookie_tmp),
|
||||||
|
descriptor_cookie_base64ext,
|
||||||
|
strlen(descriptor_cookie_base64ext)) < 0) {
|
||||||
|
log_warn(LD_CONFIG, "Decoding authorization cookie failed: '%s'",
|
||||||
|
descriptor_cookie);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
auth_type_val = (descriptor_cookie_tmp[16] >> 4) + 1;
|
||||||
|
if (auth_type_val < 1 || auth_type_val > 2) {
|
||||||
|
log_warn(LD_CONFIG, "Authorization cookie has unknown authorization "
|
||||||
|
"type encoded.");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
auth->auth_type = auth_type_val == 1 ? REND_BASIC_AUTH : REND_STEALTH_AUTH;
|
||||||
|
memcpy(auth->descriptor_cookie, descriptor_cookie_tmp,
|
||||||
|
REND_DESC_COOKIE_LEN);
|
||||||
|
if (strmap_get(parsed, auth->onion_address)) {
|
||||||
|
log_warn(LD_CONFIG, "Duplicate authorization for the same hidden "
|
||||||
|
"service.");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
strmap_set(parsed, auth->onion_address, auth);
|
||||||
|
}
|
||||||
|
res = 0;
|
||||||
|
goto done;
|
||||||
|
err:
|
||||||
|
res = -1;
|
||||||
|
done:
|
||||||
|
SMARTLIST_FOREACH(sl, char *, c, tor_free(c););
|
||||||
|
smartlist_free(sl);
|
||||||
|
if (!validate_only && res == 0) {
|
||||||
|
rend_service_authorization_free_all();
|
||||||
|
auth_hid_servs = parsed;
|
||||||
|
} else {
|
||||||
|
strmap_free(parsed, rend_service_authorization_strmap_item_free);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -40,13 +40,6 @@ typedef struct rend_service_port_config_t {
|
|||||||
* rendezvous point before giving up? */
|
* rendezvous point before giving up? */
|
||||||
#define MAX_REND_TIMEOUT 30
|
#define MAX_REND_TIMEOUT 30
|
||||||
|
|
||||||
/** DOCDOC */
|
|
||||||
typedef enum rend_auth_type_t {
|
|
||||||
REND_NO_AUTH = 0,
|
|
||||||
REND_BASIC_AUTH = 1,
|
|
||||||
REND_STEALTH_AUTH = 2,
|
|
||||||
} rend_auth_type_t;
|
|
||||||
|
|
||||||
/** Represents a single hidden service running at this OP. */
|
/** Represents a single hidden service running at this OP. */
|
||||||
typedef struct rend_service_t {
|
typedef struct rend_service_t {
|
||||||
/* Fields specified in config file */
|
/* Fields specified in config file */
|
||||||
|
Loading…
Reference in New Issue
Block a user