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