summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrandon Wiley <brandon@blanu.net>2016-11-16 15:10:16 -0600
committerBrandon Wiley <brandon@blanu.net>2016-11-16 15:10:16 -0600
commitfc4bf82171d7337c9db1ce91e553a3b9a97beb02 (patch)
treedbc39637fe5888e010b9cfd02536fd46add147e4
parentc1d70905378fefa781172e9e9b314a816765c32a (diff)
Added new command line flags and refactored ClientSetup to use them
-rw-r--r--common/pt_extras/pt_extras.go10
-rw-r--r--modes/pt_socks5/pt_socks5.go34
-rw-r--r--modes/stun_udp/stun_udp.go57
-rw-r--r--modes/transparent_tcp/transparent_tcp.go23
-rw-r--r--modes/transparent_udp/transparent_udp.go61
-rw-r--r--shapeshifter-dispatcher/shapeshifter-dispatcher.go89
6 files changed, 135 insertions, 139 deletions
diff --git a/common/pt_extras/pt_extras.go b/common/pt_extras/pt_extras.go
index 5f287e3..17314bf 100644
--- a/common/pt_extras/pt_extras.go
+++ b/common/pt_extras/pt_extras.go
@@ -71,8 +71,14 @@ func PtIsClient() (bool, error) {
return false, errors.New("not launched as a managed transport")
}
-func PtGetProxy() (*url.URL, error) {
- specString := os.Getenv("TOR_PT_PROXY")
+func PtGetProxy(proxy *string) (*url.URL, error) {
+ var specString string
+
+ if proxy != nil {
+ specString = *proxy
+ } else {
+ specString = os.Getenv("TOR_PT_PROXY")
+ }
if specString == "" {
return nil, nil
}
diff --git a/modes/pt_socks5/pt_socks5.go b/modes/pt_socks5/pt_socks5.go
index e7a4cec..38b0e2c 100644
--- a/modes/pt_socks5/pt_socks5.go
+++ b/modes/pt_socks5/pt_socks5.go
@@ -41,7 +41,6 @@ import (
"git.torproject.org/pluggable-transports/goptlib.git"
"github.com/OperatorFoundation/shapeshifter-dispatcher/common/log"
- "github.com/OperatorFoundation/shapeshifter-dispatcher/common/pt_extras"
"github.com/OperatorFoundation/shapeshifter-dispatcher/common/socks5"
"github.com/OperatorFoundation/shapeshifter-dispatcher/common/termmon"
"github.com/OperatorFoundation/shapeshifter-dispatcher/transports"
@@ -49,41 +48,14 @@ import (
)
const (
- obfs4proxyVersion = "0.0.7-dev"
- obfs4proxyLogFile = "obfs4proxy.log"
- socksAddr = "127.0.0.1:0"
+ socksAddr = "127.0.0.1:0"
)
var stateDir string
-func ClientSetup(termMon *termmon.TermMonitor) (launched bool, listeners []net.Listener) {
- ptClientInfo, err := pt.ClientSetup(transports.Transports())
- if err != nil {
- golog.Fatal(err)
- }
-
- ptClientProxy, err := pt_extras.PtGetProxy()
- fmt.Println("ptclientproxy", ptClientProxy)
- if err != nil {
- golog.Fatal(err)
- } else if ptClientProxy != nil {
- pt_extras.PtProxyDone()
- }
-
+func ClientSetup(termMon *termmon.TermMonitor, ptClientProxy *url.URL, factories map[string]base.ClientFactory) (launched bool, listeners []net.Listener) {
// Launch each of the client listeners.
- for _, name := range ptClientInfo.MethodNames {
- t := transports.Get(name)
- if t == nil {
- pt.CmethodError(name, "no such transport is supported")
- continue
- }
-
- f, err := t.ClientFactory(stateDir)
- if err != nil {
- pt.CmethodError(name, "failed to get ClientFactory")
- continue
- }
-
+ for name, f := range factories {
ln, err := net.Listen("tcp", socksAddr)
if err != nil {
pt.CmethodError(name, err.Error())
diff --git a/modes/stun_udp/stun_udp.go b/modes/stun_udp/stun_udp.go
index bf3045d..d636881 100644
--- a/modes/stun_udp/stun_udp.go
+++ b/modes/stun_udp/stun_udp.go
@@ -30,8 +30,8 @@
package stun_udp
import (
- "io"
"fmt"
+ "io"
golog "log"
"net"
"net/url"
@@ -52,15 +52,13 @@ import (
)
const (
- obfs4proxyVersion = "0.0.7-dev"
- obfs4proxyLogFile = "obfs4proxy.log"
- socksAddr = "127.0.0.1:1234"
+ socksAddr = "127.0.0.1:1234"
)
var stateDir string
type ConnState struct {
- Conn *net.Conn
+ Conn *net.Conn
Waiting bool
}
@@ -70,24 +68,9 @@ func NewConnState() ConnState {
type ConnTracker map[string]ConnState
-func ClientSetup(termMon *termmon.TermMonitor, target string) bool {
- methodNames := [...]string{"obfs2"}
- var ptClientProxy *url.URL = nil
-
+func ClientSetup(termMon *termmon.TermMonitor, target string, ptClientProxy *url.URL, factories map[string]base.ClientFactory) bool {
// Launch each of the client listeners.
- for _, name := range methodNames {
- t := transports.Get(name)
- if t == nil {
- log.Errorf("no such transport is supported: %s", name)
- continue
- }
-
- f, err := t.ClientFactory(stateDir)
- if err != nil {
- log.Errorf("failed to get ClientFactory: %s", name)
- continue
- }
-
+ for name, f := range factories {
udpAddr, err := net.ResolveUDPAddr("udp", socksAddr)
if err != nil {
fmt.Println("Error resolving address", socksAddr)
@@ -115,24 +98,24 @@ func clientHandler(target string, termMon *termmon.TermMonitor, f base.ClientFac
fmt.Println("@@@ handling...")
- tracker := make(ConnTracker)
+ tracker := make(ConnTracker)
name := f.Transport().Name()
fmt.Println("Transport is", name)
- buf := make([]byte, 1024)
+ buf := make([]byte, 1024)
- // Receive UDP packets and forward them over transport connections forever
+ // Receive UDP packets and forward them over transport connections forever
for {
n, addr, err := conn.ReadFromUDP(buf)
- fmt.Println("Received ",string(buf[0:n]), " from ",addr)
+ fmt.Println("Received ", string(buf[0:n]), " from ", addr)
if err != nil {
- fmt.Println("Error: ",err)
+ fmt.Println("Error: ", err)
}
- fmt.Println(tracker)
+ fmt.Println(tracker)
if state, ok := tracker[addr.String()]; ok {
// There is an open transport connection, or a connection attempt is in progress.
@@ -148,11 +131,11 @@ func clientHandler(target string, termMon *termmon.TermMonitor, f base.ClientFac
fmt.Println("writing...")
(*state.Conn).Write(buf)
}
- } else {
+ } else {
// There is not an open transport connection and a connection attempt is not in progress.
// Open a transport connection.
- fmt.Println("Opening connection to ", target)
+ fmt.Println("Opening connection to ", target)
openConnection(&tracker, addr.String(), target, termMon, f, proxyURI)
@@ -166,7 +149,7 @@ func openConnection(tracker *ConnTracker, addr string, target string, termMon *t
fmt.Println("Making dialer...")
newConn := NewConnState()
- (*tracker)[addr]=newConn
+ (*tracker)[addr] = newConn
go dialConn(tracker, addr, target, f, proxyURI)
}
@@ -209,7 +192,7 @@ func dialConn(tracker *ConnTracker, addr string, target string, f base.ClientFac
fmt.Println("Success")
- (*tracker)[addr]=ConnState{&remote, false}
+ (*tracker)[addr] = ConnState{&remote, false}
}
func ServerSetup(termMon *termmon.TermMonitor, bindaddrString string, target string) bool {
@@ -347,7 +330,7 @@ func serverHandler(termMon *termmon.TermMonitor, f base.ServerFactory, conn net.
return
}
- serverAddr, err := net.ResolveUDPAddr("udp",target)
+ serverAddr, err := net.ResolveUDPAddr("udp", target)
if err != nil {
golog.Fatal(err)
}
@@ -362,7 +345,7 @@ func serverHandler(termMon *termmon.TermMonitor, f base.ServerFactory, conn net.
golog.Fatal(err)
}
- fmt.Println("pumping")
+ fmt.Println("pumping")
defer dest.Close()
@@ -371,7 +354,7 @@ func serverHandler(termMon *termmon.TermMonitor, f base.ServerFactory, conn net.
for {
fmt.Println("reading...")
// Read the incoming connection into the buffer.
- _, err := io.ReadFull(remote, headerBuffer)
+ _, err := io.ReadFull(remote, headerBuffer)
if err != nil {
fmt.Println("read error")
break
@@ -394,8 +377,8 @@ func serverHandler(termMon *termmon.TermMonitor, f base.ServerFactory, conn net.
break
}
- writeBuffer := append(headerBuffer, readBuffer...)
+ writeBuffer := append(headerBuffer, readBuffer...)
dest.Write(writeBuffer)
- }
+ }
}
diff --git a/modes/transparent_tcp/transparent_tcp.go b/modes/transparent_tcp/transparent_tcp.go
index 30e04fc..119e797 100644
--- a/modes/transparent_tcp/transparent_tcp.go
+++ b/modes/transparent_tcp/transparent_tcp.go
@@ -49,31 +49,14 @@ import (
)
const (
- obfs4proxyVersion = "0.0.7-dev"
- obfs4proxyLogFile = "obfs4proxy.log"
- socksAddr = "127.0.0.1:1234"
+ socksAddr = "127.0.0.1:1234"
)
var stateDir string
-func ClientSetup(termMon *termmon.TermMonitor, target string) (launched bool, listeners []net.Listener) {
- methodNames := [...]string{"obfs2"}
- var ptClientProxy *url.URL = nil
-
+func ClientSetup(termMon *termmon.TermMonitor, target string, ptClientProxy *url.URL, factories map[string]base.ClientFactory) (launched bool, listeners []net.Listener) {
// Launch each of the client listeners.
- for _, name := range methodNames {
- t := transports.Get(name)
- if t == nil {
- log.Errorf("no such transport is supported: %s", name)
- continue
- }
-
- f, err := t.ClientFactory(stateDir)
- if err != nil {
- log.Errorf("failed to get ClientFactory: %s", name)
- continue
- }
-
+ for name, f := range factories {
fmt.Println("Listening ", socksAddr)
ln, err := net.Listen("tcp", socksAddr)
if err != nil {
diff --git a/modes/transparent_udp/transparent_udp.go b/modes/transparent_udp/transparent_udp.go
index d7ee938..f9c2efc 100644
--- a/modes/transparent_udp/transparent_udp.go
+++ b/modes/transparent_udp/transparent_udp.go
@@ -30,15 +30,15 @@
package transparent_udp
import (
- "io"
+ "bytes"
+ "encoding/binary"
"fmt"
+ "io"
golog "log"
"net"
"net/url"
"strconv"
"strings"
- "bytes"
- "encoding/binary"
"golang.org/x/net/proxy"
@@ -50,15 +50,13 @@ import (
)
const (
- obfs4proxyVersion = "0.0.7-dev"
- obfs4proxyLogFile = "obfs4proxy.log"
- socksAddr = "127.0.0.1:1234"
+ socksAddr = "127.0.0.1:1234"
)
var stateDir string
type ConnState struct {
- Conn *net.Conn
+ Conn *net.Conn
Waiting bool
}
@@ -68,24 +66,9 @@ func NewConnState() ConnState {
type ConnTracker map[string]ConnState
-func ClientSetup(termMon *termmon.TermMonitor, target string) bool {
- methodNames := [...]string{"obfs2"}
- var ptClientProxy *url.URL = nil
-
+func ClientSetup(termMon *termmon.TermMonitor, target string, ptClientProxy *url.URL, factories map[string]base.ClientFactory) bool {
// Launch each of the client listeners.
- for _, name := range methodNames {
- t := transports.Get(name)
- if t == nil {
- log.Errorf("no such transport is supported: %s", name)
- continue
- }
-
- f, err := t.ClientFactory(stateDir)
- if err != nil {
- log.Errorf("failed to get ClientFactory: %s", name)
- continue
- }
-
+ for name, f := range factories {
udpAddr, err := net.ResolveUDPAddr("udp", socksAddr)
if err != nil {
fmt.Println("Error resolving address", socksAddr)
@@ -107,7 +90,7 @@ func ClientSetup(termMon *termmon.TermMonitor, target string) bool {
}
func clientHandler(target string, termMon *termmon.TermMonitor, f base.ClientFactory, conn *net.UDPConn, proxyURI *url.URL) {
- var length16 uint16
+ var length16 uint16
defer conn.Close()
termMon.OnHandlerStart()
@@ -115,24 +98,24 @@ func clientHandler(target string, termMon *termmon.TermMonitor, f base.ClientFac
fmt.Println("@@@ handling...")
- tracker := make(ConnTracker)
+ tracker := make(ConnTracker)
name := f.Transport().Name()
fmt.Println("Transport is", name)
- buf := make([]byte, 1024)
+ buf := make([]byte, 1024)
- // Receive UDP packets and forward them over transport connections forever
+ // Receive UDP packets and forward them over transport connections forever
for {
n, addr, err := conn.ReadFromUDP(buf)
- fmt.Println("Received ",string(buf[0:n]), " from ",addr)
+ fmt.Println("Received ", string(buf[0:n]), " from ", addr)
if err != nil {
- fmt.Println("Error: ",err)
+ fmt.Println("Error: ", err)
}
- fmt.Println(tracker)
+ fmt.Println(tracker)
if state, ok := tracker[addr.String()]; ok {
// There is an open transport connection, or a connection attempt is in progress.
@@ -158,11 +141,11 @@ func clientHandler(target string, termMon *termmon.TermMonitor, f base.ClientFac
(*state.Conn).Write(buf)
}
}
- } else {
+ } else {
// There is not an open transport connection and a connection attempt is not in progress.
// Open a transport connection.
- fmt.Println("Opening connection to ", target)
+ fmt.Println("Opening connection to ", target)
openConnection(&tracker, addr.String(), target, termMon, f, proxyURI)
@@ -176,7 +159,7 @@ func openConnection(tracker *ConnTracker, addr string, target string, termMon *t
fmt.Println("Making dialer...")
newConn := NewConnState()
- (*tracker)[addr]=newConn
+ (*tracker)[addr] = newConn
go dialConn(tracker, addr, target, f, proxyURI)
}
@@ -219,7 +202,7 @@ func dialConn(tracker *ConnTracker, addr string, target string, f base.ClientFac
fmt.Println("Success")
- (*tracker)[addr]=ConnState{&remote, false}
+ (*tracker)[addr] = ConnState{&remote, false}
}
func ServerSetup(termMon *termmon.TermMonitor, bindaddrString string, target string) bool {
@@ -357,7 +340,7 @@ func serverHandler(termMon *termmon.TermMonitor, f base.ServerFactory, conn net.
return
}
- serverAddr, err := net.ResolveUDPAddr("udp",target)
+ serverAddr, err := net.ResolveUDPAddr("udp", target)
if err != nil {
golog.Fatal(err)
}
@@ -372,7 +355,7 @@ func serverHandler(termMon *termmon.TermMonitor, f base.ServerFactory, conn net.
golog.Fatal(err)
}
- fmt.Println("pumping")
+ fmt.Println("pumping")
defer dest.Close()
@@ -381,7 +364,7 @@ func serverHandler(termMon *termmon.TermMonitor, f base.ServerFactory, conn net.
for {
fmt.Println("reading...")
// Read the incoming connection into the buffer.
- readLen, err := io.ReadFull(remote, lengthBuffer)
+ readLen, err := io.ReadFull(remote, lengthBuffer)
if err != nil {
fmt.Println("read error")
break
@@ -405,5 +388,5 @@ func serverHandler(termMon *termmon.TermMonitor, f base.ServerFactory, conn net.
}
dest.Write(readBuffer)
- }
+ }
}
diff --git a/shapeshifter-dispatcher/shapeshifter-dispatcher.go b/shapeshifter-dispatcher/shapeshifter-dispatcher.go
index 7132bc2..c4a230d 100644
--- a/shapeshifter-dispatcher/shapeshifter-dispatcher.go
+++ b/shapeshifter-dispatcher/shapeshifter-dispatcher.go
@@ -34,23 +34,26 @@ import (
"fmt"
golog "log"
"net"
+ "net/url"
"os"
"path"
+ "strings"
"syscall"
"git.torproject.org/pluggable-transports/goptlib.git"
"github.com/OperatorFoundation/shapeshifter-dispatcher/common/log"
"github.com/OperatorFoundation/shapeshifter-dispatcher/common/pt_extras"
"github.com/OperatorFoundation/shapeshifter-dispatcher/common/termmon"
- "github.com/OperatorFoundation/shapeshifter-dispatcher/transports"
"github.com/OperatorFoundation/shapeshifter-dispatcher/modes/pt_socks5"
+ "github.com/OperatorFoundation/shapeshifter-dispatcher/modes/stun_udp"
"github.com/OperatorFoundation/shapeshifter-dispatcher/modes/transparent_tcp"
"github.com/OperatorFoundation/shapeshifter-dispatcher/modes/transparent_udp"
- "github.com/OperatorFoundation/shapeshifter-dispatcher/modes/stun_udp"
- _ "github.com/OperatorFoundation/obfs4/proxy_dialers/proxy_socks4"
_ "github.com/OperatorFoundation/obfs4/proxy_dialers/proxy_http"
+ _ "github.com/OperatorFoundation/obfs4/proxy_dialers/proxy_socks4"
+ "github.com/OperatorFoundation/shapeshifter-dispatcher/transports"
+ "github.com/OperatorFoundation/shapeshifter-transports/transports/base"
)
const (
@@ -72,6 +75,15 @@ func main() {
// Handle the command line arguments.
_, execName := path.Split(os.Args[0])
+
+ flag.Usage = func() {
+ fmt.Fprintf(os.Stderr, "shapeshifter-dispatcher is a PT v2.0 proxy supporting multiple transports and proxy modes\n\n")
+ fmt.Fprintf(os.Stderr, "Usage:\n\t%s --client --state [statedir] --ptversion 2 --transports [transport1,transport2,...]\n\n", os.Args[0])
+ fmt.Fprintf(os.Stderr, "Example:\n\t%s --client --state state --ptversion 2 --transports obfs2\n\n", os.Args[0])
+ fmt.Fprintf(os.Stderr, "Flags:\n\n")
+ flag.PrintDefaults()
+ }
+
showVer := flag.Bool("version", false, "Print version and exit")
logLevelStr := flag.String("logLevel", "ERROR", "Log level (ERROR/WARN/INFO/DEBUG)")
enableLogging := flag.Bool("enableLogging", false, "Log to TOR_PT_STATE_LOCATION/"+dispatcherLogFile)
@@ -83,6 +95,9 @@ func main() {
serverMode := flag.Bool("server", false, "Enable server mode")
statePath := flag.String("state", "", "Specify transport server destination address")
bindAddr := flag.String("bindaddr", "", "Specify the bind address for transparent server")
+ ptversion := flag.String("ptversion", "", "Specify the Pluggable Transport protocol version to use")
+ proxy := flag.String("proxy", "", "Specify an HTTP or SOCKS4a proxy that the PT needs to use to reach the Internet")
+ transportsList := flag.String("transports", "", "Specify transports to enable")
flag.Parse()
if *showVer {
@@ -99,10 +114,10 @@ func main() {
launched := false
isClient, err := checkIsClient(*clientMode, *serverMode)
if err != nil {
- golog.Fatalf("[ERROR]: %s - must be run as a managed transport", execName)
+ golog.Fatalf("[ERROR]: %s - either --client or --server is required, or configure using PT 2.0 environment variables", execName)
}
if stateDir, err = makeStateDir(*statePath); err != nil {
- golog.Fatalf("[ERROR]: %s - No state directory: %s", execName, err)
+ golog.Fatalf("[ERROR]: %s - No state directory: Use --state or TOR_PT_STATE_LOCATION environment variable", execName)
}
if err = log.Init(*enableLogging, path.Join(stateDir, dispatcherLogFile), *unsafeLogging); err != nil {
golog.Fatalf("[ERROR]: %s - failed to initialize logging", execName)
@@ -126,7 +141,8 @@ func main() {
log.Errorf("%s - transparent mode requires a target", execName)
} else {
fmt.Println("transparent udp client")
- launched = transparent_udp.ClientSetup(termMon, *target)
+ factories, ptClientProxy := getClientFactories(ptversion, transportsList, proxy)
+ launched = transparent_udp.ClientSetup(termMon, *target, factories, ptClientProxy)
}
} else {
log.Infof("%s - initializing server transport listeners", execName)
@@ -145,7 +161,8 @@ func main() {
if *target == "" {
log.Errorf("%s - transparent mode requires a target", execName)
} else {
- launched, ptListeners = transparent_tcp.ClientSetup(termMon, *target)
+ factories, ptClientProxy := getClientFactories(ptversion, transportsList, proxy)
+ launched, ptListeners = transparent_tcp.ClientSetup(termMon, *target, factories, ptClientProxy)
}
} else {
log.Infof("%s - initializing server transport listeners", execName)
@@ -166,7 +183,8 @@ func main() {
log.Errorf("%s - STUN mode requires a target", execName)
} else {
fmt.Println("STUN udp client")
- launched = stun_udp.ClientSetup(termMon, *target)
+ factories, ptClientProxy := getClientFactories(ptversion, transportsList, proxy)
+ launched = stun_udp.ClientSetup(termMon, *target, factories, ptClientProxy)
}
} else {
log.Infof("%s - initializing server transport listeners", execName)
@@ -183,7 +201,8 @@ func main() {
log.Infof("%s - initializing PT 1.0 proxy", execName)
if isClient {
log.Infof("%s - initializing client transport listeners", execName)
- launched, ptListeners = pt_socks5.ClientSetup(termMon)
+ factories, ptClientProxy := getClientFactories(ptversion, transportsList, proxy)
+ launched, ptListeners = pt_socks5.ClientSetup(termMon, factories, ptClientProxy)
} else {
log.Infof("%s - initializing server transport listeners", execName)
launched, ptListeners = pt_socks5.ServerSetup(termMon)
@@ -221,7 +240,7 @@ func main() {
termMon.Wait(true)
- fmt.Println("waiting")
+ fmt.Println("waiting")
for {
// FIXME - block because termMon.Wait is not blocking
}
@@ -245,3 +264,53 @@ func makeStateDir(statePath string) (string, error) {
return pt.MakeStateDir()
}
}
+
+func getClientFactories(ptversion *string, transportsList *string, proxy *string) (clientProxy *url.URL, factories map[string]base.ClientFactory) {
+ var ptClientInfo pt.ClientInfo
+ var err error
+
+ // FIXME - instead of this, goptlib should be modified to accept command line flag override of EITHER ptversion or transports (or both)
+ if ptversion == nil || transportsList == nil {
+ fmt.Println("Falling back to environment variables for ptversion/transports", ptversion, transportsList)
+ ptClientInfo, err = pt.ClientSetup(transports.Transports())
+ if err != nil {
+ // FIXME - print a more useful error, specifying --ptversion and --transports flags
+ golog.Fatal(err)
+ }
+ } else {
+ if *transportsList == "*" {
+ ptClientInfo = pt.ClientInfo{MethodNames: transports.Transports()}
+ } else {
+ ptClientInfo = pt.ClientInfo{MethodNames: strings.Split(*transportsList, ",")}
+ }
+ }
+
+ ptClientProxy, err := pt_extras.PtGetProxy(proxy)
+ fmt.Println("ptclientproxy", ptClientProxy)
+ if err != nil {
+ golog.Fatal(err)
+ } else if ptClientProxy != nil {
+ pt_extras.PtProxyDone()
+ }
+
+ factories = make(map[string]base.ClientFactory)
+
+ // Launch each of the client listeners.
+ for _, name := range ptClientInfo.MethodNames {
+ t := transports.Get(name)
+ if t == nil {
+ pt.CmethodError(name, "no such transport is supported")
+ continue
+ }
+
+ f, err := t.ClientFactory(stateDir)
+ if err != nil {
+ pt.CmethodError(name, "failed to get ClientFactory")
+ continue
+ }
+
+ factories[name] = f
+ }
+
+ return ptClientProxy, factories
+}