From 1b1dc5cdfea11e303d18d5e57ed9fcdabb89362e Mon Sep 17 00:00:00 2001 From: N0mansky Date: Wed, 12 Apr 2023 18:04:15 +0800 Subject: [PATCH] Feat: support http proxy as a complementary way to use in network limited environments. --- go.mod | 1 + go.sum | 2 ++ src/cli/cli.go | 3 +++ src/comm/comm.go | 23 +++++++++++++++++++++++ 4 files changed, 29 insertions(+) diff --git a/go.mod b/go.mod index 76bdd45..33c8784 100644 --- a/go.mod +++ b/go.mod @@ -23,6 +23,7 @@ require ( github.com/OneOfOne/xxhash v1.2.8 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/magisterquis/connectproxy v0.0.0-20200725203833-3582e84f0c9b github.com/mattn/go-runewidth v0.0.14 // indirect github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/pmezard/go-difflib v1.0.0 // indirect diff --git a/go.sum b/go.sum index a7cbd28..04ee198 100644 --- a/go.sum +++ b/go.sum @@ -26,6 +26,8 @@ github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/magisterquis/connectproxy v0.0.0-20200725203833-3582e84f0c9b h1:xZ59n7Frzh8CwyfAapUZLSg+gXH5m63YEaFCMpDHhpI= +github.com/magisterquis/connectproxy v0.0.0-20200725203833-3582e84f0c9b/go.mod h1:uDd4sYVYsqcxAB8j+Q7uhL6IJCs/r1kxib1HV4bgOMg= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= diff --git a/src/cli/cli.go b/src/cli/cli.go index 529b127..1e613a9 100644 --- a/src/cli/cli.go +++ b/src/cli/cli.go @@ -106,6 +106,7 @@ func Run() (err error) { &cli.StringFlag{Name: "out", Value: ".", Usage: "specify an output folder to receive the file"}, &cli.StringFlag{Name: "pass", Value: models.DEFAULT_PASSPHRASE, Usage: "password for the relay", EnvVars: []string{"CROC_PASS"}}, &cli.StringFlag{Name: "socks5", Value: "", Usage: "add a socks5 proxy", EnvVars: []string{"SOCKS5_PROXY"}}, + &cli.StringFlag{Name: "connect", Value: "", Usage: "add a http proxy", EnvVars: []string{"HTTP_PROXY"}}, &cli.StringFlag{Name: "throttleUpload", Value: "", Usage: "Throttle the upload speed e.g. 500k"}, } app.EnableBashCompletion = true @@ -170,6 +171,7 @@ func determinePass(c *cli.Context) (pass string) { func send(c *cli.Context) (err error) { setDebugLevel(c) comm.Socks5Proxy = c.String("socks5") + comm.HttpProxy = c.String("connect") portsString := c.String("ports") if portsString == "" { portsString = "9009,9010,9011,9012,9013" @@ -388,6 +390,7 @@ func (t TabComplete) Do(line []rune, pos int) ([][]rune, int) { func receive(c *cli.Context) (err error) { comm.Socks5Proxy = c.String("socks5") + comm.HttpProxy = c.String("connect") crocOptions := croc.Options{ SharedSecret: c.String("code"), IsSender: false, diff --git a/src/comm/comm.go b/src/comm/comm.go index 7df8e6d..35968b7 100644 --- a/src/comm/comm.go +++ b/src/comm/comm.go @@ -10,12 +10,14 @@ import ( "strings" "time" + "github.com/magisterquis/connectproxy" "github.com/schollz/croc/v9/src/utils" log "github.com/schollz/logger" "golang.org/x/net/proxy" ) var Socks5Proxy = "" +var HttpProxy = "" var MAGIC_BYTES = []byte("croc") @@ -51,6 +53,27 @@ func NewConnection(address string, timelimit ...time.Duration) (c *Comm, err err } log.Debug("dialing with dialer.Dial") connection, err = dialer.Dial("tcp", address) + } else if HttpProxy != "" && !utils.IsLocalIP(address) { + var dialer proxy.Dialer + // prepend schema if no schema is given + if !strings.Contains(HttpProxy, `://`) { + HttpProxy = `http://` + HttpProxy + } + HttpProxyURL, urlParseError := url.Parse(HttpProxy) + if urlParseError != nil { + err = fmt.Errorf("unable to parse socks proxy url: %s", urlParseError) + log.Debug(err) + return + } + dialer, err = connectproxy.New(HttpProxyURL, proxy.Direct) + if err != nil { + err = fmt.Errorf("proxy failed: %w", err) + log.Debug(err) + return + } + log.Debug("dialing with dialer.Dial") + connection, err = dialer.Dial("tcp", address) + } else { log.Debugf("dialing to %s with timelimit %s", address, tlimit) connection, err = net.DialTimeout("tcp", address, tlimit)