mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2025-02-26 23:52:30 +01:00
Allow ClientTransportPlugins to use proxies
This change allows using Socks4Proxy, Socks5Proxy and HTTPSProxy with ClientTransportPlugins via the TOR_PT_PROXY extension to the pluggable transport specification. This fixes bug #8402.
This commit is contained in:
parent
fef65fa643
commit
41d2b4d3af
5 changed files with 251 additions and 23 deletions
|
@ -3174,11 +3174,11 @@ options_validate(or_options_t *old_options, or_options_t *options,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if more than one proxy type has been enabled. */
|
/* Check if more than one exclusive proxy type has been enabled. */
|
||||||
if (!!options->Socks4Proxy + !!options->Socks5Proxy +
|
if (!!options->Socks4Proxy + !!options->Socks5Proxy +
|
||||||
!!options->HTTPSProxy + !!options->ClientTransportPlugin > 1)
|
!!options->HTTPSProxy > 1)
|
||||||
REJECT("You have configured more than one proxy type. "
|
REJECT("You have configured more than one proxy type. "
|
||||||
"(Socks4Proxy|Socks5Proxy|HTTPSProxy|ClientTransportPlugin)");
|
"(Socks4Proxy|Socks5Proxy|HTTPSProxy)");
|
||||||
|
|
||||||
/* Check if the proxies will give surprising behavior. */
|
/* Check if the proxies will give surprising behavior. */
|
||||||
if (options->HTTPProxy && !(options->Socks4Proxy ||
|
if (options->HTTPProxy && !(options->Socks4Proxy ||
|
||||||
|
@ -4842,6 +4842,13 @@ parse_client_transport_line(const or_options_t *options,
|
||||||
pt_kickstart_client_proxy(transport_list, proxy_argv);
|
pt_kickstart_client_proxy(transport_list, proxy_argv);
|
||||||
}
|
}
|
||||||
} else { /* external */
|
} else { /* external */
|
||||||
|
/* ClientTransportPlugins connecting through a proxy is managed only. */
|
||||||
|
if (options->Socks4Proxy || options->Socks5Proxy || options->HTTPSProxy) {
|
||||||
|
log_warn(LD_CONFIG, "You have configured an external proxy with another "
|
||||||
|
"proxy type. (Socks4Proxy|Socks5Proxy|HTTPSProxy)");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
if (smartlist_len(transport_list) != 1) {
|
if (smartlist_len(transport_list) != 1) {
|
||||||
log_warn(LD_CONFIG, "You can't have an external proxy with "
|
log_warn(LD_CONFIG, "You can't have an external proxy with "
|
||||||
"more than one transports.");
|
"more than one transports.");
|
||||||
|
|
|
@ -86,6 +86,8 @@ static int connection_read_https_proxy_response(connection_t *conn);
|
||||||
static void connection_send_socks5_connect(connection_t *conn);
|
static void connection_send_socks5_connect(connection_t *conn);
|
||||||
static const char *proxy_type_to_string(int proxy_type);
|
static const char *proxy_type_to_string(int proxy_type);
|
||||||
static int get_proxy_type(void);
|
static int get_proxy_type(void);
|
||||||
|
static int get_bridge_pt_addrport(tor_addr_t *addr, uint16_t *port,
|
||||||
|
int *proxy_type, const connection_t *conn);
|
||||||
|
|
||||||
/** The last addresses that our network interface seemed to have been
|
/** The last addresses that our network interface seemed to have been
|
||||||
* binding to. We use this as one way to detect when our IP changes.
|
* binding to. We use this as one way to detect when our IP changes.
|
||||||
|
@ -1689,14 +1691,14 @@ get_proxy_type(void)
|
||||||
{
|
{
|
||||||
const or_options_t *options = get_options();
|
const or_options_t *options = get_options();
|
||||||
|
|
||||||
if (options->HTTPSProxy)
|
if (options->ClientTransportPlugin)
|
||||||
|
return PROXY_PLUGGABLE;
|
||||||
|
else if (options->HTTPSProxy)
|
||||||
return PROXY_CONNECT;
|
return PROXY_CONNECT;
|
||||||
else if (options->Socks4Proxy)
|
else if (options->Socks4Proxy)
|
||||||
return PROXY_SOCKS4;
|
return PROXY_SOCKS4;
|
||||||
else if (options->Socks5Proxy)
|
else if (options->Socks5Proxy)
|
||||||
return PROXY_SOCKS5;
|
return PROXY_SOCKS5;
|
||||||
else if (options->ClientTransportPlugin)
|
|
||||||
return PROXY_PLUGGABLE;
|
|
||||||
else
|
else
|
||||||
return PROXY_NONE;
|
return PROXY_NONE;
|
||||||
}
|
}
|
||||||
|
@ -4770,6 +4772,35 @@ assert_connection_ok(connection_t *conn, time_t now)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Fills <b>addr</b> and <b>port</b> with the details of the global
|
||||||
|
* pluggable transport or bridge we are using.
|
||||||
|
* <b>conn</b> contains the connection we are using the PT/bridge for.
|
||||||
|
*
|
||||||
|
* Return 0 on success, -1 on failure.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
get_bridge_pt_addrport(tor_addr_t *addr, uint16_t *port, int *proxy_type,
|
||||||
|
const connection_t *conn)
|
||||||
|
{
|
||||||
|
const or_options_t *options = get_options();
|
||||||
|
|
||||||
|
if (options->ClientTransportPlugin || options->Bridges) {
|
||||||
|
const transport_t *transport = NULL;
|
||||||
|
int r;
|
||||||
|
r = get_transport_by_bridge_addrport(&conn->addr, conn->port, &transport);
|
||||||
|
if (r<0)
|
||||||
|
return -1;
|
||||||
|
if (transport) { /* transport found */
|
||||||
|
tor_addr_copy(addr, &transport->addr);
|
||||||
|
*port = transport->port;
|
||||||
|
*proxy_type = transport->socks_version;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/** Fills <b>addr</b> and <b>port</b> with the details of the global
|
/** Fills <b>addr</b> and <b>port</b> with the details of the global
|
||||||
* proxy server we are using.
|
* proxy server we are using.
|
||||||
* <b>conn</b> contains the connection we are using the proxy for.
|
* <b>conn</b> contains the connection we are using the proxy for.
|
||||||
|
@ -4782,6 +4813,16 @@ get_proxy_addrport(tor_addr_t *addr, uint16_t *port, int *proxy_type,
|
||||||
{
|
{
|
||||||
const or_options_t *options = get_options();
|
const or_options_t *options = get_options();
|
||||||
|
|
||||||
|
/* Client Transport Plugins can use another proxy, but that should be hidden
|
||||||
|
* from the rest of tor (as the plugin is responsible for dealing with the
|
||||||
|
* proxy), check it first, then check the rest of the proxy types to allow
|
||||||
|
* the config to have unused ClientTransportPlugin entries.
|
||||||
|
*/
|
||||||
|
if (options->ClientTransportPlugin) {
|
||||||
|
if (get_bridge_pt_addrport(addr, port, proxy_type, conn) == 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (options->HTTPSProxy) {
|
if (options->HTTPSProxy) {
|
||||||
tor_addr_copy(addr, &options->HTTPSProxyAddr);
|
tor_addr_copy(addr, &options->HTTPSProxyAddr);
|
||||||
*port = options->HTTPSProxyPort;
|
*port = options->HTTPSProxyPort;
|
||||||
|
@ -4797,19 +4838,8 @@ get_proxy_addrport(tor_addr_t *addr, uint16_t *port, int *proxy_type,
|
||||||
*port = options->Socks5ProxyPort;
|
*port = options->Socks5ProxyPort;
|
||||||
*proxy_type = PROXY_SOCKS5;
|
*proxy_type = PROXY_SOCKS5;
|
||||||
return 0;
|
return 0;
|
||||||
} else if (options->ClientTransportPlugin ||
|
} else if (options->Bridges) {
|
||||||
options->Bridges) {
|
return get_bridge_pt_addrport(addr, port, proxy_type, conn);
|
||||||
const transport_t *transport = NULL;
|
|
||||||
int r;
|
|
||||||
r = get_transport_by_bridge_addrport(&conn->addr, conn->port, &transport);
|
|
||||||
if (r<0)
|
|
||||||
return -1;
|
|
||||||
if (transport) { /* transport found */
|
|
||||||
tor_addr_copy(addr, &transport->addr);
|
|
||||||
*port = transport->port;
|
|
||||||
*proxy_type = transport->socks_version;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tor_addr_make_unspec(addr);
|
tor_addr_make_unspec(addr);
|
||||||
|
|
|
@ -124,6 +124,8 @@ static INLINE void free_execve_args(char **arg);
|
||||||
#define PROTO_SMETHOD_ERROR "SMETHOD-ERROR"
|
#define PROTO_SMETHOD_ERROR "SMETHOD-ERROR"
|
||||||
#define PROTO_CMETHODS_DONE "CMETHODS DONE"
|
#define PROTO_CMETHODS_DONE "CMETHODS DONE"
|
||||||
#define PROTO_SMETHODS_DONE "SMETHODS DONE"
|
#define PROTO_SMETHODS_DONE "SMETHODS DONE"
|
||||||
|
#define PROTO_PROXY_DONE "PROXY DONE"
|
||||||
|
#define PROTO_PROXY_ERROR "PROXY-ERROR"
|
||||||
|
|
||||||
/** The first and only supported - at the moment - configuration
|
/** The first and only supported - at the moment - configuration
|
||||||
protocol version. */
|
protocol version. */
|
||||||
|
@ -439,6 +441,17 @@ add_transport_to_proxy(const char *transport, managed_proxy_t *mp)
|
||||||
static int
|
static int
|
||||||
proxy_needs_restart(const managed_proxy_t *mp)
|
proxy_needs_restart(const managed_proxy_t *mp)
|
||||||
{
|
{
|
||||||
|
int ret = 1;
|
||||||
|
char* proxy_uri;
|
||||||
|
|
||||||
|
/* If the PT proxy config has changed, then all existing pluggable transports
|
||||||
|
* should be restarted.
|
||||||
|
*/
|
||||||
|
|
||||||
|
proxy_uri = get_pt_proxy_uri();
|
||||||
|
if (strcmp_opt(proxy_uri, mp->proxy_uri) != 0)
|
||||||
|
goto needs_restart;
|
||||||
|
|
||||||
/* mp->transport_to_launch is populated with the names of the
|
/* mp->transport_to_launch is populated with the names of the
|
||||||
transports that must be launched *after* the SIGHUP.
|
transports that must be launched *after* the SIGHUP.
|
||||||
mp->transports is populated with the transports that were
|
mp->transports is populated with the transports that were
|
||||||
|
@ -459,10 +472,10 @@ proxy_needs_restart(const managed_proxy_t *mp)
|
||||||
|
|
||||||
} SMARTLIST_FOREACH_END(t);
|
} SMARTLIST_FOREACH_END(t);
|
||||||
|
|
||||||
return 0;
|
ret = 0;
|
||||||
|
|
||||||
needs_restart:
|
needs_restart:
|
||||||
return 1;
|
tor_free(proxy_uri);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Managed proxy <b>mp</b> must be restarted. Do all the necessary
|
/** Managed proxy <b>mp</b> must be restarted. Do all the necessary
|
||||||
|
@ -493,6 +506,11 @@ proxy_prepare_for_restart(managed_proxy_t *mp)
|
||||||
SMARTLIST_FOREACH(mp->transports, transport_t *, t, transport_free(t));
|
SMARTLIST_FOREACH(mp->transports, transport_t *, t, transport_free(t));
|
||||||
smartlist_clear(mp->transports);
|
smartlist_clear(mp->transports);
|
||||||
|
|
||||||
|
/* Reset the proxy's HTTPS/SOCKS proxy */
|
||||||
|
tor_free(mp->proxy_uri);
|
||||||
|
mp->proxy_uri = get_pt_proxy_uri();
|
||||||
|
mp->proxy_supported = 0;
|
||||||
|
|
||||||
/* flag it as an infant proxy so that it gets launched on next tick */
|
/* flag it as an infant proxy so that it gets launched on next tick */
|
||||||
mp->conf_state = PT_PROTO_INFANT;
|
mp->conf_state = PT_PROTO_INFANT;
|
||||||
unconfigured_proxies_n++;
|
unconfigured_proxies_n++;
|
||||||
|
@ -727,12 +745,52 @@ managed_proxy_destroy(managed_proxy_t *mp,
|
||||||
/* free the argv */
|
/* free the argv */
|
||||||
free_execve_args(mp->argv);
|
free_execve_args(mp->argv);
|
||||||
|
|
||||||
|
/* free the outgoing proxy URI */
|
||||||
|
tor_free(mp->proxy_uri);
|
||||||
|
|
||||||
tor_process_handle_destroy(mp->process_handle, also_terminate_process);
|
tor_process_handle_destroy(mp->process_handle, also_terminate_process);
|
||||||
mp->process_handle = NULL;
|
mp->process_handle = NULL;
|
||||||
|
|
||||||
tor_free(mp);
|
tor_free(mp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Convert the tor proxy options to a URI suitable for TOR_PT_PROXY. */
|
||||||
|
STATIC char *
|
||||||
|
get_pt_proxy_uri(void)
|
||||||
|
{
|
||||||
|
const or_options_t *options = get_options();
|
||||||
|
char *uri = NULL;
|
||||||
|
|
||||||
|
if (options->Socks4Proxy || options->Socks5Proxy || options->HTTPSProxy) {
|
||||||
|
char addr[TOR_ADDR_BUF_LEN+1];
|
||||||
|
|
||||||
|
if (options->Socks4Proxy) {
|
||||||
|
tor_addr_to_str(addr, &options->Socks4ProxyAddr, sizeof(addr), 1);
|
||||||
|
tor_asprintf(&uri, "socks4a://%s:%d", addr, options->Socks4ProxyPort);
|
||||||
|
} else if (options->Socks5Proxy) {
|
||||||
|
tor_addr_to_str(addr, &options->Socks5ProxyAddr, sizeof(addr), 1);
|
||||||
|
if (!options->Socks5ProxyUsername && !options->Socks5ProxyPassword) {
|
||||||
|
tor_asprintf(&uri, "socks5://%s:%d", addr, options->Socks5ProxyPort);
|
||||||
|
} else {
|
||||||
|
tor_asprintf(&uri, "socks5://%s:%s@%s:%d",
|
||||||
|
options->Socks5ProxyUsername,
|
||||||
|
options->Socks5ProxyPassword,
|
||||||
|
addr, options->Socks5ProxyPort);
|
||||||
|
}
|
||||||
|
} else if (options->HTTPSProxy) {
|
||||||
|
tor_addr_to_str(addr, &options->HTTPSProxyAddr, sizeof(addr), 1);
|
||||||
|
if (!options->HTTPSProxyAuthenticator) {
|
||||||
|
tor_asprintf(&uri, "http://%s:%d", addr, options->HTTPSProxyPort);
|
||||||
|
} else {
|
||||||
|
tor_asprintf(&uri, "http://%s@%s:%d", options->HTTPSProxyAuthenticator,
|
||||||
|
addr, options->HTTPSProxyPort);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return uri;
|
||||||
|
}
|
||||||
|
|
||||||
/** Handle a configured or broken managed proxy <b>mp</b>. */
|
/** Handle a configured or broken managed proxy <b>mp</b>. */
|
||||||
static void
|
static void
|
||||||
handle_finished_proxy(managed_proxy_t *mp)
|
handle_finished_proxy(managed_proxy_t *mp)
|
||||||
|
@ -745,6 +803,12 @@ handle_finished_proxy(managed_proxy_t *mp)
|
||||||
managed_proxy_destroy(mp, 0); /* destroy it but don't terminate */
|
managed_proxy_destroy(mp, 0); /* destroy it but don't terminate */
|
||||||
break;
|
break;
|
||||||
case PT_PROTO_CONFIGURED: /* if configured correctly: */
|
case PT_PROTO_CONFIGURED: /* if configured correctly: */
|
||||||
|
if (mp->proxy_uri && !mp->proxy_supported) {
|
||||||
|
log_warn(LD_CONFIG, "Managed proxy '%s' did not configure the "
|
||||||
|
"specified outgoing proxy.", mp->argv[0]);
|
||||||
|
managed_proxy_destroy(mp, 1); /* annihilate it. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
register_proxy(mp); /* register its transports */
|
register_proxy(mp); /* register its transports */
|
||||||
mp->conf_state = PT_PROTO_COMPLETED; /* and mark it as completed. */
|
mp->conf_state = PT_PROTO_COMPLETED; /* and mark it as completed. */
|
||||||
break;
|
break;
|
||||||
|
@ -862,6 +926,22 @@ handle_proxy_line(const char *line, managed_proxy_t *mp)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
} else if (!strcmpstart(line, PROTO_PROXY_DONE)) {
|
||||||
|
if (mp->conf_state != PT_PROTO_ACCEPTING_METHODS)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (mp->proxy_uri) {
|
||||||
|
mp->proxy_supported = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No proxy was configured, this should log */
|
||||||
|
} else if (!strcmpstart(line, PROTO_PROXY_ERROR)) {
|
||||||
|
if (mp->conf_state != PT_PROTO_ACCEPTING_METHODS)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
parse_proxy_error(line);
|
||||||
|
goto err;
|
||||||
} else if (!strcmpstart(line, SPAWN_ERROR_MESSAGE)) {
|
} else if (!strcmpstart(line, SPAWN_ERROR_MESSAGE)) {
|
||||||
/* managed proxy launch failed: parse error message to learn why. */
|
/* managed proxy launch failed: parse error message to learn why. */
|
||||||
int retval, child_state, saved_errno;
|
int retval, child_state, saved_errno;
|
||||||
|
@ -1128,6 +1208,21 @@ parse_cmethod_line(const char *line, managed_proxy_t *mp)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Parses an PROXY-ERROR <b>line</b> and warns the user accordingly. */
|
||||||
|
STATIC void
|
||||||
|
parse_proxy_error(const char *line)
|
||||||
|
{
|
||||||
|
/* (Length of the protocol string) plus (a space) and (the first char of
|
||||||
|
the error message) */
|
||||||
|
if (strlen(line) < (strlen(PROTO_PROXY_ERROR) + 2))
|
||||||
|
log_notice(LD_CONFIG, "Managed proxy sent us an %s without an error "
|
||||||
|
"message.", PROTO_PROXY_ERROR);
|
||||||
|
|
||||||
|
log_warn(LD_CONFIG, "Managed proxy failed to configure the "
|
||||||
|
"pluggable transport's outgoing proxy. (%s)",
|
||||||
|
line+strlen(PROTO_PROXY_ERROR)+1);
|
||||||
|
}
|
||||||
|
|
||||||
/** Return a newly allocated string that tor should place in
|
/** Return a newly allocated string that tor should place in
|
||||||
* TOR_PT_SERVER_TRANSPORT_OPTIONS while configuring the server
|
* TOR_PT_SERVER_TRANSPORT_OPTIONS while configuring the server
|
||||||
* manged proxy in <b>mp</b>. Return NULL if no such options are found. */
|
* manged proxy in <b>mp</b>. Return NULL if no such options are found. */
|
||||||
|
@ -1292,6 +1387,14 @@ create_managed_proxy_environment(const managed_proxy_t *mp)
|
||||||
} else {
|
} else {
|
||||||
smartlist_add_asprintf(envs, "TOR_PT_EXTENDED_SERVER_PORT=");
|
smartlist_add_asprintf(envs, "TOR_PT_EXTENDED_SERVER_PORT=");
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
/* If ClientTransportPlugin has a HTTPS/SOCKS proxy configured, set the
|
||||||
|
* TOR_PT_PROXY line.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (mp->proxy_uri) {
|
||||||
|
smartlist_add_asprintf(envs, "TOR_PT_PROXY=%s", mp->proxy_uri);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SMARTLIST_FOREACH_BEGIN(envs, const char *, env_var) {
|
SMARTLIST_FOREACH_BEGIN(envs, const char *, env_var) {
|
||||||
|
@ -1324,6 +1427,7 @@ managed_proxy_create(const smartlist_t *transport_list,
|
||||||
mp->is_server = is_server;
|
mp->is_server = is_server;
|
||||||
mp->argv = proxy_argv;
|
mp->argv = proxy_argv;
|
||||||
mp->transports = smartlist_new();
|
mp->transports = smartlist_new();
|
||||||
|
mp->proxy_uri = get_pt_proxy_uri();
|
||||||
|
|
||||||
mp->transports_to_launch = smartlist_new();
|
mp->transports_to_launch = smartlist_new();
|
||||||
SMARTLIST_FOREACH(transport_list, const char *, transport,
|
SMARTLIST_FOREACH(transport_list, const char *, transport,
|
||||||
|
|
|
@ -81,6 +81,9 @@ typedef struct {
|
||||||
char **argv; /* the cli arguments of this proxy */
|
char **argv; /* the cli arguments of this proxy */
|
||||||
int conf_protocol; /* the configuration protocol version used */
|
int conf_protocol; /* the configuration protocol version used */
|
||||||
|
|
||||||
|
char *proxy_uri; /* the outgoing proxy in TOR_PT_PROXY URI format */
|
||||||
|
int proxy_supported : 1; /* the proxy claims to honor TOR_PT_PROXY */
|
||||||
|
|
||||||
int is_server; /* is it a server proxy? */
|
int is_server; /* is it a server proxy? */
|
||||||
|
|
||||||
/* A pointer to the process handle of this managed proxy. */
|
/* A pointer to the process handle of this managed proxy. */
|
||||||
|
@ -112,6 +115,7 @@ STATIC int parse_smethod_line(const char *line, managed_proxy_t *mp);
|
||||||
|
|
||||||
STATIC int parse_version(const char *line, managed_proxy_t *mp);
|
STATIC int parse_version(const char *line, managed_proxy_t *mp);
|
||||||
STATIC void parse_env_error(const char *line);
|
STATIC void parse_env_error(const char *line);
|
||||||
|
STATIC void parse_proxy_error(const char *line);
|
||||||
STATIC void handle_proxy_line(const char *line, managed_proxy_t *mp);
|
STATIC void handle_proxy_line(const char *line, managed_proxy_t *mp);
|
||||||
STATIC char *get_transport_options_for_server_proxy(const managed_proxy_t *mp);
|
STATIC char *get_transport_options_for_server_proxy(const managed_proxy_t *mp);
|
||||||
|
|
||||||
|
@ -123,6 +127,8 @@ STATIC managed_proxy_t *managed_proxy_create(const smartlist_t *transport_list,
|
||||||
|
|
||||||
STATIC int configure_proxy(managed_proxy_t *mp);
|
STATIC int configure_proxy(managed_proxy_t *mp);
|
||||||
|
|
||||||
|
STATIC char* get_pt_proxy_uri(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -450,6 +450,85 @@ test_pt_configure_proxy(void *arg)
|
||||||
tor_free(mp);
|
tor_free(mp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Test the get_pt_proxy_uri() function. */
|
||||||
|
static void
|
||||||
|
test_get_pt_proxy_uri(void *arg)
|
||||||
|
{
|
||||||
|
or_options_t *options = get_options_mutable();
|
||||||
|
char *uri = NULL;
|
||||||
|
int ret;
|
||||||
|
(void) arg;
|
||||||
|
|
||||||
|
/* Test with no proxy. */
|
||||||
|
uri = get_pt_proxy_uri();
|
||||||
|
tt_assert(uri == NULL);
|
||||||
|
|
||||||
|
/* Test with a SOCKS4 proxy. */
|
||||||
|
options->Socks4Proxy = "192.0.2.1:1080";
|
||||||
|
ret = tor_addr_port_lookup(options->Socks4Proxy,
|
||||||
|
&options->Socks4ProxyAddr,
|
||||||
|
&options->Socks4ProxyPort);
|
||||||
|
tt_assert(ret == 0);
|
||||||
|
uri = get_pt_proxy_uri();
|
||||||
|
tt_str_op(uri, ==, "socks4a://192.0.2.1:1080");
|
||||||
|
tor_free(uri);
|
||||||
|
|
||||||
|
options->Socks4Proxy = NULL;
|
||||||
|
|
||||||
|
/* Test with a SOCKS5 proxy, no username/password. */
|
||||||
|
options->Socks5Proxy = "192.0.2.1:1080";
|
||||||
|
ret = tor_addr_port_lookup(options->Socks5Proxy,
|
||||||
|
&options->Socks5ProxyAddr,
|
||||||
|
&options->Socks5ProxyPort);
|
||||||
|
tt_assert(ret == 0);
|
||||||
|
uri = get_pt_proxy_uri();
|
||||||
|
tt_str_op(uri, ==, "socks5://192.0.2.1:1080");
|
||||||
|
tor_free(uri);
|
||||||
|
|
||||||
|
/* Test with a SOCKS5 proxy, with username/password. */
|
||||||
|
options->Socks5ProxyUsername = "hwest";
|
||||||
|
options->Socks5ProxyPassword = "r34n1m470r";
|
||||||
|
uri = get_pt_proxy_uri();
|
||||||
|
tt_str_op(uri, ==, "socks5://hwest:r34n1m470r@192.0.2.1:1080");
|
||||||
|
tor_free(uri);
|
||||||
|
|
||||||
|
options->Socks5Proxy = NULL;
|
||||||
|
|
||||||
|
/* Test with a HTTPS proxy, no authenticator. */
|
||||||
|
options->HTTPSProxy = "192.0.2.1:80";
|
||||||
|
ret = tor_addr_port_lookup(options->HTTPSProxy,
|
||||||
|
&options->HTTPSProxyAddr,
|
||||||
|
&options->HTTPSProxyPort);
|
||||||
|
tt_assert(ret == 0);
|
||||||
|
uri = get_pt_proxy_uri();
|
||||||
|
tt_str_op(uri, ==, "http://192.0.2.1:80");
|
||||||
|
tor_free(uri);
|
||||||
|
|
||||||
|
/* Test with a HTTPS proxy, with authenticator. */
|
||||||
|
options->HTTPSProxyAuthenticator = "hwest:r34n1m470r";
|
||||||
|
uri = get_pt_proxy_uri();
|
||||||
|
tt_str_op(uri, ==, "http://hwest:r34n1m470r@192.0.2.1:80");
|
||||||
|
tor_free(uri);
|
||||||
|
|
||||||
|
options->HTTPSProxy = NULL;
|
||||||
|
|
||||||
|
/* Token nod to the fact that IPv6 exists. */
|
||||||
|
options->Socks4Proxy = "[2001:db8::1]:1080";
|
||||||
|
ret = tor_addr_port_lookup(options->Socks4Proxy,
|
||||||
|
&options->Socks4ProxyAddr,
|
||||||
|
&options->Socks4ProxyPort);
|
||||||
|
tt_assert(ret == 0);
|
||||||
|
uri = get_pt_proxy_uri();
|
||||||
|
tt_str_op(uri, ==, "socks4a://[2001:db8::1]:1080");
|
||||||
|
tor_free(uri);
|
||||||
|
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (uri)
|
||||||
|
tor_free(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define PT_LEGACY(name) \
|
#define PT_LEGACY(name) \
|
||||||
{ #name, legacy_test_helper, 0, &legacy_setup, test_pt_ ## name }
|
{ #name, legacy_test_helper, 0, &legacy_setup, test_pt_ ## name }
|
||||||
|
|
||||||
|
@ -462,6 +541,8 @@ struct testcase_t pt_tests[] = {
|
||||||
NULL, NULL },
|
NULL, NULL },
|
||||||
{ "configure_proxy",test_pt_configure_proxy, TT_FORK,
|
{ "configure_proxy",test_pt_configure_proxy, TT_FORK,
|
||||||
NULL, NULL },
|
NULL, NULL },
|
||||||
|
{ "get_pt_proxy_uri", test_get_pt_proxy_uri, TT_FORK,
|
||||||
|
NULL, NULL },
|
||||||
END_OF_TESTCASES
|
END_OF_TESTCASES
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue