Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 14, 05:15 UTC
caddytls: customizable client auth modes (#2913)
* ability to specify that client cert must be present in SSL * changed the clientauthtype to string and make room for the values supported by go as in caddy1 * renamed the config parameter according to review comments and added documentation on allowed values * missed a reference * Minor cleanup; docs enhancements Co-authored-by: Matthew Holt <mholt@users.noreply.github.com>
evtr committed
Mar 8, 2020 at 16:48 UTC
ca6e54bbb8ab2bad3cc9192bd4857be7e9501c6c
1 file changed
+37
-6
modules/caddytls/connpolicy.go
+37
-6
@@ -276,6 +276,20 @@ type ClientAuthentication struct {
276
// which are not in this list will be rejected.
277
TrustedLeafCerts []string `json:"trusted_leaf_certs,omitempty"`
278
279
+ // The mode for authenticating the client. Allowed values are:
280
+ //
281
+ // Mode | Description
282
+ // -----|---------------
283
+ // `request` | Ask clients for a certificate, but allow even if there isn't one; do not verify it
284
+ // `require` | Require clients to present a certificate, but do not verify it
285
+ // `verify_if_given` | Ask clients for a certificate; allow even if there isn't one, but verify it if there is
286
+ // `require_and_verify` | Require clients to present a valid certificate that is verified
287
+ //
288
+ // The default mode is `require_and_verify` if any
289
+ // TrustedCACerts or TrustedLeafCerts are provided;
290
+ // otherwise, the default mode is `require`.
291
+ Mode string `json:"mode,omitempty"`
292
+
293
// state established with the last call to ConfigureTLSConfig
294
trustedLeafCerts []*x509.Certificate
295
existingVerifyPeerCert func([][]byte, [][]*x509.Certificate) error
@@ -283,7 +297,7 @@ type ClientAuthentication struct {
297
298
// Active returns true if clientauth has an actionable configuration.
299
func (clientauth ClientAuthentication) Active() bool {
286
- return len(clientauth.TrustedCACerts) > 0 || len(clientauth.TrustedLeafCerts) > 0
300
+ return len(clientauth.TrustedCACerts) > 0 || len(clientauth.TrustedLeafCerts) > 0 || len(clientauth.Mode) > 0
301
}
302
303
// ConfigureTLSConfig sets up cfg to enforce clientauth's configuration.
@@ -294,8 +308,28 @@ func (clientauth *ClientAuthentication) ConfigureTLSConfig(cfg *tls.Config) erro
308
return nil
309
}
310
297
- // otherwise, at least require any client certificate
298
- cfg.ClientAuth = tls.RequireAnyClientCert
311
+ // enforce desired mode of client authentication
312
+ if len(clientauth.Mode) > 0 {
313
+ switch clientauth.Mode {
314
+ case "request":
315
+ cfg.ClientAuth = tls.RequestClientCert
316
+ case "require":
317
+ cfg.ClientAuth = tls.RequireAnyClientCert
318
+ case "verify_if_given":
319
+ cfg.ClientAuth = tls.VerifyClientCertIfGiven
320
+ case "require_and_verify":
321
+ cfg.ClientAuth = tls.RequireAndVerifyClientCert
322
+ default:
323
+ return fmt.Errorf("client auth mode %s not allowed", clientauth.Mode)
324
+ }
325
+ } else {
326
+ // otherwise, set a safe default mode
327
+ if len(clientauth.TrustedCACerts) > 0 || len(clientauth.TrustedLeafCerts) > 0 {
328
+ cfg.ClientAuth = tls.RequireAndVerifyClientCert
329
+ } else {
330
+ cfg.ClientAuth = tls.RequireAnyClientCert
331
+ }
332
+ }
333
334
// enforce CA verification by adding CA certs to the ClientCAs pool
335
if len(clientauth.TrustedCACerts) > 0 {
@@ -308,9 +342,6 @@ func (clientauth *ClientAuthentication) ConfigureTLSConfig(cfg *tls.Config) erro
342
caPool.AddCert(clientCA)
343
}
344
cfg.ClientCAs = caPool
311
-
312
- // now ensure the standard lib will verify client certificates
313
- cfg.ClientAuth = tls.RequireAndVerifyClientCert
345
}
346
347
// enforce leaf verification by writing our own verify function