1 /*
2 * Copyright (c) 2023-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 #include "dlp_file_manager.h"
16
17 #include <dirent.h>
18 #include <cstdio>
19 #include <sys/stat.h>
20 #include <sys/types.h>
21 #include <unistd.h>
22 #include <string>
23
24 #include "dlp_crypt.h"
25 #include "dlp_file.h"
26 #include "dlp_permission.h"
27 #include "dlp_permission_kit.h"
28 #include "dlp_permission_log.h"
29 #include "hitrace_meter.h"
30 #include "securec.h"
31 #include "dlp_utils.h"
32 #include "dlp_file_kits.h"
33
34 namespace OHOS {
35 namespace Security {
36 namespace DlpPermission {
37 namespace {
38 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_DLP_PERMISSION, "DlpFileManager"};
39 static constexpr uint32_t MAX_DLP_FILE_SIZE = 1000; // max open dlp file
40 const std::string PATH_CACHE = "/cache";
41 }
42
AddDlpFileNode(const std::shared_ptr<DlpFile> & filePtr)43 int32_t DlpFileManager::AddDlpFileNode(const std::shared_ptr<DlpFile>& filePtr)
44 {
45 if (filePtr == nullptr) {
46 DLP_LOG_ERROR(LABEL, "Add dlp file node failed, filePtr is null");
47 return DLP_PARSE_ERROR_VALUE_INVALID;
48 }
49 Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->g_DlpMapLock_);
50 if (g_DlpFileMap_.size() >= MAX_DLP_FILE_SIZE) {
51 DLP_LOG_ERROR(LABEL, "Add dlp file node failed, too many files");
52 return DLP_PARSE_ERROR_TOO_MANY_OPEN_DLP_FILE;
53 }
54 auto iter = g_DlpFileMap_.find(filePtr->dlpFd_);
55 if (iter != g_DlpFileMap_.end()) {
56 DLP_LOG_ERROR(LABEL, "Add dlp file node fail, fd %{public}d already exist", filePtr->dlpFd_);
57 return DLP_PARSE_ERROR_FILE_ALREADY_OPENED;
58 }
59 g_DlpFileMap_[filePtr->dlpFd_] = filePtr;
60 return DLP_OK;
61 }
62
RemoveDlpFileNode(const std::shared_ptr<DlpFile> & filePtr)63 int32_t DlpFileManager::RemoveDlpFileNode(const std::shared_ptr<DlpFile>& filePtr)
64 {
65 if (filePtr == nullptr) {
66 DLP_LOG_ERROR(LABEL, "Remove dlp file node fail, filePtr is null");
67 return DLP_PARSE_ERROR_VALUE_INVALID;
68 }
69 Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->g_DlpMapLock_);
70 for (auto iter = g_DlpFileMap_.begin(); iter != g_DlpFileMap_.end(); iter++) {
71 if (filePtr->dlpFd_ == iter->first) {
72 g_DlpFileMap_.erase(iter);
73 return DLP_OK;
74 }
75 }
76
77 DLP_LOG_ERROR(LABEL, "Remove dlp file node fail, fd %{public}d not exist", filePtr->dlpFd_);
78 return DLP_PARSE_ERROR_FILE_NOT_OPENED;
79 }
80
GetDlpFile(int32_t dlpFd)81 std::shared_ptr<DlpFile> DlpFileManager::GetDlpFile(int32_t dlpFd)
82 {
83 Utils::UniqueReadGuard<Utils::RWLock> infoGuard(this->g_DlpMapLock_);
84 for (auto iter = g_DlpFileMap_.begin(); iter != g_DlpFileMap_.end(); iter++) {
85 if (dlpFd == iter->first) {
86 return iter->second;
87 }
88 }
89
90 return nullptr;
91 }
92
GenerateCertData(const PermissionPolicy & policy,struct DlpBlob & certData) const93 int32_t DlpFileManager::GenerateCertData(const PermissionPolicy& policy, struct DlpBlob& certData) const
94 {
95 std::vector<uint8_t> cert;
96 StartTrace(HITRACE_TAG_ACCESS_CONTROL, "DlpGenerateCertificate");
97 int32_t result = DlpPermissionKit::GenerateDlpCertificate(policy, cert);
98 FinishTrace(HITRACE_TAG_ACCESS_CONTROL);
99 if (result != DLP_OK) {
100 DLP_LOG_ERROR(LABEL, "Generate dlp cert fail, errno=%{public}d", result);
101 return result;
102 }
103 return GenerateCertBlob(cert, certData);
104 }
105
GenerateCertBlob(const std::vector<uint8_t> & cert,struct DlpBlob & certData) const106 int32_t DlpFileManager::GenerateCertBlob(const std::vector<uint8_t>& cert, struct DlpBlob& certData) const
107 {
108 size_t certSize = cert.size();
109 if (certSize > DLP_MAX_CERT_SIZE) {
110 DLP_LOG_ERROR(LABEL, "Check dlp cert fail, cert is too large, size=%{public}zu", certSize);
111 return DLP_PARSE_ERROR_VALUE_INVALID;
112 }
113 if (certSize == 0) {
114 DLP_LOG_ERROR(LABEL, "Check dlp cert fail, cert is zero, size=%{public}zu", certSize);
115 return DLP_PARSE_ERROR_VALUE_INVALID;
116 }
117
118 uint8_t* certBuffer = new (std::nothrow) uint8_t[certSize];
119 if (certBuffer == nullptr) {
120 DLP_LOG_ERROR(LABEL, "Copy dlp cert fail, alloc buff fail");
121 return DLP_PARSE_ERROR_MEMORY_OPERATE_FAIL;
122 }
123
124 if (memcpy_s(certBuffer, certSize, &cert[0], certSize) != EOK) {
125 DLP_LOG_ERROR(LABEL, "Copy dlp cert fail, memcpy_s fail");
126 (void)memset_s(certBuffer, certSize, 0, certSize);
127 delete[] certBuffer;
128 return DLP_PARSE_ERROR_MEMORY_OPERATE_FAIL;
129 }
130 if (certData.data != nullptr) {
131 (void)memset_s(certData.data, certData.size, 0, certData.size);
132 delete[] certData.data;
133 }
134 certData.data = certBuffer;
135 certData.size = static_cast<uint32_t>(certSize);
136 return DLP_OK;
137 }
138
CleanBlobParam(struct DlpBlob & blob)139 static int32_t CleanBlobParam(struct DlpBlob& blob)
140 {
141 if (blob.data == nullptr || blob.size == 0) {
142 DLP_LOG_ERROR(LABEL, "blobData null");
143 return DLP_PARSE_ERROR_VALUE_INVALID;
144 }
145
146 (void)memset_s(blob.data, blob.size, 0, blob.size);
147 delete[] blob.data;
148 blob.data = nullptr;
149 blob.size = 0;
150 return DLP_OK;
151 }
152
CleanTempBlob(struct DlpBlob & key,struct DlpCipherParam ** tagIv,struct DlpBlob & hmacKey) const153 void DlpFileManager::CleanTempBlob(struct DlpBlob& key, struct DlpCipherParam** tagIv, struct DlpBlob& hmacKey) const
154 {
155 if (key.data != nullptr) {
156 CleanBlobParam(key);
157 }
158 if (hmacKey.data != nullptr) {
159 CleanBlobParam(hmacKey);
160 }
161 if (tagIv == nullptr || (*tagIv) == nullptr) {
162 return;
163 }
164 if ((*tagIv)->iv.data != nullptr) {
165 CleanBlobParam((*tagIv)->iv);
166 }
167 delete (*tagIv);
168 (*tagIv) = nullptr;
169 }
170
PrepareDlpEncryptParms(PermissionPolicy & policy,struct DlpBlob & key,struct DlpUsageSpec & usage,struct DlpBlob & certData,struct DlpBlob & hmacKey) const171 int32_t DlpFileManager::PrepareDlpEncryptParms(PermissionPolicy& policy, struct DlpBlob& key,
172 struct DlpUsageSpec& usage, struct DlpBlob& certData, struct DlpBlob& hmacKey) const
173 {
174 DLP_LOG_INFO(LABEL, "Generate key");
175 int32_t res = DlpOpensslGenerateRandomKey(DLP_AES_KEY_SIZE_256, &key);
176 if (res != DLP_OK) {
177 DLP_LOG_ERROR(LABEL, "Generate key fail, errno=%{public}d", res);
178 return res;
179 }
180
181 struct DlpCipherParam* tagIv = new (std::nothrow) struct DlpCipherParam;
182 if (tagIv == nullptr) {
183 DLP_LOG_ERROR(LABEL, "Alloc iv buff fail");
184 CleanTempBlob(key, &tagIv, hmacKey);
185 return DLP_PARSE_ERROR_MEMORY_OPERATE_FAIL;
186 }
187 DLP_LOG_INFO(LABEL, "Generate iv");
188 res = DlpOpensslGenerateRandomKey(IV_SIZE * BIT_NUM_OF_UINT8, &tagIv->iv);
189 if (res != DLP_OK) {
190 DLP_LOG_ERROR(LABEL, "Generate iv fail, errno=%{public}d", res);
191 CleanTempBlob(key, &tagIv, hmacKey);
192 return res;
193 }
194
195 DLP_LOG_INFO(LABEL, "Generate hmac key");
196 res = DlpOpensslGenerateRandomKey(DLP_AES_KEY_SIZE_256, &hmacKey);
197 if (res != DLP_OK) {
198 DLP_LOG_ERROR(LABEL, "Generate hmacKey fail, errno=%{public}d", res);
199 CleanTempBlob(key, &tagIv, hmacKey);
200 return res;
201 }
202
203 usage.mode = DLP_MODE_CTR;
204 usage.algParam = tagIv;
205 policy.SetAeskey(key.data, key.size);
206 policy.SetIv(tagIv->iv.data, tagIv->iv.size);
207 policy.SetHmacKey(hmacKey.data, hmacKey.size);
208
209 DLP_LOG_INFO(LABEL, "Generate cert");
210 res = GenerateCertData(policy, certData);
211 if (res != DLP_OK) {
212 DLP_LOG_ERROR(LABEL, "Generate cert fail, errno=%{public}d", res);
213 CleanTempBlob(key, &tagIv, hmacKey);
214 return res;
215 }
216
217 return DLP_OK;
218 }
219
UpdateDlpFile(bool isNeedAdapter,uint32_t oldCertSize,const std::string & workDir,const std::vector<uint8_t> & cert,std::shared_ptr<DlpFile> & filePtr)220 int32_t DlpFileManager::UpdateDlpFile(bool isNeedAdapter, uint32_t oldCertSize, const std::string& workDir,
221 const std::vector<uint8_t>& cert, std::shared_ptr<DlpFile>& filePtr)
222 {
223 std::lock_guard<std::mutex> lock(g_offlineLock_);
224 int32_t result = filePtr->CheckDlpFile();
225 if (result != DLP_OK) {
226 return result;
227 }
228 struct DlpBlob certBlob;
229 #ifdef SUPPORT_DLP_CREDENTIAL
230 result = GenerateCertBlob(cert, certBlob);
231 if (result != DLP_OK) {
232 return result;
233 }
234 #else
235 return DLP_OK;
236 #endif
237 int32_t res = DLP_OK;
238 if (isNeedAdapter || oldCertSize != certBlob.size) {
239 res = filePtr->UpdateCertAndText(cert, workDir, certBlob);
240 } else {
241 res = filePtr->UpdateCert(certBlob);
242 }
243 (void)memset_s(certBlob.data, certBlob.size, 0, certBlob.size);
244 delete[] certBlob.data;
245 return res;
246 }
247
ParseDlpFileFormat(std::shared_ptr<DlpFile> & filePtr,const std::string & workDir,const std::string & appId)248 int32_t DlpFileManager::ParseDlpFileFormat(std::shared_ptr<DlpFile>& filePtr, const std::string& workDir,
249 const std::string& appId)
250 {
251 int32_t result = filePtr->ParseDlpHeader();
252 if (result != DLP_OK) {
253 return result;
254 }
255 struct DlpBlob cert;
256 filePtr->GetEncryptCert(cert);
257 sptr<CertParcel> certParcel = new (std::nothrow) CertParcel();
258 if (certParcel == nullptr) {
259 DLP_LOG_ERROR(LABEL, "Alloc certParcel parcel fail");
260 return DLP_PARSE_ERROR_MEMORY_OPERATE_FAIL;
261 }
262 certParcel->cert = std::vector<uint8_t>(cert.data, cert.data + cert.size);
263 uint32_t oldCertSize = cert.size;
264 struct DlpBlob offlineCert = { 0 };
265 uint32_t flag = filePtr->GetOfflineAccess();
266 if (flag != 0) {
267 filePtr->GetOfflineCert(offlineCert);
268 certParcel->offlineCert = std::vector<uint8_t>(offlineCert.data, offlineCert.data + offlineCert.size);
269 }
270 PermissionPolicy policy;
271 filePtr->GetContactAccount(certParcel->contactAccount);
272 certParcel->isNeedAdapter = filePtr->NeedAdapter();
273 StartTrace(HITRACE_TAG_ACCESS_CONTROL, "DlpParseCertificate");
274 result = DlpPermissionKit::ParseDlpCertificate(certParcel, policy, appId, filePtr->GetOfflineAccess());
275 FinishTrace(HITRACE_TAG_ACCESS_CONTROL);
276 if (result != DLP_OK) {
277 DLP_LOG_ERROR(LABEL, "Parse cert fail, errno=%{public}d", result);
278 return result;
279 }
280 result = filePtr->SetPolicy(policy);
281 if (result != DLP_OK) {
282 return result;
283 }
284 struct DlpBlob key = {.size = policy.GetAeskeyLen(), .data = policy.GetAeskey()};
285 struct DlpCipherParam param = {.iv = {.size = policy.GetIvLen(), .data = policy.GetIv()}};
286 struct DlpUsageSpec usage = {.mode = DLP_MODE_CTR, .algParam = ¶m};
287 struct DlpBlob hmacKey = {.size = policy.GetHmacKeyLen(), .data = policy.GetHmacKey()};
288 result = filePtr->SetCipher(key, usage, hmacKey);
289 if (result != DLP_OK) {
290 return result;
291 }
292 result = filePtr->HmacCheck();
293 if (result != DLP_OK) {
294 return result;
295 }
296 return UpdateDlpFile(filePtr->NeedAdapter(), oldCertSize, workDir, certParcel->offlineCert, filePtr);
297 }
298
FreeChiperBlob(struct DlpBlob & key,struct DlpBlob & certData,struct DlpUsageSpec & usage,struct DlpBlob & hmacKey) const299 void DlpFileManager::FreeChiperBlob(struct DlpBlob& key, struct DlpBlob& certData,
300 struct DlpUsageSpec& usage, struct DlpBlob& hmacKey) const
301 {
302 if (key.data != nullptr) {
303 CleanBlobParam(key);
304 }
305
306 if (certData.data != nullptr) {
307 CleanBlobParam(certData);
308 }
309 if (usage.algParam != nullptr) {
310 if (usage.algParam->iv.data != nullptr) {
311 CleanBlobParam(usage.algParam->iv);
312 }
313 delete usage.algParam;
314 usage.algParam = nullptr;
315 }
316
317 if (hmacKey.data != nullptr) {
318 CleanBlobParam(hmacKey);
319 }
320 }
321
SetDlpFileParams(std::shared_ptr<DlpFile> & filePtr,const DlpProperty & property) const322 int32_t DlpFileManager::SetDlpFileParams(std::shared_ptr<DlpFile>& filePtr, const DlpProperty& property) const
323 {
324 PermissionPolicy policy(property);
325 struct DlpBlob key;
326 struct DlpBlob certData;
327 struct DlpUsageSpec usage;
328 struct DlpBlob hmacKey;
329
330 int32_t result = PrepareDlpEncryptParms(policy, key, usage, certData, hmacKey);
331 if (result != DLP_OK) {
332 DLP_LOG_ERROR(LABEL, "Set dlp obj params fail, prepare encrypt params error, errno=%{public}d", result);
333 return result;
334 }
335 result = filePtr->SetCipher(key, usage, hmacKey);
336 if (result != DLP_OK) {
337 FreeChiperBlob(key, certData, usage, hmacKey);
338 DLP_LOG_ERROR(LABEL, "Set dlp obj params fail, set cipher error, errno=%{public}d", result);
339 return result;
340 }
341
342 result = filePtr->SetPolicy(policy);
343 if (result != DLP_OK) {
344 FreeChiperBlob(key, certData, usage, hmacKey);
345 DLP_LOG_ERROR(LABEL, "Set dlp obj params fail, set policy error, errno=%{public}d", result);
346 return result;
347 }
348
349 result = filePtr->SetEncryptCert(certData);
350 if (result != DLP_OK) {
351 FreeChiperBlob(key, certData, usage, hmacKey);
352 DLP_LOG_ERROR(LABEL, "Set dlp obj params fail, set cert error, errno=%{public}d", result);
353 return result;
354 }
355
356 result = filePtr->SetContactAccount(property.contactAccount);
357 if (result != DLP_OK) {
358 DLP_LOG_WARN(LABEL, "Set dlp obj params fail, set contact account error, errno=%{public}d", result);
359 }
360
361 filePtr->SetOfflineAccess(property.offlineAccess);
362
363 FreeChiperBlob(key, certData, usage, hmacKey);
364 return result;
365 }
366
RemoveDirRecursive(const char * path)367 static bool RemoveDirRecursive(const char *path)
368 {
369 if (path == nullptr) {
370 return false;
371 }
372 DIR *dir = opendir(path);
373 if (dir == nullptr) {
374 return false;
375 }
376
377 dirent *entry;
378 while ((entry = readdir(dir)) != nullptr) {
379 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
380 continue;
381 }
382 std::string subPath = std::string(path) + "/" + entry->d_name;
383 if ((entry->d_type == DT_DIR) && (!RemoveDirRecursive(subPath.c_str()))) {
384 closedir(dir);
385 return false;
386 }
387 if ((entry->d_type != DT_DIR) && (remove(subPath.c_str()) != 0)) {
388 closedir(dir);
389 return false;
390 }
391 }
392
393 closedir(dir);
394
395 if (rmdir(path) != 0) {
396 DLP_LOG_ERROR(LABEL, "rmdir fail, errno %{public}s", strerror(errno));
397 return false;
398 }
399 return true;
400 }
401
402 std::mutex g_dirCleanLock;
PrepareDirs(const std::string & path)403 static void PrepareDirs(const std::string& path)
404 {
405 std::lock_guard<std::mutex> lock(g_dirCleanLock);
406 static bool cleanOnce = true;
407 if (cleanOnce) {
408 cleanOnce = false;
409 RemoveDirRecursive(path.c_str());
410 mkdir(path.c_str(), S_IRWXU);
411 }
412 }
413
GenerateDlpFile(int32_t plainFileFd,int32_t dlpFileFd,const DlpProperty & property,std::shared_ptr<DlpFile> & filePtr,const std::string & workDir)414 int32_t DlpFileManager::GenerateDlpFile(
415 int32_t plainFileFd, int32_t dlpFileFd, const DlpProperty& property, std::shared_ptr<DlpFile>& filePtr,
416 const std::string& workDir)
417 {
418 if (plainFileFd < 0 || dlpFileFd < 0) {
419 DLP_LOG_ERROR(LABEL, "Generate dlp file fail, plain file fd or dlp file fd invalid");
420 return DLP_PARSE_ERROR_FD_ERROR;
421 }
422
423 if (GetDlpFile(dlpFileFd) != nullptr) {
424 DLP_LOG_ERROR(LABEL, "Generate dlp file fail, dlp file has generated, if you want to rebuild, close it first");
425 return DLP_PARSE_ERROR_FILE_ALREADY_OPENED;
426 }
427
428 std::string cache = workDir + PATH_CACHE;
429 PrepareDirs(cache);
430 int64_t timeStamp =
431 std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
432 .count();
433 filePtr = std::make_shared<DlpFile>(dlpFileFd, cache, timeStamp, true);
434
435 int32_t result = SetDlpFileParams(filePtr, property);
436 if (result != DLP_OK) {
437 DLP_LOG_ERROR(LABEL, "Generate dlp file fail, set dlp obj params error, errno=%{public}d", result);
438 return result;
439 }
440
441 result = filePtr->GenFile(plainFileFd);
442 if (result != DLP_OK) {
443 DLP_LOG_ERROR(LABEL, "Generate dlp file fail, errno=%{public}d", result);
444 return result;
445 }
446
447 return AddDlpFileNode(filePtr);
448 }
449
GetBundleInfoWithBundleName(const std::string & bundleName,int32_t flag,AppExecFwk::BundleInfo & bundleInfo,int32_t userId)450 static bool GetBundleInfoWithBundleName(const std::string &bundleName, int32_t flag,
451 AppExecFwk::BundleInfo &bundleInfo, int32_t userId)
452 {
453 auto bundleMgrProxy = DlpUtils::GetBundleMgrProxy();
454 if (bundleMgrProxy == nullptr) {
455 return false;
456 }
457 return bundleMgrProxy->GetBundleInfo(bundleName, flag, bundleInfo, userId);
458 }
459
GetAppIdWithBundleName(const std::string & bundleName,const int32_t & userId)460 static std::string GetAppIdWithBundleName(const std::string &bundleName, const int32_t &userId)
461 {
462 AppExecFwk::BundleInfo bundleInfo;
463 bool result = GetBundleInfoWithBundleName(bundleName,
464 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_SIGNATURE_INFO), bundleInfo, userId);
465 if (!result) {
466 DLP_LOG_ERROR(LABEL, "get appId error");
467 return DEFAULT_STRING;
468 }
469 return bundleInfo.appId;
470 }
471
SupportDlpWithAppId(const std::string & appId,const std::string & fileName)472 static int32_t SupportDlpWithAppId(const std::string &appId, const std::string &fileName)
473 {
474 std::string realSuffix = DlpUtils::GetDlpFileRealSuffix(fileName);
475 if (realSuffix == DEFAULT_STRING) {
476 DLP_LOG_ERROR(LABEL, "get realSuffix error.");
477 return DLP_PARSE_ERROR_VALUE_INVALID;
478 }
479 std::string fileType = DlpUtils::GetFileTypeBySuffix(realSuffix);
480 if (fileType == DEFAULT_STRING) {
481 DLP_LOG_ERROR(LABEL, "get fileType error.");
482 return DLP_PARSE_ERROR_VALUE_INVALID;
483 }
484
485 int32_t userId = 0;
486 int32_t ret = AccountSA::OsAccountManager::GetForegroundOsAccountLocalId(userId);
487 if (ret != ERR_OK) {
488 DLP_LOG_ERROR(LABEL, "Get os account localId error, %{public}d", ret);
489 return DLP_PARSE_ERROR_GET_ACCOUNT_FAIL;
490 }
491
492 std::vector<std::string> whitelist;
493 if (!DlpUtils::GetWhitelistWithType(DLP_WHITELIST, fileType, whitelist)) {
494 DLP_LOG_DEBUG(LABEL, "not have white list.");
495 return DLP_OK;
496 }
497 for (size_t i = 0; i < whitelist.size(); i++) {
498 if (appId == GetAppIdWithBundleName(whitelist[i], userId)) {
499 return DLP_OK;
500 }
501 }
502 DLP_LOG_ERROR(LABEL, "Check DLP whitelist error.");
503 return DLP_CREDENTIAL_ERROR_APPID_NOT_AUTHORIZED;
504 }
505
OpenDlpFile(int32_t dlpFileFd,std::shared_ptr<DlpFile> & filePtr,const std::string & workDir,const std::string & appId)506 int32_t DlpFileManager::OpenDlpFile(int32_t dlpFileFd, std::shared_ptr<DlpFile>& filePtr, const std::string& workDir,
507 const std::string& appId)
508 {
509 if (dlpFileFd < 0) {
510 DLP_LOG_ERROR(LABEL, "Open dlp file fail, fd %{public}d is invalid", dlpFileFd);
511 return DLP_PARSE_ERROR_FD_ERROR;
512 }
513
514 std::string fileName;
515 int32_t ret = DlpUtils::GetFileNameWithFd(dlpFileFd, fileName);
516 if (ret != DLP_OK) {
517 return ret;
518 }
519
520 ret = SupportDlpWithAppId(appId, fileName);
521 if (ret != DLP_OK) {
522 return ret;
523 }
524
525 filePtr = GetDlpFile(dlpFileFd);
526 if (filePtr != nullptr) {
527 DLP_LOG_INFO(LABEL, "Open dlp file fail, fd %{public}d has opened", dlpFileFd);
528 return DLP_OK;
529 }
530
531 std::string cache = workDir + PATH_CACHE;
532 PrepareDirs(cache);
533 int64_t timeStamp =
534 std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
535 .count();
536 filePtr = std::make_shared<DlpFile>(dlpFileFd, cache, timeStamp, false);
537
538 int32_t result = ParseDlpFileFormat(filePtr, workDir, appId);
539 if (result != DLP_OK) {
540 DLP_LOG_ERROR(LABEL, "Open dlp file fail, parse dlp file error, errno=%{public}d", result);
541 return result;
542 }
543
544 return AddDlpFileNode(filePtr);
545 }
546
CloseDlpFile(const std::shared_ptr<DlpFile> & dlpFile)547 int32_t DlpFileManager::CloseDlpFile(const std::shared_ptr<DlpFile>& dlpFile)
548 {
549 if (dlpFile == nullptr) {
550 DLP_LOG_ERROR(LABEL, "Close dlp file fail, dlp obj is null");
551 return DLP_PARSE_ERROR_PTR_NULL;
552 }
553
554 return RemoveDlpFileNode(dlpFile);
555 }
556
RecoverDlpFile(std::shared_ptr<DlpFile> & filePtr,int32_t plainFd) const557 int32_t DlpFileManager::RecoverDlpFile(std::shared_ptr<DlpFile>& filePtr, int32_t plainFd) const
558 {
559 if (filePtr == nullptr) {
560 DLP_LOG_ERROR(LABEL, "Recover dlp file fail, dlp obj is null");
561 return DLP_PARSE_ERROR_PTR_NULL;
562 }
563 if (plainFd < 0) {
564 DLP_LOG_ERROR(LABEL, "Recover dlp file fail, fd %{public}d is invalid", plainFd);
565 return DLP_PARSE_ERROR_FD_ERROR;
566 }
567
568 return filePtr->RemoveDlpPermission(plainFd);
569 }
570
GetInstance()571 DlpFileManager& DlpFileManager::GetInstance()
572 {
573 static DlpFileManager instance;
574 return instance;
575 }
576 } // namespace DlpPermission
577 } // namespace Security
578 } // namespace OHOS
579