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