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