func serverHandler(termMon *termmon.TermMonitor, f base.ServerFactory, conn net.Conn, info *pt.ServerInfo) { defer conn.Close() termMon.OnHandlerStart() defer termMon.OnHandlerFinish() name := f.Transport().Name() addrStr := log.ElideAddr(conn.RemoteAddr().String()) log.Infof("%s(%s) - new connection", name, addrStr) // Instantiate the server transport method and handshake. remote, err := f.WrapConn(conn) if err != nil { log.Warnf("%s(%s) - handshake failed: %s", name, addrStr, log.ElideError(err)) return } // Connect to the orport. orConn, err := pt.DialOr(info, conn.RemoteAddr().String(), name) if err != nil { log.Errorf("%s(%s) - failed to connect to ORPort: %s", name, addrStr, log.ElideError(err)) return } defer orConn.Close() if err = copyLoop(orConn, remote); err != nil { log.Warnf("%s(%s) - closed connection: %s", name, addrStr, log.ElideError(err)) } else { log.Infof("%s(%s) - closed connection", name, addrStr) } return }
func ServerSetup(termMon *termmon.TermMonitor, bindaddrString string, target string) bool { fmt.Println("ServerSetup") bindaddrs, _ := getServerBindaddrs(bindaddrString) for _, bindaddr := range bindaddrs { name := bindaddr.MethodName fmt.Println("bindaddr", bindaddr) t := transports.Get(name) if t == nil { fmt.Println(name, "no such transport is supported") continue } f, err := t.ServerFactory(stateDir, &bindaddr.Options) if err != nil { fmt.Println(name, err.Error()) continue } ln, err := net.ListenTCP("tcp", bindaddr.Addr) if err != nil { fmt.Println(name, err.Error()) continue } go serverAcceptLoop(termMon, f, ln, target) log.Infof("%s - registered listener: %s", name, log.ElideAddr(ln.Addr().String())) } return true }
func clientHandler(termMon *termmon.TermMonitor, f base.ClientFactory, conn net.Conn, proxyURI *url.URL) { defer conn.Close() termMon.OnHandlerStart() defer termMon.OnHandlerFinish() name := f.Transport().Name() // Read the client's SOCKS handshake. socksReq, err := socks5.Handshake(conn) if err != nil { log.Errorf("%s - client failed socks handshake: %s", name, err) return } addrStr := log.ElideAddr(socksReq.Target) // 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 } // Obtain the proxy dialer if any, and create the outgoing TCP connection. dialFn := proxy.Direct.Dial if proxyURI != nil { dialer, err := proxy.FromURL(proxyURI, proxy.Direct) if err != nil { // This should basically never happen, since config protocol // verifies this. log.Errorf("%s(%s) - failed to obtain proxy dialer: %s", name, addrStr, log.ElideError(err)) socksReq.Reply(socks5.ReplyGeneralFailure) return } dialFn = dialer.Dial } fmt.Println("Got dialer", dialFn, proxyURI, proxy.Direct) remote, err := f.Dial("tcp", socksReq.Target, dialFn, args) if err != nil { log.Errorf("%s(%s) - outgoing connection failed: %s", name, addrStr, log.ElideError(err)) socksReq.Reply(socks5.ErrorToReplyCode(err)) return } defer remote.Close() err = socksReq.Reply(socks5.ReplySucceeded) if err != nil { log.Errorf("%s(%s) - SOCKS reply failed: %s", name, addrStr, log.ElideError(err)) return } if err = copyLoop(conn, remote); err != nil { log.Warnf("%s(%s) - closed connection: %s", name, addrStr, log.ElideError(err)) } else { log.Infof("%s(%s) - closed connection", name, addrStr) } return }
func ClientSetup(termMon *termmon.TermMonitor, target string) (launched bool, listeners []net.Listener) { methodNames := [...]string{"obfs2"} var ptClientProxy *url.URL = nil // 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 } fmt.Println("Listening ", socksAddr) ln, err := net.Listen("tcp", socksAddr) if err != nil { log.Errorf("failed to listen %s %s", name, err.Error()) continue } go clientAcceptLoop(target, termMon, f, ln, ptClientProxy) log.Infof("%s - registered listener: %s", name, ln.Addr()) listeners = append(listeners, ln) launched = true } return }
func clientHandler(target string, termMon *termmon.TermMonitor, f base.ClientFactory, conn net.Conn, proxyURI *url.URL) { defer conn.Close() termMon.OnHandlerStart() defer termMon.OnHandlerFinish() fmt.Println("handling...") name := f.Transport().Name() fmt.Println("Transport is", name) // Deal with arguments. args, err := f.ParseArgs(&pt.Args{}) if err != nil { fmt.Println("Invalid arguments") log.Errorf("%s(%s) - invalid arguments: %s", name, target, err) return } fmt.Println("Making dialer...") // Obtain the proxy dialer if any, and create the outgoing TCP connection. dialFn := proxy.Direct.Dial if proxyURI != nil { dialer, err := proxy.FromURL(proxyURI, proxy.Direct) if err != nil { // This should basically never happen, since config protocol // verifies this. fmt.Println("failed to obtain dialer", proxyURI, proxy.Direct) log.Errorf("%s(%s) - failed to obtain proxy dialer: %s", name, target, log.ElideError(err)) return } dialFn = dialer.Dial } fmt.Println("Dialing...") remote, err := f.Dial("tcp", target, dialFn, args) if err != nil { fmt.Println("outgoing connection failed") log.Errorf("%s(%s) - outgoing connection failed: %s", name, target, log.ElideError(err)) return } defer remote.Close() fmt.Println("copying...") if err = copyLoop(conn, remote); err != nil { log.Warnf("%s(%s) - closed connection: %s", name, target, log.ElideError(err)) } else { log.Infof("%s(%s) - closed connection", name, target) } fmt.Println("done") return }
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() } // 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 } ln, err := net.Listen("tcp", socksAddr) if err != nil { pt.CmethodError(name, err.Error()) continue } go clientAcceptLoop(termMon, f, ln, ptClientProxy) pt.Cmethod(name, socks5.Version(), ln.Addr()) log.Infof("%s - registered listener: %s", name, ln.Addr()) listeners = append(listeners, ln) launched = true } pt.CmethodsDone() return }
func ServerSetup(termMon *termmon.TermMonitor) (launched bool, listeners []net.Listener) { ptServerInfo, err := pt.ServerSetup(transports.Transports()) if err != nil { golog.Fatal(err) } for _, bindaddr := range ptServerInfo.Bindaddrs { name := bindaddr.MethodName t := transports.Get(name) if t == nil { pt.SmethodError(name, "no such transport is supported") continue } f, err := t.ServerFactory(stateDir, &bindaddr.Options) if err != nil { pt.SmethodError(name, err.Error()) continue } ln, err := net.ListenTCP("tcp", bindaddr.Addr) if err != nil { pt.SmethodError(name, err.Error()) continue } go serverAcceptLoop(termMon, f, ln, &ptServerInfo) if args := f.Args(); args != nil { pt.SmethodArgs(name, ln.Addr(), *args) } else { pt.SmethodArgs(name, ln.Addr(), nil) } log.Infof("%s - registered listener: %s", name, log.ElideAddr(ln.Addr().String())) listeners = append(listeners, ln) launched = true } pt.SmethodsDone() return }
func ServerSetup(termMon *termmon.TermMonitor, bindaddrString string) (launched bool, listeners []net.Listener) { ptServerInfo, err := pt.ServerSetup(transports.Transports()) if err != nil { golog.Fatal(err) } fmt.Println("ServerSetup") bindaddrs, _ := getServerBindaddrs(bindaddrString) for _, bindaddr := range bindaddrs { name := bindaddr.MethodName fmt.Println("bindaddr", bindaddr) t := transports.Get(name) if t == nil { fmt.Println(name, "no such transport is supported") continue } f, err := t.ServerFactory(stateDir, &bindaddr.Options) if err != nil { fmt.Println(name, err.Error()) continue } ln, err := net.ListenTCP("tcp", bindaddr.Addr) if err != nil { fmt.Println(name, err.Error()) continue } go serverAcceptLoop(termMon, f, ln, &ptServerInfo) log.Infof("%s - registered listener: %s", name, log.ElideAddr(ln.Addr().String())) listeners = append(listeners, ln) launched = true } return }
func ClientSetup(termMon *termmon.TermMonitor, target string) bool { methodNames := [...]string{"obfs2"} var ptClientProxy *url.URL = nil // 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 } udpAddr, err := net.ResolveUDPAddr("udp", socksAddr) if err != nil { fmt.Println("Error resolving address", socksAddr) } fmt.Println("@@@ Listening ", name, socksAddr) ln, err := net.ListenUDP("udp", udpAddr) if err != nil { log.Errorf("failed to listen %s %s", name, err.Error()) continue } go clientHandler(target, termMon, f, ln, ptClientProxy) log.Infof("%s - registered listener: %s", name, ln) } return true }
func serverHandler(termMon *termmon.TermMonitor, f base.ServerFactory, conn net.Conn, target string) { var length16 uint16 defer conn.Close() termMon.OnHandlerStart() defer termMon.OnHandlerFinish() name := f.Transport().Name() addrStr := log.ElideAddr(conn.RemoteAddr().String()) fmt.Println("### handling", name) log.Infof("%s(%s) - new connection", name, addrStr) // Instantiate the server transport method and handshake. remote, err := f.WrapConn(conn) if err != nil { fmt.Println("handshake failed", err) log.Warnf("%s(%s) - handshake failed: %s", name, addrStr, log.ElideError(err)) return } serverAddr, err := net.ResolveUDPAddr("udp", target) if err != nil { golog.Fatal(err) } localAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:0") if err != nil { golog.Fatal(err) } dest, err := net.DialUDP("udp", localAddr, serverAddr) if err != nil { golog.Fatal(err) } fmt.Println("pumping") defer dest.Close() lengthBuffer := make([]byte, 2) for { fmt.Println("reading...") // Read the incoming connection into the buffer. readLen, err := io.ReadFull(remote, lengthBuffer) if err != nil { fmt.Println("read error") break } fmt.Println(readLen) err = binary.Read(bytes.NewReader(lengthBuffer), binary.LittleEndian, &length16) if err != nil { fmt.Println("deserialization error") return } fmt.Println("reading data") readBuffer := make([]byte, length16) readLen, err = io.ReadFull(remote, readBuffer) if err != nil { fmt.Println("read error") break } dest.Write(readBuffer) } }
func main() { // Initialize the termination state monitor as soon as possible. termMon = termmon.NewTermMonitor() // Handle the command line arguments. _, execName := path.Split(os.Args[0]) 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/"+obfs4proxyLogFile) unsafeLogging := flag.Bool("unsafeLogging", false, "Disable the address scrubber") transparent := flag.Bool("transparent", false, "Enable transparent proxy mode") udp := flag.Bool("udp", false, "Enable UDP proxy mode") target := flag.String("target", "", "Specify transport server destination address") clientMode := flag.Bool("client", false, "Enable client mode") 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") flag.Parse() if *showVer { fmt.Printf("%s\n", getVersion()) os.Exit(0) } if err := log.SetLogLevel(*logLevelStr); err != nil { fmt.Println("failed to set log level") golog.Fatalf("[ERROR]: %s - failed to set log level: %s", execName, err) } // Determine if this is a client or server, initialize the common state. var ptListeners []net.Listener launched := false isClient, err := checkIsClient(*clientMode, *serverMode) if err != nil { golog.Fatalf("[ERROR]: %s - must be run as a managed transport", execName) } if stateDir, err = makeStateDir(*statePath); err != nil { golog.Fatalf("[ERROR]: %s - No state directory: %s", execName, err) } if err = log.Init(*enableLogging, path.Join(stateDir, obfs4proxyLogFile), *unsafeLogging); err != nil { golog.Fatalf("[ERROR]: %s - failed to initialize logging", execName) } if err = transports.Init(); err != nil { log.Errorf("%s - failed to initialize transports: %s", execName, err) os.Exit(-1) } log.Noticef("%s - launched", getVersion()) fmt.Println("launching") if *transparent { // Do the transparent proxy configuration. log.Infof("%s - initializing transparent proxy", execName) if *udp { log.Infof("%s - initializing UDP transparent proxy", execName) if isClient { log.Infof("%s - initializing client transport listeners", execName) if *target == "" { log.Errorf("%s - transparent mode requires a target", execName) } else { fmt.Println("transparent udp client") launched = transparent_udp.ClientSetup(termMon, *target) } } else { log.Infof("%s - initializing server transport listeners", execName) if *bindAddr == "" { fmt.Println("%s - transparent mode requires a bindaddr", execName) } else { fmt.Println("transparent udp server") launched = transparent_udp.ServerSetup(termMon, *bindAddr, *target) fmt.Println("launched", launched, ptListeners) } } } else { log.Infof("%s - initializing TCP transparent proxy", execName) if isClient { log.Infof("%s - initializing client transport listeners", execName) if *target == "" { log.Errorf("%s - transparent mode requires a target", execName) } else { launched, ptListeners = transparent_tcp.ClientSetup(termMon, *target) } } else { log.Infof("%s - initializing server transport listeners", execName) if *bindAddr == "" { fmt.Println("%s - transparent mode requires a bindaddr", execName) } else { launched, ptListeners = transparent_tcp.ServerSetup(termMon, *bindAddr) fmt.Println("launched", launched, ptListeners) } } } } else { if *udp { log.Infof("%s - initializing STUN UDP proxy", execName) if isClient { log.Infof("%s - initializing client transport listeners", execName) if *target == "" { log.Errorf("%s - STUN mode requires a target", execName) } else { fmt.Println("STUN udp client") launched = stun_udp.ClientSetup(termMon, *target) } } else { log.Infof("%s - initializing server transport listeners", execName) if *bindAddr == "" { fmt.Println("%s - STUN mode requires a bindaddr", execName) } else { fmt.Println("STUN udp server") launched = stun_udp.ServerSetup(termMon, *bindAddr, *target) fmt.Println("launched", launched, ptListeners) } } } else { // Do the managed pluggable transport protocol configuration. 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) } else { log.Infof("%s - initializing server transport listeners", execName) launched, ptListeners = pt_socks5.ServerSetup(termMon) } } } if !launched { // Initialization failed, the client or server setup routines should // have logged, so just exit here. os.Exit(-1) } fmt.Println("launched") log.Infof("%s - accepting connections", execName) defer func() { log.Noticef("%s - terminated", execName) }() // At this point, the pt config protocol is finished, and incoming // connections will be processed. Wait till the parent dies // (immediate exit), a SIGTERM is received (immediate exit), // or a SIGINT is received. if sig := termMon.Wait(false); sig == syscall.SIGTERM { return } // Ok, it was the first SIGINT, close all listeners, and wait till, // the parent dies, all the current connections are closed, or either // a SIGINT/SIGTERM is received, and exit. for _, ln := range ptListeners { ln.Close() } termMon.Wait(true) fmt.Println("waiting") for { // FIXME - block because termMon.Wait is not blocking } }
func serverHandler(termMon *termmon.TermMonitor, f base.ServerFactory, conn net.Conn, target string) { var header *common.Message defer conn.Close() termMon.OnHandlerStart() defer termMon.OnHandlerFinish() name := f.Transport().Name() addrStr := log.ElideAddr(conn.RemoteAddr().String()) fmt.Println("### handling", name) log.Infof("%s(%s) - new connection", name, addrStr) // Instantiate the server transport method and handshake. remote, err := f.WrapConn(conn) if err != nil { fmt.Println("handshake failed", err) log.Warnf("%s(%s) - handshake failed: %s", name, addrStr, log.ElideError(err)) return } serverAddr, err := net.ResolveUDPAddr("udp", target) if err != nil { golog.Fatal(err) } localAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:0") if err != nil { golog.Fatal(err) } dest, err := net.DialUDP("udp", localAddr, serverAddr) if err != nil { golog.Fatal(err) } fmt.Println("pumping") defer dest.Close() headerBuffer := make([]byte, 20) for { fmt.Println("reading...") // Read the incoming connection into the buffer. _, err := io.ReadFull(remote, headerBuffer) if err != nil { fmt.Println("read error") break } header, err = goturn.ParseStun(headerBuffer) if err != nil { fmt.Println("parse error") break } fmt.Println(header.Length) fmt.Println("reading data") readBuffer := make([]byte, header.Length) _, err = io.ReadFull(remote, readBuffer) if err != nil { fmt.Println("read error") break } writeBuffer := append(headerBuffer, readBuffer...) dest.Write(writeBuffer) } }