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