From 4cec5ff078f32dd50f78177875f8fa66a79dff73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kim=20=22BKC=22=20Carlb=C3=A4cker?= Date: Tue, 10 Jul 2018 06:41:52 +0200 Subject: [PATCH] Add InternalTokenURI to load/save InteralToken ... from an external file. - URI HAVE TO start with 'file:' or 'file://'. Possibility to add http/s3 support in the future. - On errors it WILL ALWAYS fall back to reading AND WRITING InternalToken to the config file! - The File HAVE TO exist to be used. Gitea WILL NOT create it for you. It can however be empty and a new token will be generated for you. --- modules/setting/setting.go | 102 ++++++++++++++++++++++++++++--------- 1 file changed, 77 insertions(+), 25 deletions(-) diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 410cdfbfb..984d07a88 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -8,6 +8,8 @@ package setting import ( "encoding/base64" "fmt" + "io" + "io/ioutil" "net" "net/mail" "net/url" @@ -924,31 +926,7 @@ func NewContext() { MinPasswordLength = sec.Key("MIN_PASSWORD_LENGTH").MustInt(6) ImportLocalPaths = sec.Key("IMPORT_LOCAL_PATHS").MustBool(false) DisableGitHooks = sec.Key("DISABLE_GIT_HOOKS").MustBool(false) - InternalToken = sec.Key("INTERNAL_TOKEN").String() - if len(InternalToken) == 0 { - InternalToken, err = generate.NewInternalToken() - if err != nil { - log.Fatal(4, "Error generate internal token: %v", err) - } - - // Save secret - cfgSave := ini.Empty() - if com.IsFile(CustomConf) { - // Keeps custom settings if there is already something. - if err := cfgSave.Append(CustomConf); err != nil { - log.Error(4, "Failed to load custom conf '%s': %v", CustomConf, err) - } - } - - cfgSave.Section("security").Key("INTERNAL_TOKEN").SetValue(InternalToken) - - if err := os.MkdirAll(filepath.Dir(CustomConf), os.ModePerm); err != nil { - log.Fatal(4, "Failed to create '%s': %v", CustomConf, err) - } - if err := cfgSave.SaveTo(CustomConf); err != nil { - log.Fatal(4, "Error saving generated JWT Secret to custom config: %v", err) - } - } + InternalToken = loadInternalToken(sec) IterateBufferSize = Cfg.Section("database").Key("ITERATE_BUFFER_SIZE").MustInt(50) LogSQL = Cfg.Section("database").Key("LOG_SQL").MustBool(true) @@ -1160,6 +1138,80 @@ func NewContext() { U2F.AppID = sec.Key("APP_ID").MustString(strings.TrimRight(AppURL, "/")) } +func loadInternalToken(sec *ini.Section) string { + uri := sec.Key("INTERNAL_TOKEN_URI").String() + if len(uri) > 0 { + tempURI, err := url.Parse(uri) + if err != nil { + log.Warn("Failed to parse INTERNAL_TOKEN_URI (%s). Falling back to INTERNAL_TOKEN: %v", uri, err) + return loadOrGenerateInternalToken(sec) + } + if tempURI.Scheme == "file" { + if !com.IsFile(tempURI.RequestURI()) { + log.Warn("INTERNAL_TOKEN_URI (%s) is not a file. Falling back to INTERNAL_TOKEN", uri) + return loadOrGenerateInternalToken(sec) + } + fp, err := os.OpenFile(tempURI.RequestURI(), os.O_RDWR, 0600) + if err != nil { + log.Error(4, "Failed to open InternalTokenURI (%s): %v", uri, err) + return loadOrGenerateInternalToken(sec) + } + defer fp.Close() + + buf, err := ioutil.ReadAll(fp) + if err != nil { + log.Error(4, "Failed to read InternalTokenURI (%s): %v", uri, err) + return loadOrGenerateInternalToken(sec) + } + // No token in the file, generate one and store it. + if len(buf) == 0 { + token, err := generate.NewInternalToken() + if err != nil { + log.Fatal(4, "Error generate internal token: %v", err) + } + if _, err := io.WriteString(fp, token); err != nil { + log.Error(4, "Error writing to InternalTokenURI (%s): %v", uri, err) + return loadOrGenerateInternalToken(sec) + } + return token + } + + return string(buf) + } + } + return loadOrGenerateInternalToken(sec) +} + +func loadOrGenerateInternalToken(sec *ini.Section) string { + var err error + token := sec.Key("INTERNAL_TOKEN").String() + if len(token) == 0 { + token, err = generate.NewInternalToken() + if err != nil { + log.Fatal(4, "Error generate internal token: %v", err) + } + + // Save secret + cfgSave := ini.Empty() + if com.IsFile(CustomConf) { + // Keeps custom settings if there is already something. + if err := cfgSave.Append(CustomConf); err != nil { + log.Error(4, "Failed to load custom conf '%s': %v", CustomConf, err) + } + } + + cfgSave.Section("security").Key("INTERNAL_TOKEN").SetValue(token) + + if err := os.MkdirAll(filepath.Dir(CustomConf), os.ModePerm); err != nil { + log.Fatal(4, "Failed to create '%s': %v", CustomConf, err) + } + if err := cfgSave.SaveTo(CustomConf); err != nil { + log.Fatal(4, "Error saving generated JWT Secret to custom config: %v", err) + } + } + return token +} + // Service settings var Service struct { ActiveCodeLives int