mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
config: Add TCPProxy option for haproxy protocol
Read the TCPProxy option and put in or_options_t.
This commit is contained in:
+81
-8
@@ -522,6 +522,7 @@ static const config_var_t option_vars_[] = {
|
||||
V(Socks5Proxy, STRING, NULL),
|
||||
V(Socks5ProxyUsername, STRING, NULL),
|
||||
V(Socks5ProxyPassword, STRING, NULL),
|
||||
V(TCPProxy, STRING, NULL),
|
||||
VAR("KeyDirectory", FILENAME, KeyDirectory_option, NULL),
|
||||
V(KeyDirectoryGroupReadable, BOOL, "0"),
|
||||
VAR_D("HSLayer2Nodes", ROUTERSET, HSLayer2Nodes, NULL),
|
||||
@@ -4150,19 +4151,28 @@ options_validate(or_options_t *old_options, or_options_t *options,
|
||||
}
|
||||
}
|
||||
|
||||
if (options->TCPProxy) {
|
||||
int res = parse_tcp_proxy_line(options->TCPProxy, options, msg);
|
||||
if (res < 0) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if more than one exclusive proxy type has been enabled. */
|
||||
if (!!options->Socks4Proxy + !!options->Socks5Proxy +
|
||||
!!options->HTTPSProxy > 1)
|
||||
!!options->HTTPSProxy + !!options->TCPProxy > 1)
|
||||
REJECT("You have configured more than one proxy type. "
|
||||
"(Socks4Proxy|Socks5Proxy|HTTPSProxy)");
|
||||
"(Socks4Proxy|Socks5Proxy|HTTPSProxy|TCPProxy)");
|
||||
|
||||
/* Check if the proxies will give surprising behavior. */
|
||||
if (options->HTTPProxy && !(options->Socks4Proxy ||
|
||||
options->Socks5Proxy ||
|
||||
options->HTTPSProxy)) {
|
||||
log_warn(LD_CONFIG, "HTTPProxy configured, but no SOCKS proxy or "
|
||||
"HTTPS proxy configured. Watch out: this configuration will "
|
||||
"proxy unencrypted directory connections only.");
|
||||
options->HTTPSProxy ||
|
||||
options->TCPProxy)) {
|
||||
log_warn(LD_CONFIG, "HTTPProxy configured, but no SOCKS proxy, "
|
||||
"HTTPS proxy, or any other TCP proxy configured. Watch out: "
|
||||
"this configuration will proxy unencrypted directory "
|
||||
"connections only.");
|
||||
}
|
||||
|
||||
if (options->Socks5ProxyUsername) {
|
||||
@@ -5962,6 +5972,68 @@ parse_bridge_line(const char *line)
|
||||
return bridge_line;
|
||||
}
|
||||
|
||||
/** Parse the contents of a TCPProxy line from <b>line</b> and put it
|
||||
* in <b>options</b>. Return 0 if the line is well-formed, and -1 if it
|
||||
* isn't.
|
||||
*
|
||||
* This will mutate only options->TCPProxyProtocol, options->TCPProxyAddr,
|
||||
* and options->TCPProxyPort.
|
||||
*
|
||||
* On error, tor_strdup an error explanation into *<b>msg</b>.
|
||||
*/
|
||||
STATIC int
|
||||
parse_tcp_proxy_line(const char *line, or_options_t *options, char **msg)
|
||||
{
|
||||
int ret = 0;
|
||||
tor_assert(line);
|
||||
tor_assert(options);
|
||||
tor_assert(msg);
|
||||
|
||||
smartlist_t *sl = smartlist_new();
|
||||
/* Split between the protocol and the address/port. */
|
||||
smartlist_split_string(sl, line, " ",
|
||||
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
|
||||
|
||||
/* The address/port is not specified. */
|
||||
if (smartlist_len(sl) < 2) {
|
||||
*msg = tor_strdup("TCPProxy has no address/port. Please fix.");
|
||||
goto err;
|
||||
}
|
||||
|
||||
char *protocol_string = smartlist_get(sl, 0);
|
||||
char *addrport_string = smartlist_get(sl, 1);
|
||||
|
||||
/* The only currently supported protocol is 'haproxy'. */
|
||||
if (strcasecmp(protocol_string, "haproxy")) {
|
||||
*msg = tor_strdup("TCPProxy protocol is not supported. Currently "
|
||||
"the only supported protocol is 'haproxy'. "
|
||||
"Please fix.");
|
||||
goto err;
|
||||
} else {
|
||||
/* Otherwise, set the correct protocol. */
|
||||
options->TCPProxyProtocol = TCP_PROXY_PROTOCOL_HAPROXY;
|
||||
}
|
||||
|
||||
/* Parse the address/port. */
|
||||
if (tor_addr_port_lookup(addrport_string, &options->TCPProxyAddr,
|
||||
&options->TCPProxyPort) < 0) {
|
||||
*msg = tor_strdup("TCPProxy address/port failed to parse or resolve. "
|
||||
"Please fix.");
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Success. */
|
||||
ret = 0;
|
||||
goto end;
|
||||
|
||||
err:
|
||||
ret = -1;
|
||||
end:
|
||||
SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
|
||||
smartlist_free(sl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Read the contents of a ClientTransportPlugin or ServerTransportPlugin
|
||||
* line from <b>line</b>, depending on the value of <b>server</b>. Return 0
|
||||
* if the line is well-formed, and -1 if it isn't.
|
||||
@@ -6110,9 +6182,10 @@ parse_transport_line(const or_options_t *options,
|
||||
|
||||
/* ClientTransportPlugins connecting through a proxy is managed only. */
|
||||
if (!server && (options->Socks4Proxy || options->Socks5Proxy ||
|
||||
options->HTTPSProxy)) {
|
||||
options->HTTPSProxy || options->TCPProxy)) {
|
||||
log_warn(LD_CONFIG, "You have configured an external proxy with another "
|
||||
"proxy type. (Socks4Proxy|Socks5Proxy|HTTPSProxy)");
|
||||
"proxy type. (Socks4Proxy|Socks5Proxy|HTTPSProxy|"
|
||||
"TCPProxy)");
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
@@ -266,6 +266,8 @@ STATIC int options_validate(or_options_t *old_options,
|
||||
STATIC int parse_transport_line(const or_options_t *options,
|
||||
const char *line, int validate_only,
|
||||
int server);
|
||||
STATIC int parse_tcp_proxy_line(const char *line, or_options_t *options,
|
||||
char **msg);
|
||||
STATIC int consider_adding_dir_servers(const or_options_t *options,
|
||||
const or_options_t *old_options);
|
||||
STATIC void add_default_trusted_dir_authorities(dirinfo_type_t type);
|
||||
|
||||
@@ -26,6 +26,12 @@ typedef enum {OUTBOUND_ADDR_EXIT, OUTBOUND_ADDR_OR,
|
||||
OUTBOUND_ADDR_EXIT_AND_OR,
|
||||
OUTBOUND_ADDR_MAX} outbound_addr_t;
|
||||
|
||||
/** Which protocol to use for TCPProxy. */
|
||||
typedef enum {
|
||||
/** Use the HAProxy proxy protocol. */
|
||||
TCP_PROXY_PROTOCOL_HAPROXY
|
||||
} tcp_proxy_protocol_t;
|
||||
|
||||
/** Configuration options for a Tor process. */
|
||||
struct or_options_t {
|
||||
uint32_t magic_;
|
||||
@@ -423,6 +429,11 @@ struct or_options_t {
|
||||
char *Socks5ProxyUsername; /**< Username for SOCKS5 authentication, if any */
|
||||
char *Socks5ProxyPassword; /**< Password for SOCKS5 authentication, if any */
|
||||
|
||||
char *TCPProxy; /**< protocol and hostname:port to use as a proxy, if any. */
|
||||
tcp_proxy_protocol_t TCPProxyProtocol; /**< Derived from TCPProxy. */
|
||||
tor_addr_t TCPProxyAddr; /**< Derived from TCPProxy. */
|
||||
uint16_t TCPProxyPort; /**< Derived from TCPProxy. */
|
||||
|
||||
/** List of configuration lines for replacement directory authorities.
|
||||
* If you just want to replace one class of authority at a time,
|
||||
* use the "Alternate*Authority" options below instead. */
|
||||
|
||||
@@ -2953,7 +2953,7 @@ test_options_validate__proxy(void *ignored)
|
||||
ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
|
||||
tt_int_op(ret, OP_EQ, -1);
|
||||
tt_str_op(msg, OP_EQ, "You have configured more than one proxy type. "
|
||||
"(Socks4Proxy|Socks5Proxy|HTTPSProxy)");
|
||||
"(Socks4Proxy|Socks5Proxy|HTTPSProxy|TCPProxy)");
|
||||
tor_free(msg);
|
||||
|
||||
free_options_test_data(tdata);
|
||||
@@ -2963,9 +2963,10 @@ test_options_validate__proxy(void *ignored)
|
||||
mock_clean_saved_logs();
|
||||
ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
|
||||
tt_int_op(ret, OP_EQ, 0);
|
||||
expect_log_msg("HTTPProxy configured, but no SOCKS "
|
||||
"proxy or HTTPS proxy configured. Watch out: this configuration "
|
||||
"will proxy unencrypted directory connections only.\n");
|
||||
expect_log_msg("HTTPProxy configured, but no SOCKS proxy, "
|
||||
"HTTPS proxy, or any other TCP proxy configured. Watch out: "
|
||||
"this configuration will proxy unencrypted directory "
|
||||
"connections only.\n");
|
||||
tor_free(msg);
|
||||
|
||||
free_options_test_data(tdata);
|
||||
|
||||
Reference in New Issue
Block a user