예제 #1
0
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
}
예제 #2
0
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
}
예제 #3
0
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
}
예제 #4
0
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
}
예제 #5
0
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
}
예제 #6
0
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
}
예제 #7
0
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
}
예제 #8
0
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
}
예제 #9
0
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
}
예제 #10
0
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)
	}
}
예제 #11
0
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
	}
}
예제 #12
0
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)
	}
}