mirror of
https://github.com/drakkan/sftpgo.git
synced 2025-12-07 23:00:55 +03:00
allow to use a persistent signing key for JWT and CSRF tokens
Fixes #466
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
package httpd
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
@@ -245,6 +246,10 @@ type Conf struct {
|
||||
// CARevocationLists defines a set a revocation lists, one for each root CA, to be used to check
|
||||
// if a client certificate has been revoked
|
||||
CARevocationLists []string `json:"ca_revocation_lists" mapstructure:"ca_revocation_lists"`
|
||||
// SigningPassphrase defines the passphrase to use to derive the signing key for JWT and CSRF tokens.
|
||||
// If empty a random signing key will be generated each time SFTPGo starts. If you set a
|
||||
// signing passphrase you should consider rotating it periodically for added security
|
||||
SigningPassphrase string `json:"signing_passphrase" mapstructure:"signing_passphrase"`
|
||||
}
|
||||
|
||||
type apiResponse struct {
|
||||
@@ -289,9 +294,15 @@ func (c *Conf) checkRequiredDirs(staticFilesPath, templatesPath string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Conf) getRedacted() Conf {
|
||||
conf := *c
|
||||
conf.SigningPassphrase = "[redacted]"
|
||||
return conf
|
||||
}
|
||||
|
||||
// Initialize configures and starts the HTTP server
|
||||
func (c *Conf) Initialize(configDir string) error {
|
||||
logger.Debug(logSender, "", "initializing HTTP server with config %+v", c)
|
||||
logger.Debug(logSender, "", "initializing HTTP server with config %v", c.getRedacted())
|
||||
backupsPath = getConfigPath(c.BackupsPath, configDir)
|
||||
staticFilesPath := getConfigPath(c.StaticFilesPath, configDir)
|
||||
templatesPath := getConfigPath(c.TemplatesPath, configDir)
|
||||
@@ -331,7 +342,7 @@ func (c *Conf) Initialize(configDir string) error {
|
||||
certMgr = mgr
|
||||
}
|
||||
|
||||
csrfTokenAuth = jwtauth.New(jwa.HS256.String(), utils.GenerateRandomBytes(32), nil)
|
||||
csrfTokenAuth = jwtauth.New(jwa.HS256.String(), getSigningKey(c.SigningPassphrase), nil)
|
||||
|
||||
exitChannel := make(chan error, 1)
|
||||
|
||||
@@ -344,7 +355,7 @@ func (c *Conf) Initialize(configDir string) error {
|
||||
}
|
||||
|
||||
go func(b Binding) {
|
||||
server := newHttpdServer(b, staticFilesPath)
|
||||
server := newHttpdServer(b, staticFilesPath, c.SigningPassphrase)
|
||||
|
||||
exitChannel <- server.listenAndServe()
|
||||
}(binding)
|
||||
@@ -473,7 +484,7 @@ func GetHTTPRouter() http.Handler {
|
||||
EnableWebAdmin: true,
|
||||
EnableWebClient: true,
|
||||
}
|
||||
server := newHttpdServer(b, "../static")
|
||||
server := newHttpdServer(b, "../static", "")
|
||||
server.initializeRouter()
|
||||
return server.router
|
||||
}
|
||||
@@ -513,3 +524,11 @@ func cleanupExpiredJWTTokens() {
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
func getSigningKey(signingPassphrase string) []byte {
|
||||
if signingPassphrase != "" {
|
||||
sk := sha256.Sum256([]byte(signingPassphrase))
|
||||
return sk[:]
|
||||
}
|
||||
return utils.GenerateRandomBytes(32)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user