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 = &param};
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