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