• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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