diff --git a/common/protocol_test.go b/common/protocol_test.go index f89c8112..ad2f3968 100644 --- a/common/protocol_test.go +++ b/common/protocol_test.go @@ -496,15 +496,19 @@ func TestHiddenPatternFilter(t *testing.T) { assert.NoError(t, err) dirName := "beta" + subDirName := "testDir" testFile := filepath.Join(u.GetHomeDir(), deniedDir, "file.txt") testFile1 := filepath.Join(u.GetHomeDir(), deniedDir, "beta.txt") + testHiddenFile := filepath.Join(u.GetHomeDir(), deniedDir, dirName, subDirName, "hidden.jpg") err = os.MkdirAll(filepath.Join(u.GetHomeDir(), deniedDir), os.ModePerm) assert.NoError(t, err) err = os.WriteFile(testFile, testFileContent, os.ModePerm) assert.NoError(t, err) err = os.WriteFile(testFile1, testFileContent, os.ModePerm) assert.NoError(t, err) - err = os.MkdirAll(filepath.Join(u.GetHomeDir(), deniedDir, dirName), os.ModePerm) + err = os.MkdirAll(filepath.Join(u.GetHomeDir(), deniedDir, dirName, subDirName), os.ModePerm) + assert.NoError(t, err) + err = os.WriteFile(testHiddenFile, testFileContent, os.ModePerm) assert.NoError(t, err) conn, client, err := getSftpClient(user) @@ -529,6 +533,10 @@ func TestHiddenPatternFilter(t *testing.T) { assert.ErrorIs(t, err, os.ErrPermission) err = writeSFTPFile(path.Join(deniedDir, "afile.txt"), 1024, client) assert.ErrorIs(t, err, os.ErrPermission) + err = writeSFTPFile(path.Join(deniedDir, dirName, subDirName, "afile.jpg"), 1024, client) + assert.ErrorIs(t, err, os.ErrPermission) + _, err = client.Open(path.Join(deniedDir, dirName, subDirName, filepath.Base(testHiddenFile))) + assert.ErrorIs(t, err, os.ErrNotExist) err = client.Symlink(path.Join(deniedDir, dirName), dirName) assert.ErrorIs(t, err, os.ErrNotExist) err = writeSFTPFile(path.Join(deniedDir, testFileName), 1024, client) @@ -568,6 +576,12 @@ func TestHiddenPatternFilter(t *testing.T) { assert.ErrorIs(t, err, os.ErrPermission) err = client.Symlink(path.Join(deniedDir, testFileName), path.Join(deniedDir, "link.txt")) assert.ErrorIs(t, err, os.ErrPermission) + err = writeSFTPFile(path.Join(deniedDir, dirName, subDirName, "afile.jpg"), 1024, client) + assert.NoError(t, err) + f, err := client.Open(path.Join(deniedDir, dirName, subDirName, filepath.Base(testHiddenFile))) + assert.NoError(t, err) + err = f.Close() + assert.NoError(t, err) } _, err = httpdtest.RemoveUser(user, http.StatusOK) diff --git a/dataprovider/user.go b/dataprovider/user.go index 2c26f41f..de130246 100644 --- a/dataprovider/user.go +++ b/dataprovider/user.go @@ -854,10 +854,32 @@ func (u *User) getPatternsFilterForPath(virtualPath string) sdk.PatternsFilter { return filter } +func (u *User) isDirHidden(virtualPath string) bool { + if len(u.Filters.FilePatterns) == 0 { + return false + } + for _, dirPath := range util.GetDirsForVirtualPath(virtualPath) { + if dirPath == "/" { + return false + } + filter := u.getPatternsFilterForPath(dirPath) + if filter.DenyPolicy == sdk.DenyPolicyHide { + if !filter.CheckAllowed(path.Base(dirPath)) { + return true + } + } + } + return false +} + // IsFileAllowed returns true if the specified file is allowed by the file restrictions filters. // The second parameter returned is the deny policy func (u *User) IsFileAllowed(virtualPath string) (bool, int) { - filter := u.getPatternsFilterForPath(path.Dir(virtualPath)) + dirPath := path.Dir(virtualPath) + if u.isDirHidden(dirPath) { + return false, sdk.DenyPolicyHide + } + filter := u.getPatternsFilterForPath(dirPath) return filter.CheckAllowed(path.Base(virtualPath)), filter.DenyPolicy }