• 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 "plugin_manager.h"
35 #include "policy_manager.h"
36 #include "want.h"
37 
38 namespace OHOS {
39 namespace EDM {
40 const bool REGISTER_RESULT = PluginManager::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_ = "managed_browser_policy";
52     permissionMap_.insert(std::make_pair(
53         FuncOperateType::SET, IPlugin::PolicyPermissionConfig("ohos.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 
66     std::string bundleName = data.ReadString();
67     std::string policyName = data.ReadString();
68     std::string policyValue = data.ReadString();
69     if (bundleName.empty() || policyName.empty() || bundleName.find("..") != std::string::npos) {
70         return EdmReturnErrCode::PARAM_ERROR;
71     }
72 
73     auto policyManager = IPolicyManager::GetInstance();
74     policyManager->GetPolicy("", "managed_browser_policy", policyData.policyData);
75 
76     auto serializer = ManagedBrowserPolicySerializer::GetInstance();
77     std::map<std::string, ManagedBrowserPolicyType> policies;
78     if (!serializer->Deserialize(policyData.policyData, policies)) {
79         EDMLOGE("ManagedBrowserPolicyPlugin::OnHandlePolicy Deserialize fail");
80         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
81     }
82 
83     ErrCode ret = EdmReturnErrCode::SYSTEM_ABNORMALLY;
84     std::vector<std::string> &policyNames = policies[bundleName].policyNames;
85     auto it = std::find(policyNames.begin(), policyNames.end(), policyName);
86     bool isModifyOrRemove = (it != policyNames.end());
87     if (isModifyOrRemove) {
88         if (policyValue.empty()) {
89             policyNames.erase(it);
90         }
91     } else {
92         policies[bundleName].policyNames.push_back(policyName);
93     }
94     policies[bundleName].version++;
95 
96     std::string afterHandle;
97     if (!serializer->Serialize(policies, afterHandle)) {
98         EDMLOGE("ManagedBrowserPolicyPlugin::OnHandlePolicy Serialize fail");
99         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
100     }
101 
102     size_t pos = 0;
103     while ((pos = policyValue.find("\n", pos)) != std::string::npos) {
104         policyValue.replace(pos, 1, "");
105     }
106 
107     if (isModifyOrRemove) {
108         ret = ModifyOrRemoveManagedBrowserPolicy(policies, bundleName, policyName, policyValue);
109     } else {
110         ret = AddManagedBrowserPolicy(policies, bundleName, policyName, policyValue);
111     }
112     if (ret != ERR_OK) {
113         return ret;
114     }
115 
116     policyData.isChanged = true;
117     policyData.policyData = afterHandle;
118 
119     return ret;
120 }
121 
ModifyOrRemoveManagedBrowserPolicy(std::map<std::string,ManagedBrowserPolicyType> & policies,const std::string & bundleName,const std::string & policyName,const std::string & policyValue)122 ErrCode ManagedBrowserPolicyPlugin::ModifyOrRemoveManagedBrowserPolicy(
123     std::map<std::string, ManagedBrowserPolicyType> &policies, const std::string &bundleName,
124     const std::string &policyName, const std::string &policyValue)
125 {
126     EDMLOGI("ManagedBrowserPolicyPlugin::ModifyOrRemoveManagedBrowserPolicy start");
127     std::string url = MANAGED_BROWSER_POLICY_DIR + bundleName + MANAGED_BROWSER_POLICY_SUFFIX;
128     if (!EdmUtils::CheckRealPath(url, MANAGED_BROWSER_POLICY_DIR)) {
129         EDMLOGE("ManagedBrowserPolicyPlugin::CheckRealPath fail");
130         return EdmReturnErrCode::PARAM_ERROR;
131     }
132     std::ifstream inFile(url);
133     if (inFile.fail()) {
134         EDMLOGE("ManagedBrowserPolicyPlugin::ModifyOrRemoveManagedBrowserPolicy open file fail");
135         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
136     }
137 
138     std::string tempUrl = MANAGED_BROWSER_POLICY_DIR + bundleName + "_tmp" + MANAGED_BROWSER_POLICY_SUFFIX;
139     std::ofstream tempOutFile(tempUrl);
140     if (tempOutFile.fail()) {
141         EDMLOGE("ManagedBrowserPolicyPlugin::ModifyOrRemoveManagedBrowserPolicy open file fail");
142         inFile.close();
143         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
144     }
145     std::string policyNameWithQuotation = "\"" + policyName + "\"";
146     std::string line;
147     while (std::getline(inFile, line)) {
148         std::string policyNameInLine;
149         if (!FindPolicyNameInLine(line, policyNameInLine)) {
150             EDMLOGE("can not find policyNameInLine");
151             inFile.close();
152             tempOutFile.close();
153             return EdmReturnErrCode::SYSTEM_ABNORMALLY;
154         }
155 
156         if (policyNameInLine == policyNameWithQuotation) {
157             if (policyValue.empty()) {
158                 continue;
159             } else {
160                 tempOutFile << policyNameWithQuotation << ":" << policyValue << std::endl;
161             }
162         } else {
163             tempOutFile << line << std::endl;
164         }
165     }
166 
167     inFile.close();
168     tempOutFile.close();
169 
170     return UpdatePolicyFile(policies, bundleName, url, tempUrl) ? ERR_OK : EdmReturnErrCode::SYSTEM_ABNORMALLY;
171 }
172 
AddManagedBrowserPolicy(std::map<std::string,ManagedBrowserPolicyType> & policies,const std::string & bundleName,const std::string & policyName,const std::string & policyValue)173 ErrCode ManagedBrowserPolicyPlugin::AddManagedBrowserPolicy(std::map<std::string, ManagedBrowserPolicyType> &policies,
174     const std::string &bundleName, const std::string &policyName, const std::string &policyValue)
175 {
176     std::string url = MANAGED_BROWSER_POLICY_DIR + bundleName + MANAGED_BROWSER_POLICY_SUFFIX;
177     std::ofstream outfile(url, std::ios::app);
178     if (outfile.fail()) {
179         EDMLOGE("ManagedBrowserPolicyPlugin::AddManagedBrowserPolicy open file fail");
180         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
181     }
182     std::string newPolicy = "\"" + policyName + "\":" + policyValue;
183     outfile << newPolicy << std::endl;
184     outfile.close();
185     return ERR_OK;
186 }
187 
OnHandlePolicyDone(std::uint32_t funcCode,const std::string & adminName,bool isGlobalChanged,int32_t userId)188 void ManagedBrowserPolicyPlugin::OnHandlePolicyDone(std::uint32_t funcCode, const std::string &adminName,
189     bool isGlobalChanged, int32_t userId)
190 {
191     EDMLOGD("ManagedBrowserPolicyPlugin::OnHandlePolicyDone called");
192     AAFwk::Want want;
193     want.SetAction(BROWSER_POLICY_CHANGED_EVENT);
194     EventFwk::CommonEventData eventData;
195     eventData.SetWant(want);
196     if (!EventFwk::CommonEventManager::PublishCommonEvent(eventData)) {
197         EDMLOGE("NotifyBrowserPolicyChanged failed.");
198     }
199 }
200 
OnGetPolicy(std::string & policyData,MessageParcel & data,MessageParcel & reply,int32_t userId)201 ErrCode ManagedBrowserPolicyPlugin::OnGetPolicy(std::string &policyData, MessageParcel &data, MessageParcel &reply,
202     int32_t userId)
203 {
204     std::string type = data.ReadString();
205     EDMLOGI("ManagedBrowserPolicyPlugin::OnGetPolicy type %{public}s", type.c_str());
206     std::string bundleName;
207     if (type == EdmConstants::Browser::GET_MANAGED_BROWSER_FILE_DATA) {
208         bundleName = data.ReadString();
209     } else if (!GetCallingBundleName(bundleName)) {
210         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
211     }
212     if (bundleName.empty() || bundleName.find("..") != std::string::npos) {
213         EDMLOGI("ManagedBrowserPolicyPlugin::OnGetPolicy bundleName empty");
214         return EdmReturnErrCode::PARAM_ERROR;
215     }
216 
217     if (type == EdmConstants::Browser::GET_MANAGED_BROWSER_VERSION) {
218         return GetManagedBrowserPolicyVersion(policyData, bundleName, reply);
219     } else if (type == EdmConstants::Browser::GET_MANAGED_BROWSER_FILE_DATA ||
220         type == EdmConstants::Browser::GET_SELF_MANAGED_BROWSER_FILE_DATA) {
221         return GetManagedBrowserPolicyFileData(bundleName, reply);
222     } else {
223         EDMLOGE("ManagedBrowserPolicyPlugin::OnGetPolicy type error");
224         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
225     }
226 }
227 
GetManagedBrowserPolicyFileData(const std::string & bundleName,MessageParcel & reply)228 ErrCode ManagedBrowserPolicyPlugin::GetManagedBrowserPolicyFileData(const std::string &bundleName, MessageParcel &reply)
229 {
230     std::string url = MANAGED_BROWSER_POLICY_DIR + bundleName + MANAGED_BROWSER_POLICY_SUFFIX;
231     std::ifstream infile(url, std::ios::binary | std::ios::ate);
232     if (infile.fail()) {
233         EDMLOGE("ManagedBrowserPolicyPlugin::OnGetPolicy open file fail");
234         reply.WriteInt32(ERR_OK);
235         reply.WriteInt32(EMPTY_POLICY_SIZE);
236         reply.WriteRawData(reinterpret_cast<const void*>(EMPTY_POLICY), EMPTY_POLICY_SIZE);
237         return ERR_OK;
238     }
239     std::streamsize size = infile.tellg();
240     if (size < 0 || size >= MAX_POLICY_FILE_SIZE) {
241         EDMLOGE("ManagedBrowserPolicyPlugin::OnGetPolicy size error.size: %{public}d", (int32_t)size);
242         infile.close();
243         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
244     }
245     infile.seekg(0, std::ios::beg);
246     std::string line;
247     std::vector<char> fileData;
248     fileData.push_back('{');
249     while (std::getline(infile, line)) {
250         fileData.insert(fileData.end(), line.begin(), line.end());
251         if (fileData.back() == '\n') {
252             fileData.pop_back();
253         }
254         fileData.push_back(',');
255     }
256     if (fileData.back() == ',') {
257         fileData.pop_back();
258     }
259     fileData.push_back('}');
260     fileData.push_back('\0');
261     infile.close();
262     if (fileData.size() < 0 || fileData.size() >= MAX_POLICY_FILE_SIZE) {
263         EDMLOGE("ManagedBrowserPolicyPlugin::OnGetPolicy fileData.size error.size: %{public}d",
264             (int32_t)fileData.size());
265         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
266     }
267     reply.WriteInt32(ERR_OK);
268     reply.WriteInt32(fileData.size());
269     reply.WriteRawData(reinterpret_cast<const void*>(fileData.data()), fileData.size());
270     return ERR_OK;
271 }
272 
GetManagedBrowserPolicyVersion(const std::string & policyData,const std::string & bundleName,MessageParcel & reply)273 ErrCode ManagedBrowserPolicyPlugin::GetManagedBrowserPolicyVersion(const std::string &policyData,
274     const std::string &bundleName, MessageParcel &reply)
275 {
276     auto serializer = ManagedBrowserPolicySerializer::GetInstance();
277     std::map<std::string, ManagedBrowserPolicyType> policies;
278     if (!serializer->Deserialize(policyData, policies)) {
279         EDMLOGE("ManagedBrowserPolicyPlugin::OnGetPolicy Deserialize fail");
280         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
281     }
282     reply.WriteInt32(ERR_OK);
283     auto it = policies.find(bundleName);
284     if (it == policies.end()) {
285         int32_t emptyVersion = 0;
286         reply.WriteInt32(emptyVersion);
287     } else {
288         reply.WriteInt32((int32_t)it->second.version);
289     }
290     return ERR_OK;
291 }
292 
FindPolicyNameInLine(const std::string & line,std::string & policyNameInLine)293 bool ManagedBrowserPolicyPlugin::FindPolicyNameInLine(const std::string &line, std::string &policyNameInLine)
294 {
295     size_t pos = line.find(':');
296     if (pos != std::string::npos && pos > 0) {
297         policyNameInLine = line.substr(0, pos);
298         return true;
299     }
300     return false;
301 }
302 
GetCallingBundleName(std::string & bundleName)303 bool ManagedBrowserPolicyPlugin::GetCallingBundleName(std::string &bundleName)
304 {
305     auto bundleMgr = std::make_shared<EdmBundleManagerImpl>();
306     int uid = IPCSkeleton::GetCallingUid();
307     if (bundleMgr->GetNameForUid(uid, bundleName) != ERR_OK || bundleName.empty()) {
308         EDMLOGW("ManagedBrowserPolicyPlugin::OnGetPolicy failed: get bundleName for uid %{public}d fail.", uid);
309         return false;
310     }
311     return true;
312 }
313 
OnAdminRemove(const std::string & adminName,const std::string & policyData,int32_t userId)314 ErrCode ManagedBrowserPolicyPlugin::OnAdminRemove(const std::string &adminName,
315     const std::string &policyData, int32_t userId)
316 {
317     auto serializer = ManagedBrowserPolicySerializer::GetInstance();
318     std::map<std::string, ManagedBrowserPolicyType> policies;
319     if (!serializer->Deserialize(policyData, policies)) {
320         EDMLOGE("ManagedBrowserPolicyPlugin::OnAdminRemove Deserialize fail");
321         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
322     }
323     for (auto& it : policies) {
324         std::string url = MANAGED_BROWSER_POLICY_DIR + it.first + MANAGED_BROWSER_POLICY_SUFFIX;
325         if (remove(url.c_str()) != 0) {
326             EDMLOGE("ManagedBrowserPolicyPlugin::OnAdminRemove remove failed.bundleName:%{public}s", it.first.c_str());
327         }
328     }
329     return ERR_OK;
330 }
331 
UpdatePolicyFile(std::map<std::string,ManagedBrowserPolicyType> & policies,const std::string & bundleName,std::string & url,std::string & tempUrl)332 bool ManagedBrowserPolicyPlugin::UpdatePolicyFile(std::map<std::string, ManagedBrowserPolicyType> &policies,
333     const std::string &bundleName, std::string &url, std::string &tempUrl)
334 {
335     if (remove(url.c_str()) != 0) {
336         remove(tempUrl.c_str());
337         EDMLOGE("ManagedBrowserPolicyPlugin::updatePolicyFile remove inFile fail");
338         return false;
339     }
340 
341     if (rename(tempUrl.c_str(), url.c_str()) != 0) {
342         remove(tempUrl.c_str());
343         policies.erase(bundleName);
344         EDMLOGE("ManagedBrowserPolicyPlugin::updatePolicyFile rename tempFile fail");
345         return false;
346     }
347     return true;
348 }
349 } // namespace EDM
350 } // namespace OHOS
351