mirror of
https://github.com/syncthing/syncthing.git
synced 2024-11-16 10:28:49 -07:00
Support multiple API keys (command-line and config) (fixes #2747)
This commit is contained in:
parent
8ff7531f89
commit
5971c00a4f
@ -238,7 +238,7 @@ func (s *apiService) Serve() {
|
||||
|
||||
// Wrap everything in CSRF protection. The /rest prefix should be
|
||||
// protected, other requests will grant cookies.
|
||||
handler := csrfMiddleware(s.id.String()[:5], "/rest", guiCfg.APIKey(), mux)
|
||||
handler := csrfMiddleware(s.id.String()[:5], "/rest", guiCfg, mux)
|
||||
|
||||
// Add the CORS handling
|
||||
handler = corsMiddleware(handler)
|
||||
|
@ -33,9 +33,8 @@ func emitLoginAttempt(success bool, username string) {
|
||||
}
|
||||
|
||||
func basicAuthAndSessionMiddleware(cookieName string, cfg config.GUIConfiguration, next http.Handler) http.Handler {
|
||||
apiKey := cfg.APIKey()
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if apiKey != "" && r.Header.Get("X-API-Key") == apiKey {
|
||||
if cfg.IsValidAPIKey(r.Header.Get("X-API-Key")) {
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/syncthing/syncthing/lib/config"
|
||||
"github.com/syncthing/syncthing/lib/osutil"
|
||||
"github.com/syncthing/syncthing/lib/sync"
|
||||
)
|
||||
@ -30,11 +31,11 @@ const maxCsrfTokens = 25
|
||||
// Check for CSRF token on /rest/ URLs. If a correct one is not given, reject
|
||||
// the request with 403. For / and /index.html, set a new CSRF cookie if none
|
||||
// is currently set.
|
||||
func csrfMiddleware(unique, prefix, apiKey string, next http.Handler) http.Handler {
|
||||
func csrfMiddleware(unique string, prefix string, cfg config.GUIConfiguration, next http.Handler) http.Handler {
|
||||
loadCsrfTokens()
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// Allow requests carrying a valid API key
|
||||
if apiKey != "" && r.Header.Get("X-API-Key") == apiKey {
|
||||
if cfg.IsValidAPIKey(r.Header.Get("X-API-Key")) {
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
@ -478,7 +478,7 @@ func upgradeViaRest() error {
|
||||
cfg, _ := loadConfig()
|
||||
target := cfg.GUI().URL()
|
||||
r, _ := http.NewRequest("POST", target+"/rest/system/upgrade", nil)
|
||||
r.Header.Set("X-API-Key", cfg.GUI().APIKey())
|
||||
r.Header.Set("X-API-Key", cfg.GUI().RawAPIKey)
|
||||
|
||||
tr := &http.Transport{
|
||||
Dial: dialer.Dial,
|
||||
|
@ -76,9 +76,17 @@ func (c GUIConfiguration) URL() string {
|
||||
return u.String()
|
||||
}
|
||||
|
||||
func (c GUIConfiguration) APIKey() string {
|
||||
if override := os.Getenv("STGUIAPIKEY"); override != "" {
|
||||
return override
|
||||
// Returns whether the given API key is valid, including both the value in config
|
||||
// and any overrides
|
||||
func (c GUIConfiguration) IsValidAPIKey(apiKey string) bool {
|
||||
switch apiKey {
|
||||
case "":
|
||||
return false
|
||||
|
||||
case c.RawAPIKey, os.Getenv("STGUIAPIKEY"):
|
||||
return true
|
||||
|
||||
default:
|
||||
return false
|
||||
}
|
||||
return c.RawAPIKey
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user