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 secureUidStatus_ = FAILED;
74 std::shared_ptr<UserSecCallback> secCallback = std::make_shared<UserSecCallback>();
75 int32_t retCode = UserIam::UserAuth::UserIdmClient::GetInstance().GetSecUserInfo(userId, secCallback);
76 if (retCode != UserIam::UserAuth::ResultCode::SUCCESS && retCode != UserIam::UserAuth::ResultCode::NOT_ENROLLED &&
77 retCode != UserIam::UserAuth::ResultCode::GENERAL_ERROR) {
78 for (int i = 0; i < IAM_MAX_RETRY_TIME; ++i) {
79 usleep(IAM_RETRY_INTERVAL_MS);
80 retCode = UserIam::UserAuth::UserIdmClient::GetInstance().GetSecUserInfo(userId, secCallback);
81 LOGE("GetSecureUid has retry %{public}d times, retryRet %{public}d", i, retCode);
82 if (retCode == UserIam::UserAuth::ResultCode::SUCCESS ||
83 retCode == UserIam::UserAuth::ResultCode::NOT_ENROLLED ||
84 retCode == UserIam::UserAuth::ResultCode::GENERAL_ERROR) {
85 break;
86 }
87 }
88 }
89 if (retCode != UserIam::UserAuth::ResultCode::SUCCESS && retCode != UserIam::UserAuth::ResultCode::NOT_ENROLLED &&
90 retCode != UserIam::UserAuth::ResultCode::GENERAL_ERROR) {
91 LOGE("Get secure uid failed !");
92 StorageRadar::ReportIamResult("GetSecureUid", userId, retCode);
93 return false;
94 }
95 std::unique_lock<std::mutex> lock(iamMutex_);
96 iamCon_.wait_for(lock, std::chrono::seconds(GET_SEC_TIMEOUT), [this] {
97 return (this->secureUidStatus_ == SUCCESS);
98 });
99 if (secureUidStatus_ == FAILED) {
100 LOGE("Get secure uid failed, use default !");
101 }
102 secureUid = secCallback->GetSecureUid();
103 #else
104 LOGI("iam not support, use default !");
105 secureUid = { 0 };
106 #endif
107 LOGI("finish");
108 return true;
109 }
110
GetSecUserInfo(uint32_t userId,UserIam::UserAuth::SecUserInfo & info)111 bool IamClient::GetSecUserInfo(uint32_t userId, UserIam::UserAuth::SecUserInfo &info)
112 {
113 LOGI("enter");
114 #ifdef USER_AUTH_FRAMEWORK
115 LOGI("Get SecUserInfo real !");
116 secUserInfoState_ = SEC_USER_INFO_FAILED;
117 std::shared_ptr<UserEnrollCallback> userEnrollCallback = std::make_shared<UserEnrollCallback>();
118 int32_t retCode = UserIam::UserAuth::UserIdmClient::GetInstance().GetSecUserInfo(userId, userEnrollCallback);
119 if (retCode != UserIam::UserAuth::ResultCode::SUCCESS && retCode != UserIam::UserAuth::ResultCode::NOT_ENROLLED &&
120 retCode != UserIam::UserAuth::ResultCode::GENERAL_ERROR) {
121 for (int i = 0; i < IAM_MAX_RETRY_TIME; ++i) {
122 usleep(IAM_RETRY_INTERVAL_MS);
123 retCode = UserIam::UserAuth::UserIdmClient::GetInstance().GetSecUserInfo(userId, userEnrollCallback);
124 LOGE("GetSecureUid has retry %{public}d times, retryRet %{public}d", i, retCode);
125 if (retCode == UserIam::UserAuth::ResultCode::SUCCESS ||
126 retCode == UserIam::UserAuth::ResultCode::NOT_ENROLLED ||
127 retCode == UserIam::UserAuth::ResultCode::GENERAL_ERROR) {
128 break;
129 }
130 }
131 }
132 if (retCode != UserIam::UserAuth::ResultCode::SUCCESS && retCode != UserIam::UserAuth::ResultCode::NOT_ENROLLED &&
133 retCode != UserIam::UserAuth::ResultCode::GENERAL_ERROR) {
134 LOGE("Get SecUserInfo failed !");
135 return false;
136 }
137 std::unique_lock<std::mutex> lock(iamMutex_);
138 iamCon_.wait_for(lock, std::chrono::seconds(GET_SEC_TIMEOUT),
139 [this] { return (this->secUserInfoState_ == SEC_USER_INFO_SUCCESS); });
140 if (secUserInfoState_ == SEC_USER_INFO_FAILED) {
141 LOGE("Get SecUserInfo failed, use default !");
142 }
143 info = userEnrollCallback->GetSecUserInfo();
144 #else
145 LOGI("iam not support, use default !");
146 info = {};
147 #endif
148 LOGI("finish");
149 return true;
150 }
151
HasFaceFinger(uint32_t userId,bool & isExist)152 int IamClient::HasFaceFinger(uint32_t userId, bool &isExist)
153 {
154 isExist = false;
155 UserIam::UserAuth::SecUserInfo info;
156 if (!GetSecUserInfo(userId, info)) {
157 LOGE("Get SecUserInfo failed!");
158 return -ENOENT;
159 }
160 std::vector<UserIam::UserAuth::EnrolledInfo> enrollInfo = info.enrolledInfo;
161 for (auto &item : enrollInfo) {
162 LOGI("EnrollInfo authType is : %{public}d", item.authType);
163 if (item.authType == UserIam::UserAuth::FACE || item.authType == UserIam::UserAuth::FINGERPRINT) {
164 LOGI("The user: %{public}d have authType: %{public}d", userId, item.authType);
165 isExist = true;
166 return 0;
167 }
168 }
169 LOGI("The Face And FingerPrint are not exist !");
170 return 0;
171 }
172
HasPinProtect(uint32_t userId)173 bool IamClient::HasPinProtect(uint32_t userId)
174 {
175 UserIam::UserAuth::SecUserInfo info;
176 if (!GetSecUserInfo(userId, info)) {
177 LOGE("Get SecUserInfo failed!");
178 return false;
179 }
180 std::vector<UserIam::UserAuth::EnrolledInfo> enrollInfo = info.enrolledInfo;
181 for (auto &item : enrollInfo) {
182 if (item.authType == UserIam::UserAuth::PIN) {
183 LOGI("The device have pin protect for userId = %{public}d.", userId);
184 return true;
185 }
186 }
187 LOGI("The device has no pin protect for userId = %{public}d.", userId);
188 return false;
189 }
190
NotifyGetSecUserInfo()191 int32_t IamClient::NotifyGetSecUserInfo()
192 {
193 std::lock_guard<std::mutex> lock(iamMutex_);
194 secUserInfoState_ = SEC_USER_INFO_SUCCESS;
195 iamCon_.notify_one();
196 return 0;
197 }
198
NotifyGetSecureUid()199 int32_t IamClient::NotifyGetSecureUid()
200 {
201 std::lock_guard<std::mutex> lock(iamMutex_);
202 secureUidStatus_ = SUCCESS;
203 iamCon_.notify_one();
204 return 0;
205 }
206 } // namespace StorageDaemon
207 } // namespace HOHS