From 3396743d73adf6fb6ba65b5a730b6cd33775563c Mon Sep 17 00:00:00 2001 From: Zack Date: Mon, 5 Oct 2020 08:30:45 -0700 Subject: [PATCH] allow proxying connection (#283) --- go.mod | 2 +- src/cli/cli.go | 10 +++++++--- src/comm/comm.go | 17 ++++++++++++++++- src/utils/utils.go | 40 ++++++++++++++++++++++++++++++++++++++++ src/utils/utils_test.go | 4 ++++ 5 files changed, 68 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index d15c5e18..8d586163 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/stretchr/testify v1.4.0 github.com/tscholl2/siec v0.0.0-20191122224205-8da93652b094 golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a - golang.org/x/net v0.0.0-20200904194848-62affa334b73 // indirect + golang.org/x/net v0.0.0-20200904194848-62affa334b73 golang.org/x/sys v0.0.0-20200916084744-dbad9cb7cb7a // indirect golang.org/x/text v0.3.3 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect diff --git a/src/cli/cli.go b/src/cli/cli.go index 85e55332..d02a085e 100644 --- a/src/cli/cli.go +++ b/src/cli/cli.go @@ -14,6 +14,7 @@ import ( "time" "github.com/schollz/cli/v2" + "github.com/schollz/croc/v8/src/comm" "github.com/schollz/croc/v8/src/croc" "github.com/schollz/croc/v8/src/models" "github.com/schollz/croc/v8/src/tcp" @@ -84,6 +85,7 @@ func Run() (err error) { &cli.StringFlag{Name: "relay6", Value: models.DEFAULT_RELAY6, Usage: "ipv6 address of the relay", EnvVars: []string{"CROC_RELAY6"}}, &cli.StringFlag{Name: "out", Value: ".", Usage: "specify an output folder to receive the file"}, &cli.StringFlag{Name: "pass", Value: "pass123", Usage: "password for the relay", EnvVars: []string{"CROC_PASS"}}, + &cli.StringFlag{Name: "socks5", Value: "", Usage: "add a socks5 proxy", EnvVars: []string{"http_proxy"}}, } app.EnableBashCompletion = true app.HideHelp = false @@ -92,10 +94,10 @@ func Run() (err error) { allStringsAreFiles := func(strs []string) bool { for _, str := range strs { if !utils.Exists(str) { - return false; + return false } } - return true; + return true } // if trying to send but forgot send, let the user know @@ -103,7 +105,7 @@ func Run() (err error) { fnames := []string{} for _, fpath := range c.Args().Slice() { _, basename := filepath.Split(fpath) - fnames = append(fnames, "'" + basename + "'") + fnames = append(fnames, "'"+basename+"'") } yn := utils.GetInput(fmt.Sprintf("Did you mean to send %s? (y/n) ", strings.Join(fnames, ", "))) if strings.ToLower(yn) == "y" { @@ -159,6 +161,7 @@ func determinePass(c *cli.Context) (pass string) { func send(c *cli.Context) (err error) { setDebugLevel(c) + comm.Socks5Proxy = c.String("socks5") crocOptions := croc.Options{ SharedSecret: c.String("code"), IsSender: true, @@ -356,6 +359,7 @@ func saveConfig(c *cli.Context, crocOptions croc.Options) { } func receive(c *cli.Context) (err error) { + comm.Socks5Proxy = c.String("socks5") crocOptions := croc.Options{ SharedSecret: c.String("code"), IsSender: false, diff --git a/src/comm/comm.go b/src/comm/comm.go index d2c1b9c2..7afa12d8 100644 --- a/src/comm/comm.go +++ b/src/comm/comm.go @@ -8,9 +8,13 @@ import ( "net" "time" + "github.com/schollz/croc/v8/src/utils" log "github.com/schollz/logger" + "golang.org/x/net/proxy" ) +var Socks5Proxy = "" + const MAXBYTES = 4000000 // Comm is some basic TCP communication @@ -24,7 +28,18 @@ func NewConnection(address string, timelimit ...time.Duration) (c *Comm, err err if len(timelimit) > 0 { tlimit = timelimit[0] } - connection, err := net.DialTimeout("tcp", address, tlimit) + var connection net.Conn + if Socks5Proxy != "" && !utils.IsLocalIP(address) { + var dialer proxy.Dialer + dialer, err = proxy.SOCKS5("tcp", Socks5Proxy, nil, proxy.Direct) + if err != nil { + err = fmt.Errorf("proxy failed: %w", err) + return + } + connection, err = dialer.Dial("tcp", address) + } else { + connection, err = net.DialTimeout("tcp", address, tlimit) + } if err != nil { err = fmt.Errorf("comm.NewConnection failed: %w", err) return diff --git a/src/utils/utils.go b/src/utils/utils.go index 8a0224bd..9e4bc49d 100644 --- a/src/utils/utils.go +++ b/src/utils/utils.go @@ -261,3 +261,43 @@ func FindOpenPorts(host string, portNumStart, numPorts int) (openPorts []int) { } return } + +// local ip determination +// https://stackoverflow.com/questions/41240761/check-if-ip-address-is-in-private-network-space +var privateIPBlocks []*net.IPNet + +func init() { + for _, cidr := range []string{ + "127.0.0.0/8", // IPv4 loopback + "10.0.0.0/8", // RFC1918 + "172.16.0.0/12", // RFC1918 + "192.168.0.0/16", // RFC1918 + "169.254.0.0/16", // RFC3927 link-local + "::1/128", // IPv6 loopback + "fe80::/10", // IPv6 link-local + "fc00::/7", // IPv6 unique local addr + } { + _, block, err := net.ParseCIDR(cidr) + if err != nil { + panic(fmt.Errorf("parse error on %q: %v", cidr, err)) + } + privateIPBlocks = append(privateIPBlocks, block) + } +} + +func IsLocalIP(ipaddress string) bool { + if strings.Contains(ipaddress, "localhost") { + return true + } + host, _, _ := net.SplitHostPort(ipaddress) + ip := net.ParseIP(host) + if ip.IsLoopback() || ip.IsLinkLocalUnicast() || ip.IsLinkLocalMulticast() { + return true + } + for _, block := range privateIPBlocks { + if block.Contains(ip) { + return true + } + } + return false +} diff --git a/src/utils/utils_test.go b/src/utils/utils_test.go index cd7bd8cc..101162e5 100644 --- a/src/utils/utils_test.go +++ b/src/utils/utils_test.go @@ -191,3 +191,7 @@ func TestFindOpenPorts(t *testing.T) { openPorts := FindOpenPorts("localhost", 9009, 4) assert.Equal(t, []int{9009, 9010, 9011, 9012}, openPorts) } + +func TestIsLocalIP(t *testing.T) { + assert.True(t, IsLocalIP("192.168.0.14:9009")) +}