Repository: caddyserver/caddy (language: go)

Issue:
Add Caddyfile Config Adapter Support for Client Auth Verifiers
Hey All,

I'm using Caddy with client TLS and the caddy-revocation-validator verifier, but the Caddyfile config adapter isn't built to handle client_auth verifiers, so the source code needed some updates for it to work. Can we add support for verifiers in the Caddyfile?

Here is an example Caddyfile that I had:
```
localhost:8080 {
        respond "hello!"
        tls certificate.crt private.key {
                client_auth {
                        mode require_and_verify
                        trusted_ca_cert_file certificate.crt
                        verifier revocation {
                                mode crl_only
                                crl_config {
                                        storage_type memory
                                        signature_validation_mode verify
                                        trusted_signature_cert_file certificate.crt
                                }
                        }
                }
        }
}
```

When I run Caddy with the above Caddyfile, I get the following error:
`Error: adapting config using caddyfile: parsing caddyfile tokens for 'tls': unknown subdirective for client_auth: verifier, at Caddyfile:7`

Which comes from here: https://github.com/caddyserver/caddy/blob/8a50f191bf3e4e60fdd51753f54604735f9787e4/caddyconfig/httpcaddyfile/builtins.go#L272

In order to make it work, the following code needed to be added to the caddyconfig/httpcaddyfile/builtins.go in the client_auth select statement right above where that error is:
```
case "verifier":
						if !h.NextArg() { -> Verify that the argument we are currently on is actually another argument by checking that it is not a curly bracket or is not on a new line
							return nil, h.ArgErr()
						}

						vType := h.Val() -> Get the current argument
						modID := "tls.client_auth." + vType -> Append it to "tls.client_auth" to create the ID to use in the GetModule method to get the caddy.ModuleInfo of the module for this verifier
						unm, err := caddyfile.UnmarshalModule(h.Dispenser, modID) -> Unmarshal the passed arguments based on the valid configuration of the module
						if err != nil {
							return nil, err
						}

						ccv, ok := unm.(caddytls.ClientCertificateVerifier) -> Verify that the module is an implementation of the caddytls.ClientCertificateVerifier struct
						if !ok {
							return nil, h.Dispenser.Errf("module %s is not a caddytls.ClientCertificatVerifier", modID)
						}

						bytes, err := json.Marshal(ccv) -> Convert the configuration to JSON
						if err != nil {
							return nil, err
						}
						cp.ClientAuthentication.VerifiersRaw = append(cp.ClientAuthentication.VerifiersRaw, bytes) -> Append the bytes object of the JSON config to the slice of ClientAuthentication verifiers
```

Could we add something similar to the above so that you can use a Caddyfile rather than JSON with client_auth verifiers? Happy to submit a PR if this is something you all would be interested in!



Discussion / hints:
Sure, PR welcome!

Fix patch:
diff --git a/caddyconfig/httpcaddyfile/builtins.go b/caddyconfig/httpcaddyfile/builtins.go
index 5680283880f..f345a676fdc 100644
--- a/caddyconfig/httpcaddyfile/builtins.go
+++ b/caddyconfig/httpcaddyfile/builtins.go
@@ -219,6 +219,24 @@ func parseTLS(h Helper) ([]ConfigValue, error) {
 				for nesting := h.Nesting(); h.NextBlock(nesting); {
 					subdir := h.Val()
 					switch subdir {
+					case "verifier":
+						if !h.NextArg() {
+							return nil, h.ArgErr()
+						}
+
+						vType := h.Val()
+						modID := "tls.client_auth." + vType
+						unm, err := caddyfile.UnmarshalModule(h.Dispenser, modID)
+						if err != nil {
+							return nil, err
+						}
+
+						_, ok := unm.(caddytls.ClientCertificateVerifier)
+						if !ok {
+							return nil, h.Dispenser.Errf("module %s is not a caddytls.ClientCertificatVerifier", modID)
+						}
+
+						cp.ClientAuthentication.VerifiersRaw = append(cp.ClientAuthentication.VerifiersRaw, caddyconfig.JSONModuleObject(unm, "verifier", vType, h.warnings))
 					case "mode":
 						if !h.Args(&cp.ClientAuthentication.Mode) {
 							return nil, h.ArgErr()


Test patch: