• 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 "account_iam_callback.h"
17 
18 #include <mutex>
19 #include <securec.h>
20 #include <string>
21 #include "access_token.h"
22 #include "accesstoken_kit.h"
23 #include "account_iam_info.h"
24 #include "account_info_report.h"
25 #include "account_log_wrapper.h"
26 #include "account_hisysevent_adapter.h"
27 #include "iinner_os_account_manager.h"
28 #include "inner_account_iam_manager.h"
29 #ifdef SUPPORT_DOMAIN_ACCOUNTS
30 #include "inner_domain_account_manager.h"
31 #endif // SUPPORT_DOMAIN_ACCOUNTS
32 #include "ipc_skeleton.h"
33 #include "os_account_delete_user_idm_callback.h"
34 #include "storage_service_errno.h"
35 #include "token_setproc.h"
36 #include "user_auth_client.h"
37 #include "user_idm_client.h"
38 #include "os_account_constants.h"
39 
40 namespace OHOS {
41 namespace AccountSA {
42 namespace {
43 const char OPERATION_REENROLL[] = "re-enroll";
44 }
45 
46 using UserIDMClient = UserIam::UserAuth::UserIdmClient;
47 using UserAuthClient = UserIam::UserAuth::UserAuthClient;
48 
49 const std::vector<uint8_t> TEMP_PIN = {50, 48, 50, 52, 48, 56};
50 
SetContextId(uint16_t contextId)51 void AuthCallbackDeathRecipient::SetContextId(uint16_t contextId)
52 {
53     contextId_ = contextId;
54 }
55 
OnRemoteDied(const wptr<IRemoteObject> & remote)56 void AuthCallbackDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
57 {
58     ACCOUNT_LOGI("remote callback died, cancel authentication");
59     if (contextId_ > 0) {
60         UserAuthClient::GetInstance().CancelAuthentication(contextId_);
61     }
62 }
63 
AuthCallback(uint32_t userId,AuthType authType,AuthIntent authIntent,const sptr<IIDMCallback> & callback)64 AuthCallback::AuthCallback(
65     uint32_t userId, AuthType authType, AuthIntent authIntent, const sptr<IIDMCallback> &callback)
66     : userId_(userId), authType_(authType), authIntent_(authIntent), innerCallback_(callback)
67 {
68     // save caller tokenId for pin re-enroll
69     if (authType == AuthType::PIN) {
70         callerTokenId_ = IPCSkeleton::GetCallingTokenID();
71     }
72 }
73 
AuthCallback(uint32_t userId,AuthType authType,AuthIntent authIntent,bool isRemoteAuth,const sptr<IIDMCallback> & callback)74 AuthCallback::AuthCallback(uint32_t userId, AuthType authType, AuthIntent authIntent,
75     bool isRemoteAuth, const sptr<IIDMCallback> &callback)
76     : userId_(userId), authType_(authType), authIntent_(authIntent),
77     isRemoteAuth_(isRemoteAuth), innerCallback_(callback)
78 {
79     // save caller tokenId for pin re-enroll
80     if (authType == AuthType::PIN) {
81         callerTokenId_ = IPCSkeleton::GetCallingTokenID();
82     }
83 }
84 
UpdateCredInfo(const Attributes & extraInfo)85 UpdateCredInfo::UpdateCredInfo(const Attributes &extraInfo)
86 {
87     extraInfo.GetUint64Value(Attributes::AttributeKey::ATTR_CREDENTIAL_ID, credentialId);
88     extraInfo.GetUint64Value(Attributes::AttributeKey::ATTR_SEC_USER_ID, secureUid);
89     extraInfo.GetUint8ArrayValue(Attributes::ATTR_AUTH_TOKEN, token);
90     extraInfo.GetUint8ArrayValue(Attributes::ATTR_ROOT_SECRET, newSecret);
91     extraInfo.GetUint8ArrayValue(Attributes::ATTR_OLD_ROOT_SECRET, oldSecret);
92 }
93 
ReEnrollCallback(const sptr<IIDMCallback> & innerCallback)94 ReEnrollCallback::ReEnrollCallback(const sptr<IIDMCallback> &innerCallback) : innerCallback_(innerCallback)
95 {}
96 
OnResult(int32_t result,const Attributes & extraInfo)97 void ReEnrollCallback::OnResult(int32_t result, const Attributes &extraInfo)
98 {
99     std::unique_lock<std::mutex> lock(mutex_);
100     ACCOUNT_LOGE("ReEnroll: UpdateCredential call to ReEnroll OnResult, result is %{public}d", result);
101     result_ = result;
102     isCalled_ = true;
103     onResultCondition_.notify_one();
104     return;
105 }
106 
OnAcquireInfo(int32_t module,uint32_t acquireInfo,const AccountSA::Attributes & extraInfo)107 void ReEnrollCallback::OnAcquireInfo(int32_t module, uint32_t acquireInfo, const AccountSA::Attributes &extraInfo)
108 {
109     std::unique_lock<std::mutex> lock(mutex_);
110     ACCOUNT_LOGI("ReEnroll: UpdateCredential call to ReEnroll OnAcquireInfo");
111     innerCallback_->OnAcquireInfo(module, acquireInfo, extraInfo);
112     return;
113 }
114 
InnerHandleReEnroll(const std::vector<uint8_t> & token)115 ErrCode AuthCallback::InnerHandleReEnroll(const std::vector<uint8_t> &token)
116 {
117     //set first caller to sceneboard
118     SetFirstCallerTokenID(callerTokenId_);
119     sptr<ReEnrollCallback> callback = new (std::nothrow) ReEnrollCallback(innerCallback_);
120     if (callback == nullptr) {
121         ACCOUNT_LOGE("ReEnroll: failed to allocate callback");
122         return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
123     }
124     CredentialParameters credInfo = {
125         .authType = AuthType::PIN,
126         // `pinType` is unused in iam
127         .pinType = PinSubType::PIN_SIX,
128         .token = token
129     };
130     InnerAccountIAMManager::GetInstance().UpdateCredential(userId_, credInfo, callback);
131     std::unique_lock<std::mutex> lock(callback->mutex_);
132     bool done = callback->onResultCondition_.wait_for(lock, std::chrono::seconds(Constants::REENROLL_WAIT_TIME),
133         [cb = callback]() { return cb->isCalled_; });
134     ErrCode result = callback->result_;
135     if (!done) {
136         ACCOUNT_LOGE("ReEnroll: UpdateCredential failed, timeout");
137         return ERR_ACCOUNT_COMMON_OPERATION_TIMEOUT;
138     }
139     return result;
140 }
141 
HandleReEnroll(const Attributes & extraInfo,int32_t accountId,const std::vector<uint8_t> & token)142 void AuthCallback::HandleReEnroll(const Attributes &extraInfo, int32_t accountId, const std::vector<uint8_t> &token)
143 {
144     bool needReEnroll = false;
145     extraInfo.GetBoolValue(Attributes::ATTR_RE_ENROLL_FLAG, needReEnroll);
146     if (!needReEnroll) {
147         return;
148     }
149     if (authType_ == AuthType::PIN) {
150         ACCOUNT_LOGI("ReEnroll: need re-enroll for accountId %{public}d", accountId);
151         ErrCode result = InnerHandleReEnroll(token);
152         if (result != ERR_OK) {
153             ACCOUNT_LOGE("ReEnroll: UpdateCredential failed, result is %{public}d", result);
154             ReportOsAccountOperationFail(accountId, "ReEnroll", result, "UpdateCredential failed");
155         } else {
156             ACCOUNT_LOGI("ReEnroll: UpdateCredential successful");
157             ReportOsAccountLifeCycle(accountId, OPERATION_REENROLL);
158         }
159     } else {
160         ACCOUNT_LOGW("ReEnroll: re-enroll flag exist but authType:%{public}d is not pin", authType_);
161     }
162     // ATTR_RE_ENROLL_FLAG is true means iam opened a session, remeber to close it
163     InnerAccountIAMManager::GetInstance().CloseSession(userId_);
164 }
165 
UnlockAccount(int32_t accountId,const std::vector<uint8_t> & token,const std::vector<uint8_t> & secret,bool & isUpdateVerifiedStatus)166 ErrCode AuthCallback::UnlockAccount(int32_t accountId, const std::vector<uint8_t> &token,
167     const std::vector<uint8_t> &secret, bool &isUpdateVerifiedStatus)
168 {
169     ErrCode ret = ERR_OK;
170     if (authType_ == AuthType::PIN) {
171         if (secret.empty()) {
172             ACCOUNT_LOGI("No need to active user.");
173             return ERR_OK;
174         }
175         (void)InnerAccountIAMManager::GetInstance().HandleFileKeyException(accountId, secret, token);
176         bool isVerified = false;
177         (void)IInnerOsAccountManager::GetInstance().IsOsAccountVerified(accountId, isVerified);
178         bool needActivateKey = true;
179         if (isVerified) {
180             ret = InnerAccountIAMManager::GetInstance().CheckNeedReactivateUserKey(accountId, needActivateKey);
181             if (ret != ERR_OK) {
182                 ReportOsAccountOperationFail(accountId, "auth", ret, "Failed to check need reactivate user key");
183                 ACCOUNT_LOGE("Failed to check need reactivate key, ret = %{public}d.", ret);
184             }
185         }
186 
187         if (needActivateKey) {
188             // el2 file decryption
189             ret = InnerAccountIAMManager::GetInstance().ActivateUserKey(accountId, token, secret);
190             if (ret != 0 && ret != ErrNo::E_PARAMS_NULLPTR_ERR) {
191                 ACCOUNT_LOGE("Failed to activate user key");
192                 ReportOsAccountOperationFail(accountId, "auth", ret, "Failed to activate user key");
193                 return ret;
194             }
195             ret = InnerAccountIAMManager::GetInstance().PrepareStartUser(accountId);
196             if (ret != 0) {
197                 ACCOUNT_LOGE("Failed to prepare start user");
198                 ReportOsAccountOperationFail(accountId, "auth", ret, "Failed to prepare start user");
199             }
200             isUpdateVerifiedStatus = true;
201         }
202     }
203     ret = UnlockUserScreen(accountId, token, secret, isUpdateVerifiedStatus);
204     return ret;
205 }
206 
UnlockUserScreen(int32_t accountId,const std::vector<uint8_t> & token,const std::vector<uint8_t> & secret,bool & isUpdateVerifiedStatus)207 ErrCode AuthCallback::UnlockUserScreen(int32_t accountId, const std::vector<uint8_t> &token,
208     const std::vector<uint8_t> &secret, bool &isUpdateVerifiedStatus)
209 {
210     ErrCode ret = ERR_OK;
211     if (!isUpdateVerifiedStatus) {
212         if (authType_ == AuthType::RECOVERY_KEY) {
213             ACCOUNT_LOGI("No need to unlock screen.");
214             return ERR_OK;
215         }
216         bool lockScreenStatus = false;
217         ret = InnerAccountIAMManager::GetInstance().GetLockScreenStatus(accountId, lockScreenStatus);
218         if (ret != 0) {
219             ReportOsAccountOperationFail(accountId, "auth", ret, "Failed to get lock status");
220         }
221         if (!lockScreenStatus) {
222             ACCOUNT_LOGI("start unlock user screen");
223             // el3\4 file decryption
224             ret = InnerAccountIAMManager::GetInstance().UnlockUserScreen(accountId, token, secret);
225             if (ret != 0) {
226                 ReportOsAccountOperationFail(accountId, "auth", ret, "Failed to unlock user");
227                 return ret;
228             }
229         }
230     }
231     return ret;
232 }
233 
HandleAuthResult(const Attributes & extraInfo,int32_t accountId,bool & isUpdateVerifiedStatus)234 ErrCode AuthCallback::HandleAuthResult(const Attributes &extraInfo, int32_t accountId, bool &isUpdateVerifiedStatus)
235 {
236     // domain account authentication
237     if (authType_ == static_cast<AuthType>(IAMAuthType::DOMAIN)) {
238         return ERR_OK;
239     }
240     std::vector<uint8_t> token;
241     extraInfo.GetUint8ArrayValue(Attributes::ATTR_SIGNATURE, token);
242     std::vector<uint8_t> secret;
243     if (!extraInfo.GetUint8ArrayValue(Attributes::ATTR_ROOT_SECRET, secret)) {
244         ACCOUNT_LOGW("No secret to support user unlock");
245         secret.clear();
246     }
247     ErrCode ret = UnlockAccount(accountId, token, secret, isUpdateVerifiedStatus);
248     if (ret != ERR_OK) {
249         return ret;
250     }
251 #ifdef SUPPORT_DOMAIN_ACCOUNTS
252     // send msg for domain account offline authentication
253     InnerDomainAccountManager::GetInstance().AuthWithToken(accountId, token);
254 #endif // SUPPORT_DOMAIN_ACCOUNTS
255     HandleReEnroll(extraInfo, accountId, token);
256     return ret;
257 }
258 
SetDeathRecipient(const sptr<AuthCallbackDeathRecipient> & deathRecipient)259 void AuthCallback::SetDeathRecipient(const sptr<AuthCallbackDeathRecipient> &deathRecipient)
260 {
261     deathRecipient_ = deathRecipient;
262 }
263 
OnResult(int32_t result,const Attributes & extraInfo)264 void AuthCallback::OnResult(int32_t result, const Attributes &extraInfo)
265 {
266     int32_t authedAccountId = 0;
267     if (!extraInfo.GetInt32Value(Attributes::AttributeKey::ATTR_USER_ID, authedAccountId)) {
268         ACCOUNT_LOGE("Get account id from auth result failed");
269         authedAccountId = static_cast<int32_t>(userId_);
270     }
271     ACCOUNT_LOGI("Auth ret: authType=%{public}d, result=%{public}d, id=%{public}d", authType_, result, authedAccountId);
272     if (innerCallback_ == nullptr) {
273         ACCOUNT_LOGE("innerCallback_ is nullptr");
274         return;
275     }
276     sptr<IRemoteObject> remoteObject = innerCallback_->AsObject();
277     if ((deathRecipient_ != nullptr) && (remoteObject != nullptr)) {
278         remoteObject->RemoveDeathRecipient(deathRecipient_);
279     }
280     if (result != 0) {
281         innerCallback_->OnResult(result, extraInfo);
282         ReportOsAccountOperationFail(authedAccountId, "auth", result,
283             "Failed to auth, type:" + std::to_string(authType_));
284         return AccountInfoReport::ReportSecurityInfo("", authedAccountId, ReportEvent::EVENT_LOGIN, result);
285     }
286     // private pin auth
287     if ((authType_ == AuthType::PRIVATE_PIN) || (authIntent_ == AuthIntent::QUESTION_AUTH)) {
288         ACCOUNT_LOGI("Private pin auth");
289         return innerCallback_->OnResult(result, extraInfo);
290     }
291     if (isRemoteAuth_) {
292         ACCOUNT_LOGI("Remote auth");
293         return innerCallback_->OnResult(result, extraInfo);
294     }
295     bool isUpdateVerifiedStatus = false;
296     if (HandleAuthResult(extraInfo, authedAccountId, isUpdateVerifiedStatus) != ERR_OK) {
297         int32_t remainTimes = 0;
298         int32_t freezingTime = 0;
299         extraInfo.GetInt32Value(Attributes::AttributeKey::ATTR_REMAIN_TIMES, remainTimes);
300         extraInfo.GetInt32Value(Attributes::AttributeKey::ATTR_FREEZING_TIME, freezingTime);
301         Attributes errInfo;
302         errInfo.SetInt32Value(Attributes::AttributeKey::ATTR_REMAIN_TIMES, remainTimes);
303         errInfo.SetInt32Value(Attributes::AttributeKey::ATTR_FREEZING_TIME, freezingTime);
304         innerCallback_->OnResult(ResultCode::FAIL, errInfo);
305         return AccountInfoReport::ReportSecurityInfo("", authedAccountId, ReportEvent::EVENT_LOGIN, ResultCode::FAIL);
306     }
307     innerCallback_->OnResult(result, extraInfo);
308     if (isUpdateVerifiedStatus) {
309         (void)IInnerOsAccountManager::GetInstance().SetOsAccountIsVerified(authedAccountId, true);
310     }
311     (void)IInnerOsAccountManager::GetInstance().SetOsAccountIsLoggedIn(authedAccountId, true);
312     AccountInfoReport::ReportSecurityInfo("", authedAccountId, ReportEvent::EVENT_LOGIN, result);
313 }
314 
OnAcquireInfo(int32_t module,uint32_t acquireInfo,const Attributes & extraInfo)315 void AuthCallback::OnAcquireInfo(int32_t module, uint32_t acquireInfo, const Attributes &extraInfo)
316 {
317     if (innerCallback_ == nullptr) {
318         ACCOUNT_LOGE("innerCallback_ is nullptr");
319         return;
320     }
321     innerCallback_->OnAcquireInfo(module, acquireInfo, extraInfo);
322 }
323 
OnRemoteDied(const wptr<IRemoteObject> & remote)324 void IDMCallbackDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
325 {
326     ACCOUNT_LOGW("Remote callback died, cancel cred");
327     if (userId_ > 0) {
328         UserIDMClient::GetInstance().Cancel(userId_);
329     }
330 }
331 
IDMCallbackDeathRecipient(uint32_t userId)332 IDMCallbackDeathRecipient::IDMCallbackDeathRecipient(uint32_t userId) : userId_(userId)
333 {}
334 
AddCredCallback(uint32_t userId,const CredentialParameters & credInfo,const sptr<IIDMCallback> & callback)335 AddCredCallback::AddCredCallback(uint32_t userId, const CredentialParameters &credInfo,
336     const sptr<IIDMCallback> &callback)
337     : userId_(userId), credInfo_(credInfo), innerCallback_(callback)
338 {}
339 
SetDeathRecipient(const sptr<IDMCallbackDeathRecipient> & deathRecipient)340 void AddCredCallback::SetDeathRecipient(const sptr<IDMCallbackDeathRecipient> &deathRecipient)
341 {
342     deathRecipient_ = deathRecipient;
343 }
344 
AddUserKey(int32_t userId,uint64_t secureUid,const std::vector<uint8_t> & token,const std::vector<uint8_t> & oldSecret,const std::vector<uint8_t> & newSecret)345 static ErrCode AddUserKey(int32_t userId, uint64_t secureUid, const std::vector<uint8_t> &token,
346     const std::vector<uint8_t> &oldSecret, const std::vector<uint8_t> &newSecret)
347 {
348     ErrCode errCode = InnerAccountIAMManager::GetInstance().UpdateStorageUserAuth(
349         userId, secureUid, token, oldSecret, newSecret);
350     if (errCode != ERR_OK) {
351         ReportOsAccountOperationFail(userId, "addCredential", errCode, "Failed to update user auth");
352         return errCode;
353     }
354     errCode = InnerAccountIAMManager::GetInstance().UpdateStorageKeyContext(userId);
355     if (errCode != ERR_OK) {
356         ReportOsAccountOperationFail(userId, "addCredential", errCode, "Failed to update key context");
357     }
358     return errCode;
359 }
360 
GetSecretFlagFilePath(const uint32_t userId)361 static inline std::string GetSecretFlagFilePath(const uint32_t userId)
362 {
363     return Constants::USER_INFO_BASE + Constants::PATH_SEPARATOR + std::to_string(userId) +
364         Constants::PATH_SEPARATOR + Constants::USER_ADD_SECRET_FLAG_FILE_NAME;
365 }
366 
OnResult(int32_t result,const Attributes & extraInfo)367 void AddCredCallback::OnResult(int32_t result, const Attributes &extraInfo)
368 {
369     std::unique_lock<std::mutex> lock(mutex_);
370     ACCOUNT_LOGI("Add cred result, userId:%{public}d, authType:%{public}d, result:%{public}d.",
371         userId_, credInfo_.authType, result);
372     if (innerCallback_ == nullptr || innerCallback_->AsObject() == nullptr) {
373         ACCOUNT_LOGE("innerCallback_ is nullptr");
374         isCalled_ = true;
375         return onResultCondition_.notify_one();
376     }
377     innerCallback_->AsObject()->RemoveDeathRecipient(deathRecipient_);
378     auto &innerIamMgr = InnerAccountIAMManager::GetInstance();
379     if ((result == 0) && (credInfo_.authType == AuthType::PIN)) {
380         innerIamMgr.SetState(userId_, AFTER_ADD_CRED);
381         uint64_t credentialId = 0;
382         extraInfo.GetUint64Value(Attributes::AttributeKey::ATTR_CREDENTIAL_ID, credentialId);
383         (void)IInnerOsAccountManager::GetInstance().SetOsAccountCredentialId(userId_, credentialId);
384         uint64_t secureUid = 0;
385         extraInfo.GetUint64Value(Attributes::AttributeKey::ATTR_SEC_USER_ID, secureUid);
386         std::vector<uint8_t> newSecret;
387         extraInfo.GetUint8ArrayValue(Attributes::ATTR_ROOT_SECRET, newSecret);
388         std::vector<uint8_t> token;
389         extraInfo.GetUint8ArrayValue(Attributes::ATTR_AUTH_TOKEN, token);
390         std::vector<uint8_t> oldSecret;
391         ErrCode code = AddUserKey(userId_, secureUid, token, oldSecret, newSecret);
392         if (code == ERR_OK) {
393             std::string path = GetSecretFlagFilePath(userId_);
394             auto accountFileOperator = std::make_shared<AccountFileOperator>();
395             code = accountFileOperator->DeleteDirOrFile(path);
396             if (code != ERR_OK) {
397                 ReportOsAccountOperationFail(userId_, "addCredential", code, "Failed to delete add_secret_flag file");
398             }
399         }
400     }
401     if (result != 0) {
402         ReportOsAccountOperationFail(userId_, "addCredential", result,
403             "Failed to add credential, type: " + std::to_string(credInfo_.authType));
404         if (credInfo_.authType == AuthType::PIN) {
405             std::string path = GetSecretFlagFilePath(userId_);
406             auto accountFileOperator = std::make_shared<AccountFileOperator>();
407             accountFileOperator->DeleteDirOrFile(path);
408         }
409     } else {
410         ReportOsAccountLifeCycle(userId_,
411             std::string(Constants::OPERATION_ADD_CRED) + "_" + std::to_string(credInfo_.authType));
412     }
413     innerIamMgr.SetState(userId_, AFTER_OPEN_SESSION);
414     innerCallback_->OnResult(result, extraInfo);
415     isCalled_ = true;
416     onResultCondition_.notify_one();
417 }
418 
OnAcquireInfo(int32_t module,uint32_t acquireInfo,const Attributes & extraInfo)419 void AddCredCallback::OnAcquireInfo(int32_t module, uint32_t acquireInfo, const Attributes &extraInfo)
420 {
421     if (innerCallback_ == nullptr) {
422         ACCOUNT_LOGE("innerCallback_ is nullptr");
423         return;
424     }
425     innerCallback_->OnAcquireInfo(module, acquireInfo, extraInfo);
426 }
427 
UpdateCredCallback(uint32_t userId,const CredentialParameters & credInfo,const sptr<IIDMCallback> & callback)428 UpdateCredCallback::UpdateCredCallback(
429     uint32_t userId, const CredentialParameters &credInfo, const sptr<IIDMCallback> &callback)
430     : userId_(userId), credInfo_(credInfo), innerCallback_(callback)
431 {}
432 
SetDeathRecipient(const sptr<IDMCallbackDeathRecipient> & deathRecipient)433 void UpdateCredCallback::SetDeathRecipient(const sptr<IDMCallbackDeathRecipient> &deathRecipient)
434 {
435     deathRecipient_ = deathRecipient;
436 }
437 
DeleteCredential(uint32_t userId,uint64_t credentialId,const std::vector<uint8_t> & token)438 static void DeleteCredential(uint32_t userId, uint64_t credentialId, const std::vector<uint8_t> &token)
439 {
440     auto idmCallback = std::make_shared<DelCredCallback>(userId, true, token, nullptr);
441     UserIDMClient::GetInstance().DeleteCredential(userId, credentialId, token, idmCallback);
442 }
443 
InnerOnResult(int32_t result,const Attributes & extraInfo)444 void UpdateCredCallback::InnerOnResult(int32_t result, const Attributes &extraInfo)
445 {
446     ACCOUNT_LOGI("UpdateCredCallback, userId=%{public}d, result=%{public}d.", userId_, result);
447     if (innerCallback_ == nullptr || innerCallback_->AsObject() == nullptr) {
448         ACCOUNT_LOGE("inner callback is nullptr");
449         return;
450     }
451     innerCallback_->AsObject()->RemoveDeathRecipient(deathRecipient_);
452     auto &innerIamMgr = InnerAccountIAMManager::GetInstance();
453     if (result != 0) {
454         ReportOsAccountOperationFail(userId_, "updateCredential", result,
455             "Failed to update credential, type: " + std::to_string(credInfo_.authType));
456     } else {
457         ReportOsAccountLifeCycle(userId_,
458             std::string(Constants::OPERATION_UPDATE_CRED) + "_" + std::to_string(credInfo_.authType));
459     }
460     if ((result != 0) || (credInfo_.authType != AuthType::PIN)) {
461         ACCOUNT_LOGE("UpdateCredCallback fail code=%{public}d, authType=%{public}d", result, credInfo_.authType);
462         return innerCallback_->OnResult(result, extraInfo);
463     }
464     innerIamMgr.SetState(userId_, AFTER_OPEN_SESSION);
465     UpdateCredInfo updateCredInfo(extraInfo);
466     if (updateCredInfo.oldSecret.empty()) {
467         ErrCode code = innerIamMgr.UpdateUserAuthWithRecoveryKey(credInfo_.token,
468             updateCredInfo.newSecret, updateCredInfo.secureUid, userId_);
469         if (code != ERR_OK) {
470             DeleteCredential(userId_, updateCredInfo.credentialId, credInfo_.token);
471             ReportOsAccountOperationFail(userId_, "updateCredential", code,
472                 "Failed to update user auth with recovery key");
473             return innerCallback_->OnResult(code, extraInfo);
474         }
475     } else {
476         ErrCode code = innerIamMgr.UpdateStorageUserAuth(userId_, updateCredInfo.secureUid,
477             updateCredInfo.token, updateCredInfo.oldSecret, {});
478         if (code != ERR_OK) {
479             DeleteCredential(userId_, updateCredInfo.credentialId, credInfo_.token);
480             ReportOsAccountOperationFail(userId_, "updateCredential", code, "Failed to update user auth");
481             return innerCallback_->OnResult(code, extraInfo);
482         }
483     }
484     uint64_t oldCredentialId = 0;
485     extraInfo.GetUint64Value(Attributes::AttributeKey::ATTR_OLD_CREDENTIAL_ID, oldCredentialId);
486     auto idmCallback = std::make_shared<CommitCredUpdateCallback>(userId_, updateCredInfo, innerCallback_);
487     Security::AccessToken::AccessTokenID selfToken = IPCSkeleton::GetSelfTokenID();
488     result = SetFirstCallerTokenID(selfToken);
489     ACCOUNT_LOGI("Set first caller info result: %{public}d", result);
490     UserIDMClient::GetInstance().DeleteCredential(userId_, oldCredentialId, credInfo_.token, idmCallback);
491     std::unique_lock<std::mutex> delLock(idmCallback->mutex_);
492     idmCallback->onResultCondition_.wait(delLock, [idmCallback] { return idmCallback->isCalled_; });
493 }
494 
OnResult(int32_t result,const Attributes & extraInfo)495 void UpdateCredCallback::OnResult(int32_t result, const Attributes &extraInfo)
496 {
497     std::unique_lock<std::mutex> updateLock(mutex_);
498     InnerOnResult(result, extraInfo);
499     isCalled_ = true;
500     onResultCondition_.notify_one();
501 }
502 
OnAcquireInfo(int32_t module,uint32_t acquireInfo,const Attributes & extraInfo)503 void UpdateCredCallback::OnAcquireInfo(int32_t module, uint32_t acquireInfo, const Attributes &extraInfo)
504 {
505     if (innerCallback_ == nullptr) {
506         ACCOUNT_LOGE("innerCallback_ is nullptr");
507         return;
508     }
509     innerCallback_->OnAcquireInfo(module, acquireInfo, extraInfo);
510 }
511 
VerifyTokenCallbackWrapper(uint32_t userId,const std::vector<uint8_t> & token,Security::AccessToken::AccessTokenID callerTokenId,const sptr<IIDMCallback> & callback)512 VerifyTokenCallbackWrapper::VerifyTokenCallbackWrapper(uint32_t userId, const std::vector<uint8_t> &token,
513     Security::AccessToken::AccessTokenID callerTokenId, const sptr<IIDMCallback> &callback)
514     : userId_(userId), token_(token), callerTokenId_(callerTokenId), innerCallback_(callback)
515 {}
516 
OnResult(int32_t result,const Attributes & extraInfo)517 void VerifyTokenCallbackWrapper::OnResult(int32_t result, const Attributes &extraInfo)
518 {
519     std::unique_lock<std::mutex> verifyLock(mutex_);
520     InnerOnResult(result, extraInfo);
521     isCalled_ = true;
522     onResultCondition_.notify_one();
523 }
524 
InnerOnResult(int32_t result,const Attributes & extraInfo)525 void VerifyTokenCallbackWrapper::InnerOnResult(int32_t result, const Attributes &extraInfo)
526 {
527     ACCOUNT_LOGI("Verify token result = %{public}d, userId = %{public}d", result, userId_);
528     if (result != ERR_OK) {
529         ReportOsAccountOperationFail(userId_, "deleteCredential", result, "Failed to verify token");
530         return innerCallback_->OnResult(result, extraInfo);
531     }
532     uint64_t secureUid = 0;
533     extraInfo.GetUint64Value(Attributes::AttributeKey::ATTR_SEC_USER_ID, secureUid);
534     std::vector<uint8_t> rootSecret;
535     extraInfo.GetUint8ArrayValue(Attributes::ATTR_ROOT_SECRET, rootSecret);
536     auto &innerIamMgr = InnerAccountIAMManager::GetInstance();
537     ErrCode errCode = innerIamMgr.UpdateStorageUserAuth(userId_, secureUid, token_, rootSecret, {});
538     if (errCode != ERR_OK) {
539         ReportOsAccountOperationFail(userId_, "deleteCredential", errCode, "Failed to update user auth");
540         Attributes emptyExtraInfo;
541         return innerCallback_->OnResult(ResultCode::FAIL, emptyExtraInfo);
542     }
543     result = SetFirstCallerTokenID(callerTokenId_);
544     ACCOUNT_LOGI("Set first caller info result: %{public}d", result);
545     auto deleteUserCallback = std::make_shared<CommitDelCredCallback>(userId_, innerCallback_);
546     UserIDMClient::GetInstance().DeleteUser(userId_, token_, deleteUserCallback);
547     std::unique_lock<std::mutex> lock(deleteUserCallback->mutex_);
548     deleteUserCallback->onResultCondition_.wait(lock, [deleteUserCallback] { return deleteUserCallback->isCalled_; });
549 }
550 
CommitDelCredCallback(uint32_t userId,const sptr<IIDMCallback> callback)551 CommitDelCredCallback::CommitDelCredCallback(uint32_t userId, const sptr<IIDMCallback> callback)
552     : userId_(userId), innerCallback_(callback)
553 {}
554 
OnResult(int32_t result,const UserIam::UserAuth::Attributes & extraInfo)555 void CommitDelCredCallback::OnResult(int32_t result, const UserIam::UserAuth::Attributes &extraInfo)
556 {
557     std::unique_lock<std::mutex> lock(mutex_);
558     ACCOUNT_LOGI("Commit delete user result = %{public}d, userId = %{public}d", result, userId_);
559     isCalled_ = true;
560     if (result != ERR_OK) {
561         ReportOsAccountOperationFail(userId_, "deleteCredential", result, "Failed to delete user's credential");
562     } else {
563         ReportOsAccountLifeCycle(userId_, std::string(Constants::OPERATION_DELETE_CRED) + "_0" + "_commit");
564         ErrCode errCode = InnerAccountIAMManager::GetInstance().UpdateStorageKeyContext(userId_);
565         if (errCode != ERR_OK) {
566             ReportOsAccountOperationFail(userId_, "deleteCredential", errCode, "Failed to update key context");
567         }
568         (void)IInnerOsAccountManager::GetInstance().SetOsAccountCredentialId(userId_, 0);
569     }
570     innerCallback_->OnResult(result, extraInfo);
571     onResultCondition_.notify_one();
572 }
573 
OnAcquireInfo(int32_t module,uint32_t acquireInfo,const UserIam::UserAuth::Attributes & extraInfo)574 void CommitDelCredCallback::OnAcquireInfo(int32_t module, uint32_t acquireInfo,
575     const UserIam::UserAuth::Attributes &extraInfo)
576 {
577     ACCOUNT_LOGI("IAM OnAcquireInfo callback! module %{public}d, acquire %{public}u.", module, acquireInfo);
578 }
579 
CommitCredUpdateCallback(int32_t userId,const UpdateCredInfo & extraUpdateInfo,const sptr<IIDMCallback> & callback)580 CommitCredUpdateCallback::CommitCredUpdateCallback(int32_t userId,
581     const UpdateCredInfo &extraUpdateInfo, const sptr<IIDMCallback> &callback)
582     : userId_(userId), extraUpdateInfo_(extraUpdateInfo), innerCallback_(callback)
583 {}
584 
InnerOnResult(int32_t result,const Attributes & extraInfo)585 void CommitCredUpdateCallback::InnerOnResult(int32_t result, const Attributes &extraInfo)
586 {
587     ACCOUNT_LOGI("CommitCredUpdateCallback, result=%{public}d.", result);
588     if (innerCallback_ == nullptr) {
589         ACCOUNT_LOGE("innerCallback_ is nullptr");
590         return;
591     }
592 
593     auto &innerIamMgr = InnerAccountIAMManager::GetInstance();
594     if (result != 0) {
595         ACCOUNT_LOGE("CommitCredUpdateCallback fail code=%{public}d", result);
596         ReportOsAccountOperationFail(userId_, std::string(Constants::OPERATION_UPDATE_CRED) + "_commit",
597             result, "Failed to commit credential update");
598         innerCallback_->OnResult(result, extraInfo);
599         innerIamMgr.SetState(userId_, AFTER_OPEN_SESSION);
600         return;
601     } else {
602         ReportOsAccountLifeCycle(userId_,
603             std::string(Constants::OPERATION_UPDATE_CRED) + "_" + std::to_string(AuthType::PIN) + "_commit");
604     }
605     if (!extraUpdateInfo_.oldSecret.empty()) {
606         ErrCode code = innerIamMgr.UpdateStorageUserAuth(
607             userId_, extraUpdateInfo_.secureUid, extraUpdateInfo_.token, {}, extraUpdateInfo_.newSecret);
608         if (code != ERR_OK) {
609             ACCOUNT_LOGE("Fail to update user auth, userId=%{public}d, code=%{public}d", userId_, code);
610             innerIamMgr.SetState(userId_, AFTER_OPEN_SESSION);
611             ReportOsAccountOperationFail(userId_, std::string(Constants::OPERATION_UPDATE_CRED) + "_commit",
612                 code, "Failed to update user auth");
613             innerCallback_->OnResult(code, extraInfo);
614             return;
615         }
616     }
617     (void)IInnerOsAccountManager::GetInstance().SetOsAccountCredentialId(userId_, extraUpdateInfo_.credentialId);
618     Attributes extraInfoResult;
619     extraInfoResult.SetUint64Value(Attributes::AttributeKey::ATTR_CREDENTIAL_ID, extraUpdateInfo_.credentialId);
620     innerIamMgr.SetState(userId_, AFTER_UPDATE_CRED);
621     innerCallback_->OnResult(result, extraInfoResult);
622     ErrCode updateRet = innerIamMgr.UpdateStorageKeyContext(userId_);
623     if (updateRet != ERR_OK) {
624         ReportOsAccountOperationFail(userId_, std::string(Constants::OPERATION_UPDATE_CRED) + "_commit",
625             updateRet, "Failed to update key context");
626     }
627 }
628 
OnResult(int32_t result,const Attributes & extraInfo)629 void CommitCredUpdateCallback::OnResult(int32_t result, const Attributes &extraInfo)
630 {
631     std::unique_lock<std::mutex> lock(mutex_);
632     InnerOnResult(result, extraInfo);
633     isCalled_ = true;
634     onResultCondition_.notify_one();
635 }
636 
OnAcquireInfo(int32_t module,uint32_t acquireInfo,const Attributes & extraInfo)637 void CommitCredUpdateCallback::OnAcquireInfo(int32_t module, uint32_t acquireInfo, const Attributes &extraInfo)
638 {
639     ACCOUNT_LOGE("CommitCredUpdateCallback OnAcquireInfo");
640 }
641 
DelCredCallback(int32_t userId,bool isPIN,std::vector<uint8_t> token,const sptr<IIDMCallback> & callback)642 DelCredCallback::DelCredCallback(int32_t userId, bool isPIN, std::vector<uint8_t> token,
643     const sptr<IIDMCallback> &callback)
644     : userId_(userId), isPIN_(isPIN), token_(token), innerCallback_(callback)
645 {}
646 
OnResult(int32_t result,const Attributes & extraInfo)647 void DelCredCallback::OnResult(int32_t result, const Attributes &extraInfo)
648 {
649     ACCOUNT_LOGI("DelCredCallback, result=%{public}d, userId=%{public}d", result, userId_);
650     if (innerCallback_ == nullptr) {
651         ACCOUNT_LOGE("innerCallback_ is nullptr");
652         return;
653     }
654     auto &innerIamMgr = InnerAccountIAMManager::GetInstance();
655     if ((result == 0) && isPIN_) {
656         (void)IInnerOsAccountManager::GetInstance().SetOsAccountCredentialId(userId_, 0);  // 0-invalid credentialId
657         std::vector<uint8_t> newSecret;
658         std::vector<uint8_t> oldSecret;
659         extraInfo.GetUint8ArrayValue(Attributes::ATTR_OLD_ROOT_SECRET, oldSecret);
660         uint64_t secureUid = 0;
661         extraInfo.GetUint64Value(Attributes::AttributeKey::ATTR_SEC_USER_ID, secureUid);
662         ErrCode updateRet = innerIamMgr.UpdateStorageUserAuth(userId_, secureUid, token_, oldSecret, newSecret);
663         if (updateRet != ERR_OK) {
664             ReportOsAccountOperationFail(userId_, "deleteCredential", updateRet, "Failed to update user auth");
665         }
666         updateRet = innerIamMgr.UpdateStorageKeyContext(userId_);
667         if (updateRet != ERR_OK) {
668             ReportOsAccountOperationFail(userId_, "deleteCredential", updateRet, "Failed to update key context");
669         }
670     }
671     if (result != 0) {
672         ACCOUNT_LOGE("DelCredCallback fail code=%{public}d, userId=%{public}d", result, userId_);
673         ReportOsAccountOperationFail(userId_, "deleteCredential", result, "Failed to delete credential");
674     } else {
675         ReportOsAccountLifeCycle(userId_, std::string(Constants::OPERATION_DELETE_CRED));
676     }
677 
678     innerIamMgr.SetState(userId_, AFTER_OPEN_SESSION);
679     innerCallback_->OnResult(result, extraInfo);
680 }
681 
OnAcquireInfo(int32_t module,uint32_t acquireInfo,const Attributes & extraInfo)682 void DelCredCallback::OnAcquireInfo(int32_t module, uint32_t acquireInfo, const Attributes &extraInfo)
683 {
684     ACCOUNT_LOGI("DelCredCallback, userId=%{public}d", userId_);
685     if (innerCallback_ == nullptr) {
686         ACCOUNT_LOGE("innerCallback_ is nullptr");
687         return;
688     }
689     innerCallback_->OnAcquireInfo(module, acquireInfo, extraInfo);
690 }
691 
GetCredInfoCallbackWrapper(int32_t userId,int32_t authType,const sptr<IGetCredInfoCallback> & callback)692 GetCredInfoCallbackWrapper::GetCredInfoCallbackWrapper(
693     int32_t userId, int32_t authType, const sptr<IGetCredInfoCallback> &callback)
694     : userId_(userId), authType_(authType), innerCallback_(callback)
695 {}
696 
OnCredentialInfo(int32_t result,const std::vector<CredentialInfo> & infoList)697 void GetCredInfoCallbackWrapper::OnCredentialInfo(int32_t result, const std::vector<CredentialInfo> &infoList)
698 {
699     ACCOUNT_LOGI("Get credential info ret:%{public}d, userId:%{public}d, authType:%{public}d",
700         result, userId_, authType_);
701     if (innerCallback_ == nullptr) {
702         ACCOUNT_LOGE("InnerCallback_ is nullptr");
703         return;
704     }
705     if (result != 0) {
706         REPORT_OS_ACCOUNT_FAIL(userId_, "getCredentialInfo", result,
707             "Failed to get credential info, authType:" + std::to_string(authType_));
708     }
709     if (result == ERR_IAM_NOT_ENROLLED) {
710         result = 0;
711     }
712     if ((result == 0) && (authType_ == 0)) {
713         bool isAvailable = InnerAccountIAMManager::GetInstance().CheckDomainAuthAvailable(userId_);
714         if (isAvailable) {
715             ACCOUNT_LOGI("Domain auth is support");
716             std::vector<CredentialInfo> newInfoList = infoList;
717             CredentialInfo info;
718             info.authType = static_cast<AuthType>(IAMAuthType::DOMAIN);
719             info.pinType = static_cast<PinSubType>(IAMAuthSubType::DOMAIN_MIXED);
720             newInfoList.emplace_back(info);
721             return innerCallback_->OnCredentialInfo(result, newInfoList);
722         }
723     }
724     return innerCallback_->OnCredentialInfo(result, infoList);
725 }
726 
GetPropCallbackWrapper(int32_t userId,const sptr<IGetSetPropCallback> & callback)727 GetPropCallbackWrapper::GetPropCallbackWrapper(int32_t userId, const sptr<IGetSetPropCallback> &callback)
728     : userId_(userId), innerCallback_(callback)
729 {}
730 
OnResult(int32_t result,const Attributes & extraInfo)731 void GetPropCallbackWrapper::OnResult(int32_t result, const Attributes &extraInfo)
732 {
733     ACCOUNT_LOGI("Get property, result:%{public}d, userId:%{public}d", result, userId_);
734     if (innerCallback_ == nullptr) {
735         ACCOUNT_LOGE("inner callback is nullptr");
736         return;
737     }
738     if (result != 0) {
739         ReportOsAccountOperationFail(userId_, "getProperty", result, "Failed to get property");
740     }
741     innerCallback_->OnResult(result, extraInfo);
742 }
743 
SetPropCallbackWrapper(int32_t userId,const sptr<IGetSetPropCallback> & callback)744 SetPropCallbackWrapper::SetPropCallbackWrapper(int32_t userId, const sptr<IGetSetPropCallback> &callback)
745     : userId_(userId), innerCallback_(callback)
746 {}
747 
OnResult(int32_t result,const Attributes & extraInfo)748 void SetPropCallbackWrapper::OnResult(int32_t result, const Attributes &extraInfo)
749 {
750     ACCOUNT_LOGI("Set property, result:%{public}d, userId:%{public}d", result, userId_);
751     if (innerCallback_ == nullptr) {
752         ACCOUNT_LOGE("inner callback is nullptr");
753         return;
754     }
755     if (result != 0) {
756         ReportOsAccountOperationFail(userId_, "setProperty", result, "Failed to set property");
757     }
758     innerCallback_->OnResult(result, extraInfo);
759 }
760 
GetSecUserInfoCallbackWrapper(int32_t userId,AuthType authType,const sptr<IGetEnrolledIdCallback> & callback)761 GetSecUserInfoCallbackWrapper::GetSecUserInfoCallbackWrapper(
762     int32_t userId, AuthType authType, const sptr<IGetEnrolledIdCallback> &callback)
763     : userId_(userId), authType_(authType), innerCallback_(callback)
764 {}
765 
OnSecUserInfo(int32_t result,const SecUserInfo & info)766 void GetSecUserInfoCallbackWrapper::OnSecUserInfo(int32_t result, const SecUserInfo &info)
767 {
768     ACCOUNT_LOGI("Get sec user info, result:%{public}d, authType_:%{public}d", result, authType_);
769     static_cast<void>(result);
770     if (innerCallback_ == nullptr) {
771         ACCOUNT_LOGE("Inner callback is nullptr");
772         return;
773     }
774     if (result != 0) {
775         REPORT_OS_ACCOUNT_FAIL(userId_, "getEnrolledId", result,
776             "Failed to get sec user info, type = " + std::to_string(authType_));
777     }
778     auto it = std::find_if(info.enrolledInfo.begin(), info.enrolledInfo.end(), [this](const auto& item) {
779         return item.authType == authType_;
780     });
781     if (it != info.enrolledInfo.end()) {
782         return innerCallback_->OnEnrolledId(ERR_OK, it->enrolledId);
783     } else {
784         return innerCallback_->OnEnrolledId(ERR_IAM_NOT_ENROLLED, 0);
785     }
786 }
787 
GetSecureUidCallback(int32_t userId)788 GetSecureUidCallback::GetSecureUidCallback(int32_t userId): userId_(userId)
789 {}
790 
OnSecUserInfo(int32_t result,const SecUserInfo & info)791 void GetSecureUidCallback::OnSecUserInfo(int32_t result, const SecUserInfo &info)
792 {
793     static_cast<void>(result);
794     ACCOUNT_LOGI("SecUserInfo call back userId=%{public}d", userId_);
795     std::unique_lock<std::mutex> lck(secureMtx_);
796     this->secureUid_ = info.secureUid;
797     isCalled_ = true;
798     secureCv_.notify_all();
799 }
800 
PrepareRemoteAuthCallbackWrapper(const sptr<IPreRemoteAuthCallback> & callback)801 PrepareRemoteAuthCallbackWrapper::PrepareRemoteAuthCallbackWrapper(const sptr<IPreRemoteAuthCallback> &callback)
802     : innerCallback_(callback)
803 {}
804 
OnResult(int32_t result)805 void PrepareRemoteAuthCallbackWrapper::OnResult(int32_t result)
806 {
807     ACCOUNT_LOGI("Prepare remote auth, result:%{public}d.", result);
808     if (innerCallback_ == nullptr) {
809         ACCOUNT_LOGE("Inner callback is nullptr.");
810         return;
811     }
812     if (result != 0) {
813         ACCOUNT_LOGE("PrepareRemoteAuth, result=%{public}d fail to prepare remote auth.", result);
814         REPORT_OS_ACCOUNT_FAIL(0, "prepareRemoteAuth", result, "Failed to prepare remote auth");
815     }
816     innerCallback_->OnResult(result);
817 }
818 
819 #ifdef SUPPORT_DOMAIN_ACCOUNTS
GetDomainAuthStatusInfoCallback(const GetPropertyRequest & request,const sptr<IGetSetPropCallback> & callback)820 GetDomainAuthStatusInfoCallback::GetDomainAuthStatusInfoCallback(
821     const GetPropertyRequest &request, const sptr<IGetSetPropCallback> &callback)
822     : request_(request), innerCallback_(callback)
823 {}
824 
OnResult(int32_t result,Parcel & parcel)825 void GetDomainAuthStatusInfoCallback::OnResult(int32_t result, Parcel &parcel)
826 {
827     ACCOUNT_LOGI("Get domain auth status info, result=%{public}d.", result);
828     if (innerCallback_ == nullptr) {
829         ACCOUNT_LOGE("inner callback is nullptr");
830         return;
831     }
832     Attributes attributes;
833     std::shared_ptr<AuthStatusInfo> infoPtr(AuthStatusInfo::Unmarshalling(parcel));
834     if (infoPtr == nullptr) {
835         ACCOUNT_LOGE("Unmarshalling parcel to auth status info failed.");
836         innerCallback_->OnResult(ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR, attributes);
837         return;
838     }
839     attributes.SetInt32Value(Attributes::ATTR_PIN_SUB_TYPE, static_cast<int32_t>(IAMAuthSubType::DOMAIN_MIXED));
840     attributes.SetInt32Value(Attributes::ATTR_REMAIN_TIMES, infoPtr->remainingTimes);
841     attributes.SetInt32Value(Attributes::ATTR_FREEZING_TIME, infoPtr->freezingTime);
842     innerCallback_->OnResult(result, attributes);
843 }
844 #endif // SUPPORT_DOMAIN_ACCOUNTS
845 }  // namespace AccountSA
846 }  // namespace OHOS
847