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