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