1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "retention_file_manager.h"
17 #include "dlp_permission.h"
18 #include "dlp_permission_log.h"
19 
20 namespace OHOS {
21 namespace Security {
22 namespace DlpPermission {
23 namespace {
24 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, SECURITY_DOMAIN_DLP_PERMISSION, "RetentionFileManager" };
25 const std::string PATH_SEPARATOR = "/";
26 const std::string USER_INFO_BASE = "/data/service/el1/public/dlp_permission_service";
27 const std::string DLP_RETENTION_JSON_PATH = USER_INFO_BASE + PATH_SEPARATOR + "retention_sandbox_info.json";
28 }
29 
RetentionFileManager()30 RetentionFileManager::RetentionFileManager()
31     : hasInit(false),
32       fileOperator_(std::make_shared<FileOperator>()),
33       sandboxJsonManager_(std::make_shared<SandboxJsonManager>())
34 {
35     Init();
36 }
37 
~RetentionFileManager()38 RetentionFileManager::~RetentionFileManager() {}
39 
GetInstance()40 RetentionFileManager& RetentionFileManager::GetInstance()
41 {
42     static RetentionFileManager instance;
43     return instance;
44 }
45 
HasRetentionSandboxInfo(const std::string & bundleName)46 bool RetentionFileManager::HasRetentionSandboxInfo(const std::string& bundleName)
47 {
48     return sandboxJsonManager_->HasRetentionSandboxInfo(bundleName);
49 }
50 
Init()51 bool RetentionFileManager::Init()
52 {
53     std::lock_guard<std::recursive_mutex> lock(mutex_);
54     if (fileOperator_->IsExistFile(DLP_RETENTION_JSON_PATH)) {
55         std::string constraintsConfigStr;
56         if (fileOperator_->GetFileContentByPath(DLP_RETENTION_JSON_PATH, constraintsConfigStr) != DLP_OK) {
57             return false;
58         }
59         if (constraintsConfigStr.empty()) {
60             hasInit = true;
61             return true;
62         }
63         Json callbackInfoJson = Json::parse(constraintsConfigStr, nullptr, false);
64         if (callbackInfoJson.is_discarded()) {
65             DLP_LOG_ERROR(LABEL, "callbackInfoJson is discarded");
66             return false;
67         }
68         sandboxJsonManager_->FromJson(callbackInfoJson);
69     } else {
70         if (fileOperator_->InputFileByPathAndContent(DLP_RETENTION_JSON_PATH, "") != DLP_OK) {
71             DLP_LOG_ERROR(LABEL, "InputFileByPathAndContent failed!");
72             return false;
73         }
74     }
75     hasInit = true;
76     return true;
77 }
78 
UpdateFile(const int32_t & jsonRes)79 int32_t RetentionFileManager::UpdateFile(const int32_t& jsonRes)
80 {
81     std::lock_guard<std::recursive_mutex> lock(mutex_);
82     if (jsonRes == DLP_FILE_NO_NEED_UPDATE) {
83         return DLP_OK;
84     }
85     if (jsonRes != DLP_OK) {
86         return jsonRes;
87     }
88     std::string jsonStr = sandboxJsonManager_->ToString();
89     if (fileOperator_->InputFileByPathAndContent(DLP_RETENTION_JSON_PATH, jsonStr) != DLP_OK) {
90         DLP_LOG_ERROR(LABEL, "InputFileByPathAndContent failed!");
91         return DLP_INSERT_FILE_ERROR;
92     }
93     return DLP_OK;
94 }
95 
AddSandboxInfo(const RetentionInfo & retentionInfo)96 int32_t RetentionFileManager::AddSandboxInfo(const RetentionInfo& retentionInfo)
97 {
98     if (!hasInit && !Init()) {
99         DLP_LOG_ERROR(LABEL, "Init failed!");
100         return DLP_RETENTION_UPDATE_ERROR;
101     }
102     int32_t res = sandboxJsonManager_->AddSandboxInfo(retentionInfo);
103     return UpdateFile(res);
104 }
105 
DelSandboxInfo(uint32_t tokenId)106 int32_t RetentionFileManager::DelSandboxInfo(uint32_t tokenId)
107 {
108     if (!hasInit && !Init()) {
109         DLP_LOG_ERROR(LABEL, "Init failed!");
110         return DLP_RETENTION_UPDATE_ERROR;
111     }
112     int32_t res = sandboxJsonManager_->DelSandboxInfo(tokenId);
113     return UpdateFile(res);
114 }
115 
CanUninstall(const uint32_t & tokenId)116 bool RetentionFileManager::CanUninstall(const uint32_t& tokenId)
117 {
118     if (!hasInit && !Init()) {
119         DLP_LOG_ERROR(LABEL, "Init failed!");
120         return false;
121     }
122     return sandboxJsonManager_->CanUninstall(tokenId);
123 }
124 
UpdateSandboxInfo(const std::set<std::string> & docUriSet,RetentionInfo & info,bool isRetention)125 int32_t RetentionFileManager::UpdateSandboxInfo(const std::set<std::string>& docUriSet, RetentionInfo& info,
126     bool isRetention)
127 {
128     if (!hasInit && !Init()) {
129         DLP_LOG_ERROR(LABEL, "Init failed!");
130         return DLP_RETENTION_UPDATE_ERROR;
131     }
132     int32_t res = sandboxJsonManager_->UpdateRetentionState(docUriSet, info, isRetention);
133     return UpdateFile(res);
134 }
135 
RemoveRetentionState(const std::string & bundleName,const int32_t & appIndex)136 int32_t RetentionFileManager::RemoveRetentionState(const std::string& bundleName, const int32_t& appIndex)
137 {
138     if (!hasInit && !Init()) {
139         DLP_LOG_ERROR(LABEL, "Init failed!");
140         return DLP_RETENTION_UPDATE_ERROR;
141     }
142     int32_t res = sandboxJsonManager_->RemoveRetentionState(bundleName, appIndex);
143     return UpdateFile(res);
144 }
145 
ClearUnreservedSandbox()146 int32_t RetentionFileManager::ClearUnreservedSandbox()
147 {
148     if (!hasInit && !Init()) {
149         DLP_LOG_ERROR(LABEL, "Init failed!");
150         return DLP_RETENTION_UPDATE_ERROR;
151     }
152     int32_t res = sandboxJsonManager_->ClearUnreservedSandbox();
153     return UpdateFile(res);
154 }
155 
GetRetentionSandboxList(const std::string & bundleName,std::vector<RetentionSandBoxInfo> & retentionSandBoxInfoVec,bool isRetention)156 int32_t RetentionFileManager::GetRetentionSandboxList(const std::string& bundleName,
157     std::vector<RetentionSandBoxInfo>& retentionSandBoxInfoVec, bool isRetention)
158 {
159     if (!hasInit && !Init()) {
160         DLP_LOG_ERROR(LABEL, "Init failed!");
161         return DLP_RETENTION_UPDATE_ERROR;
162     }
163     return sandboxJsonManager_->GetRetentionSandboxList(bundleName, retentionSandBoxInfoVec, isRetention);
164 }
165 
GetBundleNameSetByUserId(const int32_t userId,std::set<std::string> & bundleNameSet)166 int32_t RetentionFileManager::GetBundleNameSetByUserId(const int32_t userId, std::set<std::string>& bundleNameSet)
167 {
168     if (!hasInit && !Init()) {
169         DLP_LOG_ERROR(LABEL, "Init failed!");
170         return DLP_RETENTION_UPDATE_ERROR;
171     }
172     return sandboxJsonManager_->GetBundleNameSetByUserId(userId, bundleNameSet);
173 }
174 
RemoveRetentionInfoByUserId(const int32_t userId,const std::set<std::string> & bundleNameSet)175 int32_t RetentionFileManager::RemoveRetentionInfoByUserId(const int32_t userId,
176     const std::set<std::string>& bundleNameSet)
177 {
178     if (!hasInit && !Init()) {
179         DLP_LOG_ERROR(LABEL, "Init failed!");
180         return DLP_RETENTION_UPDATE_ERROR;
181     }
182     int32_t res = sandboxJsonManager_->RemoveRetentionInfoByUserId(userId, bundleNameSet);
183     return UpdateFile(res);
184 }
185 
UpdateReadFlag(uint32_t tokenId)186 int32_t RetentionFileManager::UpdateReadFlag(uint32_t tokenId)
187 {
188     if (!hasInit && !Init()) {
189         DLP_LOG_ERROR(LABEL, "Init failed!");
190         return DLP_RETENTION_UPDATE_ERROR;
191     }
192     int32_t res = sandboxJsonManager_->UpdateReadFlag(tokenId);
193     return UpdateFile(res);
194 }
195 } // namespace DlpPermission
196 } // namespace Security
197 } // namespace OHOS
198