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