Ben Chan | cb51773 | 2012-04-11 17:00:00 -0700 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium OS Authors. All rights reserved. |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
Ben Chan | 5ccd9fe | 2013-11-13 18:28:27 -0800 | [diff] [blame] | 5 | #include "cros-disks/archive_manager.h" |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 6 | |
François Degros | f76886e | 2020-07-24 18:13:40 +1000 | [diff] [blame] | 7 | #include <brillo/process/process_reaper.h> |
| 8 | #include <gmock/gmock.h> |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 9 | #include <gtest/gtest.h> |
| 10 | |
François Degros | f76886e | 2020-07-24 18:13:40 +1000 | [diff] [blame] | 11 | #include "cros-disks/metrics.h" |
| 12 | #include "cros-disks/platform.h" |
Sergei Datsenko | 87c49bb | 2021-01-13 15:08:07 +1100 | [diff] [blame] | 13 | #include "cros-disks/user.h" |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 14 | |
François Degros | f76886e | 2020-07-24 18:13:40 +1000 | [diff] [blame] | 15 | namespace cros_disks { |
| 16 | namespace { |
| 17 | |
| 18 | using testing::_; |
| 19 | using testing::DoAll; |
| 20 | using testing::Invoke; |
| 21 | using testing::IsEmpty; |
| 22 | using testing::Return; |
| 23 | using testing::SetArgPointee; |
| 24 | using testing::UnorderedElementsAre; |
| 25 | |
| 26 | const char kMountRootDirectory[] = "/my_mount_point"; |
| 27 | |
| 28 | // Mock Platform implementation for testing. |
| 29 | class MockPlatform : public Platform { |
| 30 | public: |
| 31 | MOCK_METHOD(bool, |
| 32 | GetUserAndGroupId, |
| 33 | (const std::string&, uid_t*, gid_t*), |
| 34 | (const, override)); |
| 35 | MOCK_METHOD(bool, |
| 36 | GetGroupId, |
| 37 | (const std::string&, gid_t*), |
| 38 | (const, override)); |
| 39 | }; |
| 40 | |
Sergei Datsenko | 87c49bb | 2021-01-13 15:08:07 +1100 | [diff] [blame] | 41 | } // namespace |
| 42 | |
François Degros | f76886e | 2020-07-24 18:13:40 +1000 | [diff] [blame] | 43 | class ArchiveManagerUnderTest : public ArchiveManager { |
| 44 | public: |
| 45 | using ArchiveManager::ArchiveManager; |
| 46 | ~ArchiveManagerUnderTest() override { UnmountAll(); } |
| 47 | |
| 48 | MOCK_METHOD(bool, CanMount, (const std::string&), (const, override)); |
| 49 | MOCK_METHOD(std::unique_ptr<MountPoint>, |
| 50 | DoMount, |
| 51 | (const std::string&, |
| 52 | const std::string&, |
| 53 | const std::vector<std::string>&, |
| 54 | const base::FilePath&, |
François Degros | f76886e | 2020-07-24 18:13:40 +1000 | [diff] [blame] | 55 | MountErrorType*), |
| 56 | (override)); |
François Degros | f76886e | 2020-07-24 18:13:40 +1000 | [diff] [blame] | 57 | |
Sergei Datsenko | 87c49bb | 2021-01-13 15:08:07 +1100 | [diff] [blame] | 58 | using ArchiveManager::CreateSandboxFactory; |
| 59 | }; |
François Degros | f76886e | 2020-07-24 18:13:40 +1000 | [diff] [blame] | 60 | |
| 61 | class ArchiveManagerTest : public testing::Test { |
| 62 | protected: |
| 63 | Metrics metrics_; |
| 64 | MockPlatform platform_; |
| 65 | brillo::ProcessReaper reaper_; |
| 66 | const ArchiveManagerUnderTest manager_{kMountRootDirectory, &platform_, |
| 67 | &metrics_, &reaper_}; |
| 68 | }; |
| 69 | |
| 70 | TEST_F(ArchiveManagerTest, IsInAllowedFolder) { |
| 71 | EXPECT_FALSE(ArchiveManager::IsInAllowedFolder("")); |
| 72 | EXPECT_FALSE(ArchiveManager::IsInAllowedFolder("foo")); |
| 73 | EXPECT_FALSE(ArchiveManager::IsInAllowedFolder("/foo")); |
François Degros | 262deb9 | 2020-06-19 16:24:39 +1000 | [diff] [blame] | 74 | EXPECT_FALSE(ArchiveManager::IsInAllowedFolder("/dev/sda1")); |
François Degros | f76886e | 2020-07-24 18:13:40 +1000 | [diff] [blame] | 75 | EXPECT_TRUE(ArchiveManager::IsInAllowedFolder( |
| 76 | "/home/chronos/u-0123456789abcdef0123456789abcdef01234567/MyFiles/foo")); |
| 77 | EXPECT_TRUE(ArchiveManager::IsInAllowedFolder( |
| 78 | "/home/chronos/u-0123456789abcdef0123456789abcdef01234567/MyFiles/x/" |
| 79 | "foo")); |
| 80 | EXPECT_TRUE(ArchiveManager::IsInAllowedFolder( |
| 81 | "/home/chronos/u-0123456789abcdef0123456789abcdef01234567/MyFiles/" |
| 82 | "Downloads/foo")); |
| 83 | EXPECT_TRUE(ArchiveManager::IsInAllowedFolder( |
| 84 | "/home/chronos/u-0123456789abcdef0123456789abcdef01234567/MyFiles/" |
| 85 | "Downloads/x/foo")); |
| 86 | EXPECT_FALSE(ArchiveManager::IsInAllowedFolder( |
| 87 | "/home/chronos/u-0123456789abcdef0123456789abcdef01234567/x/foo")); |
François Degros | 262deb9 | 2020-06-19 16:24:39 +1000 | [diff] [blame] | 88 | EXPECT_FALSE( |
François Degros | f76886e | 2020-07-24 18:13:40 +1000 | [diff] [blame] | 89 | ArchiveManager::IsInAllowedFolder("/home/chronos/user/MyFiles/foo")); |
| 90 | EXPECT_FALSE(ArchiveManager::IsInAllowedFolder( |
| 91 | "/homex/chronos/u-0123456789abcdef0123456789abcdef01234567/MyFiles/" |
| 92 | "Downloads/x/foo")); |
| 93 | EXPECT_FALSE(ArchiveManager::IsInAllowedFolder( |
| 94 | "/home/chronosx/u-0123456789abcdef0123456789abcdef01234567/MyFiles/foo")); |
| 95 | EXPECT_FALSE(ArchiveManager::IsInAllowedFolder( |
| 96 | "/home/chronos/0123456789abcdef0123456789abcdef01234567/MyFiles/foo")); |
| 97 | EXPECT_FALSE(ArchiveManager::IsInAllowedFolder( |
| 98 | "/home/chronos/u-0123456789abcdef0123456789abcdef01234567x/MyFiles/foo")); |
François Degros | 262deb9 | 2020-06-19 16:24:39 +1000 | [diff] [blame] | 99 | EXPECT_FALSE( |
| 100 | ArchiveManager::IsInAllowedFolder("/home/chronos/user/Downloads/bar")); |
François Degros | 262deb9 | 2020-06-19 16:24:39 +1000 | [diff] [blame] | 101 | EXPECT_TRUE(ArchiveManager::IsInAllowedFolder( |
| 102 | "/home/chronos/u-0123456789abcdef0123456789abcdef01234567/MyFiles/" |
| 103 | "Downloads/bar")); |
François Degros | 262deb9 | 2020-06-19 16:24:39 +1000 | [diff] [blame] | 104 | EXPECT_FALSE(ArchiveManager::IsInAllowedFolder("/media/removable")); |
| 105 | EXPECT_FALSE(ArchiveManager::IsInAllowedFolder("/media/removable/")); |
| 106 | EXPECT_FALSE(ArchiveManager::IsInAllowedFolder("/media/archive")); |
| 107 | EXPECT_FALSE(ArchiveManager::IsInAllowedFolder("/media/archive/")); |
| 108 | EXPECT_FALSE( |
| 109 | ArchiveManager::IsInAllowedFolder("/home/chronos/user/Downloads")); |
| 110 | EXPECT_FALSE( |
| 111 | ArchiveManager::IsInAllowedFolder("/home/chronos/user/Downloads/")); |
François Degros | 262deb9 | 2020-06-19 16:24:39 +1000 | [diff] [blame] | 112 | EXPECT_FALSE(ArchiveManager::IsInAllowedFolder( |
Ben Chan | 16d8586 | 2013-05-28 20:30:30 -0700 | [diff] [blame] | 113 | "/home/chronos/u-0123456789abcdef0123456789abcdef01234567/Downloads")); |
François Degros | 262deb9 | 2020-06-19 16:24:39 +1000 | [diff] [blame] | 114 | EXPECT_FALSE(ArchiveManager::IsInAllowedFolder( |
Ben Chan | 16d8586 | 2013-05-28 20:30:30 -0700 | [diff] [blame] | 115 | "/home/chronos/u-0123456789abcdef0123456789abcdef01234567/Downloads/")); |
François Degros | 262deb9 | 2020-06-19 16:24:39 +1000 | [diff] [blame] | 116 | EXPECT_FALSE(ArchiveManager::IsInAllowedFolder("/home/chronos/bar")); |
| 117 | EXPECT_FALSE(ArchiveManager::IsInAllowedFolder("/home/chronos/user/bar")); |
| 118 | EXPECT_FALSE(ArchiveManager::IsInAllowedFolder( |
| 119 | "/home/chronos/u-0123456789abcdef0123456789abcdef01234567/bar")); |
Ben Chan | de0e3f6 | 2017-09-26 06:28:39 -0700 | [diff] [blame] | 120 | EXPECT_FALSE( |
François Degros | 262deb9 | 2020-06-19 16:24:39 +1000 | [diff] [blame] | 121 | ArchiveManager::IsInAllowedFolder("/home/chronos/Downloads/bar")); |
Ben Chan | de0e3f6 | 2017-09-26 06:28:39 -0700 | [diff] [blame] | 122 | EXPECT_FALSE( |
François Degros | 262deb9 | 2020-06-19 16:24:39 +1000 | [diff] [blame] | 123 | ArchiveManager::IsInAllowedFolder("/home/chronos/foo/Downloads/bar")); |
| 124 | EXPECT_FALSE( |
François Degros | 262deb9 | 2020-06-19 16:24:39 +1000 | [diff] [blame] | 125 | ArchiveManager::IsInAllowedFolder("/home/chronos/u-/Downloads/bar")); |
| 126 | EXPECT_FALSE(ArchiveManager::IsInAllowedFolder( |
| 127 | "/home/chronos/u-0123456789abcdef0123456789abcdef0123456/Downloads/bar")); |
| 128 | EXPECT_FALSE(ArchiveManager::IsInAllowedFolder( |
| 129 | "/home/chronos/u-xyz3456789abcdef0123456789abcdef01234567/Downloads/" |
| 130 | "bar")); |
François Degros | f76886e | 2020-07-24 18:13:40 +1000 | [diff] [blame] | 131 | EXPECT_TRUE(ArchiveManager::IsInAllowedFolder("/media/archive/y/foo")); |
| 132 | EXPECT_TRUE(ArchiveManager::IsInAllowedFolder("/media/fuse/y/foo")); |
| 133 | EXPECT_TRUE(ArchiveManager::IsInAllowedFolder("/media/removable/y/foo")); |
| 134 | EXPECT_FALSE(ArchiveManager::IsInAllowedFolder("/media/x/y/foo")); |
| 135 | EXPECT_FALSE(ArchiveManager::IsInAllowedFolder("/media/x/foo")); |
| 136 | EXPECT_FALSE(ArchiveManager::IsInAllowedFolder("x/media/fuse/y/foo")); |
| 137 | EXPECT_FALSE(ArchiveManager::IsInAllowedFolder("media/fuse/y/foo")); |
| 138 | EXPECT_FALSE(ArchiveManager::IsInAllowedFolder("file:///media/fuse/y/foo")); |
| 139 | EXPECT_FALSE(ArchiveManager::IsInAllowedFolder("ssh:///media/fuse/y/foo")); |
| 140 | } |
| 141 | |
| 142 | TEST_F(ArchiveManagerTest, GetMountSourceType) { |
| 143 | EXPECT_EQ(manager_.GetMountSourceType(), MOUNT_SOURCE_ARCHIVE); |
| 144 | } |
| 145 | |
| 146 | TEST_F(ArchiveManagerTest, SuggestMountPath) { |
| 147 | EXPECT_EQ(manager_.SuggestMountPath("/home/chronos/Downloads/My Doc.rar"), |
| 148 | std::string(kMountRootDirectory) + "/My Doc.rar"); |
| 149 | EXPECT_EQ(manager_.SuggestMountPath("/media/archive/Test.rar/My Doc.zip"), |
| 150 | std::string(kMountRootDirectory) + "/My Doc.zip"); |
| 151 | } |
| 152 | |
| 153 | TEST_F(ArchiveManagerTest, GetSupplementaryGroups) { |
| 154 | const gid_t gid = 478785; |
| 155 | EXPECT_CALL(platform_, GetGroupId("android-everybody", _)) |
| 156 | .WillOnce(DoAll(SetArgPointee<1>(gid), Return(true))); |
| 157 | EXPECT_THAT(manager_.GetSupplementaryGroups(), UnorderedElementsAre(gid)); |
| 158 | } |
| 159 | |
| 160 | TEST_F(ArchiveManagerTest, GetSupplementaryGroupsCannotGetGroupId) { |
| 161 | EXPECT_CALL(platform_, GetGroupId("android-everybody", _)) |
| 162 | .WillOnce(Return(false)); |
| 163 | EXPECT_THAT(manager_.GetSupplementaryGroups(), IsEmpty()); |
| 164 | } |
| 165 | |
Sergei Datsenko | 87c49bb | 2021-01-13 15:08:07 +1100 | [diff] [blame] | 166 | TEST_F(ArchiveManagerTest, CreateSandboxFactory) { |
| 167 | EXPECT_CALL(platform_, GetUserAndGroupId("fuse-zip", _, _)) |
| 168 | .WillOnce( |
| 169 | DoAll(SetArgPointee<1>(300), SetArgPointee<2>(301), Return(true))); |
| 170 | auto zip_sandbox = |
| 171 | manager_.CreateSandboxFactory({base::FilePath("/foo")}, "fuse-zip"); |
| 172 | EXPECT_EQ(kChronosAccessGID, zip_sandbox->run_as().gid); |
| 173 | EXPECT_CALL(platform_, GetUserAndGroupId("fuse-rar2fs", _, _)) |
| 174 | .WillOnce( |
| 175 | DoAll(SetArgPointee<1>(400), SetArgPointee<2>(401), Return(true))); |
| 176 | auto rar_sandbox = |
| 177 | manager_.CreateSandboxFactory({base::FilePath("/foo")}, "fuse-rar2fs"); |
| 178 | EXPECT_EQ(kChronosAccessGID, rar_sandbox->run_as().gid); |
| 179 | } |
| 180 | |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 181 | } // namespace cros_disks |