@marcel91200 / caddy Mirror · read-only / commits / 0005e3ac
Fork 0

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

httpcaddyfile: Combine repeated cert loaders (fix #3004)

Also only append 1 catch-all TLS connection policy to a server, even if multiple site blocks contribute to that server.

Matthew Holt committed Feb 20, 2020 at 00:15 UTC 0005e3acdc7f0bc89f7a8bb15a1e23295986a3b7
1 file changed +34 -18
caddyconfig/httpcaddyfile/httptype.go
+34 -18
@@ -205,10 +205,26 @@ func (st ServerType) Setup(originalServerBlocks []caddyfile.ServerBlock,
205 }
206 // group certificate loaders by module name, then add to config
207 if len(certLoaders) > 0 {
208 - loadersByName := make(map[string][]caddytls.CertificateLoader)
208 + loadersByName := make(map[string]caddytls.CertificateLoader)
209 for _, cl := range certLoaders {
210 name := caddy.GetModuleName(cl)
211 - loadersByName[name] = append(loadersByName[name], cl)
211 + // ugh... technically, we may have multiple FileLoader and FolderLoader
212 + // modules (because the tls directive returns one per occurrence), but
213 + // the config structure expects only one instance of each kind of loader
214 + // module, so we have to combine them... instead of enumerating each
215 + // possible cert loader module in a type switch, we can use reflection,
216 + // which works on any cert loaders that are slice types
217 + if reflect.TypeOf(cl).Kind() == reflect.Slice {
218 + combined := reflect.ValueOf(loadersByName[name])
219 + if !combined.IsValid() {
220 + combined = reflect.New(reflect.TypeOf(cl)).Elem()
221 + }
222 + clVal := reflect.ValueOf(cl)
223 + for i := 0; i < clVal.Len(); i++ {
224 + combined = reflect.Append(reflect.Value(combined), clVal.Index(i))
225 + }
226 + loadersByName[name] = combined.Interface().(caddytls.CertificateLoader)
227 + }
228 }
229 for certLoaderName, loaders := range loadersByName {
230 tlsApp.CertificatesRaw[certLoaderName] = caddyconfig.JSON(loaders, &warnings)
@@ -400,6 +416,8 @@ func (st *ServerType) serversFromPairings(
416 return specificity(iLongestHost) > specificity(jLongestHost)
417 })
418
419 + var hasCatchAllTLSConnPolicy bool
420 +
421 // create a subroute for each site in the server block
422 for _, sblock := range p.serverBlocks {
423 matcherSetsEnc, err := st.compileEncodedMatcherSets(sblock.block)
@@ -420,7 +438,6 @@ func (st *ServerType) serversFromPairings(
438 srv.AutoHTTPS.Skip = append(srv.AutoHTTPS.Skip, autoHTTPSQualifiedHosts...)
439 } else if cpVals, ok := sblock.pile["tls.connection_policy"]; ok {
440 // tls connection policies
423 - var hasCatchAll bool
441 for _, cpVal := range cpVals {
442 cp := cpVal.Value.(*caddytls.ConnectionPolicy)
443
@@ -436,25 +453,11 @@ func (st *ServerType) serversFromPairings(
453 "sni": caddyconfig.JSON(hosts, warnings), // make sure to match all hosts, not just auto-HTTPS-qualified ones
454 }
455 } else {
439 - hasCatchAll = true
456 + hasCatchAllTLSConnPolicy = true
457 }
458
459 srv.TLSConnPolicies = append(srv.TLSConnPolicies, cp)
460 }
444 -
445 - // a catch-all is necessary to ensure TLS can be offered to
446 - // all hostnames of the server; even though only one policy
447 - // is needed to enable TLS for the server, that policy might
448 - // apply to only certain TLS handshakes; but when using the
449 - // Caddyfile, user would expect all handshakes to at least
450 - // have a matching connection policy, so here we append a
451 - // catch-all/default policy if there isn't one already (it's
452 - // important that it goes at the end) - see issue #3004:
453 - // https://github.com/caddyserver/caddy/issues/3004
454 - if !hasCatchAll {
455 - srv.TLSConnPolicies = append(srv.TLSConnPolicies, new(caddytls.ConnectionPolicy))
456 - }
457 -
461 // TODO: consolidate equal conn policies
462 }
463
@@ -498,6 +501,19 @@ func (st *ServerType) serversFromPairings(
501 }
502 }
503
504 + // a catch-all TLS conn policy is necessary to ensure TLS can
505 + // be offered to all hostnames of the server; even though only
506 + // one policy is needed to enable TLS for the server, that
507 + // policy might apply to only certain TLS handshakes; but when
508 + // using the Caddyfile, user would expect all handshakes to at
509 + // least have a matching connection policy, so here we append a
510 + // catch-all/default policy if there isn't one already (it's
511 + // important that it goes at the end) - see issue #3004:
512 + // https://github.com/caddyserver/caddy/issues/3004
513 + if len(srv.TLSConnPolicies) > 0 && !hasCatchAllTLSConnPolicy {
514 + srv.TLSConnPolicies = append(srv.TLSConnPolicies, new(caddytls.ConnectionPolicy))
515 + }
516 +
517 srv.Routes = consolidateRoutes(srv.Routes)
518
519 servers[fmt.Sprintf("srv%d", i)] = srv