From a222fa29821e3821e9250ccf949c9cff9168fb67 Mon Sep 17 00:00:00 2001 From: Sam Whited Date: Fri, 4 Mar 2022 13:35:44 -0500 Subject: Use upstream obfs4 Signed-off-by: Sam Whited --- go.mod | 10 ++++---- go.sum | 35 ++++++++++++++-------------- shapeshifter.go | 71 ++++++++++++++++++++++++++++++++++++--------------------- 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 -} -- cgit v1.2.3