Encrypt LDAP bind password in db with SECRET_KEY (#15547)
* Encrypt LDAP bind password in db with SECRET_KEY The LDAP source bind password are currently stored in plaintext in the db This PR simply encrypts them with the setting.SECRET_KEY. Fix #15460 Signed-off-by: Andrew Thornton <art27@cantab.net> * remove ui warning regarding unencrypted password Co-authored-by: silverwind <me@silverwind.io>release/v1.15
parent
124b256c53
commit
17be645498
|
@ -88,8 +88,8 @@ Adds the following fields:
|
||||||
- Bind Password (optional)
|
- Bind Password (optional)
|
||||||
|
|
||||||
- The password for the Bind DN specified above, if any. _Note: The password
|
- The password for the Bind DN specified above, if any. _Note: The password
|
||||||
is stored in plaintext at the server. As such, ensure that the Bind DN
|
is stored encrypted with the SECRET_KEY on the server. It is still recommended
|
||||||
has as few privileges as possible._
|
to ensure that the Bind DN has as few privileges as possible._
|
||||||
|
|
||||||
- User Search Base **(required)**
|
- User Search Base **(required)**
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ import (
|
||||||
"code.gitea.io/gitea/modules/auth/oauth2"
|
"code.gitea.io/gitea/modules/auth/oauth2"
|
||||||
"code.gitea.io/gitea/modules/auth/pam"
|
"code.gitea.io/gitea/modules/auth/pam"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
"code.gitea.io/gitea/modules/secret"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
@ -77,11 +78,25 @@ type LDAPConfig struct {
|
||||||
// FromDB fills up a LDAPConfig from serialized format.
|
// FromDB fills up a LDAPConfig from serialized format.
|
||||||
func (cfg *LDAPConfig) FromDB(bs []byte) error {
|
func (cfg *LDAPConfig) FromDB(bs []byte) error {
|
||||||
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
||||||
return json.Unmarshal(bs, &cfg)
|
err := json.Unmarshal(bs, &cfg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if cfg.BindPasswordEncrypt != "" {
|
||||||
|
cfg.BindPassword, err = secret.DecryptSecret(setting.SecretKey, cfg.BindPasswordEncrypt)
|
||||||
|
cfg.BindPasswordEncrypt = ""
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToDB exports a LDAPConfig to a serialized format.
|
// ToDB exports a LDAPConfig to a serialized format.
|
||||||
func (cfg *LDAPConfig) ToDB() ([]byte, error) {
|
func (cfg *LDAPConfig) ToDB() ([]byte, error) {
|
||||||
|
var err error
|
||||||
|
cfg.BindPasswordEncrypt, err = secret.EncryptSecret(setting.SecretKey, cfg.BindPassword)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cfg.BindPassword = ""
|
||||||
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
||||||
return json.Marshal(cfg)
|
return json.Marshal(cfg)
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ type Source struct {
|
||||||
SecurityProtocol SecurityProtocol
|
SecurityProtocol SecurityProtocol
|
||||||
SkipVerify bool
|
SkipVerify bool
|
||||||
BindDN string // DN to bind with
|
BindDN string // DN to bind with
|
||||||
|
BindPasswordEncrypt string // Encrypted Bind BN password
|
||||||
BindPassword string // Bind DN password
|
BindPassword string // Bind DN password
|
||||||
UserBase string // Base search path for users
|
UserBase string // Base search path for users
|
||||||
UserDN string // Template for the DN of the user for simple auth
|
UserDN string // Template for the DN of the user for simple auth
|
||||||
|
|
|
@ -2283,7 +2283,6 @@ auths.host = Host
|
||||||
auths.port = Port
|
auths.port = Port
|
||||||
auths.bind_dn = Bind DN
|
auths.bind_dn = Bind DN
|
||||||
auths.bind_password = Bind Password
|
auths.bind_password = Bind Password
|
||||||
auths.bind_password_helper = Warning: This password is stored in plain text. Use a read-only account if possible.
|
|
||||||
auths.user_base = User Search Base
|
auths.user_base = User Search Base
|
||||||
auths.user_dn = User DN
|
auths.user_dn = User DN
|
||||||
auths.attribute_username = Username Attribute
|
auths.attribute_username = Username Attribute
|
||||||
|
|
|
@ -53,7 +53,6 @@
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="bind_password">{{.i18n.Tr "admin.auths.bind_password"}}</label>
|
<label for="bind_password">{{.i18n.Tr "admin.auths.bind_password"}}</label>
|
||||||
<input id="bind_password" name="bind_password" type="password" value="{{$cfg.BindPassword}}">
|
<input id="bind_password" name="bind_password" type="password" value="{{$cfg.BindPassword}}">
|
||||||
<p class="help text red">{{.i18n.Tr "admin.auths.bind_password_helper"}}</p>
|
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
<div class="{{if .Source.IsLDAP}}required{{end}} field">
|
<div class="{{if .Source.IsLDAP}}required{{end}} field">
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
<div class="ldap field {{if not (eq .type 2)}}hide{{end}}">
|
<div class="ldap field {{if not (eq .type 2)}}hide{{end}}">
|
||||||
<label for="bind_password">{{.i18n.Tr "admin.auths.bind_password"}}</label>
|
<label for="bind_password">{{.i18n.Tr "admin.auths.bind_password"}}</label>
|
||||||
<input id="bind_password" name="bind_password" type="password" autocomplete="off" value="{{.bind_password}}">
|
<input id="bind_password" name="bind_password" type="password" autocomplete="off" value="{{.bind_password}}">
|
||||||
<p class="help text red">{{.i18n.Tr "admin.auths.bind_password_helper"}}</p>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="binddnrequired {{if (eq .type 2)}}required{{end}} field">
|
<div class="binddnrequired {{if (eq .type 2)}}required{{end}} field">
|
||||||
<label for="user_base">{{.i18n.Tr "admin.auths.user_base"}}</label>
|
<label for="user_base">{{.i18n.Tr "admin.auths.user_base"}}</label>
|
||||||
|
|
Loading…
Reference in New Issue