1 /*
2 * Copyright (c) 2022-2023 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 "user_auth_client_impl.h"
17
18 #include "system_ability_definition.h"
19
20 #include "auth_common.h"
21 #include "callback_manager.h"
22 #include "iam_check.h"
23 #include "iam_logger.h"
24 #include "iam_ptr.h"
25 #include "ipc_client_utils.h"
26 #include "user_auth_callback_service.h"
27 #include "widget_callback_service.h"
28
29 #define LOG_LABEL UserIam::Common::LABEL_USER_AUTH_SDK
30 namespace OHOS {
31 namespace UserIam {
32 namespace UserAuth {
33 namespace {
34 class NorthAuthenticationCallback : public AuthenticationCallback, public NoCopyable {
35 public:
36 explicit NorthAuthenticationCallback(std::shared_ptr<AuthenticationCallback> innerCallback);
37 void OnAcquireInfo(int32_t module, uint32_t acquireInfo, const Attributes &extraInfo) override;
38 void OnResult(int32_t result, const Attributes &extraInfo) override;
39
40 private:
41 std::shared_ptr<AuthenticationCallback> innerCallback_ = nullptr;
42 };
43
NorthAuthenticationCallback(std::shared_ptr<AuthenticationCallback> innerCallback)44 NorthAuthenticationCallback::NorthAuthenticationCallback(std::shared_ptr<AuthenticationCallback> innerCallback)
45 : innerCallback_(innerCallback) {};
46
OnAcquireInfo(int32_t module,uint32_t acquireInfo,const Attributes & extraInfo)47 void NorthAuthenticationCallback::OnAcquireInfo(int32_t module, uint32_t acquireInfo, const Attributes &extraInfo)
48 {
49 if (innerCallback_ == nullptr) {
50 IAM_LOGE("callback is nullptr");
51 return;
52 }
53
54 if (module == AuthType::FACE) {
55 if (acquireInfo == 0 || acquireInfo > FACE_AUTH_TIP_MAX) {
56 IAM_LOGI("skip undefined face auth tip %{public}u", acquireInfo);
57 return;
58 }
59 } else if (module == AuthType::FINGERPRINT) {
60 if (acquireInfo > FINGERPRINT_AUTH_TIP_MAX) {
61 IAM_LOGI("skip undefined fingerprint auth tip %{public}u", acquireInfo);
62 return;
63 }
64 }
65
66 innerCallback_->OnAcquireInfo(module, acquireInfo, extraInfo);
67 }
68
OnResult(int32_t result,const Attributes & extraInfo)69 void NorthAuthenticationCallback::OnResult(int32_t result, const Attributes &extraInfo)
70 {
71 if (innerCallback_ == nullptr) {
72 IAM_LOGE("callback is nullptr");
73 return;
74 }
75
76 innerCallback_->OnResult(result, extraInfo);
77 }
78 } // namespace
79
GetAvailableStatus(AuthType authType,AuthTrustLevel authTrustLevel)80 int32_t UserAuthClientImpl::GetAvailableStatus(AuthType authType, AuthTrustLevel authTrustLevel)
81 {
82 return GetAvailableStatus(INT32_MAX, authType, authTrustLevel);
83 }
84
GetAvailableStatus(int32_t apiVersion,AuthType authType,AuthTrustLevel authTrustLevel)85 int32_t UserAuthClientImpl::GetAvailableStatus(int32_t apiVersion, AuthType authType, AuthTrustLevel authTrustLevel)
86 {
87 auto proxy = GetProxy();
88 if (!proxy) {
89 IAM_LOGE("proxy is nullptr");
90 return GENERAL_ERROR;
91 }
92
93 return proxy->GetAvailableStatus(apiVersion, authType, authTrustLevel);
94 }
95
GetProperty(int32_t userId,const GetPropertyRequest & request,const std::shared_ptr<GetPropCallback> & callback)96 void UserAuthClientImpl::GetProperty(int32_t userId, const GetPropertyRequest &request,
97 const std::shared_ptr<GetPropCallback> &callback)
98 {
99 if (!callback) {
100 IAM_LOGE("get prop callback is nullptr");
101 return;
102 }
103
104 auto proxy = GetProxy();
105 if (!proxy) {
106 IAM_LOGE("proxy is nullptr");
107 Attributes extraInfo;
108 callback->OnResult(GENERAL_ERROR, extraInfo);
109 return;
110 }
111
112 sptr<GetExecutorPropertyCallbackInterface> wrapper(
113 new (std::nothrow) GetExecutorPropertyCallbackService(callback));
114 if (wrapper == nullptr) {
115 IAM_LOGE("failed to create wrapper");
116 Attributes extraInfo;
117 callback->OnResult(GENERAL_ERROR, extraInfo);
118 return;
119 }
120 proxy->GetProperty(userId, request.authType, request.keys, wrapper);
121 }
122
SetPropertyInner(int32_t userId,const SetPropertyRequest & request,const std::shared_ptr<SetPropCallback> & callback)123 ResultCode UserAuthClientImpl::SetPropertyInner(int32_t userId, const SetPropertyRequest &request,
124 const std::shared_ptr<SetPropCallback> &callback)
125 {
126 auto proxy = GetProxy();
127 if (!proxy) {
128 IAM_LOGE("proxy is nullptr");
129 return GENERAL_ERROR;
130 }
131
132 auto keys = request.attrs.GetKeys();
133 IF_FALSE_LOGE_AND_RETURN_VAL(keys.size() == 1, GENERAL_ERROR);
134
135 Attributes::AttributeKey key = keys[0];
136 Attributes attr;
137
138 std::vector<uint8_t> extraInfo;
139 bool getArrayRet = request.attrs.GetUint8ArrayValue(static_cast<Attributes::AttributeKey>(key), extraInfo);
140 IF_FALSE_LOGE_AND_RETURN_VAL(getArrayRet, GENERAL_ERROR);
141
142 bool setModeRet = attr.SetUint32Value(Attributes::ATTR_PROPERTY_MODE, static_cast<uint32_t>(key));
143 IF_FALSE_LOGE_AND_RETURN_VAL(setModeRet, GENERAL_ERROR);
144
145 bool setArrayRet = attr.SetUint8ArrayValue(Attributes::ATTR_EXTRA_INFO, extraInfo);
146 IF_FALSE_LOGE_AND_RETURN_VAL(setArrayRet, GENERAL_ERROR);
147
148 sptr<SetExecutorPropertyCallbackInterface> wrapper(
149 new (std::nothrow) SetExecutorPropertyCallbackService(callback));
150 IF_FALSE_LOGE_AND_RETURN_VAL(wrapper != nullptr, GENERAL_ERROR);
151 proxy->SetProperty(userId, request.authType, attr, wrapper);
152 return SUCCESS;
153 }
154
SetProperty(int32_t userId,const SetPropertyRequest & request,const std::shared_ptr<SetPropCallback> & callback)155 void UserAuthClientImpl::SetProperty(int32_t userId, const SetPropertyRequest &request,
156 const std::shared_ptr<SetPropCallback> &callback)
157 {
158 if (!callback) {
159 IAM_LOGE("set prop callback is nullptr");
160 return;
161 }
162
163 ResultCode result = SetPropertyInner(userId, request, callback);
164 if (result != SUCCESS) {
165 IAM_LOGE("result is not success");
166 Attributes retExtraInfo;
167 callback->OnResult(GENERAL_ERROR, retExtraInfo);
168 return;
169 }
170 }
171
BeginAuthentication(int32_t userId,const std::vector<uint8_t> & challenge,AuthType authType,AuthTrustLevel atl,const std::shared_ptr<AuthenticationCallback> & callback)172 uint64_t UserAuthClientImpl::BeginAuthentication(int32_t userId, const std::vector<uint8_t> &challenge,
173 AuthType authType, AuthTrustLevel atl, const std::shared_ptr<AuthenticationCallback> &callback)
174 {
175 if (!callback) {
176 IAM_LOGE("auth callback is nullptr");
177 return INVALID_SESSION_ID;
178 }
179
180 auto proxy = GetProxy();
181 if (!proxy) {
182 IAM_LOGE("proxy is nullptr");
183 Attributes extraInfo;
184 callback->OnResult(GENERAL_ERROR, extraInfo);
185 return INVALID_SESSION_ID;
186 }
187
188 sptr<UserAuthCallbackInterface> wrapper(new (std::nothrow) UserAuthCallbackService(callback));
189 if (wrapper == nullptr) {
190 IAM_LOGE("failed to create wrapper");
191 Attributes extraInfo;
192 callback->OnResult(GENERAL_ERROR, extraInfo);
193 return INVALID_SESSION_ID;
194 }
195 return proxy->AuthUser(userId, challenge, authType, atl, wrapper);
196 }
197
BeginNorthAuthentication(int32_t apiVersion,const std::vector<uint8_t> & challenge,AuthType authType,AuthTrustLevel atl,const std::shared_ptr<AuthenticationCallback> & callback)198 uint64_t UserAuthClientImpl::BeginNorthAuthentication(int32_t apiVersion, const std::vector<uint8_t> &challenge,
199 AuthType authType, AuthTrustLevel atl, const std::shared_ptr<AuthenticationCallback> &callback)
200 {
201 if (!callback) {
202 IAM_LOGE("auth callback is nullptr");
203 return INVALID_SESSION_ID;
204 }
205
206 auto northCallback = Common::MakeShared<NorthAuthenticationCallback>(callback);
207 if (!northCallback) {
208 IAM_LOGE("auth callback is nullptr");
209 Attributes extraInfo;
210 callback->OnResult(GENERAL_ERROR, extraInfo);
211 return INVALID_SESSION_ID;
212 }
213
214 auto proxy = GetProxy();
215 if (!proxy) {
216 IAM_LOGE("proxy is nullptr");
217 Attributes extraInfo;
218 callback->OnResult(GENERAL_ERROR, extraInfo);
219 return INVALID_SESSION_ID;
220 }
221
222 sptr<UserAuthCallbackInterface> wrapper(new (std::nothrow) UserAuthCallbackService(northCallback));
223 if (wrapper == nullptr) {
224 IAM_LOGE("failed to create wrapper");
225 Attributes extraInfo;
226 callback->OnResult(GENERAL_ERROR, extraInfo);
227 return INVALID_SESSION_ID;
228 }
229 return proxy->Auth(apiVersion, challenge, authType, atl, wrapper);
230 }
231
CancelAuthentication(uint64_t contextId)232 int32_t UserAuthClientImpl::CancelAuthentication(uint64_t contextId)
233 {
234 auto proxy = GetProxy();
235 if (!proxy) {
236 IAM_LOGE("proxy is nullptr");
237 return GENERAL_ERROR;
238 }
239
240 return proxy->CancelAuthOrIdentify(contextId);
241 }
242
BeginIdentification(const std::vector<uint8_t> & challenge,AuthType authType,const std::shared_ptr<IdentificationCallback> & callback)243 uint64_t UserAuthClientImpl::BeginIdentification(const std::vector<uint8_t> &challenge, AuthType authType,
244 const std::shared_ptr<IdentificationCallback> &callback)
245 {
246 if (!callback) {
247 IAM_LOGE("identify callback is nullptr");
248 return INVALID_SESSION_ID;
249 }
250
251 auto proxy = GetProxy();
252 if (!proxy) {
253 IAM_LOGE("proxy is nullptr");
254 Attributes extraInfo;
255 callback->OnResult(GENERAL_ERROR, extraInfo);
256 return INVALID_SESSION_ID;
257 }
258
259 sptr<UserAuthCallbackInterface> wrapper(new (std::nothrow) UserAuthCallbackService(callback));
260 if (wrapper == nullptr) {
261 IAM_LOGE("failed to create wrapper");
262 Attributes extraInfo;
263 callback->OnResult(GENERAL_ERROR, extraInfo);
264 return INVALID_SESSION_ID;
265 }
266 return proxy->Identify(challenge, authType, wrapper);
267 }
268
CancelIdentification(uint64_t contextId)269 int32_t UserAuthClientImpl::CancelIdentification(uint64_t contextId)
270 {
271 auto proxy = GetProxy();
272 if (!proxy) {
273 IAM_LOGE("proxy is nullptr");
274 return GENERAL_ERROR;
275 }
276
277 return proxy->CancelAuthOrIdentify(contextId);
278 }
279
GetVersion(int32_t & version)280 int32_t UserAuthClientImpl::GetVersion(int32_t &version)
281 {
282 auto proxy = GetProxy();
283 if (!proxy) {
284 IAM_LOGE("proxy is nullptr");
285 return GENERAL_ERROR;
286 }
287
288 return proxy->GetVersion(version);
289 }
290
GetProxy()291 sptr<UserAuthInterface> UserAuthClientImpl::GetProxy()
292 {
293 IAM_LOGI("start");
294 std::lock_guard<std::mutex> lock(mutex_);
295 if (proxy_ != nullptr) {
296 return proxy_;
297 }
298 sptr<IRemoteObject> obj = IpcClientUtils::GetRemoteObject(SUBSYS_USERIAM_SYS_ABILITY_USERAUTH);
299 if (obj == nullptr) {
300 IAM_LOGE("remote object is null");
301 return proxy_;
302 }
303 sptr<IRemoteObject::DeathRecipient> dr(new (std::nothrow) UserAuthImplDeathRecipient());
304 if ((dr == nullptr) || (obj->IsProxyObject() && !obj->AddDeathRecipient(dr))) {
305 IAM_LOGE("add death recipient fail");
306 return proxy_;
307 }
308
309 proxy_ = iface_cast<UserAuthInterface>(obj);
310 deathRecipient_ = dr;
311 return proxy_;
312 }
313
ResetProxy(const wptr<IRemoteObject> & remote)314 void UserAuthClientImpl::ResetProxy(const wptr<IRemoteObject> &remote)
315 {
316 IAM_LOGI("start");
317 std::lock_guard<std::mutex> lock(mutex_);
318 if (proxy_ == nullptr) {
319 IAM_LOGE("proxy_ is null");
320 return;
321 }
322 auto serviceRemote = proxy_->AsObject();
323 if ((serviceRemote != nullptr) && (serviceRemote == remote.promote())) {
324 IAM_LOGI("need reset");
325 serviceRemote->RemoveDeathRecipient(deathRecipient_);
326 proxy_ = nullptr;
327 deathRecipient_ = nullptr;
328 }
329 IAM_LOGI("end reset proxy");
330 }
331
OnRemoteDied(const wptr<IRemoteObject> & remote)332 void UserAuthClientImpl::UserAuthImplDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
333 {
334 IAM_LOGI("start");
335 if (remote == nullptr) {
336 IAM_LOGE("remote is nullptr");
337 return;
338 }
339 CallbackManager::GetInstance().OnServiceDeath();
340 UserAuthClientImpl::Instance().ResetProxy(remote);
341 }
342
Instance()343 UserAuthClientImpl &UserAuthClientImpl::Instance()
344 {
345 static UserAuthClientImpl impl;
346 return impl;
347 }
348
GetInstance()349 UserAuthClient &UserAuthClient::GetInstance()
350 {
351 return UserAuthClientImpl::Instance();
352 }
353
BeginWidgetAuth(int32_t apiVersion,const AuthParam & authParam,const WidgetParam & widgetParam,const std::shared_ptr<AuthenticationCallback> & callback)354 uint64_t UserAuthClientImpl::BeginWidgetAuth(int32_t apiVersion, const AuthParam &authParam,
355 const WidgetParam &widgetParam, const std::shared_ptr<AuthenticationCallback> &callback)
356 {
357 // parameter verification
358 if (!callback) {
359 IAM_LOGE("auth callback is nullptr");
360 return INVALID_SESSION_ID;
361 }
362 auto proxy = GetProxy();
363 if (!proxy) {
364 IAM_LOGE("proxy is nullptr");
365 Attributes extraInfo;
366 callback->OnResult(static_cast<int32_t>(ResultCode::GENERAL_ERROR), extraInfo);
367 return INVALID_SESSION_ID;
368 }
369
370 sptr<UserAuthCallbackInterface> wrapper(new (std::nothrow) UserAuthCallbackService(callback));
371 if (wrapper == nullptr) {
372 IAM_LOGE("failed to create wrapper");
373 Attributes extraInfo;
374 callback->OnResult(static_cast<int32_t>(ResultCode::GENERAL_ERROR), extraInfo);
375 return INVALID_SESSION_ID;
376 }
377 return proxy->AuthWidget(apiVersion, authParam, widgetParam, wrapper);
378 }
379
SetWidgetCallback(int32_t version,const std::shared_ptr<IUserAuthWidgetCallback> & callback)380 int32_t UserAuthClientImpl::SetWidgetCallback(int32_t version, const std::shared_ptr<IUserAuthWidgetCallback> &callback)
381 {
382 if (!callback) {
383 IAM_LOGE("widget callback is nullptr");
384 return GENERAL_ERROR;
385 }
386 auto proxy = GetProxy();
387 if (!proxy) {
388 IAM_LOGE("proxy is nullptr");
389 return GENERAL_ERROR;
390 }
391
392 sptr<WidgetCallbackInterface> wrapper(new (std::nothrow) WidgetCallbackService(callback));
393 if (wrapper == nullptr) {
394 IAM_LOGE("failed to create wrapper");
395 return GENERAL_ERROR;
396 }
397 return proxy->RegisterWidgetCallback(version, wrapper);
398 }
399
Notice(NoticeType noticeType,const std::string & eventData)400 int32_t UserAuthClientImpl::Notice(NoticeType noticeType, const std::string &eventData)
401 {
402 auto proxy = GetProxy();
403 if (!proxy) {
404 IAM_LOGE("proxy is nullptr");
405 return GENERAL_ERROR;
406 }
407 IAM_LOGI("UserAuthClientImpl::Notice noticeType:%{public}d, eventDat:%{public}s",
408 static_cast<int32_t>(noticeType), eventData.c_str());
409 return proxy->Notice(noticeType, eventData);
410 }
411 } // namespace UserAuth
412 } // namespace UserIam
413 } // namespace OHOS
414