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 #include "sec_comp_stub.h"
16 
17 #include "accesstoken_kit.h"
18 #include "ipc_skeleton.h"
19 #include "sec_comp_click_event_parcel.h"
20 #include "sec_comp_enhance_adapter.h"
21 #include "sec_comp_err.h"
22 #include "sec_comp_log.h"
23 
24 namespace OHOS {
25 namespace Security {
26 namespace SecurityComponent {
27 namespace {
28 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_SECURITY_COMPONENT, "SecCompStub"};
29 static constexpr int32_t ROOT_UID = 0;
30 static constexpr int32_t BASE_USER_RANGE = 200000;
31 }  // namespace
32 
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)33 int32_t SecCompStub::OnRemoteRequest(
34     uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option)
35 {
36     std::u16string descripter = SecCompStub::GetDescriptor();
37     std::u16string remoteDescripter = data.ReadInterfaceToken();
38     if (descripter != remoteDescripter) {
39         SC_LOG_ERROR(LABEL, "Deal remote request failed, descriptor is not matched");
40         return SC_SERVICE_ERROR_IPC_REQUEST_FAIL;
41     }
42 
43     auto funcIter = requestFuncMap_.find(code);
44     if (funcIter != requestFuncMap_.end()) {
45         auto func = funcIter->second;
46         if (func != nullptr) {
47             return (this->*func)(data, reply);
48         }
49     }
50     return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
51 }
52 
RegisterSecurityComponentInner(MessageParcel & data,MessageParcel & reply)53 int32_t SecCompStub::RegisterSecurityComponentInner(MessageParcel& data, MessageParcel& reply)
54 {
55     MessageParcel deserializedData;
56     if (!SecCompEnhanceAdapter::EnhanceSrvDeserialize(data, deserializedData, reply)) {
57         SC_LOG_ERROR(LABEL, "Register deserialize session info failed");
58         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
59     }
60     uint32_t type;
61     if (!deserializedData.ReadUint32(type)) {
62         SC_LOG_ERROR(LABEL, "Register read component type failed");
63         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
64     }
65 
66     if (type <= UNKNOWN_SC_TYPE || type >= MAX_SC_TYPE) {
67         SC_LOG_ERROR(LABEL, "Register security component type invalid");
68         return SC_SERVICE_ERROR_VALUE_INVALID;
69     }
70 
71     std::string componentInfo;
72     if (!deserializedData.ReadString(componentInfo)) {
73         SC_LOG_ERROR(LABEL, "Register read component info failed");
74         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
75     }
76 
77     int32_t scId = INVALID_SC_ID;
78     int32_t res = this->RegisterSecurityComponent(static_cast<SecCompType>(type), componentInfo, scId);
79     MessageParcel rawReply;
80     if (!rawReply.WriteInt32(res)) {
81         SC_LOG_ERROR(LABEL, "Register security component result failed");
82         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
83     }
84 
85     if (!rawReply.WriteInt32(scId)) {
86         SC_LOG_ERROR(LABEL, "Register security component result failed");
87         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
88     }
89 
90     if (!SecCompEnhanceAdapter::EnhanceSrvSerialize(rawReply, reply)) {
91         SC_LOG_ERROR(LABEL, "Register serialize session info failed");
92         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
93     }
94 
95     return SC_OK;
96 }
97 
UpdateSecurityComponentInner(MessageParcel & data,MessageParcel & reply)98 int32_t SecCompStub::UpdateSecurityComponentInner(MessageParcel& data, MessageParcel& reply)
99 {
100     MessageParcel deserializedData;
101     if (!SecCompEnhanceAdapter::EnhanceSrvDeserialize(data, deserializedData, reply)) {
102         SC_LOG_ERROR(LABEL, "Update deserialize session info failed");
103         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
104     }
105     int32_t scId;
106     if (!deserializedData.ReadInt32(scId)) {
107         SC_LOG_ERROR(LABEL, "Update read component id failed");
108         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
109     }
110 
111     if (scId < 0) {
112         SC_LOG_ERROR(LABEL, "Update security component id invalid");
113         return SC_SERVICE_ERROR_VALUE_INVALID;
114     }
115 
116     std::string componentInfo;
117     if (!deserializedData.ReadString(componentInfo)) {
118         SC_LOG_ERROR(LABEL, "Update read component info failed");
119         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
120     }
121 
122     int32_t res = this->UpdateSecurityComponent(scId, componentInfo);
123     MessageParcel rawReply;
124     if (!rawReply.WriteInt32(res)) {
125         SC_LOG_ERROR(LABEL, "Update security component result failed");
126         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
127     }
128 
129     if (!SecCompEnhanceAdapter::EnhanceSrvSerialize(rawReply, reply)) {
130         SC_LOG_ERROR(LABEL, "Update serialize session info failed");
131         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
132     }
133 
134     return res;
135 }
136 
UnregisterSecurityComponentInner(MessageParcel & data,MessageParcel & reply)137 int32_t SecCompStub::UnregisterSecurityComponentInner(MessageParcel& data, MessageParcel& reply)
138 {
139     MessageParcel deserializedData;
140     if (!SecCompEnhanceAdapter::EnhanceSrvDeserialize(data, deserializedData, reply)) {
141         SC_LOG_ERROR(LABEL, "Unreigster deserialize session info failed");
142         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
143     }
144     int32_t scId;
145     if (!deserializedData.ReadInt32(scId)) {
146         SC_LOG_ERROR(LABEL, "Unreigster read component id failed");
147         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
148     }
149 
150     if (scId < 0) {
151         SC_LOG_ERROR(LABEL, "Unreigster security component id invalid");
152         return SC_SERVICE_ERROR_VALUE_INVALID;
153     }
154 
155     int32_t res = this->UnregisterSecurityComponent(scId);
156     MessageParcel rawReply;
157     if (!rawReply.WriteInt32(res)) {
158         SC_LOG_ERROR(LABEL, "Unregister security component result failed");
159         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
160     }
161 
162     if (!SecCompEnhanceAdapter::EnhanceSrvSerialize(rawReply, reply)) {
163         SC_LOG_ERROR(LABEL, "Unreigster serialize session info failed");
164         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
165     }
166 
167     return SC_OK;
168 }
169 
ReportSecurityComponentClickEventInner(MessageParcel & data,MessageParcel & reply)170 int32_t SecCompStub::ReportSecurityComponentClickEventInner(MessageParcel& data, MessageParcel& reply)
171 {
172     sptr<IRemoteObject> callerToken = data.ReadRemoteObject();
173     if (callerToken == nullptr) {
174         SC_LOG_ERROR(LABEL, "callerToken is nullptr");
175         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
176     }
177 
178     sptr<IRemoteObject> dialogCallback = data.ReadRemoteObject();
179     if (dialogCallback == nullptr) {
180         SC_LOG_ERROR(LABEL, "dialogCallback is nullptr");
181         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
182     }
183 
184     MessageParcel deserializedData;
185     if (!SecCompEnhanceAdapter::EnhanceSrvDeserialize(data, deserializedData, reply)) {
186         SC_LOG_ERROR(LABEL, "Report deserialize session info failed");
187         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
188     }
189     int32_t scId;
190     if (!deserializedData.ReadInt32(scId)) {
191         SC_LOG_ERROR(LABEL, "Report read component id failed");
192         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
193     }
194 
195     if (scId < 0) {
196         SC_LOG_ERROR(LABEL, "Report security component id invalid");
197         return SC_SERVICE_ERROR_VALUE_INVALID;
198     }
199 
200     std::string componentInfo;
201     if (!deserializedData.ReadString(componentInfo)) {
202         SC_LOG_ERROR(LABEL, "Report read component info failed");
203         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
204     }
205     sptr<SecCompClickEventParcel> clickInfoParcel = deserializedData.ReadParcelable<SecCompClickEventParcel>();
206     if (clickInfoParcel == nullptr) {
207         SC_LOG_ERROR(LABEL, "Report read clickInfo info failed");
208         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
209     }
210 
211     int32_t res =
212         this->ReportSecurityComponentClickEvent(scId,
213         componentInfo, clickInfoParcel->clickInfoParams_,
214         callerToken, dialogCallback);
215     MessageParcel rawReply;
216     if (!rawReply.WriteInt32(res)) {
217         SC_LOG_ERROR(LABEL, "Report security component result failed");
218         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
219     }
220 
221     if (!SecCompEnhanceAdapter::EnhanceSrvSerialize(rawReply, reply)) {
222         SC_LOG_ERROR(LABEL, "Report serialize session info failed");
223         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
224     }
225 
226     return SC_OK;
227 }
228 
VerifySavePermissionInner(MessageParcel & data,MessageParcel & reply)229 int32_t SecCompStub::VerifySavePermissionInner(MessageParcel& data, MessageParcel& reply)
230 {
231     if (!IsMediaLibraryCalling()) {
232         SC_LOG_ERROR(LABEL, "Not medialibrary called");
233         return SC_SERVICE_ERROR_CALLER_INVALID;
234     }
235     uint32_t tokenId;
236     if (!data.ReadUint32(tokenId)) {
237         SC_LOG_ERROR(LABEL, "Verify read component id failed");
238         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
239     }
240 
241     if (tokenId == 0) {
242         SC_LOG_ERROR(LABEL, "Verify AccessTokenId invalid");
243         return SC_SERVICE_ERROR_VALUE_INVALID;
244     }
245 
246     bool res = this->VerifySavePermission(tokenId);
247     if (!reply.WriteBool(res)) {
248         SC_LOG_ERROR(LABEL, "Verify temp save permission result failed");
249         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
250     }
251 
252     return SC_OK;
253 }
254 
GetEnhanceRemoteObjectInner(MessageParcel & data,MessageParcel & reply)255 int32_t SecCompStub::GetEnhanceRemoteObjectInner(MessageParcel& data, MessageParcel& reply)
256 {
257     MessageParcel deserializedData;
258     if (!SecCompEnhanceAdapter::EnhanceSrvDeserialize(data, deserializedData, reply)) {
259         SC_LOG_ERROR(LABEL, "Get remote obj deserialize session info failed");
260         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
261     }
262     auto res = this->GetEnhanceRemoteObject();
263     MessageParcel rawReply;
264     if (!reply.WriteRemoteObject(res)) {
265         SC_LOG_ERROR(LABEL, "Security component enhance remote object failed");
266         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
267     }
268 
269     if (!SecCompEnhanceAdapter::EnhanceSrvSerialize(rawReply, reply)) {
270         SC_LOG_ERROR(LABEL, "Get remote obj serialize session info failed");
271         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
272     }
273 
274     return SC_OK;
275 }
276 
PreRegisterSecCompProcessInner(MessageParcel & data,MessageParcel & reply)277 int32_t SecCompStub::PreRegisterSecCompProcessInner(MessageParcel& data, MessageParcel& reply)
278 {
279     MessageParcel deserializedData;
280     if (!SecCompEnhanceAdapter::EnhanceSrvDeserialize(data, deserializedData, reply)) {
281         SC_LOG_ERROR(LABEL, "preRegister deserialize session info failed");
282         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
283     }
284     int32_t res = this->PreRegisterSecCompProcess();
285     MessageParcel rawReply;
286     if (!rawReply.WriteInt32(res)) {
287         SC_LOG_ERROR(LABEL, "preRegister write result failed");
288         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
289     }
290 
291     if (!SecCompEnhanceAdapter::EnhanceSrvSerialize(rawReply, reply)) {
292         SC_LOG_ERROR(LABEL, "preRegister serialize session info failed");
293         return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL;
294     }
295 
296     return SC_OK;
297 }
298 
IsMediaLibraryCalling()299 bool SecCompStub::IsMediaLibraryCalling()
300 {
301     int32_t uid = IPCSkeleton::GetCallingUid();
302     if (uid == ROOT_UID) {
303         return true;
304     }
305     int32_t userId = uid / BASE_USER_RANGE;
306     uint32_t tokenCaller = IPCSkeleton::GetCallingTokenID();
307     if (mediaLibraryTokenId_ != tokenCaller) {
308         mediaLibraryTokenId_ = AccessToken::AccessTokenKit::GetHapTokenID(
309             userId, "com.ohos.medialibrary.medialibrarydata", 0);
310     }
311     return tokenCaller == mediaLibraryTokenId_;
312 }
313 
SecCompStub()314 SecCompStub::SecCompStub()
315 {
316     requestFuncMap_[static_cast<uint32_t>(SecurityComponentServiceInterfaceCode::REGISTER_SECURITY_COMPONENT)] =
317         &SecCompStub::RegisterSecurityComponentInner;
318     requestFuncMap_[static_cast<uint32_t>(SecurityComponentServiceInterfaceCode::UPDATE_SECURITY_COMPONENT)] =
319         &SecCompStub::UpdateSecurityComponentInner;
320     requestFuncMap_[static_cast<uint32_t>(SecurityComponentServiceInterfaceCode::UNREGISTER_SECURITY_COMPONENT)] =
321         &SecCompStub::UnregisterSecurityComponentInner;
322     requestFuncMap_[static_cast<uint32_t>(
323         SecurityComponentServiceInterfaceCode::REPORT_SECURITY_COMPONENT_CLICK_EVENT)] =
324         &SecCompStub::ReportSecurityComponentClickEventInner;
325     requestFuncMap_[static_cast<uint32_t>(SecurityComponentServiceInterfaceCode::VERIFY_TEMP_SAVE_PERMISSION)] =
326         &SecCompStub::VerifySavePermissionInner;
327     requestFuncMap_[static_cast<uint32_t>(
328         SecurityComponentServiceInterfaceCode::GET_SECURITY_COMPONENT_ENHANCE_OBJECT)] =
329         &SecCompStub::GetEnhanceRemoteObjectInner;
330     requestFuncMap_[static_cast<uint32_t>(
331         SecurityComponentServiceInterfaceCode::PRE_REGISTER_PROCESS)] =
332         &SecCompStub::PreRegisterSecCompProcessInner;
333 }
334 
~SecCompStub()335 SecCompStub::~SecCompStub()
336 {
337     SC_LOG_ERROR(LABEL, "~SecCompStub");
338     requestFuncMap_.clear();
339     SC_LOG_ERROR(LABEL, "~SecCompStub end");
340 }
341 }  // namespace SecurityComponent
342 }  // namespace Security
343 }  // namespace OHOS
344