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