From 182e3e76908f0824eac155b5e14775b50fe0aca5 Mon Sep 17 00:00:00 2001 From: atanarjuat Date: Sat, 21 May 2022 01:50:47 +0200 Subject: simplify testing of client and server --- obfsproxy/Makefile | 18 ---- obfsproxy/leap-vpn.sh | 13 --- obfsproxy/main.go | 238 ------------------------------------------------- obfsproxy/main_test.go | 88 ------------------ 4 files changed, 357 deletions(-) delete mode 100644 obfsproxy/Makefile delete mode 100755 obfsproxy/leap-vpn.sh delete mode 100644 obfsproxy/main.go delete mode 100644 obfsproxy/main_test.go (limited to 'obfsproxy') diff --git a/obfsproxy/Makefile b/obfsproxy/Makefile deleted file mode 100644 index 8694349..0000000 --- a/obfsproxy/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -RHOST=163.172.126.44:443 -LHOST="10.0.0.209:443" - -run: - sudo ./obfsproxy -addr ${LHOST} -vpn ${RHOST} -state test_data -c test_data/obfs4.json - -certs: - curl -k https://black.riseup.net/ca.crt > /tmp/ca.crt - curl -k https://api.black.riseup.net/3/cert > /tmp/cert.pem - -check: - curl https://wtfismyip.com/json - -stop: - pkill -9 obfsproxy - -obfsproxy: - go build diff --git a/obfsproxy/leap-vpn.sh b/obfsproxy/leap-vpn.sh deleted file mode 100755 index 4fb09c3..0000000 --- a/obfsproxy/leap-vpn.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -sudo openvpn \ - --verb 3 \ - --tls-cipher DHE-RSA-AES128-SHA \ - --cipher AES-128-CBC \ - --dev tun --client --tls-client \ - --remote-cert-tls server --tls-version-min 1.2 \ - --ca /tmp/ca.crt --cert /tmp/cert.pem --key /tmp/cert.pem \ - --proto tcp4 \ - --remote localhost 4430 \ - --socks-proxy localhost 4430 \ - --route $GW 255.255.255.255 net_gateway \ - --persist-tun 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 - } -} diff --git a/obfsproxy/main_test.go b/obfsproxy/main_test.go deleted file mode 100644 index cdead61..0000000 --- a/obfsproxy/main_test.go +++ /dev/null @@ -1,88 +0,0 @@ -package main - -import ( - "flag" - "os" - "testing" -) - -type testWriter struct { - t *testing.T - prefix string -} - -func (w testWriter) Write(p []byte) (int, error) { - w.t.Logf("%s%s", w.prefix, p) - return len(p), nil -} - -func TestMain(m *testing.M) { - runProxy := flag.Bool("runproxy", false, "Start the command instead of running the tests") - flag.Parse() - if *runProxy { - os.Args = append(os.Args[0:1], flag.Args()...) - main() - return - } - os.Exit(m.Run()) -} - -/* -func TestRoundTrip(t *testing.T) { - // Setup and exec the proxy: - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - // Instead of passing a listener to the command or doing IPC to get the - // address of the listener created by the command back out, which would all - // require changes to the actual binary for something that has no use outside - // of tests and is just another potential source of errors, just start and - // stop a listener to get a random port and then pass that in (for the command - // to re-open) as a string. It's not ideal, but it's simple. - ln, err := net.Listen("tcp", "[::1]:0") - if err != nil { - t.Fatalf("error listening: %v", err) - } - addr := ln.Addr() - err = ln.Close() - if err != nil { - t.Fatalf("error closing listener: %v", err) - } - cmd := exec.CommandContext(ctx, os.Args[0], "-runproxy", "--", "-addr", addr.String(), "-proxy", "37.218.241.98:4430") - cmd.Stdout = testWriter{prefix: "stdout ", t: t} - cmd.Stderr = testWriter{prefix: "stderr ", t: t} - t.Logf("running proxy command %v", cmd.Args) - err = cmd.Start() - if err != nil { - t.Fatalf("error starting proxy: %v", err) - } - - // Once the proxy is running, try to connect: - ln, err = net.Listen("tcp", "[::1]:0") - if err != nil { - t.Fatalf("error listening for connection: %v", err) - } - go func() { - conn, err := ln.Accept() - if err != nil { - t.Logf("error accepting connection: %v", err) - } - t.Logf("got conn: %v", conn) - }() - dialer, err := proxy.SOCKS5("tcp", addr.String(), nil, proxy.Direct) - if err != nil { - t.Fatalf("error creating socks dialer: %v", err) - } - - // TODO: this is slow, flakey, and generally jank. Can we watch /proc for a - // new file descriptor or just poll until the listener is open? - t.Logf("waiting 3 seconds for command to start…") - time.Sleep(3 * time.Second) - - _, err = dialer.Dial("tcp", ln.Addr().String()) - if err != nil { - t.Fatalf("error dialing: %v", err) - } - - select {} -} -*/ -- cgit v1.2.3