• 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 "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, PolicyName::POLICY_INSTALL,
47         EdmPermission::PERMISSION_ENTERPRISE_INSTALL_BUNDLE, 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     close(fd);
86     fd = -1;
87     return ERR_OK;
88 }
89 
CreateDirectory()90 bool InstallPlugin::CreateDirectory()
91 {
92     if (!OHOS::ForceCreateDirectory(HAP_DIRECTORY)) {
93         EDMLOGE("mkdir %{public}s failed", HAP_DIRECTORY.c_str());
94         return false;
95     }
96     if (chown(HAP_DIRECTORY.c_str(), EDM_UID, EDM_GID) != 0) {
97         EDMLOGE("fail to change %{public}s ownership", HAP_DIRECTORY.c_str());
98         return false;
99     }
100     mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP;
101     if (!OHOS::ChangeModeFile(HAP_DIRECTORY, mode)) {
102         EDMLOGE("change mode failed, temp install dir : %{public}s", HAP_DIRECTORY.c_str());
103         return false;
104     }
105     return true;
106 }
107 
DeleteFiles()108 bool InstallPlugin::DeleteFiles()
109 {
110     std::vector<std::string> files;
111     OHOS::GetDirFiles(HAP_DIRECTORY, files);
112 
113     bool res = true;
114     for (auto const &file : files) {
115         if (!OHOS::RemoveFile(file)) {
116             EDMLOGW("can not remove file : %{public}s", file.c_str());
117             res = false;
118         }
119     }
120     return res;
121 }
122 
OnSetPolicy(InstallParam & param,MessageParcel & reply)123 ErrCode InstallPlugin::OnSetPolicy(InstallParam &param, MessageParcel &reply)
124 {
125     EDMLOGI("InstallPlugin OnSetPolicy");
126     AppExecFwk::InstallParam installParam;
127     std::vector<std::string> realPaths;
128     ErrCode initRet = InstallParamInit(param, reply, installParam, realPaths);
129     if (initRet != ERR_OK) {
130         return initRet;
131     }
132 
133     auto remoteObject = EdmSysManager::GetRemoteObjectOfSystemAbility(OHOS::BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
134     auto iBundleMgr = iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
135     if (iBundleMgr == nullptr) {
136         EDMLOGE("can not get iBundleMgr");
137         DeleteFiles();
138         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
139     }
140     auto iBundleInstaller = iBundleMgr->GetBundleInstaller();
141     if ((iBundleInstaller == nullptr) || (iBundleInstaller->AsObject() == nullptr)) {
142         EDMLOGE("can not get iBundleInstaller");
143         DeleteFiles();
144         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
145     }
146     sptr<InstallerCallback> callback = new (std::nothrow) InstallerCallback();
147     if (callback == nullptr) {
148         DeleteFiles();
149         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
150     }
151 
152     ErrCode ret = iBundleInstaller->StreamInstall(realPaths, installParam, callback);
153     if (FAILED(ret)) {
154         if (!DeleteFiles()) {
155             return EdmReturnErrCode::SYSTEM_ABNORMALLY;
156         }
157         EDMLOGE("StreamInstall resultCode %{public}d", ret);
158         reply.WriteInt32(EdmReturnErrCode::APPLICATION_INSTALL_FAILED);
159         reply.WriteString("invalid hap file path");
160         return EdmReturnErrCode::APPLICATION_INSTALL_FAILED;
161     }
162     ret = callback->GetResultCode();
163     std::string errorMessage = callback->GetResultMsg();
164     EDMLOGE("StreamInstall resultCode %{public}d resultMsg %{public}s.", ret, errorMessage.c_str());
165     if (!DeleteFiles()) {
166         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
167     }
168     if (ret != ERR_OK) {
169         reply.WriteInt32(EdmReturnErrCode::APPLICATION_INSTALL_FAILED);
170         reply.WriteString(errorMessage);
171         return EdmReturnErrCode::APPLICATION_INSTALL_FAILED;
172     }
173     EDMLOGI("InstallPlugin OnSetPolicy end");
174     return ERR_OK;
175 }
176 
InstallParamInit(InstallParam & param,MessageParcel & reply,AppExecFwk::InstallParam & installParam,std::vector<std::string> & realPaths)177 ErrCode InstallPlugin::InstallParamInit(InstallParam &param, MessageParcel &reply,
178     AppExecFwk::InstallParam &installParam, std::vector<std::string> &realPaths)
179 {
180     installParam.userId = param.userId;
181     installParam.installFlag = static_cast<AppExecFwk::InstallFlag>(param.installFlag);
182     std::vector<std::string> hapFilePaths = param.hapFilePaths;
183 
184     for (auto const &hapFilePath : hapFilePaths) {
185         std::string realPath = "";
186         if (!PathToRealPath(hapFilePath, realPath)) {
187             EDMLOGE("invalid hap file path");
188             std::string errMsg = "invalid hap file path";
189             reply.WriteInt32(EdmReturnErrCode::APPLICATION_INSTALL_FAILED);
190             reply.WriteString(errMsg);
191             DeleteFiles();
192             return EdmReturnErrCode::APPLICATION_INSTALL_FAILED;
193         }
194         realPaths.emplace_back(realPath);
195     }
196     installParam.parameters = param.parameters;
197     return ERR_OK;
198 }
199 } // namespace EDM
200 } // namespace OHOS
201