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