Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/Alpha' into mitm-test
Browse files Browse the repository at this point in the history
  • Loading branch information
xishang0128 committed Aug 3, 2024
1 parent 0ea6485 commit 44a236e
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 18 deletions.
2 changes: 1 addition & 1 deletion adapter/inbound/mitm.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

// NewMitm receive mitm request and return MitmContext
func NewMitm(target socks5.Addr, srcConn net.Conn, userAgent string, Url string, conn net.Conn, additions ...Addition) (net.Conn, *C.Metadata) {
func NewMitm(target socks5.Addr, srcConn net.Conn, userAgent string, Url string, conn net.Conn, additions []Addition) (net.Conn, *C.Metadata) {
metadata := parseSocksAddr(target)
metadata.NetWork = C.TCP
metadata.Type = C.MITM
Expand Down
3 changes: 3 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,9 @@ func parseProxies(cfg *RawConfig) (proxies map[string]C.Proxy, providersMap map[
proxyList = append(proxyList, "DIRECT", "REJECT")

if cfg.MITM.Port != 0 {
if cfg.MitmPort == 0 {
cfg.MitmPort = cfg.MITM.Port
}
proxies["MITM"] = adapter.NewProxy(outbound.NewMitm(fmt.Sprintf("127.0.0.1:%d", cfg.MITM.Port)))
proxyList = append(proxyList, "MITM")
} else if cfg.MitmPort != 0 {
Expand Down
4 changes: 2 additions & 2 deletions listener/mitm/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"github.com/metacubex/mihomo/transport/socks5"
)

func getServerConn(serverConn *N.BufferedConn, srcConn net.Conn, request *http.Request, tunnel C.Tunnel, additions ...inbound.Addition) (*N.BufferedConn, error) {
func getServerConn(serverConn *N.BufferedConn, srcConn net.Conn, request *http.Request, tunnel C.Tunnel, additions []inbound.Addition) (*N.BufferedConn, error) {
if serverConn != nil {
return serverConn, nil
}
Expand All @@ -33,7 +33,7 @@ func getServerConn(serverConn *N.BufferedConn, srcConn net.Conn, request *http.R

left, right := net.Pipe()

go tunnel.HandleTCPConn(inbound.NewMitm(dstAddr, srcConn, request.Header.Get("User-Agent"), request.URL.String(), right, additions...))
go tunnel.HandleTCPConn(inbound.NewMitm(dstAddr, srcConn, request.Header.Get("User-Agent"), request.URL.String(), right, additions))

if request.TLS != nil {
tlsConn := tls.Client(left, &tls.Config{
Expand Down
18 changes: 10 additions & 8 deletions listener/mitm/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func HandleConn(c net.Conn, opt *Option, tunnel C.Tunnel, authenticator auth.Aut
sourceAddr net.Addr
serverConn *N.BufferedConn
connState *tls.ConnectionState
user string
)

defer func() {
Expand All @@ -38,6 +39,9 @@ func HandleConn(c net.Conn, opt *Option, tunnel C.Tunnel, authenticator auth.Aut

conn := N.NewBufferedConn(c)

additions = append(additions, inbound.Placeholder)
inUserIdx := len(additions) - 1

trusted := authenticator == nil // disable authenticate if cache is nil
if !trusted {
trusted = clientIP.IsLoopback() || clientIP.IsUnspecified()
Expand All @@ -62,11 +66,9 @@ readLoop:
sourceAddr = parseSourceAddress(session.request, conn.RemoteAddr(), sourceAddr)
session.request.RemoteAddr = sourceAddr.String()

if !trusted {
session.response, _ = H.Authenticate(session.request, authenticator)

trusted = session.response == nil
}
session.response, user = H.Authenticate(session.request, authenticator)
additions[inUserIdx] = inbound.WithInUser(user)
trusted = session.response == nil

if trusted {
if session.request.Method == http.MethodConnect {
Expand Down Expand Up @@ -133,7 +135,7 @@ readLoop:
session.request.TLS = connState
}

serverConn, err = getServerConn(serverConn, c, session.request, tunnel, additions...)
serverConn, err = getServerConn(serverConn, c, session.request, tunnel, additions)
if err != nil {
break
}
Expand Down Expand Up @@ -161,7 +163,7 @@ readLoop:

// forward websocket
if isWebsocketRequest(request) {
serverConn, err = getServerConn(serverConn, c, session.request, tunnel, additions...)
serverConn, err = getServerConn(serverConn, c, session.request, tunnel, additions)
if err != nil {
break
}
Expand Down Expand Up @@ -196,7 +198,7 @@ readLoop:
if session.request.URL.Host == "" {
session.response = session.NewErrorResponse(ErrInvalidURL)
} else {
serverConn, err = getServerConn(serverConn, c, session.request, tunnel, additions...)
serverConn, err = getServerConn(serverConn, c, session.request, tunnel, additions)
if err != nil {
break
}
Expand Down
30 changes: 23 additions & 7 deletions listener/mitm/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"net"
"net/http"

"github.com/metacubex/mihomo/adapter/inbound"
"github.com/metacubex/mihomo/common/cert"
"github.com/metacubex/mihomo/component/auth"
C "github.com/metacubex/mihomo/constant"
Expand Down Expand Up @@ -53,12 +54,21 @@ func (l *Listener) Close() error {
}

// New the MITM proxy actually is a type of HTTP proxy
func New(option *Option, tunnel C.Tunnel) (*Listener, error) {
return NewWithAuthenticate(option, tunnel, authStore.Authenticator())
func New(option *Option, tunnel C.Tunnel, additions ...inbound.Addition) (*Listener, error) {
return NewWithAuthenticate(option, tunnel, authStore.Authenticator(), additions...)
}

func NewWithAuthenticate(option *Option, tunnel C.Tunnel, authenticator auth.Authenticator) (*Listener, error) {
l, err := net.Listen("tcp", option.Addr)
func NewWithAuthenticate(option *Option, tunnel C.Tunnel, authenticator auth.Authenticator, additions ...inbound.Addition) (*Listener, error) {
isDefault := false
if len(additions) == 0 {
isDefault = true
additions = []inbound.Addition{
inbound.WithInName("DEFAULT-HTTP"),
inbound.WithSpecialRules(""),
}
}

l, err := inbound.Listen("tcp", option.Addr)
if err != nil {
return nil, err
}
Expand All @@ -70,14 +80,20 @@ func NewWithAuthenticate(option *Option, tunnel C.Tunnel, authenticator auth.Aut
}
go func() {
for {
conn, err1 := hl.listener.Accept()
if err1 != nil {
conn, err := hl.listener.Accept()
if err != nil {
if hl.closed {
break
}
continue
}
go HandleConn(conn, option, tunnel, authenticator)
if isDefault { // only apply on default listener
if !inbound.IsRemoteAddrDisAllowed(conn.RemoteAddr()) {
_ = conn.Close()
continue
}
}
go HandleConn(conn, option, tunnel, authenticator, additions...)
}
}()

Expand Down

0 comments on commit 44a236e

Please sign in to comment.