mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-27 07:59:58 +00:00

This commit adds support for FedRAMP environments. Cloudflared will now dynamically configure the management hostname and API URL, switching to FedRAMP-specific values like `management.fed.argotunnel.com` and `https://api.fed.cloudflare.com/client/v4` when a FedRAMP endpoint is detected. Key to this is an enhanced `ParseToken` function, which now includes an `IsFed()` method to determine if a management token's issuer is `fed-tunnelstore`. This allows cloudflared to correctly identify and operate within a FedRAMP context, ensuring proper connectivity. Closes TUN-9583
70 lines
2.0 KiB
Go
70 lines
2.0 KiB
Go
package management
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
)
|
|
|
|
type ctxKey int
|
|
|
|
const (
|
|
accessClaimsCtxKey ctxKey = iota
|
|
)
|
|
|
|
var errMissingAccessToken = managementError{Code: 1001, Message: "missing access_token query parameter"}
|
|
|
|
// HTTP middleware setting the parsed access_token claims in the request context
|
|
func ValidateAccessTokenQueryMiddleware(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
// Validate access token
|
|
accessToken := r.URL.Query().Get("access_token")
|
|
if accessToken == "" {
|
|
writeHTTPErrorResponse(w, errMissingAccessToken)
|
|
return
|
|
}
|
|
token, err := ParseToken(accessToken)
|
|
if err != nil {
|
|
writeHTTPErrorResponse(w, errMissingAccessToken)
|
|
return
|
|
}
|
|
r = r.WithContext(context.WithValue(r.Context(), accessClaimsCtxKey, token))
|
|
next.ServeHTTP(w, r)
|
|
})
|
|
}
|
|
|
|
// Middleware validation error struct for returning to the eyeball
|
|
type managementError struct {
|
|
Code int `json:"code,omitempty"`
|
|
Message string `json:"message,omitempty"`
|
|
}
|
|
|
|
func (m *managementError) Error() string {
|
|
return m.Message
|
|
}
|
|
|
|
// Middleware validation error HTTP response JSON for returning to the eyeball
|
|
type managementErrorResponse struct {
|
|
Success bool `json:"success,omitempty"`
|
|
Errors []managementError `json:"errors,omitempty"`
|
|
}
|
|
|
|
// writeErrorResponse will respond to the eyeball with basic HTTP JSON payloads with validation failure information
|
|
func writeHTTPErrorResponse(w http.ResponseWriter, errResp managementError) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
err := json.NewEncoder(w).Encode(managementErrorResponse{
|
|
Success: false,
|
|
Errors: []managementError{errResp},
|
|
})
|
|
// we have already written the header, so write a basic error response if unable to encode the error
|
|
if err != nil {
|
|
// fallback to text message
|
|
http.Error(w, fmt.Sprintf(
|
|
"%d %s",
|
|
http.StatusBadRequest,
|
|
http.StatusText(http.StatusBadRequest),
|
|
), http.StatusBadRequest)
|
|
}
|
|
}
|