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