From b477ff6ea43d8fd085d9183f64de9c618aeae62d Mon Sep 17 00:00:00 2001 From: Fred Cox Date: Wed, 24 Mar 2021 13:20:25 +0200 Subject: [PATCH] Adds a error handler to ConnectAction This allows the users to client handle connect errors related to certificates, useful, as in the example, when some clients are using certificate pinning to allow them to connect without mitm --- examples/goproxy-mitmerror/main.go | 37 ++++++++++++++++++++++++++++++ https.go | 4 ++++ 2 files changed, 41 insertions(+) create mode 100644 examples/goproxy-mitmerror/main.go diff --git a/examples/goproxy-mitmerror/main.go b/examples/goproxy-mitmerror/main.go new file mode 100644 index 00000000..5eac6d91 --- /dev/null +++ b/examples/goproxy-mitmerror/main.go @@ -0,0 +1,37 @@ +package main + +import ( + "flag" + "log" + "net/http" + "sync" + + "github.com/elazarl/goproxy" +) + +func main() { + verbose := flag.Bool("v", false, "should every proxy request be logged to stdout") + addr := flag.String("addr", ":8080", "proxy listen address") + flag.Parse() + proxy := goproxy.NewProxyHttpServer() + var mitmErrorHosts []string + var mitmErrorHostsLock sync.Mutex + proxy.OnRequest().HandleConnectFunc(func(host string, ctx *goproxy.ProxyCtx) (*goproxy.ConnectAction, string) { + mitmErrorHostsLock.Lock() + defer mitmErrorHostsLock.Unlock() + for _, errorHost := range mitmErrorHosts { + if errorHost == host { + return goproxy.OkConnect, host + } + } + + return &goproxy.ConnectAction{Action: goproxy.ConnectMitm, TLSConfig: goproxy.MitmConnect.TLSConfig, MitmError: func(req *http.Request, ctx *goproxy.ProxyCtx, err error) { + log.Printf("Adding host to mitm error: %s", host) + mitmErrorHostsLock.Lock() + defer mitmErrorHostsLock.Unlock() + mitmErrorHosts = append(mitmErrorHosts, host) + }}, host + }) + proxy.Verbose = *verbose + log.Fatal(http.ListenAndServe(*addr, proxy)) +} diff --git a/https.go b/https.go index 6fcf17a9..de165ada 100644 --- a/https.go +++ b/https.go @@ -44,6 +44,7 @@ type ConnectAction struct { Action ConnectActionLiteral Hijack func(req *http.Request, client net.Conn, ctx *ProxyCtx) TLSConfig func(host string, ctx *ProxyCtx) (*tls.Config, error) + MitmError func(req *http.Request, ctx *ProxyCtx, err error) } func stripPort(s string) string { @@ -192,6 +193,9 @@ func (proxy *ProxyHttpServer) handleHttps(w http.ResponseWriter, r *http.Request rawClientTls := tls.Server(proxyClient, tlsConfig) if err := rawClientTls.Handshake(); err != nil { ctx.Warnf("Cannot handshake client %v %v", r.Host, err) + if todo.MitmError != nil { + todo.MitmError(r, ctx, err) + } return } defer rawClientTls.Close()