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 = ¶m};
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