140 lines
3.2 KiB
Go
140 lines
3.2 KiB
Go
package policy
|
|
|
|
import (
|
|
"net"
|
|
"net/http"
|
|
"net/url"
|
|
"testing"
|
|
|
|
"git.maze.io/maze/styx/internal/netutil"
|
|
"git.maze.io/maze/styx/proxy/match"
|
|
"github.com/miekg/dns"
|
|
)
|
|
|
|
type testInDomainList struct {
|
|
t *testing.T
|
|
list []string
|
|
}
|
|
|
|
func (testInDomainList) Name() string { return "testInDomainList" }
|
|
func (l testInDomainList) MatchesRequest(r *http.Request) bool {
|
|
for _, domain := range l.list {
|
|
if dns.IsSubDomain(domain, netutil.Host(r.URL.Host)) {
|
|
l.t.Logf("domain %s contains %s", domain, r.URL.Host)
|
|
return true
|
|
}
|
|
l.t.Logf("domain %s does not contain %s", domain, r.URL.Host)
|
|
}
|
|
return false
|
|
}
|
|
|
|
func testInDomain(t *testing.T, domains ...string) match.Matcher {
|
|
return &testInDomainList{t: t, list: domains}
|
|
}
|
|
|
|
type testInNetworkList struct {
|
|
t *testing.T
|
|
list []*net.IPNet
|
|
}
|
|
|
|
func (testInNetworkList) Name() string { return "testInNetworkList" }
|
|
func (l testInNetworkList) MatchesIP(ip net.IP) bool {
|
|
for _, ipnet := range l.list {
|
|
if ipnet.Contains(ip) {
|
|
l.t.Logf("network %s contains %s", ipnet, ip)
|
|
return true
|
|
}
|
|
l.t.Logf("network %s does not contain %s", ipnet, ip)
|
|
}
|
|
return false
|
|
}
|
|
|
|
func testInNetwork(t *testing.T, cidr string) match.Matcher {
|
|
t.Helper()
|
|
_, ipnet, err := net.ParseCIDR(cidr)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return testInNetworkList{t: t, list: []*net.IPNet{ipnet}}
|
|
}
|
|
|
|
func TestPolicy(t *testing.T) {
|
|
var (
|
|
yes = true
|
|
nope = false
|
|
)
|
|
p := &Policy{
|
|
Rules: []*rawRule{
|
|
{
|
|
Rule: &requestRule{
|
|
domainOrNetworkRule: domainOrNetworkRule{
|
|
matchers: []match.Matcher{testInNetwork(t, "127.0.0.0/8")},
|
|
isSource: []bool{true},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Rule: &requestRule{
|
|
domainOrNetworkRule: domainOrNetworkRule{
|
|
matchers: []match.Matcher{testInNetwork(t, "127.0.0.0/8")},
|
|
isSource: []bool{false},
|
|
},
|
|
Permit: &yes,
|
|
},
|
|
},
|
|
{
|
|
Rule: &requestRule{
|
|
domainOrNetworkRule: domainOrNetworkRule{
|
|
matchers: []match.Matcher{testInDomain(t, "maze.io", "maze.engineering")},
|
|
},
|
|
Permit: &yes,
|
|
},
|
|
},
|
|
{
|
|
Rule: &requestRule{
|
|
domainOrNetworkRule: domainOrNetworkRule{
|
|
matchers: []match.Matcher{testInDomain(t, "google.com")},
|
|
},
|
|
Permit: &nope,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
r := &http.Request{
|
|
URL: &url.URL{Scheme: "http", Host: "golang.org:80"},
|
|
RemoteAddr: "127.0.0.1:1234",
|
|
}
|
|
if v := p.PermitRequest(r); v != nil {
|
|
t.Errorf("expected request to return no verdict, got %t", *v)
|
|
}
|
|
|
|
p.Rules[0].Rule.(*requestRule).Permit = &yes
|
|
if v := p.PermitRequest(r); v == nil || *v != yes {
|
|
t.Errorf("expected request to return %t, %v", yes, v)
|
|
}
|
|
|
|
r.RemoteAddr = "192.168.1.2:3456"
|
|
if v := p.PermitRequest(r); v != nil {
|
|
t.Errorf("expected request to return no verdict, got %t", *v)
|
|
}
|
|
if v := p.PermitIntercept(r); v != nil {
|
|
t.Errorf("expected request to return no verdict, got %t", *v)
|
|
}
|
|
|
|
r.URL.Host = "maze.io"
|
|
if v := p.PermitRequest(r); v == nil || *v != yes {
|
|
t.Errorf("expected request to return %t, %v", yes, v)
|
|
}
|
|
|
|
r.URL.Host = "google.com"
|
|
if v := p.PermitRequest(r); v == nil || *v != nope {
|
|
t.Errorf("expected request to return %t, %v", nope, v)
|
|
}
|
|
|
|
r.URL.Host = "localhost:80"
|
|
if v := p.PermitRequest(r); v == nil || *v != yes {
|
|
t.Errorf("expected request to return %t, %v", yes, v)
|
|
}
|
|
}
|