diff options
author | Matthew Holt <[email protected]> | 2024-04-12 15:43:58 -0600 |
---|---|---|
committer | Matthew Holt <[email protected]> | 2024-04-12 15:43:58 -0600 |
commit | 61fecb130a2b3e5dc93b7656172c066d8701af7d (patch) | |
tree | 8077b9a774b2a197f0764871ff462bbe6948a8a7 | |
parent | 9aae4ce1223ac0f4c779ceb6345b639fb5032263 (diff) | |
download | caddy-61fecb130a2b3e5dc93b7656172c066d8701af7d.tar.gz caddy-61fecb130a2b3e5dc93b7656172c066d8701af7d.zip |
Fix HTTP validation with ZeroSSL API
-rw-r--r-- | go.mod | 2 | ||||
-rw-r--r-- | go.sum | 4 | ||||
-rw-r--r-- | modules/caddytls/acmeissuer.go | 1 | ||||
-rw-r--r-- | modules/caddytls/tls.go | 52 |
4 files changed, 37 insertions, 22 deletions
@@ -7,7 +7,7 @@ require ( github.com/Masterminds/sprig/v3 v3.2.3 github.com/alecthomas/chroma/v2 v2.13.0 github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b - github.com/caddyserver/certmagic v0.20.1-0.20240412144827-7681257d05cd + github.com/caddyserver/certmagic v0.20.1-0.20240412214119-167015dd6570 github.com/caddyserver/zerossl v0.1.2 github.com/dustin/go-humanize v1.0.1 github.com/go-chi/chi/v5 v5.0.12 @@ -68,8 +68,8 @@ github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM= github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/caddyserver/certmagic v0.20.1-0.20240412144827-7681257d05cd h1:27VNljzaF3jlba6l68elmo8NOFyesNpXvhHLkbqqR2U= -github.com/caddyserver/certmagic v0.20.1-0.20240412144827-7681257d05cd/go.mod h1:e1NhB1rF5KZnAuAX6oSyhE7sg1Ru5bWgggw5RtauhEY= +github.com/caddyserver/certmagic v0.20.1-0.20240412214119-167015dd6570 h1:SsAXjoQx2wOmLl6mEwJEwh7wwys2hb/l/mhtmxA3wts= +github.com/caddyserver/certmagic v0.20.1-0.20240412214119-167015dd6570/go.mod h1:e1NhB1rF5KZnAuAX6oSyhE7sg1Ru5bWgggw5RtauhEY= github.com/caddyserver/zerossl v0.1.2 h1:tlEu1VzWGoqcCpivs9liKAKhfpJWYJkHEMmlxRbVAxE= github.com/caddyserver/zerossl v0.1.2/go.mod h1:wtiJEHbdvunr40ZzhXlnIkOB8Xj4eKtBKizCcZitJiQ= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= diff --git a/modules/caddytls/acmeissuer.go b/modules/caddytls/acmeissuer.go index 3222052be..a14dc61a8 100644 --- a/modules/caddytls/acmeissuer.go +++ b/modules/caddytls/acmeissuer.go @@ -310,6 +310,7 @@ func (iss *ACMEIssuer) generateZeroSSLEABCredentials(ctx context.Context, acct a return nil, acct, fmt.Errorf("decoding API response: %v", err) } if result.Error.Code != 0 { + // do this check first because ZeroSSL's API returns 200 on errors return nil, acct, fmt.Errorf("failed getting EAB credentials: HTTP %d: %s (code %d)", resp.StatusCode, result.Error.Type, result.Error.Code) } diff --git a/modules/caddytls/tls.go b/modules/caddytls/tls.go index 83a20172a..7e30299aa 100644 --- a/modules/caddytls/tls.go +++ b/modules/caddytls/tls.go @@ -407,35 +407,49 @@ func (t *TLS) Manage(names []string) error { return nil } -// HandleHTTPChallenge ensures that the HTTP challenge is handled for the -// certificate named by r.Host, if it is an HTTP challenge request. It -// requires that the automation policy for r.Host has an issuer of type -// *certmagic.ACMEManager, or one that is ACME-enabled (GetACMEIssuer()). +// HandleHTTPChallenge ensures that the ACME HTTP challenge or ZeroSSL HTTP +// validation request is handled for the certificate named by r.Host, if it +// is an HTTP challenge request. It requires that the automation policy for +// r.Host has an issuer that implements GetACMEIssuer() or is a *ZeroSSLIssuer. func (t *TLS) HandleHTTPChallenge(w http.ResponseWriter, r *http.Request) bool { + acmeChallenge := certmagic.LooksLikeHTTPChallenge(r) + zerosslValidation := certmagic.LooksLikeZeroSSLHTTPValidation(r) + // no-op if it's not an ACME challenge request - if !certmagic.LooksLikeHTTPChallenge(r) { + if !acmeChallenge && !zerosslValidation { return false } // try all the issuers until we find the one that initiated the challenge ap := t.getAutomationPolicyForName(r.Host) - type acmeCapable interface{ GetACMEIssuer() *ACMEIssuer } - for _, iss := range ap.magic.Issuers { - if am, ok := iss.(acmeCapable); ok { - iss := am.GetACMEIssuer() - if iss.issuer.HandleHTTPChallenge(w, r) { - return true + + if acmeChallenge { + type acmeCapable interface{ GetACMEIssuer() *ACMEIssuer } + + for _, iss := range ap.magic.Issuers { + if acmeIssuer, ok := iss.(acmeCapable); ok { + if acmeIssuer.GetACMEIssuer().issuer.HandleHTTPChallenge(w, r) { + return true + } } } - } - // it's possible another server in this process initiated the challenge; - // users have requested that Caddy only handle HTTP challenges it initiated, - // so that users can proxy the others through to their backends; but we - // might not have an automation policy for all identifiers that are trying - // to get certificates (e.g. the admin endpoint), so we do this manual check - if challenge, ok := certmagic.GetACMEChallenge(r.Host); ok { - return certmagic.SolveHTTPChallenge(t.logger, w, r, challenge.Challenge) + // it's possible another server in this process initiated the challenge; + // users have requested that Caddy only handle HTTP challenges it initiated, + // so that users can proxy the others through to their backends; but we + // might not have an automation policy for all identifiers that are trying + // to get certificates (e.g. the admin endpoint), so we do this manual check + if challenge, ok := certmagic.GetACMEChallenge(r.Host); ok { + return certmagic.SolveHTTPChallenge(t.logger, w, r, challenge.Challenge) + } + } else if zerosslValidation { + for _, iss := range ap.magic.Issuers { + if ziss, ok := iss.(*ZeroSSLIssuer); ok { + if ziss.issuer.HandleZeroSSLHTTPValidation(w, r) { + return true + } + } + } } return false |