• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "dlp_utils.h"
17 #include <cctype>
18 #include <unistd.h>
19 #include <sys/stat.h>
20 #include <fstream>
21 #include <sstream>
22 #include <filesystem>
23 #include "dlp_permission.h"
24 #include "dlp_permission_log.h"
25 #include "dlp_permission_public_interface.h"
26 #include "dlp_zip.h"
27 #include "securec.h"
28 #include "system_ability_definition.h"
29 
30 namespace OHOS {
31 namespace Security {
32 namespace DlpPermission {
33 using Defer = std::shared_ptr<void>;
34 namespace {
35 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_DLP_PERMISSION, "DlpUtils"};
36 static constexpr uint32_t MAX_DLP_FILE_SIZE = 1000;
37 static const std::string DLP_FILE_SUFFIXS = ".dlp";
38 static const std::string DEFAULT_STRINGS = "";
39 static const std::string PATH_SEPARATOR = "/";
40 static const std::string DESCRIPTOR_MAP_PATH = "/proc/self/fd/";
41 const std::string DLP_GENERAL_INFO = "dlp_general_info";
42 const std::string CACHE_PATH = "/data/storage/el2/base/files/cache/";
43 const uint32_t DLP_CWD_MAX = 256;
44 const uint32_t OS_ACCOUNT = 100;
45 std::mutex g_fileOpLock;
46 }
47 
48 
GetBundleMgrProxy(void)49 sptr<AppExecFwk::IBundleMgr> DlpUtils::GetBundleMgrProxy(void)
50 {
51     sptr<ISystemAbilityManager> systemAbilityManager =
52         SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
53     if (systemAbilityManager == nullptr) {
54         DLP_LOG_ERROR(LABEL, "failed to get system ability manager");
55         return nullptr;
56     }
57 
58     sptr<IRemoteObject> remoteObj = systemAbilityManager->CheckSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
59     if (remoteObj == nullptr) {
60         DLP_LOG_ERROR(LABEL, "Fail to connect bundle manager service.");
61         return nullptr;
62     }
63 
64     return iface_cast<AppExecFwk::IBundleMgr>(remoteObj);
65 }
66 
ToLowerString(const std::string & str)67 std::string DlpUtils::ToLowerString(const std::string& str)
68 {
69     std::string lower;
70     for (char c : str) {
71         lower += std::tolower(c);
72     }
73     return lower;
74 }
75 
GetAuthPolicyWithType(const std::string & cfgFile,const std::string & type,std::vector<std::string> & authPolicy)76 bool DlpUtils::GetAuthPolicyWithType(const std::string &cfgFile, const std::string &type,
77     std::vector<std::string> &authPolicy)
78 {
79     std::string content;
80     (void)FileOperator().GetFileContentByPath(cfgFile, content);
81     if (content.empty()) {
82         return false;
83     }
84     auto jsonObj = nlohmann::json::parse(content, nullptr, false);
85     if (jsonObj.is_discarded() || (!jsonObj.is_object())) {
86         DLP_LOG_WARN(LABEL, "JsonObj is discarded");
87         return false;
88     }
89     auto result = jsonObj.find(type);
90     if (result != jsonObj.end() && result->is_array() && !result->empty() && (*result)[0].is_string()) {
91         authPolicy = result->get<std::vector<std::string>>();
92     }
93     if (authPolicy.size() != 0) {
94         return true;
95     }
96     return false;
97 }
98 
GetFileTypeBySuffix(const std::string & suffix,const bool isFromUriName)99 std::string DlpUtils::GetFileTypeBySuffix(const std::string& suffix, const bool isFromUriName)
100 {
101     std::string lower = DlpUtils::ToLowerString(suffix);
102     if (isFromUriName) {
103         for (size_t len = MAX_REALY_TYPE_LENGTH; len >= MIN_REALY_TYPE_LENGTH; len--) {
104             if (len > lower.size()) {
105                 continue;
106             }
107             std::string newStr = lower.substr(0, len);
108             auto iter = FILE_TYPE_MAP.find(newStr);
109             if (iter != FILE_TYPE_MAP.end()) {
110                 return iter->second;
111             }
112         }
113     } else {
114         auto iter = FILE_TYPE_MAP.find(lower);
115         if (iter != FILE_TYPE_MAP.end()) {
116             return iter->second;
117         }
118     }
119     return DEFAULT_STRINGS;
120 }
121 
GetFileType(const std::string & realFileType)122 bool DlpUtils::GetFileType(const std::string& realFileType)
123 {
124     std::string lower = DlpUtils::ToLowerString(realFileType);
125     for (size_t len = MAX_REALY_TYPE_LENGTH; len >= MIN_REALY_TYPE_LENGTH; len--) {
126         if (len > lower.size()) {
127             continue;
128         }
129         std::string newStr = lower.substr(0, len);
130         if (newStr == DLP_HIAE_TYPE) {
131             DLP_LOG_DEBUG(LABEL, "the file supports the HIAE.");
132             return true;
133         }
134     }
135     return false;
136 }
137 
GetDlpFileRealSuffix(const std::string & dlpFileName,bool & isFromUriName)138 std::string DlpUtils::GetDlpFileRealSuffix(const std::string& dlpFileName, bool& isFromUriName)
139 {
140     uint32_t dlpSuffixLen = DLP_FILE_SUFFIXS.size();
141     if (dlpFileName.size() <= dlpSuffixLen) {
142         DLP_LOG_ERROR(LABEL, "invalid fileName!");
143         return DEFAULT_STRINGS;
144     }
145     std::string realFileName = dlpFileName.substr(0, dlpFileName.size() - dlpSuffixLen);
146     char escape = '.';
147     std::size_t escapeLocate = realFileName.find_last_of(escape);
148     if (escapeLocate >= realFileName.size()) {
149         DLP_LOG_ERROR(LABEL, "Get file suffix fail, no '.' in file name");
150         return DEFAULT_STRINGS;
151     }
152 
153     return realFileName.substr(escapeLocate + 1);
154 }
155 
GetFileNameWithDlpFd(const int32_t & fd,std::string & srcFileName)156 int32_t DlpUtils::GetFileNameWithDlpFd(const int32_t &fd, std::string &srcFileName)
157 {
158     char *fileName = new (std::nothrow) char[MAX_DLP_FILE_SIZE + 1];
159     if (fileName == nullptr) {
160         return DLP_PARSE_ERROR_MEMORY_OPERATE_FAIL;
161     }
162     (void)memset_s(fileName, MAX_DLP_FILE_SIZE + 1, 0, MAX_DLP_FILE_SIZE + 1);
163 
164     std::string path = DESCRIPTOR_MAP_PATH + std::to_string(fd);
165 
166     int readLinkRes = readlink(path.c_str(), fileName, MAX_DLP_FILE_SIZE);
167     if (readLinkRes < 0) {
168         DLP_LOG_ERROR(LABEL, "fail to readlink uri, errno = %{public}d", errno);
169         delete[] fileName;
170         return DLP_PARSE_ERROR_FD_ERROR;
171     }
172     std::string tmp(fileName);
173     delete[] fileName;
174     std::size_t pos = tmp.find_last_of(".");
175     if (std::string::npos == pos) {
176         return DLP_PARSE_ERROR_FD_ERROR;
177     }
178     srcFileName = tmp.substr(0, pos);
179     return DLP_OK;
180 }
181 
GetFileNameWithFd(const int32_t & fd,std::string & srcFileName)182 int32_t DlpUtils::GetFileNameWithFd(const int32_t &fd, std::string &srcFileName)
183 {
184     char *fileName = new (std::nothrow) char[MAX_DLP_FILE_SIZE + 1];
185     if (fileName == nullptr) {
186         return DLP_PARSE_ERROR_MEMORY_OPERATE_FAIL;
187     }
188     (void)memset_s(fileName, MAX_DLP_FILE_SIZE + 1, 0, MAX_DLP_FILE_SIZE + 1);
189 
190     std::string path = DESCRIPTOR_MAP_PATH + std::to_string(fd);
191 
192     int readLinkRes = readlink(path.c_str(), fileName, MAX_DLP_FILE_SIZE);
193     if (readLinkRes < 0) {
194         DLP_LOG_ERROR(LABEL, "fail to readlink uri");
195         delete[] fileName;
196         return DLP_PARSE_ERROR_FD_ERROR;
197     }
198     fileName[readLinkRes] = '\0';
199 
200     srcFileName = std::string(fileName);
201     delete[] fileName;
202     return DLP_OK;
203 }
204 
GetFilePathWithFd(const int32_t & fd,std::string & srcFilePath)205 int32_t DlpUtils::GetFilePathWithFd(const int32_t &fd, std::string &srcFilePath)
206 {
207     char *fileName = new (std::nothrow) char[MAX_DLP_FILE_SIZE + 1];
208     if (fileName == nullptr) {
209         return DLP_PARSE_ERROR_MEMORY_OPERATE_FAIL;
210     }
211     (void)memset_s(fileName, MAX_DLP_FILE_SIZE + 1, 0, MAX_DLP_FILE_SIZE + 1);
212 
213     std::string path = DESCRIPTOR_MAP_PATH + std::to_string(fd);
214 
215     int readLinkRes = readlink(path.c_str(), fileName, MAX_DLP_FILE_SIZE);
216     if (readLinkRes < 0) {
217         DLP_LOG_ERROR(LABEL, "fail to readlink uri, errno = %{public}d", errno);
218         delete[] fileName;
219         return DLP_PARSE_ERROR_FD_ERROR;
220     }
221     std::string tmp(fileName);
222     std::size_t pos = tmp.find_last_of(PATH_SEPARATOR);
223     srcFilePath = tmp.substr(0, pos + 1);
224     delete[] fileName;
225     return DLP_OK;
226 }
227 
IsExistFile(const std::string & path)228 static bool IsExistFile(const std::string& path)
229 {
230     if (path.empty()) {
231         return false;
232     }
233 
234     struct stat buf = {};
235     if (stat(path.c_str(), &buf) != 0) {
236         return false;
237     }
238 
239     return S_ISREG(buf.st_mode);
240 }
241 
GetFileContent(const std::string & path)242 static std::string GetFileContent(const std::string& path)
243 {
244     if (!IsExistFile(path)) {
245         DLP_LOG_DEBUG(LABEL, "cannot find file, path = %{public}s", path.c_str());
246         return DEFAULT_STRINGS;
247     }
248     std::stringstream buffer;
249     std::ifstream i(path);
250     if (!i.is_open()) {
251         DLP_LOG_DEBUG(LABEL, "cannot open file %{public}s, errno %{public}d.", path.c_str(), errno);
252         return DEFAULT_STRINGS;
253     }
254     buffer << i.rdbuf();
255     std::string content = buffer.str();
256     i.close();
257     return content;
258 }
259 
RemoveCachePath(const std::string & path)260 static void RemoveCachePath(const std::string& path)
261 {
262     if (remove(DLP_GENERAL_INFO.c_str()) != 0) {
263         DLP_LOG_ERROR(LABEL, "remove dlp_general_info file fail, error %{public}s", strerror(errno));
264         return;
265     }
266     if (rmdir(path.c_str()) != 0) {
267         DLP_LOG_ERROR(LABEL, "remove cache path fail, error %{public}s", strerror(errno));
268     }
269 }
270 
GetGenerateInfoStr(const int32_t & fd)271 static std::string GetGenerateInfoStr(const int32_t& fd)
272 {
273     std::lock_guard<std::mutex> lock(g_fileOpLock);
274     char cwd[DLP_CWD_MAX] = {0};
275     if (getcwd(cwd, DLP_CWD_MAX) == nullptr) {
276         DLP_LOG_ERROR(LABEL, "getcwd fail error %{public}s", strerror(errno));
277         return DEFAULT_STRINGS;
278     }
279     Defer p(nullptr, [&](...) {
280         if (chdir(cwd) != 0) {
281             DLP_LOG_ERROR(LABEL, "chdir failed, %{public}s", strerror(errno));
282         }
283     });
284 
285     std::filesystem::path cachePath = CACHE_PATH;
286     if (!std::filesystem::exists(cachePath) || !std::filesystem::is_directory(cachePath)) {
287         if (mkdir(cachePath.c_str(), S_IRWXU) != 0) {
288             DLP_LOG_ERROR(LABEL, "mkdir cache path failed, errorno is %{public}s", strerror(errno));
289             return DEFAULT_STRINGS;
290         }
291     }
292 
293     int64_t timeStamp =
294         std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
295             .count();
296     std::string path = CACHE_PATH + std::to_string(timeStamp);
297     if (mkdir(path.c_str(), S_IRWXU) != 0) {
298         DLP_LOG_ERROR(LABEL, "mkdir timeStamp path failed, errorno is %{public}s", strerror(errno));
299         return DEFAULT_STRINGS;
300     }
301 
302     if (chdir(path.c_str()) != 0) {
303         DLP_LOG_ERROR(LABEL, "chdir cache err, errno is %{public}d", errno);
304         RemoveCachePath(path);
305         return DEFAULT_STRINGS;
306     }
307     if (!CheckUnzipFileInfo(fd) ||
308         UnzipSpecificFile(fd, DLP_GENERAL_INFO.c_str(), DLP_GENERAL_INFO.c_str()) != ZIP_OK) {
309         RemoveCachePath(path);
310         return DEFAULT_STRINGS;
311     }
312 
313     std::string generateInfoStr = GetFileContent(DLP_GENERAL_INFO);
314     RemoveCachePath(path);
315     return generateInfoStr;
316 }
317 
GetRealTypeWithFd(const int32_t & fd,bool & isFromUriName)318 std::string DlpUtils::GetRealTypeWithFd(const int32_t& fd, bool& isFromUriName)
319 {
320     std::string realType = DEFAULT_STRINGS;
321     do {
322         std::string generateInfoStr = GetGenerateInfoStr(fd);
323         if (generateInfoStr == DEFAULT_STRINGS) {
324             break;
325         }
326         GenerateInfoParams params;
327         if (ParseDlpGeneralInfo(generateInfoStr, params) != DLP_OK) {
328             DLP_LOG_ERROR(LABEL, "ParseDlpGeneralInfo error: %{public}s", generateInfoStr.c_str());
329             break;
330         }
331         realType = params.realType;
332         if (realType.size() >= MIN_REALY_TYPE_LENGTH && realType.size() <= MAX_REALY_TYPE_LENGTH) {
333             return realType;
334         }
335     } while (0);
336     DLP_LOG_DEBUG(LABEL, "not get real file type in dlp_general_info, will get to file name.");
337 
338     std::string fileName;
339     if (DlpUtils::GetFileNameWithFd(fd, fileName) != DLP_OK) {
340         DLP_LOG_ERROR(LABEL, "Get file name with fd error");
341         return DEFAULT_STRINGS;
342     }
343     return DlpUtils::GetDlpFileRealSuffix(fileName, isFromUriName);
344 }
345 
GetBundleInfoWithBundleName(const std::string & bundleName,int32_t flag,AppExecFwk::BundleInfo & bundleInfo,int32_t userId)346 bool DlpUtils::GetBundleInfoWithBundleName(const std::string &bundleName, int32_t flag,
347     AppExecFwk::BundleInfo &bundleInfo, int32_t userId)
348 {
349     bundleInfo.appId = "test_appId_passed";
350     return true;
351 }
352 
GetUserIdByForegroundAccount(int32_t & userId)353 bool DlpUtils::GetUserIdByForegroundAccount(int32_t &userId)
354 {
355     userId = OS_ACCOUNT;
356     return true;
357 }
358 
GetRealTypeForEnterpriseWithFd(const int32_t & fd,bool & isFromUriName)359 std::string DlpUtils::GetRealTypeForEnterpriseWithFd(const int32_t& fd, bool& isFromUriName)
360 {
361     return DlpUtils::GetRealTypeWithFd(fd, isFromUriName);
362 }
363 }  // namespace DlpPermission
364 }  // namespace Security
365 }  // namespace OHOS
366