• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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 "account_iam_callback.h"
19 #include "account_log_wrapper.h"
20 #include "domain_account_callback_service.h"
21 #include "hisysevent_adapter.h"
22 #include "iinner_os_account_manager.h"
23 #include "inner_domain_account_manager.h"
24 #include "iservice_registry.h"
25 #include "system_ability_definition.h"
26 #include "user_auth_client.h"
27 #include "user_auth_client_impl.h"
28 #include "user_idm_client.h"
29 
30 namespace OHOS {
31 namespace AccountSA {
32 namespace {
33 #ifdef HAS_STORAGE_PART
34 const int32_t ERROR_STORAGE_KEY_NOT_EXIST = -2;
35 #endif
36 }
37 using UserIDMClient = UserIam::UserAuth::UserIdmClient;
38 using UserAuthClient = UserIam::UserAuth::UserAuthClient;
39 using UserAuthClientImpl = UserIam::UserAuth::UserAuthClientImpl;
40 
InnerAccountIAMManager()41 InnerAccountIAMManager::InnerAccountIAMManager()
42 {
43     userStateMap_[0] = IDLE;
44 }
45 
GetInstance()46 InnerAccountIAMManager &InnerAccountIAMManager::GetInstance()
47 {
48     static InnerAccountIAMManager *instance = new (std::nothrow) InnerAccountIAMManager();
49     return *instance;
50 }
51 
OpenSession(int32_t userId,std::vector<uint8_t> & challenge)52 void InnerAccountIAMManager::OpenSession(int32_t userId, std::vector<uint8_t> &challenge)
53 {
54     challenge = UserIDMClient::GetInstance().OpenSession(userId);
55     std::lock_guard<std::mutex> lock(mutex_);
56     userStateMap_[userId] = AFTER_OPEN_SESSION;
57     userChallengeMap_[userId] = challenge;
58 }
59 
CloseSession(int32_t userId)60 void InnerAccountIAMManager::CloseSession(int32_t userId)
61 {
62     UserIDMClient::GetInstance().CloseSession(userId);
63     std::lock_guard<std::mutex> lock(mutex_);
64     if (userId == 0) {
65         userStateMap_[0] = IDLE;
66     } else {
67         userStateMap_.erase(userId);
68     }
69     userChallengeMap_.erase(userId);
70 }
71 
AddCredential(int32_t userId,const CredentialParameters & credInfo,const sptr<IIDMCallback> & callback)72 void InnerAccountIAMManager::AddCredential(
73     int32_t userId, const CredentialParameters &credInfo, const sptr<IIDMCallback> &callback)
74 {
75     if (callback == nullptr) {
76         ACCOUNT_LOGE("callback is nullptr");
77         return;
78     }
79     auto idmCallback = std::make_shared<AddCredCallback>(userId, credInfo, callback);
80     UserIDMClient::GetInstance().AddCredential(userId, credInfo, idmCallback);
81 }
82 
UpdateCredential(int32_t userId,const CredentialParameters & credInfo,const sptr<IIDMCallback> & callback)83 void InnerAccountIAMManager::UpdateCredential(
84     int32_t userId, const CredentialParameters &credInfo, const sptr<IIDMCallback> &callback)
85 {
86     if (callback == nullptr) {
87         ACCOUNT_LOGE("callback is nullptr");
88         return;
89     }
90     Attributes emptyResult;
91     if (credInfo.token.empty()) {
92         ACCOUNT_LOGE("token is empty");
93         callback->OnResult(ResultCode::INVALID_PARAMETERS, emptyResult);
94         return;
95     }
96     auto idmCallback = std::make_shared<UpdateCredCallback>(userId, credInfo, callback);
97     UserIDMClient::GetInstance().UpdateCredential(userId, credInfo, idmCallback);
98 }
99 
DelCred(int32_t userId,uint64_t credentialId,const std::vector<uint8_t> & authToken,const sptr<IIDMCallback> & callback)100 void InnerAccountIAMManager::DelCred(
101     int32_t userId, uint64_t credentialId, const std::vector<uint8_t> &authToken, const sptr<IIDMCallback> &callback)
102 {
103     if (callback == nullptr) {
104         ACCOUNT_LOGE("callback is nullptr");
105         return;
106     }
107     Attributes emptyResult;
108     if (authToken.empty()) {
109         ACCOUNT_LOGD("token is empty");
110         callback->OnResult(ResultCode::INVALID_PARAMETERS, emptyResult);
111         return;
112     }
113     uint64_t pinCredentialId = 0;
114     (void)IInnerOsAccountManager::GetInstance().GetOsAccountCredentialId(userId, pinCredentialId);
115     bool isPIN = false;
116     if ((pinCredentialId != 0) && (credentialId == pinCredentialId)) {
117         isPIN = true;
118         ErrCode result = RemoveUserKey(userId, authToken);
119         if (result != ERR_OK) {
120             callback->OnResult(result, emptyResult);
121             return;
122         }
123     }
124     auto idmCallback = std::make_shared<DelCredCallback>(userId, isPIN, callback);
125     UserIDMClient::GetInstance().DeleteCredential(userId, credentialId, authToken, idmCallback);
126 }
127 
DelUser(int32_t userId,const std::vector<uint8_t> & authToken,const sptr<IIDMCallback> & callback)128 void InnerAccountIAMManager::DelUser(
129     int32_t userId, const std::vector<uint8_t> &authToken, const sptr<IIDMCallback> &callback)
130 {
131     if (callback == nullptr) {
132         ACCOUNT_LOGE("callback is nullptr");
133         return;
134     }
135     Attributes errResult;
136     if (authToken.empty()) {
137         ACCOUNT_LOGE("token is empty");
138         callback->OnResult(ResultCode::INVALID_PARAMETERS, errResult);
139         return;
140     }
141     ErrCode result = RemoveUserKey(userId, authToken);
142     if (result != ERR_OK) {
143         callback->OnResult(result, errResult);
144         return;
145     }
146     auto idmCallback = std::make_shared<DelCredCallback>(userId, true, callback);
147     UserIDMClient::GetInstance().DeleteUser(userId, authToken, idmCallback);
148 }
149 
IsNonPINAllowed(int32_t userId)150 static bool IsNonPINAllowed(int32_t userId)
151 {
152     bool isVerified = false;
153     (void) IInnerOsAccountManager::GetInstance().IsOsAccountVerified(userId, isVerified);
154     return isVerified;
155 }
156 
GetCredentialInfo(int32_t userId,AuthType authType,const sptr<IGetCredInfoCallback> & callback)157 void InnerAccountIAMManager::GetCredentialInfo(
158     int32_t userId, AuthType authType, const sptr<IGetCredInfoCallback> &callback)
159 {
160     if (!IsNonPINAllowed(userId)) {
161         if ((authType != AuthType::PIN) && (authType != AuthType::ALL)) {
162             ACCOUNT_LOGD("unsupported auth type: %{public}d", authType);
163             std::vector<CredentialInfo> infoList;
164             return callback->OnCredentialInfo(infoList);
165         }
166         authType = AuthType::PIN;
167     }
168     if (static_cast<int32_t>(authType) == static_cast<int32_t>(IAMAuthType::DOMAIN)) {
169         std::vector<CredentialInfo> infoList;
170         if (CheckDomainAuthAvailable(userId)) {
171             CredentialInfo info;
172             info.authType = static_cast<AuthType>(IAMAuthType::DOMAIN);
173             info.pinType = static_cast<PinSubType>(IAMAuthSubType::DOMAIN_MIXED);
174             infoList.emplace_back(info);
175         }
176         return callback->OnCredentialInfo(infoList);
177     }
178     auto getCallback = std::make_shared<GetCredInfoCallbackWrapper>(userId, static_cast<int32_t>(authType), callback);
179     UserIDMClient::GetInstance().GetCredentialInfo(userId, authType, getCallback);
180 }
181 
Cancel(int32_t userId)182 int32_t InnerAccountIAMManager::Cancel(int32_t userId)
183 {
184     std::lock_guard<std::mutex> lock(mutex_);
185     auto it = userStateMap_.find(userId);
186     if ((it == userStateMap_.end()) || (it->second >= AFTER_ADD_CRED)) {
187         return ResultCode::GENERAL_ERROR;
188     }
189     return UserIDMClient::GetInstance().Cancel(userId);
190 }
191 
AuthUser(int32_t userId,const AuthParam & authParam,const sptr<IIDMCallback> & callback,uint64_t & contextId)192 int32_t InnerAccountIAMManager::AuthUser(
193     int32_t userId, const AuthParam &authParam, const sptr<IIDMCallback> &callback, uint64_t &contextId)
194 {
195     if (callback == nullptr) {
196         ACCOUNT_LOGE("callback is nullptr");
197         return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
198     }
199     if ((authParam.authType != AuthType::PIN) && (!IsNonPINAllowed(userId))) {
200         ACCOUNT_LOGE("unsupported auth type: %{public}d", authParam.authType);
201         return ERR_ACCOUNT_IAM_UNSUPPORTED_AUTH_TYPE;
202     }
203     sptr<AuthCallbackDeathRecipient> deathRecipient = new (std::nothrow) AuthCallbackDeathRecipient();
204     if ((deathRecipient == nullptr) || (!callback->AsObject()->AddDeathRecipient(deathRecipient))) {
205         ACCOUNT_LOGE("failed to add death recipient for auth callback");
206         return ERR_ACCOUNT_COMMON_ADD_DEATH_RECIPIENT;
207     }
208     auto callbackWrapper = std::make_shared<AuthCallback>(userId, authParam.authType, callback);
209     callbackWrapper->SetDeathRecipient(deathRecipient);
210     contextId = UserAuthClient::GetInstance().BeginAuthentication(
211         userId, authParam.challenge, authParam.authType, authParam.authTrustLevel, callbackWrapper);
212     deathRecipient->SetContextId(contextId);
213     return ERR_OK;
214 }
215 
CancelAuth(uint64_t contextId)216 int32_t InnerAccountIAMManager::CancelAuth(uint64_t contextId)
217 {
218     return UserAuthClient::GetInstance().CancelAuthentication(contextId);
219 }
220 
GetAvailableStatus(AuthType authType,AuthTrustLevel authTrustLevel,int32_t & status)221 int32_t InnerAccountIAMManager::GetAvailableStatus(
222     AuthType authType, AuthTrustLevel authTrustLevel, int32_t &status)
223 {
224     if (static_cast<int32_t>(authType) != static_cast<int32_t>(IAMAuthType::DOMAIN)) {
225         status = UserAuthClientImpl::Instance().GetAvailableStatus(authType, authTrustLevel);
226         return ERR_OK;
227     }
228     bool isPluginAvailable = InnerDomainAccountManager::GetInstance().IsPluginAvailable();
229     if (isPluginAvailable) {
230         status = ERR_JS_SUCCESS;
231     } else {
232         status = ERR_JS_AUTH_TYPE_NOT_SUPPORTED;
233     }
234     return ERR_OK;
235 }
236 
GetDomainAuthStatusInfo(int32_t userId,const GetPropertyRequest & request,const sptr<IGetSetPropCallback> & callback)237 ErrCode InnerAccountIAMManager::GetDomainAuthStatusInfo(
238     int32_t userId, const GetPropertyRequest &request, const sptr<IGetSetPropCallback> &callback)
239 {
240     OsAccountInfo osAccountInfo;
241     ErrCode result = IInnerOsAccountManager::GetInstance().QueryOsAccountById(userId, osAccountInfo);
242     if (result != ERR_OK) {
243         ACCOUNT_LOGE("failed to get account info");
244         return result;
245     }
246     DomainAccountInfo domainAccountInfo;
247     osAccountInfo.GetDomainInfo(domainAccountInfo);
248     if (domainAccountInfo.accountName_.empty()) {
249         ACCOUNT_LOGE("the target user is not a domain account");
250         return ERR_ACCOUNT_IAM_UNSUPPORTED_AUTH_TYPE;
251     }
252     std::shared_ptr<DomainAccountCallback> statusCallback =
253         std::make_shared<GetDomainAuthStatusInfoCallback>(request, callback);
254     if (statusCallback == nullptr) {
255         ACCOUNT_LOGE("failed to create GetDomainAuthStatusInfoCallback");
256         return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
257     }
258     return InnerDomainAccountManager::GetInstance().GetAuthStatusInfo(domainAccountInfo, statusCallback);
259 }
260 
CheckDomainAuthAvailable(int32_t userId)261 bool InnerAccountIAMManager::CheckDomainAuthAvailable(int32_t userId)
262 {
263     OsAccountInfo osAccountInfo;
264     if (IInnerOsAccountManager::GetInstance().QueryOsAccountById(userId, osAccountInfo) != ERR_OK) {
265         ACCOUNT_LOGE("failed to get account info");
266         return false;
267     }
268     DomainAccountInfo domainAccountInfo;
269     osAccountInfo.GetDomainInfo(domainAccountInfo);
270     bool isAvailable = InnerDomainAccountManager::GetInstance().IsPluginAvailable();
271     return !domainAccountInfo.accountName_.empty() && isAvailable;
272 }
273 
GetProperty(int32_t userId,const GetPropertyRequest & request,const sptr<IGetSetPropCallback> & callback)274 void InnerAccountIAMManager::GetProperty(
275     int32_t userId, const GetPropertyRequest &request, const sptr<IGetSetPropCallback> &callback)
276 {
277     if (callback == nullptr) {
278         ACCOUNT_LOGE("callback is nullptr");
279         return;
280     }
281     Attributes attributes;
282     if ((request.authType != AuthType::PIN) && (!IsNonPINAllowed(userId))) {
283         ACCOUNT_LOGE("unsupported auth type: %{public}d", request.authType);
284         callback->OnResult(ERR_ACCOUNT_IAM_UNSUPPORTED_AUTH_TYPE, attributes);
285         return;
286     }
287     if (static_cast<int32_t>(request.authType) != static_cast<int32_t>(IAMAuthType::DOMAIN)) {
288         auto getCallback = std::make_shared<GetPropCallbackWrapper>(userId, callback);
289         UserAuthClient::GetInstance().GetProperty(userId, request, getCallback);
290         return;
291     }
292     ErrCode result = GetDomainAuthStatusInfo(userId, request, callback);
293     if (result != ERR_OK) {
294         callback->OnResult(result, attributes);
295     }
296 }
297 
SetProperty(int32_t userId,const SetPropertyRequest & request,const sptr<IGetSetPropCallback> & callback)298 void InnerAccountIAMManager::SetProperty(
299     int32_t userId, const SetPropertyRequest &request, const sptr<IGetSetPropCallback> &callback)
300 {
301     if (static_cast<int32_t>(request.authType) == static_cast<int32_t>(IAMAuthType::DOMAIN)) {
302         Attributes result;
303         callback->OnResult(ERR_ACCOUNT_IAM_UNSUPPORTED_AUTH_TYPE, result);
304         return;
305     }
306     auto setCallback = std::make_shared<SetPropCallbackWrapper>(userId, callback);
307     UserAuthClient::GetInstance().SetProperty(userId, request, setCallback);
308 }
309 
GetState(int32_t userId)310 IAMState InnerAccountIAMManager::GetState(int32_t userId)
311 {
312     std::lock_guard<std::mutex> lock(mutex_);
313     auto it = userStateMap_.find(userId);
314     if (it != userStateMap_.end()) {
315         return it->second;
316     }
317     return userStateMap_[0];
318 }
319 
SetState(int32_t userId,IAMState state)320 void InnerAccountIAMManager::SetState(int32_t userId, IAMState state)
321 {
322     std::lock_guard<std::mutex> lock(mutex_);
323     userStateMap_[userId] = state;
324 }
325 
GetChallenge(int32_t userId,std::vector<uint8_t> & challenge)326 void InnerAccountIAMManager::GetChallenge(int32_t userId, std::vector<uint8_t> &challenge)
327 {
328     std::lock_guard<std::mutex> lock(mutex_);
329     auto it = userChallengeMap_.find(userId);
330     if (it != userChallengeMap_.end()) {
331         challenge = it->second;
332     } else {
333         challenge = userChallengeMap_[0];
334     }
335 }
336 
UpdateStorageKey(int32_t userId,uint64_t secureUid,const std::vector<uint8_t> & token,const std::vector<uint8_t> & oldSecret,const std::vector<uint8_t> & newSecret)337 ErrCode InnerAccountIAMManager::UpdateStorageKey(
338     int32_t userId, uint64_t secureUid, const std::vector<uint8_t> &token,
339     const std::vector<uint8_t> &oldSecret, const std::vector<uint8_t> &newSecret)
340 {
341 #ifdef HAS_STORAGE_PART
342     ErrCode result = GetStorageManagerProxy();
343     if (result != ERR_OK) {
344         ACCOUNT_LOGE("fail to get storage proxy");
345         return result;
346     }
347     result = storageMgrProxy_->UpdateUserAuth(userId, secureUid, token, oldSecret, newSecret);
348     if ((result != ERR_OK) && (result != ERROR_STORAGE_KEY_NOT_EXIST)) {
349         ACCOUNT_LOGE("fail to update user auth");
350         return result;
351     }
352     return storageMgrProxy_->UpdateKeyContext(userId);
353 #else
354     return ERR_OK;
355 #endif
356 }
357 
GetLockScreenStatus(uint32_t userId,bool & lockScreenStatus)358 ErrCode InnerAccountIAMManager::GetLockScreenStatus(uint32_t userId, bool &lockScreenStatus)
359 {
360 #ifdef HAS_STORAGE_PART
361     ErrCode result = GetStorageManagerProxy();
362     if (result != ERR_OK) {
363         ACCOUNT_LOGE("fail to get storage proxy");
364         return result;
365     }
366     result = storageMgrProxy_->GetLockScreenStatus(userId, lockScreenStatus);
367     if (result != ERR_OK) {
368         ACCOUNT_LOGE("failed to get lock screen status");
369         return result;
370     }
371 #endif
372     return ERR_OK;
373 }
374 
UnlockUserScreen(int32_t userId)375 ErrCode InnerAccountIAMManager::UnlockUserScreen(int32_t userId)
376 {
377 #ifdef HAS_STORAGE_PART
378     ErrCode result = GetStorageManagerProxy();
379     if (result != ERR_OK) {
380         ACCOUNT_LOGE("fail to get storage proxy");
381         return result;
382     }
383     result = storageMgrProxy_->UnlockUserScreen(userId);
384     if (result != ERR_OK) {
385         ACCOUNT_LOGE("fail to unlock screen");
386         return result;
387     }
388 #endif
389     return ERR_OK;
390 }
391 
ActivateUserKey(int32_t userId,const std::vector<uint8_t> & token,const std::vector<uint8_t> & secret)392 ErrCode InnerAccountIAMManager::ActivateUserKey(
393     int32_t userId, const std::vector<uint8_t> &token, const std::vector<uint8_t> &secret)
394 {
395 #ifdef HAS_STORAGE_PART
396     ErrCode result = GetStorageManagerProxy();
397     if (result != ERR_OK) {
398         ACCOUNT_LOGE("fail to get storage proxy");
399         return result;
400     }
401     result = storageMgrProxy_->ActiveUserKey(userId, token, secret);
402     if (result != ERR_OK && result != ERROR_STORAGE_KEY_NOT_EXIST) {
403         ACCOUNT_LOGE("fail to active user key, error code: %{public}d", result);
404         return result;
405     }
406     storageMgrProxy_->PrepareStartUser(userId);
407 #endif
408     std::lock_guard<std::mutex> lock(mutex_);
409     auto it = credInfoMap_.find(userId);
410     if (it != credInfoMap_.end()) {
411         it->second.secret = secret;
412     } else {
413         credInfoMap_[userId] = {
414             .secret = secret
415         };
416     }
417     return ERR_OK;
418 }
419 
UpdateUserKey(int32_t userId,uint64_t secureUid,uint64_t credentialId,const std::vector<uint8_t> & token,const std::vector<uint8_t> & newSecret)420 ErrCode InnerAccountIAMManager::UpdateUserKey(int32_t userId, uint64_t secureUid, uint64_t credentialId,
421     const std::vector<uint8_t> &token, const std::vector<uint8_t> &newSecret)
422 {
423     ErrCode result = ERR_OK;
424     AccountCredentialInfo oldCredInfo;
425     std::lock_guard<std::mutex> lock(mutex_);
426     auto it = credInfoMap_.find(userId);
427     if (it != credInfoMap_.end()) {
428         oldCredInfo = it->second;
429     }
430     result = UpdateStorageKey(userId, secureUid, token, oldCredInfo.secret, newSecret);
431     if (result != ERR_OK) {
432         ReportOsAccountOperationFail(userId, "updateUserKey", result, "failed to notice storage to update user key");
433         return result;
434     }
435     credInfoMap_[userId] = {
436         .oldSecureUid = oldCredInfo.secureUid,
437         .secureUid = secureUid,
438         .oldSecret = oldCredInfo.secret,
439         .secret = newSecret
440     };
441     return result;
442 }
443 
RemoveUserKey(int32_t userId,const std::vector<uint8_t> & token)444 ErrCode InnerAccountIAMManager::RemoveUserKey(int32_t userId, const std::vector<uint8_t> &token)
445 {
446     ErrCode result = ERR_OK;
447     std::lock_guard<std::mutex> lock(mutex_);
448     auto it = credInfoMap_.find(userId);
449     if (it == credInfoMap_.end()) {
450         return ERR_OK;
451     }
452     AccountCredentialInfo oldCredInfo = it->second;
453     std::vector<uint8_t> newSecret;
454     result = UpdateStorageKey(userId, 0, token, oldCredInfo.secret, newSecret);
455     if (result != ERR_OK) {
456         ReportOsAccountOperationFail(userId, "removeUserKey", result, "failed to notice storage to remove user key");
457         return result;
458     }
459     credInfoMap_[userId] = {
460         .oldSecureUid = oldCredInfo.secureUid,
461         .secureUid = 0,
462         .oldSecret = oldCredInfo.secret,
463         .secret = newSecret
464     };
465     return result;
466 }
467 
GetStorageManagerProxy()468 ErrCode InnerAccountIAMManager::GetStorageManagerProxy()
469 {
470 #ifdef HAS_STORAGE_PART
471     if (storageMgrProxy_ != nullptr) {
472         return ERR_OK;
473     }
474     auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
475     if (systemAbilityManager == nullptr) {
476         ACCOUNT_LOGE("failed to get system ability mgr");
477         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
478     }
479     auto remote = systemAbilityManager->GetSystemAbility(STORAGE_MANAGER_MANAGER_ID);
480     if (remote == nullptr) {
481         ACCOUNT_LOGE("failed to get STORAGE_MANAGER_MANAGER_ID service");
482         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY;
483     }
484     storageMgrProxy_ = iface_cast<StorageManager::IStorageManager>(remote);
485     if (storageMgrProxy_ == nullptr) {
486         ACCOUNT_LOGE("failed to get STORAGE_MANAGER_MANAGER_ID proxy");
487         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY;
488     }
489     return ERR_OK;
490 #else
491     return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY;
492 #endif
493 }
494 }  // namespace AccountSA
495 }  // namespace OHOS
496