1 /*
2 * Copyright (c) 2022 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 "distributed_bms_host.h"
17
18 #include "accesstoken_kit.h"
19 #include "app_log_wrapper.h"
20 #include "appexecfwk_errors.h"
21 #include "bundle_constants.h"
22 #include "remote_ability_info.h"
23 #include "ipc_skeleton.h"
24
25 namespace OHOS {
26 namespace AppExecFwk {
27 namespace {
28 constexpr int32_t GET_REMOTE_ABILITY_INFO_MAX_SIZE = 10;
29 }
30
DistributedBmsHost()31 DistributedBmsHost::DistributedBmsHost()
32 {
33 APP_LOGI("DistributedBmsHost instance is created");
34 }
35
~DistributedBmsHost()36 DistributedBmsHost::~DistributedBmsHost()
37 {
38 APP_LOGI("DistributedBmsHost instance is destroyed");
39 }
40
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)41 int DistributedBmsHost::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
42 {
43 APP_LOGI("DistributedBmsHost receives message from client, code = %{public}u, flags = %{public}d", code,
44 option.GetFlags());
45 std::u16string descripter = DistributedBmsHost::GetDescriptor();
46 std::u16string remoteDescripter = data.ReadInterfaceToken();
47 if (descripter != remoteDescripter) {
48 APP_LOGE("verify interface token failed");
49 return ERR_INVALID_STATE;
50 }
51 switch (code) {
52 case static_cast<uint32_t>(IDistributedBms::Message::GET_REMOTE_ABILITY_INFO):
53 case static_cast<uint32_t>(IDistributedBms::Message::GET_REMOTE_ABILITY_INFO_WITH_LOCALE):
54 return HandleGetRemoteAbilityInfo(data, reply);
55 case static_cast<uint32_t>(IDistributedBms::Message::GET_REMOTE_ABILITY_INFOS):
56 case static_cast<uint32_t>(IDistributedBms::Message::GET_REMOTE_ABILITY_INFOS_WITH_LOCALE):
57 return HandleGetRemoteAbilityInfos(data, reply);
58 case static_cast<uint32_t>(IDistributedBms::Message::GET_ABILITY_INFO):
59 case static_cast<uint32_t>(IDistributedBms::Message::GET_ABILITY_INFO_WITH_LOCALE):
60 return HandleGetAbilityInfo(data, reply);
61 case static_cast<uint32_t>(IDistributedBms::Message::GET_ABILITY_INFOS):
62 case static_cast<uint32_t>(IDistributedBms::Message::GET_ABILITY_INFOS_WITH_LOCALE):
63 return HandleGetAbilityInfos(data, reply);
64 case static_cast<uint32_t>(IDistributedBms::Message::GET_DISTRIBUTED_BUNDLE_INFO):
65 return HandleGetDistributedBundleInfo(data, reply);
66 default:
67 APP_LOGW("DistributedBmsHost receives unknown code, code = %{public}d", code);
68 return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
69 }
70 return NO_ERROR;
71 }
72
HandleGetRemoteAbilityInfo(Parcel & data,Parcel & reply)73 int DistributedBmsHost::HandleGetRemoteAbilityInfo(Parcel &data, Parcel &reply)
74 {
75 APP_LOGI("DistributedBmsHost handle get remote ability info");
76 if (!VerifyCallingPermission(Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED)) {
77 APP_LOGE("verify GET_BUNDLE_INFO_PRIVILEGED failed");
78 return ERR_BUNDLE_MANAGER_PERMISSION_DENIED;
79 }
80 std::unique_ptr<ElementName> elementName(data.ReadParcelable<ElementName>());
81 if (!elementName) {
82 APP_LOGE("ReadParcelable<elementName> failed");
83 return ERR_APPEXECFWK_PARCEL_ERROR;
84 }
85 std::string localeInfo = data.ReadString();
86 RemoteAbilityInfo remoteAbilityInfo;
87 int ret = GetRemoteAbilityInfo(*elementName, localeInfo, remoteAbilityInfo);
88 if (ret != NO_ERROR) {
89 APP_LOGE("GetRemoteAbilityInfo result:%{public}d", ret);
90 return ret;
91 }
92 if (!reply.WriteBool(true)) {
93 APP_LOGE("GetRemoteAbilityInfo write failed");
94 return ERR_APPEXECFWK_PARCEL_ERROR;
95 }
96 if (!reply.WriteParcelable(&remoteAbilityInfo)) {
97 APP_LOGE("GetRemoteAbilityInfo write failed");
98 return ERR_APPEXECFWK_PARCEL_ERROR;
99 }
100 return NO_ERROR;
101 }
102
HandleGetRemoteAbilityInfos(Parcel & data,Parcel & reply)103 int DistributedBmsHost::HandleGetRemoteAbilityInfos(Parcel &data, Parcel &reply)
104 {
105 APP_LOGI("DistributedBmsHost handle get remote ability infos");
106 if (!VerifyCallingPermission(Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED)) {
107 APP_LOGE("verify GET_BUNDLE_INFO_PRIVILEGED failed");
108 return ERR_BUNDLE_MANAGER_PERMISSION_DENIED;
109 }
110 std::vector<ElementName> elementNames;
111 if (!GetParcelableInfos<ElementName>(data, elementNames)) {
112 APP_LOGE("GetRemoteAbilityInfos get parcelable infos failed");
113 return ERR_APPEXECFWK_PARCEL_ERROR;
114 }
115 std::string localeInfo = data.ReadString();
116 std::vector<RemoteAbilityInfo> remoteAbilityInfos;
117 int ret = GetRemoteAbilityInfos(elementNames, localeInfo, remoteAbilityInfos);
118 if (ret != NO_ERROR) {
119 APP_LOGE("GetRemoteAbilityInfos result:%{public}d", ret);
120 return ret;
121 }
122 if (!reply.WriteBool(true)) {
123 APP_LOGE("GetRemoteAbilityInfos write failed");
124 return ERR_APPEXECFWK_PARCEL_ERROR;
125 }
126 if (!WriteParcelableVector<RemoteAbilityInfo>(remoteAbilityInfos, reply)) {
127 APP_LOGE("GetRemoteAbilityInfos write failed");
128 return ERR_APPEXECFWK_PARCEL_ERROR;
129 }
130 return NO_ERROR;
131 }
132
133
HandleGetAbilityInfo(Parcel & data,Parcel & reply)134 int DistributedBmsHost::HandleGetAbilityInfo(Parcel &data, Parcel &reply)
135 {
136 APP_LOGI("DistributedBmsHost handle get ability info");
137 std::unique_ptr<ElementName> elementName(data.ReadParcelable<ElementName>());
138 if (!elementName) {
139 APP_LOGE("ReadParcelable<elementName> failed");
140 return ERR_APPEXECFWK_PARCEL_ERROR;
141 }
142 std::string localeInfo = data.ReadString();
143 RemoteAbilityInfo remoteAbilityInfo;
144 int ret = GetAbilityInfo(*elementName, localeInfo, remoteAbilityInfo);
145 if (ret != NO_ERROR) {
146 APP_LOGE("GetAbilityInfo result:%{public}d", ret);
147 return ret;
148 }
149 if (!reply.WriteBool(true)) {
150 APP_LOGE("GetRemoteAbilityInfo write failed");
151 return ERR_APPEXECFWK_PARCEL_ERROR;
152 }
153 if (!reply.WriteParcelable(&remoteAbilityInfo)) {
154 APP_LOGE("GetRemoteAbilityInfo write failed");
155 return ERR_APPEXECFWK_PARCEL_ERROR;
156 }
157 return NO_ERROR;
158 }
159
HandleGetAbilityInfos(Parcel & data,Parcel & reply)160 int DistributedBmsHost::HandleGetAbilityInfos(Parcel &data, Parcel &reply)
161 {
162 APP_LOGI("DistributedBmsHost handle get ability infos");
163 std::vector<ElementName> elementNames;
164 if (!GetParcelableInfos<ElementName>(data, elementNames)) {
165 APP_LOGE("GetRemoteAbilityInfos get parcelable infos failed");
166 return ERR_APPEXECFWK_PARCEL_ERROR;
167 }
168 std::string localeInfo = data.ReadString();
169 std::vector<RemoteAbilityInfo> remoteAbilityInfos;
170 int ret = GetAbilityInfos(elementNames, localeInfo, remoteAbilityInfos);
171 if (ret != NO_ERROR) {
172 APP_LOGE("GetAbilityInfos result:%{public}d", ret);
173 return ret;
174 }
175 if (!reply.WriteBool(true)) {
176 APP_LOGE("GetAbilityInfos write failed");
177 return ERR_APPEXECFWK_PARCEL_ERROR;
178 }
179 if (!WriteParcelableVector<RemoteAbilityInfo>(remoteAbilityInfos, reply)) {
180 APP_LOGE("GetAbilityInfos write failed");
181 return ERR_APPEXECFWK_PARCEL_ERROR;
182 }
183 return NO_ERROR;
184 }
185
HandleGetDistributedBundleInfo(Parcel & data,Parcel & reply)186 int DistributedBmsHost::HandleGetDistributedBundleInfo(Parcel &data, Parcel &reply)
187 {
188 APP_LOGI("DistributedBmsHost handle get distributedBundleInfo");
189 std::string networkId = data.ReadString();
190 std::string bundleName = data.ReadString();
191 DistributedBundleInfo distributedBundleInfo;
192 bool ret = GetDistributedBundleInfo(networkId, bundleName, distributedBundleInfo);
193 if (!ret) {
194 APP_LOGE("GetDistributedBundleInfo failed");
195 return INVALID_OPERATION;
196 }
197 if (!reply.WriteBool(true)) {
198 APP_LOGE("GetDistributedBundleInfo write failed");
199 return ERR_APPEXECFWK_PARCEL_ERROR;
200 }
201 if (!reply.WriteParcelable(&distributedBundleInfo)) {
202 APP_LOGE("GetDistributedBundleInfo write failed");
203 return ERR_APPEXECFWK_PARCEL_ERROR;
204 }
205 return NO_ERROR;
206 }
207
VerifyCallingPermission(const std::string & permissionName)208 bool DistributedBmsHost::VerifyCallingPermission(const std::string &permissionName)
209 {
210 APP_LOGD("VerifyCallingPermission permission %{public}s", permissionName.c_str());
211 OHOS::Security::AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
212 OHOS::Security::AccessToken::ATokenTypeEnum tokenType =
213 OHOS::Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callerToken);
214 if (tokenType == OHOS::Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE) {
215 APP_LOGD("caller tokenType is native, verify success");
216 return true;
217 }
218 int32_t ret = OHOS::Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken, permissionName);
219 if (ret == OHOS::Security::AccessToken::PermissionState::PERMISSION_DENIED) {
220 APP_LOGE("permission %{public}s: PERMISSION_DENIED", permissionName.c_str());
221 return false;
222 }
223 APP_LOGD("verify permission success");
224 return true;
225 }
226
227 template<typename T>
WriteParcelableVector(std::vector<T> & parcelableVector,Parcel & reply)228 bool DistributedBmsHost::WriteParcelableVector(std::vector<T> &parcelableVector, Parcel &reply)
229 {
230 if (!reply.WriteInt32(parcelableVector.size())) {
231 APP_LOGE("write ParcelableVector failed");
232 return false;
233 }
234
235 for (auto &parcelable : parcelableVector) {
236 if (!reply.WriteParcelable(&parcelable)) {
237 APP_LOGE("write ParcelableVector failed");
238 return false;
239 }
240 }
241 return true;
242 }
243
244 template<typename T>
GetParcelableInfos(Parcel & data,std::vector<T> & parcelableInfos)245 bool DistributedBmsHost::GetParcelableInfos(Parcel &data, std::vector<T> &parcelableInfos)
246 {
247 int32_t infoSize = data.ReadInt32();
248 if (infoSize > GET_REMOTE_ABILITY_INFO_MAX_SIZE) {
249 APP_LOGE("GetParcelableInfos elements num exceeds the limit %{public}d", GET_REMOTE_ABILITY_INFO_MAX_SIZE);
250 return false;
251 }
252 for (int32_t i = 0; i < infoSize; i++) {
253 std::unique_ptr<T> info(data.ReadParcelable<T>());
254 if (!info) {
255 APP_LOGE("Read Parcelable infos failed");
256 return false;
257 }
258 parcelableInfos.emplace_back(*info);
259 }
260 APP_LOGD("get parcelable infos success");
261 return true;
262 }
263 } // namespace AppExecFwk
264 } // namespace OHOS