• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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