1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "dlp_file_test.h"
17
18 #include <cstring>
19 #include <dirent.h>
20 #include <fcntl.h>
21 #include <openssl/rand.h>
22 #include <securec.h>
23 #include <sys/mount.h>
24 #include <sys/stat.h>
25 #include <sys/types.h>
26 #include <thread>
27 #define private public
28 #include "dlp_file.h"
29 #undef private
30 #include "dlp_file_manager.h"
31 #include "dlp_permission.h"
32 #include "dlp_permission_log.h"
33
34 namespace OHOS {
35 namespace Security {
36 namespace DlpPermission {
37 using namespace testing::ext;
38
39 namespace {
40 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_DLP_PERMISSION, "DlpFileTest"};
41 // using for clean all link file
42 static const std::string MOUNT_POINT_DIR = "/data/fuse/";
43 static const std::string DLP_TEST_DIR = "/data/dlpTest/";
44 static const std::string FUSE_DEV = "/dev/fuse";
45 static const std::string FUSE_TYPE = "fuse";
46 static const std::string DEFAULT_CURRENT_ACCOUNT = "ohosAnonymousName";
47 static const int32_t TEST_USER_COUNT = 2;
48 static const int32_t RAND_STR_SIZE = 16;
49 static const uint8_t ARRAY_CHAR_SIZE = 62;
50 static const char CHAR_ARRAY[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
51 static const int32_t EXPIRT_TIME = 10000;
52 static int g_plainFileFd = -1;
53 static int g_dlpFileFd = -1;
54 static int g_recoveryFileFd = -1;
55 static std::shared_ptr<DlpFile> g_Dlpfile = nullptr;
56 }
57
SetUpTestCase()58 void DlpFileTest::SetUpTestCase()
59 {
60 struct stat fstat;
61 if (stat(DLP_TEST_DIR.c_str(), &fstat) != 0) {
62 if (errno == ENOENT) {
63 int32_t ret = mkdir(DLP_TEST_DIR.c_str(), S_IRWXU | S_IRWXG | S_IRWXO);
64 if (ret < 0) {
65 DLP_LOG_ERROR(LABEL, "mkdir mount point failed errno %{public}d", errno);
66 return;
67 }
68 } else {
69 DLP_LOG_ERROR(LABEL, "get mount point failed errno %{public}d", errno);
70 return;
71 }
72 }
73 }
74
TearDownTestCase()75 void DlpFileTest::TearDownTestCase()
76 {
77 int ret = umount(MOUNT_POINT_DIR.c_str());
78 DLP_LOG_INFO(LABEL, "umount ret=%{public}d error=%{public}s", ret, strerror(errno));
79 rmdir(MOUNT_POINT_DIR.c_str());
80 rmdir(DLP_TEST_DIR.c_str());
81 }
82
SetUp()83 void DlpFileTest::SetUp()
84 {}
85
TearDown()86 void DlpFileTest::TearDown()
87 {}
88
89 namespace {
GetRandNum()90 static uint8_t GetRandNum()
91 {
92 uint8_t rand;
93 RAND_bytes(reinterpret_cast<unsigned char *>(&rand), sizeof(rand));
94 return rand;
95 }
96
GenerateRandStr(uint32_t len,std::string & res)97 static void GenerateRandStr(uint32_t len, std::string& res)
98 {
99 for (uint32_t i = 0; i < len; i++) {
100 uint32_t index = GetRandNum() % ARRAY_CHAR_SIZE;
101 DLP_LOG_INFO(LABEL, "%{public}u", index);
102 res.push_back(CHAR_ARRAY[index]);
103 }
104 DLP_LOG_INFO(LABEL, "%{public}s", res.c_str());
105 }
106
GenerateRandProperty(struct DlpProperty & encProp)107 static void GenerateRandProperty(struct DlpProperty& encProp)
108 {
109 uint64_t curTime = static_cast<uint64_t>(
110 std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count());
111 encProp.ownerAccount = DEFAULT_CURRENT_ACCOUNT;
112 encProp.ownerAccountId = DEFAULT_CURRENT_ACCOUNT;
113 encProp.ownerAccountType = CLOUD_ACCOUNT;
114 for (uint32_t user = 0; user < TEST_USER_COUNT; ++user) {
115 std::string accountName;
116 GenerateRandStr(RAND_STR_SIZE, accountName);
117 AuthUserInfo perminfo = {.authAccount = accountName,
118 .authPerm = DLPFileAccess::READ_ONLY,
119 .permExpiryTime = curTime + EXPIRT_TIME,
120 .authAccountType = CLOUD_ACCOUNT};
121 encProp.authUsers.emplace_back(perminfo);
122 }
123 std::string accountName;
124 GenerateRandStr(RAND_STR_SIZE, accountName);
125 encProp.contactAccount = accountName;
126 }
127 }
128 /**
129 * @tc.name: GenerateDlpFile001
130 * @tc.desc: test dlp file generate, owner is current
131 * @tc.type: FUNC
132 * @tc.require:AR000GVIGC
133 */
134 HWTEST_F(DlpFileTest, GenerateDlpFile001, TestSize.Level0)
135 {
136 DLP_LOG_INFO(LABEL, "GenerateDlpFile001");
137
138 g_plainFileFd = open("/data/file_test.txt", O_CREAT | O_RDWR | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO);
139 g_dlpFileFd = open("/data/file_test.txt.dlp", O_CREAT | O_RDWR | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO);
140 ASSERT_GE(g_plainFileFd, 0);
141 ASSERT_GE(g_dlpFileFd, 0);
142
143 char buffer[] = "123456";
144 ASSERT_NE(write(g_plainFileFd, buffer, sizeof(buffer)), -1);
145
146 struct DlpProperty prop;
147 GenerateRandProperty(prop);
148 int32_t result = DlpFileManager::GetInstance().GenerateDlpFile(g_plainFileFd,
149 g_dlpFileFd, prop, g_Dlpfile, DLP_TEST_DIR);
150 ASSERT_EQ(result, 0);
151 ASSERT_NE(g_Dlpfile, nullptr);
152
153 g_recoveryFileFd = open("/data/fuse_test.txt.recovery", O_CREAT | O_RDWR | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO);
154 ASSERT_GE(g_recoveryFileFd, 0);
155 g_Dlpfile->authPerm_ = DLPFileAccess::FULL_CONTROL;
156 result = DlpFileManager::GetInstance().RecoverDlpFile(g_Dlpfile, g_recoveryFileFd);
157 ASSERT_EQ(result, 0);
158
159 ASSERT_NE(lseek(g_recoveryFileFd, 0, SEEK_SET), -1);
160 char buffer2[16] = {0};
161 result = read(g_recoveryFileFd, buffer2, 16);
162 ASSERT_GE(result, 0);
163 result = memcmp(buffer, buffer2, 6);
164 ASSERT_EQ(result, 0);
165 result = DlpFileManager::GetInstance().CloseDlpFile(g_Dlpfile);
166 ASSERT_EQ(result, 0);
167 g_Dlpfile = nullptr;
168 }
169
170 /**
171 * @tc.name: OpenDlpFile001
172 * @tc.desc: test dlp fuse init,fd is right
173 * @tc.type: FUNC
174 * @tc.require:AR000GVIGC
175 */
176 HWTEST_F(DlpFileTest, OpenDlpFile001, TestSize.Level0)
177 {
178 g_plainFileFd = open("/data/fuse_test.txt", O_CREAT | O_RDWR | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO);
179 g_dlpFileFd = open("/data/fuse_test.txt.dlp", O_CREAT | O_RDWR | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO);
180 ASSERT_GE(g_plainFileFd, 0);
181 ASSERT_GE(g_dlpFileFd, 0);
182 char buffer[] = "123456";
183 ASSERT_NE(write(g_plainFileFd, buffer, sizeof(buffer)), -1);
184 struct DlpProperty prop;
185 GenerateRandProperty(prop);
186 int32_t result = DlpFileManager::GetInstance().GenerateDlpFile(g_plainFileFd,
187 g_dlpFileFd, prop, g_Dlpfile, DLP_TEST_DIR);
188 ASSERT_EQ(result, 0);
189 ASSERT_NE(g_Dlpfile, nullptr);
190 result = DlpFileManager::GetInstance().CloseDlpFile(g_Dlpfile);
191 ASSERT_EQ(result, 0);
192 g_Dlpfile = nullptr;
193 result = DlpFileManager::GetInstance().OpenDlpFile(g_dlpFileFd, g_Dlpfile, DLP_TEST_DIR, "test_appId_passed");
194 ASSERT_EQ(result, 0);
195 ASSERT_NE(g_Dlpfile, nullptr);
196 PermissionPolicy policy;
197 g_Dlpfile->GetPolicy(policy);
198 ASSERT_EQ(policy.ownerAccount_, prop.ownerAccount);
199 std::vector<AuthUserInfo>& authUsers = policy.authUsers_;
200 ASSERT_EQ(authUsers.size(), prop.authUsers.size());
201 for (int32_t i = 0; i < static_cast<int32_t>(authUsers.size()); i++) {
202 for (int32_t j = 0; j < static_cast<int32_t>(prop.authUsers.size()); j++) {
203 if (authUsers[i].authAccount == prop.authUsers[j].authAccount) {
204 ASSERT_EQ(authUsers[i].authPerm, prop.authUsers[j].authPerm);
205 ASSERT_EQ(authUsers[i].authAccountType, prop.authUsers[j].authAccountType);
206 }
207 }
208 }
209 std::string contactAccount;
210 g_Dlpfile->GetContactAccount(contactAccount);
211 ASSERT_EQ(contactAccount, prop.contactAccount);
212 g_recoveryFileFd = open("/data/fuse_test.txt.recovery", O_CREAT | O_RDWR | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO);
213 ASSERT_GE(g_recoveryFileFd, 0);
214 g_Dlpfile->authPerm_ = DLPFileAccess::FULL_CONTROL;
215 ASSERT_EQ(DlpFileManager::GetInstance().RecoverDlpFile(g_Dlpfile, g_recoveryFileFd), 0);
216 lseek(g_recoveryFileFd, 0, SEEK_SET);
217 char buffer2[16] = {0};
218 ASSERT_GE(read(g_recoveryFileFd, buffer2, 16), 0);
219 result = memcmp(buffer, buffer2, result);
220 ASSERT_EQ(result, 0);
221 ASSERT_EQ(DlpFileManager::GetInstance().CloseDlpFile(g_Dlpfile), 0);
222 g_Dlpfile = nullptr;
223 }
224
225 /**
226 * @tc.name: OpenDlpFile002
227 * @tc.desc: test dlp fuse init,fd is right
228 * @tc.type: FUNC
229 * @tc.require:AR000GVIGC
230 */
231 HWTEST_F(DlpFileTest, OpenDlpFile002, TestSize.Level0)
232 {
233 g_plainFileFd = open("/data/fuse_test.txt", O_CREAT | O_RDWR | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO);
234 g_dlpFileFd = open("/data/fuse_test.txt.dlp", O_CREAT | O_RDWR | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO);
235 ASSERT_GE(g_plainFileFd, 0);
236 ASSERT_GE(g_dlpFileFd, 0);
237 char buffer[] = "123456";
238 ASSERT_NE(write(g_plainFileFd, buffer, sizeof(buffer)), -1);
239 struct DlpProperty prop;
240 GenerateRandProperty(prop);
241 prop.supportEveryone = true;
242 prop.everyonePerm = DLPFileAccess::READ_ONLY;
243 int32_t result = DlpFileManager::GetInstance().GenerateDlpFile(g_plainFileFd,
244 g_dlpFileFd, prop, g_Dlpfile, DLP_TEST_DIR);
245 ASSERT_EQ(result, 0);
246 ASSERT_NE(g_Dlpfile, nullptr);
247 result = DlpFileManager::GetInstance().CloseDlpFile(g_Dlpfile);
248 ASSERT_EQ(result, 0);
249 g_Dlpfile = nullptr;
250 std::string appId = "test_appId_passed";
251 result = DlpFileManager::GetInstance().OpenDlpFile(g_dlpFileFd, g_Dlpfile, DLP_TEST_DIR, appId);
252 ASSERT_EQ(result, 0);
253 ASSERT_NE(g_Dlpfile, nullptr);
254 PermissionPolicy policy;
255 g_Dlpfile->GetPolicy(policy);
256 ASSERT_EQ(policy.ownerAccount_, prop.ownerAccount);
257 ASSERT_EQ(policy.supportEveryone_, prop.supportEveryone);
258 ASSERT_EQ(policy.everyonePerm_, prop.everyonePerm);
259 const std::vector<AuthUserInfo>& authUsers = policy.authUsers_;
260 ASSERT_EQ(authUsers.size(), prop.authUsers.size());
261
262 std::string contactAccount;
263 g_Dlpfile->GetContactAccount(contactAccount);
264 ASSERT_EQ(contactAccount, prop.contactAccount);
265 g_recoveryFileFd = open("/data/fuse_test.txt.recovery", O_CREAT | O_RDWR | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO);
266 ASSERT_GE(g_recoveryFileFd, 0);
267 g_Dlpfile->authPerm_ = DLPFileAccess::FULL_CONTROL;
268 ASSERT_EQ(DlpFileManager::GetInstance().RecoverDlpFile(g_Dlpfile, g_recoveryFileFd), 0);
269 lseek(g_recoveryFileFd, 0, SEEK_SET);
270 char buffer2[16] = {0};
271 result = read(g_recoveryFileFd, buffer2, 16);
272 ASSERT_GE(result, 0);
273 result = memcmp(buffer, buffer2, result);
274 ASSERT_EQ(result, 0);
275 ASSERT_EQ(DlpFileManager::GetInstance().CloseDlpFile(g_Dlpfile), 0);
276 g_Dlpfile = nullptr;
277 }
278 } // namespace DlpPermission
279 } // namespace Security
280 } // namespace OHOS
281