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 <csignal>
17 #include <mutex>
18 #include "module_update_stub.h"
19 
20 #include "accesstoken_kit.h"
21 #include "ipc_skeleton.h"
22 #include "isys_installer_callback.h"
23 #include "sys_installer_sa_ipc_interface_code.h"
24 
25 #include "log/log.h"
26 #include "string_ex.h"
27 
28 constexpr int USER_UPDATE_AUTHORITY = 6666;
29 
30 static std::mutex g_mtx;
31 namespace OHOS {
32 namespace SysInstaller {
33 using namespace std;
34 using namespace Updater;
35 using namespace std::placeholders;
36 
ModuleUpdateStub()37 ModuleUpdateStub::ModuleUpdateStub()
38 {
39     requestFuncMap_.emplace(ModuleUpdateInterfaceCode::INSTALL_MODULE_PACKAGE,
40         bind(&ModuleUpdateStub::InstallModulePackageStub, this, _1, _2, _3, _4));
41     requestFuncMap_.emplace(ModuleUpdateInterfaceCode::UNINSTALL_MODULE_PACKAGE,
42         bind(&ModuleUpdateStub::UninstallModulePackageStub, this, _1, _2, _3, _4));
43     requestFuncMap_.emplace(ModuleUpdateInterfaceCode::GET_MODULE_PACKAGE_INFO,
44         bind(&ModuleUpdateStub::GetModulePackageInfoStub, this, _1, _2, _3, _4));
45     requestFuncMap_.emplace(ModuleUpdateInterfaceCode::EXIT_MODULE_UPDATE,
46         bind(&ModuleUpdateStub::ExitModuleUpdateStub, this, _1, _2, _3, _4));
47 
48     requestFuncMap_.emplace(ModuleUpdateInterfaceCode::GET_HMP_VERSION_INFO,
49         bind(&ModuleUpdateStub::GetHmpVersionInfoStub, this, _1, _2, _3, _4));
50     requestFuncMap_.emplace(ModuleUpdateInterfaceCode::START_UPDATE_HMP_PACKAGE,
51         bind(&ModuleUpdateStub::StartUpdateHmpPackageStub, this, _1, _2, _3, _4));
52     requestFuncMap_.emplace(ModuleUpdateInterfaceCode::GET_HMP_UPDATE_RESULT,
53         bind(&ModuleUpdateStub::GetHmpUpdateResultStub, this, _1, _2, _3, _4));
54 }
55 
~ModuleUpdateStub()56 ModuleUpdateStub::~ModuleUpdateStub()
57 {
58     requestFuncMap_.clear();
59 }
60 
InstallModulePackageStub(ModuleUpdateStub * service,MessageParcel & data,MessageParcel & reply,MessageOption & option) const61 int32_t ModuleUpdateStub::InstallModulePackageStub(ModuleUpdateStub *service,
62     MessageParcel &data, MessageParcel &reply, MessageOption &option) const
63 {
64     if (service == nullptr) {
65         LOG(ERROR) << "Invalid param";
66         return -1;
67     }
68     string pkgPath = Str16ToStr8(data.ReadString16());
69     int32_t ret = service->InstallModulePackage(pkgPath);
70     reply.WriteInt32(ret);
71     return 0;
72 }
73 
UninstallModulePackageStub(ModuleUpdateStub * service,MessageParcel & data,MessageParcel & reply,MessageOption & option) const74 int32_t ModuleUpdateStub::UninstallModulePackageStub(ModuleUpdateStub *service,
75     MessageParcel &data, MessageParcel &reply, MessageOption &option) const
76 {
77     if (service == nullptr) {
78         LOG(ERROR) << "Invalid param";
79         return -1;
80     }
81     string hmpName = Str16ToStr8(data.ReadString16());
82     int32_t ret = service->UninstallModulePackage(hmpName);
83     reply.WriteInt32(ret);
84     return 0;
85 }
86 
GetModulePackageInfoStub(ModuleUpdateStub * service,MessageParcel & data,MessageParcel & reply,MessageOption & option) const87 int32_t ModuleUpdateStub::GetModulePackageInfoStub(ModuleUpdateStub *service,
88     MessageParcel &data, MessageParcel &reply, MessageOption &option) const
89 {
90     if (service == nullptr) {
91         LOG(ERROR) << "Invalid param";
92         return -1;
93     }
94     string hmpName = Str16ToStr8(data.ReadString16());
95     std::list<ModulePackageInfo> infos;
96     int32_t ret = service->GetModulePackageInfo(hmpName, infos);
97     ModuleIpcHelper::WriteModulePackageInfos(reply, infos);
98     reply.WriteInt32(ret);
99     return 0;
100 }
101 
ExitModuleUpdateStub(ModuleUpdateStub * service,MessageParcel & data,MessageParcel & reply,MessageOption & option) const102 int32_t ModuleUpdateStub::ExitModuleUpdateStub(ModuleUpdateStub *service,
103     MessageParcel &data, MessageParcel &reply, MessageOption &option) const
104 {
105     if (service == nullptr) {
106         LOG(ERROR) << "Invalid param";
107         return -1;
108     }
109     int32_t ret = service->ExitModuleUpdate();
110     std::lock_guard<std::mutex> locker(g_mtx);
111     reply.WriteInt32(ret);
112     return 0;
113 }
114 
GetHmpVersionInfoStub(ModuleUpdateStub * service,MessageParcel & data,MessageParcel & reply,MessageOption & option) const115 int32_t ModuleUpdateStub::GetHmpVersionInfoStub(ModuleUpdateStub *service,
116     MessageParcel &data, MessageParcel &reply, MessageOption &option) const
117 {
118     if (service == nullptr) {
119         LOG(ERROR) << "Invalid param";
120         return -1;
121     }
122     std::vector<HmpVersionInfo> versionInfo = service->GetHmpVersionInfo();
123     reply.WriteInt32(versionInfo.size());
124     for (auto &info : versionInfo) {
125         reply.WriteParcelable(&info);
126     }
127     return 0;
128 }
129 
StartUpdateHmpPackageStub(ModuleUpdateStub * service,MessageParcel & data,MessageParcel & reply,MessageOption & option) const130 int32_t ModuleUpdateStub::StartUpdateHmpPackageStub(ModuleUpdateStub *service,
131     MessageParcel &data, MessageParcel &reply, MessageOption &option) const
132 {
133     if (service == nullptr) {
134         LOG(ERROR) << "Invalid param";
135         return -1;
136     }
137 
138     sptr<IRemoteObject> object = data.ReadRemoteObject();
139     if (object == nullptr) {
140         LOG(ERROR) << "object null";
141         return -1;
142     }
143 
144     sptr<ISysInstallerCallback> updateCallback = iface_cast<ISysInstallerCallback>(object);
145     if (updateCallback == nullptr) {
146         LOG(ERROR) << "ISysInstallerCallback updateCallback is null";
147         return ERR_NULL_OBJECT;
148     }
149     std::string path = Str16ToStr8(data.ReadString16());
150     LOG(ERROR) << "StartUpdateHmpPackageStub path:" << path;
151 
152     int32_t ret = service->StartUpdateHmpPackage(path, updateCallback);
153     reply.WriteInt32(ret);
154     return 0;
155 }
156 
GetHmpUpdateResultStub(ModuleUpdateStub * service,MessageParcel & data,MessageParcel & reply,MessageOption & option) const157 int32_t ModuleUpdateStub::GetHmpUpdateResultStub(ModuleUpdateStub *service,
158     MessageParcel &data, MessageParcel &reply, MessageOption &option) const
159 {
160     if (service == nullptr) {
161         LOG(ERROR) << "Invalid param";
162         return -1;
163     }
164     std::vector<HmpUpdateInfo> updateInfo = service->GetHmpUpdateResult();
165     reply.WriteInt32(updateInfo.size());
166     for (auto &info : updateInfo) {
167         reply.WriteParcelable(&info);
168     }
169     return 0;
170 }
171 
IsPermissionGranted(void)172 bool ModuleUpdateStub::IsPermissionGranted(void)
173 {
174     Security::AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
175     std::string permission = "ohos.permission.UPDATE_SYSTEM";
176 
177     int verifyResult = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken, permission);
178     bool isPermissionGranted = (verifyResult == Security::AccessToken::PERMISSION_GRANTED);
179     if (!isPermissionGranted) {
180         LOG(ERROR) << "not granted " << permission.c_str();
181     }
182     return isPermissionGranted;
183 }
184 
CheckCallingPerm(void)185 bool ModuleUpdateStub::CheckCallingPerm(void)
186 {
187     int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid();
188     LOG(INFO) << "CheckCallingPerm callingUid:" << callingUid;
189     if (callingUid == 0) {
190         return true;
191     }
192     return callingUid == USER_UPDATE_AUTHORITY && IsPermissionGranted();
193 }
194 
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)195 int32_t ModuleUpdateStub::OnRemoteRequest(uint32_t code,
196     MessageParcel &data, MessageParcel &reply, MessageOption &option)
197 {
198     if (data.ReadInterfaceToken() != GetDescriptor()) {
199         LOG(ERROR) << "ModuleUpdateStub ReadInterfaceToken fail";
200         return -1;
201     }
202 
203     LOG(INFO) << "OnRemoteRequest func code " << code;
204     auto inter = requestFuncMap_.find(code);
205     if (inter != requestFuncMap_.end()) {
206         if (!CheckCallingPerm()) {
207             LOG(ERROR) << "ModuleUpdateStub CheckCallingPerm fail";
208             return -1;
209         }
210         return inter->second(this, data, reply, option);
211     }
212     LOG(INFO) << "ModuleUpdateStub OnRemoteRequest code " << code << "not found";
213     return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
214 }
215 } // namespace SysInstaller
216 } // namespace OHOS