1 /*
2 * Copyright (c) 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
16 #include "managed_browser_policy_plugin.h"
17
18 #include <fcntl.h>
19 #include <fstream>
20 #include <ipc_skeleton.h>
21 #include <sys/stat.h>
22 #include <sys/types.h>
23 #include <unistd.h>
24 #include "bundle_manager_utils.h"
25 #include "cjson_check.h"
26 #include "cjson_serializer.h"
27 #include "common_event_manager.h"
28 #include "common_event_support.h"
29 #include "edm_bundle_manager_impl.h"
30 #include "edm_constants.h"
31 #include "edm_ipc_interface_code.h"
32 #include "edm_utils.h"
33 #include "managed_browser_policy_serializer.h"
34 #include "iplugin_manager.h"
35 #include "security_label.h"
36 #include "want.h"
37
38 namespace OHOS {
39 namespace EDM {
40 const bool REGISTER_RESULT = IPluginManager::GetInstance()->AddPlugin(std::make_shared<ManagedBrowserPolicyPlugin>());
41 const char* const MANAGED_BROWSER_POLICY_DIR = "/data/service/el1/public/edm/browser/";
42 const char* const MANAGED_BROWSER_POLICY_SUFFIX = ".dat";
43 const char* const BROWSER_POLICY_CHANGED_EVENT = "usual.event.MANAGED_BROWSER_POLICY_CHANGED";
44 const char* const EMPTY_POLICY = "{}";
45 constexpr int32_t EMPTY_POLICY_SIZE = 3;
46 constexpr int32_t MAX_POLICY_FILE_SIZE = 134217728; // 128 * 1024 * 1024
47
ManagedBrowserPolicyPlugin()48 ManagedBrowserPolicyPlugin::ManagedBrowserPolicyPlugin()
49 {
50 policyCode_ = EdmInterfaceCode::MANAGED_BROWSER_POLICY;
51 policyName_ = PolicyName::POLICY_MANAGED_BROWSER_POLICY;
52 permissionMap_.insert(std::make_pair(
53 FuncOperateType::SET, IPlugin::PolicyPermissionConfig(EdmPermission::PERMISSION_ENTERPRISE_SET_BROWSER_POLICY,
54 IPlugin::PermissionType::SUPER_DEVICE_ADMIN, IPlugin::ApiType::PUBLIC)));
55 permissionMap_.insert(std::make_pair(
56 FuncOperateType::GET, IPlugin::PolicyPermissionConfig("", IPlugin::PermissionType::SUPER_DEVICE_ADMIN,
57 IPlugin::ApiType::PUBLIC)));
58 needSave_ = true;
59 }
60
OnHandlePolicy(std::uint32_t funcCode,MessageParcel & data,MessageParcel & reply,HandlePolicyData & policyData,int32_t userId)61 ErrCode ManagedBrowserPolicyPlugin::OnHandlePolicy(std::uint32_t funcCode, MessageParcel &data, MessageParcel &reply,
62 HandlePolicyData &policyData, int32_t userId)
63 {
64 EDMLOGI("ManagedBrowserPolicyPlugin OnHandlePolicy.");
65 std::string bundleName = data.ReadString();
66 std::string policyName = data.ReadString();
67 std::string policyValue = data.ReadString();
68 if (bundleName.empty() || policyName.empty() || bundleName.find("..") != std::string::npos) {
69 return EdmReturnErrCode::PARAM_ERROR;
70 }
71
72 auto serializer = ManagedBrowserPolicySerializer::GetInstance();
73 std::map<std::string, ManagedBrowserPolicyType> policies;
74 std::map<std::string, ManagedBrowserPolicyType> mergePolicies;
75 if (!serializer->Deserialize(policyData.policyData, policies) ||
76 !serializer->Deserialize(policyData.mergePolicyData, mergePolicies)) {
77 EDMLOGE("ManagedBrowserPolicyPlugin::OnHandlePolicy Deserialize current policy and merge policy failed.");
78 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
79 }
80 std::vector<std::string> policyNames = policies[bundleName].policyNames;
81 bool isModifyOrRemove = (std::find(policyNames.begin(), policyNames.end(), policyName) != policyNames.end());
82 ErrCode ret = UpdateCurrentAndMergePolicy(policies, mergePolicies, bundleName, policyName, policyValue);
83 if (FAILED(ret)) {
84 return ret;
85 }
86 std::string afterHandle;
87 std::string afterMerge;
88 if (!serializer->Serialize(policies, afterHandle) || !serializer->Serialize(mergePolicies, afterMerge)) {
89 EDMLOGE("ManagedBrowserPolicyPlugin::OnHandlePolicy Serialize current policy and merge policy failed.");
90 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
91 }
92
93 size_t pos = 0;
94 while ((pos = policyValue.find("\n", pos)) != std::string::npos) {
95 policyValue.replace(pos, 1, "");
96 }
97 if (isModifyOrRemove) {
98 ret = ModifyOrRemoveManagedBrowserPolicy(policies, bundleName, policyName, policyValue);
99 } else {
100 ret = AddManagedBrowserPolicy(policies, bundleName, policyName, policyValue);
101 }
102 if (ret != ERR_OK) {
103 return ret;
104 }
105
106 policyData.isChanged = true;
107 policyData.policyData = afterHandle;
108 policyData.mergePolicyData = afterMerge;
109 return ret;
110 }
111
UpdateCurrentAndMergePolicy(std::map<std::string,ManagedBrowserPolicyType> & policies,std::map<std::string,ManagedBrowserPolicyType> & mergePolicies,const std::string & bundleName,const std::string & policyName,const std::string & policyValue)112 ErrCode ManagedBrowserPolicyPlugin::UpdateCurrentAndMergePolicy(
113 std::map<std::string, ManagedBrowserPolicyType> &policies,
114 std::map<std::string, ManagedBrowserPolicyType> &mergePolicies, const std::string &bundleName,
115 const std::string &policyName, const std::string &policyValue)
116 {
117 if (mergePolicies.find(bundleName) != mergePolicies.end() &&
118 std::find(mergePolicies[bundleName].policyNames.begin(),
119 mergePolicies[bundleName].policyNames.end(), policyName) != mergePolicies[bundleName].policyNames.end()) {
120 EDMLOGE("ManagedBrowserPolicyPlugin another admin has already set this item policy for this application.");
121 return EdmReturnErrCode::PARAM_ERROR;
122 }
123
124 std::vector<std::string> &policyNames = policies[bundleName].policyNames;
125 auto it = std::find(policyNames.begin(), policyNames.end(), policyName);
126 if (it != policyNames.end()) {
127 if (policyValue.empty()) {
128 policyNames.erase(it);
129 }
130 } else {
131 policies[bundleName].policyNames.push_back(policyName);
132 }
133 policies[bundleName].version++;
134
135 for (auto policy : policies) {
136 if (mergePolicies.find(policy.first) == mergePolicies.end()) {
137 mergePolicies[policy.first] = policy.second;
138 continue;
139 }
140 mergePolicies[policy.first].version++;
141 mergePolicies[policy.first].policyNames.insert(mergePolicies[policy.first].policyNames.end(),
142 policy.second.policyNames.begin(), policy.second.policyNames.end());
143 }
144 return ERR_OK;
145 }
146
GetOthersMergePolicyData(const std::string & adminName,int32_t userId,std::string & othersMergePolicyData)147 ErrCode ManagedBrowserPolicyPlugin::GetOthersMergePolicyData(const std::string &adminName, int32_t userId,
148 std::string &othersMergePolicyData)
149 {
150 AdminValueItemsMap adminValues;
151 IPolicyManager::GetInstance()->GetAdminByPolicyName(GetPolicyName(), adminValues);
152 EDMLOGD("IPluginTemplate::GetOthersMergePolicyData %{public}s value size %{public}d.", GetPolicyName().c_str(),
153 (uint32_t)adminValues.size());
154 if (adminValues.empty()) {
155 return ERR_OK;
156 }
157 auto entry = adminValues.find(adminName);
158 if (entry != adminValues.end()) {
159 adminValues.erase(entry);
160 }
161 if (adminValues.empty()) {
162 return ERR_OK;
163 }
164 std::map<std::string, ManagedBrowserPolicyType> mergeData;
165 auto serializer = ManagedBrowserPolicySerializer::GetInstance();
166 for (const auto &item : adminValues) {
167 std::map<std::string, ManagedBrowserPolicyType> dataItem;
168 if (item.second.empty()) {
169 continue;
170 }
171 if (!serializer->Deserialize(item.second, dataItem)) {
172 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
173 }
174 for (auto item : dataItem) {
175 if (mergeData.find(item.first) == mergeData.end()) {
176 mergeData[item.first] = item.second;
177 continue;
178 }
179 mergeData[item.first].policyNames.insert(mergeData[item.first].policyNames.end(),
180 item.second.policyNames.begin(), item.second.policyNames.end());
181 if (item.second.version > mergeData[item.first].version) {
182 mergeData[item.first].version = item.second.version;
183 }
184 }
185 }
186
187 if (!serializer->Serialize(mergeData, othersMergePolicyData)) {
188 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
189 }
190 return ERR_OK;
191 }
192
ModifyOrRemoveManagedBrowserPolicy(std::map<std::string,ManagedBrowserPolicyType> & policies,const std::string & bundleName,const std::string & policyName,const std::string & policyValue)193 ErrCode ManagedBrowserPolicyPlugin::ModifyOrRemoveManagedBrowserPolicy(
194 std::map<std::string, ManagedBrowserPolicyType> &policies, const std::string &bundleName,
195 const std::string &policyName, const std::string &policyValue)
196 {
197 EDMLOGI("ManagedBrowserPolicyPlugin::ModifyOrRemoveManagedBrowserPolicy start");
198 std::string url = MANAGED_BROWSER_POLICY_DIR + bundleName + MANAGED_BROWSER_POLICY_SUFFIX;
199 if (!EdmUtils::CheckRealPath(url, MANAGED_BROWSER_POLICY_DIR)) {
200 EDMLOGE("ManagedBrowserPolicyPlugin::CheckRealPath fail");
201 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
202 }
203 std::ifstream inFile(url);
204 if (inFile.fail()) {
205 EDMLOGE("ManagedBrowserPolicyPlugin::ModifyOrRemoveManagedBrowserPolicy open file fail");
206 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
207 }
208
209 std::string tempUrl = MANAGED_BROWSER_POLICY_DIR + bundleName + "_tmp" + MANAGED_BROWSER_POLICY_SUFFIX;
210 std::ofstream tempOutFile(tempUrl);
211 if (tempOutFile.fail()) {
212 EDMLOGE("ManagedBrowserPolicyPlugin::ModifyOrRemoveManagedBrowserPolicy open file fail");
213 inFile.close();
214 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
215 }
216 std::string policyNameWithQuotation = "\"" + policyName + "\"";
217 std::string line;
218 while (std::getline(inFile, line)) {
219 std::string policyNameInLine;
220 if (!FindPolicyNameInLine(line, policyNameInLine)) {
221 EDMLOGE("can not find policyNameInLine");
222 remove(tempUrl.c_str());
223 inFile.close();
224 tempOutFile.close();
225 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
226 }
227
228 if (policyNameInLine == policyNameWithQuotation) {
229 if (policyValue.empty()) {
230 continue;
231 } else {
232 tempOutFile << policyNameWithQuotation << ":" << policyValue << std::endl;
233 }
234 } else {
235 tempOutFile << line << std::endl;
236 }
237 }
238
239 inFile.close();
240 tempOutFile.close();
241
242 return UpdatePolicyFile(policies, bundleName, url, tempUrl) ? ERR_OK : EdmReturnErrCode::SYSTEM_ABNORMALLY;
243 }
244
AddManagedBrowserPolicy(std::map<std::string,ManagedBrowserPolicyType> & policies,const std::string & bundleName,const std::string & policyName,const std::string & policyValue)245 ErrCode ManagedBrowserPolicyPlugin::AddManagedBrowserPolicy(std::map<std::string, ManagedBrowserPolicyType> &policies,
246 const std::string &bundleName, const std::string &policyName, const std::string &policyValue)
247 {
248 std::string url = MANAGED_BROWSER_POLICY_DIR + bundleName + MANAGED_BROWSER_POLICY_SUFFIX;
249 std::ofstream outfile(url, std::ios::app);
250 if (outfile.fail()) {
251 EDMLOGE("ManagedBrowserPolicyPlugin::AddManagedBrowserPolicy open file fail");
252 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
253 }
254 std::string newPolicy = "\"" + policyName + "\":" + policyValue;
255 outfile << newPolicy << std::endl;
256 outfile.close();
257 return ERR_OK;
258 }
259
OnHandlePolicyDone(std::uint32_t funcCode,const std::string & adminName,bool isGlobalChanged,int32_t userId)260 void ManagedBrowserPolicyPlugin::OnHandlePolicyDone(std::uint32_t funcCode, const std::string &adminName,
261 bool isGlobalChanged, int32_t userId)
262 {
263 EDMLOGD("ManagedBrowserPolicyPlugin::OnHandlePolicyDone called");
264 AAFwk::Want want;
265 want.SetAction(BROWSER_POLICY_CHANGED_EVENT);
266 EventFwk::CommonEventData eventData;
267 eventData.SetWant(want);
268 if (!EventFwk::CommonEventManager::PublishCommonEvent(eventData)) {
269 EDMLOGE("NotifyBrowserPolicyChanged failed.");
270 }
271 }
272
OnGetPolicy(std::string & policyData,MessageParcel & data,MessageParcel & reply,int32_t userId)273 ErrCode ManagedBrowserPolicyPlugin::OnGetPolicy(std::string &policyData, MessageParcel &data, MessageParcel &reply,
274 int32_t userId)
275 {
276 std::string type = data.ReadString();
277 EDMLOGI("ManagedBrowserPolicyPlugin::OnGetPolicy type %{public}s", type.c_str());
278 std::string bundleName;
279 if (type == EdmConstants::Browser::GET_MANAGED_BROWSER_FILE_DATA) {
280 bundleName = data.ReadString();
281 } else if (!GetCallingBundleName(bundleName)) {
282 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
283 }
284 if (bundleName.empty() || bundleName.find("..") != std::string::npos) {
285 EDMLOGI("ManagedBrowserPolicyPlugin::OnGetPolicy bundleName error");
286 return EdmReturnErrCode::PARAM_ERROR;
287 }
288
289 if (type == EdmConstants::Browser::GET_MANAGED_BROWSER_VERSION) {
290 return GetManagedBrowserPolicyVersion(policyData, bundleName, reply);
291 } else if (type == EdmConstants::Browser::GET_MANAGED_BROWSER_FILE_DATA ||
292 type == EdmConstants::Browser::GET_SELF_MANAGED_BROWSER_FILE_DATA) {
293 return GetManagedBrowserPolicyFileData(bundleName, reply);
294 } else {
295 EDMLOGE("ManagedBrowserPolicyPlugin::OnGetPolicy type error");
296 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
297 }
298 }
299
GetManagedBrowserPolicyFileData(const std::string & bundleName,MessageParcel & reply)300 ErrCode ManagedBrowserPolicyPlugin::GetManagedBrowserPolicyFileData(const std::string &bundleName, MessageParcel &reply)
301 {
302 std::string url = MANAGED_BROWSER_POLICY_DIR + bundleName + MANAGED_BROWSER_POLICY_SUFFIX;
303 if (!EdmUtils::CheckRealPath(url, MANAGED_BROWSER_POLICY_DIR)) {
304 EDMLOGE("ManagedBrowserPolicyPlugin::CheckRealPath fail");
305 reply.WriteInt32(ERR_OK);
306 reply.WriteInt32(EMPTY_POLICY_SIZE);
307 reply.WriteRawData(reinterpret_cast<const void*>(EMPTY_POLICY), EMPTY_POLICY_SIZE);
308 return ERR_OK;
309 }
310 std::ifstream infile(url, std::ios::binary | std::ios::ate);
311 if (infile.fail()) {
312 EDMLOGE("ManagedBrowserPolicyPlugin::OnGetPolicy open file fail");
313 reply.WriteInt32(ERR_OK);
314 reply.WriteInt32(EMPTY_POLICY_SIZE);
315 reply.WriteRawData(reinterpret_cast<const void*>(EMPTY_POLICY), EMPTY_POLICY_SIZE);
316 return ERR_OK;
317 }
318 std::streamsize size = infile.tellg();
319 if (size < 0 || size >= MAX_POLICY_FILE_SIZE) {
320 EDMLOGE("ManagedBrowserPolicyPlugin::OnGetPolicy size error.size: %{public}d", (int32_t)size);
321 infile.close();
322 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
323 }
324 infile.seekg(0, std::ios::beg);
325 std::string line;
326 std::vector<char> fileData;
327 fileData.push_back('{');
328 while (std::getline(infile, line)) {
329 fileData.insert(fileData.end(), line.begin(), line.end());
330 if (fileData.back() == '\n') {
331 fileData.pop_back();
332 }
333 fileData.push_back(',');
334 }
335 if (fileData.back() == ',') {
336 fileData.pop_back();
337 }
338 fileData.push_back('}');
339 fileData.push_back('\0');
340 infile.close();
341 if (fileData.size() < 0 || fileData.size() >= MAX_POLICY_FILE_SIZE) {
342 EDMLOGE("ManagedBrowserPolicyPlugin::OnGetPolicy fileData.size error.size: %{public}d",
343 (int32_t)fileData.size());
344 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
345 }
346 reply.WriteInt32(ERR_OK);
347 reply.WriteInt32(fileData.size());
348 reply.WriteRawData(reinterpret_cast<const void*>(fileData.data()), fileData.size());
349 return ERR_OK;
350 }
351
GetManagedBrowserPolicyVersion(const std::string & policyData,const std::string & bundleName,MessageParcel & reply)352 ErrCode ManagedBrowserPolicyPlugin::GetManagedBrowserPolicyVersion(const std::string &policyData,
353 const std::string &bundleName, MessageParcel &reply)
354 {
355 auto serializer = ManagedBrowserPolicySerializer::GetInstance();
356 std::map<std::string, ManagedBrowserPolicyType> policies;
357 if (!serializer->Deserialize(policyData, policies)) {
358 EDMLOGE("ManagedBrowserPolicyPlugin::OnGetPolicy Deserialize fail");
359 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
360 }
361 reply.WriteInt32(ERR_OK);
362 auto it = policies.find(bundleName);
363 if (it == policies.end()) {
364 int32_t emptyVersion = 0;
365 reply.WriteInt32(emptyVersion);
366 } else {
367 reply.WriteInt32((int32_t)it->second.version);
368 }
369 return ERR_OK;
370 }
371
FindPolicyNameInLine(const std::string & line,std::string & policyNameInLine)372 bool ManagedBrowserPolicyPlugin::FindPolicyNameInLine(const std::string &line, std::string &policyNameInLine)
373 {
374 size_t pos = line.find(':');
375 if (pos != std::string::npos && pos > 0) {
376 policyNameInLine = line.substr(0, pos);
377 return true;
378 }
379 return false;
380 }
381
GetCallingBundleName(std::string & bundleName)382 bool ManagedBrowserPolicyPlugin::GetCallingBundleName(std::string &bundleName)
383 {
384 auto bundleMgr = std::make_shared<EdmBundleManagerImpl>();
385 int uid = IPCSkeleton::GetCallingUid();
386 if (bundleMgr->GetNameForUid(uid, bundleName) != ERR_OK || bundleName.empty()) {
387 EDMLOGW("ManagedBrowserPolicyPlugin::OnGetPolicy failed: get bundleName for uid %{public}d fail.", uid);
388 return false;
389 }
390 return true;
391 }
392
OnAdminRemove(const std::string & adminName,const std::string & policyData,const std::string & mergeData,int32_t userId)393 ErrCode ManagedBrowserPolicyPlugin::OnAdminRemove(const std::string &adminName,
394 const std::string &policyData, const std::string &mergeData, int32_t userId)
395 {
396 auto serializer = ManagedBrowserPolicySerializer::GetInstance();
397 std::map<std::string, ManagedBrowserPolicyType> policies;
398 if (!serializer->Deserialize(policyData, policies)) {
399 EDMLOGE("ManagedBrowserPolicyPlugin::OnAdminRemove Deserialize fail");
400 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
401 }
402 for (auto& it : policies) {
403 std::string url = MANAGED_BROWSER_POLICY_DIR + it.first + MANAGED_BROWSER_POLICY_SUFFIX;
404 if (remove(url.c_str()) != 0) {
405 EDMLOGE("ManagedBrowserPolicyPlugin::OnAdminRemove remove failed.bundleName:%{public}s", it.first.c_str());
406 }
407 }
408 return ERR_OK;
409 }
410
UpdatePolicyFile(std::map<std::string,ManagedBrowserPolicyType> & policies,const std::string & bundleName,std::string & url,std::string & tempUrl)411 bool ManagedBrowserPolicyPlugin::UpdatePolicyFile(std::map<std::string, ManagedBrowserPolicyType> &policies,
412 const std::string &bundleName, std::string &url, std::string &tempUrl)
413 {
414 if (remove(url.c_str()) != 0) {
415 remove(tempUrl.c_str());
416 EDMLOGE("ManagedBrowserPolicyPlugin::updatePolicyFile remove inFile fail");
417 return false;
418 }
419
420 if (rename(tempUrl.c_str(), url.c_str()) != 0) {
421 remove(tempUrl.c_str());
422 policies.erase(bundleName);
423 EDMLOGE("ManagedBrowserPolicyPlugin::updatePolicyFile rename tempFile fail");
424 return false;
425 }
426 return true;
427 }
428 } // namespace EDM
429 } // namespace OHOS
430