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