Skip to content

Commit

Permalink
Merge branch 'haxxpop/tcp_proxy_squashed' into tcp_proxy_squshed_and_…
Browse files Browse the repository at this point in the history
…merged
  • Loading branch information
nmathewson committed Jan 6, 2020
2 parents 9276c07 + 14d781f commit 1b63eea
Show file tree
Hide file tree
Showing 27 changed files with 731 additions and 153 deletions.
6 changes: 6 additions & 0 deletions changes/ticket31518
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
o Major features (proxy):
- In addition to HTTP CONNECT, SOCKS4, and SOCKS5, Tor can make all OR
connections through the HAProxy server. A new torrc option was added to
specify the address/port of the server: TCPProxy <protocol>
<host>:<port>. Currently the only supported protocol in the option is
haproxy. Close ticket 31518. Patch done by Suphanat Chunhapanya (haxxpop).
16 changes: 16 additions & 0 deletions doc/tor.1.txt
Original file line number Diff line number Diff line change
Expand Up @@ -918,6 +918,22 @@ forward slash (/) in the configuration file and on the command line.
log entries are marked with "Tor-__tag__". Can not be changed while tor is
running. (Default: none)

[[TCPProxy]] **TCPProxy** __protocol__ __host__:__port__::
Tor will use the given protocol to make all its OR (SSL) connections through
a TCP proxy on host:port, rather than connecting directly to servers. You may
want to set **FascistFirewall** to restrict the set of ports you might try to
connect to, if your proxy only allows connecting to certain ports. There is no
equivalent option for directory connections, because all Tor client versions
that support this option download directory documents via OR connections. +
+
The only protocol supported right now 'haproxy'. This option is only for
clients. (Default: none) +
+
The HAProxy version 1 proxy protocol is described in detail at
https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt +
+
Both source IP address and source port will be set to zero.

[[TruncateLogFile]] **TruncateLogFile** **0**|**1**::
If 1, Tor will overwrite logs at startup and in response to a HUP signal,
instead of appending to them. (Default: 0)
Expand Down
89 changes: 81 additions & 8 deletions src/app/config/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,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_IMMUTABLE("KeyDirectory", FILENAME, KeyDirectory_option, NULL),
V(KeyDirectoryGroupReadable, AUTOBOOL, "auto"),
VAR_D("HSLayer2Nodes", ROUTERSET, HSLayer2Nodes, NULL),
Expand Down Expand Up @@ -3940,19 +3941,28 @@ options_validate_cb(const void *old_options_, void *options_, char **msg)
}
}

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) {
Expand Down Expand Up @@ -5348,6 +5358,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.
Expand Down Expand Up @@ -5495,9 +5567,10 @@ pt_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;
}

Expand Down
2 changes: 2 additions & 0 deletions src/app/config/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,8 @@ STATIC const struct config_mgr_t *get_options_mgr(void);
STATIC void or_options_free_(or_options_t *options);
STATIC int options_validate_single_onion(or_options_t *options,
char **msg);
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);
Expand Down
11 changes: 11 additions & 0 deletions src/app/config/or_options_st.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,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_;
Expand Down Expand Up @@ -419,6 +425,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. */
Expand Down
2 changes: 2 additions & 0 deletions src/core/include.am
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ LIBTOR_APP_A_SOURCES = \
src/core/proto/proto_cell.c \
src/core/proto/proto_control0.c \
src/core/proto/proto_ext_or.c \
src/core/proto/proto_haproxy.c \
src/core/proto/proto_http.c \
src/core/proto/proto_socks.c \
src/feature/api/tor_api.c \
Expand Down Expand Up @@ -324,6 +325,7 @@ noinst_HEADERS += \
src/core/proto/proto_cell.h \
src/core/proto/proto_control0.h \
src/core/proto/proto_ext_or.h \
src/core/proto/proto_haproxy.h \
src/core/proto/proto_http.h \
src/core/proto/proto_socks.h \
src/feature/api/tor_api_internal.h \
Expand Down
Loading

0 comments on commit 1b63eea

Please sign in to comment.