MCPcopy
hub / github.com/caddyserver/certmagic / distributedHTTPChallengeSolver

Method distributedHTTPChallengeSolver

httphandlers.go:71–127  ·  view source on GitHub ↗

distributedHTTPChallengeSolver checks to see if this challenge request was initiated by this or another instance which uses the same storage as am does, and attempts to complete the challenge for it. It returns true if the request was handled; false otherwise.

(w http.ResponseWriter, r *http.Request)

Source from the content-addressed store, hash-verified

69// same storage as am does, and attempts to complete the challenge for
70// it. It returns true if the request was handled; false otherwise.
71func (am *ACMEIssuer) distributedHTTPChallengeSolver(w http.ResponseWriter, r *http.Request) bool {
72 if am == nil {
73 return false
74 }
75 host := hostOnly(r.Host)
76 chalInfo, distributed, err := am.config.getACMEChallengeInfo(r.Context(), host, !am.DisableDistributedSolvers)
77 if err != nil {
78 if am.DisableDistributedSolvers {
79 // Distributed solvers are disabled, so the only way an error can be returned is if
80 // this instance didn't initiate the challenge (or if the process exited after, but
81 // either way, we don't have the challenge info). Assuming this is a legitimate
82 // challenge request, we may still be able to solve it if we can present the correct
83 // account thumbprint with the token, since the token is given to us in the URL path.
84 //
85 // NOTE: About doing this, RFC 8555 section 8.3 says:
86 //
87 // Note that because the token appears both in the request sent by the
88 // ACME server and in the key authorization in the response, it is
89 // possible to build clients that copy the token from request to
90 // response. Clients should avoid this behavior because it can lead to
91 // cross-site scripting vulnerabilities; instead, clients should be
92 // explicitly configured on a per-challenge basis. A client that does
93 // copy tokens from requests to responses MUST validate that the token
94 // in the request matches the token syntax above (e.g., that it includes
95 // only characters from the base64url alphabet).
96 //
97 // Also, since we're just blindly solving a challenge, we're unable to mitigate DNS
98 // rebinding attacks, because we don't know what host to expect in the URL. So this
99 // is not ideal, but we do at least validate the copied token is in the base64url set.
100 if strings.HasPrefix(r.URL.Path, acmeHTTPChallengeBasePath) &&
101 strings.Count(r.URL.Path, "/") == 3 &&
102 r.Method == http.MethodGet {
103 tokenStart := strings.LastIndex(r.URL.Path, "/") + 1
104 token := r.URL.Path[tokenStart:]
105 if allBase64URL(token) {
106 if err := am.solveHTTPChallengeBlindly(w, r); err != nil {
107 am.Logger.Error("solving http-01 challenge blindly",
108 zap.String("identifier", host),
109 zap.Error(err))
110 }
111 return true
112 }
113 }
114 }
115
116 // couldn't get challenge info even with distributed solver
117 am.Logger.Warn("looking up info for HTTP challenge",
118 zap.String("uri", r.RequestURI),
119 zap.String("identifier", host),
120 zap.String("remote_addr", r.RemoteAddr),
121 zap.String("user_agent", r.Header.Get("User-Agent")),
122 zap.Error(err))
123 return false
124 }
125
126 return solveHTTPChallenge(am.Logger, w, r, chalInfo.Challenge, distributed)
127}
128

Callers 1

HandleHTTPChallengeMethod · 0.95

Calls 7

hostOnlyFunction · 0.85
allBase64URLFunction · 0.85
solveHTTPChallengeFunction · 0.85
getACMEChallengeInfoMethod · 0.80
ErrorMethod · 0.80
StringMethod · 0.80

Tested by

no test coverage detected