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