• 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 "inner_account_iam_manager.h"
17 
18 #include <thread>
19 #include "account_constants.h"
20 #include "account_iam_callback.h"
21 #include "account_log_wrapper.h"
22 #include "domain_account_callback_service.h"
23 #include "account_hisysevent_adapter.h"
24 #include "iinner_os_account_manager.h"
25 #ifdef SUPPORT_DOMAIN_ACCOUNTS
26 #include "inner_domain_account_manager.h"
27 #endif // SUPPORT_DOMAIN_ACCOUNTS
28 #include "iservice_registry.h"
29 #ifdef HAS_STORAGE_PART
30 #include "storage_service_errno.h"
31 #endif
32 #include "system_ability_definition.h"
33 #include "user_access_ctrl_client.h"
34 #include "user_auth_client.h"
35 #include "user_auth_client_impl.h"
36 #include "user_idm_client.h"
37 #include "access_token.h"
38 #include "ipc_skeleton.h"
39 #include "token_setproc.h"
40 #include "os_account_constants.h"
41 #include "account_file_operator.h"
42 
43 namespace OHOS {
44 namespace AccountSA {
45 namespace {
46 constexpr int32_t DELAY_FOR_EXCEPTION = 100;
47 constexpr int32_t MAX_RETRY_TIMES = 20;
48 constexpr int32_t TIME_WAIT_TIME_OUT = 5;
49 constexpr uint64_t TOKEN_ALLOWABLE_DURATION = 60 * 1000; // 60s -> 60 * 1000ms
50 
51 #ifdef _ARM64_
52 static const std::string RECOVERY_LIB_PATH = "/system/lib64/";
53 #else
54 static const std::string RECOVERY_LIB_PATH = "/system/lib/";
55 #endif
56 static const std::string RECOVERY_SO_PATH = RECOVERY_LIB_PATH + "librecovery_key_service_client.z.so";
57 static const char RECOVERY_METHOD_NAME[] = "UpdateUseAuthWithRecoveryKey";
58 }
59 using UserIDMClient = UserIam::UserAuth::UserIdmClient;
60 using UserAuthClient = UserIam::UserAuth::UserAuthClient;
61 using UserAuthClientImpl = UserIam::UserAuth::UserAuthClientImpl;
62 using UserAccessCtrlClient = UserIam::UserAuth::UserAccessCtrlClient;
63 
64 typedef int32_t (*UpdateUserAuthWithRecoveryKeyFunc)(const std::vector<uint8_t> &authToken,
65     const std::vector<uint8_t> &newSecret, uint64_t secureUid, uint32_t userId);
66 
InnerAccountIAMManager()67 InnerAccountIAMManager::InnerAccountIAMManager()
68 {
69     userStateMap_[0] = IDLE;
70 }
71 
GetInstance()72 InnerAccountIAMManager &InnerAccountIAMManager::GetInstance()
73 {
74     static InnerAccountIAMManager *instance = new (std::nothrow) InnerAccountIAMManager();
75     return *instance;
76 }
77 
GetOperatingUserLock(int32_t id)78 std::shared_ptr<std::mutex> InnerAccountIAMManager::GetOperatingUserLock(int32_t id)
79 {
80     std::lock_guard<std::mutex> lock(operatingMutex_);
81     auto it = userLocks_.find(id);
82     if (it == userLocks_.end()) {
83         auto mutexPtr = std::make_shared<std::mutex>();
84         userLocks_.insert(std::make_pair(id, mutexPtr));
85         return mutexPtr;
86     }
87     return it->second;
88 }
89 
OpenSession(int32_t userId,std::vector<uint8_t> & challenge)90 void InnerAccountIAMManager::OpenSession(int32_t userId, std::vector<uint8_t> &challenge)
91 {
92     ACCOUNT_LOGI("Start to open session, userId:%{public}d", userId);
93     challenge = UserIDMClient::GetInstance().OpenSession(userId);
94     if (challenge.empty()) {
95         ACCOUNT_LOGE("Failed to open session, userId:%{public}d", userId);
96         REPORT_OS_ACCOUNT_FAIL(userId, "openSession", -1, "Failed to open session");
97     }
98     std::lock_guard<std::mutex> lock(mutex_);
99     userStateMap_[userId] = AFTER_OPEN_SESSION;
100 }
101 
CloseSession(int32_t userId)102 void InnerAccountIAMManager::CloseSession(int32_t userId)
103 {
104     ACCOUNT_LOGI("Start to close session, userId:%{public}d", userId);
105     UserIDMClient::GetInstance().CloseSession(userId);
106     std::lock_guard<std::mutex> lock(mutex_);
107     if (userId == 0) {
108         userStateMap_[0] = IDLE;
109     } else {
110         userStateMap_.erase(userId);
111     }
112 }
113 
AddCredential(int32_t userId,const CredentialParameters & credInfo,const sptr<IIDMCallback> & callback)114 void InnerAccountIAMManager::AddCredential(
115     int32_t userId, const CredentialParameters &credInfo, const sptr<IIDMCallback> &callback)
116 {
117     if (callback == nullptr) {
118         ACCOUNT_LOGE("callback is nullptr");
119         return;
120     }
121 
122     std::lock_guard<std::mutex> userLock(*GetOperatingUserLock(userId));
123     sptr<IDMCallbackDeathRecipient> deathRecipient = new (std::nothrow) IDMCallbackDeathRecipient(userId);
124     if ((deathRecipient == nullptr) || (callback->AsObject() == nullptr) ||
125         (!callback->AsObject()->AddDeathRecipient(deathRecipient))) {
126         ACCOUNT_LOGE("Failed to add death recipient for AddCred");
127         return;
128     }
129     if (credInfo.authType == AuthType::PIN) {
130         std::string path = Constants::USER_INFO_BASE + Constants::PATH_SEPARATOR + std::to_string(userId) +
131             Constants::PATH_SEPARATOR + Constants::USER_SECRET_FLAG_FILE_NAME;
132         auto accountFileOperator = std::make_shared<AccountFileOperator>();
133         ErrCode code = accountFileOperator->InputFileByPathAndContent(path, "");
134         if (code != ERR_OK) {
135             ReportOsAccountOperationFail(userId, "addCredential", code, "Failed to write iam_fault file");
136             ACCOUNT_LOGE("Input file fail, path=%{public}s", path.c_str());
137         }
138     }
139     auto idmCallbackWrapper = std::make_shared<AddCredCallback>(userId, credInfo, callback);
140     idmCallbackWrapper->SetDeathRecipient(deathRecipient);
141     ACCOUNT_LOGI("Start to add credential, userId:%{public}d, authType:%{public}d", userId, credInfo.authType);
142     UserIDMClient::GetInstance().AddCredential(userId, credInfo, idmCallbackWrapper);
143     std::unique_lock<std::mutex> lock(idmCallbackWrapper->mutex_);
144     idmCallbackWrapper->onResultCondition_.wait(lock, [idmCallbackWrapper] {
145         return idmCallbackWrapper->isCalled_;
146     });
147 }
148 
UpdateCredential(int32_t userId,const CredentialParameters & credInfo,const sptr<IIDMCallback> & callback)149 void InnerAccountIAMManager::UpdateCredential(
150     int32_t userId, const CredentialParameters &credInfo, const sptr<IIDMCallback> &callback)
151 {
152     if (callback == nullptr) {
153         ACCOUNT_LOGE("callback is nullptr");
154         return;
155     }
156     Attributes emptyResult;
157     if (credInfo.token.empty()) {
158         ACCOUNT_LOGE("token is empty");
159         callback->OnResult(ResultCode::INVALID_PARAMETERS, emptyResult.Serialize());
160         return;
161     }
162 
163     std::lock_guard<std::mutex> userLock(*GetOperatingUserLock(userId));
164     sptr<IDMCallbackDeathRecipient> deathRecipient = new (std::nothrow) IDMCallbackDeathRecipient(userId);
165     sptr<IRemoteObject> object = callback->AsObject();
166     if ((deathRecipient == nullptr) || object == nullptr ||
167         ((object->IsProxyObject()) && (!object->AddDeathRecipient(deathRecipient)))) {
168         ACCOUNT_LOGE("Failed to add death recipient for UpdateCred");
169         return;
170     }
171 
172     auto idmCallbackWrapper = std::make_shared<UpdateCredCallback>(userId, credInfo, callback);
173     idmCallbackWrapper->SetDeathRecipient(deathRecipient);
174     ACCOUNT_LOGI("Start to update credential, userId:%{public}d, authType:%{public}d", userId, credInfo.authType);
175     UserIDMClient::GetInstance().UpdateCredential(userId, credInfo, idmCallbackWrapper);
176     std::unique_lock<std::mutex> lock(idmCallbackWrapper->mutex_);
177     idmCallbackWrapper->onResultCondition_.wait(lock, [idmCallbackWrapper] {
178         return idmCallbackWrapper->isCalled_;
179     });
180 }
181 
DelCred(int32_t userId,uint64_t credentialId,const std::vector<uint8_t> & authToken,const sptr<IIDMCallback> & callback)182 void InnerAccountIAMManager::DelCred(
183     int32_t userId, uint64_t credentialId, const std::vector<uint8_t> &authToken, const sptr<IIDMCallback> &callback)
184 {
185     if (callback == nullptr) {
186         ACCOUNT_LOGE("callback is nullptr");
187         return;
188     }
189     Attributes emptyResult;
190     if (authToken.empty()) {
191         ACCOUNT_LOGD("token is empty");
192         callback->OnResult(ResultCode::INVALID_PARAMETERS, emptyResult.Serialize());
193         return;
194     }
195     uint64_t pinCredentialId = 0;
196     (void)IInnerOsAccountManager::GetInstance().GetOsAccountCredentialId(userId, pinCredentialId);
197     bool isPIN = (pinCredentialId != 0) && (credentialId == pinCredentialId);
198 
199     auto idmCallback = std::make_shared<DelCredCallback>(userId, isPIN, authToken, callback);
200     ACCOUNT_LOGI("Start to delete credential, userId:%{public}d", userId);
201     UserIDMClient::GetInstance().DeleteCredential(userId, credentialId, authToken, idmCallback);
202 }
203 
DelUser(int32_t userId,const std::vector<uint8_t> & authToken,const sptr<IIDMCallback> & callback)204 void InnerAccountIAMManager::DelUser(
205     int32_t userId, const std::vector<uint8_t> &authToken, const sptr<IIDMCallback> &callback)
206 {
207     if (callback == nullptr) {
208         ACCOUNT_LOGE("callback is nullptr");
209         return;
210     }
211     Attributes errResult;
212     if (authToken.empty()) {
213         ACCOUNT_LOGE("token is empty");
214         callback->OnResult(ResultCode::FAIL, errResult.Serialize());
215         return;
216     }
217     std::lock_guard<std::mutex> userLock(*GetOperatingUserLock(userId));
218     Security::AccessToken::AccessTokenID callerTokenId = IPCSkeleton::GetCallingTokenID();
219     auto verifyTokenCallback = std::make_shared<VerifyTokenCallbackWrapper>(userId, authToken, callerTokenId, callback);
220     ACCOUNT_LOGI("Start to verify token before delete user's credential, userId:%{public}d", userId);
221     UserAccessCtrlClient::GetInstance().VerifyAuthToken(authToken, TOKEN_ALLOWABLE_DURATION, verifyTokenCallback);
222     std::unique_lock<std::mutex> lock(verifyTokenCallback->mutex_);
223     verifyTokenCallback->onResultCondition_.wait(lock, [verifyTokenCallback] {
224         return verifyTokenCallback->isCalled_;
225     });
226 }
227 
GetCredentialInfo(int32_t userId,AuthType authType,const sptr<IGetCredInfoCallback> & callback)228 void InnerAccountIAMManager::GetCredentialInfo(
229     int32_t userId, AuthType authType, const sptr<IGetCredInfoCallback> &callback)
230 {
231     if (static_cast<int32_t>(authType) == static_cast<int32_t>(IAMAuthType::DOMAIN)) {
232         std::vector<CredentialInfo> infoList;
233         if (CheckDomainAuthAvailable(userId)) {
234             ACCOUNT_LOGI("Domain auth is support");
235             CredentialInfo info;
236             info.authType = static_cast<AuthType>(IAMAuthType::DOMAIN);
237             info.pinType = static_cast<PinSubType>(IAMAuthSubType::DOMAIN_MIXED);
238             infoList.emplace_back(info);
239         }
240         auto credentialInfoIamList = ConvertToCredentialInfoIamList(infoList);
241         callback->OnCredentialInfo(ERR_OK, credentialInfoIamList);
242         return;
243     }
244     auto getCallback = std::make_shared<GetCredInfoCallbackWrapper>(userId, static_cast<int32_t>(authType), callback);
245     ACCOUNT_LOGI("Start to get credential info, userId=%{public}d, authType=%{public}d", userId, authType);
246     UserIDMClient::GetInstance().GetCredentialInfo(userId, authType, getCallback);
247 }
248 
Cancel(int32_t userId)249 int32_t InnerAccountIAMManager::Cancel(int32_t userId)
250 {
251     std::lock_guard<std::mutex> lock(mutex_);
252     auto it = userStateMap_.find(userId);
253     if ((it == userStateMap_.end()) || (it->second >= AFTER_ADD_CRED)) {
254         ACCOUNT_LOGE("Failed to cancel after 'addCredential' success");
255         return ResultCode::GENERAL_ERROR;
256     }
257     ACCOUNT_LOGI("Start to cancel, userId=%{public}d", userId);
258     return UserIDMClient::GetInstance().Cancel(userId);
259 }
260 
PrepareRemoteAuth(const std::string & remoteNetworkId,const sptr<IPreRemoteAuthCallback> & callback)261 int32_t InnerAccountIAMManager::PrepareRemoteAuth(
262     const std::string &remoteNetworkId, const sptr<IPreRemoteAuthCallback> &callback)
263 {
264     if (callback == nullptr) {
265         ACCOUNT_LOGE("callback is nullptr");
266         return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
267     }
268     ACCOUNT_LOGI("Start to prepare remote auth.");
269     auto prepareCallback = std::make_shared<PrepareRemoteAuthCallbackWrapper>(callback);
270     return UserAuthClient::GetInstance().PrepareRemoteAuth(remoteNetworkId, prepareCallback);
271 }
272 
CopyAuthParam(const AuthParam & authParam,UserIam::UserAuth::AuthParam & iamAuthParam)273 void InnerAccountIAMManager::CopyAuthParam(const AuthParam &authParam, UserIam::UserAuth::AuthParam &iamAuthParam)
274 {
275     iamAuthParam.userId = authParam.userId;
276     iamAuthParam.challenge = authParam.challenge;
277     iamAuthParam.authType = authParam.authType;
278     iamAuthParam.authTrustLevel = authParam.authTrustLevel;
279     iamAuthParam.authIntent = static_cast<UserIam::UserAuth::AuthIntent>(authParam.authIntent);
280     if (authParam.remoteAuthParam != std::nullopt) {
281         iamAuthParam.remoteAuthParam = UserIam::UserAuth::RemoteAuthParam();
282         if (authParam.remoteAuthParam.value().verifierNetworkId != std::nullopt) {
283             iamAuthParam.remoteAuthParam.value().verifierNetworkId =
284                 authParam.remoteAuthParam.value().verifierNetworkId.value();
285         }
286         if (authParam.remoteAuthParam.value().collectorNetworkId != std::nullopt) {
287             iamAuthParam.remoteAuthParam.value().collectorNetworkId =
288                 authParam.remoteAuthParam.value().collectorNetworkId.value();
289         }
290         if (authParam.remoteAuthParam.value().collectorTokenId != std::nullopt) {
291             iamAuthParam.remoteAuthParam.value().collectorTokenId =
292                 authParam.remoteAuthParam.value().collectorTokenId.value();
293         }
294     }
295 }
296 
AuthUser(AuthParam & authParam,const sptr<IIDMCallback> & callback,uint64_t & contextId)297 int32_t InnerAccountIAMManager::AuthUser(
298     AuthParam &authParam, const sptr<IIDMCallback> &callback, uint64_t &contextId)
299 {
300     if (callback == nullptr) {
301         ACCOUNT_LOGE("callback is nullptr");
302         return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
303     }
304     OsAccountInfo osAccountInfo;
305     if ((authParam.remoteAuthParam == std::nullopt) &&
306         (IInnerOsAccountManager::GetInstance().GetRealOsAccountInfoById(authParam.userId,
307             osAccountInfo)) != ERR_OK) {
308         ACCOUNT_LOGE("Account does not exist");
309         return ERR_ACCOUNT_COMMON_ACCOUNT_NOT_EXIST_ERROR;
310     }
311     bool isDeactivating = false;
312     IInnerOsAccountManager::GetInstance().IsOsAccountDeactivating(authParam.userId, isDeactivating);
313     if (isDeactivating) {
314         ACCOUNT_LOGE("The target account is deactivating, accountId:%{public}d", authParam.userId);
315         return ERR_IAM_BUSY;
316     }
317 #ifdef SUPPORT_LOCK_OS_ACCOUNT
318     bool isLocking = false;
319     IInnerOsAccountManager::GetInstance().IsOsAccountLocking(authParam.userId, isLocking);
320     if (isLocking) {
321         ACCOUNT_LOGE("The target account is isLocking, accountId:%{public}d", authParam.userId);
322         return ERR_IAM_BUSY;
323     }
324 #endif
325     sptr<AuthCallbackDeathRecipient> deathRecipient = new (std::nothrow) AuthCallbackDeathRecipient();
326     if ((deathRecipient == nullptr) || (!callback->AsObject()->AddDeathRecipient(deathRecipient))) {
327         ACCOUNT_LOGE("failed to add death recipient for auth callback");
328         return ERR_ACCOUNT_COMMON_ADD_DEATH_RECIPIENT;
329     }
330 
331     auto callbackWrapper = std::make_shared<AuthCallback>(authParam.userId,
332         authParam.authType, authParam.authIntent, (authParam.remoteAuthParam != std::nullopt), callback);
333     callbackWrapper->SetDeathRecipient(deathRecipient);
334 
335     UserIam::UserAuth::AuthParam iamAuthParam;
336     CopyAuthParam(authParam, iamAuthParam);
337     ACCOUNT_LOGI("Start to auth user.");
338     contextId = UserAuthClient::GetInstance().BeginAuthentication(iamAuthParam, callbackWrapper);
339     deathRecipient->SetContextId(contextId);
340     return ERR_OK;
341 }
342 
CancelAuth(uint64_t contextId)343 int32_t InnerAccountIAMManager::CancelAuth(uint64_t contextId)
344 {
345     ACCOUNT_LOGI("Start to cancel auth");
346     return UserAuthClient::GetInstance().CancelAuthentication(contextId);
347 }
348 
GetAvailableStatus(AuthType authType,AuthTrustLevel authTrustLevel,int32_t & status)349 int32_t InnerAccountIAMManager::GetAvailableStatus(
350     AuthType authType, AuthTrustLevel authTrustLevel, int32_t &status)
351 {
352     if (static_cast<int32_t>(authType) != static_cast<int32_t>(IAMAuthType::DOMAIN)) {
353         status = UserAuthClientImpl::Instance().GetAvailableStatus(authType, authTrustLevel);
354         ACCOUNT_LOGI("Get available status ret:%{public}d, authType:%{public}d, authTrustLevel:%{public}d",
355             status, authType, authTrustLevel);
356         return ERR_OK;
357     }
358 #ifdef SUPPORT_DOMAIN_ACCOUNTS
359     bool isPluginAvailable = InnerDomainAccountManager::GetInstance().IsPluginAvailable();
360     if (isPluginAvailable) {
361         status = ERR_JS_SUCCESS;
362     } else {
363         ACCOUNT_LOGI("Domain auth is not support");
364         status = ERR_JS_AUTH_TYPE_NOT_SUPPORTED;
365     }
366 #else
367     ACCOUNT_LOGI("Domain auth is not support");
368     status = ERR_JS_AUTH_TYPE_NOT_SUPPORTED;
369 #endif // SUPPORT_DOMAIN_ACCOUNTS
370     return ERR_OK;
371 }
372 
373 #ifdef SUPPORT_DOMAIN_ACCOUNTS
GetDomainAuthStatusInfo(int32_t userId,const GetPropertyRequest & request,const sptr<IGetSetPropCallback> & callback)374 ErrCode InnerAccountIAMManager::GetDomainAuthStatusInfo(
375     int32_t userId, const GetPropertyRequest &request, const sptr<IGetSetPropCallback> &callback)
376 {
377     OsAccountInfo osAccountInfo;
378     ErrCode result = IInnerOsAccountManager::GetInstance().GetRealOsAccountInfoById(userId, osAccountInfo);
379     if (result != ERR_OK) {
380         ACCOUNT_LOGE("failed to get account info");
381         return ERR_ACCOUNT_COMMON_ACCOUNT_NOT_EXIST_ERROR;
382     }
383     DomainAccountInfo domainAccountInfo;
384     osAccountInfo.GetDomainInfo(domainAccountInfo);
385     if (domainAccountInfo.accountName_.empty()) {
386         ACCOUNT_LOGE("the target user is not a domain account");
387         return ERR_ACCOUNT_IAM_UNSUPPORTED_AUTH_TYPE;
388     }
389     std::shared_ptr<DomainAccountCallback> statusCallback =
390         std::make_shared<GetDomainAuthStatusInfoCallback>(request, callback);
391     if (statusCallback == nullptr) {
392         ACCOUNT_LOGE("failed to create GetDomainAuthStatusInfoCallback");
393         return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
394     }
395     return InnerDomainAccountManager::GetInstance().GetAuthStatusInfo(domainAccountInfo, statusCallback);
396 }
397 #endif // SUPPORT_DOMAIN_ACCOUNTS
398 
CheckDomainAuthAvailable(int32_t userId)399 bool InnerAccountIAMManager::CheckDomainAuthAvailable(int32_t userId)
400 {
401 #ifdef SUPPORT_DOMAIN_ACCOUNTS
402     OsAccountInfo osAccountInfo;
403     if (IInnerOsAccountManager::GetInstance().GetRealOsAccountInfoById(userId, osAccountInfo) != ERR_OK) {
404         ACCOUNT_LOGE("failed to get account info");
405         return false;
406     }
407     DomainAccountInfo domainAccountInfo;
408     osAccountInfo.GetDomainInfo(domainAccountInfo);
409     bool isAvailable = InnerDomainAccountManager::GetInstance().IsPluginAvailable();
410     return !domainAccountInfo.accountName_.empty() && isAvailable;
411 #else
412     return false;
413 #endif // SUPPORT_DOMAIN_ACCOUNTS
414 }
415 
GetProperty(int32_t userId,const GetPropertyRequest & request,const sptr<IGetSetPropCallback> & callback)416 void InnerAccountIAMManager::GetProperty(
417     int32_t userId, const GetPropertyRequest &request, const sptr<IGetSetPropCallback> &callback)
418 {
419     if (callback == nullptr) {
420         ACCOUNT_LOGE("callback is nullptr");
421         return;
422     }
423     if (static_cast<int32_t>(request.authType) != static_cast<int32_t>(IAMAuthType::DOMAIN)) {
424         auto getCallback = std::make_shared<GetPropCallbackWrapper>(userId, callback);
425         ACCOUNT_LOGI("Start to get property by authType:%{public}d.", request.authType);
426         UserAuthClient::GetInstance().GetProperty(userId, request, getCallback);
427         return;
428     }
429 #ifdef SUPPORT_DOMAIN_ACCOUNTS
430     ErrCode result = GetDomainAuthStatusInfo(userId, request, callback);
431     if (result != ERR_OK) {
432         Attributes attributes;
433         callback->OnResult(result, attributes.Serialize());
434     }
435 #else
436     Attributes attributes;
437     callback->OnResult(ResultCode::NOT_ENROLLED, attributes.Serialize());
438 #endif // SUPPORT_DOMAIN_ACCOUNTS
439 }
440 
GetPropertyByCredentialId(uint64_t credentialId,std::vector<Attributes::AttributeKey> & keys,const sptr<IGetSetPropCallback> & callback)441 void InnerAccountIAMManager::GetPropertyByCredentialId(uint64_t credentialId,
442     std::vector<Attributes::AttributeKey> &keys, const sptr<IGetSetPropCallback> &callback)
443 {
444     if (callback == nullptr) {
445         ACCOUNT_LOGE("Callback is nullptr");
446         return;
447     }
448     auto getPropCallback = std::make_shared<GetPropCallbackWrapper>(-1, callback);
449     ACCOUNT_LOGI("Start to get property by credentialId.");
450     UserAuthClient::GetInstance().GetPropertyById(credentialId, keys, getPropCallback);
451     return;
452 }
453 
SetProperty(int32_t userId,const SetPropertyRequest & request,const sptr<IGetSetPropCallback> & callback)454 void InnerAccountIAMManager::SetProperty(
455     int32_t userId, const SetPropertyRequest &request, const sptr<IGetSetPropCallback> &callback)
456 {
457     if (static_cast<int32_t>(request.authType) == static_cast<int32_t>(IAMAuthType::DOMAIN)) {
458         Attributes result;
459         callback->OnResult(ERR_ACCOUNT_IAM_UNSUPPORTED_AUTH_TYPE, result.Serialize());
460         return;
461     }
462     auto setCallback = std::make_shared<SetPropCallbackWrapper>(userId, callback);
463     ACCOUNT_LOGI("Start to set property, userId:%{public}d, authType:%{public}d.", userId, request.authType);
464     UserAuthClient::GetInstance().SetProperty(userId, request, setCallback);
465 }
466 
GetEnrolledId(int32_t accountId,AuthType authType,const sptr<IGetEnrolledIdCallback> & callback)467 void InnerAccountIAMManager::GetEnrolledId(
468     int32_t accountId, AuthType authType, const sptr<IGetEnrolledIdCallback> &callback)
469 {
470     if (static_cast<int32_t>(authType) == static_cast<int32_t>(IAMAuthType::DOMAIN)) {
471         ACCOUNT_LOGE("Unsupported auth type");
472         uint64_t emptyId = 0;
473         callback->OnEnrolledId(ERR_ACCOUNT_IAM_UNSUPPORTED_AUTH_TYPE, emptyId);
474         return;
475     }
476     auto GetSecUserInfoCallback = std::make_shared<GetSecUserInfoCallbackWrapper>(accountId, authType, callback);
477     ACCOUNT_LOGI("Start to get sec user info, userId:%{public}d, authType:%{public}d", accountId, authType);
478     UserIDMClient::GetInstance().GetSecUserInfo(accountId, GetSecUserInfoCallback);
479 }
480 
HandleFileKeyException(int32_t userId,const std::vector<uint8_t> & secret,const std::vector<uint8_t> & token)481 void InnerAccountIAMManager::HandleFileKeyException(int32_t userId, const std::vector<uint8_t> &secret,
482     const std::vector<uint8_t> &token)
483 {
484     std::string path = Constants::USER_INFO_BASE + Constants::PATH_SEPARATOR + std::to_string(userId) +
485         Constants::PATH_SEPARATOR + Constants::USER_SECRET_FLAG_FILE_NAME;
486     auto accountFileOperator = std::make_shared<AccountFileOperator>();
487     bool isExistFile = accountFileOperator->IsExistFile(path);
488     ACCOUNT_LOGI("The iam_fault file existence status:%{public}d, userId:%{public}d", isExistFile, userId);
489     if (!isExistFile) {
490         return;
491     }
492     auto callback = std::make_shared<GetSecureUidCallback>(userId);
493     ACCOUNT_LOGI("Start to get sec user info, userId=%{public}d", userId);
494     ErrCode code = UserIDMClient::GetInstance().GetSecUserInfo(userId, callback);
495     if (code != ERR_OK) {
496         ACCOUNT_LOGE("Failed to get secure uid, userId: %{public}d", userId);
497         ReportOsAccountOperationFail(userId, "readdCredential", code,
498             "Failed to get secure uid when restoring key context");
499         return;
500     }
501     std::unique_lock<std::mutex> lck(callback->secureMtx_);
502     auto status = callback->secureCv_.wait_for(lck, std::chrono::seconds(TIME_WAIT_TIME_OUT), [callback] {
503         return callback->isCalled_;
504     });
505     if (!status) {
506         ACCOUNT_LOGE("GetSecureUidCallback time out");
507         ReportOsAccountOperationFail(
508             userId, "readdCredential", -1, "Get secure uid timeout when restoring key context");
509         return;
510     }
511     code = UpdateStorageUserAuth(userId, callback->secureUid_, token, {}, secret);
512     if (code != ERR_OK) {
513         ACCOUNT_LOGE("Restore user auth fail, userId: %{public}d", userId);
514         ReportOsAccountOperationFail(userId, "readdCredential", code, "Failed to restore user auth");
515         return;
516     }
517     code = UpdateStorageKeyContext(userId);
518     if (code != ERR_OK) {
519         ACCOUNT_LOGE("Restore key context fail, userId:%{public}d", userId);
520         ReportOsAccountOperationFail(userId, "readdCredential", code, "Failed to restore key context");
521         return;
522     }
523     ACCOUNT_LOGI("Restore key context successfully, userId:%{public}d", userId);
524     code = accountFileOperator->DeleteDirOrFile(path);
525     if (code != ERR_OK) {
526         ReportOsAccountOperationFail(userId, "readdCredential", code,
527             "Failed to delete iam_fault file after restoring key context");
528     }
529 }
530 
GetState(int32_t userId)531 IAMState InnerAccountIAMManager::GetState(int32_t userId)
532 {
533     std::lock_guard<std::mutex> lock(mutex_);
534     auto it = userStateMap_.find(userId);
535     if (it != userStateMap_.end()) {
536         return it->second;
537     }
538     return userStateMap_[0];
539 }
540 
SetState(int32_t userId,IAMState state)541 void InnerAccountIAMManager::SetState(int32_t userId, IAMState state)
542 {
543     std::lock_guard<std::mutex> lock(mutex_);
544     userStateMap_[userId] = state;
545 }
546 
UpdateStorageKeyContext(const int32_t userId)547 ErrCode InnerAccountIAMManager::UpdateStorageKeyContext(const int32_t userId)
548 {
549     int times = 0;
550     ErrCode errCode = ERR_OK;
551     while (times < MAX_RETRY_TIMES) {
552         errCode = InnerUpdateStorageKeyContext(userId);
553         if ((errCode != Constants::E_IPC_ERROR) && (errCode != Constants::E_IPC_SA_DIED)) {
554             return errCode;
555         }
556         ACCOUNT_LOGE("errCode=%{public}d, userId=%{public}d, times=%{public}d", errCode, userId, times);
557         times++;
558         std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
559     }
560     return errCode;
561 }
562 
InnerUpdateStorageKeyContext(const int32_t userId)563 ErrCode InnerAccountIAMManager::InnerUpdateStorageKeyContext(const int32_t userId)
564 {
565     ACCOUNT_LOGI("Enter, userId=%{public}d", userId);
566 #ifdef HAS_STORAGE_PART
567     auto storageMgrProxy = GetStorageManagerProxy();
568     if (storageMgrProxy == nullptr) {
569         ACCOUNT_LOGE("Fail to get storage proxy");
570         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY;
571     }
572     ErrCode code = storageMgrProxy->UpdateKeyContext(userId, false);
573     if (code != ERR_OK) {
574         ACCOUNT_LOGE("Fail to update key context, userId=%{public}d, code=%{public}d", userId, code);
575         return code;
576     }
577 #endif
578     return ERR_OK;
579 }
580 
UpdateStorageUserAuth(int32_t userId,uint64_t secureUid,const std::vector<uint8_t> & token,const std::vector<uint8_t> & oldSecret,const std::vector<uint8_t> & newSecret)581 ErrCode InnerAccountIAMManager::UpdateStorageUserAuth(int32_t userId, uint64_t secureUid,
582     const std::vector<uint8_t> &token, const std::vector<uint8_t> &oldSecret, const std::vector<uint8_t> &newSecret)
583 {
584     int times = 0;
585     ErrCode errCode = ERR_OK;
586     while (times < MAX_RETRY_TIMES) {
587         errCode = InnerUpdateStorageUserAuth(userId, secureUid, token, oldSecret, newSecret);
588         if ((errCode != Constants::E_IPC_ERROR) && (errCode != Constants::E_IPC_SA_DIED)) {
589             return errCode;
590         }
591         ACCOUNT_LOGE("errCode=%{public}d, userId=%{public}d, times=%{public}d", errCode, userId, times);
592         times++;
593         std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
594     }
595     return errCode;
596 }
597 
InnerUpdateStorageUserAuth(int32_t userId,uint64_t secureUid,const std::vector<uint8_t> & token,const std::vector<uint8_t> & oldSecret,const std::vector<uint8_t> & newSecret)598 ErrCode InnerAccountIAMManager::InnerUpdateStorageUserAuth(int32_t userId, uint64_t secureUid,
599     const std::vector<uint8_t> &token, const std::vector<uint8_t> &oldSecret, const std::vector<uint8_t> &newSecret)
600 {
601     ACCOUNT_LOGI("Enter, userId=%{public}d", userId);
602 #ifdef HAS_STORAGE_PART
603     auto storageMgrProxy = GetStorageManagerProxy();
604     if (storageMgrProxy == nullptr) {
605         ACCOUNT_LOGE("Fail to get storage proxy");
606         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY;
607     }
608 
609     ErrCode code = storageMgrProxy->UpdateUserAuth(userId, secureUid, token, oldSecret, newSecret);
610     if ((code != ERR_OK) && (code != ErrNo::E_PARAMS_NULLPTR_ERR)) {
611         ACCOUNT_LOGE("Fail to update user auth, userId=%{public}d, code=%{public}d", userId, code);
612         return code;
613     }
614 #endif
615     return ERR_OK;
616 }
617 
UpdateUserAuthWithRecoveryKey(const std::vector<uint8_t> & authToken,const std::vector<uint8_t> & newSecret,uint64_t secureUid,uint32_t userId)618 ErrCode InnerAccountIAMManager::UpdateUserAuthWithRecoveryKey(const std::vector<uint8_t> &authToken,
619     const std::vector<uint8_t> &newSecret, uint64_t secureUid, uint32_t userId)
620 {
621     ACCOUNT_LOGI("Enter, userId=%{public}d", userId);
622     void *handle = dlopen(RECOVERY_SO_PATH.c_str(), RTLD_LAZY);
623     if (handle == nullptr) {
624         ACCOUNT_LOGE("Call dlopen failed, error=%{public}s.", dlerror());
625         return ERR_INVALID_VALUE;
626     }
627     void *updateUserAuthWithRecoveryKey = dlsym(handle, RECOVERY_METHOD_NAME);
628     if (updateUserAuthWithRecoveryKey == nullptr) {
629         ACCOUNT_LOGE("Call dlsym failed, method=%{public}s error=%{public}s.",
630             RECOVERY_METHOD_NAME, dlerror());
631         dlclose(handle);
632         return ERR_INVALID_VALUE;
633     }
634     ErrCode res = (*reinterpret_cast<UpdateUserAuthWithRecoveryKeyFunc>(updateUserAuthWithRecoveryKey))(
635         authToken, newSecret, secureUid, userId);
636     dlclose(handle);
637     if (res != ERR_OK) {
638         ACCOUNT_LOGE("Call updateUserAuthWithRecoveryKey failed, error=%{public}d.", res);
639     }
640     return res;
641 }
642 
GetLockScreenStatus(uint32_t userId,bool & lockScreenStatus)643 ErrCode InnerAccountIAMManager::GetLockScreenStatus(uint32_t userId, bool &lockScreenStatus)
644 {
645     int times = 0;
646     ErrCode errCode = ERR_OK;
647     while (times < MAX_RETRY_TIMES) {
648         errCode = InnerGetLockScreenStatus(userId, lockScreenStatus);
649         if ((errCode != Constants::E_IPC_ERROR) && (errCode != Constants::E_IPC_SA_DIED)) {
650             return errCode;
651         }
652         ACCOUNT_LOGE("errCode=%{public}d, userId=%{public}d, times=%{public}d", errCode, userId, times);
653         times++;
654         std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
655     }
656     return errCode;
657 }
658 
InnerGetLockScreenStatus(uint32_t userId,bool & lockScreenStatus)659 ErrCode InnerAccountIAMManager::InnerGetLockScreenStatus(uint32_t userId, bool &lockScreenStatus)
660 {
661 #ifdef HAS_STORAGE_PART
662     auto storageMgrProxy = GetStorageManagerProxy();
663     if (storageMgrProxy == nullptr) {
664         ACCOUNT_LOGE("fail to get storage proxy");
665         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY;
666     }
667     ErrCode result = storageMgrProxy->GetLockScreenStatus(userId, lockScreenStatus);
668     if (result != ERR_OK) {
669         ACCOUNT_LOGE("Failed to get lock screen status, ret:%{public}d, userId:%{public}d", result, userId);
670         return result;
671     }
672 #endif
673     return ERR_OK;
674 }
675 
UnlockUserScreen(int32_t userId,const std::vector<uint8_t> & token,const std::vector<uint8_t> & secret)676 ErrCode InnerAccountIAMManager::UnlockUserScreen(
677     int32_t userId, const std::vector<uint8_t> &token, const std::vector<uint8_t> &secret)
678 {
679     int times = 0;
680     ErrCode errCode = ERR_OK;
681     while (times < MAX_RETRY_TIMES) {
682         errCode = InnerUnlockUserScreen(userId, token, secret);
683         if ((errCode != Constants::E_IPC_ERROR) && (errCode != Constants::E_IPC_SA_DIED)) {
684             return errCode;
685         }
686         ACCOUNT_LOGE("errCode=%{public}d, userId=%{public}d, times=%{public}d", errCode, userId, times);
687         times++;
688         std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
689     }
690     return errCode;
691 }
692 
InnerUnlockUserScreen(int32_t userId,const std::vector<uint8_t> & token,const std::vector<uint8_t> & secret)693 ErrCode InnerAccountIAMManager::InnerUnlockUserScreen(
694     int32_t userId, const std::vector<uint8_t> &token, const std::vector<uint8_t> &secret)
695 {
696 #ifdef HAS_STORAGE_PART
697     auto storageMgrProxy = GetStorageManagerProxy();
698     if (storageMgrProxy == nullptr) {
699         ACCOUNT_LOGE("fail to get storage proxy");
700         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY;
701     }
702     ErrCode result = storageMgrProxy->UnlockUserScreen(userId, token, secret);
703     if (result != ERR_OK) {
704         ACCOUNT_LOGE("Fail to unlock screen, ret:%{public}d, userId:%{public}d", result, userId);
705         return result;
706     }
707 #endif
708     return ERR_OK;
709 }
710 
ActivateUserKey(int32_t userId,const std::vector<uint8_t> & token,const std::vector<uint8_t> & secret)711 ErrCode InnerAccountIAMManager::ActivateUserKey(
712     int32_t userId, const std::vector<uint8_t> &token, const std::vector<uint8_t> &secret)
713 {
714     int times = 0;
715     ErrCode errCode = ERR_OK;
716     while (times < MAX_RETRY_TIMES) {
717         errCode = InnerActivateUserKey(userId, token, secret);
718         if ((errCode != Constants::E_IPC_ERROR) && (errCode != Constants::E_IPC_SA_DIED) &&
719             (errCode != ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY)) {
720             return errCode;
721         }
722         ACCOUNT_LOGE("Fail to activate user key, errCode=%{public}d, userId=%{public}d, times=%{public}d",
723             errCode, userId, times);
724         times++;
725         std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
726     }
727     return errCode;
728 }
729 
InnerActivateUserKey(int32_t userId,const std::vector<uint8_t> & token,const std::vector<uint8_t> & secret)730 ErrCode InnerAccountIAMManager::InnerActivateUserKey(
731     int32_t userId, const std::vector<uint8_t> &token, const std::vector<uint8_t> &secret)
732 {
733     ErrCode result = ERR_OK;
734 #ifdef HAS_STORAGE_PART
735     auto storageMgrProxy = GetStorageManagerProxy();
736     if (storageMgrProxy == nullptr) {
737         ACCOUNT_LOGE("Fail to get storage proxy");
738         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY;
739     }
740     result = storageMgrProxy->ActiveUserKey(userId, token, secret);
741     ACCOUNT_LOGI("ActiveUserKey end, ret: %{public}d", result);
742 #endif
743     return result;
744 }
745 
PrepareStartUser(int32_t userId)746 ErrCode InnerAccountIAMManager::PrepareStartUser(int32_t userId)
747 {
748     int times = 0;
749     ErrCode errCode = ERR_OK;
750     while (times < MAX_RETRY_TIMES) {
751         errCode = InnerPrepareStartUser(userId);
752         if ((errCode != Constants::E_IPC_ERROR) && (errCode != Constants::E_IPC_SA_DIED) &&
753             (errCode != ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY)) {
754             return errCode;
755         }
756         ACCOUNT_LOGE("Fail to prepare start user, errCode=%{public}d, userId=%{public}d, times=%{public}d",
757             errCode, userId, times);
758         times++;
759         std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
760     }
761     return errCode;
762 }
763 
InnerPrepareStartUser(int32_t userId)764 ErrCode InnerAccountIAMManager::InnerPrepareStartUser(int32_t userId)
765 {
766     ErrCode result = ERR_OK;
767 #ifdef HAS_STORAGE_PART
768     auto storageMgrProxy = GetStorageManagerProxy();
769     if (storageMgrProxy == nullptr) {
770         ACCOUNT_LOGE("Fail to get storage proxy");
771         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY;
772     }
773     result = storageMgrProxy->PrepareStartUser(userId);
774     ACCOUNT_LOGI("PrepareStartUser end, ret: %{public}d", result);
775 #endif
776     return result;
777 }
778 
779 #ifdef HAS_STORAGE_PART
GetStorageManagerProxy()780 sptr<StorageManager::IStorageManager> InnerAccountIAMManager::GetStorageManagerProxy()
781 {
782     auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
783     if (systemAbilityManager == nullptr) {
784         ACCOUNT_LOGE("failed to get system ability mgr");
785         return nullptr;
786     }
787     auto remote = systemAbilityManager->GetSystemAbility(STORAGE_MANAGER_MANAGER_ID);
788     if (remote == nullptr) {
789         ACCOUNT_LOGE("failed to get STORAGE_MANAGER_MANAGER_ID service");
790         return nullptr;
791     }
792     auto storageMgrProxy = iface_cast<StorageManager::IStorageManager>(remote);
793     return storageMgrProxy;
794 }
795 #endif
796 
CheckNeedReactivateUserKey(int32_t userId,bool & needReactivateKey)797 ErrCode InnerAccountIAMManager::CheckNeedReactivateUserKey(int32_t userId, bool &needReactivateKey)
798 {
799 #ifdef HAS_STORAGE_PART
800     int32_t errCode = 0;
801     int32_t retryTimes = 0;
802     while (retryTimes < MAX_RETRY_TIMES) {
803         sptr<StorageManager::IStorageManager> proxy = GetStorageManagerProxy();
804         if (proxy == nullptr) {
805             ACCOUNT_LOGE("Failed to get STORAGE_MANAGER_MANAGER_ID proxy, retry!");
806             errCode = ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
807             retryTimes++;
808             std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
809             continue;
810         }
811         errCode = proxy->GetUserNeedActiveStatus(userId, needReactivateKey);
812         if ((errCode == Constants::E_IPC_ERROR) || (errCode == Constants::E_IPC_SA_DIED)) {
813             ACCOUNT_LOGE("Failed to PrepareStartUser, id:%{public}d, errCode:%{public}d, retry!", userId, errCode);
814             retryTimes++;
815             std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
816             continue;
817         } else {
818             break;
819         }
820     }
821     if (errCode != ERR_OK) {
822         needReactivateKey = true;
823     }
824     ACCOUNT_LOGI("Get user %{public}d need active status, ret = %{public}d, needReactivateKey = %{public}d.",
825         userId, errCode, needReactivateKey);
826     return errCode;
827 #else
828     needReactivateKey = false;
829     return ERR_OK;
830 #endif // HAS_STORAGE_PART
831 }
832 }  // namespace AccountSA
833 }  // namespace OHOS
834