checkBootstrapToken validates the X-Bootstrap-Token header on r against the in-memory token using a constant-time comparison. Returns false if no token is configured or the header is missing/wrong. Caller MUST hold s.bootstrapMu — handleBootstrap takes the lock for the entire validate-token → check
(r *http.Request)
| 167 | // the entire validate-token → check-UserCount → CreateUser → consume |
| 168 | // sequence (F5). |
| 169 | func (s *Server) checkBootstrapToken(r *http.Request) bool { |
| 170 | if s.bootstrapToken == "" { |
| 171 | return false |
| 172 | } |
| 173 | provided := r.Header.Get(BootstrapTokenHeader) |
| 174 | if provided == "" { |
| 175 | return false |
| 176 | } |
| 177 | // Use constant-time comparison so the response time can't leak |
| 178 | // per-character feedback to an attacker grinding through guesses. |
| 179 | return subtle.ConstantTimeCompare([]byte(provided), []byte(s.bootstrapToken)) == 1 |
| 180 | } |
| 181 | |
| 182 | // SetBypassSetupToken wires the operator's PAD_BYPASS_SETUP_TOKEN choice |
| 183 | // into the Server. When true, handleBootstrap accepts a self-host |