Commit 1b63eea6 authored by Nick Mathewson's avatar Nick Mathewson 🦀
Browse files

Merge branch 'haxxpop/tcp_proxy_squashed' into tcp_proxy_squshed_and_merged

parents 9276c07a 14d781ff
Loading
Loading
Loading
Loading

changes/ticket31518

0 → 100644
+6 −0
Original line number Diff line number Diff line
  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 −0
Original line number Diff line number Diff line
@@ -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)
+81 −8
Original line number Diff line number Diff line
@@ -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),
@@ -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) {
@@ -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.
@@ -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;
    }

+2 −0
Original line number Diff line number Diff line
@@ -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);
+11 −0
Original line number Diff line number Diff line
@@ -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_;
@@ -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. */
Loading