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 if (!reply.WriteParcelable(rule)) {
86 LOG_ERROR("write rule failed");
87 return ERR_FAILED;
88 }
89 return ERR_OK;
90 }
91
OnEvaluateResolveInfosResult(MessageParcel & data,MessageParcel & reply)92 int32_t EcologicalRuleMgrServiceStub::OnEvaluateResolveInfosResult(MessageParcel &data, MessageParcel &reply)
93 {
94 if (!VerifySystemApp()) {
95 LOG_ERROR("verify system app failed");
96 return ERR_FAILED;
97 }
98 sptr<Want> want = data.ReadParcelable<Want>();
99 if (want == nullptr) {
100 LOG_ERROR("read want failed");
101 return ERR_FAILED;
102 }
103
104 int32_t type = 0;
105 if (!data.ReadInt32(type)) {
106 LOG_ERROR("read type failed");
107 return ERR_FAILED;
108 }
109 LOG_DEBUG("read type = %{public}d", type);
110 std::vector<AbilityInfo> abilityInfos = {};
111 int32_t abilityInfoSize = 0;
112 if (!data.ReadInt32(abilityInfoSize)) {
113 LOG_ERROR("read abilityInfoSize failed");
114 return ERR_FAILED;
115 }
116 if (abilityInfoSize > MAX_ABILITY_INFO_SIZE) {
117 LOG_ERROR("abilityInfoSize exceed the maximum limit, abilityInfoSize = %{public}d, limit = %{public}d",
118 abilityInfoSize, MAX_ABILITY_INFO_SIZE);
119 return ERR_FAILED;
120 }
121 for (int32_t i = 0; i < abilityInfoSize; i++) {
122 sptr<AbilityInfo> abilityInfo = data.ReadParcelable<AbilityInfo>();
123 if (abilityInfo == nullptr) {
124 LOG_ERROR("read abilityInfo failed");
125 return ERR_FAILED;
126 }
127 abilityInfos.emplace_back(*abilityInfo);
128 }
129 int32_t infoSize = static_cast<int32_t>(abilityInfos.size());
130 LOG_DEBUG("before process abilityInfos size= %{public}d", infoSize);
131
132 sptr<CallerInfo> caller = data.ReadParcelable<CallerInfo>();
133 if (caller == nullptr) {
134 LOG_ERROR("read caller failed");
135 return ERR_FAILED;
136 }
137 EvaluateResolveInfos(*want, *caller, type, abilityInfos);
138 if (!WriteParcelableVector(abilityInfos, reply)) {
139 LOG_ERROR("WriteParcelableVector failed");
140 return ERR_FAILED;
141 }
142 return ERR_OK;
143 }
144
OnQueryStartExperienceResult(MessageParcel & data,MessageParcel & reply)145 int32_t EcologicalRuleMgrServiceStub::OnQueryStartExperienceResult(MessageParcel &data, MessageParcel &reply)
146 {
147 if (!VerifySystemApp()) {
148 LOG_ERROR("verify system app failed");
149 return ERR_FAILED;
150 }
151 sptr<Want> want = data.ReadParcelable<Want>();
152 if (want == nullptr) {
153 LOG_ERROR("read want failed");
154 return ERR_FAILED;
155 }
156 sptr<CallerInfo> caller = data.ReadParcelable<CallerInfo>();
157 if (caller == nullptr) {
158 LOG_ERROR("read caller failed");
159 return ERR_FAILED;
160 }
161 sptr<ExperienceRule> rule = new ExperienceRule();
162 QueryStartExperience(*want, *caller, *rule);
163 if (!reply.WriteParcelable(rule)) {
164 LOG_ERROR("write rule failed");
165 return ERR_FAILED;
166 }
167 return ERR_OK;
168 }
169
OnIsSupportPublishFormResult(MessageParcel & data,MessageParcel & reply)170 int32_t EcologicalRuleMgrServiceStub::OnIsSupportPublishFormResult(MessageParcel &data, MessageParcel &reply)
171 {
172 if (!VerifySystemApp()) {
173 LOG_ERROR("verify system app failed");
174 return ERR_FAILED;
175 }
176 std::vector<Want> wants = {};
177 int32_t wantSize = 0;
178 if (!data.ReadInt32(wantSize)) {
179 LOG_ERROR("read wantSize failed");
180 return ERR_FAILED;
181 }
182 if (wantSize > MAX_WANT_SIZE) {
183 LOG_ERROR("wantSize exceed the maximum limit, wantSize = %{public}d, limit = %{public}d", wantSize,
184 MAX_WANT_SIZE);
185 return ERR_FAILED;
186 }
187 for (int32_t i = 0; i < wantSize; i++) {
188 sptr<Want> want = data.ReadParcelable<Want>();
189 if (want == nullptr) {
190 LOG_ERROR("read wants failed");
191 return ERR_FAILED;
192 }
193 wants.emplace_back(*want);
194 }
195
196 sptr<CallerInfo> caller = data.ReadParcelable<CallerInfo>();
197 if (caller == nullptr) {
198 LOG_ERROR("read caller failed");
199 return ERR_FAILED;
200 }
201 bool bSupport = true;
202 IsSupportPublishForm(wants, *caller, bSupport);
203
204 if (!reply.WriteBool(bSupport)) {
205 LOG_ERROR("write bSupport failed");
206 return ERR_FAILED;
207 }
208 return ERR_OK;
209 }
210
EnforceInterceToken(MessageParcel & data)211 bool EcologicalRuleMgrServiceStub::EnforceInterceToken(MessageParcel &data)
212 {
213 std::u16string interfaceToken = data.ReadInterfaceToken();
214 return interfaceToken == ERMS_INTERFACE_TOKEN;
215 }
216
VerifySystemApp()217 bool EcologicalRuleMgrServiceStub::VerifySystemApp()
218 {
219 LOG_INFO("verifying systemApp");
220 Security::AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
221 Security::AccessToken::ATokenTypeEnum tokenType =
222 Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callerToken);
223 LOG_INFO("token type is %{public}d", static_cast<int32_t>(tokenType));
224 int32_t callingUid = IPCSkeleton::GetCallingUid();
225 if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE
226 || tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL
227 || callingUid == Constants::ROOT_UID) {
228 LOG_INFO("caller tokenType is native, verify success");
229 return true;
230 }
231 if (callingUid != ERMS_FOUNDATION_UID) {
232 LOG_ERROR("calling permission denied, callingUid:%{public}d, not foundation", callingUid);
233 return false;
234 }
235 uint64_t accessTokenIdEx = IPCSkeleton::GetCallingFullTokenID();
236 if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(accessTokenIdEx)) {
237 LOG_INFO("non-system app calling system api");
238 return false;
239 }
240 return true;
241 }
242
243 template <typename T>
WriteParcelableVector(const std::vector<T> & parcelableVector,MessageParcel & reply)244 bool EcologicalRuleMgrServiceStub::WriteParcelableVector(const std::vector<T> &parcelableVector, MessageParcel &reply)
245 {
246 if (!reply.WriteInt32(parcelableVector.size())) {
247 LOG_ERROR("write ParcelableVector size failed");
248 return false;
249 }
250
251 for (auto &parcelable : parcelableVector) {
252 if (!reply.WriteParcelable(&parcelable)) {
253 LOG_ERROR("write ParcelableVector failed");
254 return false;
255 }
256 }
257 return true;
258 }
259 } // namespace EcologicalRuleMgrService
260 } // namespace OHOS