add authBasicRealm metadata for HTTP/HTTP2 handler

This commit is contained in:
ginuerzh 2023-01-31 13:42:55 +08:00
parent 1c6bc9283e
commit 3e35a7b761
4 changed files with 34 additions and 10 deletions

View File

@ -6,6 +6,7 @@ import (
"encoding/base64" "encoding/base64"
"encoding/binary" "encoding/binary"
"errors" "errors"
"fmt"
"hash/crc32" "hash/crc32"
"net" "net"
"net/http" "net/http"
@ -321,19 +322,23 @@ func (h *httpHandler) authenticate(conn net.Conn, req *http.Request, resp *http.
resp.Header = http.Header{} resp.Header = http.Header{}
} }
if resp.StatusCode == 0 { if resp.StatusCode == 0 {
realm := defaultRealm
if h.md.authBasicRealm != "" {
realm = h.md.authBasicRealm
}
resp.StatusCode = http.StatusProxyAuthRequired resp.StatusCode = http.StatusProxyAuthRequired
resp.Header.Add("Proxy-Authenticate", "Basic realm=\"gost\"") resp.Header.Add("Proxy-Authenticate", fmt.Sprintf("Basic realm=\"%s\"", realm))
if strings.ToLower(req.Header.Get("Proxy-Connection")) == "keep-alive" { if strings.ToLower(req.Header.Get("Proxy-Connection")) == "keep-alive" {
// XXX libcurl will keep sending auth request in same conn // XXX libcurl will keep sending auth request in same conn
// which we don't supported yet. // which we don't supported yet.
resp.Header.Add("Connection", "close") resp.Header.Set("Connection", "close")
resp.Header.Add("Proxy-Connection", "close") resp.Header.Set("Proxy-Connection", "close")
} }
log.Debug("proxy authentication required") log.Debug("proxy authentication required")
} else { } else {
resp.Header.Set("Server", "nginx/1.20.1") // resp.Header.Set("Server", "nginx/1.20.1")
resp.Header.Set("Date", time.Now().Format(http.TimeFormat)) // resp.Header.Set("Date", time.Now().Format(http.TimeFormat))
if resp.StatusCode == http.StatusOK { if resp.StatusCode == http.StatusOK {
resp.Header.Set("Connection", "keep-alive") resp.Header.Set("Connection", "keep-alive")
} }

View File

@ -8,11 +8,16 @@ import (
mdutil "github.com/go-gost/core/metadata/util" mdutil "github.com/go-gost/core/metadata/util"
) )
const (
defaultRealm = "gost"
)
type metadata struct { type metadata struct {
probeResistance *probeResistance probeResistance *probeResistance
enableUDP bool enableUDP bool
header http.Header header http.Header
hash string hash string
authBasicRealm string
} }
func (h *httpHandler) parseMetadata(md mdata.Metadata) error { func (h *httpHandler) parseMetadata(md mdata.Metadata) error {
@ -23,6 +28,7 @@ func (h *httpHandler) parseMetadata(md mdata.Metadata) error {
knock = "knock" knock = "knock"
enableUDP = "udp" enableUDP = "udp"
hash = "hash" hash = "hash"
authBasicRealm = "authBasicRealm"
) )
if m := mdutil.GetStringMapString(md, header); len(m) > 0 { if m := mdutil.GetStringMapString(md, header); len(m) > 0 {
@ -48,6 +54,7 @@ func (h *httpHandler) parseMetadata(md mdata.Metadata) error {
} }
h.md.enableUDP = mdutil.GetBool(md, enableUDP) h.md.enableUDP = mdutil.GetBool(md, enableUDP)
h.md.hash = mdutil.GetString(md, hash) h.md.hash = mdutil.GetString(md, hash)
h.md.authBasicRealm = mdutil.GetString(md, authBasicRealm)
return nil return nil
} }

View File

@ -7,6 +7,7 @@ import (
"encoding/base64" "encoding/base64"
"encoding/binary" "encoding/binary"
"errors" "errors"
"fmt"
"hash/crc32" "hash/crc32"
"io" "io"
"io/ioutil" "io/ioutil"
@ -304,20 +305,24 @@ func (h *http2Handler) authenticate(w http.ResponseWriter, r *http.Request, resp
} }
if resp.StatusCode == 0 { if resp.StatusCode == 0 {
realm := defaultRealm
if h.md.authBasicRealm != "" {
realm = h.md.authBasicRealm
}
resp.StatusCode = http.StatusProxyAuthRequired resp.StatusCode = http.StatusProxyAuthRequired
resp.Header.Add("Proxy-Authenticate", "Basic realm=\"gost\"") resp.Header.Add("Proxy-Authenticate", fmt.Sprintf("Basic realm=\"%s\"", realm))
if strings.ToLower(r.Header.Get("Proxy-Connection")) == "keep-alive" { if strings.ToLower(r.Header.Get("Proxy-Connection")) == "keep-alive" {
// XXX libcurl will keep sending auth request in same conn // XXX libcurl will keep sending auth request in same conn
// which we don't supported yet. // which we don't supported yet.
resp.Header.Add("Connection", "close") resp.Header.Set("Connection", "close")
resp.Header.Add("Proxy-Connection", "close") resp.Header.Set("Proxy-Connection", "close")
} }
log.Debug("proxy authentication required") log.Debug("proxy authentication required")
} else { } else {
resp.Header = http.Header{} resp.Header = http.Header{}
resp.Header.Set("Server", "nginx/1.20.1") // resp.Header.Set("Server", "nginx/1.20.1")
resp.Header.Set("Date", time.Now().Format(http.TimeFormat)) // resp.Header.Set("Date", time.Now().Format(http.TimeFormat))
if resp.StatusCode == http.StatusOK { if resp.StatusCode == http.StatusOK {
resp.Header.Set("Connection", "keep-alive") resp.Header.Set("Connection", "keep-alive")
} }

View File

@ -8,10 +8,15 @@ import (
mdutil "github.com/go-gost/core/metadata/util" mdutil "github.com/go-gost/core/metadata/util"
) )
const (
defaultRealm = "gost"
)
type metadata struct { type metadata struct {
probeResistance *probeResistance probeResistance *probeResistance
header http.Header header http.Header
hash string hash string
authBasicRealm string
} }
func (h *http2Handler) parseMetadata(md mdata.Metadata) error { func (h *http2Handler) parseMetadata(md mdata.Metadata) error {
@ -21,6 +26,7 @@ func (h *http2Handler) parseMetadata(md mdata.Metadata) error {
probeResistKeyX = "probe_resist" probeResistKeyX = "probe_resist"
knock = "knock" knock = "knock"
hash = "hash" hash = "hash"
authBasicRealm = "authBasicRealm"
) )
if m := mdutil.GetStringMapString(md, header); len(m) > 0 { if m := mdutil.GetStringMapString(md, header); len(m) > 0 {
@ -45,6 +51,7 @@ func (h *http2Handler) parseMetadata(md mdata.Metadata) error {
} }
} }
h.md.hash = mdutil.GetString(md, hash) h.md.hash = mdutil.GetString(md, hash)
h.md.authBasicRealm = mdutil.GetString(md, authBasicRealm)
return nil return nil
} }