]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
ipfw TransPort support on FreeBSD (10267)
authorNick Mathewson <nickm@torproject.org>
Mon, 3 Feb 2014 19:09:07 +0000 (14:09 -0500)
committerNick Mathewson <nickm@torproject.org>
Thu, 17 Apr 2014 03:03:25 +0000 (23:03 -0400)
This isn't on by default; to get it, you need to set "TransProxyType
ipfw".  (The original patch had automatic detection for whether
/dev/pf is present and openable, but that seems marginally fragile.)

changes/10267_tproxy [new file with mode: 0644]
doc/tor.1.txt
src/or/config.c
src/or/connection_edge.c
src/or/or.h

diff --git a/changes/10267_tproxy b/changes/10267_tproxy
new file mode 100644 (file)
index 0000000..f65e4a2
--- /dev/null
@@ -0,0 +1,4 @@
+  o Minor features:
+    - Support the ipfw firewall interface for transparent proxy support on
+      FreeBSD. To enable it, set "TransProxyType ipfw" in your torrc.
+      Resolves ticket 10267; patch from "yurivict".
index 1cc8f841ce3d465efacfae62b9a6b2e4b313b6dc..1a5ced8496465e4ab8db170a7dc8c821df62a3d6 100644 (file)
@@ -1196,7 +1196,7 @@ The following options are useful only for clients (that is, if
     compatibility, TransListenAddress is only allowed when TransPort is just
     a port number.)
 
-[[TransProxyType]] **TransProxyTYpe** **default**|**TPROXY**::
+[[TransProxyType]] **TransProxyTYpe** **default**|**TPROXY**|**ipfw**::
     TransProxyType may only be enabled when there is transparent proxy listener
     enabled.
  +
@@ -1208,8 +1208,10 @@ The following options are useful only for clients (that is, if
     feature can be found in the Linux kernel source tree in the file
     Documentation/networking/tproxy.txt.
  +
-    Set this to "default", or leave it unconfigured, to use regular IPTables
-    on Linux, or to use pf on the *BSD operating systems.
+    Set this option to "ipfw" to use the FreeBSD ipfw interface.
+ +
+    Set this option to "default", or leave it unconfigured, to use regular
+    IPTables on Linux, or to use pf on the *BSD operating systems.
  +
     (Default: "default".)
 
index 4a6b30172c013484e46d1054319296cd2224da3a..55a23b1ce3eea5d942ea55a0d9e60c2a06ec5cc6 100644 (file)
@@ -1089,7 +1089,7 @@ options_act_reversible(const or_options_t *old_options, char **msg)
 
 #if defined(HAVE_NET_IF_H) && defined(HAVE_NET_PFVAR_H)
   /* Open /dev/pf before dropping privileges. */
-  if (options->TransPort_set) {
+  if (options->TransPort_set && options->TransProxyType_parsed != TPT_IPFW) {
     if (get_pf_socket() < 0) {
       *msg = tor_strdup("Unable to open /dev/pf for transparent proxy.");
       goto rollback;
@@ -2558,6 +2558,12 @@ options_validate(or_options_t *old_options, or_options_t *options,
       REJECT("TPROXY is a Linux-specific feature.");
 #else
       options->TransProxyType_parsed = TPT_TPROXY;
+#endif
+    } else if (!strcasecmp(options->TransProxyType, "ipfw")) {
+#ifndef __FreeBSD__
+      REJECT("ipfw is a FreeBSD-specific feature.");
+#else
+      options->TransProxyType_parsed = TPT_IPFW;
 #endif
     } else {
       REJECT("Unrecognized value for TransProxyType");
index 41ca6119b09a395a567fe3133f4ff8406c74bb26..ddeac10381287ca5afd06f595ad7daf982873a6a 100644 (file)
@@ -1435,6 +1435,29 @@ connection_ap_get_original_destination(entry_connection_t *conn,
     return -1;
   }
 
+#ifdef __FreeBSD__
+  if (get_options()->TransProxyType_parsed == TPT_IPFW) {
+    /* ipfw(8) is used and in this case getsockname returned the original
+       destination */
+    if (proxy_sa->sa_family == AF_INET) {
+      struct sockaddr_in *dest_addr4 = (struct sockaddr_in *)proxy_sa;
+      tor_addr_from_ipv4n(&addr, dest_addr4->sin_addr.s_addr);
+      req->port = ntohs(dest_addr4->sin_port);
+    } else if (proxy_sa->sa_family == AF_INET6) {
+      struct sockaddr_in6 *dest_addr6 = (struct sockaddr_in6 *)proxy_sa;
+      tor_addr_from_in6(&addr, &dest_addr6->sin6_addr);
+      req->port = ntohs(dest_addr6->sin6_port);
+    } else {
+      tor_fragile_assert();
+      return -1;
+    }
+
+    tor_addr_to_str(req->address, &addr, sizeof(req->address), 0);
+
+    return 0;
+  }
+#endif
+
   memset(&pnl, 0, sizeof(pnl));
   pnl.proto           = IPPROTO_TCP;
   pnl.direction       = PF_OUT;
index 38ab1767e03fee18ae1d504e20415bb527033497..a5e2e7069dd3d56105e9599521bc86e6af3f4130 100644 (file)
@@ -3461,7 +3461,7 @@ typedef struct {
   const char *TransProxyType; /**< What kind of transparent proxy
                                * implementation are we using? */
   /** Parsed value of TransProxyType. */
-  enum { TPT_DEFAULT, TPT_TPROXY } TransProxyType_parsed;
+  enum { TPT_DEFAULT, TPT_TPROXY, TPT_IPFW } TransProxyType_parsed;
   config_line_t *NATDPort_lines; /**< Ports to listen on for transparent natd
                             * connections. */
   config_line_t *ControlPort_lines; /**< Ports to listen on for control