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 "bundle_manager_proxy.h"
17
18 #include <fcntl.h>
19 #include <sys/stat.h>
20 #include <sys/types.h>
21 #include <unistd.h>
22
23 #include "directory_ex.h"
24 #include "edm_constants.h"
25 #include "edm_log.h"
26 #include "func_code.h"
27 #include "message_parcel_utils.h"
28 #include "policy_type.h"
29
30 namespace OHOS {
31 namespace EDM {
32 std::shared_ptr<BundleManagerProxy> BundleManagerProxy::instance_ = nullptr;
33 std::mutex BundleManagerProxy::mutexLock_;
34 const std::u16string DESCRIPTOR = u"ohos.edm.IEnterpriseDeviceMgr";
35 const std::string HAP_DIRECTORY = "/data/service/el1/public/edm/stream_install";
36 const std::string SEPARATOR = "/";
37 const int32_t DEFAULT_BUFFER_SIZE = 65536;
38
BundleManagerProxy()39 BundleManagerProxy::BundleManagerProxy()
40 {
41 AddPolicyTypeMap();
42 EDMLOGD("BundleManagerProxy()");
43 }
44
~BundleManagerProxy()45 BundleManagerProxy::~BundleManagerProxy()
46 {
47 EDMLOGD("~BundleManagerProxy()");
48 }
49
AddPolicyTypeMap()50 void BundleManagerProxy::AddPolicyTypeMap()
51 {
52 policyTypeMap_[static_cast<int32_t>(PolicyType::ALLOW_INSTALL)] = EdmInterfaceCode::ALLOWED_INSTALL_BUNDLES;
53 policyTypeMap_[static_cast<int32_t>(PolicyType::DISALLOW_INSTALL)] = EdmInterfaceCode::DISALLOWED_INSTALL_BUNDLES;
54 policyTypeMap_[static_cast<int32_t>(PolicyType::DISALLOW_UNINSTALL)] =
55 EdmInterfaceCode::DISALLOWED_UNINSTALL_BUNDLES;
56 }
57
GetBundleManagerProxy()58 std::shared_ptr<BundleManagerProxy> BundleManagerProxy::GetBundleManagerProxy()
59 {
60 if (instance_ == nullptr) {
61 std::lock_guard<std::mutex> lock(mutexLock_);
62 if (instance_ == nullptr) {
63 std::shared_ptr<BundleManagerProxy> temp = std::make_shared<BundleManagerProxy>();
64 instance_ = temp;
65 }
66 }
67 return instance_;
68 }
69
Uninstall(AppExecFwk::ElementName & admin,std::string bundleName,int32_t userId,bool isKeepData,std::string & retMessage)70 int32_t BundleManagerProxy::Uninstall(AppExecFwk::ElementName &admin, std::string bundleName, int32_t userId,
71 bool isKeepData, std::string &retMessage)
72 {
73 EDMLOGD("BundleManagerProxy::Uninstall");
74 auto proxy = EnterpriseDeviceMgrProxy::GetInstance();
75 if (proxy == nullptr) {
76 EDMLOGE("can not get EnterpriseDeviceMgrProxy");
77 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
78 }
79 MessageParcel data;
80 MessageParcel reply;
81 data.WriteInterfaceToken(DESCRIPTOR);
82 data.WriteInt32(WITHOUT_USERID);
83 data.WriteParcelable(&admin);
84 data.WriteString(bundleName);
85 data.WriteInt32(userId);
86 data.WriteBool(isKeepData);
87 std::uint32_t funcCode = POLICY_FUNC_CODE((std::uint32_t)FuncOperateType::SET, EdmInterfaceCode::UNINSTALL);
88 ErrCode ret = proxy->HandleDevicePolicy(funcCode, data, reply);
89 if (ret == EdmReturnErrCode::PARAM_ERROR) {
90 retMessage = reply.ReadString();
91 }
92 return ret;
93 }
94
AddBundlesByPolicyType(AppExecFwk::ElementName & admin,std::vector<std::string> & bundles,int32_t userId,int32_t policyType)95 int32_t BundleManagerProxy::AddBundlesByPolicyType(AppExecFwk::ElementName &admin, std::vector<std::string> &bundles,
96 int32_t userId, int32_t policyType)
97 {
98 EDMLOGD("BundleManagerProxy::AddBundlesByPolicyType policyType =%{public}d", policyType);
99 auto proxy = EnterpriseDeviceMgrProxy::GetInstance();
100 if (proxy == nullptr) {
101 EDMLOGE("can not get EnterpriseDeviceMgrProxy");
102 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
103 }
104 MessageParcel data;
105 std::uint32_t funcCode = 0;
106 if (policyTypeMap_.count(policyType) > 0) {
107 funcCode = POLICY_FUNC_CODE((std::uint32_t)FuncOperateType::SET, policyTypeMap_[policyType]);
108 } else {
109 EDMLOGE("can not get policy type");
110 return EdmReturnErrCode::PARAM_ERROR;
111 }
112 data.WriteInterfaceToken(DESCRIPTOR);
113 data.WriteInt32(HAS_USERID);
114 data.WriteInt32(userId);
115 data.WriteParcelable(&admin);
116 data.WriteStringVector(bundles);
117 return proxy->HandleDevicePolicy(funcCode, data);
118 }
119
RemoveBundlesByPolicyType(AppExecFwk::ElementName & admin,std::vector<std::string> & bundles,int32_t userId,int32_t policyType)120 int32_t BundleManagerProxy::RemoveBundlesByPolicyType(AppExecFwk::ElementName &admin, std::vector<std::string> &bundles,
121 int32_t userId, int32_t policyType)
122 {
123 EDMLOGD("BundleManagerProxy::RemoveBundlesByPolicyType policyType =%{public}d", policyType);
124 auto proxy = EnterpriseDeviceMgrProxy::GetInstance();
125 if (proxy == nullptr) {
126 EDMLOGE("can not get EnterpriseDeviceMgrProxy");
127 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
128 }
129 MessageParcel data;
130 std::uint32_t funcCode = 0;
131 if (policyTypeMap_.count(policyType) > 0) {
132 funcCode = POLICY_FUNC_CODE((std::uint32_t)FuncOperateType::REMOVE, policyTypeMap_[policyType]);
133 } else {
134 EDMLOGE("can not get policy type");
135 return EdmReturnErrCode::PARAM_ERROR;
136 }
137 data.WriteInterfaceToken(DESCRIPTOR);
138 data.WriteInt32(HAS_USERID);
139 data.WriteInt32(userId);
140 data.WriteParcelable(&admin);
141 data.WriteStringVector(bundles);
142 return proxy->HandleDevicePolicy(funcCode, data);
143 }
144
GetBundlesByPolicyType(AppExecFwk::ElementName & admin,int32_t userId,std::vector<std::string> & bundles,int32_t policyType)145 int32_t BundleManagerProxy::GetBundlesByPolicyType(AppExecFwk::ElementName &admin, int32_t userId,
146 std::vector<std::string> &bundles, int32_t policyType)
147 {
148 EDMLOGD("BundleManagerProxy::GetAllowedOrDisallowedInstallBundles policyType =%{public}d", policyType);
149 auto proxy = EnterpriseDeviceMgrProxy::GetInstance();
150 if (proxy == nullptr) {
151 EDMLOGE("can not get EnterpriseDeviceMgrProxy");
152 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
153 }
154 MessageParcel data;
155 MessageParcel reply;
156 data.WriteInterfaceToken(DESCRIPTOR);
157 data.WriteInt32(HAS_USERID);
158 data.WriteInt32(userId);
159 data.WriteInt32(HAS_ADMIN);
160 data.WriteParcelable(&admin);
161 if (policyTypeMap_.count(policyType) > 0) {
162 proxy->GetPolicy(policyTypeMap_[policyType], data, reply);
163 } else {
164 EDMLOGE("can not get policy type");
165 return EdmReturnErrCode::PARAM_ERROR;
166 }
167 int32_t ret = ERR_INVALID_VALUE;
168 bool blRes = reply.ReadInt32(ret) && (ret == ERR_OK);
169 if (!blRes) {
170 EDMLOGW("EnterpriseDeviceMgrProxy:GetPolicy fail. %{public}d", ret);
171 return ret;
172 }
173 int32_t size = reply.ReadInt32();
174 if (size > EdmConstants::APPID_MAX_SIZE) {
175 EDMLOGE("bundles size=[%{public}d] is too large", size);
176 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
177 }
178 reply.ReadStringVector(&bundles);
179 return ERR_OK;
180 }
181
Install(AppExecFwk::ElementName & admin,std::vector<std::string> & hapFilePaths,AppExecFwk::InstallParam & installParam,std::string & errMessage)182 int32_t BundleManagerProxy::Install(AppExecFwk::ElementName &admin, std::vector<std::string> &hapFilePaths,
183 AppExecFwk::InstallParam &installParam, std::string &errMessage)
184 {
185 EDMLOGD("BundleManagerProxy::install");
186
187 if (hapFilePaths.empty()) {
188 EDMLOGE("install failed due to empty hapFilePaths");
189 return EdmReturnErrCode::PARAM_ERROR;
190 }
191 std::vector<std::string> realPaths;
192 for (auto const &hapFilePath : hapFilePaths) {
193 ErrCode res = WriteFileToStream(admin, hapFilePath, realPaths, errMessage);
194 if (res != ERR_OK) {
195 EDMLOGE("WriteFileToStream failed");
196 return res;
197 }
198 }
199
200 auto proxy = EnterpriseDeviceMgrProxy::GetInstance();
201 if (proxy == nullptr) {
202 EDMLOGE("can not get EnterpriseDeviceMgrProxy");
203 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
204 }
205 MessageParcel data;
206 MessageParcel reply;
207 data.WriteInterfaceToken(DESCRIPTOR);
208 data.WriteInt32(WITHOUT_USERID);
209 data.WriteParcelable(&admin);
210 data.WriteStringVector(realPaths);
211 MessageParcelUtils::WriteInstallParam(installParam, data);
212 std::uint32_t funcCode = POLICY_FUNC_CODE((std::uint32_t)FuncOperateType::SET, EdmInterfaceCode::INSTALL);
213 ErrCode ret = proxy->HandleDevicePolicy(funcCode, data, reply);
214 if (ret == EdmReturnErrCode::APPLICATION_INSTALL_FAILED) {
215 errMessage = reply.ReadString();
216 EDMLOGE("Install failed");
217 }
218 return ret;
219 }
220
WriteFileToInner(MessageParcel & reply,const std::string & realPath,std::vector<std::string> & servicePaths,std::string & errMessage)221 ErrCode BundleManagerProxy::WriteFileToInner(MessageParcel &reply, const std::string &realPath,
222 std::vector<std::string> &servicePaths, std::string &errMessage)
223 {
224 int32_t sharedFd = reply.ReadFileDescriptor();
225 servicePaths.emplace_back(reply.ReadString());
226 if (sharedFd < 0) {
227 EDMLOGE("write file to stream failed due to invalid file descriptor");
228 errMessage = "write file to stream failed due to invalid file descriptor";
229 return EdmReturnErrCode::APPLICATION_INSTALL_FAILED;
230 }
231 int32_t outputFd = dup(sharedFd);
232 close(sharedFd);
233
234 int32_t inputFd = open(realPath.c_str(), O_RDONLY);
235 if (inputFd < 0) {
236 close(outputFd);
237 EDMLOGE("write file to stream failed due to open the hap file");
238 errMessage = "write file to stream failed due to open the hap file";
239 return EdmReturnErrCode::APPLICATION_INSTALL_FAILED;
240 }
241 char buffer[DEFAULT_BUFFER_SIZE] = {0};
242 int offset = -1;
243 while ((offset = read(inputFd, buffer, sizeof(buffer))) > 0) {
244 if (write(outputFd, buffer, offset) < 0) {
245 close(inputFd);
246 close(outputFd);
247 EDMLOGE("write file to the temp dir failed");
248 errMessage = "write file to the temp dir failed";
249 return EdmReturnErrCode::APPLICATION_INSTALL_FAILED;
250 }
251 }
252 close(inputFd);
253 fsync(outputFd);
254 close(outputFd);
255 return ERR_OK;
256 }
257
WriteFileToStream(AppExecFwk::ElementName & admin,const std::string & hapFilePath,std::vector<std::string> & servicePaths,std::string & errMessage)258 ErrCode BundleManagerProxy::WriteFileToStream(AppExecFwk::ElementName &admin, const std::string &hapFilePath,
259 std::vector<std::string> &servicePaths, std::string &errMessage)
260 {
261 std::string fileName;
262 std::string realPath;
263 ErrCode checkRet = checkHapFilePath(hapFilePath, fileName, realPath, errMessage);
264 if (checkRet != ERR_OK) {
265 return checkRet;
266 }
267
268 auto proxy = EnterpriseDeviceMgrProxy::GetInstance();
269 if (proxy == nullptr) {
270 EDMLOGE("can not get EnterpriseDeviceMgrProxy");
271 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
272 }
273
274 MessageParcel data;
275 MessageParcel reply;
276 data.WriteInterfaceToken(DESCRIPTOR);
277 data.WriteInt32(WITHOUT_USERID);
278 data.WriteInt32(HAS_ADMIN);
279 data.WriteParcelable(&admin);
280 data.WriteString(fileName);
281 proxy->GetPolicy(POLICY_FUNC_CODE((std::uint32_t)FuncOperateType::GET, EdmInterfaceCode::INSTALL), data, reply);
282 int32_t ret = ERR_INVALID_VALUE;
283 bool blRes = reply.ReadInt32(ret) && (ret == ERR_OK);
284 if (!blRes) {
285 EDMLOGW("BundleManagerProxy:WriteFileToStream fail. %{public}d", ret);
286 errMessage = reply.ReadString();
287 return ret;
288 }
289 if (WriteFileToInner(reply, realPath, servicePaths, errMessage) != ERR_OK) {
290 EDMLOGE("write file to stream failed");
291 return EdmReturnErrCode::APPLICATION_INSTALL_FAILED;
292 }
293 return ERR_OK;
294 }
295
checkHapFilePath(const std::string & hapFilePath,std::string & fileName,std::string & realPath,std::string & errMessage)296 ErrCode BundleManagerProxy::checkHapFilePath(const std::string &hapFilePath, std::string &fileName,
297 std::string &realPath, std::string &errMessage)
298 {
299 if (!PathToRealPath(hapFilePath, realPath)) {
300 EDMLOGE("install failed due to invalid hapFilePaths");
301 errMessage = "install failed due to invalid hapFilePaths";
302 return EdmReturnErrCode::APPLICATION_INSTALL_FAILED;
303 }
304
305 // find hap file name
306 size_t pos = realPath.find_last_of(SEPARATOR);
307 if (pos == std::string::npos || pos == realPath.size() - 1) {
308 EDMLOGE("write file to stream failed due to invalid file path");
309 errMessage = "write file to stream failed due to invalid file path";
310 return EdmReturnErrCode::APPLICATION_INSTALL_FAILED;
311 }
312 fileName = realPath.substr(pos + 1);
313 if (fileName.empty()) {
314 EDMLOGE("write file to stream failed due to invalid file path");
315 errMessage = "write file to stream failed due to invalid file path";
316 return EdmReturnErrCode::APPLICATION_INSTALL_FAILED;
317 }
318 std::string innerFilePath = HAP_DIRECTORY + SEPARATOR + fileName;
319 if ((innerFilePath.length() > PATH_MAX)) {
320 errMessage = "invalid hap file path";
321 return EdmReturnErrCode::APPLICATION_INSTALL_FAILED;
322 }
323 return ERR_OK;
324 }
325 } // namespace EDM
326 } // namespace OHOS
327