summaryrefslogtreecommitdiff
path: root/obfsproxy/main.go
diff options
context:
space:
mode:
authoratanarjuat <atanarjuat@example.com>2022-05-21 01:50:47 +0200
committeratanarjuat <atanarjuat@example.com>2022-05-21 05:04:09 +0200
commit182e3e76908f0824eac155b5e14775b50fe0aca5 (patch)
treee0d20e237ff6159b8967a3fd4592134a35bbcf77 /obfsproxy/main.go
parenta809112a20b31b9a4adca31ae564d943a41e9023 (diff)
simplify testing of client and server
Diffstat (limited to 'obfsproxy/main.go')
-rw-r--r--obfsproxy/main.go238
1 files changed, 0 insertions, 238 deletions
diff --git a/obfsproxy/main.go b/obfsproxy/main.go
deleted file mode 100644
index 5e56789..0000000
--- a/obfsproxy/main.go
+++ /dev/null
@@ -1,238 +0,0 @@
-// The obfsproxy command creates a SOCKS5 obfuscating proxy.
-package main
-
-import (
- "context"
- "encoding/json"
- "errors"
- "flag"
- "fmt"
- "io"
- "log"
- "net"
- "os"
- "os/signal"
-
- "0xacab.org/leap/obfsvpn"
- "git.torproject.org/pluggable-transports/goptlib.git"
-)
-
-const transportName = "obfs4"
-
-type Config struct {
- NodeID string `json:"node-id"`
- PrivateKey string `json:"private-key"`
- PublicKey string `json:"public-key"`
- DRBGSeed string `json:"drbg-seed"`
- IatMode int `json:"iat-mode"`
-}
-
-func main() {
- // Setup logging.
- logger := log.New(os.Stderr, "", log.LstdFlags)
- debug := log.New(io.Discard, "DEBUG ", log.LstdFlags)
-
- // Setup command line flags.
- var (
- verbose bool
- addr string = "[::1]:0"
- vpnAddr string
- cfgFile string
- stateDir string
- )
- flags := flag.NewFlagSet(os.Args[0], flag.ContinueOnError)
- flags.BoolVar(&verbose, "v", verbose, "Enable verbose logging")
- flags.StringVar(&addr, "addr", addr, "The address to listen on for client connections")
- flags.StringVar(&vpnAddr, "vpn", vpnAddr, "The address of the OpenVPN server to connect to")
- flags.StringVar(&cfgFile, "c", cfgFile, "The JSON config file to load")
- flags.StringVar(&stateDir, "state", stateDir, "A directory in which to store bridge state")
- err := flags.Parse(os.Args[1:])
- if err != nil {
- logger.Fatalf("error parsing flags: %v", err)
- }
-
- if vpnAddr == "" {
- flags.PrintDefaults()
- logger.Fatal("must specify -vpn")
- }
-
- tcpVPNAddr, err := net.ResolveTCPAddr("tcp", vpnAddr)
- log.Println("target:", tcpVPNAddr)
- if err != nil {
- logger.Fatalf("error resolving VPN address: %v", err)
- }
-
- var cfg Config
- fd, err := os.Open(cfgFile)
- log.Println("opening:", cfgFile)
- if err != nil {
- logger.Fatalf("error opening config file: %v", err)
- }
- err = json.NewDecoder(fd).Decode(&cfg)
- if err != nil {
- logger.Fatalf("error decoding config: %v", err)
- }
-
- // Configure logging.
- if verbose {
- debug.SetOutput(os.Stderr)
- }
-
- log.Println("config:", cfg)
-
- // Setup graceful shutdown.
- ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
-
- listenConfig, err := obfsvpn.NewListenConfig(cfg.NodeID, cfg.PrivateKey, cfg.PublicKey, cfg.DRBGSeed, stateDir)
- if err != nil {
- logger.Fatalf("error creating listener from config: %v", err)
- }
- log.Println("DEBUG:", listenConfig)
- ln, err := listenConfig.Listen(ctx, "tcp", addr)
- if err != nil {
- logger.Fatalf("error binding to %s: %v", addr, err)
- }
-
- go func() {
- <-ctx.Done()
- // Stop releases the signal handling and falls back to the default behavior,
- // so sending another interrupt will immediately terminate.
- stop()
- logger.Printf("shutting down…")
- err := ln.Close()
- if err != nil {
- logger.Printf("error closing listener: %v", err)
- }
- }()
-
- info := &pt.ServerInfo{
- OrAddr: tcpVPNAddr,
- }
-
- logger.Printf("listening on %s…", ln.Addr())
- for {
- conn, err := ln.Accept()
- if err != nil {
- debug.Printf("error accepting connection: %v", err)
- return
- }
- debug.Printf("accepted connection %v…", conn)
- go proxyConn(ctx, info, conn, logger, debug)
- }
-}
-
-// obfsConn is a connection to the obfs4 client that we have accepted. we will dial to the remote contained in info
-func proxyConn(ctx context.Context, info *pt.ServerInfo, obfsConn net.Conn, logger, debug *log.Logger) {
- defer func() {
- err := obfsConn.Close()
- if err != nil {
- debug.Printf("error closing connection: %v", err)
- }
- }()
-
- // FIXME scrub ips in other than debug mode!
- log.Println("Dialing:", info.OrAddr)
- log.Println("Obfs4 client:", obfsConn.RemoteAddr().String())
-
- /*
- in the case of Tor, pt.DialOr returns a *net.TCPConn after dialing info.OrAddr.
- in the vpn case (or any transparent proxy really), we do use
- the pt.DialOr method to simply get a dialer to our upstream VPN remote.
-
- keeping this terminology is a bit stupid and slightly confusing, instead
- we could get the clearConn just by doing:
-
- s, err := net.DialTCP("tcp", nil, info.ExtendedOrAddr)
- if err != nil {
- return nil, err
- }
-
- that is precisely what the code in ptlib is doing.
-
- We also aspire at being a generic PT at some point, so perhaps it's better to keep the usage
- of DialOr?
-
- Maybe not, and so we don't need to keep the confusing info struct.
- */
-
- // we'll refer to the connection to the usptream node as "clearConn", as opposed to the obfuscated conn.
- // but for sure openvpn or whatever protocol you wrap has its own layer of encryption :)
-
- clearConn, err := pt.DialOr(info, obfsConn.RemoteAddr().String(), transportName)
-
- if err != nil {
- logger.Printf("error dialing remote: %v", err)
- return
- }
-
- if err = CopyLoop(clearConn, obfsConn); err != nil {
- debug.Printf("%s - closed connection: %s", "obfsvpn", err.Error())
- } else {
- debug.Printf("%s - closed connection", "obfsvpn")
- }
-}
-
-// a stock copy loop. let's not dwell too much on who's client and who's server
-
-func CopyLoop(left net.Conn, right net.Conn) error {
-
- fmt.Println("--> Entering copy loop.")
-
- if left == nil {
- fmt.Fprintln(os.Stderr, "--> Copy loop has a nil connection (left).")
- return errors.New("copy loop has a nil connection (left)")
- }
-
- if right == nil {
- fmt.Fprintln(os.Stderr, "--> Copy loop has a nil connection (right).")
- return errors.New("copy loop has a nil connection (right)")
- }
-
- // Note: right is always the pt connection.
- lockL := make(chan bool)
- lockR := make(chan bool)
- errChan := make(chan error)
-
- go CopyLeftToRight(left, right, lockL, errChan)
- go CopyRightToLeft(left, right, lockR, errChan)
-
- leftUp := true
- rightUp := true
-
- var copyErr error
-
- for leftUp || rightUp {
- select {
- case <-lockL:
- leftUp = false
- case <-lockR:
- rightUp = false
- case copyErr = <-errChan:
- log.Println("Error while copying")
- }
- }
-
- // XXX better to defer?
- left.Close()
- right.Close()
-
- return copyErr
-}
-
-// TODO check for data races
-
-func CopyLeftToRight(l net.Conn, r net.Conn, ll chan bool, errChan chan error) {
- _, e := io.Copy(r, l)
- ll <- true
- if e != nil {
- errChan <- e
- }
-}
-
-func CopyRightToLeft(l net.Conn, r net.Conn, lr chan bool, errChan chan error) {
- _, e := io.Copy(l, r)
- lr <- true
- if e != nil {
- errChan <- e
- }
-}