From d6b584e0643a46ddac4ea300435155eb6a36923c Mon Sep 17 00:00:00 2001 From: Nicola Murino Date: Sun, 16 Jul 2023 16:53:43 +0200 Subject: [PATCH] shares: respect password strength Signed-off-by: Nicola Murino --- internal/dataprovider/share.go | 10 ++++++++++ internal/httpd/httpd_test.go | 13 ++++++++++++- internal/version/version.go | 2 +- openapi/openapi.yaml | 2 +- 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/internal/dataprovider/share.go b/internal/dataprovider/share.go index 76d9e2be..1ba2e5b6 100644 --- a/internal/dataprovider/share.go +++ b/internal/dataprovider/share.go @@ -22,6 +22,7 @@ import ( "time" "github.com/alexedwards/argon2id" + passwordvalidator "github.com/wagslane/go-password-validator" "golang.org/x/crypto/bcrypt" "github.com/drakkan/sftpgo/v2/internal/logger" @@ -178,6 +179,15 @@ func (s *Share) HasRedactedPassword() bool { func (s *Share) hashPassword() error { if s.Password != "" && !util.IsStringPrefixInSlice(s.Password, internalHashPwdPrefixes) { + user, err := UserExists(s.Username, "") + if err != nil { + return util.NewGenericError(fmt.Sprintf("unable to validate user: %v", err)) + } + if minEntropy := user.getMinPasswordEntropy(); minEntropy > 0 { + if err := passwordvalidator.Validate(s.Password, minEntropy); err != nil { + return util.NewValidationError(err.Error()) + } + } if config.PasswordHashing.Algo == HashingAlgoBcrypt { hashed, err := bcrypt.GenerateFromPassword([]byte(s.Password), config.PasswordHashing.BcryptOptions.Cost) if err != nil { diff --git a/internal/httpd/httpd_test.go b/internal/httpd/httpd_test.go index a90bbc6b..3ebfa670 100644 --- a/internal/httpd/httpd_test.go +++ b/internal/httpd/httpd_test.go @@ -14889,9 +14889,11 @@ func TestUserAPIShares(t *testing.T) { func TestUsersAPISharesNoPasswordDisabled(t *testing.T) { u := getTestUser() u.Filters.WebClient = []string{sdk.WebClientShareNoPasswordDisabled} + u.Filters.PasswordStrength = 70 + u.Password = "ahpoo8baa6EeZieshies" user, _, err := httpdtest.AddUser(u, http.StatusCreated) assert.NoError(t, err) - token, err := getJWTAPIUserTokenFromTestServer(defaultUsername, defaultPassword) + token, err := getJWTAPIUserTokenFromTestServer(defaultUsername, u.Password) assert.NoError(t, err) share := dataprovider.Share{ @@ -14915,6 +14917,15 @@ func TestUsersAPISharesNoPasswordDisabled(t *testing.T) { assert.NoError(t, err) setBearerForReq(req, token) rr = executeRequest(req) + checkResponseCode(t, http.StatusBadRequest, rr) + + share.Password = "vi5eiJoovee5ya9yahpi" + asJSON, err = json.Marshal(share) + assert.NoError(t, err) + req, err = http.NewRequest(http.MethodPost, userSharesPath, bytes.NewBuffer(asJSON)) + assert.NoError(t, err) + setBearerForReq(req, token) + rr = executeRequest(req) checkResponseCode(t, http.StatusCreated, rr) location := rr.Header().Get("Location") assert.NotEmpty(t, location) diff --git a/internal/version/version.go b/internal/version/version.go index be72bb97..a89942f3 100644 --- a/internal/version/version.go +++ b/internal/version/version.go @@ -17,7 +17,7 @@ package version import "strings" -const version = "2.5.4" +const version = "2.5.4-dev" var ( commit = "" diff --git a/openapi/openapi.yaml b/openapi/openapi.yaml index 1bf6c778..8ca49653 100644 --- a/openapi/openapi.yaml +++ b/openapi/openapi.yaml @@ -29,7 +29,7 @@ info: SFTPGo supports groups to simplify the administration of multiple accounts by letting you assign settings once to a group, instead of multiple times to each individual user. The SFTPGo WebClient allows end users to change their credentials, browse and manage their files in the browser and setup two-factor authentication which works with Authy, Google Authenticator and other compatible apps. From the WebClient each authorized user can also create HTTP/S links to externally share files and folders securely, by setting limits to the number of downloads/uploads, protecting the share with a password, limiting access by source IP address, setting an automatic expiration date. - version: 2.5.4 + version: 2.5.4-dev contact: name: API support url: 'https://github.com/drakkan/sftpgo'