• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
UpdateStorageKeyContext(const int32_t userId)489 ErrCode InnerAccountIAMManager::UpdateStorageKeyContext(const int32_t userId)
490 {
491     int times = 0;
492     ErrCode errCode = ERR_OK;
493     while (times < MAX_RETRY_TIMES) {
494         errCode = InnerUpdateStorageKeyContext(userId);
495         if ((errCode != Constants::E_IPC_ERROR) && (errCode != Constants::E_IPC_SA_DIED)) {
496             return errCode;
497         }
498         ACCOUNT_LOGE("errCode=%{public}d, userId=%{public}d, times=%{public}d", errCode, userId, times);
499         times++;
500         std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
501     }
502     return errCode;
503 }
504 
InnerUpdateStorageKeyContext(const int32_t userId)505 ErrCode InnerAccountIAMManager::InnerUpdateStorageKeyContext(const int32_t userId)
506 {
507     ACCOUNT_LOGI("Enter, userId=%{public}d", userId);
508 #ifdef HAS_STORAGE_PART
509     auto storageMgrProxy = GetStorageManagerProxy();
510     if (storageMgrProxy == nullptr) {
511         ACCOUNT_LOGE("Fail to get storage proxy");
512         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY;
513     }
514     ErrCode code = storageMgrProxy->UpdateKeyContext(userId);
515     if (code != ERR_OK) {
516         ACCOUNT_LOGE("Fail to update key context, userId=%{public}d, code=%{public}d", userId, code);
517         return code;
518     }
519 #endif
520     return ERR_OK;
521 }
522 
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)523 ErrCode InnerAccountIAMManager::UpdateStorageUserAuth(int32_t userId, uint64_t secureUid,
524     const std::vector<uint8_t> &token, const std::vector<uint8_t> &oldSecret, const std::vector<uint8_t> &newSecret)
525 {
526     int times = 0;
527     ErrCode errCode = ERR_OK;
528     while (times < MAX_RETRY_TIMES) {
529         errCode = InnerUpdateStorageUserAuth(userId, secureUid, token, oldSecret, newSecret);
530         if ((errCode != Constants::E_IPC_ERROR) && (errCode != Constants::E_IPC_SA_DIED)) {
531             return errCode;
532         }
533         ACCOUNT_LOGE("errCode=%{public}d, userId=%{public}d, times=%{public}d", errCode, userId, times);
534         times++;
535         std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
536     }
537     return errCode;
538 }
539 
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)540 ErrCode InnerAccountIAMManager::InnerUpdateStorageUserAuth(int32_t userId, uint64_t secureUid,
541     const std::vector<uint8_t> &token, const std::vector<uint8_t> &oldSecret, const std::vector<uint8_t> &newSecret)
542 {
543     ACCOUNT_LOGI("Enter, userId=%{public}d", userId);
544 #ifdef HAS_STORAGE_PART
545     auto storageMgrProxy = GetStorageManagerProxy();
546     if (storageMgrProxy == nullptr) {
547         ACCOUNT_LOGE("Fail to get storage proxy");
548         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY;
549     }
550 
551     ErrCode code = storageMgrProxy->UpdateUserAuth(userId, secureUid, token, oldSecret, newSecret);
552     if ((code != ERR_OK) && (code != ERROR_STORAGE_KEY_NOT_EXIST)) {
553         ACCOUNT_LOGE("Fail to update user auth, userId=%{public}d, code=%{public}d", userId, code);
554         return code;
555     }
556 #endif
557     return ERR_OK;
558 }
559 
GetLockScreenStatus(uint32_t userId,bool & lockScreenStatus)560 ErrCode InnerAccountIAMManager::GetLockScreenStatus(uint32_t userId, bool &lockScreenStatus)
561 {
562     int times = 0;
563     ErrCode errCode = ERR_OK;
564     while (times < MAX_RETRY_TIMES) {
565         errCode = InnerGetLockScreenStatus(userId, lockScreenStatus);
566         if ((errCode != Constants::E_IPC_ERROR) && (errCode != Constants::E_IPC_SA_DIED)) {
567             return errCode;
568         }
569         ACCOUNT_LOGE("errCode=%{public}d, userId=%{public}d, times=%{public}d", errCode, userId, times);
570         times++;
571         std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
572     }
573     return errCode;
574 }
575 
InnerGetLockScreenStatus(uint32_t userId,bool & lockScreenStatus)576 ErrCode InnerAccountIAMManager::InnerGetLockScreenStatus(uint32_t userId, bool &lockScreenStatus)
577 {
578 #ifdef HAS_STORAGE_PART
579     auto storageMgrProxy = GetStorageManagerProxy();
580     if (storageMgrProxy == nullptr) {
581         ACCOUNT_LOGE("fail to get storage proxy");
582         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY;
583     }
584     ErrCode result = storageMgrProxy->GetLockScreenStatus(userId, lockScreenStatus);
585     if (result != ERR_OK) {
586         ACCOUNT_LOGE("failed to get lock screen status");
587         return result;
588     }
589 #endif
590     return ERR_OK;
591 }
592 
UnlockUserScreen(int32_t userId,const std::vector<uint8_t> & token,const std::vector<uint8_t> & secret)593 ErrCode InnerAccountIAMManager::UnlockUserScreen(
594     int32_t userId, const std::vector<uint8_t> &token, const std::vector<uint8_t> &secret)
595 {
596     int times = 0;
597     ErrCode errCode = ERR_OK;
598     while (times < MAX_RETRY_TIMES) {
599         errCode = InnerUnlockUserScreen(userId, token, secret);
600         if ((errCode != Constants::E_IPC_ERROR) && (errCode != Constants::E_IPC_SA_DIED)) {
601             return errCode;
602         }
603         ACCOUNT_LOGE("errCode=%{public}d, userId=%{public}d, times=%{public}d", errCode, userId, times);
604         times++;
605         std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
606     }
607     return errCode;
608 }
609 
InnerUnlockUserScreen(int32_t userId,const std::vector<uint8_t> & token,const std::vector<uint8_t> & secret)610 ErrCode InnerAccountIAMManager::InnerUnlockUserScreen(
611     int32_t userId, const std::vector<uint8_t> &token, const std::vector<uint8_t> &secret)
612 {
613 #ifdef HAS_STORAGE_PART
614     auto storageMgrProxy = GetStorageManagerProxy();
615     if (storageMgrProxy == nullptr) {
616         ACCOUNT_LOGE("fail to get storage proxy");
617         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY;
618     }
619     ErrCode result = storageMgrProxy->UnlockUserScreen(userId, token, secret);
620     if (result != ERR_OK) {
621         ACCOUNT_LOGE("fail to unlock screen");
622         return result;
623     }
624 #endif
625     return ERR_OK;
626 }
627 
ActivateUserKey(int32_t userId,const std::vector<uint8_t> & token,const std::vector<uint8_t> & secret)628 ErrCode InnerAccountIAMManager::ActivateUserKey(
629     int32_t userId, const std::vector<uint8_t> &token, const std::vector<uint8_t> &secret)
630 {
631     int times = 0;
632     ErrCode errCode = ERR_OK;
633     while (times < MAX_RETRY_TIMES) {
634         errCode = InnerActivateUserKey(userId, token, secret);
635         if ((errCode != Constants::E_IPC_ERROR) && (errCode != Constants::E_IPC_SA_DIED)) {
636             return errCode;
637         }
638         ACCOUNT_LOGE("errCode=%{public}d, userId=%{public}d, times=%{public}d", errCode, userId, times);
639         times++;
640         std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
641     }
642     return errCode;
643 }
644 
InnerActivateUserKey(int32_t userId,const std::vector<uint8_t> & token,const std::vector<uint8_t> & secret)645 ErrCode InnerAccountIAMManager::InnerActivateUserKey(
646     int32_t userId, const std::vector<uint8_t> &token, const std::vector<uint8_t> &secret)
647 {
648 #ifdef HAS_STORAGE_PART
649     auto storageMgrProxy = GetStorageManagerProxy();
650     if (storageMgrProxy == nullptr) {
651         ACCOUNT_LOGE("fail to get storage proxy");
652         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY;
653     }
654     ErrCode result = storageMgrProxy->ActiveUserKey(userId, token, secret);
655     ACCOUNT_LOGI("ActiveUserKey end, ret: %{public}d", result);
656     if (result != ERR_OK && result != ERROR_STORAGE_KEY_NOT_EXIST) {
657         return result;
658     }
659     result = storageMgrProxy->PrepareStartUser(userId);
660     ACCOUNT_LOGI("PrepareStartUser end, ret: %{public}d", result);
661 #endif
662     return ERR_OK;
663 }
664 
665 #ifdef HAS_STORAGE_PART
GetStorageManagerProxy()666 sptr<StorageManager::IStorageManager> InnerAccountIAMManager::GetStorageManagerProxy()
667 {
668     auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
669     if (systemAbilityManager == nullptr) {
670         ACCOUNT_LOGE("failed to get system ability mgr");
671         return nullptr;
672     }
673     auto remote = systemAbilityManager->GetSystemAbility(STORAGE_MANAGER_MANAGER_ID);
674     if (remote == nullptr) {
675         ACCOUNT_LOGE("failed to get STORAGE_MANAGER_MANAGER_ID service");
676         return nullptr;
677     }
678     auto storageMgrProxy = iface_cast<StorageManager::IStorageManager>(remote);
679     return storageMgrProxy;
680 }
681 #endif
682 
CheckNeedReactivateUserKey(int32_t userId,bool & needReactivateKey)683 ErrCode InnerAccountIAMManager::CheckNeedReactivateUserKey(int32_t userId, bool &needReactivateKey)
684 {
685 #ifdef HAS_STORAGE_PART
686     int32_t errCode = 0;
687     int32_t retryTimes = 0;
688     while (retryTimes < MAX_RETRY_TIMES) {
689         sptr<StorageManager::IStorageManager> proxy = GetStorageManagerProxy();
690         if (proxy == nullptr) {
691             ACCOUNT_LOGE("Failed to get STORAGE_MANAGER_MANAGER_ID proxy, retry!");
692             errCode = ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
693             retryTimes++;
694             std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
695             continue;
696         }
697         errCode = proxy->GetUserNeedActiveStatus(userId, needReactivateKey);
698         if ((errCode == Constants::E_IPC_ERROR) || (errCode == Constants::E_IPC_SA_DIED)) {
699             ACCOUNT_LOGE("Failed to PrepareStartUser, id:%{public}d, errCode:%{public}d, retry!", userId, errCode);
700             retryTimes++;
701             std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
702             continue;
703         } else {
704             break;
705         }
706     }
707     if (errCode != ERR_OK) {
708         needReactivateKey = true;
709     }
710     ACCOUNT_LOGI("Get user %{public}d need active status, ret = %{public}d, needReactivateKey = %{public}d.",
711         userId, errCode, needReactivateKey);
712     return errCode;
713 #else
714     needReactivateKey = false;
715     return ERR_OK;
716 #endif // HAS_STORAGE_PART
717 }
718 }  // namespace AccountSA
719 }  // namespace OHOS
720