1 /*
2 * Copyright (c) 2022-2025 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 "account_iam_client.h"
17
18 #include "accesstoken_kit.h"
19 #include "account_error_no.h"
20 #include "account_iam_callback_service.h"
21 #include "account_log_wrapper.h"
22 #include "account_proxy.h"
23 #include "account_permission_manager.h"
24 #include "ipc_skeleton.h"
25 #include "ohos_account_kits_impl.h"
26 #include "os_account_manager.h"
27 #ifdef HAS_PIN_AUTH_PART
28 #include "pinauth_register.h"
29 #endif
30
31 namespace OHOS {
32 namespace AccountSA {
33 namespace {
34 const char PERMISSION_ACCESS_PIN_AUTH[] = "ohos.permission.ACCESS_PIN_AUTH";
35 const char PERMISSION_MANAGE_USER_IDM[] = "ohos.permission.MANAGE_USER_IDM";
36 const char PERMISSION_ACCESS_USER_AUTH_INTERNAL[] = "ohos.permission.ACCESS_USER_AUTH_INTERNAL";
37 }
38
GetInstance()39 AccountIAMClient &AccountIAMClient::GetInstance()
40 {
41 static AccountIAMClient *instance = new (std::nothrow) AccountIAMClient();
42 return *instance;
43 }
44
OpenSession(int32_t userId,std::vector<uint8_t> & challenge)45 int32_t AccountIAMClient::OpenSession(int32_t userId, std::vector<uint8_t> &challenge)
46 {
47 auto proxy = GetAccountIAMProxy();
48 if (proxy == nullptr) {
49 return ERR_ACCOUNT_COMMON_GET_PROXY;
50 }
51 challenge.clear();
52 return proxy->OpenSession(userId, challenge);
53 }
54
CloseSession(int32_t userId)55 int32_t AccountIAMClient::CloseSession(int32_t userId)
56 {
57 auto proxy = GetAccountIAMProxy();
58 if (proxy == nullptr) {
59 return ERR_ACCOUNT_COMMON_GET_PROXY;
60 }
61 return proxy->CloseSession(userId);
62 }
63
AddCredential(int32_t userId,const CredentialParameters & credInfo,const std::shared_ptr<IDMCallback> & callback)64 void AccountIAMClient::AddCredential(
65 int32_t userId, const CredentialParameters& credInfo, const std::shared_ptr<IDMCallback> &callback)
66 {
67 if (callback == nullptr) {
68 ACCOUNT_LOGE("the callback for adding credential is nullptr");
69 return;
70 }
71 Attributes emptyResult;
72 auto proxy = GetAccountIAMProxy();
73 if (proxy == nullptr) {
74 callback->OnResult(ERR_ACCOUNT_COMMON_GET_PROXY, emptyResult);
75 return;
76 }
77 if ((userId == -1) && (!GetCurrentUserId(userId))) {
78 ACCOUNT_LOGE("fail to add credential for invalid userId");
79 callback->OnResult(ERR_ACCOUNT_COMMON_INVALID_PARAMETER, emptyResult);
80 return;
81 }
82 if (credInfo.authType == AuthType::PIN) {
83 SetAuthSubType(userId, static_cast<int32_t>(credInfo.pinType.value_or(PinSubType::PIN_MAX)));
84 }
85 sptr<IIDMCallback> wrapper = new (std::nothrow) IDMCallbackService(userId, callback);
86 if (wrapper == nullptr) {
87 ACCOUNT_LOGE("The wrapper for adding credential is nullptr");
88 callback->OnResult(ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR, emptyResult);
89 return;
90 }
91 CredentialParametersIam credentialParametersIam;
92 credentialParametersIam.credentialParameters = credInfo;
93 auto ret = proxy->AddCredential(userId, credentialParametersIam, wrapper);
94 if (ret != ERR_OK) {
95 ACCOUNT_LOGE("Failed to add credential, error code: %{public}d", ret);
96 wrapper->OnResult(ret, emptyResult.Serialize());
97 }
98 }
99
UpdateCredential(int32_t userId,const CredentialParameters & credInfo,const std::shared_ptr<IDMCallback> & callback)100 void AccountIAMClient::UpdateCredential(
101 int32_t userId, const CredentialParameters& credInfo, const std::shared_ptr<IDMCallback> &callback)
102 {
103 if (callback == nullptr) {
104 ACCOUNT_LOGE("the callback for updating credential is nullptr");
105 return;
106 }
107 Attributes emptyResult;
108 auto proxy = GetAccountIAMProxy();
109 if (proxy == nullptr) {
110 callback->OnResult(ERR_ACCOUNT_COMMON_GET_PROXY, emptyResult);
111 return;
112 }
113 if ((userId == -1) && (!GetCurrentUserId(userId))) {
114 ACCOUNT_LOGE("fail to update credential for invalid userId");
115 callback->OnResult(ERR_ACCOUNT_COMMON_INVALID_PARAMETER, emptyResult);
116 return;
117 }
118 if (credInfo.authType == AuthType::PIN) {
119 SetAuthSubType(userId, static_cast<int32_t>(credInfo.pinType.value_or(PinSubType::PIN_MAX)));
120 }
121 sptr<IIDMCallback> wrapper = new (std::nothrow) IDMCallbackService(userId, callback);
122 if (wrapper == nullptr) {
123 ACCOUNT_LOGE("The wrapper for updating credential is nullptr");
124 callback->OnResult(ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR, emptyResult);
125 return;
126 }
127 CredentialParametersIam credentialParametersIam;
128 credentialParametersIam.credentialParameters = credInfo;
129 auto ret = proxy->UpdateCredential(userId, credentialParametersIam, wrapper);
130 if (ret != ERR_OK) {
131 ACCOUNT_LOGE("Failed to update credential, error code: %{public}d", ret);
132 wrapper->OnResult(ret, emptyResult.Serialize());
133 }
134 }
135
DelCred(int32_t userId,uint64_t credentialId,const std::vector<uint8_t> & authToken,const std::shared_ptr<IDMCallback> & callback)136 void AccountIAMClient::DelCred(int32_t userId, uint64_t credentialId, const std::vector<uint8_t> &authToken,
137 const std::shared_ptr<IDMCallback>& callback)
138 {
139 if (callback == nullptr) {
140 ACCOUNT_LOGE("the callback for deleting credential is nullptr");
141 return;
142 }
143 Attributes emptyResult;
144 auto proxy = GetAccountIAMProxy();
145 if (proxy == nullptr) {
146 callback->OnResult(ERR_ACCOUNT_COMMON_GET_PROXY, emptyResult);
147 return;
148 }
149 if ((userId == -1) && (!GetCurrentUserId(userId))) {
150 callback->OnResult(ERR_ACCOUNT_COMMON_INVALID_PARAMETER, emptyResult);
151 return;
152 }
153 sptr<IIDMCallback> wrapper = new (std::nothrow) IDMCallbackService(userId, callback);
154 if (wrapper == nullptr) {
155 ACCOUNT_LOGE("The wrapper for deleting credential is nullptr");
156 callback->OnResult(ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR, emptyResult);
157 return;
158 }
159 auto ret = proxy->DelCred(userId, credentialId, authToken, wrapper);
160 if (ret != ERR_OK) {
161 ACCOUNT_LOGE("Failed to delete credential, error code: %{public}d", ret);
162 wrapper->OnResult(ret, emptyResult.Serialize());
163 }
164 }
165
DelUser(int32_t userId,const std::vector<uint8_t> & authToken,const std::shared_ptr<IDMCallback> & callback)166 void AccountIAMClient::DelUser(
167 int32_t userId, const std::vector<uint8_t> &authToken, const std::shared_ptr<IDMCallback> &callback)
168 {
169 if (callback == nullptr) {
170 ACCOUNT_LOGE("the callback for deleting user is nullptr");
171 return;
172 }
173 Attributes emptyResult;
174 auto proxy = GetAccountIAMProxy();
175 if (proxy == nullptr) {
176 callback->OnResult(ERR_ACCOUNT_COMMON_GET_PROXY, emptyResult);
177 return;
178 }
179 if ((userId == -1) && (!GetCurrentUserId(userId))) {
180 callback->OnResult(ERR_ACCOUNT_COMMON_INVALID_PARAMETER, emptyResult);
181 return;
182 }
183 sptr<IIDMCallback> wrapper = new (std::nothrow) IDMCallbackService(userId, callback);
184 if (wrapper == nullptr) {
185 ACCOUNT_LOGE("The wrapper for deleting user is nullptr");
186 callback->OnResult(ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR, emptyResult);
187 return;
188 }
189 auto ret = proxy->DelUser(userId, authToken, wrapper);
190 if (ret != ERR_OK) {
191 ACCOUNT_LOGE("Failed to delete user, error code: %{public}d", ret);
192 wrapper->OnResult(ret, emptyResult.Serialize());
193 }
194 }
195
GetCredentialInfo(int32_t userId,AuthType authType,const std::shared_ptr<GetCredInfoCallback> & callback)196 int32_t AccountIAMClient::GetCredentialInfo(
197 int32_t userId, AuthType authType, const std::shared_ptr<GetCredInfoCallback> &callback)
198 {
199 if (callback == nullptr) {
200 ACCOUNT_LOGE("The callback for get credential info is nullptr");
201 return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
202 }
203 std::vector<CredentialInfo> infoList;
204 auto proxy = GetAccountIAMProxy();
205 if (proxy == nullptr) {
206 callback->OnCredentialInfo(ERR_ACCOUNT_COMMON_GET_PROXY, infoList);
207 return ERR_ACCOUNT_COMMON_GET_PROXY;
208 }
209 sptr<IGetCredInfoCallback> wrapper = new (std::nothrow) GetCredInfoCallbackService(callback);
210 if (wrapper == nullptr) {
211 ACCOUNT_LOGE("The wrapper is nullptr");
212 callback->OnCredentialInfo(ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR, infoList);
213 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
214 }
215 ErrCode result = proxy->GetCredentialInfo(userId, static_cast<int32_t>(authType), wrapper);
216 if (result != ERR_OK) {
217 auto infoListIam = ConvertToCredentialInfoIamList(infoList);
218 wrapper->OnCredentialInfo(result, infoListIam);
219 }
220 return result;
221 }
222
Cancel(int32_t userId)223 int32_t AccountIAMClient::Cancel(int32_t userId)
224 {
225 auto proxy = GetAccountIAMProxy();
226 if (proxy == nullptr) {
227 return ERR_ACCOUNT_COMMON_GET_PROXY;
228 }
229 return proxy->Cancel(userId);
230 }
231
232 #ifdef HAS_PIN_AUTH_PART
StartDomainAuth(int32_t userId,const std::shared_ptr<IDMCallback> & callback)233 uint64_t AccountIAMClient::StartDomainAuth(int32_t userId, const std::shared_ptr<IDMCallback> &callback)
234 {
235 std::lock_guard<std::mutex> lock(domainMutex_);
236 Attributes emptyResult;
237 if (domainInputer_ == nullptr) {
238 ACCOUNT_LOGE("the registered inputer is not found or invalid");
239 callback->OnResult(ERR_ACCOUNT_IAM_KIT_INPUTER_NOT_REGISTERED, emptyResult);
240 return 0;
241 }
242 domainInputer_->OnGetData(IAMAuthType::DOMAIN, std::vector<uint8_t>(),
243 std::make_shared<DomainCredentialRecipient>(userId, callback));
244 return 0;
245 }
246 #endif
247
PrepareRemoteAuth(const std::string & remoteNetworkId,const std::shared_ptr<PreRemoteAuthCallback> & callback)248 int32_t AccountIAMClient::PrepareRemoteAuth(
249 const std::string &remoteNetworkId, const std::shared_ptr<PreRemoteAuthCallback> &callback)
250 {
251 if (callback == nullptr) {
252 ACCOUNT_LOGE("Callback for PrepareRemoteAuth is nullptr.");
253 return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
254 }
255 auto proxy = GetAccountIAMProxy();
256 if (proxy == nullptr) {
257 callback->OnResult(ERR_ACCOUNT_COMMON_GET_PROXY);
258 return ERR_ACCOUNT_COMMON_GET_PROXY;
259 }
260 sptr<IPreRemoteAuthCallback> wrapper = new (std::nothrow) PreRemoteAuthCallbackService(callback);
261 if (wrapper == nullptr) {
262 ACCOUNT_LOGE("The wrapper for prepare remote auth is nullptr");
263 callback->OnResult(ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR);
264 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
265 }
266 auto ret = proxy->PrepareRemoteAuth(remoteNetworkId, wrapper);
267 if (ret != ERR_OK) {
268 ACCOUNT_LOGE("Failed to prepare remote auth, error code: %{public}d", ret);
269 wrapper->OnResult(ret);
270 }
271 return ret;
272 }
273
Auth(AuthOptions & authOptions,const std::vector<uint8_t> & challenge,AuthType authType,AuthTrustLevel authTrustLevel,const std::shared_ptr<IDMCallback> & callback)274 uint64_t AccountIAMClient::Auth(AuthOptions& authOptions, const std::vector<uint8_t> &challenge,
275 AuthType authType, AuthTrustLevel authTrustLevel, const std::shared_ptr<IDMCallback> &callback)
276 {
277 return AuthUser(authOptions, challenge, authType, authTrustLevel, callback);
278 }
279
CopyAuthOptionsToAuthParam(const AuthOptions & authOptions,AuthParam & authParam)280 static void CopyAuthOptionsToAuthParam(const AuthOptions &authOptions, AuthParam &authParam)
281 {
282 authParam.userId = authOptions.accountId;
283 authParam.authIntent = authOptions.authIntent;
284 if (!authOptions.hasRemoteAuthOptions) {
285 return;
286 }
287 authParam.remoteAuthParam = RemoteAuthParam();
288 if (authOptions.remoteAuthOptions.hasVerifierNetworkId) {
289 authParam.remoteAuthParam.value().verifierNetworkId = authOptions.remoteAuthOptions.verifierNetworkId;
290 }
291 if (authOptions.remoteAuthOptions.hasCollectorNetworkId) {
292 authParam.remoteAuthParam.value().collectorNetworkId = authOptions.remoteAuthOptions.collectorNetworkId;
293 }
294 if (authOptions.remoteAuthOptions.hasCollectorTokenId) {
295 authParam.remoteAuthParam.value().collectorTokenId = authOptions.remoteAuthOptions.collectorTokenId;
296 }
297 }
298
AuthUser(AuthOptions & authOptions,const std::vector<uint8_t> & challenge,AuthType authType,AuthTrustLevel authTrustLevel,const std::shared_ptr<IDMCallback> & callback)299 uint64_t AccountIAMClient::AuthUser(
300 AuthOptions &authOptions, const std::vector<uint8_t> &challenge, AuthType authType,
301 AuthTrustLevel authTrustLevel, const std::shared_ptr<IDMCallback> &callback)
302 {
303 uint64_t contextId = 0;
304 if (callback == nullptr) {
305 ACCOUNT_LOGE("callback is nullptr");
306 return contextId;
307 }
308 Attributes emptyResult;
309 auto proxy = GetAccountIAMProxy();
310 if (proxy == nullptr) {
311 callback->OnResult(ERR_ACCOUNT_COMMON_GET_PROXY, emptyResult);
312 return contextId;
313 }
314 if ((!authOptions.hasRemoteAuthOptions) && (authOptions.accountId == -1) &&
315 (!GetCurrentUserId(authOptions.accountId))) {
316 callback->OnResult(ERR_ACCOUNT_COMMON_INVALID_PARAMETER, emptyResult);
317 return contextId;
318 }
319 #ifdef HAS_PIN_AUTH_PART
320 if (static_cast<int32_t>(authType) == static_cast<int32_t>(IAMAuthType::DOMAIN)) {
321 return StartDomainAuth(authOptions.accountId, callback);
322 }
323 #endif
324 sptr<IIDMCallback> wrapper = new (std::nothrow) IDMCallbackService(authOptions.accountId, callback);
325 if (wrapper == nullptr) {
326 ACCOUNT_LOGE("The wrapper is nullptr");
327 callback->OnResult(ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR, emptyResult);
328 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
329 }
330 AuthParam authParam;
331 authParam.challenge = challenge;
332 authParam.authType = authType;
333 authParam.authTrustLevel = authTrustLevel;
334 CopyAuthOptionsToAuthParam(authOptions, authParam);
335 ErrCode result = proxy->AuthUser(authParam, wrapper, contextId);
336 if (result != ERR_OK) {
337 ACCOUNT_LOGE("Failed to auth user, result = %{public}d", result);
338 wrapper->OnResult(result, emptyResult.Serialize());
339 }
340 return contextId;
341 }
342
CancelAuth(uint64_t contextId)343 int32_t AccountIAMClient::CancelAuth(uint64_t contextId)
344 {
345 auto proxy = GetAccountIAMProxy();
346 if (proxy == nullptr) {
347 return ERR_ACCOUNT_COMMON_GET_PROXY;
348 }
349 return proxy->CancelAuth(contextId);
350 }
351
GetAvailableStatus(AuthType authType,AuthTrustLevel authTrustLevel,int32_t & status)352 int32_t AccountIAMClient::GetAvailableStatus(AuthType authType, AuthTrustLevel authTrustLevel, int32_t &status)
353 {
354 auto proxy = GetAccountIAMProxy();
355 if (proxy == nullptr) {
356 return ERR_ACCOUNT_COMMON_GET_PROXY;
357 }
358 if (authTrustLevel < UserIam::UserAuth::ATL1 || authTrustLevel > UserIam::UserAuth::ATL4) {
359 ACCOUNT_LOGE("authTrustLevel is not in correct range");
360 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
361 }
362 if (authType < UserIam::UserAuth::ALL) {
363 ACCOUNT_LOGE("authType is not in correct range");
364 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
365 }
366 return proxy->GetAvailableStatus(static_cast<int32_t>(authType), static_cast<uint32_t>(authTrustLevel), status);
367 }
368
GetProperty(int32_t userId,const GetPropertyRequest & request,const std::shared_ptr<GetSetPropCallback> & callback)369 void AccountIAMClient::GetProperty(
370 int32_t userId, const GetPropertyRequest &request, const std::shared_ptr<GetSetPropCallback> &callback)
371 {
372 if (callback == nullptr) {
373 ACCOUNT_LOGE("the callback for getting property is nullptr");
374 return;
375 }
376 Attributes emptyResult;
377 auto proxy = GetAccountIAMProxy();
378 if (proxy == nullptr) {
379 callback->OnResult(ERR_ACCOUNT_COMMON_GET_PROXY, emptyResult);
380 return;
381 }
382 sptr<IGetSetPropCallback> wrapper = new (std::nothrow) GetSetPropCallbackService(callback);
383 if (wrapper == nullptr) {
384 ACCOUNT_LOGE("The wrapper for getting property is nullptr");
385 callback->OnResult(ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR, emptyResult);
386 return;
387 }
388 GetPropertyRequestIam getPropertyRequestIam;
389 getPropertyRequestIam.getPropertyRequest = request;
390 auto ret = proxy->GetProperty(userId, getPropertyRequestIam, wrapper);
391 if (ret != ERR_OK) {
392 ACCOUNT_LOGE("Failed to get property, error code: %{public}d", ret);
393 wrapper->OnResult(ret, emptyResult.Serialize());
394 }
395 }
396
GetPropertyByCredentialId(uint64_t credentialId,std::vector<Attributes::AttributeKey> & keys,const std::shared_ptr<GetSetPropCallback> & callback)397 void AccountIAMClient::GetPropertyByCredentialId(uint64_t credentialId,
398 std::vector<Attributes::AttributeKey> &keys, const std::shared_ptr<GetSetPropCallback> &callback)
399 {
400 if (callback == nullptr) {
401 ACCOUNT_LOGE("The callback for getting property is nullptr");
402 return;
403 }
404 Attributes emptyResult;
405 auto proxy = GetAccountIAMProxy();
406 if (proxy == nullptr) {
407 callback->OnResult(ERR_ACCOUNT_COMMON_GET_PROXY, emptyResult);
408 return;
409 }
410 sptr<IGetSetPropCallback> wrapper = new (std::nothrow) GetSetPropCallbackService(callback);
411 if (wrapper == nullptr) {
412 ACCOUNT_LOGE("The wrapper for getting property by credentialId is nullptr");
413 callback->OnResult(ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR, emptyResult);
414 return;
415 }
416 std::vector<int32_t> keysInt;
417 for (auto &key : keys) {
418 keysInt.push_back(static_cast<int32_t>(key));
419 }
420 auto ret = proxy->GetPropertyByCredentialId(credentialId, keysInt, wrapper);
421 if (ret != ERR_OK) {
422 ACCOUNT_LOGE("Failed to get property by credentialId, error code: %{public}d", ret);
423 wrapper->OnResult(ret, emptyResult.Serialize());
424 }
425 }
426
SetProperty(int32_t userId,const SetPropertyRequest & request,const std::shared_ptr<GetSetPropCallback> & callback)427 void AccountIAMClient::SetProperty(
428 int32_t userId, const SetPropertyRequest &request, const std::shared_ptr<GetSetPropCallback> &callback)
429 {
430 if (callback == nullptr) {
431 ACCOUNT_LOGE("the callback for setting property is nullptr");
432 return;
433 }
434 Attributes emptyResult;
435 auto proxy = GetAccountIAMProxy();
436 if (proxy == nullptr) {
437 callback->OnResult(ERR_ACCOUNT_COMMON_GET_PROXY, emptyResult);
438 return;
439 }
440 sptr<IGetSetPropCallback> wrapper = new (std::nothrow) GetSetPropCallbackService(callback);
441 if (wrapper == nullptr) {
442 ACCOUNT_LOGE("The wrapper for setting property is nullptr");
443 callback->OnResult(ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR, emptyResult);
444 return;
445 }
446 Attributes extraInfo(request.attrs.Serialize());
447 SetPropertyRequestIam setPropertyRequestIam;
448 setPropertyRequestIam.setPropertyRequest.authType = request.authType;
449 setPropertyRequestIam.setPropertyRequest.mode = request.mode;
450 setPropertyRequestIam.setPropertyRequest.attrs = std::move(extraInfo);
451 auto ret = proxy->SetProperty(userId, setPropertyRequestIam, wrapper);
452 if (ret != ERR_OK) {
453 ACCOUNT_LOGE("Failed to set property, error code: %{public}d", ret);
454 wrapper->OnResult(ret, emptyResult.Serialize());
455 }
456 }
457
GetEnrolledId(int32_t accountId,AuthType authType,const std::shared_ptr<GetEnrolledIdCallback> & callback)458 void AccountIAMClient::GetEnrolledId(
459 int32_t accountId, AuthType authType, const std::shared_ptr<GetEnrolledIdCallback> &callback)
460 {
461 if (callback == nullptr) {
462 ACCOUNT_LOGE("The callback for get enrolled id is nullptr");
463 return;
464 }
465 uint64_t emptyResult = 0;
466 auto proxy = GetAccountIAMProxy();
467 if (proxy == nullptr) {
468 callback->OnEnrolledId(ERR_ACCOUNT_COMMON_GET_PROXY, emptyResult);
469 return;
470 }
471 sptr<IGetEnrolledIdCallback> wrapper = new (std::nothrow) GetEnrolledIdCallbackService(callback);
472 if (wrapper == nullptr) {
473 ACCOUNT_LOGE("The wrapper is nullptr");
474 callback->OnEnrolledId(ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR, emptyResult);
475 return;
476 }
477 auto ret = proxy->GetEnrolledId(accountId, static_cast<int32_t>(authType), wrapper);
478 if (ret != ERR_OK) {
479 ACCOUNT_LOGE("Failed to get enrolled id, error code: %{public}d", ret);
480 wrapper->OnEnrolledId(ret, emptyResult);
481 }
482 }
483
CheckSelfPermission(const std::string & permissionName)484 bool AccountIAMClient::CheckSelfPermission(const std::string &permissionName)
485 {
486 Security::AccessToken::AccessTokenID tokenId = IPCSkeleton::GetSelfTokenID();
487 ErrCode result = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, permissionName);
488 return result == Security::AccessToken::TypePermissionState::PERMISSION_GRANTED;
489 }
490
491 #ifdef HAS_PIN_AUTH_PART
RegisterPINInputer(const std::shared_ptr<IInputer> & inputer)492 ErrCode AccountIAMClient::RegisterPINInputer(const std::shared_ptr<IInputer> &inputer)
493 {
494 std::lock_guard<std::mutex> lock(pinMutex_);
495 ErrCode result = AccountPermissionManager::CheckSystemApp(false);
496 if (result != ERR_OK) {
497 ACCOUNT_LOGE("is not system application, result = %{public}u.", result);
498 return result;
499 }
500 if (pinInputer_ != nullptr) {
501 ACCOUNT_LOGE("inputer is already registered");
502 return ERR_ACCOUNT_IAM_KIT_INPUTER_ALREADY_REGISTERED;
503 }
504 int32_t userId = -1;
505 if (!GetCurrentUserId(userId)) {
506 return ERR_ACCOUNT_IAM_KIT_GET_USERID_FAIL;
507 }
508 auto iamInputer = std::make_shared<IAMInputer>(userId, inputer);
509 if (UserIam::PinAuth::PinAuthRegister::GetInstance().RegisterInputer(iamInputer)) {
510 pinInputer_ = inputer;
511 ACCOUNT_LOGI("Register inputer successful!");
512 return ERR_OK;
513 }
514 return ERR_ACCOUNT_COMMON_PERMISSION_DENIED;
515 }
516
RegisterDomainInputer(const std::shared_ptr<IInputer> & inputer)517 ErrCode AccountIAMClient::RegisterDomainInputer(const std::shared_ptr<IInputer> &inputer)
518 {
519 std::lock_guard<std::mutex> lock(domainMutex_);
520 if (domainInputer_ != nullptr) {
521 ACCOUNT_LOGE("inputer is already registered");
522 return ERR_ACCOUNT_IAM_KIT_INPUTER_ALREADY_REGISTERED;
523 }
524 domainInputer_ = inputer;
525 return ERR_OK;
526 }
527
RegisterInputer(int32_t authType,const std::shared_ptr<IInputer> & inputer)528 ErrCode AccountIAMClient::RegisterInputer(int32_t authType, const std::shared_ptr<IInputer> &inputer)
529 {
530 ErrCode result = AccountPermissionManager::CheckSystemApp(false);
531 if (result != ERR_OK) {
532 ACCOUNT_LOGE("is not system application, result = %{public}u.", result);
533 return result;
534 }
535 if ((!CheckSelfPermission(PERMISSION_ACCESS_USER_AUTH_INTERNAL)) &&
536 (!CheckSelfPermission(PERMISSION_MANAGE_USER_IDM))) {
537 ACCOUNT_LOGE("failed to check permission");
538 return ERR_ACCOUNT_COMMON_PERMISSION_DENIED;
539 }
540 if (inputer == nullptr) {
541 ACCOUNT_LOGE("inputer is nullptr");
542 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
543 }
544 switch (authType) {
545 case IAMAuthType::DOMAIN:
546 return RegisterDomainInputer(inputer);
547 default:
548 ACCOUNT_LOGE("Unsupport auth type = %{public}d", authType);
549 return ERR_ACCOUNT_IAM_UNSUPPORTED_AUTH_TYPE;
550 }
551 }
552
UnregisterInputer(int32_t authType)553 ErrCode AccountIAMClient::UnregisterInputer(int32_t authType)
554 {
555 ErrCode result = AccountPermissionManager::CheckSystemApp(false);
556 if (result != ERR_OK) {
557 ACCOUNT_LOGE("is not system application, result = %{public}u.", result);
558 return result;
559 }
560 if ((!CheckSelfPermission(PERMISSION_ACCESS_USER_AUTH_INTERNAL)) &&
561 (!CheckSelfPermission(PERMISSION_MANAGE_USER_IDM))) {
562 ACCOUNT_LOGE("failed to check permission");
563 return ERR_ACCOUNT_COMMON_PERMISSION_DENIED;
564 }
565 switch (authType) {
566 case IAMAuthType::DOMAIN:
567 return UnregisterDomainInputer();
568 default:
569 ACCOUNT_LOGE("Unsupport auth type = %{public}d", authType);
570 return ERR_ACCOUNT_IAM_UNSUPPORTED_AUTH_TYPE;
571 }
572 return ERR_OK;
573 }
574
UnregisterPINInputer()575 ErrCode AccountIAMClient::UnregisterPINInputer()
576 {
577 ErrCode result = AccountPermissionManager::CheckSystemApp(false);
578 if (result != ERR_OK) {
579 ACCOUNT_LOGE("is not system application, result = %{public}u.", result);
580 return result;
581 }
582 if (!CheckSelfPermission(PERMISSION_ACCESS_PIN_AUTH)) {
583 ACCOUNT_LOGE("failed to check permission");
584 return ERR_ACCOUNT_COMMON_PERMISSION_DENIED;
585 }
586 UserIam::PinAuth::PinAuthRegister::GetInstance().UnRegisterInputer();
587 std::lock_guard<std::mutex> lock(pinMutex_);
588 pinInputer_ = nullptr;
589 ACCOUNT_LOGI("Unregister PIN inputer successful!");
590 return ERR_OK;
591 }
592
UnregisterDomainInputer()593 ErrCode AccountIAMClient::UnregisterDomainInputer()
594 {
595 std::lock_guard<std::mutex> lock(domainMutex_);
596 domainInputer_ = nullptr;
597 return ERR_OK;
598 }
599 #endif
600
GetAccountState(int32_t userId)601 IAMState AccountIAMClient::GetAccountState(int32_t userId)
602 {
603 auto proxy = GetAccountIAMProxy();
604 if (proxy == nullptr) {
605 return IDLE;
606 }
607 int32_t state = static_cast<int32_t>(IDLE);
608 proxy->GetAccountState(userId, state);
609 return static_cast<IAMState>(state);
610 }
611
SetAuthSubType(int32_t userId,int32_t authSubType)612 void AccountIAMClient::SetAuthSubType(int32_t userId, int32_t authSubType)
613 {
614 std::lock_guard<std::mutex> lock(mutex_);
615 auto it = credentialMap_.find(userId);
616 if (it != credentialMap_.end()) {
617 return;
618 }
619 credentialMap_[userId] = {
620 .type = authSubType
621 };
622 }
623
GetAuthSubType(int32_t userId)624 int32_t AccountIAMClient::GetAuthSubType(int32_t userId)
625 {
626 std::lock_guard<std::mutex> lock(mutex_);
627 auto it = credentialMap_.find(userId);
628 if (it != credentialMap_.end()) {
629 return it->second.type;
630 }
631 return 0;
632 }
633
GetCurrentUserId(int32_t & userId)634 bool AccountIAMClient::GetCurrentUserId(int32_t &userId)
635 {
636 std::vector<int32_t> userIds;
637 if ((OsAccountManager::QueryActiveOsAccountIds(userIds) != ERR_OK) || userIds.empty()) {
638 ACCOUNT_LOGE("fail to get activated os account ids");
639 return false;
640 }
641 userId = userIds[0];
642 return true;
643 }
644
ResetAccountIAMProxy(const wptr<IRemoteObject> & remote)645 void AccountIAMClient::ResetAccountIAMProxy(const wptr<IRemoteObject>& remote)
646 {
647 std::lock_guard<std::mutex> lock(mutex_);
648 if (proxy_ == nullptr) {
649 ACCOUNT_LOGE("proxy is nullptr");
650 return;
651 }
652 auto serviceRemote = proxy_->AsObject();
653 if ((serviceRemote != nullptr) && (serviceRemote == remote.promote())) {
654 serviceRemote->RemoveDeathRecipient(deathRecipient_);
655 proxy_ = nullptr;
656 }
657 }
658
OnRemoteDied(const wptr<IRemoteObject> & remote)659 void AccountIAMClient::AccountIAMDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
660 {
661 if (remote == nullptr) {
662 ACCOUNT_LOGE("remote is nullptr");
663 return;
664 }
665 AccountIAMClient::GetInstance().ResetAccountIAMProxy(remote);
666 }
667
GetAccountIAMProxy()668 sptr<IAccountIAM> AccountIAMClient::GetAccountIAMProxy()
669 {
670 std::lock_guard<std::mutex> lock(mutex_);
671 if (proxy_ != nullptr) {
672 return proxy_;
673 }
674 sptr<IRemoteObject> object = OhosAccountKitsImpl::GetInstance().GetAccountIAMService();
675 if (object == nullptr) {
676 ACCOUNT_LOGE("failed to get account iam service");
677 return nullptr;
678 }
679 deathRecipient_ = new (std::nothrow) AccountIAMDeathRecipient();
680 if (deathRecipient_ == nullptr) {
681 ACCOUNT_LOGE("failed to create account iam death recipient");
682 return nullptr;
683 }
684 if (!object->AddDeathRecipient(deathRecipient_)) {
685 ACCOUNT_LOGE("failed to add account iam death recipient");
686 deathRecipient_ = nullptr;
687 return nullptr;
688 }
689 proxy_ = iface_cast<IAccountIAM>(object);
690 if (proxy_ == nullptr) {
691 ACCOUNT_LOGE("failed to get account iam proxy");
692 }
693 return proxy_;
694 }
695 } // namespace AccountSA
696 } // namespace OHOS
697