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 "account_iam_client.h"
17
18 #include "accesstoken_kit.h"
19 #include "account_error_no.h"
20 #include "account_iam_callback_service.h"
21 #include "account_log_wrapper.h"
22 #include "account_proxy.h"
23 #include "iservice_registry.h"
24 #include "os_account_manager.h"
25 #include "pinauth_register.h"
26 #include "system_ability_definition.h"
27 #include "token_setproc.h"
28
29 namespace OHOS {
30 namespace AccountSA {
31 namespace {
32 const std::string PERMISSION_MANAGE_USER_IDM = "ohos.permission.MANAGE_USER_IDM";
33 const std::string PERMISSION_ACCESS_USER_AUTH_INTERNAL = "ohos.permission.ACCESS_USER_AUTH_INTERNAL";
34 }
AccountIAMClient()35 AccountIAMClient::AccountIAMClient()
36 {}
37
OpenSession(int32_t userId,std::vector<uint8_t> & challenge)38 int32_t AccountIAMClient::OpenSession(int32_t userId, std::vector<uint8_t> &challenge)
39 {
40 if (GetAccountIAMProxy() != ERR_OK) {
41 return ERR_ACCOUNT_IAM_KIT_PROXY_ERROR;
42 }
43 return proxy_->OpenSession(userId, challenge);
44 }
45
CloseSession(int32_t userId)46 int32_t AccountIAMClient::CloseSession(int32_t userId)
47 {
48 if (GetAccountIAMProxy() != ERR_OK) {
49 return ERR_ACCOUNT_IAM_KIT_PROXY_ERROR;
50 }
51 return proxy_->CloseSession(userId);
52 }
53
AddCredential(int32_t userId,const CredentialParameters & credInfo,const std::shared_ptr<IDMCallback> & callback)54 void AccountIAMClient::AddCredential(
55 int32_t userId, const CredentialParameters& credInfo, const std::shared_ptr<IDMCallback> &callback)
56 {
57 if (callback == nullptr) {
58 ACCOUNT_LOGE("callback is nullptr");
59 return;
60 }
61 Attributes emptyResult;
62 if (GetAccountIAMProxy() != ERR_OK) {
63 callback->OnResult(ERR_ACCOUNT_IAM_KIT_PROXY_ERROR, emptyResult);
64 return;
65 }
66 if ((userId == 0) && (!GetCurrentUserId(userId))) {
67 ACCOUNT_LOGE("fail to add credential for invalid userId");
68 callback->OnResult(ERR_ACCOUNT_IAM_KIT_PARAM_INVALID_ERROR, emptyResult);
69 return;
70 }
71 if (credInfo.authType == AuthType::PIN) {
72 SetAuthSubType(userId, static_cast<int32_t>(credInfo.pinType.value_or(PinSubType::PIN_MAX)));
73 }
74 sptr<IIDMCallback> wrapper = new (std::nothrow) IDMCallbackService(userId, callback);
75 proxy_->AddCredential(userId, credInfo, wrapper);
76 }
77
UpdateCredential(int32_t userId,const CredentialParameters & credInfo,const std::shared_ptr<IDMCallback> & callback)78 void AccountIAMClient::UpdateCredential(
79 int32_t userId, const CredentialParameters& credInfo, const std::shared_ptr<IDMCallback> &callback)
80 {
81 if (callback == nullptr) {
82 ACCOUNT_LOGE("callback is nullptr");
83 return;
84 }
85 Attributes emptyResult;
86 if (GetAccountIAMProxy() != ERR_OK) {
87 callback->OnResult(ERR_ACCOUNT_IAM_KIT_PROXY_ERROR, emptyResult);
88 return;
89 }
90 if ((userId == 0) && (!GetCurrentUserId(userId))) {
91 ACCOUNT_LOGE("fail to update credential for invalid userId");
92 callback->OnResult(ERR_ACCOUNT_IAM_KIT_PARAM_INVALID_ERROR, emptyResult);
93 return;
94 }
95 if (credInfo.authType == AuthType::PIN) {
96 SetAuthSubType(userId, static_cast<int32_t>(credInfo.pinType.value_or(PinSubType::PIN_MAX)));
97 }
98 sptr<IIDMCallback> wrapper = new (std::nothrow) IDMCallbackService(userId, callback);
99 proxy_->UpdateCredential(userId, credInfo, wrapper);
100 }
101
DelCred(int32_t userId,uint64_t credentialId,const std::vector<uint8_t> & authToken,const std::shared_ptr<IDMCallback> & callback)102 void AccountIAMClient::DelCred(int32_t userId, uint64_t credentialId, const std::vector<uint8_t> &authToken,
103 const std::shared_ptr<IDMCallback>& callback)
104 {
105 if (callback == nullptr) {
106 ACCOUNT_LOGE("callback is nullptr");
107 return;
108 }
109 Attributes emptyResult;
110 if (GetAccountIAMProxy() != ERR_OK) {
111 callback->OnResult(ERR_ACCOUNT_IAM_KIT_PROXY_ERROR, emptyResult);
112 return;
113 }
114 if ((userId == 0) && (!GetCurrentUserId(userId))) {
115 callback->OnResult(ERR_ACCOUNT_IAM_KIT_PARAM_INVALID_ERROR, emptyResult);
116 return;
117 }
118 sptr<IIDMCallback> wrapper = new (std::nothrow) IDMCallbackService(userId, callback);
119 proxy_->DelCred(userId, credentialId, authToken, wrapper);
120 }
121
DelUser(int32_t userId,const std::vector<uint8_t> & authToken,const std::shared_ptr<IDMCallback> & callback)122 void AccountIAMClient::DelUser(
123 int32_t userId, const std::vector<uint8_t> &authToken, const std::shared_ptr<IDMCallback> &callback)
124 {
125 if (callback == nullptr) {
126 ACCOUNT_LOGE("callback is nullptr");
127 return;
128 }
129 Attributes emptyResult;
130 if (GetAccountIAMProxy() != ERR_OK) {
131 callback->OnResult(ERR_ACCOUNT_IAM_KIT_PROXY_ERROR, emptyResult);
132 return;
133 }
134 if ((userId == 0) && (!GetCurrentUserId(userId))) {
135 callback->OnResult(ERR_ACCOUNT_IAM_KIT_PARAM_INVALID_ERROR, emptyResult);
136 return;
137 }
138 sptr<IIDMCallback> wrapper = new (std::nothrow) IDMCallbackService(userId, callback);
139 proxy_->DelUser(userId, authToken, wrapper);
140 }
141
GetCredentialInfo(int32_t userId,AuthType authType,const std::shared_ptr<GetCredInfoCallback> & callback)142 int32_t AccountIAMClient::GetCredentialInfo(
143 int32_t userId, AuthType authType, const std::shared_ptr<GetCredInfoCallback> &callback)
144 {
145 if (GetAccountIAMProxy() != ERR_OK) {
146 return ERR_ACCOUNT_IAM_KIT_PROXY_ERROR;
147 }
148 sptr<IGetCredInfoCallback> wrapper = new (std::nothrow) GetCredInfoCallbackService(callback);
149 return proxy_->GetCredentialInfo(userId, authType, wrapper);
150 }
151
Cancel(int32_t userId)152 int32_t AccountIAMClient::Cancel(int32_t userId)
153 {
154 if (GetAccountIAMProxy() != ERR_OK) {
155 return ERR_ACCOUNT_IAM_KIT_PROXY_ERROR;
156 }
157 return proxy_->Cancel(userId);
158 }
159
StartDomainAuth(int32_t userId,const std::shared_ptr<IDMCallback> & callback)160 uint64_t AccountIAMClient::StartDomainAuth(int32_t userId, const std::shared_ptr<IDMCallback> &callback)
161 {
162 std::lock_guard<std::mutex> lock(domainMutex_);
163 Attributes emptyResult;
164 if (domainInputer_ == nullptr) {
165 ACCOUNT_LOGE("the registered inputer is not found or invalid");
166 callback->OnResult(ERR_ACCOUNT_IAM_KIT_INPUTER_NOT_REGISTERED, emptyResult);
167 return 0;
168 }
169 auto credentialRecipient = std::make_shared<DomainCredentialRecipient>(userId, callback);
170 if (credentialRecipient == nullptr) {
171 ACCOUNT_LOGE("failed to create DomainCredentialRecipient");
172 callback->OnResult(ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR, emptyResult);
173 return 0;
174 }
175 domainInputer_->OnGetData(IAMAuthType::DOMAIN, credentialRecipient);
176 return 0;
177 }
178
Auth(const std::vector<uint8_t> & challenge,AuthType authType,AuthTrustLevel authTrustLevel,const std::shared_ptr<IDMCallback> & callback)179 uint64_t AccountIAMClient::Auth(const std::vector<uint8_t> &challenge, AuthType authType,
180 AuthTrustLevel authTrustLevel, const std::shared_ptr<IDMCallback> &callback)
181 {
182 return AuthUser(0, challenge, authType, authTrustLevel, callback);
183 }
184
AuthUser(int32_t userId,const std::vector<uint8_t> & challenge,AuthType authType,AuthTrustLevel authTrustLevel,const std::shared_ptr<IDMCallback> & callback)185 uint64_t AccountIAMClient::AuthUser(
186 int32_t userId, const std::vector<uint8_t> &challenge, AuthType authType,
187 AuthTrustLevel authTrustLevel, const std::shared_ptr<IDMCallback> &callback)
188 {
189 uint64_t contextId = 0;
190 if (callback == nullptr) {
191 ACCOUNT_LOGE("callback is nullptr");
192 return contextId;
193 }
194 if (GetAccountIAMProxy() != ERR_OK) {
195 return contextId;
196 }
197 if ((userId == 0) && (!GetCurrentUserId(userId))) {
198 return contextId;
199 }
200 if (static_cast<int32_t>(authType) == static_cast<int32_t>(IAMAuthType::DOMAIN)) {
201 return StartDomainAuth(userId, callback);
202 }
203 sptr<IIDMCallback> wrapper = new (std::nothrow) IDMCallbackService(userId, callback);
204 return proxy_->AuthUser(userId, challenge, authType, authTrustLevel, wrapper);
205 }
206
CancelAuth(uint64_t contextId)207 int32_t AccountIAMClient::CancelAuth(uint64_t contextId)
208 {
209 if (GetAccountIAMProxy() != ERR_OK) {
210 return ERR_ACCOUNT_IAM_KIT_PROXY_ERROR;
211 }
212 return proxy_->CancelAuth(contextId);
213 }
214
GetAvailableStatus(AuthType authType,AuthTrustLevel authTrustLevel,int32_t & status)215 int32_t AccountIAMClient::GetAvailableStatus(AuthType authType, AuthTrustLevel authTrustLevel, int32_t &status)
216 {
217 if (GetAccountIAMProxy() != ERR_OK) {
218 return ERR_ACCOUNT_IAM_KIT_PROXY_ERROR;
219 }
220 if (authTrustLevel < UserIam::UserAuth::ATL1 || authTrustLevel > UserIam::UserAuth::ATL4) {
221 ACCOUNT_LOGE("authTrustLevel is not in correct range");
222 return ERR_ACCOUNT_IAM_KIT_PARAM_INVALID_ERROR;
223 }
224 if (authType < UserIam::UserAuth::ALL) {
225 ACCOUNT_LOGE("authType is not in correct range");
226 return ERR_ACCOUNT_IAM_KIT_PARAM_INVALID_ERROR;
227 }
228 return proxy_->GetAvailableStatus(authType, authTrustLevel, status);
229 }
230
GetProperty(int32_t userId,const GetPropertyRequest & request,const std::shared_ptr<GetSetPropCallback> & callback)231 void AccountIAMClient::GetProperty(
232 int32_t userId, const GetPropertyRequest &request, const std::shared_ptr<GetSetPropCallback> &callback)
233 {
234 if (callback == nullptr) {
235 ACCOUNT_LOGE("callback is nullptr");
236 return;
237 }
238 Attributes emptyResult;
239 if (GetAccountIAMProxy() != ERR_OK) {
240 callback->OnResult(ERR_ACCOUNT_IAM_KIT_PROXY_ERROR, emptyResult);
241 return;
242 }
243 sptr<IGetSetPropCallback> wrapper = new (std::nothrow) GetSetPropCallbackService(callback);
244 proxy_->GetProperty(userId, request, wrapper);
245 }
246
SetProperty(int32_t userId,const SetPropertyRequest & request,const std::shared_ptr<GetSetPropCallback> & callback)247 void AccountIAMClient::SetProperty(
248 int32_t userId, const SetPropertyRequest &request, const std::shared_ptr<GetSetPropCallback> &callback)
249 {
250 if (callback == nullptr) {
251 ACCOUNT_LOGE("callback is nullptr");
252 return;
253 }
254 Attributes emptyResult;
255 if (GetAccountIAMProxy() != ERR_OK) {
256 callback->OnResult(ERR_ACCOUNT_IAM_KIT_PROXY_ERROR, emptyResult);
257 return;
258 }
259 sptr<IGetSetPropCallback> wrapper = new (std::nothrow) GetSetPropCallbackService(callback);
260 proxy_->SetProperty(userId, request, wrapper);
261 }
262
RegisterPINInputer(const std::shared_ptr<IInputer> & inputer)263 ErrCode AccountIAMClient::RegisterPINInputer(const std::shared_ptr<IInputer> &inputer)
264 {
265 std::lock_guard<std::mutex> lock(pinMutex_);
266 if (pinInputer_ != nullptr) {
267 ACCOUNT_LOGE("inputer is already registered");
268 return ERR_ACCOUNT_IAM_KIT_INPUTER_ALREADY_REGISTERED;
269 }
270 int32_t userId = 0;
271 if (!GetCurrentUserId(userId)) {
272 return ERR_ACCOUNT_IAM_KIT_GET_USERID_FAIL;
273 }
274 auto iamInputer = std::make_shared<IAMInputer>(userId, inputer);
275 if (iamInputer == nullptr) {
276 ACCOUNT_LOGE("failed to create IAMInputer");
277 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
278 }
279 if (UserIam::PinAuth::PinAuthRegister::GetInstance().RegisterInputer(iamInputer)) {
280 pinInputer_ = inputer;
281 return ERR_OK;
282 }
283 return ERR_ACCOUNT_IAM_SERVICE_PERMISSION_DENIED;
284 }
285
CheckSelfPermission(const std::string & permissionName)286 bool AccountIAMClient::CheckSelfPermission(const std::string &permissionName)
287 {
288 Security::AccessToken::AccessTokenID tokenId = GetSelfTokenID();
289 ErrCode result = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, permissionName);
290 return result == Security::AccessToken::TypePermissionState::PERMISSION_GRANTED;
291 }
292
RegisterDomainInputer(const std::shared_ptr<IInputer> & inputer)293 ErrCode AccountIAMClient::RegisterDomainInputer(const std::shared_ptr<IInputer> &inputer)
294 {
295 std::lock_guard<std::mutex> lock(domainMutex_);
296 if (domainInputer_ != nullptr) {
297 ACCOUNT_LOGE("inputer is already registered");
298 return ERR_ACCOUNT_IAM_KIT_INPUTER_ALREADY_REGISTERED;
299 }
300 domainInputer_ = inputer;
301 return ERR_OK;
302 }
303
RegisterInputer(int32_t authType,const std::shared_ptr<IInputer> & inputer)304 ErrCode AccountIAMClient::RegisterInputer(int32_t authType, const std::shared_ptr<IInputer> &inputer)
305 {
306 if ((!CheckSelfPermission(PERMISSION_ACCESS_USER_AUTH_INTERNAL)) &&
307 (!CheckSelfPermission(PERMISSION_MANAGE_USER_IDM))) {
308 ACCOUNT_LOGE("failed to check permission");
309 return ERR_ACCOUNT_IAM_SERVICE_PERMISSION_DENIED;
310 }
311 if (inputer == nullptr) {
312 ACCOUNT_LOGE("inputer is nullptr");
313 return ERR_ACCOUNT_COMMON_INVALID_PARAMTER;
314 }
315 switch (authType) {
316 case IAMAuthType::DOMAIN:
317 return RegisterDomainInputer(inputer);
318 default:
319 return ERR_ACCOUNT_IAM_UNSUPPORTED_AUTH_TYPE;
320 }
321 }
322
UnregisterInputer(int32_t authType)323 ErrCode AccountIAMClient::UnregisterInputer(int32_t authType)
324 {
325 if ((!CheckSelfPermission(PERMISSION_ACCESS_USER_AUTH_INTERNAL)) &&
326 (!CheckSelfPermission(PERMISSION_MANAGE_USER_IDM))) {
327 ACCOUNT_LOGE("failed to check permission");
328 return ERR_ACCOUNT_IAM_SERVICE_PERMISSION_DENIED;
329 }
330 switch (authType) {
331 case IAMAuthType::DOMAIN:
332 return UnregisterDomainInputer();
333 default:
334 return ERR_ACCOUNT_IAM_UNSUPPORTED_AUTH_TYPE;
335 }
336 return ERR_OK;
337 }
338
UnregisterPINInputer()339 void AccountIAMClient::UnregisterPINInputer()
340 {
341 UserIam::PinAuth::PinAuthRegister::GetInstance().UnRegisterInputer();
342 std::lock_guard<std::mutex> lock(pinMutex_);
343 pinInputer_ = nullptr;
344 }
345
UnregisterDomainInputer()346 ErrCode AccountIAMClient::UnregisterDomainInputer()
347 {
348 std::lock_guard<std::mutex> lock(domainMutex_);
349 domainInputer_ = nullptr;
350 return ERR_OK;
351 }
352
GetAccountState(int32_t userId)353 IAMState AccountIAMClient::GetAccountState(int32_t userId)
354 {
355 if (GetAccountIAMProxy() != ERR_OK) {
356 return IDLE;
357 }
358 return proxy_->GetAccountState(userId);
359 }
360
GetCredential(int32_t userId,CredentialItem & credItem)361 void AccountIAMClient::GetCredential(int32_t userId, CredentialItem &credItem)
362 {
363 std::lock_guard<std::mutex> lock(mutex_);
364 auto it = credentialMap_.find(userId);
365 if (it != credentialMap_.end()) {
366 credItem = it->second;
367 }
368 }
369
SetCredential(int32_t userId,const std::vector<uint8_t> & credential)370 void AccountIAMClient::SetCredential(int32_t userId, const std::vector<uint8_t> &credential)
371 {
372 std::lock_guard<std::mutex> lock(mutex_);
373 auto it = credentialMap_.find(userId);
374 if (it != credentialMap_.end()) {
375 it->second.oldCredential = it->second.credential;
376 it->second.credential = credential;
377 return;
378 }
379 credentialMap_[userId] = {
380 .credential = credential
381 };
382 }
383
ClearCredential(int32_t userId)384 void AccountIAMClient::ClearCredential(int32_t userId)
385 {
386 std::lock_guard<std::mutex> lock(mutex_);
387 credentialMap_.erase(userId);
388 }
389
SetAuthSubType(int32_t userId,int32_t authSubType)390 void AccountIAMClient::SetAuthSubType(int32_t userId, int32_t authSubType)
391 {
392 std::lock_guard<std::mutex> lock(mutex_);
393 auto it = credentialMap_.find(userId);
394 if (it != credentialMap_.end()) {
395 return;
396 }
397 credentialMap_[userId] = {
398 .type = authSubType
399 };
400 }
401
GetAuthSubType(int32_t userId)402 int32_t AccountIAMClient::GetAuthSubType(int32_t userId)
403 {
404 std::lock_guard<std::mutex> lock(mutex_);
405 auto it = credentialMap_.find(userId);
406 if (it != credentialMap_.end()) {
407 return it->second.type;
408 }
409 return 0;
410 }
411
GetCurrentUserId(int32_t & userId)412 bool AccountIAMClient::GetCurrentUserId(int32_t &userId)
413 {
414 std::vector<int32_t> userIds;
415 if ((OsAccountManager::QueryActiveOsAccountIds(userIds) != ERR_OK) || userIds.empty()) {
416 ACCOUNT_LOGE("fail to get activated os account ids");
417 return false;
418 }
419 userId = userIds[0];
420 return true;
421 }
422
ResetAccountIAMProxy(const wptr<IRemoteObject> & remote)423 void AccountIAMClient::ResetAccountIAMProxy(const wptr<IRemoteObject>& remote)
424 {
425 std::lock_guard<std::mutex> lock(mutex_);
426 if (proxy_ == nullptr) {
427 ACCOUNT_LOGE("proxy is nullptr");
428 return;
429 }
430 auto serviceRemote = proxy_->AsObject();
431 if ((serviceRemote != nullptr) && (serviceRemote == remote.promote())) {
432 serviceRemote->RemoveDeathRecipient(deathRecipient_);
433 proxy_ = nullptr;
434 }
435 }
436
OnRemoteDied(const wptr<IRemoteObject> & remote)437 void AccountIAMClient::AccountIAMDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
438 {
439 if (remote == nullptr) {
440 ACCOUNT_LOGE("remote is nullptr");
441 return;
442 }
443 AccountIAMClient::GetInstance().ResetAccountIAMProxy(remote);
444 }
445
GetAccountIAMProxy()446 ErrCode AccountIAMClient::GetAccountIAMProxy()
447 {
448 std::lock_guard<std::mutex> lock(mutex_);
449 if (proxy_ != nullptr) {
450 return ERR_OK;
451 }
452 sptr<ISystemAbilityManager> saMgr =
453 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
454 if (saMgr == nullptr) {
455 ACCOUNT_LOGE("failed to get system ability manager");
456 return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
457 }
458 sptr<IRemoteObject> remoteObject = saMgr->GetSystemAbility(SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN);
459 if (remoteObject == nullptr) {
460 ACCOUNT_LOGE("failed to get account system ability");
461 return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY;
462 }
463 sptr<IAccount> accountProxy = iface_cast<AccountProxy>(remoteObject);
464 if (accountProxy == nullptr) {
465 ACCOUNT_LOGE("failed to cast account proxy");
466 return ERR_ACCOUNT_COMMON_GET_PROXY;
467 }
468 proxy_ = iface_cast<IAccountIAM>(accountProxy->GetAccountIAMService());
469 if ((proxy_ == nullptr) || (proxy_->AsObject() == nullptr)) {
470 ACCOUNT_LOGE("failed to cast account iam proxy");
471 return ERR_ACCOUNT_COMMON_GET_PROXY;
472 }
473 deathRecipient_ = new (std::nothrow) AccountIAMDeathRecipient();
474 if (deathRecipient_ == nullptr) {
475 ACCOUNT_LOGE("failed to create account iam death recipient");
476 proxy_ = nullptr;
477 return ERR_ACCOUNT_COMMON_CREATE_DEATH_RECIPIENT;
478 }
479 if (!proxy_->AsObject()->AddDeathRecipient(deathRecipient_)) {
480 ACCOUNT_LOGE("failed to add account iam death recipient");
481 proxy_ = nullptr;
482 return ERR_ACCOUNT_COMMON_ADD_DEATH_RECIPIENT;
483 }
484 return ERR_OK;
485 }
486 } // namespace AccountSA
487 } // namespace OHOS
488