From b54edc9e0d3bf40b57473746ef721e71ac0e079a Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Sat, 26 Feb 2022 19:54:30 +0100 Subject: tunnel: add experimental SOCKS client --- tunnel/tools/libwg-go/http-proxy.go | 56 ++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/tunnel/tools/libwg-go/http-proxy.go b/tunnel/tools/libwg-go/http-proxy.go index c73e1edf..a44aaac6 100644 --- a/tunnel/tools/libwg-go/http-proxy.go +++ b/tunnel/tools/libwg-go/http-proxy.go @@ -14,6 +14,8 @@ import ( "golang.zx2c4.com/wireguard/device" + net_proxy "golang.org/x/net/proxy" + "gopkg.in/olebedev/go-duktape.v3" ) @@ -295,10 +297,17 @@ func (l *Logger) Printf(format string, v ...interface{}) { l.logger.Verbosef(format, v...) } -func (p *HttpProxy) newGoProxy(proxyUrl string) *goproxy.ProxyHttpServer { +func (p *HttpProxy) newGoProxy(cat, proxyUrl string) (*goproxy.ProxyHttpServer, error) { proxy := goproxy.NewProxyHttpServer() proxy.Logger = &Logger{logger: p.logger} proxy.Verbose = true + if cat == "SOCKS5" { + socksDialer, err := net_proxy.SOCKS5("tcp", proxyUrl, nil, nil) + if err != nil { + return nil, err + } + proxy.Tr.Dial = socksDialer.Dial + } proxy.NonproxyHandler = http.HandlerFunc(func (w http.ResponseWriter, req *http.Request) { if req.Host == "" { fmt.Fprintln(w, "Cannot handle requests without Host header, e.g., HTTP 1.0") @@ -309,14 +318,14 @@ func (p *HttpProxy) newGoProxy(proxyUrl string) *goproxy.ProxyHttpServer { proxy.ServeHTTP(w, req) }) - if proxyUrl != "" { + if cat == "PROXY" { proxy.Tr.Proxy = func(req *http.Request) (*url.URL, error) { return url.Parse(proxyUrl) } proxy.ConnectDial = proxy.NewConnectDialToProxy(proxyUrl) } - return proxy + return proxy, nil } func FindProxyForURL(ctx *duktape.Context, url, host string, logger *device.Logger) (res string, err error) { @@ -452,7 +461,10 @@ func (p *HttpProxy) Start() (listen_port uint16, err error) { proxyMap := make(map[string]*goproxy.ProxyHttpServer) - p.defaultProxy = p.newGoProxy("") + p.defaultProxy, err = p.newGoProxy("", "") + if err != nil { + return + } proxyMap[""] = p.defaultProxy listen_port, handler, err := p.startRegularProxy(proxyMap) @@ -508,7 +520,7 @@ type HttpHandler struct { remoteAddrPkgMap map[string]*goproxy.ProxyHttpServer uidRequest chan UidRequest ctx *duktape.Context - proxyMap map[string]*goproxy.ProxyHttpServer + proxyMap map[string]*goproxy.ProxyHttpServer // FIXME include type in map key } func NewHttpHandler(p *HttpProxy, defaultProxy *goproxy.ProxyHttpServer, proxyMap map[string]*goproxy.ProxyHttpServer, logger *device.Logger) *HttpHandler{ @@ -555,7 +567,10 @@ func (h *HttpHandler) addConnToProxyMap(c net.Conn) error { proxy, ok := h.proxyMap[pkg] if !ok { - proxy = h.findProxyForPkg(pkg) + proxy, err = h.findProxyForPkg(pkg) + if err != nil { + return err + } } if proxy != nil { @@ -589,9 +604,9 @@ func (h *HttpHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { } } -func (h *HttpHandler) findProxyForPkg(pkg string) *goproxy.ProxyHttpServer { +func (h *HttpHandler) findProxyForPkg(pkg string) (*goproxy.ProxyHttpServer, error) { if h.ctx == nil { - return nil + return nil, fmt.Errorf("Null context") } find := func() (cat string, res string, err error) { @@ -601,34 +616,43 @@ func (h *HttpHandler) findProxyForPkg(pkg string) *goproxy.ProxyHttpServer { if err != nil { h.logger.Verbosef("FindProxyForPkg result is: %v stack:%v", res, h.ctx.GetTop()) return "", "", err + } else if res == "" { + return "DIRECT", "", nil } else { values := strings.Split(strings.Trim(res, " "), ";") for _, v := range values { value := strings.Trim(v, " ") parts := strings.SplitN(value, " ", 2) - if parts[0] == "PROXY" { - return parts[0], parts[1], nil + if parts[0] == "PROXY" || parts[0] == "HTTP" { + return "PROXY", "http://" + parts[1], nil + } else if parts[0] == "HTTPS" { + return "PROXY", "https://" + parts[1], nil } else if parts[0] == "DIRECT" { return parts[0], "", nil + } else if parts[0] == "SOCKS" || parts[0] == "SOCKS5" { + return "SOCKS5", parts[1], nil } } - } + } return "", "", fmt.Errorf("No result") } cat, res, err := find() if err != nil { - return nil + return nil, err } var proxy *goproxy.ProxyHttpServer - if cat == "PROXY" { - proxy = h.p.newGoProxy("http://" + res) - } else { + if cat == "DIRECT" { proxy = h.defaultProxy + } else { + proxy, err = h.p.newGoProxy(cat, res) + if err != nil { + return nil, err + } } h.proxyMap[pkg] = proxy - return proxy + return proxy, nil } type AddrPortPair struct { -- cgit v1.2.3