mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 05:33:47 +01:00
Merge branch 'tor-gitlab/mr/327'
Conflicts: src/test/test.c Minor comment issue.
This commit is contained in:
commit
3bd7367274
@ -5466,6 +5466,77 @@ pt_parse_transport_line(const or_options_t *options,
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a flag describing an extra dirport for a directory authority.
|
||||
*
|
||||
* Right now, the supported format is exactly:
|
||||
* `{upload,download,voting}=http://[IP:PORT]/`.
|
||||
* Other URL schemes, and other suffixes, might be supported in the future.
|
||||
*
|
||||
* Only call this function if `flag` starts with one of the above strings.
|
||||
*
|
||||
* Return 0 on success, and -1 on failure.
|
||||
*
|
||||
* If `ds` is provided, then add any parsed dirport to `ds`. If `ds` is NULL,
|
||||
* take no action other than parsing.
|
||||
**/
|
||||
static int
|
||||
parse_dirauth_dirport(dir_server_t *ds, const char *flag)
|
||||
{
|
||||
tor_assert(flag);
|
||||
|
||||
auth_dirport_usage_t usage;
|
||||
|
||||
if (!strcasecmpstart(flag, "upload=")) {
|
||||
usage = AUTH_USAGE_UPLOAD;
|
||||
} else if (!strcasecmpstart(flag, "download=")) {
|
||||
usage = AUTH_USAGE_DOWNLOAD;
|
||||
} else if (!strcasecmpstart(flag, "vote=")) {
|
||||
usage = AUTH_USAGE_VOTING;
|
||||
} else {
|
||||
// We shouldn't get called with a flag that we don't recognize.
|
||||
tor_assert_nonfatal_unreached();
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *eq = strchr(flag, '=');
|
||||
tor_assert(eq);
|
||||
const char *target = eq + 1;
|
||||
|
||||
// Find the part inside the http://{....}/
|
||||
if (strcmpstart(target, "http://")) {
|
||||
log_warn(LD_CONFIG, "Unsupported URL scheme in authority flag %s", flag);
|
||||
return -1;
|
||||
}
|
||||
const char *addr = target + strlen("http://");
|
||||
|
||||
const char *eos = strchr(addr, '/');
|
||||
size_t addr_len;
|
||||
if (eos && strcmp(eos, "/")) {
|
||||
log_warn(LD_CONFIG, "Unsupported URL prefix in authority flag %s", flag);
|
||||
return -1;
|
||||
} else if (eos) {
|
||||
addr_len = eos - addr;
|
||||
} else {
|
||||
addr_len = strlen(addr);
|
||||
}
|
||||
|
||||
// Finally, parse the addr:port part.
|
||||
char *addr_string = tor_strndup(addr, addr_len);
|
||||
tor_addr_port_t dirport;
|
||||
memset(&dirport, 0, sizeof(dirport));
|
||||
int rv = tor_addr_port_parse(LOG_WARN, addr_string,
|
||||
&dirport.addr, &dirport.port, -1);
|
||||
if (ds != NULL && rv == 0) {
|
||||
trusted_dir_server_add_dirport(ds, usage, &dirport);
|
||||
} else if (rv == -1) {
|
||||
log_warn(LD_CONFIG, "Unable to parse address in authority flag %s",flag);
|
||||
}
|
||||
|
||||
tor_free(addr_string);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/** Read the contents of a DirAuthority line from <b>line</b>. If
|
||||
* <b>validate_only</b> is 0, and the line is well-formed, and it
|
||||
* shares any bits with <b>required_type</b> or <b>required_type</b>
|
||||
@ -5486,6 +5557,7 @@ parse_dir_authority_line(const char *line, dirinfo_type_t required_type,
|
||||
char v3_digest[DIGEST_LEN];
|
||||
dirinfo_type_t type = 0;
|
||||
double weight = 1.0;
|
||||
smartlist_t *extra_dirports = smartlist_new();
|
||||
|
||||
memset(v3_digest, 0, sizeof(v3_digest));
|
||||
|
||||
@ -5554,6 +5626,12 @@ parse_dir_authority_line(const char *line, dirinfo_type_t required_type,
|
||||
}
|
||||
ipv6_addrport_ptr = &ipv6_addrport;
|
||||
}
|
||||
} else if (!strcasecmpstart(flag, "upload=") ||
|
||||
!strcasecmpstart(flag, "download=") ||
|
||||
!strcasecmpstart(flag, "vote=")) {
|
||||
// We'll handle these after creating the authority object.
|
||||
smartlist_add(extra_dirports, flag);
|
||||
flag = NULL; // prevent double-free.
|
||||
} else {
|
||||
log_warn(LD_CONFIG, "Unrecognized flag '%s' on DirAuthority line",
|
||||
flag);
|
||||
@ -5597,6 +5675,13 @@ parse_dir_authority_line(const char *line, dirinfo_type_t required_type,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (validate_only) {
|
||||
SMARTLIST_FOREACH_BEGIN(extra_dirports, const char *, cp) {
|
||||
if (parse_dirauth_dirport(NULL, cp) < 0)
|
||||
goto err;
|
||||
} SMARTLIST_FOREACH_END(cp);
|
||||
}
|
||||
|
||||
if (!validate_only && (!required_type || required_type & type)) {
|
||||
dir_server_t *ds;
|
||||
if (required_type)
|
||||
@ -5608,16 +5693,23 @@ parse_dir_authority_line(const char *line, dirinfo_type_t required_type,
|
||||
ipv6_addrport_ptr,
|
||||
digest, v3_digest, type, weight)))
|
||||
goto err;
|
||||
|
||||
SMARTLIST_FOREACH_BEGIN(extra_dirports, const char *, cp) {
|
||||
if (parse_dirauth_dirport(ds, cp) < 0)
|
||||
goto err;
|
||||
} SMARTLIST_FOREACH_END(cp);
|
||||
dir_server_add(ds);
|
||||
}
|
||||
|
||||
r = 0;
|
||||
goto done;
|
||||
|
||||
err:
|
||||
err:
|
||||
r = -1;
|
||||
|
||||
done:
|
||||
done:
|
||||
SMARTLIST_FOREACH(extra_dirports, char*, s, tor_free(s));
|
||||
smartlist_free(extra_dirports);
|
||||
SMARTLIST_FOREACH(items, char*, s, tor_free(s));
|
||||
smartlist_free(items);
|
||||
tor_free(addrport);
|
||||
|
@ -16,6 +16,8 @@
|
||||
#include "core/or/or.h"
|
||||
#include "feature/nodelist/routerstatus_st.h"
|
||||
|
||||
struct smartlist_t;
|
||||
|
||||
/** Represents information about a single trusted or fallback directory
|
||||
* server. */
|
||||
struct dir_server_t {
|
||||
@ -48,6 +50,10 @@ struct dir_server_t {
|
||||
time_t addr_current_at; /**< When was the document that we derived the
|
||||
* address information from published? */
|
||||
|
||||
/** Authority only. Can be null. If present, a list of auth_dirport_t
|
||||
* representing HTTP dirports for this authority. */
|
||||
struct smartlist_t *auth_dirports;
|
||||
|
||||
routerstatus_t fake_status; /**< Used when we need to pass this trusted
|
||||
* dir_server_t to
|
||||
* directory_request_set_routerstatus.
|
||||
|
@ -1119,6 +1119,7 @@ directory_request_set_routerstatus(directory_request_t *req,
|
||||
{
|
||||
req->routerstatus = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper: update the addresses, ports, and identities in <b>req</b>
|
||||
* from the routerstatus object in <b>req</b>. Return 0 on success.
|
||||
@ -1161,7 +1162,7 @@ directory_request_set_dir_from_routerstatus(directory_request_t *req)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* At this point, if we are a client making a direct connection to a
|
||||
/* At this point, if we are a client making a direct connection to a
|
||||
* directory server, we have selected a server that has at least one address
|
||||
* allowed by ClientUseIPv4/6 and Reachable{"",OR,Dir}Addresses. This
|
||||
* selection uses the preference in ClientPreferIPv6{OR,Dir}Port, if
|
||||
@ -1176,6 +1177,37 @@ directory_request_set_dir_from_routerstatus(directory_request_t *req)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* One last thing: If we're talking to an authority, we might want to use
|
||||
* a special HTTP port for it based on our purpose.
|
||||
*/
|
||||
if (req->indirection == DIRIND_DIRECT_CONN && status->is_authority) {
|
||||
const dir_server_t *ds = router_get_trusteddirserver_by_digest(
|
||||
status->identity_digest);
|
||||
if (ds) {
|
||||
const tor_addr_port_t *v4 = NULL;
|
||||
if (authdir_mode_v3(get_options())) {
|
||||
// An authority connecting to another authority should always
|
||||
// prefer the VOTING usage, if one is specifically configured.
|
||||
v4 = trusted_dir_server_get_dirport_exact(
|
||||
ds, AUTH_USAGE_VOTING, AF_INET);
|
||||
}
|
||||
if (! v4) {
|
||||
// Everybody else should prefer a usage dependent on their
|
||||
// the dir_purpose.
|
||||
auth_dirport_usage_t usage =
|
||||
auth_dirport_usage_for_purpose(req->dir_purpose);
|
||||
v4 = trusted_dir_server_get_dirport(ds, usage, AF_INET);
|
||||
}
|
||||
tor_assert_nonfatal(v4);
|
||||
if (v4) {
|
||||
// XXXX We could, if we wanted, also select a v6 address. But a v4
|
||||
// address must exist here, and we as a relay are required to support
|
||||
// ipv4. So we just that.
|
||||
tor_addr_port_copy(&use_dir_ap, v4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
directory_request_set_or_addr_port(req, &use_or_ap);
|
||||
directory_request_set_dir_addr_port(req, &use_dir_ap);
|
||||
directory_request_set_directory_id_digest(req, status->identity_digest);
|
||||
@ -1194,7 +1226,7 @@ directory_initiate_request,(directory_request_t *request))
|
||||
tor_assert_nonfatal(
|
||||
! directory_request_dir_contact_info_specified(request));
|
||||
if (directory_request_set_dir_from_routerstatus(request) < 0) {
|
||||
return;
|
||||
return; // or here XXXX
|
||||
}
|
||||
}
|
||||
|
||||
@ -1309,6 +1341,8 @@ directory_initiate_request,(directory_request_t *request))
|
||||
entry_guard_cancel(&guard_state);
|
||||
}
|
||||
|
||||
// XXXX This is the case where we replace.
|
||||
|
||||
switch (connection_connect(TO_CONN(conn), conn->base_.address, &addr,
|
||||
port, &socket_error)) {
|
||||
case -1:
|
||||
|
@ -43,6 +43,14 @@
|
||||
#include "feature/dirclient/dir_server_st.h"
|
||||
#include "feature/nodelist/node_st.h"
|
||||
|
||||
/** Information about an (HTTP) dirport for a directory authority. */
|
||||
struct auth_dirport_t {
|
||||
/** What is the intended usage for this dirport? One of AUTH_USAGE_* */
|
||||
auth_dirport_usage_t usage;
|
||||
/** What is the correct address/port ? */
|
||||
tor_addr_port_t dirport;
|
||||
};
|
||||
|
||||
/** Global list of a dir_server_t object for each directory
|
||||
* authority. */
|
||||
static smartlist_t *trusted_dir_servers = NULL;
|
||||
@ -66,6 +74,11 @@ add_trusted_dir_to_nodelist_addr_set(const dir_server_t *dir)
|
||||
/* IPv6 DirPort is not a thing yet for authorities. */
|
||||
nodelist_add_addr_to_address_set(&dir->ipv6_addr, dir->ipv6_orport, 0);
|
||||
}
|
||||
if (dir->auth_dirports) {
|
||||
SMARTLIST_FOREACH_BEGIN(dir->auth_dirports, const auth_dirport_t *, p) {
|
||||
nodelist_add_addr_to_address_set(&p->dirport.addr, 0, p->dirport.port);
|
||||
} SMARTLIST_FOREACH_END(p);
|
||||
}
|
||||
}
|
||||
|
||||
/** Go over the trusted directory server list and add their address(es) to the
|
||||
@ -256,7 +269,10 @@ MOCK_IMPL(int, router_digest_is_trusted_dir_type,
|
||||
/** Return true iff the given address matches a trusted directory that matches
|
||||
* at least one bit of type.
|
||||
*
|
||||
* If type is NO_DIRINFO or ALL_DIRINFO, any authority is matched. */
|
||||
* If type is NO_DIRINFO or ALL_DIRINFO, any authority is matched.
|
||||
*
|
||||
* Only ORPorts' addresses are considered.
|
||||
*/
|
||||
bool
|
||||
router_addr_is_trusted_dir_type(const tor_addr_t *addr, dirinfo_type_t type)
|
||||
{
|
||||
@ -281,6 +297,42 @@ router_addr_is_trusted_dir_type(const tor_addr_t *addr, dirinfo_type_t type)
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Return an appropriate usage value describing which authdir port to use
|
||||
* for a given directory connection purpose.
|
||||
*/
|
||||
auth_dirport_usage_t
|
||||
auth_dirport_usage_for_purpose(int purpose)
|
||||
{
|
||||
switch (purpose) {
|
||||
case DIR_PURPOSE_FETCH_SERVERDESC:
|
||||
case DIR_PURPOSE_FETCH_EXTRAINFO:
|
||||
case DIR_PURPOSE_FETCH_CONSENSUS:
|
||||
case DIR_PURPOSE_FETCH_CERTIFICATE:
|
||||
case DIR_PURPOSE_FETCH_MICRODESC:
|
||||
return AUTH_USAGE_DOWNLOAD;
|
||||
|
||||
case DIR_PURPOSE_UPLOAD_DIR:
|
||||
return AUTH_USAGE_UPLOAD;
|
||||
|
||||
case DIR_PURPOSE_UPLOAD_VOTE:
|
||||
case DIR_PURPOSE_UPLOAD_SIGNATURES:
|
||||
case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES:
|
||||
case DIR_PURPOSE_FETCH_STATUS_VOTE:
|
||||
return AUTH_USAGE_VOTING;
|
||||
|
||||
case DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2:
|
||||
case DIR_PURPOSE_SERVER:
|
||||
case DIR_PURPOSE_UPLOAD_RENDDESC_V2:
|
||||
case DIR_PURPOSE_FETCH_RENDDESC_V2:
|
||||
case DIR_PURPOSE_UPLOAD_HSDESC:
|
||||
case DIR_PURPOSE_FETCH_HSDESC:
|
||||
case DIR_PURPOSE_HAS_FETCHED_HSDESC:
|
||||
default:
|
||||
tor_assert_nonfatal_unreached();
|
||||
return AUTH_USAGE_LEGACY;
|
||||
}
|
||||
}
|
||||
|
||||
/** Create a directory server at <b>address</b>:<b>port</b>, with OR identity
|
||||
* key <b>digest</b> which has DIGEST_LEN bytes. If <b>address</b> is NULL,
|
||||
* add ourself. If <b>is_authority</b>, this is a directory authority. Return
|
||||
@ -357,6 +409,7 @@ dir_server_new(int is_authority,
|
||||
ent->fake_status.ipv4_dirport = ent->ipv4_dirport;
|
||||
ent->fake_status.ipv4_orport = ent->ipv4_orport;
|
||||
ent->fake_status.ipv6_orport = ent->ipv6_orport;
|
||||
ent->fake_status.is_authority = !! is_authority;
|
||||
|
||||
return ent;
|
||||
}
|
||||
@ -404,10 +457,98 @@ trusted_dir_server_new(const char *nickname, const char *address,
|
||||
ipv6_addrport,
|
||||
digest,
|
||||
v3_auth_digest, type, weight);
|
||||
|
||||
if (ipv4_dirport) {
|
||||
tor_addr_port_t p;
|
||||
memset(&p, 0, sizeof(p));
|
||||
tor_addr_copy(&p.addr, &ipv4_addr);
|
||||
p.port = ipv4_dirport;
|
||||
trusted_dir_server_add_dirport(result, AUTH_USAGE_LEGACY, &p);
|
||||
}
|
||||
tor_free(hostname);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add @a dirport as an HTTP DirPort contact point for the directory authority
|
||||
* @a ds, for use when contacting that authority for the given @a usage.
|
||||
*
|
||||
* Multiple ports of the same usage are allowed; if present, then only
|
||||
* the first one of each address family is currently used.
|
||||
*/
|
||||
void
|
||||
trusted_dir_server_add_dirport(dir_server_t *ds,
|
||||
auth_dirport_usage_t usage,
|
||||
const tor_addr_port_t *dirport)
|
||||
{
|
||||
tor_assert(ds);
|
||||
tor_assert(dirport);
|
||||
|
||||
if (BUG(! ds->is_authority)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ds->auth_dirports == NULL) {
|
||||
ds->auth_dirports = smartlist_new();
|
||||
}
|
||||
|
||||
auth_dirport_t *port = tor_malloc_zero(sizeof(auth_dirport_t));
|
||||
port->usage = usage;
|
||||
tor_addr_port_copy(&port->dirport, dirport);
|
||||
smartlist_add(ds->auth_dirports, port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for trusted_dir_server_get_dirport: only return the exact requested
|
||||
* usage type.
|
||||
*/
|
||||
const tor_addr_port_t *
|
||||
trusted_dir_server_get_dirport_exact(const dir_server_t *ds,
|
||||
auth_dirport_usage_t usage,
|
||||
int addr_family)
|
||||
{
|
||||
tor_assert(ds);
|
||||
tor_assert_nonfatal(addr_family == AF_INET || addr_family == AF_INET6);
|
||||
if (ds->auth_dirports == NULL)
|
||||
return NULL;
|
||||
|
||||
SMARTLIST_FOREACH_BEGIN(ds->auth_dirports, const auth_dirport_t *, port) {
|
||||
if (port->usage == usage &&
|
||||
tor_addr_family(&port->dirport.addr) == addr_family) {
|
||||
return &port->dirport;
|
||||
}
|
||||
} SMARTLIST_FOREACH_END(port);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the DirPort of the authority @a ds for with the usage type
|
||||
* @a usage and address family @a addr_family. If none is found, try
|
||||
* again with an AUTH_USAGE_LEGACY dirport, if there is one. Return NULL
|
||||
* if no port can be found.
|
||||
*/
|
||||
const tor_addr_port_t *
|
||||
trusted_dir_server_get_dirport(const dir_server_t *ds,
|
||||
auth_dirport_usage_t usage,
|
||||
int addr_family)
|
||||
{
|
||||
const tor_addr_port_t *port;
|
||||
|
||||
while (1) {
|
||||
port = trusted_dir_server_get_dirport_exact(ds, usage, addr_family);
|
||||
if (port)
|
||||
return port;
|
||||
|
||||
// If we tried LEGACY, there is no fallback from this point.
|
||||
if (usage == AUTH_USAGE_LEGACY)
|
||||
return NULL;
|
||||
|
||||
// Try again with LEGACY.
|
||||
usage = AUTH_USAGE_LEGACY;
|
||||
}
|
||||
}
|
||||
|
||||
/** Return a new dir_server_t for a fallback directory server at
|
||||
* <b>addr</b>:<b>or_port</b>/<b>dir_port</b>, with identity key digest
|
||||
* <b>id_digest</b> */
|
||||
@ -447,6 +588,10 @@ dir_server_free_(dir_server_t *ds)
|
||||
if (!ds)
|
||||
return;
|
||||
|
||||
if (ds->auth_dirports) {
|
||||
SMARTLIST_FOREACH(ds->auth_dirports, auth_dirport_t *, p, tor_free(p));
|
||||
smartlist_free(ds->auth_dirports);
|
||||
}
|
||||
tor_free(ds->nickname);
|
||||
tor_free(ds->description);
|
||||
tor_free(ds->address);
|
||||
|
@ -11,6 +11,28 @@
|
||||
#ifndef TOR_DIRLIST_H
|
||||
#define TOR_DIRLIST_H
|
||||
|
||||
typedef struct auth_dirport_t auth_dirport_t;
|
||||
/**
|
||||
* Different usages for an authority's HTTP directory port.
|
||||
*
|
||||
* Historically, only legacy ports existed; proposal 330 added multiple types
|
||||
* of dirport to better enable authorities to offload work and resist DoS
|
||||
* attacks.
|
||||
**/
|
||||
typedef enum auth_dirport_usage_t {
|
||||
/** Flag for an authority's dirport that is intended for misc/legacy
|
||||
* usage. May be used when no other dirport is available. */
|
||||
AUTH_USAGE_LEGACY,
|
||||
/** Flag for an authority's dirport that is intended for descriptor uploads
|
||||
* only. */
|
||||
AUTH_USAGE_UPLOAD,
|
||||
/** Flag for an authority's dirport that is intended for voting only */
|
||||
AUTH_USAGE_VOTING,
|
||||
/** Flag for an authority's dirport that is intended for relay downloads
|
||||
* only. */
|
||||
AUTH_USAGE_DOWNLOAD,
|
||||
} auth_dirport_usage_t;
|
||||
|
||||
int get_n_authorities(dirinfo_type_t type);
|
||||
const smartlist_t *router_get_trusted_dir_servers(void);
|
||||
const smartlist_t *router_get_fallback_dir_servers(void);
|
||||
@ -18,6 +40,8 @@ smartlist_t *router_get_trusted_dir_servers_mutable(void);
|
||||
smartlist_t *router_get_fallback_dir_servers_mutable(void);
|
||||
void mark_all_dirservers_up(smartlist_t *server_list);
|
||||
|
||||
auth_dirport_usage_t auth_dirport_usage_for_purpose(int purpose);
|
||||
|
||||
dir_server_t *router_get_trusteddirserver_by_digest(const char *d);
|
||||
dir_server_t *router_get_fallback_dirserver_by_digest(
|
||||
const char *digest);
|
||||
@ -28,6 +52,14 @@ MOCK_DECL(dir_server_t *, trusteddirserver_get_by_v3_auth_digest,
|
||||
MOCK_DECL(int, router_digest_is_trusted_dir_type,
|
||||
(const char *digest, dirinfo_type_t type));
|
||||
|
||||
const tor_addr_port_t *trusted_dir_server_get_dirport(const dir_server_t *ds,
|
||||
auth_dirport_usage_t usage,
|
||||
int addr_family);
|
||||
const tor_addr_port_t *trusted_dir_server_get_dirport_exact(
|
||||
const dir_server_t *ds,
|
||||
auth_dirport_usage_t usage,
|
||||
int addr_family);
|
||||
|
||||
bool router_addr_is_trusted_dir_type(const tor_addr_t *addr,
|
||||
dirinfo_type_t type);
|
||||
#define router_addr_is_trusted_dir(d) \
|
||||
@ -41,6 +73,9 @@ dir_server_t *trusted_dir_server_new(const char *nickname, const char *address,
|
||||
const tor_addr_port_t *addrport_ipv6,
|
||||
const char *digest, const char *v3_auth_digest,
|
||||
dirinfo_type_t type, double weight);
|
||||
void trusted_dir_server_add_dirport(dir_server_t *ds,
|
||||
auth_dirport_usage_t usage,
|
||||
const tor_addr_port_t *dirport);
|
||||
dir_server_t *fallback_dir_server_new(const tor_addr_t *addr,
|
||||
uint16_t dir_port, uint16_t or_port,
|
||||
const tor_addr_port_t *addrport_ipv6,
|
||||
|
@ -170,6 +170,7 @@ src_test_test_SOURCES += \
|
||||
src/test/test_crypto_rng.c \
|
||||
src/test/test_data.c \
|
||||
src/test/test_dir.c \
|
||||
src/test/test_dirauth_ports.c \
|
||||
src/test/test_dirvote.c \
|
||||
src/test/test_dir_common.c \
|
||||
src/test/test_dir_handle_get.c \
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* Copyright (c) 2001-2004, Roger Dingledine.
|
||||
->a * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||
* Copyright (c) 2007-2021, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
@ -673,6 +672,7 @@ struct testgroup_t testgroups[] = {
|
||||
{ "crypto/pem/", pem_tests },
|
||||
{ "crypto/rng/", crypto_rng_tests },
|
||||
{ "dir/", dir_tests },
|
||||
{ "dir/auth/ports/", dirauth_port_tests },
|
||||
{ "dir/auth/process_descs/", process_descs_tests },
|
||||
{ "dir/md/", microdesc_tests },
|
||||
{ "dirauth/dirvote/", dirvote_tests},
|
||||
|
@ -120,6 +120,7 @@ extern struct testcase_t crypto_ope_tests[];
|
||||
extern struct testcase_t crypto_openssl_tests[];
|
||||
extern struct testcase_t crypto_rng_tests[];
|
||||
extern struct testcase_t crypto_tests[];
|
||||
extern struct testcase_t dirauth_port_tests[];
|
||||
extern struct testcase_t dir_handle_get_tests[];
|
||||
extern struct testcase_t dir_tests[];
|
||||
extern struct testcase_t dirvote_tests[];
|
||||
|
152
src/test/test_dirauth_ports.c
Normal file
152
src/test/test_dirauth_ports.c
Normal file
@ -0,0 +1,152 @@
|
||||
/* Copyright (c) 2001-2004, Roger Dingledine.
|
||||
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||
* Copyright (c) 2007-2021, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
#include "orconfig.h"
|
||||
#define CONFIG_PRIVATE
|
||||
|
||||
#include "core/or/or.h"
|
||||
#include "feature/dirclient/dir_server_st.h"
|
||||
#include "feature/nodelist/dirlist.h"
|
||||
#include "app/config/config.h"
|
||||
#include "test/test.h"
|
||||
#include "test/log_test_helpers.h"
|
||||
|
||||
static void
|
||||
test_dirauth_port_parsing(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
|
||||
// This one is okay.
|
||||
int rv = parse_dir_authority_line(
|
||||
"moria1 orport=9101 "
|
||||
"v3ident=D586D18309DED4CD6D57C18FDB97EFA96D330566 "
|
||||
"upload=http://128.31.0.39:9131/ "
|
||||
"download=http://128.31.0.39:9131 "
|
||||
"vote=http://128.31.0.39:9131/ "
|
||||
"128.31.0.39:9131 9695 DFC3 5FFE B861 329B 9F1A B04C 4639 7020 CE31",
|
||||
NO_DIRINFO, 1);
|
||||
tt_int_op(rv,OP_EQ,0);
|
||||
|
||||
// These have bad syntax.
|
||||
setup_capture_of_logs(LOG_WARN);
|
||||
rv = parse_dir_authority_line(
|
||||
"moria1 orport=9101 "
|
||||
"v3ident=D586D18309DED4CD6D57C18FDB97EFA96D330566 "
|
||||
"uploadx=http://128.31.0.39:9131/ "
|
||||
"128.31.0.39:9131 9695 DFC3 5FFE B861 329B 9F1A B04C 4639 7020 CE31",
|
||||
NO_DIRINFO, 1);
|
||||
tt_int_op(rv,OP_EQ,0);
|
||||
expect_log_msg_containing("Unrecognized flag");
|
||||
mock_clean_saved_logs();
|
||||
|
||||
rv = parse_dir_authority_line(
|
||||
"moria1 orport=9101 "
|
||||
"v3ident=D586D18309DED4CD6D57C18FDB97EFA96D330566 "
|
||||
"upload=https://128.31.0.39:9131/ " // https is not recognized
|
||||
"128.31.0.39:9131 9695 DFC3 5FFE B861 329B 9F1A B04C 4639 7020 CE31",
|
||||
NO_DIRINFO, 1);
|
||||
tt_int_op(rv,OP_EQ,-1);
|
||||
expect_log_msg_containing("Unsupported URL scheme");
|
||||
mock_clean_saved_logs();
|
||||
|
||||
rv = parse_dir_authority_line(
|
||||
"moria1 orport=9101 "
|
||||
"v3ident=D586D18309DED4CD6D57C18FDB97EFA96D330566 "
|
||||
"upload=http://128.31.0.39:9131/tor " // suffix is not supported
|
||||
"128.31.0.39:9131 9695 DFC3 5FFE B861 329B 9F1A B04C 4639 7020 CE31",
|
||||
NO_DIRINFO, 1);
|
||||
tt_int_op(rv,OP_EQ,-1);
|
||||
expect_log_msg_containing("Unsupported URL prefix");
|
||||
mock_clean_saved_logs();
|
||||
|
||||
rv = parse_dir_authority_line(
|
||||
"moria1 orport=9101 "
|
||||
"v3ident=D586D18309DED4CD6D57C18FDB97EFA96D330566 "
|
||||
"upload=http://128.31.0.256:9131/ " // "256" is not ipv4.
|
||||
"128.31.0.39:9131 9695 DFC3 5FFE B861 329B 9F1A B04C 4639 7020 CE31",
|
||||
NO_DIRINFO, 1);
|
||||
tt_int_op(rv,OP_EQ,-1);
|
||||
expect_log_msg_containing("Unable to parse address");
|
||||
|
||||
rv = parse_dir_authority_line(
|
||||
"moria1 orport=9101 "
|
||||
"v3ident=D586D18309DED4CD6D57C18FDB97EFA96D330566 "
|
||||
"upload=http://xyz.example.com/ " // hostnames not supported.
|
||||
"128.31.0.39:9131 9695 DFC3 5FFE B861 329B 9F1A B04C 4639 7020 CE31",
|
||||
NO_DIRINFO, 1);
|
||||
tt_int_op(rv,OP_EQ,-1);
|
||||
expect_log_msg_containing("Unable to parse address");
|
||||
|
||||
done:
|
||||
teardown_capture_of_logs();
|
||||
}
|
||||
|
||||
static void
|
||||
test_dirauth_port_lookup(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
|
||||
clear_dir_servers();
|
||||
|
||||
int rv = parse_dir_authority_line(
|
||||
"moria1 orport=9101 "
|
||||
"v3ident=D586D18309DED4CD6D57C18FDB97EFA96D330566 "
|
||||
"upload=http://128.31.0.40:9132/ "
|
||||
"download=http://128.31.0.41:9133 "
|
||||
"vote=http://128.31.0.42:9134/ "
|
||||
"128.31.0.39:9131 9695 DFC3 5FFE B861 329B 9F1A B04C 4639 7020 CE31",
|
||||
NO_DIRINFO, 0);
|
||||
tt_int_op(rv,OP_EQ,0);
|
||||
|
||||
rv = parse_dir_authority_line(
|
||||
"morgoth orport=9101 "
|
||||
"v3ident=D586D18309DED4CDFFFFFFFFDB97EFA96D330566 "
|
||||
"upload=http://128.31.0.43:9140/ "
|
||||
"128.31.0.44:9131 9695 DFC3 5FFE B861 329B 9F1A B04C 4639 7020 CE31",
|
||||
NO_DIRINFO, 0);
|
||||
tt_int_op(rv,OP_EQ,0);
|
||||
|
||||
const smartlist_t *servers = router_get_trusted_dir_servers();
|
||||
tt_assert(servers);
|
||||
tt_int_op(smartlist_len(servers), OP_EQ, 2);
|
||||
const dir_server_t *moria = smartlist_get(servers, 0);
|
||||
const dir_server_t *morgoth = smartlist_get(servers, 1);
|
||||
tt_str_op(moria->nickname, OP_EQ, "moria1");
|
||||
tt_str_op(morgoth->nickname, OP_EQ, "morgoth");
|
||||
|
||||
const tor_addr_port_t *dirport;
|
||||
|
||||
dirport = trusted_dir_server_get_dirport(moria,
|
||||
AUTH_USAGE_UPLOAD, AF_INET);
|
||||
tt_int_op(dirport->port, OP_EQ, 9132);
|
||||
dirport = trusted_dir_server_get_dirport(moria,
|
||||
AUTH_USAGE_DOWNLOAD, AF_INET);
|
||||
tt_int_op(dirport->port, OP_EQ, 9133);
|
||||
dirport = trusted_dir_server_get_dirport(moria,
|
||||
AUTH_USAGE_VOTING, AF_INET);
|
||||
tt_int_op(dirport->port, OP_EQ, 9134);
|
||||
|
||||
dirport = trusted_dir_server_get_dirport(morgoth,
|
||||
AUTH_USAGE_UPLOAD, AF_INET);
|
||||
tt_int_op(dirport->port, OP_EQ, 9140);
|
||||
dirport = trusted_dir_server_get_dirport(morgoth,
|
||||
AUTH_USAGE_DOWNLOAD, AF_INET);
|
||||
tt_int_op(dirport->port, OP_EQ, 9131); // fallback
|
||||
dirport = trusted_dir_server_get_dirport(morgoth,
|
||||
AUTH_USAGE_VOTING, AF_INET);
|
||||
tt_int_op(dirport->port, OP_EQ, 9131); // fallback
|
||||
|
||||
done:
|
||||
;
|
||||
}
|
||||
|
||||
#define T(name) \
|
||||
{ #name, test_dirauth_port_ ## name, TT_FORK, NULL, NULL }
|
||||
|
||||
struct testcase_t dirauth_port_tests[] = {
|
||||
T(parsing),
|
||||
T(lookup),
|
||||
END_OF_TESTCASES
|
||||
};
|
Loading…
Reference in New Issue
Block a user