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 <thread>
17 #include <chrono>
18 #include "ecological_rule_mgr_service_stub.h"
19 #include "string_ex.h"
20 #include "system_ability_definition.h"
21 #include "iservice_registry.h"
22 #include "ecological_rule_mgr_service_logger.h"
23
24 namespace OHOS {
25 namespace EcologicalRuleMgrService {
26 #define TAG "ERMS_STUB"
27 #define ERMS_FOUNDATION_UID 5523
28
29 static inline const std::u16string ERMS_INTERFACE_TOKEN =
30 u"ohos.cloud.ecologicalrulemgrservice.IEcologicalRuleMgrService";
31
32 std::mutex EcologicalRuleMgrServiceStub::bmInstanceLock_;
EcologicalRuleMgrServiceStub()33 EcologicalRuleMgrServiceStub::EcologicalRuleMgrServiceStub()
34 {
35 memberFuncMap_[QUERY_FREE_INSTALL_EXPERIENCE_CMD] =
36 &EcologicalRuleMgrServiceStub::OnQueryFreeInstallExperienceResult;
37 memberFuncMap_[QUERY_START_EXPERIENCE_CMD] = &EcologicalRuleMgrServiceStub::OnQueryStartExperienceResult;
38 memberFuncMap_[EVALUATE_RESOLVE_INFO_CMD] = &EcologicalRuleMgrServiceStub::OnEvaluateResolveInfosResult;
39 memberFuncMap_[IS_SUPPORT_PUBLISH_FORM_CMD] = &EcologicalRuleMgrServiceStub::OnIsSupportPublishFormResult;
40 }
41
~EcologicalRuleMgrServiceStub()42 EcologicalRuleMgrServiceStub::~EcologicalRuleMgrServiceStub()
43 {
44 memberFuncMap_.clear();
45 }
46
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)47 int32_t EcologicalRuleMgrServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
48 MessageOption &option)
49 {
50 LOG_INFO("OnRemoteRequest called, code=%{public}d", code);
51 if (!EnforceInterceToken(data)) {
52 LOG_ERROR("check interface token failed");
53 return ERR_PERMISSION_DENIED;
54 }
55
56 auto itFunc = memberFuncMap_.find(code);
57 if (itFunc != memberFuncMap_.end()) {
58 auto memberFunc = itFunc->second;
59 if (memberFunc != nullptr) {
60 return (this->*memberFunc)(data, reply);
61 }
62 }
63 auto defaultRet = IPCObjectStub::OnRemoteRequest(code, data, reply, option);
64 return defaultRet;
65 }
66
OnQueryFreeInstallExperienceResult(MessageParcel & data,MessageParcel & reply)67 int32_t EcologicalRuleMgrServiceStub::OnQueryFreeInstallExperienceResult(MessageParcel &data, MessageParcel &reply)
68 {
69 if (!VerifySystemApp()) {
70 LOG_ERROR("verify system app failed");
71 return ERR_FAILED;
72 }
73 sptr<Want> want = data.ReadParcelable<Want>();
74 if (want == nullptr) {
75 LOG_ERROR("read want failed");
76 return ERR_FAILED;
77 }
78 sptr<CallerInfo> caller = data.ReadParcelable<CallerInfo>();
79 if (caller == nullptr) {
80 LOG_ERROR("read caller failed");
81 return ERR_FAILED;
82 }
83 sptr<ExperienceRule> rule = new ExperienceRule();
84 QueryFreeInstallExperience(*want, *caller, *rule);
85 sptr<BmsExperienceRule> bmsExpRule = new BmsExperienceRule();
86 TransBmsExperienceRule(*rule, *bmsExpRule);
87 if (!reply.WriteParcelable(bmsExpRule)) {
88 LOG_ERROR("write bmsExpRule failed");
89 return ERR_FAILED;
90 }
91 return ERR_OK;
92 }
93
OnEvaluateResolveInfosResult(MessageParcel & data,MessageParcel & reply)94 int32_t EcologicalRuleMgrServiceStub::OnEvaluateResolveInfosResult(MessageParcel &data, MessageParcel &reply)
95 {
96 if (!VerifySystemApp()) {
97 LOG_ERROR("verify system app failed");
98 return ERR_FAILED;
99 }
100 sptr<Want> want = data.ReadParcelable<Want>();
101 if (want == nullptr) {
102 LOG_ERROR("read want failed");
103 return ERR_FAILED;
104 }
105
106 int32_t type = 0;
107 if (!data.ReadInt32(type)) {
108 LOG_ERROR("read type failed");
109 return ERR_FAILED;
110 }
111 LOG_DEBUG("read type = %{public}d", type);
112 std::vector<AbilityInfo> abilityInfos = {};
113 int32_t abilityInfoSize = 0;
114 if (!data.ReadInt32(abilityInfoSize)) {
115 LOG_ERROR("read abilityInfoSize failed");
116 return ERR_FAILED;
117 }
118 if (abilityInfoSize > MAX_ABILITY_INFO_SIZE) {
119 LOG_ERROR("abilityInfoSize exceed the maximum limit, abilityInfoSize = %{public}d, limit = %{public}d",
120 abilityInfoSize, MAX_ABILITY_INFO_SIZE);
121 return ERR_FAILED;
122 }
123 for (int32_t i = 0; i < abilityInfoSize; i++) {
124 sptr<AbilityInfo> abilityInfo = data.ReadParcelable<AbilityInfo>();
125 if (abilityInfo == nullptr) {
126 LOG_ERROR("read abilityInfo failed");
127 return ERR_FAILED;
128 }
129 abilityInfos.emplace_back(*abilityInfo);
130 }
131 int32_t infoSize = static_cast<int32_t>(abilityInfos.size());
132 LOG_DEBUG("before process abilityInfos size= %{public}d", infoSize);
133
134 sptr<CallerInfo> caller = data.ReadParcelable<CallerInfo>();
135 if (caller == nullptr) {
136 LOG_ERROR("read caller failed");
137 return ERR_FAILED;
138 }
139 EvaluateResolveInfos(*want, *caller, type, abilityInfos);
140 if (!WriteParcelableVector(abilityInfos, reply)) {
141 LOG_ERROR("WriteParcelableVector failed");
142 return ERR_FAILED;
143 }
144 return ERR_OK;
145 }
146
TransAmsExperienceRule(ExperienceRule & rule,AmsExperienceRule & amsRule)147 void EcologicalRuleMgrServiceStub::TransAmsExperienceRule(ExperienceRule &rule, AmsExperienceRule &amsRule)
148 {
149 amsRule.resultCode = 10; // 10 is default value
150 amsRule.replaceWant = rule.replaceWant;
151 }
152
TransBmsExperienceRule(ExperienceRule & rule,BmsExperienceRule & bmsRule)153 void EcologicalRuleMgrServiceStub::TransBmsExperienceRule(ExperienceRule &rule, BmsExperienceRule &bmsRule)
154 {
155 bmsRule.isAllow = rule.isAllow;
156 bmsRule.replaceWant = rule.replaceWant;
157 }
158
OnQueryStartExperienceResult(MessageParcel & data,MessageParcel & reply)159 int32_t EcologicalRuleMgrServiceStub::OnQueryStartExperienceResult(MessageParcel &data, MessageParcel &reply)
160 {
161 if (!VerifySystemApp()) {
162 LOG_ERROR("verify system app failed");
163 return ERR_FAILED;
164 }
165 sptr<Want> want = data.ReadParcelable<Want>();
166 if (want == nullptr) {
167 LOG_ERROR("read want failed");
168 return ERR_FAILED;
169 }
170 sptr<CallerInfo> caller = data.ReadParcelable<CallerInfo>();
171 if (caller == nullptr) {
172 LOG_ERROR("read caller failed");
173 return ERR_FAILED;
174 }
175 sptr<ExperienceRule> rule = new ExperienceRule();
176 QueryStartExperience(*want, *caller, *rule);
177 sptr<AmsExperienceRule> amsExpRule = new AmsExperienceRule();
178 TransAmsExperienceRule(*rule, *amsExpRule);
179 if (!reply.WriteParcelable(amsExpRule)) {
180 LOG_ERROR("write amsExpRule failed");
181 return ERR_FAILED;
182 }
183 return ERR_OK;
184 }
185
OnIsSupportPublishFormResult(MessageParcel & data,MessageParcel & reply)186 int32_t EcologicalRuleMgrServiceStub::OnIsSupportPublishFormResult(MessageParcel &data, MessageParcel &reply)
187 {
188 if (!VerifySystemApp()) {
189 LOG_ERROR("verify system app failed");
190 return ERR_FAILED;
191 }
192 std::vector<Want> wants = {};
193 int32_t wantSize = 0;
194 if (!data.ReadInt32(wantSize)) {
195 LOG_ERROR("read wantSize failed");
196 return ERR_FAILED;
197 }
198 if (wantSize > MAX_WANT_SIZE) {
199 LOG_ERROR("wantSize exceed the maximum limit, wantSize = %{public}d, limit = %{public}d", wantSize,
200 MAX_WANT_SIZE);
201 return ERR_FAILED;
202 }
203 for (int32_t i = 0; i < wantSize; i++) {
204 sptr<Want> want = data.ReadParcelable<Want>();
205 if (want == nullptr) {
206 LOG_ERROR("read wants failed");
207 return ERR_FAILED;
208 }
209 wants.emplace_back(*want);
210 }
211
212 sptr<CallerInfo> caller = data.ReadParcelable<CallerInfo>();
213 if (caller == nullptr) {
214 LOG_ERROR("read caller failed");
215 return ERR_FAILED;
216 }
217 bool bSupport = true;
218 IsSupportPublishForm(wants, *caller, bSupport);
219
220 if (!reply.WriteBool(bSupport)) {
221 LOG_ERROR("write bSupport failed");
222 return ERR_FAILED;
223 }
224 return ERR_OK;
225 }
226
EnforceInterceToken(MessageParcel & data)227 bool EcologicalRuleMgrServiceStub::EnforceInterceToken(MessageParcel &data)
228 {
229 std::u16string interfaceToken = data.ReadInterfaceToken();
230 return interfaceToken == ERMS_INTERFACE_TOKEN;
231 }
232
VerifySystemApp()233 bool EcologicalRuleMgrServiceStub::VerifySystemApp()
234 {
235 LOG_INFO("verifying systemApp");
236 Security::AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
237 Security::AccessToken::ATokenTypeEnum tokenType =
238 Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callerToken);
239 LOG_INFO("token type is %{public}d", static_cast<int32_t>(tokenType));
240 int32_t callingUid = IPCSkeleton::GetCallingUid();
241 if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE
242 || tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL
243 || callingUid == Constants::ROOT_UID) {
244 LOG_INFO("caller tokenType is native, verify success");
245 return true;
246 }
247 if (callingUid != ERMS_FOUNDATION_UID) {
248 LOG_ERROR("calling permission denied, callingUid:%{public}d, not foundation", callingUid);
249 return false;
250 }
251 uint64_t accessTokenIdEx = IPCSkeleton::GetCallingFullTokenID();
252 if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(accessTokenIdEx)) {
253 LOG_INFO("non-system app calling system api");
254 return false;
255 }
256 return true;
257 }
258
259 template <typename T>
WriteParcelableVector(const std::vector<T> & parcelableVector,MessageParcel & reply)260 bool EcologicalRuleMgrServiceStub::WriteParcelableVector(const std::vector<T> &parcelableVector, MessageParcel &reply)
261 {
262 if (!reply.WriteInt32(parcelableVector.size())) {
263 LOG_ERROR("write ParcelableVector size failed");
264 return false;
265 }
266
267 for (auto &parcelable : parcelableVector) {
268 if (!reply.WriteParcelable(&parcelable)) {
269 LOG_ERROR("write ParcelableVector failed");
270 return false;
271 }
272 }
273 return true;
274 }
275 } // namespace EcologicalRuleMgrService
276 } // namespace OHOS