[Pkg-privacy-commits] [obfs4proxy] 63/151: Wire in go.net/proxy, enabling SOCKS5 via TOR_PT_PROXY.

Ximin Luo infinity0 at moszumanska.debian.org
Sat Aug 22 12:59:39 UTC 2015


This is an automated email from the git hooks/post-receive script.

infinity0 pushed a commit to branch master
in repository obfs4proxy.

commit 92494597ce18e21ca8db4d0cd7ba1be3ba05e735
Author: Yawning Angel <yawning at schwanenlied.me>
Date:   Sun May 25 09:14:14 2014 +0000

    Wire in go.net/proxy, enabling SOCKS5 via TOR_PT_PROXY.
    
    With tor patched to support 8402, obfs4 bootstraps via a SOCKSv5 proxy
    now.  Other schemes will bail with a PROXY-ERROR, as the go.net/proxy
    package does not support them, and I have not gotten around to writing
    dialers for them yet (next on my TODO list).
    
    Part of issue #7.
---
 obfs4.go                   | 15 ++++++++++++--
 obfs4proxy/obfs4proxy.go   | 29 +++++++++++++++++---------
 obfs4proxy/proxy_extras.go | 51 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 83 insertions(+), 12 deletions(-)

diff --git a/obfs4.go b/obfs4.go
index 6978a97..e4c22f8 100644
--- a/obfs4.go
+++ b/obfs4.go
@@ -533,10 +533,21 @@ func (c *Obfs4Conn) SetWriteDeadline(t time.Time) error {
 	return syscall.ENOTSUP
 }
 
+// DialFn is a function pointer to a dial routine that matches the
+// net.Dialer.Dial routine.
+type DialFn func(string, string) (net.Conn, error)
+
 // DialObfs4 connects to the remote address on the network, and handshakes with
 // the peer's obfs4 Node ID and Identity Public Key.  nodeID and publicKey are
 // expected as strings containing the Base64 encoded values.
 func DialObfs4(network, address, nodeID, publicKey string, iatObfuscation bool) (*Obfs4Conn, error) {
+
+	return DialObfs4DialFn(net.Dial, network, address, nodeID, publicKey, iatObfuscation)
+}
+
+// DialObfs4DialFn connects to the remote address on the network via DialFn,
+// and handshakes with the peers' obfs4 Node ID and Identity Public Key.
+func DialObfs4DialFn(dialFn DialFn, network, address, nodeID, publicKey string, iatObfuscation bool) (*Obfs4Conn, error) {
 	// Decode the node_id/public_key.
 	pub, err := ntor.PublicKeyFromBase64(publicKey)
 	if err != nil {
@@ -553,13 +564,13 @@ func DialObfs4(network, address, nodeID, publicKey string, iatObfuscation bool)
 		return nil, err
 	}
 
-	// Connect to the peer.
+	// Generate the Obfs4Conn.
 	c := new(Obfs4Conn)
 	c.lenProbDist = newWDist(seed, 0, framing.MaximumSegmentLength)
 	if iatObfuscation {
 		c.iatProbDist = newWDist(seed, 0, maxIatDelay)
 	}
-	c.conn, err = net.Dial(network, address)
+	c.conn, err = dialFn(network, address)
 	if err != nil {
 		return nil, err
 	}
diff --git a/obfs4proxy/obfs4proxy.go b/obfs4proxy/obfs4proxy.go
index 2e8a011..c00ee88 100644
--- a/obfs4proxy/obfs4proxy.go
+++ b/obfs4proxy/obfs4proxy.go
@@ -53,6 +53,7 @@ import (
 	"io/ioutil"
 	"log"
 	"net"
+	"net/url"
 	"os"
 	"os/signal"
 	"path"
@@ -222,7 +223,7 @@ func serverSetup() (launched bool) {
 	return
 }
 
-func clientHandler(conn *pt.SocksConn) error {
+func clientHandler(conn *pt.SocksConn, proxyURI *url.URL) error {
 	defer conn.Close()
 
 	var addr string
@@ -254,8 +255,13 @@ func clientHandler(conn *pt.SocksConn) error {
 	}()
 
 	defer logAndRecover(nil)
-	remote, err := obfs4.DialObfs4("tcp", conn.Req.Target, nodeID, publicKey,
-		iatObfuscation)
+	dialFn, err := getProxyDialer(proxyURI)
+	if err != nil {
+		log.Printf("[ERROR] client: failed to get proxy dialer: %s", err)
+		conn.Reject()
+		return err
+	}
+	remote, err := obfs4.DialObfs4DialFn(dialFn, "tcp", conn.Req.Target, nodeID, publicKey, iatObfuscation)
 	if err != nil {
 		log.Printf("[ERROR] client: %p: Handshake failed: %s", remote, err)
 		conn.Reject()
@@ -272,7 +278,7 @@ func clientHandler(conn *pt.SocksConn) error {
 	return nil
 }
 
-func clientAcceptLoop(ln *pt.SocksListener) error {
+func clientAcceptLoop(ln *pt.SocksListener, proxyURI *url.URL) error {
 	defer ln.Close()
 	for {
 		conn, err := ln.AcceptSocks()
@@ -282,7 +288,7 @@ func clientAcceptLoop(ln *pt.SocksListener) error {
 			}
 			continue
 		}
-		go clientHandler(conn)
+		go clientHandler(conn, proxyURI)
 	}
 }
 
@@ -296,17 +302,20 @@ func clientSetup() (launched bool) {
 	ptClientInfo, err := pt.ClientSetup([]string{obfs4Method})
 	if err != nil {
 		log.Fatal(err)
-		return
 	}
 
 	ptClientProxy, err := ptGetProxy()
 	if err != nil {
 		log.Fatal(err)
-		return
 	}
 	if ptClientProxy != nil {
-		// XXX: Remove this once done.
-		ptProxyError("proxy are not supported yet")
+		// XXX: Limit this to SOCKS5 for now.
+		if ptClientProxy.Scheme != "socks5" {
+			ptProxyError(fmt.Sprintf("proxy scheme not supported: %s",
+				ptClientProxy.Scheme))
+			return
+		}
+		ptProxyDone()
 	}
 
 	for _, methodName := range ptClientInfo.MethodNames {
@@ -317,7 +326,7 @@ func clientSetup() (launched bool) {
 				pt.CmethodError(methodName, err.Error())
 				break
 			}
-			go clientAcceptLoop(ln)
+			go clientAcceptLoop(ln, ptClientProxy)
 			pt.Cmethod(methodName, ln.Version(), ln.Addr())
 			ptListeners = append(ptListeners, ln)
 			launched = true
diff --git a/obfs4proxy/proxy_extras.go b/obfs4proxy/proxy_extras.go
new file mode 100644
index 0000000..27b638b
--- /dev/null
+++ b/obfs4proxy/proxy_extras.go
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2014, Yawning Angel <yawning at torproject dot org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package main
+
+import (
+	"net/url"
+
+	"code.google.com/p/go.net/proxy"
+
+	"github.com/yawning/obfs4"
+)
+
+// getProxyDialer is a trival wrapper around the go.net/proxy package to avoid
+// having it as a dependency for anything else.
+func getProxyDialer(uri *url.URL) (obfs4.DialFn, error) {
+	if uri == nil {
+		return proxy.Direct.Dial, nil
+	}
+
+	dialer, err := proxy.FromURL(uri, proxy.Direct)
+	if err != nil {
+		return nil, err
+	}
+
+	return dialer.Dial, nil
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-privacy/packages/obfs4proxy.git



More information about the Pkg-privacy-commits mailing list