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 "install_plugin.h"
17
18 #include <fcntl.h>
19 #include <sys/stat.h>
20 #include <sys/types.h>
21 #include <system_ability_definition.h>
22 #include <unistd.h>
23
24 #include "bundle_mgr_interface.h"
25 #include "bundle_mgr_proxy.h"
26 #include "directory_ex.h"
27 #include "edm_ipc_interface_code.h"
28 #include "edm_sys_manager.h"
29 #include "install_param_serializer.h"
30 #include "installer_callback.h"
31 #include "iplugin_manager.h"
32
33 namespace OHOS {
34 namespace EDM {
35 const bool REGISTER_RESULT = IPluginManager::GetInstance()->AddPlugin(InstallPlugin::GetPlugin());
36 const std::string HAP_DIRECTORY = "/data/service/el1/public/edm/stream_install";
37 const std::string RELATIVE_PATH = "../";
38 const std::string CURRENT_PATH = "./";
39 const std::string SEPARATOR = "/";
40 constexpr int32_t EDM_UID = 3057;
41 constexpr int32_t EDM_GID = 3057;
42
InitPlugin(std::shared_ptr<IPluginTemplate<InstallPlugin,InstallParam>> ptr)43 void InstallPlugin::InitPlugin(std::shared_ptr<IPluginTemplate<InstallPlugin, InstallParam>> ptr)
44 {
45 EDMLOGI("InstallPlugin InitPlugin...");
46 ptr->InitAttribute(EdmInterfaceCode::INSTALL, "install", EdmPermission::PERMISSION_ENTERPRISE_INSTALL_BUNDLE,
47 IPlugin::PermissionType::SUPER_DEVICE_ADMIN, false);
48 ptr->SetSerializer(InstallParamSerializer::GetInstance());
49 ptr->SetOnHandlePolicyListener(&InstallPlugin::OnSetPolicy, FuncOperateType::SET);
50 }
51
OnGetPolicy(std::string & policyData,MessageParcel & data,MessageParcel & reply,int32_t userId)52 ErrCode InstallPlugin::OnGetPolicy(std::string &policyData, MessageParcel &data, MessageParcel &reply, int32_t userId)
53 {
54 std::string fileName = data.ReadString();
55 std::string bundlePath = HAP_DIRECTORY + "/" + fileName;
56
57 if (bundlePath.length() > PATH_MAX) {
58 EDMLOGE("bundlePath length is error, the length is: [%{public}zu]", bundlePath.length());
59 reply.WriteInt32(EdmReturnErrCode::APPLICATION_INSTALL_FAILED);
60 reply.WriteString("invalid hapFilePath");
61 return EdmReturnErrCode::APPLICATION_INSTALL_FAILED;
62 }
63 if (fileName.find(RELATIVE_PATH) != std::string::npos || fileName.find(CURRENT_PATH) != std::string::npos ||
64 fileName.find(SEPARATOR) != std::string::npos) {
65 EDMLOGE("file path %{public}s invalid", bundlePath.c_str());
66 reply.WriteInt32(EdmReturnErrCode::APPLICATION_INSTALL_FAILED);
67 reply.WriteString("invalid hapFilePath");
68 return EdmReturnErrCode::APPLICATION_INSTALL_FAILED;
69 }
70 if (!CreateDirectory()) {
71 reply.WriteInt32(EdmReturnErrCode::SYSTEM_ABNORMALLY);
72 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
73 }
74
75 int32_t fd = open(bundlePath.c_str(), O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
76 if (fd < 0) {
77 EDMLOGE("open bundlePath %{public}s failed", bundlePath.c_str());
78 DeleteFiles();
79 reply.WriteInt32(EdmReturnErrCode::SYSTEM_ABNORMALLY);
80 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
81 }
82 reply.WriteInt32(ERR_OK);
83 reply.WriteFileDescriptor(fd);
84 reply.WriteString(bundlePath);
85 return ERR_OK;
86 }
87
CreateDirectory()88 bool InstallPlugin::CreateDirectory()
89 {
90 if (!OHOS::ForceCreateDirectory(HAP_DIRECTORY)) {
91 EDMLOGE("mkdir %{public}s failed", HAP_DIRECTORY.c_str());
92 return false;
93 }
94 if (chown(HAP_DIRECTORY.c_str(), EDM_UID, EDM_GID) != 0) {
95 EDMLOGE("fail to change %{public}s ownership", HAP_DIRECTORY.c_str());
96 return false;
97 }
98 mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP;
99 if (!OHOS::ChangeModeFile(HAP_DIRECTORY, mode)) {
100 EDMLOGE("change mode failed, temp install dir : %{public}s", HAP_DIRECTORY.c_str());
101 return false;
102 }
103 return true;
104 }
105
DeleteFiles()106 bool InstallPlugin::DeleteFiles()
107 {
108 std::vector<std::string> files;
109 OHOS::GetDirFiles(HAP_DIRECTORY, files);
110
111 for (auto const &file : files) {
112 if (!OHOS::RemoveFile(file)) {
113 EDMLOGE("can not remove file : %{public}s", file.c_str());
114 return false;
115 }
116 }
117 return true;
118 }
119
OnSetPolicy(InstallParam & param,MessageParcel & reply)120 ErrCode InstallPlugin::OnSetPolicy(InstallParam ¶m, MessageParcel &reply)
121 {
122 EDMLOGI("InstallPlugin OnSetPolicy");
123 AppExecFwk::InstallParam installParam;
124 std::vector<std::string> realPaths;
125 ErrCode initRet = InstallParamInit(param, reply, installParam, realPaths);
126 if (initRet != ERR_OK) {
127 return initRet;
128 }
129
130 auto remoteObject = EdmSysManager::GetRemoteObjectOfSystemAbility(OHOS::BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
131 auto iBundleMgr = iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
132 if (iBundleMgr == nullptr) {
133 EDMLOGE("can not get iBundleMgr");
134 DeleteFiles();
135 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
136 }
137 auto iBundleInstaller = iBundleMgr->GetBundleInstaller();
138 if ((iBundleInstaller == nullptr) || (iBundleInstaller->AsObject() == nullptr)) {
139 EDMLOGE("can not get iBundleInstaller");
140 DeleteFiles();
141 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
142 }
143 sptr<InstallerCallback> callback = new (std::nothrow) InstallerCallback();
144 if (callback == nullptr) {
145 DeleteFiles();
146 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
147 }
148
149 ErrCode ret = iBundleInstaller->StreamInstall(realPaths, installParam, callback);
150 if (FAILED(ret)) {
151 if (!DeleteFiles()) {
152 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
153 }
154 EDMLOGE("StreamInstall resultCode %{public}d", ret);
155 reply.WriteInt32(EdmReturnErrCode::APPLICATION_INSTALL_FAILED);
156 reply.WriteString("invalid hap file path");
157 return EdmReturnErrCode::APPLICATION_INSTALL_FAILED;
158 }
159 ret = callback->GetResultCode();
160 std::string errorMessage = callback->GetResultMsg();
161 EDMLOGE("StreamInstall resultCode %{public}d resultMsg %{public}s.", ret, errorMessage.c_str());
162 if (!DeleteFiles()) {
163 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
164 }
165 if (ret != ERR_OK) {
166 reply.WriteInt32(EdmReturnErrCode::APPLICATION_INSTALL_FAILED);
167 reply.WriteString(errorMessage);
168 return EdmReturnErrCode::APPLICATION_INSTALL_FAILED;
169 }
170 EDMLOGI("InstallPlugin OnSetPolicy end");
171 return ERR_OK;
172 }
173
InstallParamInit(InstallParam & param,MessageParcel & reply,AppExecFwk::InstallParam & installParam,std::vector<std::string> & realPaths)174 ErrCode InstallPlugin::InstallParamInit(InstallParam ¶m, MessageParcel &reply,
175 AppExecFwk::InstallParam &installParam, std::vector<std::string> &realPaths)
176 {
177 installParam.userId = param.userId;
178 installParam.installFlag = static_cast<AppExecFwk::InstallFlag>(param.installFlag);
179 std::vector<std::string> hapFilePaths = param.hapFilePaths;
180
181 for (auto const &hapFilePath : hapFilePaths) {
182 std::string realPath = "";
183 if (!PathToRealPath(hapFilePath, realPath)) {
184 EDMLOGE("invalid hap file path");
185 std::string errMsg = "invalid hap file path";
186 reply.WriteInt32(EdmReturnErrCode::APPLICATION_INSTALL_FAILED);
187 reply.WriteString(errMsg);
188 DeleteFiles();
189 return EdmReturnErrCode::APPLICATION_INSTALL_FAILED;
190 }
191 realPaths.emplace_back(realPath);
192 }
193 return ERR_OK;
194 }
195 } // namespace EDM
196 } // namespace OHOS
197