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_service.h"
17 #include "hisysevent_adapter.h"
18
19 #include <cinttypes>
20
21 #include "accesstoken_kit.h"
22 #include "auth_common.h"
23 #include "auth_widget_helper.h"
24 #include "context_factory.h"
25 #include "auth_common.h"
26 #include "context_helper.h"
27 #include "hdi_wrapper.h"
28 #include "iam_check.h"
29 #include "iam_common_defines.h"
30 #include "iam_logger.h"
31 #include "iam_ptr.h"
32 #include "iam_time.h"
33 #include "ipc_common.h"
34 #include "ipc_skeleton.h"
35 #include "widget_client.h"
36
37 #define LOG_LABEL UserIam::Common::LABEL_USER_AUTH_SA
38
39 namespace OHOS {
40 namespace UserIam {
41 namespace UserAuth {
42 namespace {
43 const uint64_t BAD_CONTEXT_ID = 0;
44 const int32_t MINIMUM_VERSION = 0;
45 const int32_t CURRENT_VERSION = 1;
46 const uint32_t AUTH_TRUST_LEVEL_SYS = 1;
47 const int32_t USERIAM_IPC_THREAD_NUM = 4;
48 const uint32_t MAX_AUTH_TYPE_SIZE = 3;
49
GetTemplatesByAuthType(int32_t userId,AuthType authType,std::vector<uint64_t> & templateIds)50 void GetTemplatesByAuthType(int32_t userId, AuthType authType, std::vector<uint64_t> &templateIds)
51 {
52 templateIds.clear();
53 auto credentialInfos = UserIdmDatabase::Instance().GetCredentialInfo(userId, authType);
54 if (credentialInfos.empty()) {
55 IAM_LOGE("user %{public}d has no credential type %{public}d", userId, authType);
56 return;
57 }
58
59 templateIds.reserve(credentialInfos.size());
60 for (auto &info : credentialInfos) {
61 if (info == nullptr) {
62 IAM_LOGE("info is nullptr");
63 continue;
64 }
65 templateIds.push_back(info->GetTemplateId());
66 }
67 }
68
IsTemplateIdListRequired(const std::vector<Attributes::AttributeKey> & keys)69 bool IsTemplateIdListRequired(const std::vector<Attributes::AttributeKey> &keys)
70 {
71 for (const auto &key : keys) {
72 if (key == Attributes::AttributeKey::ATTR_PIN_SUB_TYPE ||
73 key == Attributes::AttributeKey::ATTR_REMAIN_TIMES ||
74 key == Attributes::AttributeKey::ATTR_FREEZING_TIME) {
75 return true;
76 }
77 }
78 return false;
79 }
80
GetResourceNodeByType(AuthType authType,std::vector<std::weak_ptr<ResourceNode>> & authTypeNodes)81 void GetResourceNodeByType(AuthType authType, std::vector<std::weak_ptr<ResourceNode>> &authTypeNodes)
82 {
83 authTypeNodes.clear();
84 ResourceNodePool::Instance().Enumerate(
85 [&authTypeNodes, authType](const std::weak_ptr<ResourceNode> &weakNode) {
86 auto node = weakNode.lock();
87 if (node == nullptr) {
88 return;
89 }
90 if (node->GetAuthType() == authType) {
91 authTypeNodes.push_back(node);
92 }
93 });
94 }
95 } // namespace
96
97 REGISTER_SYSTEM_ABILITY_BY_ID(UserAuthService, SUBSYS_USERIAM_SYS_ABILITY_USERAUTH, true);
98
UserAuthService(int32_t systemAbilityId,bool runOnCreate)99 UserAuthService::UserAuthService(int32_t systemAbilityId, bool runOnCreate)
100 : SystemAbility(systemAbilityId, runOnCreate)
101 {
102 }
103
OnStart()104 void UserAuthService::OnStart()
105 {
106 IAM_LOGI("start service");
107 IPCSkeleton::SetMaxWorkThreadNum(USERIAM_IPC_THREAD_NUM);
108 if (!Publish(this)) {
109 IAM_LOGE("failed to publish service");
110 }
111 }
112
OnStop()113 void UserAuthService::OnStop()
114 {
115 IAM_LOGI("stop service");
116 }
117
GetAvailableStatus(int32_t apiVersion,AuthType authType,AuthTrustLevel authTrustLevel)118 int32_t UserAuthService::GetAvailableStatus(int32_t apiVersion, AuthType authType, AuthTrustLevel authTrustLevel)
119 {
120 IAM_LOGI("start");
121 ResultCode checkRet = CheckServicePermission(authType);
122 if (checkRet != SUCCESS) {
123 IAM_LOGE("failed to check permission");
124 return checkRet;
125 }
126 if (authTrustLevel != ATL1 && authTrustLevel != ATL2 && authTrustLevel != ATL3 && authTrustLevel != ATL4) {
127 IAM_LOGE("authTrustLevel is not in correct range");
128 return TRUST_LEVEL_NOT_SUPPORT;
129 }
130 int32_t userId;
131 if (IpcCommon::GetCallingUserId(*this, userId) != SUCCESS) {
132 IAM_LOGE("failed to get callingUserId");
133 return GENERAL_ERROR;
134 }
135 auto hdi = HdiWrapper::GetHdiInstance();
136 if (hdi == nullptr) {
137 IAM_LOGE("hdi interface is nullptr");
138 return GENERAL_ERROR;
139 }
140 uint32_t supportedAtl = AUTH_TRUST_LEVEL_SYS;
141 int32_t result =
142 hdi->GetAuthTrustLevel(userId, static_cast<HdiAuthType>(authType), supportedAtl);
143 if (result != SUCCESS) {
144 IAM_LOGE("failed to get current supported authTrustLevel from hdi apiVersion:%{public}d result:%{public}d",
145 apiVersion, result);
146 return result;
147 }
148 if (authTrustLevel > supportedAtl) {
149 IAM_LOGE("the current authTrustLevel does not support");
150 return TRUST_LEVEL_NOT_SUPPORT;
151 }
152 return SUCCESS;
153 }
154
GetProperty(int32_t userId,AuthType authType,const std::vector<Attributes::AttributeKey> & keys,sptr<GetExecutorPropertyCallbackInterface> & callback)155 void UserAuthService::GetProperty(int32_t userId, AuthType authType,
156 const std::vector<Attributes::AttributeKey> &keys, sptr<GetExecutorPropertyCallbackInterface> &callback)
157 {
158 IAM_LOGI("start");
159 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
160 Attributes values;
161
162 if (!IpcCommon::CheckPermission(*this, ACCESS_USER_AUTH_INTERNAL_PERMISSION)) {
163 IAM_LOGE("failed to check permission");
164 callback->OnGetExecutorPropertyResult(CHECK_PERMISSION_FAILED, values);
165 return;
166 }
167
168 std::vector<uint64_t> templateIds;
169 if (IsTemplateIdListRequired(keys)) {
170 GetTemplatesByAuthType(userId, authType, templateIds);
171 if (templateIds.size() == 0) {
172 IAM_LOGE("template id list is required, but templateIds size is 0");
173 callback->OnGetExecutorPropertyResult(NOT_ENROLLED, values);
174 return;
175 }
176 }
177
178 std::vector<std::weak_ptr<ResourceNode>> authTypeNodes;
179 GetResourceNodeByType(authType, authTypeNodes);
180 if (authTypeNodes.size() != 1) {
181 IAM_LOGE("auth type %{public}d resource node num %{public}zu is not expected",
182 authType, authTypeNodes.size());
183 callback->OnGetExecutorPropertyResult(GENERAL_ERROR, values);
184 return;
185 }
186
187 auto resourceNode = authTypeNodes[0].lock();
188 if (resourceNode == nullptr) {
189 IAM_LOGE("resourceNode is nullptr");
190 callback->OnGetExecutorPropertyResult(GENERAL_ERROR, values);
191 return;
192 }
193
194 std::vector<uint32_t> uint32Keys;
195 uint32Keys.reserve(keys.size());
196 for (auto &key : keys) {
197 uint32Keys.push_back(static_cast<uint32_t>(key));
198 }
199
200 Attributes attr;
201 attr.SetInt32Value(Attributes::ATTR_AUTH_TYPE, authType);
202 attr.SetUint32Value(Attributes::ATTR_PROPERTY_MODE, PROPERTY_MODE_GET);
203 attr.SetUint64ArrayValue(Attributes::ATTR_TEMPLATE_ID_LIST, templateIds);
204 attr.SetUint64Value(Attributes::ATTR_CALLER_UID, static_cast<uint64_t>(this->GetCallingUid()));
205 attr.SetUint32ArrayValue(Attributes::ATTR_KEY_LIST, uint32Keys);
206
207 int32_t result = resourceNode->GetProperty(attr, values);
208 if (result != SUCCESS) {
209 IAM_LOGE("failed to get property, result = %{public}d", result);
210 }
211 callback->OnGetExecutorPropertyResult(result, values);
212 }
213
SetProperty(int32_t userId,AuthType authType,const Attributes & attributes,sptr<SetExecutorPropertyCallbackInterface> & callback)214 void UserAuthService::SetProperty(int32_t userId, AuthType authType, const Attributes &attributes,
215 sptr<SetExecutorPropertyCallbackInterface> &callback)
216 {
217 IAM_LOGI("start");
218 if (callback == nullptr) {
219 IAM_LOGE("callback is nullptr");
220 return;
221 }
222 if (!IpcCommon::CheckPermission(*this, ACCESS_USER_AUTH_INTERNAL_PERMISSION)) {
223 IAM_LOGE("permission check failed");
224 callback->OnSetExecutorPropertyResult(CHECK_PERMISSION_FAILED);
225 return;
226 }
227
228 std::vector<std::weak_ptr<ResourceNode>> authTypeNodes;
229 GetResourceNodeByType(authType, authTypeNodes);
230 if (authTypeNodes.size() != 1) {
231 IAM_LOGE("auth type %{public}d resource node num %{public}zu is not expected",
232 authType, authTypeNodes.size());
233 callback->OnSetExecutorPropertyResult(GENERAL_ERROR);
234 return;
235 }
236
237 auto resourceNode = authTypeNodes[0].lock();
238 if (resourceNode == nullptr) {
239 IAM_LOGE("resourceNode is nullptr");
240 callback->OnSetExecutorPropertyResult(GENERAL_ERROR);
241 return;
242 }
243 int32_t result = resourceNode->SetProperty(attributes);
244 if (result != SUCCESS) {
245 IAM_LOGE("set property failed, result = %{public}d", result);
246 }
247 callback->OnSetExecutorPropertyResult(result);
248 }
249
CheckNorthPermission(AuthType authType)250 ResultCode UserAuthService::CheckNorthPermission(AuthType authType)
251 {
252 if (!IpcCommon::CheckPermission(*this, ACCESS_BIOMETRIC_PERMISSION)) {
253 IAM_LOGE("CheckNorthPermission failed, no permission");
254 return CHECK_PERMISSION_FAILED;
255 }
256 if (authType == PIN) {
257 IAM_LOGE("CheckNorthPermission, type error");
258 return TYPE_NOT_SUPPORT;
259 }
260 return SUCCESS;
261 }
262
CheckWidgetNorthPermission()263 ResultCode UserAuthService::CheckWidgetNorthPermission()
264 {
265 if (!IpcCommon::CheckPermission(*this, ACCESS_BIOMETRIC_PERMISSION)) {
266 IAM_LOGE("CheckWidgetNorthPermission failed, no permission");
267 return ResultCode::CHECK_PERMISSION_FAILED;
268 }
269 return ResultCode::SUCCESS;
270 }
271
CheckServicePermission(AuthType authType)272 ResultCode UserAuthService::CheckServicePermission(AuthType authType)
273 {
274 if (IpcCommon::CheckPermission(*this, ACCESS_USER_AUTH_INTERNAL_PERMISSION)) {
275 return SUCCESS;
276 }
277 return CheckNorthPermission(authType);
278 }
279
CheckAuthWidgetParam(const AuthParam & authParam,const WidgetParam & widgetParam)280 ResultCode UserAuthService::CheckAuthWidgetParam(const AuthParam &authParam, const WidgetParam &widgetParam)
281 {
282 if (authParam.authType.size() == 0 || authParam.authType.size() > MAX_AUTH_TYPE_SIZE) {
283 IAM_LOGE("invalid authType size:%{public}zu", authParam.authType.size());
284 return ResultCode::INVALID_PARAMETERS;
285 }
286
287 std::set<AuthType> authTypeChecker = {};
288 for (auto &type : authParam.authType) {
289 if (authTypeChecker.find(type) != authTypeChecker.end()) {
290 IAM_LOGE("duplicate auth type");
291 return ResultCode::INVALID_PARAMETERS;
292 }
293 switch (type) {
294 case AuthType::PIN:
295 case AuthType::FACE:
296 case AuthType::FINGERPRINT:
297 break;
298 default:
299 IAM_LOGE("invalid auth type");
300 return ResultCode::TYPE_NOT_SUPPORT;
301 }
302 authTypeChecker.emplace(type);
303 }
304
305 if (authParam.authTrustLevel != AuthTrustLevel::ATL1 && authParam.authTrustLevel != AuthTrustLevel::ATL2
306 && authParam.authTrustLevel != AuthTrustLevel::ATL3 && authParam.authTrustLevel != AuthTrustLevel::ATL4) {
307 IAM_LOGE("authType not match with trustLevel: %{public}u", authParam.authTrustLevel);
308 return ResultCode::TRUST_LEVEL_NOT_SUPPORT;
309 }
310
311 if (widgetParam.title == "") {
312 IAM_LOGE("title shouldn't be empty");
313 return ResultCode::INVALID_PARAMETERS;
314 }
315
316 if (widgetParam.navigationButtonText != "") {
317 IAM_LOGI("authParam.authType.size() = %{public}zu", authParam.authType.size());
318 if (authParam.authType.size() != 1 || (authParam.authType[0] != AuthType::FACE &&
319 authParam.authType[0] != AuthType::FINGERPRINT)) {
320 IAM_LOGE("navigationButtonText check fail");
321 return ResultCode::INVALID_PARAMETERS;
322 }
323 }
324
325 if (widgetParam.windowMode == FULLSCREEN && authParam.authType.size() == 1 &&
326 (authParam.authType[0] == AuthType::FACE || authParam.authType[0] == AuthType::FINGERPRINT)) {
327 IAM_LOGE("Single fingerprint or single face does not support full screen");
328 return ResultCode::GENERAL_ERROR;
329 }
330 return ResultCode::SUCCESS;
331 }
332
GetAuthContextCallback(const std::vector<uint8_t> & challenge,AuthType authType,AuthTrustLevel authTrustLevel,sptr<UserAuthCallbackInterface> & callback)333 std::shared_ptr<ContextCallback> UserAuthService::GetAuthContextCallback(const std::vector<uint8_t> &challenge,
334 AuthType authType, AuthTrustLevel authTrustLevel, sptr<UserAuthCallbackInterface> &callback)
335 {
336 if (callback == nullptr) {
337 IAM_LOGE("callback is nullptr");
338 return nullptr;
339 }
340 auto contextCallback = ContextCallback::NewInstance(callback, TRACE_AUTH_USER);
341 if (contextCallback == nullptr) {
342 IAM_LOGE("failed to construct context callback");
343 Attributes extraInfo;
344 callback->OnResult(GENERAL_ERROR, extraInfo);
345 return nullptr;
346 }
347 auto callingUid = static_cast<uint64_t>(this->GetCallingUid());
348 contextCallback->SetTraceCallingUid(callingUid);
349 contextCallback->SetTraceAuthType(authType);
350 contextCallback->SetTraceAuthTrustLevel(authTrustLevel);
351 return contextCallback;
352 }
353
Auth(int32_t apiVersion,const std::vector<uint8_t> & challenge,AuthType authType,AuthTrustLevel authTrustLevel,sptr<UserAuthCallbackInterface> & callback)354 uint64_t UserAuthService::Auth(int32_t apiVersion, const std::vector<uint8_t> &challenge,
355 AuthType authType, AuthTrustLevel authTrustLevel, sptr<UserAuthCallbackInterface> &callback)
356 {
357 IAM_LOGI("start");
358 auto contextCallback = GetAuthContextCallback(challenge, authType, authTrustLevel, callback);
359 if (contextCallback == nullptr) {
360 IAM_LOGE("contextCallback is nullptr");
361 return BAD_CONTEXT_ID;
362 }
363 Attributes extraInfo;
364 ResultCode checkRet = CheckNorthPermission(authType);
365 if (checkRet != SUCCESS) {
366 IAM_LOGE("CheckNorthPermission failed");
367 contextCallback->OnResult(checkRet, extraInfo);
368 return BAD_CONTEXT_ID;
369 }
370 int32_t userId;
371 if (IpcCommon::GetCallingUserId(*this, userId) != SUCCESS) {
372 IAM_LOGE("get callingUserId failed");
373 contextCallback->OnResult(GENERAL_ERROR, extraInfo);
374 return BAD_CONTEXT_ID;
375 }
376 contextCallback->SetTraceUserId(userId);
377 if (authTrustLevel != ATL1 && authTrustLevel != ATL2 && authTrustLevel != ATL3 && authTrustLevel != ATL4) {
378 IAM_LOGE("authTrustLevel is not in correct range");
379 contextCallback->OnResult(TRUST_LEVEL_NOT_SUPPORT, extraInfo);
380 return BAD_CONTEXT_ID;
381 }
382 ContextFactory::AuthContextPara para = {};
383 para.tokenId = IpcCommon::GetAccessTokenId(*this);
384 para.userId = userId;
385 para.authType = authType;
386 para.atl = authTrustLevel;
387 para.challenge = std::move(challenge);
388 para.endAfterFirstFail = true;
389 auto context = ContextFactory::CreateSimpleAuthContext(para, contextCallback);
390 if (!ContextPool::Instance().Insert(context)) {
391 IAM_LOGE("failed to insert context");
392 contextCallback->OnResult(GENERAL_ERROR, extraInfo);
393 return BAD_CONTEXT_ID;
394 }
395
396 contextCallback->SetCleaner(ContextHelper::Cleaner(context));
397
398 if (!context->Start()) {
399 int32_t errorCode = context->GetLatestError();
400 IAM_LOGE("failed to start auth apiVersion:%{public}d errorCode:%{public}d", apiVersion, errorCode);
401 contextCallback->OnResult(errorCode, extraInfo);
402 return BAD_CONTEXT_ID;
403 }
404 return context->GetContextId();
405 }
406
AuthUser(int32_t userId,const std::vector<uint8_t> & challenge,AuthType authType,AuthTrustLevel authTrustLevel,sptr<UserAuthCallbackInterface> & callback)407 uint64_t UserAuthService::AuthUser(int32_t userId, const std::vector<uint8_t> &challenge,
408 AuthType authType, AuthTrustLevel authTrustLevel, sptr<UserAuthCallbackInterface> &callback)
409 {
410 IAM_LOGI("start");
411 auto contextCallback = GetAuthContextCallback(challenge, authType, authTrustLevel, callback);
412 if (contextCallback == nullptr) {
413 IAM_LOGE("contextCallback is nullptr");
414 return BAD_CONTEXT_ID;
415 }
416 contextCallback->SetTraceUserId(userId);
417 Attributes extraInfo;
418 if (authTrustLevel < ATL1 || authTrustLevel > ATL4) {
419 IAM_LOGE("authTrustLevel is not in correct range");
420 contextCallback->OnResult(TRUST_LEVEL_NOT_SUPPORT, extraInfo);
421 return BAD_CONTEXT_ID;
422 }
423 if (!IpcCommon::CheckPermission(*this, ACCESS_USER_AUTH_INTERNAL_PERMISSION)) {
424 IAM_LOGE("failed to check permission");
425 contextCallback->OnResult(CHECK_PERMISSION_FAILED, extraInfo);
426 return BAD_CONTEXT_ID;
427 }
428 ContextFactory::AuthContextPara para = {};
429 para.tokenId = IpcCommon::GetAccessTokenId(*this);
430 para.userId = userId;
431 para.authType = authType;
432 para.atl = authTrustLevel;
433 para.challenge = std::move(challenge);
434 para.endAfterFirstFail = false;
435 auto context = ContextFactory::CreateSimpleAuthContext(para, contextCallback);
436 if (!ContextPool::Instance().Insert(context)) {
437 IAM_LOGE("failed to insert context");
438 contextCallback->OnResult(GENERAL_ERROR, extraInfo);
439 return BAD_CONTEXT_ID;
440 }
441
442 contextCallback->SetCleaner(ContextHelper::Cleaner(context));
443
444 if (!context->Start()) {
445 IAM_LOGE("failed to start auth");
446 contextCallback->OnResult(context->GetLatestError(), extraInfo);
447 return BAD_CONTEXT_ID;
448 }
449 return context->GetContextId();
450 }
451
Identify(const std::vector<uint8_t> & challenge,AuthType authType,sptr<UserAuthCallbackInterface> & callback)452 uint64_t UserAuthService::Identify(const std::vector<uint8_t> &challenge, AuthType authType,
453 sptr<UserAuthCallbackInterface> &callback)
454 {
455 IAM_LOGI("start");
456
457 if (callback == nullptr) {
458 IAM_LOGE("callback is nullptr");
459 return BAD_CONTEXT_ID;
460 }
461 Attributes extraInfo;
462 auto contextCallback = ContextCallback::NewInstance(callback, TRACE_IDENTIFY);
463 if (contextCallback == nullptr) {
464 IAM_LOGE("failed to construct context callback");
465 callback->OnResult(GENERAL_ERROR, extraInfo);
466 return BAD_CONTEXT_ID;
467 }
468 if (authType == PIN) {
469 IAM_LOGE("pin not support");
470 contextCallback->OnResult(TYPE_NOT_SUPPORT, extraInfo);
471 return BAD_CONTEXT_ID;
472 }
473 if (!IpcCommon::CheckPermission(*this, ACCESS_USER_AUTH_INTERNAL_PERMISSION)) {
474 IAM_LOGE("failed to check permission");
475 contextCallback->OnResult(CHECK_PERMISSION_FAILED, extraInfo);
476 return BAD_CONTEXT_ID;
477 }
478
479 ContextFactory::IdentifyContextPara para = {};
480 para.tokenId = IpcCommon::GetAccessTokenId(*this);
481 para.authType = authType;
482 para.challenge = std::move(challenge);
483 auto context = ContextFactory::CreateIdentifyContext(para, contextCallback);
484 if (!ContextPool::Instance().Insert(context)) {
485 IAM_LOGE("failed to insert context");
486 contextCallback->OnResult(GENERAL_ERROR, extraInfo);
487 return BAD_CONTEXT_ID;
488 }
489
490 contextCallback->SetCleaner(ContextHelper::Cleaner(context));
491
492 if (!context->Start()) {
493 IAM_LOGE("failed to start identify");
494 contextCallback->OnResult(context->GetLatestError(), extraInfo);
495 return BAD_CONTEXT_ID;
496 }
497 return context->GetContextId();
498 }
499
CancelAuthOrIdentify(uint64_t contextId)500 int32_t UserAuthService::CancelAuthOrIdentify(uint64_t contextId)
501 {
502 IAM_LOGI("start");
503 bool checkRet = !IpcCommon::CheckPermission(*this, ACCESS_USER_AUTH_INTERNAL_PERMISSION) &&
504 !IpcCommon::CheckPermission(*this, ACCESS_BIOMETRIC_PERMISSION);
505 if (checkRet) {
506 IAM_LOGE("failed to check permission");
507 return CHECK_PERMISSION_FAILED;
508 }
509 auto context = ContextPool::Instance().Select(contextId).lock();
510 if (context == nullptr) {
511 IAM_LOGE("context not exist");
512 return GENERAL_ERROR;
513 }
514
515 if (context->GetTokenId() != IpcCommon::GetAccessTokenId(*this)) {
516 IAM_LOGE("failed to check tokenId");
517 return INVALID_CONTEXT_ID;
518 }
519
520 if (!context->Stop()) {
521 IAM_LOGE("failed to cancel auth or identify");
522 return context->GetLatestError();
523 }
524
525 return SUCCESS;
526 }
527
GetVersion(int32_t & version)528 int32_t UserAuthService::GetVersion(int32_t &version)
529 {
530 IAM_LOGI("start");
531 version = MINIMUM_VERSION;
532 bool checkRet = !IpcCommon::CheckPermission(*this, ACCESS_USER_AUTH_INTERNAL_PERMISSION) &&
533 !IpcCommon::CheckPermission(*this, ACCESS_BIOMETRIC_PERMISSION);
534 if (checkRet) {
535 IAM_LOGE("failed to check permission");
536 return CHECK_PERMISSION_FAILED;
537 }
538 version = CURRENT_VERSION;
539 return SUCCESS;
540 }
541
CheckParam(const AuthParam & authParam,const WidgetParam & widgetParam)542 ResultCode UserAuthService::CheckParam(const AuthParam &authParam, const WidgetParam &widgetParam)
543 {
544 if (!IpcCommon::CheckPermission(*this, IS_SYSTEM_APP) &&
545 widgetParam.windowMode != WindowModeType::UNKNOWN_WINDOW_MODE) {
546 IAM_LOGE("normal app can't set window mode.");
547 return INVALID_PARAMETERS;
548 }
549 ResultCode checkRet = CheckWidgetNorthPermission();
550 if (checkRet != SUCCESS) {
551 IAM_LOGE("CheckWidgetNorthPermission failed. errCode: %{public}d", checkRet);
552 return checkRet;
553 }
554 checkRet = CheckAuthWidgetParam(authParam, widgetParam);
555 if (checkRet != SUCCESS) {
556 IAM_LOGE("parameter failed. errCode: %{public}d", checkRet);
557 return checkRet;
558 }
559 return SUCCESS;
560 }
561
AuthWidget(int32_t apiVersion,const AuthParam & authParam,const WidgetParam & widgetParam,sptr<UserAuthCallbackInterface> & callback)562 uint64_t UserAuthService::AuthWidget(int32_t apiVersion, const AuthParam &authParam,
563 const WidgetParam &widgetParam, sptr<UserAuthCallbackInterface> &callback)
564 {
565 IAM_LOGI("start");
566 auto contextCallback = GetAuthContextCallback(authParam, widgetParam, callback);
567 if (contextCallback == nullptr) {
568 IAM_LOGE("contextCallback is nullptr");
569 return BAD_CONTEXT_ID;
570 }
571 Attributes extraInfo;
572 ResultCode checkRet = CheckParam(authParam, widgetParam);
573 if (checkRet != SUCCESS) {
574 contextCallback->OnResult(checkRet, extraInfo);
575 return BAD_CONTEXT_ID;
576 }
577 int32_t userId;
578 if (IpcCommon::GetCallingUserId(*this, userId) != SUCCESS) {
579 IAM_LOGE("get callingUserId failed");
580 contextCallback->OnResult(ResultCode::GENERAL_ERROR, extraInfo);
581 return BAD_CONTEXT_ID;
582 }
583 contextCallback->SetTraceUserId(userId);
584 int32_t ret = AuthWidgetHelper::CheckValidSolution(userId, authParam.authType, authParam.authTrustLevel);
585 if (ret != SUCCESS) {
586 contextCallback->OnResult(ret, extraInfo);
587 return BAD_CONTEXT_ID;
588 }
589
590 ContextFactory::AuthWidgetContextPara para;
591 para.userId = userId;
592 para.tokenId = IpcCommon::GetAccessTokenId(*this);
593 para.callingUid = GetCallingUid();
594 if (!AuthWidgetHelper::InitWidgetContextParam(userId, authParam, widgetParam, para)) {
595 IAM_LOGE("init widgetContext failed");
596 contextCallback->OnResult(ResultCode::GENERAL_ERROR, extraInfo);
597 return BAD_CONTEXT_ID;
598 }
599 auto context = ContextFactory::CreateWidgetContext(para, contextCallback);
600 if (!Insert2ContextPool(context)) {
601 contextCallback->OnResult(ResultCode::GENERAL_ERROR, extraInfo);
602 return BAD_CONTEXT_ID;
603 }
604
605 contextCallback->SetCleaner(ContextHelper::Cleaner(context));
606 if (!context->Start()) {
607 int32_t errorCode = context->GetLatestError();
608 IAM_LOGE("failed to start auth apiVersion:%{public}d errorCode:%{public}d", apiVersion, errorCode);
609 contextCallback->OnResult(errorCode, extraInfo);
610 return BAD_CONTEXT_ID;
611 }
612 IAM_LOGI("authWidget end, receive message success.");
613 return context->GetContextId();
614 }
615
Insert2ContextPool(const std::shared_ptr<Context> & context)616 bool UserAuthService::Insert2ContextPool(const std::shared_ptr<Context> &context)
617 {
618 bool ret = false;
619 const int32_t retryTimes = 3;
620 for (auto i = 0; i < retryTimes; i++) {
621 ret = ContextPool::Instance().Insert(context);
622 if (ret) {
623 break;
624 }
625 }
626 IAM_LOGI("insert context to pool, retry %{public}d times", retryTimes);
627 return ret;
628 }
629
GetAuthContextCallback(const AuthParam & authParam,const WidgetParam & widgetParam,sptr<UserAuthCallbackInterface> & callback)630 std::shared_ptr<ContextCallback> UserAuthService::GetAuthContextCallback(const AuthParam &authParam,
631 const WidgetParam &widgetParam, sptr<UserAuthCallbackInterface> &callback)
632 {
633 if (callback == nullptr) {
634 IAM_LOGE("callback is nullptr");
635 return nullptr;
636 }
637 auto contextCallback = ContextCallback::NewInstance(callback, TRACE_AUTH_USER);
638 if (contextCallback == nullptr) {
639 IAM_LOGE("failed to construct context callback");
640 Attributes extraInfo;
641 callback->OnResult(ResultCode::GENERAL_ERROR, extraInfo);
642 return nullptr;
643 }
644 auto callingUid = static_cast<uint64_t>(this->GetCallingUid());
645 contextCallback->SetTraceCallingUid(callingUid);
646 contextCallback->SetTraceAuthTrustLevel(authParam.authTrustLevel);
647
648 uint32_t authWidgetType = 0;
649 for (const auto authType : authParam.authType) {
650 authWidgetType |= static_cast<uint32_t>(authType);
651 }
652 static const uint32_t BIT_WINDOW_MODE = 0x40000000;
653 if (widgetParam.windowMode == FULLSCREEN) {
654 authWidgetType |= BIT_WINDOW_MODE;
655 }
656 static const uint32_t BIT_NAVIGATION = 0x80000000;
657 if (!widgetParam.navigationButtonText.empty()) {
658 authWidgetType |= BIT_NAVIGATION;
659 }
660 IAM_LOGE("SetTraceAuthWidgetType %{public}u", authWidgetType);
661 contextCallback->SetTraceAuthWidgetType(authWidgetType);
662
663 return contextCallback;
664 }
665
Notice(NoticeType noticeType,const std::string & eventData)666 int32_t UserAuthService::Notice(NoticeType noticeType, const std::string &eventData)
667 {
668 IAM_LOGI("start");
669 if (!IpcCommon::CheckPermission(*this, IS_SYSTEM_APP)) {
670 IAM_LOGE("the caller is not a system application");
671 return ResultCode::CHECK_SYSTEM_APP_FAILED;
672 }
673
674 if (!IpcCommon::CheckPermission(*this, SUPPORT_USER_AUTH)) {
675 IAM_LOGE("failed to check permission");
676 return ResultCode::CHECK_PERMISSION_FAILED;
677 }
678 return WidgetClient::Instance().OnNotice(noticeType, eventData);
679 }
680
RegisterWidgetCallback(int32_t version,sptr<WidgetCallbackInterface> & callback)681 int32_t UserAuthService::RegisterWidgetCallback(int32_t version, sptr<WidgetCallbackInterface> &callback)
682 {
683 if (!IpcCommon::CheckPermission(*this, IS_SYSTEM_APP)) {
684 IAM_LOGE("the caller is not a system application");
685 return ResultCode::CHECK_SYSTEM_APP_FAILED;
686 }
687
688 if (!IpcCommon::CheckPermission(*this, SUPPORT_USER_AUTH)) {
689 IAM_LOGE("CheckWidgetNorthPermission failed, no permission");
690 return ResultCode::CHECK_PERMISSION_FAILED;
691 }
692
693 uint32_t tokenId = IpcCommon::GetTokenId(*this);
694 IAM_LOGE("RegisterWidgetCallback tokenId %{public}u", tokenId);
695
696 int32_t curVersion = std::stoi(NOTICE_VERSION_STR);
697 if (version != curVersion) {
698 return ResultCode::INVALID_PARAMETERS;
699 }
700 if (callback == nullptr) {
701 IAM_LOGE("callback is nullptr");
702 return ResultCode::INVALID_PARAMETERS;
703 }
704 WidgetClient::Instance().SetWidgetCallback(callback);
705 WidgetClient::Instance().SetAuthTokenId(tokenId);
706 return ResultCode::SUCCESS;
707 }
708
709 } // namespace UserAuth
710 } // namespace UserIam
711 } // namespace OHOS