diff options
Diffstat (limited to 'obfs4-client/obfs4-client.go')
-rw-r--r-- | obfs4-client/obfs4-client.go | 183 |
1 files changed, 0 insertions, 183 deletions
diff --git a/obfs4-client/obfs4-client.go b/obfs4-client/obfs4-client.go deleted file mode 100644 index 077fb85..0000000 --- a/obfs4-client/obfs4-client.go +++ /dev/null @@ -1,183 +0,0 @@ -/* - * 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. - * - * This file is based off goptlib's dummy-client.go file. - */ - -// obfs4 pluggable transport client. Works only as a managed proxy. -// -// Usage (in torrc): -// UseBridges 1 -// Bridge obfs4 X.X.X.X:YYYY public-key=<Base64 Bridge public key> node-id=<Base64 Node ID> -// ClientTransportPlugin obfs4 exec obfs4-client -// -// Becuase the pluggable transport requires arguments, using obfs4-client -// requires tor 0.2.5.x. -package main - -import ( - "io" - "net" - "os" - "os/signal" - "sync" - "syscall" - - "github.com/yawning/obfs4" -) - -import "git.torproject.org/pluggable-transports/goptlib.git" - -var ptInfo pt.ClientInfo - -// When a connection handler starts, +1 is written to this channel; when it -// ends, -1 is written. -var handlerChan = make(chan int) - -func copyLoop(a, b net.Conn) { - var wg sync.WaitGroup - wg.Add(2) - - // TODO: Log errors. - go func() { - io.Copy(b, a) - wg.Done() - }() - go func() { - io.Copy(a, b) - wg.Done() - }() - - wg.Wait() -} - -func handler(conn *pt.SocksConn) error { - // Extract the peer's node ID and public key. - nodeID, ok := conn.Req.Args.Get("node-id") - if !ok { - // TODO: Log something here. - conn.Reject() - } - publicKey, ok := conn.Req.Args.Get("public-key") - if !ok { - // TODO: Log something here. - conn.Reject() - } - - handlerChan <- 1 - defer func() { - handlerChan <- -1 - }() - - defer conn.Close() - remote, err := obfs4.Dial("tcp", conn.Req.Target, nodeID, publicKey) - if err != nil { - conn.Reject() - return err - } - defer remote.Close() - err = conn.Grant(remote.RemoteAddr().(*net.TCPAddr)) - if err != nil { - return err - } - - copyLoop(conn, remote) - - return nil -} - -func acceptLoop(ln *pt.SocksListener) error { - defer ln.Close() - for { - conn, err := ln.AcceptSocks() - if err != nil { - if e, ok := err.(net.Error); ok && !e.Temporary() { - return err - } - continue - } - go handler(conn) - } -} - -func main() { - var err error - - ptInfo, err = pt.ClientSetup([]string{"obfs4"}) - if err != nil { - os.Exit(1) - } - - listeners := make([]net.Listener, 0) - for _, methodName := range ptInfo.MethodNames { - switch methodName { - case "obfs4": - ln, err := pt.ListenSocks("tcp", "127.0.0.1:0") - if err != nil { - pt.CmethodError(methodName, err.Error()) - break - } - go acceptLoop(ln) - pt.Cmethod(methodName, ln.Version(), ln.Addr()) - listeners = append(listeners, ln) - default: - pt.CmethodError(methodName, "no such method") - } - } - pt.CmethodsDone() - - var numHandlers int = 0 - var sig os.Signal - sigChan := make(chan os.Signal, 1) - signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) - - // wait for first signal - sig = nil - for sig == nil { - select { - case n := <-handlerChan: - numHandlers += n - case sig = <-sigChan: - } - } - for _, ln := range listeners { - ln.Close() - } - - if sig == syscall.SIGTERM { - return - } - - // wait for second signal or no more handlers - sig = nil - for sig == nil && numHandlers != 0 { - select { - case n := <-handlerChan: - numHandlers += n - case sig = <-sigChan: - } - } -} |