diff --git a/.drone.star b/.drone.star index 5829e0f10db..c3013c73011 100644 --- a/.drone.star +++ b/.drone.star @@ -1411,6 +1411,8 @@ def ocisServer(storage): 'KONNECTD_IDENTIFIER_REGISTRATION_CONF': '/drone/src/ocis/tests/config/drone/identifier-registration.yml', 'KONNECTD_ISS': 'https://ocis-server:9200', 'KONNECTD_TLS': 'true', + # 4 is the lowest possible value. ONLY FOR TESTS + 'ACCOUNTS_HASH_DIFFICULTY': 4, }, 'commands': [ 'apk add mailcap', # install /etc/mime.types diff --git a/accounts/pkg/config/config.go b/accounts/pkg/config/config.go index d3730f003e6..ac0b6abe866 100644 --- a/accounts/pkg/config/config.go +++ b/accounts/pkg/config/config.go @@ -42,6 +42,7 @@ type Server struct { Version string Name string AccountsDataPath string + HashDifficulty int } // Asset defines the available asset configuration. diff --git a/accounts/pkg/flagset/flagset.go b/accounts/pkg/flagset/flagset.go index 88e67f2744e..1eb93815395 100644 --- a/accounts/pkg/flagset/flagset.go +++ b/accounts/pkg/flagset/flagset.go @@ -85,6 +85,13 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag { EnvVars: []string{"ACCOUNTS_DATA_PATH"}, Destination: &cfg.Server.AccountsDataPath, }, + &cli.IntFlag{ + Name: "accounts-hash-difficulty", + Value: 11, + Usage: "accounts password hash difficulty", + EnvVars: []string{"ACCOUNTS_HASH_DIFFICULTY"}, + Destination: &cfg.Server.HashDifficulty, + }, &cli.StringFlag{ Name: "asset-path", Value: "", diff --git a/accounts/pkg/service/v0/accounts.go b/accounts/pkg/service/v0/accounts.go index 3e8fc06d24a..2d88c313f4e 100644 --- a/accounts/pkg/service/v0/accounts.go +++ b/accounts/pkg/service/v0/accounts.go @@ -3,6 +3,7 @@ package service import ( "context" "fmt" + "golang.org/x/crypto/bcrypt" "path" "regexp" "strconv" @@ -24,15 +25,8 @@ import ( settings "github.com/owncloud/ocis/settings/pkg/proto/v0" settings_svc "github.com/owncloud/ocis/settings/pkg/service/v0" "github.com/rs/zerolog" - "github.com/tredoe/osutil/user/crypt" "google.golang.org/genproto/protobuf/field_mask" "google.golang.org/protobuf/types/known/timestamppb" - - // register crypt functions - _ "github.com/tredoe/osutil/user/crypt/apr1_crypt" - _ "github.com/tredoe/osutil/user/crypt/md5_crypt" - _ "github.com/tredoe/osutil/user/crypt/sha256_crypt" - _ "github.com/tredoe/osutil/user/crypt/sha512_crypt" ) // accLock mutually exclude readers from writers on account files @@ -317,11 +311,13 @@ func (s Service) CreateAccount(ctx context.Context, in *proto.CreateAccountReque if out.PasswordProfile != nil { if out.PasswordProfile.Password != "" { // encrypt password - c := crypt.New(crypt.SHA512) - if out.PasswordProfile.Password, err = c.Generate([]byte(out.PasswordProfile.Password), nil); err != nil { + hashed, err := bcrypt.GenerateFromPassword([]byte(in.Account.PasswordProfile.Password), s.Config.Server.HashDifficulty) + if err != nil { s.log.Error().Err(err).Str("id", id).Msg("could not hash password") return merrors.InternalServerError(s.id, "could not hash password: %v", err.Error()) } + out.PasswordProfile.Password = string(hashed) + in.Account.PasswordProfile.Password = "" } if err := passwordPoliciesValid(out.PasswordProfile.PasswordPolicies); err != nil { @@ -499,13 +495,13 @@ func (s Service) UpdateAccount(ctx context.Context, in *proto.UpdateAccountReque } if in.Account.PasswordProfile.Password != "" { // encrypt password - c := crypt.New(crypt.SHA512) - if out.PasswordProfile.Password, err = c.Generate([]byte(in.Account.PasswordProfile.Password), nil); err != nil { + hashed, err := bcrypt.GenerateFromPassword([]byte(in.Account.PasswordProfile.Password), s.Config.Server.HashDifficulty) + if err != nil { in.Account.PasswordProfile.Password = "" s.log.Error().Err(err).Str("id", id).Msg("could not hash password") return merrors.InternalServerError(s.id, "could not hash password: %v", err.Error()) } - + out.PasswordProfile.Password = string(hashed) in.Account.PasswordProfile.Password = "" } @@ -805,6 +801,5 @@ func isPasswordValid(logger log.Logger, hash string, pwd string) (ok bool) { } }() - c := crypt.NewFromHash(hash) - return c.Verify(hash, []byte(pwd)) == nil + return bcrypt.CompareHashAndPassword([]byte(hash), []byte(pwd)) == nil } diff --git a/accounts/pkg/service/v0/service.go b/accounts/pkg/service/v0/service.go index 231568d4459..889be2536c8 100644 --- a/accounts/pkg/service/v0/service.go +++ b/accounts/pkg/service/v0/service.go @@ -153,7 +153,7 @@ func (s Service) createDefaultAccounts() (err error) { UidNumber: 20000, GidNumber: 30000, PasswordProfile: &proto.PasswordProfile{ - Password: "$6$rounds=35210$sa1u5Pmfo4cr23Vw$RJNGElaDB1D3xorWkfTEGm2Ko.o2QL3E0cimKx23MNxVWVFSkUUeRoC7FqC4RzYDNQBD6cKzovTEaDD.8TDkD.", + Password: "$2a$11$4WNffzgU/WrIRiDnwu8OnOwgOIIUqR/2Ptvp7WJAQCTSgSrylyuvC", }, AccountEnabled: true, MemberOf: []*proto.Group{ @@ -172,7 +172,7 @@ func (s Service) createDefaultAccounts() (err error) { UidNumber: 20001, GidNumber: 30000, PasswordProfile: &proto.PasswordProfile{ - Password: "$6$rounds=81434$sa1u5Pmfo4cr23Vw$W78cyL884GmuvDpxYPvSRBVzEj02T5QhTTcI8Dv4IKvMooDFGv4bwaWMkH9HfJ0wgpEBW7Lp.4Cad0xE/MYSg1", + Password: "$2a$11$Wu2XcDnE6G2No8C88FVWluNHyXuQQi0cHzSe82Vni8AdwIO12fphC", }, AccountEnabled: true, MemberOf: []*proto.Group{ @@ -191,7 +191,7 @@ func (s Service) createDefaultAccounts() (err error) { UidNumber: 20002, GidNumber: 30000, PasswordProfile: &proto.PasswordProfile{ - Password: "$6$rounds=5524$sa1u5Pmfo4cr23Vw$58bQVL/JeUlwM0RY21YKAFMvKvwKLLysGllYXox.vwKT5dHMwdzJjCxwTDMnB2o2pwexC8o/iOXyP2zrhALS40", + Password: "$2a$11$6Lak4zh1xUkpObg2rrOotOTdQYGj2Uu/sowcVLhub.8qYIr.CxzEW", }, AccountEnabled: true, MemberOf: []*proto.Group{ @@ -211,7 +211,7 @@ func (s Service) createDefaultAccounts() (err error) { UidNumber: 20003, GidNumber: 30000, PasswordProfile: &proto.PasswordProfile{ - Password: "$6$rounds=47068$lhw6odzXW0LTk/ao$GgxS.pIgP8jawLJBAiyNor2FrWzrULF95PwspRkli2W3VF.4HEwTYlQfRXbNQBMjNCEcEYlgZo3a.kRz2k2N0/", + Password: "$2a$11$jvI6PHuvrimpcCHzL2Q2WOqfm1FGdYAuSYZBDahr/B48fpiFxyDy2", }, AccountEnabled: true, MemberOf: []*proto.Group{ @@ -227,7 +227,7 @@ func (s Service) createDefaultAccounts() (err error) { UidNumber: 20004, GidNumber: 30000, PasswordProfile: &proto.PasswordProfile{ - Password: "$6$rounds=95551$/bdqsmiGleA20kAS$rCAvHV7wjaHVF5nEVAnpW7mugRqcnPmdU4UPqhSroE74gXFxNGZflCF.ZyHwocDwgAw3uLkqsCzB1h5bXBjYB0", + Password: "$2a$11$En9VIUtqOdDyUl.LuUq2KeuBb5A2n8zE0lkJ2v6IDRSaOamhNq6Uu", }, AccountEnabled: true, MemberOf: []*proto.Group{ @@ -244,7 +244,7 @@ func (s Service) createDefaultAccounts() (err error) { UidNumber: 10000, GidNumber: 15000, PasswordProfile: &proto.PasswordProfile{ - Password: "$6$rounds=9746$sa1u5Pmfo4cr23Vw$2hnwpkTvUkWX0v6mh8Aw1pbzEXa9EUJzmrey4g2W/8arwWCwhteqU//3aWnA3S0d5T21fOKYteoqlsN1IbTcN.", + Password: "$2a$11$ntoTP2W/kyQIuoYpH5mRBuNzaEERYWSwn/zCsY5rtffen4d41y9.6", }, AccountEnabled: true, MemberOf: []*proto.Group{ @@ -260,7 +260,7 @@ func (s Service) createDefaultAccounts() (err error) { UidNumber: 10001, GidNumber: 15000, PasswordProfile: &proto.PasswordProfile{ - Password: "$6$rounds=91087$sa1u5Pmfo4cr23Vw$wPC3BbMTbP/ytlo0p.f99zJifyO70AUCdKIK9hkhwutBKGCirLmZs/MsWAG6xHjVvmnmHN5NoON7FUGv5pPaN.", + Password: "$2a$11$40xzy3rO8Tq4j2VkFbKz8Ow19BRaqaixEjAR0IbvQXxtOvMtkjwzy", }, AccountEnabled: true, MemberOf: []*proto.Group{ diff --git a/changelog/unreleased/change-hashing-algorithm.md b/changelog/unreleased/change-hashing-algorithm.md new file mode 100644 index 00000000000..b9a0f8ffef6 --- /dev/null +++ b/changelog/unreleased/change-hashing-algorithm.md @@ -0,0 +1,7 @@ +Change: Use bcrypt to hash the user passwords + +Change the hashing algorithm from SHA-512 to bcrypt since the latter is better suitable for password hashing. +This is a breaking change. Existing deployments need to regenerate the accounts folder. + + +https://github.com/owncloud/ocis/issues/510