From 514eef33fe6ea4e52438e62f73c8f3c0aadd45db Mon Sep 17 00:00:00 2001 From: v-rosa Date: Fri, 31 Jul 2020 22:06:30 +0100 Subject: caddyhttp: Add support to resolve DN in CEL expression (#3608) --- modules/caddyhttp/celmatcher_test.go | 75 +++++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) (limited to 'modules/caddyhttp/celmatcher_test.go') diff --git a/modules/caddyhttp/celmatcher_test.go b/modules/caddyhttp/celmatcher_test.go index 0e3b335..a78eb5a 100644 --- a/modules/caddyhttp/celmatcher_test.go +++ b/modules/caddyhttp/celmatcher_test.go @@ -15,6 +15,11 @@ package caddyhttp import ( + "context" + "crypto/tls" + "crypto/x509" + "encoding/pem" + "net/http/httptest" "testing" "github.com/caddyserver/caddy/v2" @@ -27,7 +32,7 @@ func TestMatchExpressionProvision(t *testing.T) { wantErr bool }{ { - name: "boolean mtaches succeed", + name: "boolean matches succeed", expression: &MatchExpression{ Expr: "{http.request.uri.query} != ''", }, @@ -49,3 +54,71 @@ func TestMatchExpressionProvision(t *testing.T) { }) } } + +func TestMatchExpressionMatch(t *testing.T) { + + clientCert := []byte(`-----BEGIN CERTIFICATE----- +MIIB9jCCAV+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1DYWRk +eSBUZXN0IENBMB4XDTE4MDcyNDIxMzUwNVoXDTI4MDcyMTIxMzUwNVowHTEbMBkG +A1UEAwwSY2xpZW50LmxvY2FsZG9tYWluMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB +iQKBgQDFDEpzF0ew68teT3xDzcUxVFaTII+jXH1ftHXxxP4BEYBU4q90qzeKFneF +z83I0nC0WAQ45ZwHfhLMYHFzHPdxr6+jkvKPASf0J2v2HDJuTM1bHBbik5Ls5eq+ +fVZDP8o/VHKSBKxNs8Goc2NTsr5b07QTIpkRStQK+RJALk4x9QIDAQABo0swSTAJ +BgNVHRMEAjAAMAsGA1UdDwQEAwIHgDAaBgNVHREEEzARgglsb2NhbGhvc3SHBH8A +AAEwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADgYEANSjz2Sk+ +eqp31wM9il1n+guTNyxJd+FzVAH+hCZE5K+tCgVDdVFUlDEHHbS/wqb2PSIoouLV +3Q9fgDkiUod+uIK0IynzIKvw+Cjg+3nx6NQ0IM0zo8c7v398RzB4apbXKZyeeqUH +9fNwfEi+OoXR6s+upSKobCmLGLGi9Na5s5g= +-----END CERTIFICATE-----`) + + tests := []struct { + name string + expression *MatchExpression + wantErr bool + wantResult bool + clientCertificate []byte + }{ + { + name: "boolean matches succeed for placeholder http.request.tls.client.subject", + expression: &MatchExpression{ + Expr: "{http.request.tls.client.subject} == 'CN=client.localdomain'", + }, + clientCertificate: clientCert, + wantResult: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := tt.expression.Provision(caddy.Context{}); (err != nil) != tt.wantErr { + t.Errorf("MatchExpression.Provision() error = %v, wantErr %v", err, tt.wantErr) + } + + req := httptest.NewRequest("GET", "https://example.com/foo", nil) + repl := caddy.NewReplacer() + ctx := context.WithValue(req.Context(), caddy.ReplacerCtxKey, repl) + req = req.WithContext(ctx) + addHTTPVarsToReplacer(repl, req, httptest.NewRecorder()) + + if tt.clientCertificate != nil { + block, _ := pem.Decode(clientCert) + if block == nil { + t.Fatalf("failed to decode PEM certificate") + } + + cert, err := x509.ParseCertificate(block.Bytes) + if err != nil { + t.Fatalf("failed to decode PEM certificate: %v", err) + } + + req.TLS = &tls.ConnectionState{ + PeerCertificates: []*x509.Certificate{cert}, + } + } + + if tt.expression.Match(req) != tt.wantResult { + t.Errorf("MatchExpression.Match() expected to return '%t', for expression : '%s'", tt.wantResult, tt.expression) + } + + }) + } +} -- cgit v1.2.3