summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrandon Wiley <brandon@blanu.net>2017-02-22 11:39:25 -0600
committerBrandon Wiley <brandon@blanu.net>2017-02-22 11:39:25 -0600
commit664d8e4d3af0337cd0c6392f9f3f01b6315e9b84 (patch)
treeff4e6fe47283589fed4e45bd803e1311a0b9d61f
parent697b3622db6aee8891ab7542677b1fff4594d1b9 (diff)
Implemented use of transports that require parameters
-rw-r--r--modes/pt_socks5/pt_socks5.go135
-rw-r--r--modes/stun_udp/stun_udp.go125
-rw-r--r--modes/transparent_tcp/transparent_tcp.go124
-rw-r--r--modes/transparent_udp/transparent_udp.go124
4 files changed, 430 insertions, 78 deletions
diff --git a/modes/pt_socks5/pt_socks5.go b/modes/pt_socks5/pt_socks5.go
index b6bda12..9243f31 100644
--- a/modes/pt_socks5/pt_socks5.go
+++ b/modes/pt_socks5/pt_socks5.go
@@ -30,10 +30,10 @@
package pt_socks5
import (
- "fmt"
"io"
"net"
"net/url"
+ "strconv"
"sync"
"github.com/OperatorFoundation/shapeshifter-dispatcher/common/log"
@@ -41,6 +41,9 @@ import (
"github.com/OperatorFoundation/shapeshifter-dispatcher/common/termmon"
"github.com/OperatorFoundation/shapeshifter-ipc"
"github.com/OperatorFoundation/shapeshifter-transports/transports/base"
+ "github.com/OperatorFoundation/shapeshifter-transports/transports/meeklite"
+ "github.com/OperatorFoundation/shapeshifter-transports/transports/obfs2"
+ "github.com/OperatorFoundation/shapeshifter-transports/transports/obfs4"
)
const (
@@ -49,16 +52,16 @@ const (
var stateDir string
-func ClientSetup(termMon *termmon.TermMonitor, target string, ptClientProxy *url.URL, factories map[string]base.ClientFactory) (launched bool, listeners []net.Listener) {
+func ClientSetup(termMon *termmon.TermMonitor, target string, ptClientProxy *url.URL, names []string, options string) (launched bool, listeners []net.Listener) {
// Launch each of the client listeners.
- for name, f := range factories {
+ for _, name := range names {
ln, err := net.Listen("tcp", socksAddr)
if err != nil {
pt.CmethodError(name, err.Error())
continue
}
- go clientAcceptLoop(target, termMon, name, f, ln, ptClientProxy)
+ go clientAcceptLoop(target, termMon, name, ln, ptClientProxy, options)
pt.Cmethod(name, socks5.Version(), ln.Addr())
log.Infof("%s - registered listener: %s", name, ln.Addr())
@@ -71,7 +74,7 @@ func ClientSetup(termMon *termmon.TermMonitor, target string, ptClientProxy *url
return
}
-func clientAcceptLoop(target string, termMon *termmon.TermMonitor, name string, f base.ClientFactory, ln net.Listener, proxyURI *url.URL) error {
+func clientAcceptLoop(target string, termMon *termmon.TermMonitor, name string, ln net.Listener, proxyURI *url.URL, options string) error {
defer ln.Close()
for {
conn, err := ln.Accept()
@@ -81,30 +84,79 @@ func clientAcceptLoop(target string, termMon *termmon.TermMonitor, name string,
}
continue
}
- go clientHandler(target, termMon, name, f, conn, proxyURI)
+ go clientHandler(target, termMon, name, conn, proxyURI, options)
}
}
-func clientHandler(target string, termMon *termmon.TermMonitor, name string, f base.ClientFactory, conn net.Conn, proxyURI *url.URL) {
+func clientHandler(target string, termMon *termmon.TermMonitor, name string, conn net.Conn, proxyURI *url.URL, options string) {
defer conn.Close()
termMon.OnHandlerStart()
defer termMon.OnHandlerFinish()
+ var needOptions bool = options == ""
+
// Read the client's SOCKS handshake.
- socksReq, err := socks5.Handshake(conn)
+ socksReq, err := socks5.Handshake(conn, needOptions)
if err != nil {
log.Errorf("%s - client failed socks handshake: %s", name, err)
return
}
addrStr := log.ElideAddr(socksReq.Target)
+ var args pt.Args
+ if needOptions {
+ args = socksReq.Args
+ } else {
+ args, err = pt.ParsePT2ClientParameters(options)
+ if err != nil {
+ return
+ }
+ }
+
+ var transport base.Transport
+
// Deal with arguments.
- // args, err := f.ParseArgs(&socksReq.Args)
- // if err != nil {
- // log.Errorf("%s(%s) - invalid arguments: %s", name, addrStr, err)
- // socksReq.Reply(socks5.ReplyGeneralFailure)
- // return
- // }
+ switch name {
+ case "obfs2":
+ transport = obfs2.NewObfs2Transport()
+ case "meeklite":
+ if url, ok := args.Get("url"); ok {
+ if front, ok2 := args.Get("front"); ok2 {
+ transport = meeklite.NewMeekTransportWithFront(url, front)
+ } else {
+ transport = meeklite.NewMeekTransport(url)
+ }
+ } else {
+ log.Errorf("meeklite transport missing URL argument: %s", args)
+ socksReq.Reply(socks5.ReplyGeneralFailure)
+ return
+ }
+ case "obfs4":
+ if cert, ok := args.Get("cert"); ok {
+ if iatModeStr, ok2 := args.Get("iatMode"); ok2 {
+ iatMode, err := strconv.Atoi(iatModeStr)
+ if err != nil {
+ transport = obfs4.NewObfs4Client(cert, iatMode)
+ } else {
+ log.Errorf("obfs4 transport bad iatMode value: %s", iatModeStr)
+ socksReq.Reply(socks5.ReplyGeneralFailure)
+ return
+ }
+ } else {
+ log.Errorf("obfs4 transport missing cert argument: %s", args)
+ socksReq.Reply(socks5.ReplyGeneralFailure)
+ return
+ }
+ } else {
+ log.Errorf("obfs4 transport missing cert argument: %s", args)
+ socksReq.Reply(socks5.ReplyGeneralFailure)
+ return
+ }
+ default:
+ log.Errorf("Unknown transport: %s", name)
+ socksReq.Reply(socks5.ReplyGeneralFailure)
+ return
+ }
// Obtain the proxy dialer if any, and create the outgoing TCP connection.
// dialFn := proxy.Direct.Dial
@@ -122,6 +174,8 @@ func clientHandler(target string, termMon *termmon.TermMonitor, name string, f b
//
// fmt.Println("Got dialer", dialFn, proxyURI, proxy.Direct)
+ f := transport.Dial
+
remote := f(socksReq.Target)
if err != nil {
log.Errorf("%s(%s) - outgoing connection failed: %s", name, addrStr, log.ElideError(err))
@@ -144,15 +198,58 @@ func clientHandler(target string, termMon *termmon.TermMonitor, name string, f b
return
}
-func ServerSetup(termMon *termmon.TermMonitor, bindaddrString string, factories map[string]base.ServerFactory, ptServerInfo pt.ServerInfo) (launched bool, listeners []base.TransportListener) {
+func ServerSetup(termMon *termmon.TermMonitor, bindaddrString string, ptServerInfo pt.ServerInfo, options string) (launched bool, listeners []base.TransportListener) {
for _, bindaddr := range ptServerInfo.Bindaddrs {
name := bindaddr.MethodName
- f := factories[name]
- if f == nil {
- fmt.Println(name, "no such transport is supported")
- continue
+
+ var transport base.Transport
+
+ args, argsErr := pt.ParsePT2ClientParameters(options)
+ if argsErr != nil {
+ log.Errorf("Error parsing transport options: %s", options)
+ return
}
+ // Deal with arguments.
+ switch name {
+ case "obfs2":
+ transport = obfs2.NewObfs2Transport()
+ case "meeklite":
+ if url, ok := args["url"]; ok {
+ if front, ok2 := args["front"]; ok2 {
+ transport = meeklite.NewMeekTransportWithFront(url[0], front[0])
+ } else {
+ transport = meeklite.NewMeekTransport(url[0])
+ }
+ } else {
+ log.Errorf("meeklite transport missing URL argument: %s", args)
+ return
+ }
+ case "obfs4":
+ if cert, ok := args["cert"]; ok {
+ if iatModeStr, ok2 := args["iatMode"]; ok2 {
+ iatMode, err := strconv.Atoi(iatModeStr[0])
+ if err != nil {
+ transport = obfs4.NewObfs4Client(cert[0], iatMode)
+ } else {
+ log.Errorf("obfs4 transport bad iatMode value: %s", iatModeStr)
+ return
+ }
+ } else {
+ log.Errorf("obfs4 transport missing cert argument: %s", args)
+ return
+ }
+ } else {
+ log.Errorf("obfs4 transport missing cert argument: %s", args)
+ return
+ }
+ default:
+ log.Errorf("Unknown transport: %s", name)
+ return
+ }
+
+ f := transport.Listen
+
transportLn := f(bindaddr.Addr.String())
go serverAcceptLoop(termMon, name, transportLn, &ptServerInfo)
diff --git a/modes/stun_udp/stun_udp.go b/modes/stun_udp/stun_udp.go
index d1cff6f..81ef6d8 100644
--- a/modes/stun_udp/stun_udp.go
+++ b/modes/stun_udp/stun_udp.go
@@ -46,6 +46,9 @@ import (
"github.com/OperatorFoundation/shapeshifter-dispatcher/common/termmon"
"github.com/OperatorFoundation/shapeshifter-ipc"
"github.com/OperatorFoundation/shapeshifter-transports/transports/base"
+ "github.com/OperatorFoundation/shapeshifter-transports/transports/meeklite"
+ "github.com/OperatorFoundation/shapeshifter-transports/transports/obfs2"
+ "github.com/OperatorFoundation/shapeshifter-transports/transports/obfs4"
)
const (
@@ -65,9 +68,9 @@ func NewConnState() ConnState {
type ConnTracker map[string]ConnState
-func ClientSetup(termMon *termmon.TermMonitor, target string, ptClientProxy *url.URL, factories map[string]base.ClientFactory) bool {
+func ClientSetup(termMon *termmon.TermMonitor, target string, ptClientProxy *url.URL, names []string, options string) bool {
// Launch each of the client listeners.
- for name, f := range factories {
+ for _, name := range names {
udpAddr, err := net.ResolveUDPAddr("udp", socksAddr)
if err != nil {
fmt.Println("Error resolving address", socksAddr)
@@ -80,7 +83,7 @@ func ClientSetup(termMon *termmon.TermMonitor, target string, ptClientProxy *url
continue
}
- go clientHandler(target, termMon, name, f, ln, ptClientProxy)
+ go clientHandler(target, termMon, name, options, ln, ptClientProxy)
log.Infof("%s - registered listener: %s", name, ln)
}
@@ -88,7 +91,7 @@ func ClientSetup(termMon *termmon.TermMonitor, target string, ptClientProxy *url
return true
}
-func clientHandler(target string, termMon *termmon.TermMonitor, name string, f base.ClientFactory, conn *net.UDPConn, proxyURI *url.URL) {
+func clientHandler(target string, termMon *termmon.TermMonitor, name string, options string, conn *net.UDPConn, proxyURI *url.URL) {
defer conn.Close()
termMon.OnHandlerStart()
defer termMon.OnHandlerFinish()
@@ -131,7 +134,7 @@ func clientHandler(target string, termMon *termmon.TermMonitor, name string, f b
fmt.Println("Opening connection to ", target)
- openConnection(&tracker, addr.String(), target, termMon, f, proxyURI)
+ openConnection(&tracker, addr.String(), target, termMon, name, options, proxyURI)
// Drop the packet.
fmt.Println("recv: Open")
@@ -139,16 +142,16 @@ func clientHandler(target string, termMon *termmon.TermMonitor, name string, f b
}
}
-func openConnection(tracker *ConnTracker, addr string, target string, termMon *termmon.TermMonitor, f base.ClientFactory, proxyURI *url.URL) {
+func openConnection(tracker *ConnTracker, addr string, target string, termMon *termmon.TermMonitor, name string, options string, proxyURI *url.URL) {
fmt.Println("Making dialer...")
newConn := NewConnState()
(*tracker)[addr] = newConn
- go dialConn(tracker, addr, target, f, proxyURI)
+ go dialConn(tracker, addr, target, name, options, proxyURI)
}
-func dialConn(tracker *ConnTracker, addr string, target string, f base.ClientFactory, proxyURI *url.URL) {
+func dialConn(tracker *ConnTracker, addr string, target string, name string, options string, proxyURI *url.URL) {
// Obtain the proxy dialer if any, and create the outgoing TCP connection.
// dialFn := proxy.Direct.Dial
// if proxyURI != nil {
@@ -165,14 +168,53 @@ func dialConn(tracker *ConnTracker, addr string, target string, f base.ClientFac
fmt.Println("Dialing....")
+ var transport base.Transport
+
+ args, argsErr := pt.ParsePT2ClientParameters(options)
+ if argsErr != nil {
+ log.Errorf("Error parsing transport options: %s", options)
+ return
+ }
+
// Deal with arguments.
- // args, err := f.ParseArgs(&pt.Args{})
- // if err != nil {
- // fmt.Println("Invalid arguments")
- // log.Errorf("(%s) - invalid arguments: %s", target, err)
- // delete(*tracker, addr)
- // return
- // }
+ switch name {
+ case "obfs2":
+ transport = obfs2.NewObfs2Transport()
+ case "meeklite":
+ if url, ok := args["url"]; ok {
+ if front, ok2 := args["front"]; ok2 {
+ transport = meeklite.NewMeekTransportWithFront(url[0], front[0])
+ } else {
+ transport = meeklite.NewMeekTransport(url[0])
+ }
+ } else {
+ log.Errorf("meeklite transport missing URL argument: %s", args)
+ return
+ }
+ case "obfs4":
+ if cert, ok := args["cert"]; ok {
+ if iatModeStr, ok2 := args["iatMode"]; ok2 {
+ iatMode, err := strconv.Atoi(iatModeStr[0])
+ if err != nil {
+ transport = obfs4.NewObfs4Client(cert[0], iatMode)
+ } else {
+ log.Errorf("obfs4 transport bad iatMode value: %s", iatModeStr)
+ return
+ }
+ } else {
+ log.Errorf("obfs4 transport missing cert argument: %s", args)
+ return
+ }
+ } else {
+ log.Errorf("obfs4 transport missing cert argument: %s", args)
+ return
+ }
+ default:
+ log.Errorf("Unknown transport: %s", name)
+ return
+ }
+
+ f := transport.Dial
fmt.Println("Dialing ", target)
remote := f(target)
@@ -189,19 +231,62 @@ func dialConn(tracker *ConnTracker, addr string, target string, f base.ClientFac
(*tracker)[addr] = ConnState{remote, false}
}
-func ServerSetup(termMon *termmon.TermMonitor, bindaddrString string, factories map[string]base.ServerFactory, ptServerInfo pt.ServerInfo) (launched bool, listeners []base.TransportListener) {
+func ServerSetup(termMon *termmon.TermMonitor, bindaddrString string, ptServerInfo pt.ServerInfo, options string) (launched bool, listeners []base.TransportListener) {
fmt.Println("ServerSetup")
// Launch each of the server listeners.
for _, bindaddr := range ptServerInfo.Bindaddrs {
name := bindaddr.MethodName
fmt.Println("bindaddr", bindaddr)
- f := factories[name]
- if f == nil {
- fmt.Println(name, "no such transport is supported")
- continue
+
+ var transport base.Transport
+
+ args, argsErr := pt.ParsePT2ClientParameters(options)
+ if argsErr != nil {
+ log.Errorf("Error parsing transport options: %s", options)
+ return
}
+ // Deal with arguments.
+ switch name {
+ case "obfs2":
+ transport = obfs2.NewObfs2Transport()
+ case "meeklite":
+ if url, ok := args["url"]; ok {
+ if front, ok2 := args["front"]; ok2 {
+ transport = meeklite.NewMeekTransportWithFront(url[0], front[0])
+ } else {
+ transport = meeklite.NewMeekTransport(url[0])
+ }
+ } else {
+ log.Errorf("meeklite transport missing URL argument: %s", args)
+ return
+ }
+ case "obfs4":
+ if cert, ok := args["cert"]; ok {
+ if iatModeStr, ok2 := args["iatMode"]; ok2 {
+ iatMode, err := strconv.Atoi(iatModeStr[0])
+ if err != nil {
+ transport = obfs4.NewObfs4Client(cert[0], iatMode)
+ } else {
+ log.Errorf("obfs4 transport bad iatMode value: %s", iatModeStr)
+ return
+ }
+ } else {
+ log.Errorf("obfs4 transport missing cert argument: %s", args)
+ return
+ }
+ } else {
+ log.Errorf("obfs4 transport missing cert argument: %s", args)
+ return
+ }
+ default:
+ log.Errorf("Unknown transport: %s", name)
+ return
+ }
+
+ f := transport.Listen
+
transportLn := f(bindaddr.Addr.String())
go serverAcceptLoop(termMon, name, transportLn, &ptServerInfo)
diff --git a/modes/transparent_tcp/transparent_tcp.go b/modes/transparent_tcp/transparent_tcp.go
index bbc0c7f..61d6c6e 100644
--- a/modes/transparent_tcp/transparent_tcp.go
+++ b/modes/transparent_tcp/transparent_tcp.go
@@ -34,6 +34,7 @@ import (
"io"
"net"
"net/url"
+ "strconv"
"strings"
"sync"
@@ -41,6 +42,9 @@ import (
"github.com/OperatorFoundation/shapeshifter-dispatcher/common/termmon"
"github.com/OperatorFoundation/shapeshifter-ipc"
"github.com/OperatorFoundation/shapeshifter-transports/transports/base"
+ "github.com/OperatorFoundation/shapeshifter-transports/transports/meeklite"
+ "github.com/OperatorFoundation/shapeshifter-transports/transports/obfs2"
+ "github.com/OperatorFoundation/shapeshifter-transports/transports/obfs4"
)
const (
@@ -49,9 +53,9 @@ const (
var stateDir string
-func ClientSetup(termMon *termmon.TermMonitor, target string, ptClientProxy *url.URL, factories map[string]base.ClientFactory) (launched bool, listeners []net.Listener) {
+func ClientSetup(termMon *termmon.TermMonitor, target string, ptClientProxy *url.URL, names []string, options string) (launched bool, listeners []net.Listener) {
// Launch each of the client listeners.
- for name, f := range factories {
+ for _, name := range names {
fmt.Println("Listening ", socksAddr)
ln, err := net.Listen("tcp", socksAddr)
if err != nil {
@@ -59,7 +63,7 @@ func ClientSetup(termMon *termmon.TermMonitor, target string, ptClientProxy *url
continue
}
- go clientAcceptLoop(target, termMon, name, f, ln, ptClientProxy)
+ go clientAcceptLoop(target, termMon, name, options, ln, ptClientProxy)
log.Infof("%s - registered listener: %s", name, ln.Addr())
@@ -70,7 +74,7 @@ func ClientSetup(termMon *termmon.TermMonitor, target string, ptClientProxy *url
return
}
-func clientAcceptLoop(target string, termMon *termmon.TermMonitor, name string, f base.ClientFactory, ln net.Listener, proxyURI *url.URL) error {
+func clientAcceptLoop(target string, termMon *termmon.TermMonitor, name string, options string, ln net.Listener, proxyURI *url.URL) error {
defer ln.Close()
for {
conn, err := ln.Accept()
@@ -81,11 +85,11 @@ func clientAcceptLoop(target string, termMon *termmon.TermMonitor, name string,
}
continue
}
- go clientHandler(target, termMon, name, f, conn, proxyURI)
+ go clientHandler(target, termMon, name, options, conn, proxyURI)
}
}
-func clientHandler(target string, termMon *termmon.TermMonitor, name string, f base.ClientFactory, conn net.Conn, proxyURI *url.URL) {
+func clientHandler(target string, termMon *termmon.TermMonitor, name string, options string, conn net.Conn, proxyURI *url.URL) {
defer conn.Close()
termMon.OnHandlerStart()
defer termMon.OnHandlerFinish()
@@ -94,14 +98,53 @@ func clientHandler(target string, termMon *termmon.TermMonitor, name string, f b
fmt.Println("Transport is", name)
+ var transport base.Transport
+
+ args, argsErr := pt.ParsePT2ClientParameters(options)
+ if argsErr != nil {
+ log.Errorf("Error parsing transport options: %s", options)
+ return
+ }
+
// Deal with arguments.
- // FIXME - deal with args for transports that have args
- // args, err := f.ParseArgs(&pt.Args{})
- // if err != nil {
- // fmt.Println("Invalid arguments")
- // log.Errorf("%s(%s) - invalid arguments: %s", name, target, err)
- // return
- // }
+ switch name {
+ case "obfs2":
+ transport = obfs2.NewObfs2Transport()
+ case "meeklite":
+ if url, ok := args["url"]; ok {
+ if front, ok2 := args["front"]; ok2 {
+ transport = meeklite.NewMeekTransportWithFront(url[0], front[0])
+ } else {
+ transport = meeklite.NewMeekTransport(url[0])
+ }
+ } else {
+ log.Errorf("meeklite transport missing URL argument: %s", args)
+ return
+ }
+ case "obfs4":
+ if cert, ok := args["cert"]; ok {
+ if iatModeStr, ok2 := args["iatMode"]; ok2 {
+ iatMode, err := strconv.Atoi(iatModeStr[0])
+ if err != nil {
+ transport = obfs4.NewObfs4Client(cert[0], iatMode)
+ } else {
+ log.Errorf("obfs4 transport bad iatMode value: %s", iatModeStr)
+ return
+ }
+ } else {
+ log.Errorf("obfs4 transport missing cert argument: %s", args)
+ return
+ }
+ } else {
+ log.Errorf("obfs4 transport missing cert argument: %s", args)
+ return
+ }
+ default:
+ log.Errorf("Unknown transport: %s", name)
+ return
+ }
+
+ f := transport.Dial
fmt.Println("Making dialer...")
@@ -143,19 +186,62 @@ func clientHandler(target string, termMon *termmon.TermMonitor, name string, f b
return
}
-func ServerSetup(termMon *termmon.TermMonitor, bindaddrString string, factories map[string]base.ServerFactory, ptServerInfo pt.ServerInfo) (launched bool, listeners []base.TransportListener) {
- fmt.Println("ServerSetup", bindaddrString, factories, ptServerInfo)
+func ServerSetup(termMon *termmon.TermMonitor, bindaddrString string, ptServerInfo pt.ServerInfo, options string) (launched bool, listeners []base.TransportListener) {
+ fmt.Println("ServerSetup", bindaddrString, ptServerInfo, options)
// Launch each of the server listeners.
for _, bindaddr := range ptServerInfo.Bindaddrs {
name := bindaddr.MethodName
fmt.Println("bindaddr", bindaddr)
- f := factories[name]
- if f == nil {
- fmt.Println(name, "no such transport is supported")
- continue
+
+ var transport base.Transport
+
+ args, argsErr := pt.ParsePT2ClientParameters(options)
+ if argsErr != nil {
+ log.Errorf("Error parsing transport options: %s", options)
+ return
}
+ // Deal with arguments.
+ switch name {
+ case "obfs2":
+ transport = obfs2.NewObfs2Transport()
+ case "meeklite":
+ if url, ok := args["url"]; ok {
+ if front, ok2 := args["front"]; ok2 {
+ transport = meeklite.NewMeekTransportWithFront(url[0], front[0])
+ } else {
+ transport = meeklite.NewMeekTransport(url[0])
+ }
+ } else {
+ log.Errorf("meeklite transport missing URL argument: %s", args)
+ return
+ }
+ case "obfs4":
+ if cert, ok := args["cert"]; ok {
+ if iatModeStr, ok2 := args["iatMode"]; ok2 {
+ iatMode, err := strconv.Atoi(iatModeStr[0])
+ if err != nil {
+ transport = obfs4.NewObfs4Client(cert[0], iatMode)
+ } else {
+ log.Errorf("obfs4 transport bad iatMode value: %s", iatModeStr)
+ return
+ }
+ } else {
+ log.Errorf("obfs4 transport missing cert argument: %s", args)
+ return
+ }
+ } else {
+ log.Errorf("obfs4 transport missing cert argument: %s", args)
+ return
+ }
+ default:
+ log.Errorf("Unknown transport: %s", name)
+ return
+ }
+
+ f := transport.Listen
+
transportLn := f(bindaddr.Addr.String())
go serverAcceptLoop(termMon, name, transportLn, &ptServerInfo)
diff --git a/modes/transparent_udp/transparent_udp.go b/modes/transparent_udp/transparent_udp.go
index f993b5e..63591a7 100644
--- a/modes/transparent_udp/transparent_udp.go
+++ b/modes/transparent_udp/transparent_udp.go
@@ -44,6 +44,9 @@ import (
"github.com/OperatorFoundation/shapeshifter-dispatcher/common/termmon"
"github.com/OperatorFoundation/shapeshifter-ipc"
"github.com/OperatorFoundation/shapeshifter-transports/transports/base"
+ "github.com/OperatorFoundation/shapeshifter-transports/transports/meeklite"
+ "github.com/OperatorFoundation/shapeshifter-transports/transports/obfs2"
+ "github.com/OperatorFoundation/shapeshifter-transports/transports/obfs4"
)
const (
@@ -63,9 +66,9 @@ func NewConnState() ConnState {
type ConnTracker map[string]ConnState
-func ClientSetup(termMon *termmon.TermMonitor, target string, ptClientProxy *url.URL, factories map[string]base.ClientFactory) bool {
+func ClientSetup(termMon *termmon.TermMonitor, target string, ptClientProxy *url.URL, names []string, options string) bool {
// Launch each of the client listeners.
- for name, f := range factories {
+ for _, name := range names {
udpAddr, err := net.ResolveUDPAddr("udp", socksAddr)
if err != nil {
fmt.Println("Error resolving address", socksAddr)
@@ -78,7 +81,7 @@ func ClientSetup(termMon *termmon.TermMonitor, target string, ptClientProxy *url
continue
}
- go clientHandler(target, termMon, name, f, ln, ptClientProxy)
+ go clientHandler(target, termMon, name, options, ln, ptClientProxy)
log.Infof("%s - registered listener: %s", name, ln)
}
@@ -86,7 +89,7 @@ func ClientSetup(termMon *termmon.TermMonitor, target string, ptClientProxy *url
return true
}
-func clientHandler(target string, termMon *termmon.TermMonitor, name string, f base.ClientFactory, conn *net.UDPConn, proxyURI *url.URL) {
+func clientHandler(target string, termMon *termmon.TermMonitor, name string, options string, conn *net.UDPConn, proxyURI *url.URL) {
var length16 uint16
defer conn.Close()
@@ -142,7 +145,7 @@ func clientHandler(target string, termMon *termmon.TermMonitor, name string, f b
fmt.Println("Opening connection to ", target)
- openConnection(&tracker, addr.String(), target, termMon, f, proxyURI)
+ openConnection(&tracker, addr.String(), target, termMon, name, options, proxyURI)
// Drop the packet.
fmt.Println("recv: Open")
@@ -150,16 +153,16 @@ func clientHandler(target string, termMon *termmon.TermMonitor, name string, f b
}
}
-func openConnection(tracker *ConnTracker, addr string, target string, termMon *termmon.TermMonitor, f base.ClientFactory, proxyURI *url.URL) {
+func openConnection(tracker *ConnTracker, addr string, target string, termMon *termmon.TermMonitor, name string, options string, proxyURI *url.URL) {
fmt.Println("Making dialer...")
newConn := NewConnState()
(*tracker)[addr] = newConn
- go dialConn(tracker, addr, target, f, proxyURI)
+ go dialConn(tracker, addr, target, name, options, proxyURI)
}
-func dialConn(tracker *ConnTracker, addr string, target string, f base.ClientFactory, proxyURI *url.URL) {
+func dialConn(tracker *ConnTracker, addr string, target string, name string, options string, proxyURI *url.URL) {
// Obtain the proxy dialer if any, and create the outgoing TCP connection.
// dialFn := proxy.Direct.Dial
// if proxyURI != nil {
@@ -176,15 +179,53 @@ func dialConn(tracker *ConnTracker, addr string, target string, f base.ClientFac
fmt.Println("Dialing....")
+ var transport base.Transport
+
+ args, argsErr := pt.ParsePT2ClientParameters(options)
+ if argsErr != nil {
+ log.Errorf("Error parsing transport options: %s", options)
+ return
+ }
+
// Deal with arguments.
- // args, err := f.ParseArgs(&pt.Args{})
- // if err != nil {
- // fmt.Println("Invalid arguments")
- // log.Errorf("(%s) - invalid arguments: %s", target, err)
- // delete(*tracker, addr)
- // return
- // }
+ switch name {
+ case "obfs2":
+ transport = obfs2.NewObfs2Transport()
+ case "meeklite":
+ if url, ok := args["url"]; ok {
+ if front, ok2 := args["front"]; ok2 {
+ transport = meeklite.NewMeekTransportWithFront(url[0], front[0])
+ } else {
+ transport = meeklite.NewMeekTransport(url[0])
+ }
+ } else {
+ log.Errorf("meeklite transport missing URL argument: %s", args)
+ return
+ }
+ case "obfs4":
+ if cert, ok := args["cert"]; ok {
+ if iatModeStr, ok2 := args["iatMode"]; ok2 {
+ iatMode, err := strconv.Atoi(iatModeStr[0])
+ if err != nil {
+ transport = obfs4.NewObfs4Client(cert[0], iatMode)
+ } else {
+ log.Errorf("obfs4 transport bad iatMode value: %s", iatModeStr)
+ return
+ }
+ } else {
+ log.Errorf("obfs4 transport missing cert argument: %s", args)
+ return
+ }
+ } else {
+ log.Errorf("obfs4 transport missing cert argument: %s", args)
+ return
+ }
+ default:
+ log.Errorf("Unknown transport: %s", name)
+ return
+ }
+ f := transport.Dial
fmt.Println("Dialing ", target)
remote := f(target)
// if err != nil {
@@ -200,19 +241,62 @@ func dialConn(tracker *ConnTracker, addr string, target string, f base.ClientFac
(*tracker)[addr] = ConnState{remote, false}
}
-func ServerSetup(termMon *termmon.TermMonitor, bindaddrString string, factories map[string]base.ServerFactory, ptServerInfo pt.ServerInfo) (launched bool, listeners []base.TransportListener) {
+func ServerSetup(termMon *termmon.TermMonitor, bindaddrString string, ptServerInfo pt.ServerInfo, options string) (launched bool, listeners []base.TransportListener) {
fmt.Println("ServerSetup")
// Launch each of the server listeners.
for _, bindaddr := range ptServerInfo.Bindaddrs {
name := bindaddr.MethodName
fmt.Println("bindaddr", bindaddr)
- f := factories[name]
- if f == nil {
- fmt.Println(name, "no such transport is supported")
- continue
+
+ var transport base.Transport
+
+ args, argsErr := pt.ParsePT2ClientParameters(options)
+ if argsErr != nil {
+ log.Errorf("Error parsing transport options: %s", options)
+ return
+ }
+
+ // Deal with arguments.
+ switch name {
+ case "obfs2":
+ transport = obfs2.NewObfs2Transport()
+ case "meeklite":
+ if url, ok := args["url"]; ok {
+ if front, ok2 := args["front"]; ok2 {
+ transport = meeklite.NewMeekTransportWithFront(url[0], front[0])
+ } else {
+ transport = meeklite.NewMeekTransport(url[0])
+ }
+ } else {
+ log.Errorf("meeklite transport missing URL argument: %s", args)
+ return
+ }
+ case "obfs4":
+ if cert, ok := args["cert"]; ok {
+ if iatModeStr, ok2 := args["iatMode"]; ok2 {
+ iatMode, err := strconv.Atoi(iatModeStr[0])
+ if err != nil {
+ transport = obfs4.NewObfs4Client(cert[0], iatMode)
+ } else {
+ log.Errorf("obfs4 transport bad iatMode value: %s", iatModeStr)
+ return
+ }
+ } else {
+ log.Errorf("obfs4 transport missing cert argument: %s", args)
+ return
+ }
+ } else {
+ log.Errorf("obfs4 transport missing cert argument: %s", args)
+ return
+ }
+ default:
+ log.Errorf("Unknown transport: %s", name)
+ return
}
+ f := transport.Listen
+
transportLn := f(bindaddr.Addr.String())
go serverAcceptLoop(termMon, name, transportLn, &ptServerInfo)