• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 <unistd.h>
17 
18 #include "iam_client.h"
19 #include "storage_service_log.h"
20 #include "utils/storage_radar.h"
21 
22 using namespace OHOS::StorageService;
23 namespace OHOS {
24 namespace StorageDaemon {
25 constexpr uint8_t IAM_MAX_RETRY_TIME = 3;
26 constexpr uint16_t IAM_RETRY_INTERVAL_MS = 50 * 1000;
27 constexpr int8_t GET_SEC_TIMEOUT = 10;
IamClient()28 IamClient::IamClient()
29 {
30     LOGI("enter");
31 }
32 
~IamClient()33 IamClient::~IamClient()
34 {
35     LOGI("enter");
36 }
37 
38 #ifdef USER_AUTH_FRAMEWORK
OnSecUserInfo(int32_t result,const UserIam::UserAuth::SecUserInfo & info)39 void UserSecCallback::OnSecUserInfo(int32_t result, const UserIam::UserAuth::SecUserInfo &info)
40 {
41     static_cast<void>(result);
42     LOGI("enter");
43     secureUid_ = info.secureUid;
44     IamClient::GetInstance().NotifyGetSecureUid();
45 }
46 
GetSecureUid()47 uint64_t UserSecCallback::GetSecureUid()
48 {
49     LOGI("enter");
50     return secureUid_;
51 }
52 
OnSecUserInfo(int32_t result,const UserIam::UserAuth::SecUserInfo & info)53 void UserEnrollCallback::OnSecUserInfo(int32_t result, const UserIam::UserAuth::SecUserInfo &info)
54 {
55     static_cast<void>(result);
56     LOGI("enter");
57     info_ = info;
58     IamClient::GetInstance().NotifyGetSecUserInfo();
59 }
60 
GetSecUserInfo()61 UserIam::UserAuth::SecUserInfo UserEnrollCallback::GetSecUserInfo()
62 {
63     LOGI("enter");
64     return info_;
65 }
66 #endif
67 
GetSecureUid(uint32_t userId,uint64_t & secureUid)68 bool IamClient::GetSecureUid(uint32_t userId, uint64_t &secureUid)
69 {
70     LOGI("enter");
71 #ifdef USER_AUTH_FRAMEWORK
72     LOGI("get secure uid real !");
73     auto startTime = StorageService::StorageRadar::RecordCurrentTime();
74     secureUidStatus_ = FAILED;
75     std::shared_ptr<UserSecCallback> secCallback = std::make_shared<UserSecCallback>();
76     int32_t retCode = UserIam::UserAuth::UserIdmClient::GetInstance().GetSecUserInfo(userId, secCallback);
77     if (retCode != UserIam::UserAuth::ResultCode::SUCCESS && retCode != UserIam::UserAuth::ResultCode::NOT_ENROLLED &&
78         retCode != UserIam::UserAuth::ResultCode::GENERAL_ERROR) {
79         for (int i = 0; i < IAM_MAX_RETRY_TIME; ++i) {
80             usleep(IAM_RETRY_INTERVAL_MS);
81             retCode = UserIam::UserAuth::UserIdmClient::GetInstance().GetSecUserInfo(userId, secCallback);
82             LOGE("GetSecureUid has retry %{public}d times, retryRet %{public}d", i, retCode);
83             if (retCode == UserIam::UserAuth::ResultCode::SUCCESS ||
84                 retCode == UserIam::UserAuth::ResultCode::NOT_ENROLLED ||
85                 retCode == UserIam::UserAuth::ResultCode::GENERAL_ERROR) {
86                 break;
87             }
88         }
89     }
90     if (retCode != UserIam::UserAuth::ResultCode::SUCCESS && retCode != UserIam::UserAuth::ResultCode::NOT_ENROLLED &&
91         retCode != UserIam::UserAuth::ResultCode::GENERAL_ERROR) {
92         LOGE("Get secure uid failed !");
93         StorageRadar::ReportIamResult("GetSecureUid", userId, retCode);
94         return false;
95     }
96     std::unique_lock<std::mutex> lock(iamMutex_);
97     iamCon_.wait_for(lock, std::chrono::seconds(GET_SEC_TIMEOUT), [this] {
98         return (this->secureUidStatus_ == SUCCESS);
99     });
100     if (secureUidStatus_ == FAILED) {
101         LOGE("Get secure uid failed, use default !");
102     }
103     secureUid = secCallback->GetSecureUid();
104     auto delay = StorageService::StorageRadar::ReportDuration("IAM: GET SECURE UID",
105         startTime, StorageService::DEFAULT_DELAY_TIME_THRESH, userId);
106     LOGI("SD_DURATION: IAM: GET SECUR UID, delay time = %{public}s", delay.c_str());
107 #else
108     LOGI("iam not support, use default !");
109     secureUid = { 0 };
110 #endif
111     LOGI("finish");
112     return true;
113 }
114 
GetSecUserInfo(uint32_t userId,UserIam::UserAuth::SecUserInfo & info)115 bool IamClient::GetSecUserInfo(uint32_t userId, UserIam::UserAuth::SecUserInfo &info)
116 {
117     LOGI("enter");
118 #ifdef USER_AUTH_FRAMEWORK
119     LOGI("Get SecUserInfo real !");
120     auto startTime = StorageService::StorageRadar::RecordCurrentTime();
121     secUserInfoState_ = SEC_USER_INFO_FAILED;
122     std::shared_ptr<UserEnrollCallback> userEnrollCallback = std::make_shared<UserEnrollCallback>();
123     int32_t retCode = UserIam::UserAuth::UserIdmClient::GetInstance().GetSecUserInfo(userId, userEnrollCallback);
124     if (retCode != UserIam::UserAuth::ResultCode::SUCCESS && retCode != UserIam::UserAuth::ResultCode::NOT_ENROLLED &&
125         retCode != UserIam::UserAuth::ResultCode::GENERAL_ERROR) {
126         for (int i = 0; i < IAM_MAX_RETRY_TIME; ++i) {
127             usleep(IAM_RETRY_INTERVAL_MS);
128             retCode = UserIam::UserAuth::UserIdmClient::GetInstance().GetSecUserInfo(userId, userEnrollCallback);
129             LOGE("GetSecureUid has retry %{public}d times, retryRet %{public}d", i, retCode);
130             if (retCode == UserIam::UserAuth::ResultCode::SUCCESS ||
131                 retCode == UserIam::UserAuth::ResultCode::NOT_ENROLLED ||
132                 retCode == UserIam::UserAuth::ResultCode::GENERAL_ERROR) {
133                 break;
134             }
135         }
136     }
137     if (retCode != UserIam::UserAuth::ResultCode::SUCCESS && retCode != UserIam::UserAuth::ResultCode::NOT_ENROLLED &&
138         retCode != UserIam::UserAuth::ResultCode::GENERAL_ERROR) {
139         LOGE("Get SecUserInfo failed !");
140         return false;
141     }
142     std::unique_lock<std::mutex> lock(iamMutex_);
143     iamCon_.wait_for(lock, std::chrono::seconds(GET_SEC_TIMEOUT),
144                      [this] { return (this->secUserInfoState_ == SEC_USER_INFO_SUCCESS); });
145     if (secUserInfoState_ == SEC_USER_INFO_FAILED) {
146         LOGE("Get SecUserInfo failed, use default !");
147     }
148     info = userEnrollCallback->GetSecUserInfo();
149     auto delay = StorageService::StorageRadar::ReportDuration("IAM: GET SECURE USER INFO",
150         startTime, StorageService::DEFAULT_DELAY_TIME_THRESH, userId);
151     LOGI("SD_DURATION: IAM: GET SECURE USER INFO, delay time = %{public}s", delay.c_str());
152 #else
153     LOGI("iam not support, use default !");
154     info = {};
155 #endif
156     LOGI("finish");
157     return true;
158 }
159 
HasFaceFinger(uint32_t userId,bool & isExist)160 int IamClient::HasFaceFinger(uint32_t userId, bool &isExist)
161 {
162     isExist = false;
163     UserIam::UserAuth::SecUserInfo info;
164     if (!GetSecUserInfo(userId, info)) {
165         LOGE("Get SecUserInfo failed!");
166         return -ENOENT;
167     }
168     std::vector<UserIam::UserAuth::EnrolledInfo> enrollInfo = info.enrolledInfo;
169     for (auto &item : enrollInfo) {
170         LOGI("EnrollInfo authType is : %{public}d", item.authType);
171         if (item.authType == UserIam::UserAuth::FACE || item.authType == UserIam::UserAuth::FINGERPRINT) {
172             LOGI("The user: %{public}d have authType: %{public}d", userId, item.authType);
173             isExist = true;
174             return 0;
175         }
176     }
177     LOGI("The Face And FingerPrint are not exist !");
178     return 0;
179 }
180 
HasPinProtect(uint32_t userId)181 bool IamClient::HasPinProtect(uint32_t userId)
182 {
183     UserIam::UserAuth::SecUserInfo info;
184     if (!GetSecUserInfo(userId, info)) {
185         LOGE("Get SecUserInfo failed!");
186         return false;
187     }
188     std::vector<UserIam::UserAuth::EnrolledInfo> enrollInfo = info.enrolledInfo;
189     for (auto &item : enrollInfo) {
190         if (item.authType == UserIam::UserAuth::PIN) {
191             LOGI("The device have pin protect for userId = %{public}d.", userId);
192             return true;
193         }
194     }
195     LOGI("The device has no pin protect for userId = %{public}d.", userId);
196     return false;
197 }
198 
NotifyGetSecUserInfo()199 int32_t IamClient::NotifyGetSecUserInfo()
200 {
201     std::lock_guard<std::mutex> lock(iamMutex_);
202     secUserInfoState_ = SEC_USER_INFO_SUCCESS;
203     iamCon_.notify_one();
204     return 0;
205 }
206 
NotifyGetSecureUid()207 int32_t IamClient::NotifyGetSecureUid()
208 {
209     std::lock_guard<std::mutex> lock(iamMutex_);
210     secureUidStatus_ = SUCCESS;
211     iamCon_.notify_one();
212     return 0;
213 }
214 } // namespace StorageDaemon
215 } // namespace HOHS
216