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