mirror of https://github.com/go-gitea/gitea.git
Revert "Add simple master key provider for secret encryption"
This reverts commit d4e84c0433
.
This commit is contained in:
parent
b54f148164
commit
88e813d1ca
|
@ -5,14 +5,10 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"code.gitea.io/gitea/modules/generate"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/services/secrets"
|
||||
|
||||
"github.com/mattn/go-isatty"
|
||||
"github.com/urfave/cli"
|
||||
|
@ -35,7 +31,6 @@ var (
|
|||
microcmdGenerateInternalToken,
|
||||
microcmdGenerateLfsJwtSecret,
|
||||
microcmdGenerateSecretKey,
|
||||
microcmdGenerateMasterKey,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -57,12 +52,6 @@ var (
|
|||
Usage: "Generate a new SECRET_KEY",
|
||||
Action: runGenerateSecretKey,
|
||||
}
|
||||
|
||||
microcmdGenerateMasterKey = cli.Command{
|
||||
Name: "MASTER_KEY",
|
||||
Usage: "Generate a new MASTER_KEY",
|
||||
Action: runGenerateMasterKey,
|
||||
}
|
||||
)
|
||||
|
||||
func runGenerateInternalToken(c *cli.Context) error {
|
||||
|
@ -109,43 +98,3 @@ func runGenerateSecretKey(c *cli.Context) error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func runGenerateMasterKey(c *cli.Context) error {
|
||||
// Silence the console logger
|
||||
log.DelNamedLogger("console")
|
||||
log.DelNamedLogger(log.DEFAULT)
|
||||
|
||||
// Read configuration file
|
||||
setting.LoadFromExisting()
|
||||
|
||||
providerType := secrets.MasterKeyProviderType(setting.MasterKeyProvider)
|
||||
if providerType == secrets.MasterKeyProviderTypeNone {
|
||||
return fmt.Errorf("configured master key provider does not support key generation")
|
||||
}
|
||||
|
||||
if err := secrets.Init(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
scrts, err := secrets.GenerateMasterKey()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(scrts) > 1 {
|
||||
fmt.Println("Unseal secrets:")
|
||||
for i, secret := range scrts {
|
||||
if i > 0 {
|
||||
fmt.Printf("\n")
|
||||
}
|
||||
fmt.Printf("%s\n", base64.StdEncoding.EncodeToString(secret))
|
||||
}
|
||||
}
|
||||
fmt.Println("Setting changes required:")
|
||||
fmt.Println("[secrets]")
|
||||
if providerType == secrets.MasterKeyProviderTypePlain && len(scrts) == 1 {
|
||||
fmt.Printf("MASTER_KEY = %s\n", base64.StdEncoding.EncodeToString(scrts[0]))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -66,8 +66,3 @@ func NewSecretKey() (string, error) {
|
|||
|
||||
return secretKey, nil
|
||||
}
|
||||
|
||||
// NewMasterKey generate a new value intended to be used by MASTER_KEY.
|
||||
func NewMasterKey() ([]byte, error) {
|
||||
return util.CryptoRandomBytes(32)
|
||||
}
|
||||
|
|
|
@ -216,8 +216,6 @@ var (
|
|||
HMACKey string `ini:"HMAC_KEY"`
|
||||
Allways bool
|
||||
}{}
|
||||
MasterKeyProvider string
|
||||
MasterKey []byte
|
||||
|
||||
// UI settings
|
||||
UI = struct {
|
||||
|
@ -977,19 +975,6 @@ func loadFromConf(allowEmpty bool, extraConfig string) {
|
|||
PasswordCheckPwn = sec.Key("PASSWORD_CHECK_PWN").MustBool(false)
|
||||
SuccessfulTokensCacheSize = sec.Key("SUCCESSFUL_TOKENS_CACHE_SIZE").MustInt(20)
|
||||
|
||||
// Master key provider configuration
|
||||
MasterKeyProvider = sec.Key("MASTER_KEY_PROVIDER").MustString("plain")
|
||||
switch MasterKeyProvider {
|
||||
case "plain":
|
||||
tempSalt := []byte{'g', 'i', 't', 'e', 'a'}
|
||||
MasterKey = []byte(sec.Key("MASTER_KEY").MustString(SecretKey))
|
||||
MasterKey = pbkdf2.Key(MasterKey, tempSalt, 4096, 32, sha1.New)
|
||||
case "none":
|
||||
default:
|
||||
log.Fatal("invalid master key provider type: %v", MasterKeyProvider)
|
||||
return
|
||||
}
|
||||
|
||||
InternalToken = loadSecret(sec, "INTERNAL_TOKEN_URI", "INTERNAL_TOKEN")
|
||||
if InstallLock && InternalToken == "" {
|
||||
// if Gitea has been installed but the InternalToken hasn't been generated (upgrade from an old release), we should generate
|
||||
|
|
|
@ -78,11 +78,6 @@ func GetInclude(field reflect.StructField) string {
|
|||
return getRuleBody(field, "Include(")
|
||||
}
|
||||
|
||||
// GetIn get allowed values in form tag
|
||||
func GetIn(field reflect.StructField) string {
|
||||
return getRuleBody(field, "In(")
|
||||
}
|
||||
|
||||
// Validate validate TODO:
|
||||
func Validate(errs binding.Errors, data map[string]interface{}, f Form, l translation.Locale) binding.Errors {
|
||||
if errs.Len() == 0 {
|
||||
|
@ -135,8 +130,6 @@ func Validate(errs binding.Errors, data map[string]interface{}, f Form, l transl
|
|||
data["ErrorMsg"] = trName + l.Tr("form.url_error", errs[0].Message)
|
||||
case binding.ERR_INCLUDE:
|
||||
data["ErrorMsg"] = trName + l.Tr("form.include_error", GetInclude(field))
|
||||
case binding.ERR_IN:
|
||||
data["ErrorMsg"] = trName + l.Tr("form.in_error", strings.Join(strings.Split(GetIn(field), ","), ", "))
|
||||
case validation.ErrGlobPattern:
|
||||
data["ErrorMsg"] = trName + l.Tr("form.glob_pattern_error", errs[0].Message)
|
||||
case validation.ErrRegexPattern:
|
||||
|
|
|
@ -185,12 +185,6 @@ app_url_helper = Base address for HTTP(S) clone URLs and email notifications.
|
|||
log_root_path = Log Path
|
||||
log_root_path_helper = Log files will be written to this directory.
|
||||
|
||||
security_title = Security Settings
|
||||
master_key_provider = Master Key Provider
|
||||
master_key_provider_none = None
|
||||
master_key_provider_plain = Plain
|
||||
master_key_provider_helper = Master Key Provider to use to store secret key that will be used for other secret encryption. Use "None" to not encrypt secrets. Use "Plain" to store automatically generated secret in configuration file.
|
||||
|
||||
optional_title = Optional Settings
|
||||
email_title = Email Settings
|
||||
smtp_addr = SMTP Host
|
||||
|
@ -251,7 +245,6 @@ password_algorithm = Password Hash Algorithm
|
|||
password_algorithm_helper = Set the password hashing algorithm. Algorithms have differing requirements and strength. `argon2` whilst having good characteristics uses a lot of memory and may be inappropriate for small systems.
|
||||
enable_update_checker = Enable Update Checker
|
||||
enable_update_checker_helper = Checks for new version releases periodically by connecting to gitea.io.
|
||||
master_key_failed = Failed to generate master key: %v
|
||||
|
||||
[home]
|
||||
uname_holder = Username or Email Address
|
||||
|
@ -473,7 +466,6 @@ max_size_error = ` must contain at most %s characters.`
|
|||
email_error = ` is not a valid email address.`
|
||||
url_error = `'%s' is not a valid URL.`
|
||||
include_error = ` must contain substring '%s'.`
|
||||
in_error = ` can contain only specific values: %s.`
|
||||
glob_pattern_error = ` glob pattern is invalid: %s.`
|
||||
regex_pattern_error = ` regex pattern is invalid: %s.`
|
||||
username_error = ` can only contain alphanumeric chars ('0-9','a-z','A-Z'), dash ('-'), underscore ('_') and dot ('.'). It cannot begin or end with non-alphanumeric chars, and consecutive non-alphanumeric chars are also forbidden.`
|
||||
|
|
|
@ -6,7 +6,6 @@ package install
|
|||
|
||||
import (
|
||||
goctx "context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
|
@ -34,7 +33,6 @@ import (
|
|||
"code.gitea.io/gitea/modules/web"
|
||||
"code.gitea.io/gitea/modules/web/middleware"
|
||||
"code.gitea.io/gitea/services/forms"
|
||||
"code.gitea.io/gitea/services/secrets"
|
||||
|
||||
"gitea.com/go-chi/session"
|
||||
"gopkg.in/ini.v1"
|
||||
|
@ -164,7 +162,6 @@ func Install(ctx *context.Context) {
|
|||
form.DefaultEnableTimetracking = setting.Service.DefaultEnableTimetracking
|
||||
form.NoReplyAddress = setting.Service.NoReplyAddress
|
||||
form.PasswordAlgorithm = setting.PasswordHashAlgo
|
||||
form.MasterKeyProvider = secrets.MasterKeyProviderTypePlain
|
||||
|
||||
middleware.AssignForm(form, ctx.Data)
|
||||
ctx.HTML(http.StatusOK, tplInstall)
|
||||
|
@ -390,40 +387,10 @@ func SubmitInstall(ctx *context.Context) {
|
|||
log.Error("Failed to load custom conf '%s': %v", setting.CustomConf, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Setup master key provider
|
||||
cfg.Section("security").Key("MASTER_KEY_PROVIDER").SetValue(string(form.MasterKeyProvider))
|
||||
var provider secrets.MasterKeyProvider
|
||||
switch form.MasterKeyProvider {
|
||||
case secrets.MasterKeyProviderTypePlain:
|
||||
provider = secrets.NewPlainMasterKeyProvider()
|
||||
}
|
||||
var masterKey []byte
|
||||
if provider != nil {
|
||||
if err = provider.Init(); err != nil {
|
||||
ctx.RenderWithErr(ctx.Tr("install.master_key_failed", err), tplInstall, &form)
|
||||
return
|
||||
}
|
||||
// Generate master key
|
||||
if _, err = provider.GenerateMasterKey(); err != nil {
|
||||
ctx.RenderWithErr(ctx.Tr("install.master_key_failed", err), tplInstall, &form)
|
||||
return
|
||||
}
|
||||
masterKey, err = provider.GetMasterKey()
|
||||
if err != nil {
|
||||
ctx.RenderWithErr(ctx.Tr("install.master_key_failed", err), tplInstall, &form)
|
||||
return
|
||||
}
|
||||
if form.MasterKeyProvider == secrets.MasterKeyProviderTypePlain {
|
||||
cfg.Section("security").Key("MASTER_KEY").SetValue(base64.StdEncoding.EncodeToString(masterKey))
|
||||
}
|
||||
}
|
||||
|
||||
cfg.Section("database").Key("DB_TYPE").SetValue(setting.Database.Type)
|
||||
cfg.Section("database").Key("HOST").SetValue(setting.Database.Host)
|
||||
cfg.Section("database").Key("NAME").SetValue(setting.Database.Name)
|
||||
cfg.Section("database").Key("USER").SetValue(setting.Database.User)
|
||||
// TODO: Encrypt secret
|
||||
cfg.Section("database").Key("PASSWD").SetValue(setting.Database.Passwd)
|
||||
cfg.Section("database").Key("SCHEMA").SetValue(setting.Database.Schema)
|
||||
cfg.Section("database").Key("SSL_MODE").SetValue(setting.Database.SSLMode)
|
||||
|
@ -465,7 +432,6 @@ func SubmitInstall(ctx *context.Context) {
|
|||
cfg.Section("mailer").Key("SMTP_PORT").SetValue(form.SMTPPort)
|
||||
cfg.Section("mailer").Key("FROM").SetValue(form.SMTPFrom)
|
||||
cfg.Section("mailer").Key("USER").SetValue(form.SMTPUser)
|
||||
// TODO: Encrypt secret
|
||||
cfg.Section("mailer").Key("PASSWD").SetValue(form.SMTPPasswd)
|
||||
} else {
|
||||
cfg.Section("mailer").Key("ENABLED").SetValue("false")
|
||||
|
|
|
@ -13,7 +13,6 @@ import (
|
|||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/web/middleware"
|
||||
"code.gitea.io/gitea/services/secrets"
|
||||
|
||||
"gitea.com/go-chi/binding"
|
||||
)
|
||||
|
@ -64,7 +63,6 @@ type InstallForm struct {
|
|||
NoReplyAddress string
|
||||
|
||||
PasswordAlgorithm string
|
||||
MasterKeyProvider secrets.MasterKeyProviderType `binding:"Required;In(none,plain)"`
|
||||
|
||||
AdminName string `binding:"OmitEmpty;Username;MaxSize(30)" locale:"install.admin_name"`
|
||||
AdminPasswd string `binding:"OmitEmpty;MaxSize(255)" locale:"install.admin_password"`
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package secrets
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// ErrMasterKeySealed is returned when trying to use master key that is sealed
|
||||
var ErrMasterKeySealed = fmt.Errorf("master key sealed")
|
||||
|
||||
// MasterKeyProvider provides master key used for encryption
|
||||
type MasterKeyProvider interface {
|
||||
Init() error
|
||||
|
||||
GenerateMasterKey() ([][]byte, error)
|
||||
|
||||
Unseal(secret []byte) error
|
||||
|
||||
Seal() error
|
||||
|
||||
IsSealed() bool
|
||||
|
||||
GetMasterKey() ([]byte, error)
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package secrets
|
||||
|
||||
type nopMasterKeyProvider struct{}
|
||||
|
||||
// NewNopMasterKeyProvider returns master key provider that holds no master key and is always unsealed
|
||||
func NewNopMasterKeyProvider() MasterKeyProvider {
|
||||
return &nopMasterKeyProvider{}
|
||||
}
|
||||
|
||||
// Init initializes master key provider
|
||||
func (k *nopMasterKeyProvider) Init() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GenerateMasterKey always returns empty master key
|
||||
func (k *nopMasterKeyProvider) GenerateMasterKey() ([][]byte, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Unseal master key by providing unsealing secret
|
||||
func (k *nopMasterKeyProvider) Unseal(secret []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Seal master key
|
||||
func (k *nopMasterKeyProvider) Seal() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsSealed always returns false
|
||||
func (k *nopMasterKeyProvider) IsSealed() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// GetMasterKey returns empty master key
|
||||
func (k *nopMasterKeyProvider) GetMasterKey() ([]byte, error) {
|
||||
return nil, nil
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package secrets
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/modules/generate"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
)
|
||||
|
||||
type plainMasterKeyProvider struct {
|
||||
key []byte
|
||||
}
|
||||
|
||||
// NewPlainMasterKeyProvider returns unsecured static master key provider
|
||||
func NewPlainMasterKeyProvider() MasterKeyProvider {
|
||||
return &plainMasterKeyProvider{}
|
||||
}
|
||||
|
||||
// Init initializes master key provider
|
||||
func (k *plainMasterKeyProvider) Init() error {
|
||||
return k.Unseal(nil)
|
||||
}
|
||||
|
||||
// GenerateMasterKey generates a new master key and returns secret or secrets for unsealing
|
||||
func (k *plainMasterKeyProvider) GenerateMasterKey() ([][]byte, error) {
|
||||
key, err := generate.NewMasterKey()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
k.key = key
|
||||
return [][]byte{key}, nil
|
||||
}
|
||||
|
||||
// Unseal master key by providing unsealing secret
|
||||
func (k *plainMasterKeyProvider) Unseal(secret []byte) error {
|
||||
k.key = setting.MasterKey
|
||||
return nil
|
||||
}
|
||||
|
||||
// Seal master key
|
||||
func (k *plainMasterKeyProvider) Seal() error {
|
||||
k.key = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsSealed returns if master key is sealed
|
||||
func (k *plainMasterKeyProvider) IsSealed() bool {
|
||||
return len(k.key) == 0
|
||||
}
|
||||
|
||||
// GetMasterKey returns master key
|
||||
func (k *plainMasterKeyProvider) GetMasterKey() ([]byte, error) {
|
||||
if k.IsSealed() {
|
||||
return nil, ErrMasterKeySealed
|
||||
}
|
||||
return k.key, nil
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package secrets
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
)
|
||||
|
||||
// MasterKeyProviderType is the type of master key provider
|
||||
type MasterKeyProviderType string
|
||||
|
||||
// Types of master key providers
|
||||
const (
|
||||
MasterKeyProviderTypeNone MasterKeyProviderType = "none"
|
||||
MasterKeyProviderTypePlain MasterKeyProviderType = "plain"
|
||||
)
|
||||
|
||||
var (
|
||||
masterKey MasterKeyProvider
|
||||
)
|
||||
|
||||
// Init initializes master key provider based on settings
|
||||
func Init() error {
|
||||
switch MasterKeyProviderType(setting.MasterKeyProvider) {
|
||||
case MasterKeyProviderTypeNone:
|
||||
masterKey = NewNopMasterKeyProvider()
|
||||
case MasterKeyProviderTypePlain:
|
||||
masterKey = NewPlainMasterKeyProvider()
|
||||
default:
|
||||
return fmt.Errorf("invalid master key provider %v", setting.MasterKeyProvider)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GenerateMasterKey generates a new master key and returns secret or secrets for unsealing
|
||||
func GenerateMasterKey() ([][]byte, error) {
|
||||
return masterKey.GenerateMasterKey()
|
||||
}
|
|
@ -170,22 +170,6 @@
|
|||
<span class="help">{{.locale.Tr "install.enable_update_checker_helper"}}</span>
|
||||
</div>
|
||||
|
||||
<!-- Security Settings -->
|
||||
<h4 class="ui dividing header">{{.i18n.Tr "install.security_title"}}</h4>
|
||||
|
||||
<div class="inline required field">
|
||||
<label>{{.i18n.Tr "install.master_key_provider"}}</label>
|
||||
<div class="ui selection master-key-provider dropdown">
|
||||
<input type="hidden" name="master_key_provider" value="{{if .master_key_provider}}{{.master_key_provider}}{{else}}plain{{end}}">
|
||||
<div class="text">{{.i18n.Tr "install.master_key_provider_plain"}}</div>
|
||||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||
<div class="menu">
|
||||
<div class="item" data-value="none">{{.i18n.Tr "install.master_key_provider_none"}}</div>
|
||||
<div class="item" data-value="plain">{{.i18n.Tr "install.master_key_provider_plain"}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="help">{{.i18n.Tr "install.master_key_provider_helper"}}</span>
|
||||
</div>
|
||||
|
||||
<!-- Optional Settings -->
|
||||
<h4 class="ui dividing header">{{.locale.Tr "install.optional_title"}}</h4>
|
||||
|
|
Loading…
Reference in New Issue