summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Whited <sam@samwhited.com>2022-03-04 13:35:44 -0500
committerSam Whited <sam@samwhited.com>2022-03-04 13:36:54 -0500
commita222fa29821e3821e9250ccf949c9cff9168fb67 (patch)
tree68c2e109539a97c4349859b80cbb2028f42266d7
parent32872b5a198037082ab77f34bfb44200d09aee60 (diff)
Use upstream obfs4
Signed-off-by: Sam Whited <sam@samwhited.com>
-rw-r--r--go.mod10
-rw-r--r--go.sum35
-rw-r--r--shapeshifter.go71
3 files changed, 68 insertions, 48 deletions
diff --git a/go.mod b/go.mod
index 0f0aaff..bc72b44 100644
--- a/go.mod
+++ b/go.mod
@@ -3,15 +3,15 @@ module 0xacab.org/leap/shapeshifter
go 1.17
require (
- github.com/OperatorFoundation/obfs4 v1.0.0
- github.com/OperatorFoundation/shapeshifter-transports/transports/obfs4/v2 v2.2.8
+ git.torproject.org/pluggable-transports/goptlib.git v1.1.0
+ gitlab.com/yawning/obfs4.git v0.0.0-20220204003609-77af0cba934d
golang.org/x/net v0.0.0-20220225172249-27dd8689420f
)
require (
- github.com/OperatorFoundation/ed25519 v0.0.0-20200225224545-b22b4bd3ddef // indirect
- github.com/OperatorFoundation/shapeshifter-ipc/v2 v2.0.0 // indirect
+ filippo.io/edwards25519 v1.0.0-rc.1.0.20210721174708-390f27c3be20 // indirect
github.com/dchest/siphash v1.2.1 // indirect
- golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d // indirect
+ gitlab.com/yawning/edwards25519-extra.git v0.0.0-20211229043746-2f91fcc9fbdb // indirect
+ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
)
diff --git a/go.sum b/go.sum
index ab209a4..d073214 100644
--- a/go.sum
+++ b/go.sum
@@ -1,24 +1,25 @@
+filippo.io/edwards25519 v1.0.0-rc.1.0.20210721174708-390f27c3be20 h1:iJoUgXvhagsNMrJrvavw7vu1eG8+hm6jLOxlLFcoODw=
+filippo.io/edwards25519 v1.0.0-rc.1.0.20210721174708-390f27c3be20/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
+git.torproject.org/pluggable-transports/goptlib.git v1.0.0/go.mod h1:YT4XMSkuEXbtqlydr9+OxqFAyspUv0Gr9qhM3B++o/Q=
+git.torproject.org/pluggable-transports/goptlib.git v1.1.0 h1:LMQAA8pAho+QtYrrVNimJQiINNEwcwuuD99vezD/PAo=
git.torproject.org/pluggable-transports/goptlib.git v1.1.0/go.mod h1:YT4XMSkuEXbtqlydr9+OxqFAyspUv0Gr9qhM3B++o/Q=
-github.com/OperatorFoundation/ed25519 v0.0.0-20200225224545-b22b4bd3ddef h1:1xEtDEuNE9/yybZaHS94OIjx5FUo4e8M3UwcK9bFC9s=
-github.com/OperatorFoundation/ed25519 v0.0.0-20200225224545-b22b4bd3ddef/go.mod h1:gQNGvsyT4Zmps9H/yzCqdc+RQzt8ZxCndRNtGTYnBzQ=
-github.com/OperatorFoundation/obfs4 v1.0.0 h1:OcfdNMzv69fKQrLTkTSwpaBkHyBZMLjigA5M3txZpAg=
-github.com/OperatorFoundation/obfs4 v1.0.0/go.mod h1:6apgxOLYwyvbpzujpFHWu6Jlc+mjn1aFK7WvNijIVWc=
-github.com/OperatorFoundation/shapeshifter-ipc/v2 v2.0.0 h1:6aQs+TF3KULMarpzbKu8DhFOF9D2UBCaAN5ZtbK53nQ=
-github.com/OperatorFoundation/shapeshifter-ipc/v2 v2.0.0/go.mod h1:gb/QiZH0QDXLSQ9PskyJ2oTflB7tsP4AYc8y+FppvB0=
-github.com/OperatorFoundation/shapeshifter-transports/transports/obfs4/v2 v2.2.8 h1:tVkPBx13P6OLKV1OOGnX8BzL3xldHLz7hZAf1V3ZqT4=
-github.com/OperatorFoundation/shapeshifter-transports/transports/obfs4/v2 v2.2.8/go.mod h1:WbvdPacTr1IvoVsd9fYk4sDaWoxxCZIQDks9jRveRC0=
github.com/dchest/siphash v1.2.1 h1:4cLinnzVJDKxTCl9B01807Yiy+W7ZzVHj/KIroQRvT4=
github.com/dchest/siphash v1.2.1/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4=
-github.com/willscott/goturn v0.0.0-20170802220503-19f41278d0c9/go.mod h1:PfwRjodCaQXOsHnh2DeVaXqCFCIrbn5WLj1+A5bQkD4=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d h1:1ZiEyfaQIg3Qh0EoqpwAakHVhecoE5wlSg5GjnafJGw=
-golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+gitlab.com/yawning/edwards25519-extra.git v0.0.0-20211229043746-2f91fcc9fbdb h1:qRSZHsODmAP5qDvb3YsO7Qnf3TRiVbGxNG/WYnlM4/o=
+gitlab.com/yawning/edwards25519-extra.git v0.0.0-20211229043746-2f91fcc9fbdb/go.mod h1:gvdJuZuO/tPZyhEV8K3Hmoxv/DWud5L4qEQxfYjEUTo=
+gitlab.com/yawning/obfs4.git v0.0.0-20220204003609-77af0cba934d h1:tJ8F7ABaQ3p3wjxwXiWSktVDgjZEXkvaRawd2rIq5ws=
+gitlab.com/yawning/obfs4.git v0.0.0-20220204003609-77af0cba934d/go.mod h1:9GcM8QNU9/wXtEEH2q8bVOnPI7FtIF6VVLzZ1l6Hgf8=
+golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI=
+golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
diff --git a/shapeshifter.go b/shapeshifter.go
index 25a6400..c717cd2 100644
--- a/shapeshifter.go
+++ b/shapeshifter.go
@@ -6,13 +6,33 @@ import (
"io"
"log"
"net"
+ "strconv"
"sync"
- "github.com/OperatorFoundation/obfs4/common/ntor"
- "github.com/OperatorFoundation/shapeshifter-transports/transports/obfs4/v2"
+ pt "git.torproject.org/pluggable-transports/goptlib.git"
+ "gitlab.com/yawning/obfs4.git/common/ntor"
+ "gitlab.com/yawning/obfs4.git/transports/obfs4"
"golang.org/x/net/proxy"
)
+const (
+ certLength = ntor.NodeIDLength + ntor.PublicKeyLength
+)
+
+func unpackCert(cert string) (*ntor.NodeID, *ntor.PublicKey, error) {
+ if l := base64.RawStdEncoding.DecodedLen(len(cert)); l != certLength {
+ return nil, nil, fmt.Errorf("cert length %d is invalid", l)
+ }
+ decoded, err := base64.RawStdEncoding.DecodeString(cert)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ nodeID, _ := ntor.NewNodeID(decoded[:ntor.NodeIDLength])
+ pubKey, _ := ntor.NewPublicKey(decoded[ntor.NodeIDLength:])
+ return nodeID, pubKey, nil
+}
+
type Logger interface {
Log(msg string)
}
@@ -78,12 +98,31 @@ func (ss ShapeShifter) clientHandler(conn net.Conn) {
defer conn.Close()
dialer := proxy.Direct
- transport, err := obfs4.NewObfs4Client(ss.Cert, ss.IatMode, dialer)
+ // The empty string is the StateDir argument which appears unused on the
+ // client side. I am unsure why the clientfactory requires it; possibly to
+ // satisfy an interface somewhere, but this is not documented.
+ //transport, err := obfs4.NewObfs4Client(ss.Cert, ss.IatMode, dialer)
+
+ transport, err := (&obfs4.Transport{}).ClientFactory("")
if err != nil {
ss.sendError("Can not create an obfs4 client (cert: %s, iat-mode: %d): %v", ss.Cert, ss.IatMode, err)
return
}
- remote, err := transport.Dial(ss.Target)
+ ptArgs := make(pt.Args)
+ nodeID, pubKey, err := unpackCert(ss.Cert)
+ if err != nil {
+ ss.sendError("Error unpacking cert: %v", err)
+ return
+ }
+ ptArgs.Add("node-id", nodeID.Hex())
+ ptArgs.Add("public-key", pubKey.Hex())
+ ptArgs.Add("iat-mode", strconv.Itoa(ss.IatMode))
+ args, err := transport.ParseArgs(&ptArgs)
+ if err != nil {
+ ss.sendError("Cannot parse arguments: %v", err)
+ return
+ }
+ remote, err := transport.Dial("tcp", ss.Target, dialer.Dial, args)
if err != nil {
ss.sendError("outgoing connection failed %s: %v", ss.Target, err)
return
@@ -142,7 +181,8 @@ func (ss *ShapeShifter) checkOptions() error {
if ss.SocksAddr == "" {
ss.SocksAddr = "127.0.0.1:0"
}
- return isCertValid(ss.Cert)
+ _, _, err := unpackCert(ss.Cert)
+ return err
}
func (ss *ShapeShifter) sendError(format string, a ...interface{}) {
@@ -160,24 +200,3 @@ func (ss *ShapeShifter) sendError(format string, a ...interface{}) {
log.Printf(format, a...)
}
}
-
-func isCertValid(cert string) error {
- // copied from github.com/OperatorFoundation/shapeshifter-transports/transports/obfs4/statefile.go
- const certSuffix = "=="
- const certLength = ntor.NodeIDLength + ntor.PublicKeyLength
-
- if cert == "" {
- return fmt.Errorf("obfs4 transport missing cert argument")
- }
-
- decoded, err := base64.StdEncoding.DecodeString(cert + certSuffix)
- if err != nil {
- return fmt.Errorf("failed to decode cert: %s", err)
- }
-
- if len(decoded) != certLength {
- return fmt.Errorf("cert length %d is invalid", len(decoded))
- }
-
- return nil
-}