• 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 "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