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