• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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