Allow specifying SECRET_KEY_URI, similar to INTERNAL_TOKEN_URI (#19663)

Only load SECRET_KEY and INTERNAL_TOKEN if they exist.
Never write the config file if the keys do not exist, which was only a fallback for Gitea upgraded from < 1.5

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
Clar Fon 2022-10-01 13:26:33 -04:00 committed by GitHub
parent 04e97b8311
commit 3d10193be2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 52 additions and 51 deletions

View file

@ -62,7 +62,7 @@ func newLFSService() {
}
// Save secret
CreateOrAppendToCustomConf(func(cfg *ini.File) {
CreateOrAppendToCustomConf("server.LFS_JWT_SECRET", func(cfg *ini.File) {
cfg.Section("server").Key("LFS_JWT_SECRET").SetValue(LFS.JWTSecretBase64)
})
}

View file

@ -21,7 +21,6 @@ import (
"text/template"
"time"
"code.gitea.io/gitea/modules/generate"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/user"
@ -923,9 +922,15 @@ func loadFromConf(allowEmpty bool, extraConfig string) {
sec = Cfg.Section("security")
InstallLock = sec.Key("INSTALL_LOCK").MustBool(false)
SecretKey = sec.Key("SECRET_KEY").MustString("!#@FDEWREWR&*(")
LogInRememberDays = sec.Key("LOGIN_REMEMBER_DAYS").MustInt(7)
CookieUserName = sec.Key("COOKIE_USERNAME").MustString("gitea_awesome")
SecretKey = loadSecret(sec, "SECRET_KEY_URI", "SECRET_KEY")
if SecretKey == "" {
// FIXME: https://github.com/go-gitea/gitea/issues/16832
// Until it supports rotating an existing secret key, we shouldn't move users off of the widely used default value
SecretKey = "!#@FDEWREWR&*(" // nolint:gosec
}
CookieRememberName = sec.Key("COOKIE_REMEMBER_NAME").MustString("gitea_incredible")
ReverseProxyAuthUser = sec.Key("REVERSE_PROXY_AUTHENTICATION_USER").MustString("X-WEBAUTH-USER")
@ -948,11 +953,7 @@ func loadFromConf(allowEmpty bool, extraConfig string) {
PasswordCheckPwn = sec.Key("PASSWORD_CHECK_PWN").MustBool(false)
SuccessfulTokensCacheSize = sec.Key("SUCCESSFUL_TOKENS_CACHE_SIZE").MustInt(20)
InternalToken = loadInternalToken(sec)
if InstallLock && InternalToken == "" {
// if Gitea has been installed but the InternalToken hasn't been generated (upgrade from an old release), we should generate
generateSaveInternalToken()
}
InternalToken = loadSecret(sec, "INTERNAL_TOKEN_URI", "INTERNAL_TOKEN")
cfgdata := sec.Key("PASSWORD_COMPLEXITY").Strings(",")
if len(cfgdata) == 0 {
@ -1141,51 +1142,36 @@ func parseAuthorizedPrincipalsAllow(values []string) ([]string, bool) {
return authorizedPrincipalsAllow, true
}
func loadInternalToken(sec *ini.Section) string {
uri := sec.Key("INTERNAL_TOKEN_URI").String()
if uri == "" {
return sec.Key("INTERNAL_TOKEN").String()
func loadSecret(sec *ini.Section, uriKey, verbatimKey string) string {
// don't allow setting both URI and verbatim string
uri := sec.Key(uriKey).String()
verbatim := sec.Key(verbatimKey).String()
if uri != "" && verbatim != "" {
log.Fatal("Cannot specify both %s and %s", uriKey, verbatimKey)
}
// if we have no URI, use verbatim
if uri == "" {
return verbatim
}
tempURI, err := url.Parse(uri)
if err != nil {
log.Fatal("Failed to parse INTERNAL_TOKEN_URI (%s): %v", uri, err)
log.Fatal("Failed to parse %s (%s): %v", uriKey, uri, err)
}
switch tempURI.Scheme {
case "file":
buf, err := os.ReadFile(tempURI.RequestURI())
if err != nil && !os.IsNotExist(err) {
log.Fatal("Failed to open InternalTokenURI (%s): %v", uri, err)
}
// No token in the file, generate one and store it.
if len(buf) == 0 {
token, err := generate.NewInternalToken()
if err != nil {
log.Fatal("Error generate internal token: %v", err)
}
err = os.WriteFile(tempURI.RequestURI(), []byte(token), 0o600)
if err != nil {
log.Fatal("Error writing to InternalTokenURI (%s): %v", uri, err)
}
return token
if err != nil {
log.Fatal("Failed to read %s (%s): %v", uriKey, tempURI.RequestURI(), err)
}
return strings.TrimSpace(string(buf))
// only file URIs are allowed
default:
log.Fatal("Unsupported URI-Scheme %q (INTERNAL_TOKEN_URI = %q)", tempURI.Scheme, uri)
return ""
}
return ""
}
// generateSaveInternalToken generates and saves the internal token to app.ini
func generateSaveInternalToken() {
token, err := generate.NewInternalToken()
if err != nil {
log.Fatal("Error generate internal token: %v", err)
}
InternalToken = token
CreateOrAppendToCustomConf(func(cfg *ini.File) {
cfg.Section("security").Key("INTERNAL_TOKEN").SetValue(token)
})
}
// MakeAbsoluteAssetURL returns the absolute asset url prefix without a trailing slash
@ -1249,7 +1235,12 @@ func MakeManifestData(appName, appURL, absoluteAssetURL string) []byte {
// CreateOrAppendToCustomConf creates or updates the custom config.
// Use the callback to set individual values.
func CreateOrAppendToCustomConf(callback func(cfg *ini.File)) {
func CreateOrAppendToCustomConf(purpose string, callback func(cfg *ini.File)) {
if CustomConf == "" {
log.Error("Custom config path must not be empty")
return
}
cfg := ini.Empty()
isFile, err := util.IsFile(CustomConf)
if err != nil {
@ -1264,8 +1255,6 @@ func CreateOrAppendToCustomConf(callback func(cfg *ini.File)) {
callback(cfg)
log.Info("Settings saved to: %q", CustomConf)
if err := os.MkdirAll(filepath.Dir(CustomConf), os.ModePerm); err != nil {
log.Fatal("failed to create '%s': %v", CustomConf, err)
return
@ -1273,6 +1262,7 @@ func CreateOrAppendToCustomConf(callback func(cfg *ini.File)) {
if err := cfg.SaveTo(CustomConf); err != nil {
log.Fatal("error saving to custom config: %v", err)
}
log.Info("Settings for %s saved to: %q", purpose, CustomConf)
// Change permissions to be more restrictive
fi, err := os.Stat(CustomConf)