1 /*
2  * Copyright (c) 2022-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 "quick_fix_manager_host_impl.h"
17 
18 #include "app_log_tag_wrapper.h"
19 #include "bundle_permission_mgr.h"
20 #include "bundle_util.h"
21 
22 namespace OHOS {
23 namespace AppExecFwk {
QuickFixManagerHostImpl()24 QuickFixManagerHostImpl::QuickFixManagerHostImpl()
25 {
26     LOG_I(BMS_TAG_DEFAULT, "create QuickFixManagerHostImpl");
27 }
28 
~QuickFixManagerHostImpl()29 QuickFixManagerHostImpl::~QuickFixManagerHostImpl()
30 {
31     LOG_I(BMS_TAG_DEFAULT, "destory QuickFixManagerHostImpl");
32 }
33 
DeployQuickFix(const std::vector<std::string> & bundleFilePaths,const sptr<IQuickFixStatusCallback> & statusCallback,bool isDebug,const std::string & targetPath)34 ErrCode QuickFixManagerHostImpl::DeployQuickFix(const std::vector<std::string> &bundleFilePaths,
35     const sptr<IQuickFixStatusCallback> &statusCallback, bool isDebug, const std::string &targetPath)
36 {
37     LOG_I(BMS_TAG_DEFAULT, "QuickFixManagerHostImpl::DeployQuickFix start");
38     if (bundleFilePaths.empty() || (statusCallback == nullptr)) {
39         LOG_E(BMS_TAG_DEFAULT, "QuickFixManagerHostImpl::DeployQuickFix wrong parms");
40         return ERR_BUNDLEMANAGER_QUICK_FIX_PARAM_ERROR;
41     }
42     if (!BundlePermissionMgr::IsSystemApp()) {
43         LOG_E(BMS_TAG_DEFAULT, "non-system app is not allowed call this function");
44         return ERR_BUNDLE_MANAGER_SYSTEM_API_DENIED;
45     }
46     if (!BundlePermissionMgr::VerifyCallingPermissionForAll(Constants::PERMISSION_INSTALL_BUNDLE) &&
47         !BundlePermissionMgr::VerifyCallingPermissionForAll(ServiceConstants::PERMISSION_INSTALL_QUICK_FIX_BUNDLE)) {
48         LOG_E(BMS_TAG_DEFAULT, "verify install permission failed");
49         return ERR_BUNDLEMANAGER_QUICK_FIX_PERMISSION_DENIED;
50     }
51     if (!GetQuickFixMgr()) {
52         LOG_E(BMS_TAG_DEFAULT, "QuickFixManagerHostImpl::DeployQuickFix quickFixerMgr is nullptr");
53         return ERR_BUNDLEMANAGER_QUICK_FIX_INTERNAL_ERROR;
54     }
55     std::vector<std::string> securityFilePaths;
56     ErrCode result = CopyHqfToSecurityDir(bundleFilePaths, securityFilePaths);
57     if (result != ERR_OK) {
58         LOG_E(BMS_TAG_DEFAULT, "copy file to secure dir failed %{public}d", result);
59         return result;
60     }
61     return quickFixMgr_->DeployQuickFix(securityFilePaths, statusCallback, isDebug, targetPath);
62 }
63 
SwitchQuickFix(const std::string & bundleName,bool enable,const sptr<IQuickFixStatusCallback> & statusCallback)64 ErrCode QuickFixManagerHostImpl::SwitchQuickFix(const std::string &bundleName, bool enable,
65     const sptr<IQuickFixStatusCallback> &statusCallback)
66 {
67     LOG_I(BMS_TAG_DEFAULT, "QuickFixManagerHostImpl::SwitchQuickFix start");
68     if (bundleName.empty() || (statusCallback == nullptr)) {
69         LOG_E(BMS_TAG_DEFAULT, "QuickFixManagerHostImpl::SwitchQuickFix wrong parms");
70         return ERR_BUNDLEMANAGER_QUICK_FIX_PARAM_ERROR;
71     }
72     if (!BundlePermissionMgr::IsSystemApp()) {
73         LOG_E(BMS_TAG_DEFAULT, "non-system app is not allowed call this function");
74         return ERR_BUNDLE_MANAGER_SYSTEM_API_DENIED;
75     }
76     if (!BundlePermissionMgr::VerifyCallingPermissionForAll(Constants::PERMISSION_INSTALL_BUNDLE) &&
77         !BundlePermissionMgr::VerifyCallingPermissionForAll(ServiceConstants::PERMISSION_INSTALL_QUICK_FIX_BUNDLE)) {
78         LOG_E(BMS_TAG_DEFAULT, "verify install permission failed");
79         return ERR_BUNDLEMANAGER_QUICK_FIX_PERMISSION_DENIED;
80     }
81     if (!GetQuickFixMgr()) {
82         LOG_E(BMS_TAG_DEFAULT, "QuickFixManagerHostImpl::SwitchQuickFix quickFixerMgr is nullptr");
83         return ERR_BUNDLEMANAGER_QUICK_FIX_INTERNAL_ERROR;
84     }
85 
86     return quickFixMgr_->SwitchQuickFix(bundleName, enable, statusCallback);
87 }
88 
DeleteQuickFix(const std::string & bundleName,const sptr<IQuickFixStatusCallback> & statusCallback)89 ErrCode QuickFixManagerHostImpl::DeleteQuickFix(const std::string &bundleName,
90     const sptr<IQuickFixStatusCallback> &statusCallback)
91 {
92     LOG_I(BMS_TAG_DEFAULT, "QuickFixManagerHostImpl::DeleteQuickFix start");
93     if (bundleName.empty() || (statusCallback == nullptr)) {
94         LOG_E(BMS_TAG_DEFAULT, "QuickFixManagerHostImpl::DeleteQuickFix wrong parms");
95         return ERR_BUNDLEMANAGER_QUICK_FIX_PARAM_ERROR;
96     }
97     if (!BundlePermissionMgr::IsSystemApp()) {
98         LOG_E(BMS_TAG_DEFAULT, "non-system app is not allowed call this function");
99         return ERR_BUNDLE_MANAGER_SYSTEM_API_DENIED;
100     }
101     if (!BundlePermissionMgr::VerifyCallingPermissionForAll(Constants::PERMISSION_INSTALL_BUNDLE) &&
102         !BundlePermissionMgr::VerifyCallingPermissionForAll(ServiceConstants::PERMISSION_UNINSTALL_QUICK_FIX_BUNDLE)) {
103         LOG_E(BMS_TAG_DEFAULT, "verify install permission failed");
104         return ERR_BUNDLEMANAGER_QUICK_FIX_PERMISSION_DENIED;
105     }
106     if (!GetQuickFixMgr()) {
107         LOG_E(BMS_TAG_DEFAULT, "QuickFixManagerHostImpl::DeleteQuickFix quickFixerMgr is nullptr");
108         return ERR_BUNDLEMANAGER_QUICK_FIX_INTERNAL_ERROR;
109     }
110 
111     return quickFixMgr_->DeleteQuickFix(bundleName, statusCallback);
112 }
113 
CreateFd(const std::string & fileName,int32_t & fd,std::string & path)114 ErrCode QuickFixManagerHostImpl::CreateFd(const std::string &fileName, int32_t &fd, std::string &path)
115 {
116     LOG_D(BMS_TAG_DEFAULT, "QuickFixManagerHostImpl::CreateFd start");
117     if (!BundlePermissionMgr::IsSystemApp()) {
118         LOG_E(BMS_TAG_DEFAULT, "non-system app is not allowed call this function");
119         return ERR_BUNDLE_MANAGER_SYSTEM_API_DENIED;
120     }
121     if (!BundlePermissionMgr::VerifyCallingPermissionForAll(Constants::PERMISSION_INSTALL_BUNDLE) &&
122         !BundlePermissionMgr::VerifyCallingPermissionForAll(ServiceConstants::PERMISSION_INSTALL_QUICK_FIX_BUNDLE)) {
123         LOG_E(BMS_TAG_DEFAULT, "verify install permission failed");
124         return ERR_BUNDLEMANAGER_QUICK_FIX_PERMISSION_DENIED;
125     }
126     if (!BundleUtil::CheckFileType(fileName, ServiceConstants::QUICK_FIX_FILE_SUFFIX)) {
127         LOG_E(BMS_TAG_DEFAULT, "not quick fix file");
128         return ERR_BUNDLEMANAGER_QUICK_FIX_PARAM_ERROR;
129     }
130     if (!IsFileNameValid(fileName)) {
131         LOG_E(BMS_TAG_DEFAULT, "invalid fileName");
132         return ERR_BUNDLEMANAGER_QUICK_FIX_PARAM_ERROR;
133     }
134     std::string tmpDir = BundleUtil::CreateInstallTempDir(++id_, DirType::QUICK_FIX_DIR);
135     if (tmpDir.empty()) {
136         LOG_E(BMS_TAG_DEFAULT, "create tmp dir failed");
137         return ERR_BUNDLEMANAGER_QUICK_FIX_CREATE_TARGET_DIR_FAILED;
138     }
139     path = tmpDir + fileName;
140     if ((fd = BundleUtil::CreateFileDescriptor(path, 0)) < 0) {
141         LOG_E(BMS_TAG_DEFAULT, "create file descriptor failed");
142         BundleUtil::DeleteDir(tmpDir);
143         return ERR_BUNDLEMANAGER_QUICK_FIX_CREATE_FD_FAILED;
144     }
145     return ERR_OK;
146 }
147 
GetQuickFixMgr()148 bool QuickFixManagerHostImpl::GetQuickFixMgr()
149 {
150     if (quickFixMgr_ == nullptr) {
151         quickFixMgr_ = std::make_shared<QuickFixMgr>();
152     }
153     return true;
154 }
155 
IsFileNameValid(const std::string & fileName) const156 bool QuickFixManagerHostImpl::IsFileNameValid(const std::string &fileName) const
157 {
158     if (fileName.find("..") != std::string::npos
159         || fileName.find("/") != std::string::npos
160         || fileName.find("\\") != std::string::npos
161         || fileName.find("%") != std::string::npos) {
162         return false;
163     }
164     return true;
165 }
166 
CopyHqfToSecurityDir(const std::vector<std::string> & bundleFilePaths,std::vector<std::string> & securityFilePaths) const167 ErrCode QuickFixManagerHostImpl::CopyHqfToSecurityDir(const std::vector<std::string> &bundleFilePaths,
168     std::vector<std::string> &securityFilePaths) const
169 {
170     LOG_D(BMS_TAG_DEFAULT, "start to copy hqf files to securityFilePaths");
171     std::string prefixStr = ServiceConstants::HAP_COPY_PATH + ServiceConstants::PATH_SEPARATOR
172         + ServiceConstants::QUICK_FIX_PATH;
173     for (const auto &path : bundleFilePaths) {
174         if (path.find(ServiceConstants::RELATIVE_PATH) != std::string::npos) {
175             LOG_E(BMS_TAG_DEFAULT, "invalid hqf path %{public}s", path.c_str());
176             return ERR_BUNDLEMANAGER_QUICK_FIX_INVALID_PATH;
177         }
178         if (path.find(prefixStr) != 0) {
179             LOG_E(BMS_TAG_DEFAULT, "invalid hqf path %{public}s", path.c_str());
180             return ERR_BUNDLEMANAGER_QUICK_FIX_INVALID_PATH;
181         }
182         std::string securityPathPrefix = ServiceConstants::HAP_COPY_PATH + ServiceConstants::PATH_SEPARATOR +
183             ServiceConstants::SECURITY_QUICK_FIX_PATH;
184         std::string securityPath = path;
185         securityPath.replace(0, prefixStr.length(), securityPathPrefix);
186 
187         auto pos = securityPath.rfind(ServiceConstants::PATH_SEPARATOR);
188         if (pos == std::string::npos) {
189             return ERR_BUNDLEMANAGER_QUICK_FIX_INVALID_PATH;
190         }
191         std::string secureDir = securityPath.substr(0, pos);
192         if (!BundleUtil::CreateDir(secureDir)) {
193             return ERR_BUNDLEMANAGER_QUICK_FIX_INTERNAL_ERROR;
194         }
195         LOG_D(BMS_TAG_DEFAULT, "copy hqf file from path(%{public}s) to securePath(%{public}s)",
196             path.c_str(), securityPath.c_str());
197         if (!BundleUtil::CopyFile(path, securityPath)) {
198             LOG_E(BMS_TAG_DEFAULT, "CopyFile failed");
199             return ERR_BUNDLEMANAGER_QUICK_FIX_MOVE_PATCH_FILE_FAILED;
200         }
201         securityFilePaths.emplace_back(securityPath);
202     }
203     BundleUtil::DeleteDir(prefixStr);
204     return ERR_OK;
205 }
206 }
207 } // namespace OHOS
208