allow to use a persistent signing key for JWT and CSRF tokens

Fixes #466
This commit is contained in:
Nicola Murino
2021-07-01 20:17:40 +02:00
parent 04001f7ad3
commit ff19879ffd
8 changed files with 86 additions and 24 deletions

View File

@@ -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)
}