1 /*
2 * Copyright (c) 2022-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 "user_auth_stub.h"
17
18 #include <algorithm>
19 #include <cinttypes>
20
21 #include "iam_logger.h"
22 #include "iam_scope_guard.h"
23 #include "iam_common_defines.h"
24 #include "user_auth_callback_proxy.h"
25 #include "widget_callback_proxy.h"
26 #include "user_auth_common_defines.h"
27
28 #define LOG_LABEL UserIam::Common::LABEL_USER_AUTH_SA
29
30 namespace OHOS {
31 namespace UserIam {
32 namespace UserAuth {
33 namespace {
34 const uint32_t MAX_ATTR_COUNT = 512;
35 } // namespace
36
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)37 int32_t UserAuthStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
38 {
39 IAM_LOGD("cmd = %{public}u, flags = %{public}d", code, option.GetFlags());
40 if (UserAuthStub::GetDescriptor() != data.ReadInterfaceToken()) {
41 IAM_LOGE("descriptor is not matched");
42 return GENERAL_ERROR;
43 }
44 switch (code) {
45 case UserAuthInterfaceCode::USER_AUTH_GET_AVAILABLE_STATUS:
46 return GetAvailableStatusStub(data, reply);
47 case UserAuthInterfaceCode::USER_AUTH_GET_PROPERTY:
48 return GetPropertyStub(data, reply);
49 case UserAuthInterfaceCode::USER_AUTH_SET_PROPERTY:
50 return SetPropertyStub(data, reply);
51 case UserAuthInterfaceCode::USER_AUTH_AUTH:
52 return AuthStub(data, reply);
53 case UserAuthInterfaceCode::USER_AUTH_AUTH_WIDGET:
54 return AuthWidgetStub(data, reply);
55 case UserAuthInterfaceCode::USER_AUTH_AUTH_USER:
56 return AuthUserStub(data, reply);
57 case UserAuthInterfaceCode::USER_AUTH_CANCEL_AUTH:
58 return CancelAuthOrIdentifyStub(data, reply);
59 case UserAuthInterfaceCode::USER_AUTH_IDENTIFY:
60 return IdentifyStub(data, reply);
61 case UserAuthInterfaceCode::USER_AUTH_CANCEL_IDENTIFY:
62 return CancelAuthOrIdentifyStub(data, reply);
63 case UserAuthInterfaceCode::USER_AUTH_GET_VERSION:
64 return GetVersionStub(data, reply);
65 case UserAuthInterfaceCode::USER_AUTH_NOTICE:
66 return NoticeStub(data, reply);
67 case UserAuthInterfaceCode::USER_AUTH_REG_WIDGET_CB:
68 return RegisterWidgetCallbackStub(data, reply);
69 default:
70 return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
71 }
72 }
73
GetAvailableStatusStub(MessageParcel & data,MessageParcel & reply)74 int32_t UserAuthStub::GetAvailableStatusStub(MessageParcel &data, MessageParcel &reply)
75 {
76 IAM_LOGI("enter");
77 ON_SCOPE_EXIT(IAM_LOGI("leave"));
78
79 int32_t authType;
80 uint32_t authTrustLevel;
81 int32_t apiVersion;
82
83 if (!data.ReadInt32(authType)) {
84 IAM_LOGE("failed to read authType");
85 return READ_PARCEL_ERROR;
86 }
87 if (!data.ReadUint32(authTrustLevel)) {
88 IAM_LOGE("failed to read authTrustLevel");
89 return READ_PARCEL_ERROR;
90 }
91 if (!data.ReadInt32(apiVersion)) {
92 IAM_LOGE("failed to read authType");
93 return READ_PARCEL_ERROR;
94 }
95
96 int32_t result = GetAvailableStatus(apiVersion,
97 static_cast<AuthType>(authType), static_cast<AuthTrustLevel>(authTrustLevel));
98 if (!reply.WriteInt32(result)) {
99 IAM_LOGE("failed to write GetAvailableStatus result");
100 return WRITE_PARCEL_ERROR;
101 }
102 return SUCCESS;
103 }
104
GetPropertyStub(MessageParcel & data,MessageParcel & reply)105 int32_t UserAuthStub::GetPropertyStub(MessageParcel &data, MessageParcel &reply)
106 {
107 IAM_LOGI("enter");
108 ON_SCOPE_EXIT(IAM_LOGI("leave"));
109
110 int32_t userId;
111 int32_t authType;
112 std::vector<uint32_t> keys;
113
114 if (!data.ReadInt32(userId)) {
115 IAM_LOGE("failed to read userId");
116 return READ_PARCEL_ERROR;
117 }
118 if (!data.ReadInt32(authType)) {
119 IAM_LOGE("failed to read authType");
120 return READ_PARCEL_ERROR;
121 }
122 if (!data.ReadUInt32Vector(&keys)) {
123 IAM_LOGE("failed to read attribute keys");
124 return READ_PARCEL_ERROR;
125 }
126 std::vector<Attributes::AttributeKey> attrKeys;
127 if (keys.empty()) {
128 IAM_LOGE("the attribute key vector is empty");
129 return GENERAL_ERROR;
130 }
131 if (keys.size() > MAX_ATTR_COUNT) {
132 IAM_LOGE("the attribute key vector size exceed limit");
133 return GENERAL_ERROR;
134 }
135 attrKeys.resize(keys.size());
136 std::transform(keys.begin(), keys.end(), attrKeys.begin(), [](uint32_t key) {
137 return static_cast<Attributes::AttributeKey>(key);
138 });
139
140 sptr<IRemoteObject> obj = data.ReadRemoteObject();
141 if (obj == nullptr) {
142 IAM_LOGE("failed to read remote object");
143 return READ_PARCEL_ERROR;
144 }
145 sptr<GetExecutorPropertyCallbackInterface> callback = iface_cast<GetExecutorPropertyCallbackProxy>(obj);
146 if (callback == nullptr) {
147 IAM_LOGE("GetExecutorPropertyCallbackInterface is nullptr");
148 return GENERAL_ERROR;
149 }
150
151 GetProperty(userId, static_cast<AuthType>(authType), attrKeys, callback);
152 return SUCCESS;
153 }
154
SetPropertyStub(MessageParcel & data,MessageParcel & reply)155 int32_t UserAuthStub::SetPropertyStub(MessageParcel &data, MessageParcel &reply)
156 {
157 IAM_LOGI("enter");
158 ON_SCOPE_EXIT(IAM_LOGI("leave"));
159
160 int32_t userId;
161 int32_t authType;
162 std::vector<uint8_t> attr;
163
164 if (!data.ReadInt32(userId)) {
165 IAM_LOGE("failed to read userId");
166 return READ_PARCEL_ERROR;
167 }
168 if (!data.ReadInt32(authType)) {
169 IAM_LOGE("failed to read authType");
170 return READ_PARCEL_ERROR;
171 }
172 if (!data.ReadUInt8Vector(&attr)) {
173 IAM_LOGE("failed to read attributes");
174 return READ_PARCEL_ERROR;
175 }
176 Attributes attributes(attr);
177
178 sptr<IRemoteObject> obj = data.ReadRemoteObject();
179 if (obj == nullptr) {
180 IAM_LOGE("failed to read remote object");
181 return READ_PARCEL_ERROR;
182 }
183 sptr<SetExecutorPropertyCallbackInterface> callback = iface_cast<SetExecutorPropertyCallbackProxy>(obj);
184 if (callback == nullptr) {
185 IAM_LOGE("SetExecutorPropertyCallbackInterface is nullptr");
186 return GENERAL_ERROR;
187 }
188
189 SetProperty(userId, static_cast<AuthType>(authType), attributes, callback);
190 return SUCCESS;
191 }
192
AuthStub(MessageParcel & data,MessageParcel & reply)193 int32_t UserAuthStub::AuthStub(MessageParcel &data, MessageParcel &reply)
194 {
195 IAM_LOGI("enter");
196 ON_SCOPE_EXIT(IAM_LOGI("leave"));
197
198 std::vector<uint8_t> challenge;
199 int32_t authType;
200 uint32_t authTrustLevel;
201 int32_t apiVersion;
202
203 if (!data.ReadUInt8Vector(&challenge)) {
204 IAM_LOGE("failed to read challenge");
205 return READ_PARCEL_ERROR;
206 }
207 if (!data.ReadInt32(authType)) {
208 IAM_LOGE("failed to read authType");
209 return READ_PARCEL_ERROR;
210 }
211 if (!data.ReadUint32(authTrustLevel)) {
212 IAM_LOGE("failed to read authTrustLevel");
213 return READ_PARCEL_ERROR;
214 }
215
216 sptr<IRemoteObject> obj = data.ReadRemoteObject();
217 if (obj == nullptr) {
218 IAM_LOGE("failed to read remote object");
219 return READ_PARCEL_ERROR;
220 }
221 sptr<UserAuthCallbackInterface> callback = iface_cast<UserAuthCallbackProxy>(obj);
222 if (callback == nullptr) {
223 IAM_LOGE("UserAuthCallbackInterface is nullptr");
224 return GENERAL_ERROR;
225 }
226 if (!data.ReadInt32(apiVersion)) {
227 IAM_LOGE("failed to read apiVersion");
228 return READ_PARCEL_ERROR;
229 }
230
231 uint64_t contextId = Auth(apiVersion, challenge, static_cast<AuthType>(authType),
232 static_cast<AuthTrustLevel>(authTrustLevel), callback);
233 if (!reply.WriteUint64(contextId)) {
234 IAM_LOGE("failed to write AuthUser result");
235 return WRITE_PARCEL_ERROR;
236 }
237 return SUCCESS;
238 }
239
AuthWidgetStub(MessageParcel & data,MessageParcel & reply)240 int32_t UserAuthStub::AuthWidgetStub(MessageParcel &data, MessageParcel &reply)
241 {
242 IAM_LOGI("enter");
243 ON_SCOPE_EXIT(IAM_LOGI("leave"));
244
245 AuthParam authParam;
246 WidgetParam widgetParam;
247 if (!ReadWidgetParam(data, authParam, widgetParam)) {
248 IAM_LOGE("failed to read widget param");
249 return ResultCode::READ_PARCEL_ERROR;
250 }
251
252 sptr<IRemoteObject> obj = data.ReadRemoteObject();
253 if (obj == nullptr) {
254 IAM_LOGE("failed to read remote object");
255 return ResultCode::READ_PARCEL_ERROR;
256 }
257 sptr<UserAuthCallbackInterface> callback = iface_cast<UserAuthCallbackProxy>(obj);
258 if (callback == nullptr) {
259 IAM_LOGE("UserAuthCallbackInterface is nullptr");
260 return ResultCode::GENERAL_ERROR;
261 }
262
263 int32_t apiVersion;
264 if (!data.ReadInt32(apiVersion)) {
265 IAM_LOGE("failed to read apiVersion");
266 return ResultCode::READ_PARCEL_ERROR;
267 }
268
269 uint64_t contextId = AuthWidget(apiVersion, authParam, widgetParam, callback);
270 if (!reply.WriteUint64(contextId)) {
271 IAM_LOGE("failed to write contextId");
272 return ResultCode::WRITE_PARCEL_ERROR;
273 }
274 return ResultCode::SUCCESS;
275 }
276
ReadWidgetParam(MessageParcel & data,AuthParam & authParam,WidgetParam & widgetParam)277 bool UserAuthStub::ReadWidgetParam(MessageParcel &data, AuthParam &authParam, WidgetParam &widgetParam)
278 {
279 if (!data.ReadUInt8Vector(&authParam.challenge)) {
280 IAM_LOGE("failed to read challenge");
281 return false;
282 }
283 std::vector<int32_t> atList;
284 if (!data.ReadInt32Vector(&atList)) {
285 IAM_LOGE("failed to read authTypeList");
286 return false;
287 }
288 for (auto at : atList) {
289 authParam.authType.push_back(static_cast<AuthType>(at));
290 }
291
292 uint32_t authTrustLevel;
293 if (!data.ReadUint32(authTrustLevel)) {
294 IAM_LOGE("failed to read authTrustLevel");
295 return false;
296 }
297 authParam.authTrustLevel = static_cast<AuthTrustLevel>(authTrustLevel);
298
299 widgetParam.title = data.ReadString();
300 widgetParam.navigationButtonText = data.ReadString();
301 int32_t winMode;
302 if (!data.ReadInt32(winMode)) {
303 IAM_LOGE("failed to read window mode");
304 return false;
305 }
306 widgetParam.windowMode = static_cast<WindowModeType>(winMode);
307 return true;
308 }
309
AuthUserStub(MessageParcel & data,MessageParcel & reply)310 int32_t UserAuthStub::AuthUserStub(MessageParcel &data, MessageParcel &reply)
311 {
312 IAM_LOGI("enter");
313 ON_SCOPE_EXIT(IAM_LOGI("leave"));
314
315 int32_t userId;
316 std::vector<uint8_t> challenge;
317 int32_t authType;
318 uint32_t authTrustLevel;
319
320 if (!data.ReadInt32(userId)) {
321 IAM_LOGE("failed to read userId");
322 return READ_PARCEL_ERROR;
323 }
324 if (!data.ReadUInt8Vector(&challenge)) {
325 IAM_LOGE("failed to read challenge");
326 return READ_PARCEL_ERROR;
327 }
328 if (!data.ReadInt32(authType)) {
329 IAM_LOGE("failed to read authType");
330 return READ_PARCEL_ERROR;
331 }
332 if (!data.ReadUint32(authTrustLevel)) {
333 IAM_LOGE("failed to read authTrustLevel");
334 return READ_PARCEL_ERROR;
335 }
336
337 sptr<IRemoteObject> obj = data.ReadRemoteObject();
338 if (obj == nullptr) {
339 IAM_LOGE("failed to read remote object");
340 return READ_PARCEL_ERROR;
341 }
342 sptr<UserAuthCallbackInterface> callback = iface_cast<UserAuthCallbackProxy>(obj);
343 if (callback == nullptr) {
344 IAM_LOGE("UserAuthCallbackInterface is nullptr");
345 return GENERAL_ERROR;
346 }
347
348 uint64_t contextId = AuthUser(userId, challenge, static_cast<AuthType>(authType),
349 static_cast<AuthTrustLevel>(authTrustLevel), callback);
350 if (!reply.WriteUint64(contextId)) {
351 IAM_LOGE("failed to write AuthUser result");
352 return WRITE_PARCEL_ERROR;
353 }
354 return SUCCESS;
355 }
356
IdentifyStub(MessageParcel & data,MessageParcel & reply)357 int32_t UserAuthStub::IdentifyStub(MessageParcel &data, MessageParcel &reply)
358 {
359 IAM_LOGI("enter");
360 ON_SCOPE_EXIT(IAM_LOGI("leave"));
361
362 std::vector<uint8_t> challenge;
363 int32_t authType;
364
365 if (!data.ReadUInt8Vector(&challenge)) {
366 IAM_LOGE("failed to read challenge");
367 return READ_PARCEL_ERROR;
368 }
369 if (!data.ReadInt32(authType)) {
370 IAM_LOGE("failed to read authType");
371 return READ_PARCEL_ERROR;
372 }
373
374 sptr<IRemoteObject> obj = data.ReadRemoteObject();
375 if (obj == nullptr) {
376 IAM_LOGE("failed to read remote object");
377 return READ_PARCEL_ERROR;
378 }
379 sptr<UserAuthCallbackInterface> callback = iface_cast<UserAuthCallbackProxy>(obj);
380 if (callback == nullptr) {
381 IAM_LOGE("UserAuthCallbackInterface is nullptr");
382 return GENERAL_ERROR;
383 }
384
385 uint64_t contextId = Identify(challenge, static_cast<AuthType>(authType), callback);
386 if (!reply.WriteUint64(contextId)) {
387 IAM_LOGE("failed to write Identify result");
388 return WRITE_PARCEL_ERROR;
389 }
390 return SUCCESS;
391 }
392
CancelAuthOrIdentifyStub(MessageParcel & data,MessageParcel & reply)393 int32_t UserAuthStub::CancelAuthOrIdentifyStub(MessageParcel &data, MessageParcel &reply)
394 {
395 IAM_LOGI("enter");
396 ON_SCOPE_EXIT(IAM_LOGI("leave"));
397
398 uint64_t contextId;
399
400 if (!data.ReadUint64(contextId)) {
401 IAM_LOGE("failed to read contextId");
402 return READ_PARCEL_ERROR;
403 }
404
405 int32_t result = CancelAuthOrIdentify(contextId);
406 if (!reply.WriteInt32(result)) {
407 IAM_LOGE("failed to write CancelAuthOrIdentify result");
408 return WRITE_PARCEL_ERROR;
409 }
410 return SUCCESS;
411 }
412
GetVersionStub(MessageParcel & data,MessageParcel & reply)413 int32_t UserAuthStub::GetVersionStub(MessageParcel &data, MessageParcel &reply)
414 {
415 IAM_LOGI("enter");
416 ON_SCOPE_EXIT(IAM_LOGI("leave"));
417
418 int32_t version;
419 int32_t result = GetVersion(version);
420 if (!reply.WriteInt32(version)) {
421 IAM_LOGE("failed to write GetVersion version");
422 return WRITE_PARCEL_ERROR;
423 }
424 if (!reply.WriteInt32(result)) {
425 IAM_LOGE("failed to write GetVersion result");
426 return WRITE_PARCEL_ERROR;
427 }
428 return SUCCESS;
429 }
430
NoticeStub(MessageParcel & data,MessageParcel & reply)431 int32_t UserAuthStub::NoticeStub(MessageParcel &data, MessageParcel &reply)
432 {
433 IAM_LOGI("enter");
434 ON_SCOPE_EXIT(IAM_LOGI("leave"));
435
436 int32_t type;
437 if (!data.ReadInt32(type)) {
438 IAM_LOGE("failed to read type");
439 return ResultCode::READ_PARCEL_ERROR;
440 }
441 NoticeType noticeType = static_cast<NoticeType>(type);
442 if (noticeType != WIDGET_NOTICE) {
443 IAM_LOGE("NoticeStub unsupport notice type");
444 return ResultCode::GENERAL_ERROR;
445 }
446 std::string eventData = data.ReadString();
447
448 int32_t result = Notice(noticeType, eventData);
449 if (!reply.WriteInt32(result)) {
450 IAM_LOGE("failed to write notice result");
451 return ResultCode::WRITE_PARCEL_ERROR;
452 }
453 IAM_LOGI("noticeStub success");
454 return ResultCode::SUCCESS;
455 }
456
RegisterWidgetCallbackStub(MessageParcel & data,MessageParcel & reply)457 int32_t UserAuthStub::RegisterWidgetCallbackStub(MessageParcel &data, MessageParcel &reply)
458 {
459 IAM_LOGI("enter");
460 ON_SCOPE_EXIT(IAM_LOGI("leave"));
461
462 int32_t version;
463 if (!data.ReadInt32(version)) {
464 IAM_LOGE("failed to read version");
465 return READ_PARCEL_ERROR;
466 }
467
468 sptr<IRemoteObject> obj = data.ReadRemoteObject();
469 if (obj == nullptr) {
470 IAM_LOGE("failed to read remote object");
471 return READ_PARCEL_ERROR;
472 }
473 sptr<WidgetCallbackInterface> callback = iface_cast<WidgetCallbackProxy>(obj);
474 if (callback == nullptr) {
475 IAM_LOGE("RegisterWidgetCallbackStub is nullptr");
476 return GENERAL_ERROR;
477 }
478 int32_t result = RegisterWidgetCallback(version, callback);
479 if (!reply.WriteInt32(result)) {
480 IAM_LOGE("failed to write register widget callback result");
481 return WRITE_PARCEL_ERROR;
482 }
483 IAM_LOGI("RegisterWidgetCallbackStub success");
484 return SUCCESS;
485 }
486 } // namespace UserAuth
487 } // namespace UserIam
488 } // namespace OHOS