This commit is contained in:
Jeff Becker 2019-01-19 08:30:28 -05:00
parent 7c6dca6e40
commit 606002b7ff
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05
1 changed files with 86 additions and 29 deletions

67
main.go
View File

@ -1,16 +1,62 @@
package main package main
import ( import (
"socks5" "crypto/tls"
"fmt"
"golang.org/x/net/context" "golang.org/x/net/context"
"golang.org/x/net/proxy" "golang.org/x/net/proxy"
"net" "net"
"net/http"
"os" "os"
"fmt" "socks5"
"strings" "strings"
) )
type httpProxyHandler struct {
upstream proxy.Dialer
}
func transfer(dst io.WriteCloser, src io.ReadCloser) {
defer dst.Close()
defer src.Close()
io.Copy(dst, src)
}
func (h *httpProxyHandler) dialOut(addr string) (net.Conn, error) {
host, _, err := net.SplitHostPort(addr)
if err != nil {
return nil, err
}
if strings.HasSuffix(host, ".onion") {
return h.upstream.Dial("tcp", addr)
}
return net.Dial("tcp", addr)
}
func (h *httpProxyHandler) ServeHTTP(w http.ResposneWriter, r *http.Request) {
if r.Method == http.MethodConnect {
outConn, err := h.dialOut(r.Host)
if err != nil {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
hijacker, ok := w.(http.Hijacker)
if !ok {
http.Error(w, "hijack disallowed", http.StatusInternalServerError)
return
}
conn, _, err := hijacker.Hijack()
if err != nil {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
} else {
w.WriteHeader(http.StatusMethodNotAllowed)
}
}
func main() { func main() {
usehttp := os.Args[0] == "http-fedproxy"
args := os.Args[1:] args := os.Args[1:]
if len(args) < 2 { if len(args) < 2 {
@ -18,11 +64,21 @@ func main() {
return return
} }
upstream, err:= proxy.SOCKS5("tcp", os.Args[2], nil, nil) upstream, err := proxy.SOCKS5("tcp", os.Args[2], nil, nil)
if err != nil { if err != nil {
fmt.Printf("failed to create upstream proxy to %s, %s", os.Args[2], err.Error()) fmt.Printf("failed to create upstream proxy to %s, %s", os.Args[2], err.Error())
return return
} }
if usehttp {
serv := &http.Server{
Addr: os.Args[1],
Handler: &proxyHandler{
upstream: upstream,
},
TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler)),
}
http.ListenAndServe(proxyHandler, os.Args[1])
} else {
serv, err := socks5.New(&socks5.Config{ serv, err := socks5.New(&socks5.Config{
Dial: func(addr string) (net.Conn, error) { Dial: func(addr string) (net.Conn, error) {
host, _, err := net.SplitHostPort(addr) host, _, err := net.SplitHostPort(addr)
@ -41,11 +97,12 @@ func main() {
return return
} }
l, err := net.Listen("tcp", os.Args[1]) l, err := net.Listen("tcp", os.Args[1])
if err != nil { if err != nil {
fmt.Printf("failed to listen on %s, %s", os.Args[1], err.Error()) fmt.Printf("failed to listen on %s, %s", os.Args[1], err.Error())
return return
}
serv.Serve(l) serv.Serve(l)
}
}
} }