1 /*
2 * Copyright (c) 2022-2024 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 "help_utils.h"
17
18 #include <cerrno>
19 #include <dirent.h>
20 #include <fcntl.h>
21 #include <mntent.h>
22 #include <sys/mount.h>
23 #include <sys/stat.h>
24 #include <unistd.h>
25
26 #include "ipc/istorage_daemon.h"
27 #include "user/user_manager.h"
28 #include "utils/file_utils.h"
29
30 namespace OHOS {
31 namespace StorageDaemon {
32 namespace StorageTest {
33 const std::string hmdfsTarget = "/storage/media/%d/local";
34 static constexpr int MODE_0711 = 0711;
35 const std::vector<Dir> StorageTestUtils::gRootDirs = {
36 {"/data/app/%s/%d", MODE_0711, OID_ROOT, OID_ROOT},
37 {"/data/service/%s/%d", MODE_0711, OID_ROOT, OID_ROOT},
38 {"/data/chipset/%s/%d", MODE_0711, OID_ROOT, OID_ROOT}
39 };
40
41 const std::vector<Dir> StorageTestUtils::gSubDirs = {
42 {"/data/app/%s/%d/base", MODE_0711, OID_ROOT, OID_ROOT},
43 {"/data/app/%s/%d/database", MODE_0711, OID_ROOT, OID_ROOT}
44 };
45
46 const std::vector<Dir> StorageTestUtils::gHmdfsDirs = {
47 {"/data/service/el2/%d/hmdfs", MODE_0711, OID_SYSTEM, OID_SYSTEM},
48 {"/data/service/el2/%d/hmdfs/files", MODE_0711, OID_SYSTEM, OID_SYSTEM},
49 {"/data/service/el2/%d/hmdfs/data", MODE_0711, OID_SYSTEM, OID_SYSTEM},
50 {"/storage/media/%d", MODE_0711, OID_ROOT, OID_ROOT},
51 {"/storage/media/%d/local", MODE_0711, OID_ROOT, OID_ROOT}
52 };
53
CheckMount(const std::string & dstPath)54 bool StorageTestUtils::CheckMount(const std::string& dstPath)
55 {
56 const std::string fileName = "/proc/mounts";
57 FILE *mntFile;
58 struct mntent *mntent = nullptr;
59
60 mntFile = setmntent(fileName.c_str(), "r");
61 if (!mntFile) {
62 return false;
63 }
64
65 while ((mntent = getmntent(mntFile)) != nullptr) {
66 if (dstPath.compare(mntent->mnt_dir) == 0) {
67 endmntent(mntFile);
68 return true;
69 }
70 }
71 endmntent(mntFile);
72 return false;
73 }
74
CheckDir(const std::string & path)75 bool StorageTestUtils::CheckDir(const std::string &path)
76 {
77 struct stat st;
78 if (lstat(path.c_str(), &st) != 0) {
79 return false;
80 }
81 return S_ISDIR(st.st_mode) == 1;
82 }
83
CheckUserDir(int32_t userId,uint32_t flags)84 bool StorageTestUtils::CheckUserDir(int32_t userId, uint32_t flags)
85 {
86 for (const Dir &dir : gRootDirs) {
87 std::string path(dir.path);
88 path.replace(path.find("%d"), strlen("%d"), std::to_string(userId));
89
90 if (flags & IStorageDaemon::CRYPTO_FLAG_EL1) {
91 std::string realPath(path);
92 realPath.replace(realPath.find("%s"), strlen("%s"), "el1");
93 if (CheckDir(realPath) == false) {
94 return false;
95 }
96 }
97 if (flags & IStorageDaemon::CRYPTO_FLAG_EL2) {
98 std::string realPath(path);
99 realPath.replace(realPath.find("%s"), strlen("%s"), "el2");
100 if (CheckDir(realPath) == false) {
101 return false;
102 }
103 }
104 }
105
106 for (const Dir &dir : gSubDirs) {
107 if (flags & IStorageDaemon::CRYPTO_FLAG_EL1) {
108 std::string path(dir.path);
109 path.replace(path.find("%d"), strlen("%d"), std::to_string(userId));
110 path.replace(path.find("%s"), strlen("%s"), "el1");
111 if (CheckDir(path) == false) {
112 return false;
113 }
114 }
115
116 if (flags & IStorageDaemon::CRYPTO_FLAG_EL2) {
117 std::string path(dir.path);
118 path.replace(path.find("%d"), strlen("%d"), std::to_string(userId));
119 path.replace(path.find("%s"), strlen("%s"), "el2");
120 if (CheckDir(path) == false) {
121 return false;
122 }
123 }
124 }
125
126 for (const Dir &dir : gHmdfsDirs) {
127 std::string path(dir.path);
128 path.replace(path.find("%d"), strlen("%d"), std::to_string(userId));
129 if (CheckDir(path) == false) {
130 return false;
131 }
132 }
133 return true;
134 }
135
CreateFile(const std::string & path)136 bool StorageTestUtils::CreateFile(const std::string &path)
137 {
138 (void)RmDirRecurse(path);
139 int fd = open(path.c_str(), O_RDWR | O_CREAT | O_TRUNC, MODE);
140 if (fd == -1) {
141 return false;
142 }
143 (void)close(fd);
144 return true;
145 }
146
MkDir(const std::string & path,mode_t mode)147 bool StorageTestUtils::MkDir(const std::string &path, mode_t mode)
148 {
149 if (access(path.c_str(), 0) == 0) {
150 if (rmdir(path.c_str()) != 0) {
151 return false;
152 }
153 }
154 if (mkdir(path.c_str(), mode) != 0) {
155 return false;
156 }
157 if (access(path.c_str(), 0) != 0) {
158 return false;
159 }
160 return true;
161 }
162
RmDirRecurse(const std::string & path)163 bool StorageTestUtils::RmDirRecurse(const std::string &path)
164 {
165 struct stat st;
166 if (lstat(path.c_str(), &st) != 0) {
167 return false;
168 }
169 if (S_ISDIR(st.st_mode) != 1) {
170 return (unlink(path.c_str()) == 0);
171 }
172
173 DIR *dir = opendir(path.c_str());
174 if (!dir) {
175 if (errno == ENOENT) {
176 return true;
177 }
178 return false;
179 }
180
181 for (struct dirent *ent = readdir(dir); ent != nullptr; ent = readdir(dir)) {
182 if (ent->d_type == DT_DIR) {
183 if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) {
184 continue;
185 }
186
187 if (!RmDirRecurse(path + "/" + ent->d_name)) {
188 (void)closedir(dir);
189 return false;
190 }
191 } else {
192 if (unlink((path + "/" + ent->d_name).c_str())) {
193 (void)closedir(dir);
194 return false;
195 }
196 }
197 }
198
199 (void)closedir(dir);
200 if (rmdir(path.c_str())) {
201 return false;
202 }
203
204 return true;
205 }
206
RmDir(const int32_t userId)207 void StorageTestUtils::RmDir(const int32_t userId)
208 {
209 std::vector<std::string> paths = {
210 "/data/app/el1/",
211 "/data/app/el2/",
212 "/data/service/el1/",
213 "/data/service/el2/",
214 "/data/chipset/el1/",
215 "/data/chipset/el2/",
216 "/storage/media/"
217 };
218
219 for (auto path : paths) {
220 path.append(std::to_string(userId));
221 RmDirRecurse(path);
222 }
223 }
224
ClearTestResource()225 void StorageTestUtils::ClearTestResource()
226 {
227 const int32_t userIds[] = {
228 USER_ID1,
229 USER_ID2,
230 USER_ID3,
231 USER_ID4,
232 USER_ID5
233 };
234 for (const auto id : userIds) {
235 std::string dstPath(hmdfsTarget);
236 dstPath.replace(dstPath.find("%d"), strlen("%d"), std::to_string(id));
237 UMount(dstPath);
238 RmDir(id);
239 }
240 }
241 } // StorageTest
242 } // STORAGE_DAEMON
243 } // OHOS
244