Checkpoint
This commit is contained in:
@@ -1,9 +1,12 @@
|
||||
package policy
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"crypto/tls"
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
"git.maze.io/maze/styx/ca"
|
||||
"git.maze.io/maze/styx/internal/netutil"
|
||||
"git.maze.io/maze/styx/logger"
|
||||
proxy "git.maze.io/maze/styx/proxy"
|
||||
@@ -24,6 +27,7 @@ func NewRequestHandler(p *Policy) proxy.RequestHandler {
|
||||
log.Err(err).Error("Error generating response")
|
||||
return nil, nil
|
||||
}
|
||||
log.Debug("Replacing HTTP response from policy")
|
||||
return nil, r
|
||||
})
|
||||
}
|
||||
@@ -47,21 +51,52 @@ func NewDialHandler(p *Policy) proxy.DialHandler {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
c := netutil.NewLoopback()
|
||||
// Create a fake loopback connection
|
||||
pipe := netutil.NewLoopback()
|
||||
|
||||
go func(c net.Conn) {
|
||||
s := &http.Server{
|
||||
Handler: http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||
r.Write(w)
|
||||
}),
|
||||
defer func() { _ = c.Close() }()
|
||||
if req.URL.Scheme == "https" || req.URL.Scheme == "wss" || netutil.Port(req.URL.Host) == 443 {
|
||||
c = maybeUpgradeToTLS(c, ctx, req, log)
|
||||
}
|
||||
_ = s.Serve(&netutil.AcceptOnce{Conn: c})
|
||||
}(c.Server)
|
||||
|
||||
return c.Client, nil
|
||||
br := bufio.NewReader(c)
|
||||
if _, err := http.ReadRequest(br); err != nil {
|
||||
log.Err(err).Warn("Malformed HTTP request in MITM connection")
|
||||
}
|
||||
_ = r.Write(c)
|
||||
}(pipe.Server)
|
||||
|
||||
return pipe.Client, nil
|
||||
})
|
||||
}
|
||||
|
||||
func maybeUpgradeToTLS(c net.Conn, ctx proxy.Context, req *http.Request, log logger.Structured) net.Conn {
|
||||
var ca ca.CertificateAuthority
|
||||
if caCtx, ok := ctx.(proxy.WithCertificateAuthority); ok {
|
||||
ca = caCtx.CertificateAuthority()
|
||||
}
|
||||
if ca == nil {
|
||||
return c
|
||||
}
|
||||
|
||||
secure := tls.Server(c, &tls.Config{
|
||||
GetCertificate: func(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||
log.Values(logger.Values{
|
||||
"cn": req.URL.Host,
|
||||
"names": hello.ServerName,
|
||||
}).Debug("Requesting certificate from CA")
|
||||
return ca.GetCertificate(netutil.Host(req.URL.Host), []string{hello.ServerName}, nil)
|
||||
},
|
||||
NextProtos: []string{"http/1.1"},
|
||||
})
|
||||
if err := secure.Handshake(); err != nil {
|
||||
log.Err(err).Warn("Failed to pretend secure HTTP")
|
||||
return c
|
||||
}
|
||||
return secure
|
||||
}
|
||||
|
||||
func NewForwardHandler(p *Policy) proxy.ForwardHandler {
|
||||
log := logger.StandardLog.Value("policy", p.name)
|
||||
return proxy.ForwardHandlerFunc(func(ctx proxy.Context, req *http.Request) (*http.Response, error) {
|
||||
@@ -72,7 +107,15 @@ func NewForwardHandler(p *Policy) proxy.ForwardHandler {
|
||||
log.Err(err).Error("Error evaulating policy")
|
||||
return nil, nil
|
||||
}
|
||||
return result.Response(ctx)
|
||||
r, err := result.Response(ctx)
|
||||
if err != nil {
|
||||
log.Err(err).Error("Error generating response")
|
||||
return nil, err
|
||||
}
|
||||
if r != nil {
|
||||
log.Debug("Replacing HTTP response from policy")
|
||||
}
|
||||
return r, nil
|
||||
})
|
||||
}
|
||||
|
||||
@@ -80,6 +123,7 @@ func NewResponseHandler(p *Policy) proxy.ResponseHandler {
|
||||
log := logger.StandardLog.Value("policy", p.name)
|
||||
return proxy.ResponseHandlerFunc(func(ctx proxy.Context) *http.Response {
|
||||
input := NewInputFromResponse(ctx, ctx.Response())
|
||||
input.logValues(log).Trace("Running response handler")
|
||||
result, err := p.Query(input)
|
||||
if err != nil {
|
||||
log.Err(err).Error("Error evaulating policy")
|
||||
@@ -90,6 +134,9 @@ func NewResponseHandler(p *Policy) proxy.ResponseHandler {
|
||||
log.Err(err).Error("Error generating response")
|
||||
return nil
|
||||
}
|
||||
if r != nil {
|
||||
log.Debug("Replacing HTTP response from policy")
|
||||
}
|
||||
return r
|
||||
})
|
||||
}
|
||||
|
Reference in New Issue
Block a user