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