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 "framework_executor_callback.h"
17
18 #include <mutex>
19 #include <sstream>
20
21 #include "abandon_command.h"
22 #include "auth_command.h"
23 #include "collect_command.h"
24 #include "custom_command.h"
25 #include "enroll_command.h"
26 #include "hisysevent_adapter.h"
27 #include "iam_check.h"
28 #include "iam_defines.h"
29 #include "iam_hitrace_helper.h"
30 #include "iam_logger.h"
31 #include "iam_mem.h"
32 #include "iam_para2str.h"
33 #include "iam_ptr.h"
34 #include "identify_command.h"
35
36 #define LOG_TAG "USER_AUTH_EXECUTOR"
37
38 namespace OHOS {
39 namespace UserIam {
40 namespace UserAuth {
FrameworkExecutorCallback(std::weak_ptr<Executor> executor)41 FrameworkExecutorCallback::FrameworkExecutorCallback(std::weak_ptr<Executor> executor) : executor_(executor)
42 {
43 uint32_t callbackId = GenerateExecutorCallbackId();
44 std::ostringstream ss;
45 ss << "ExecutorCallback(Id:" << callbackId << ")";
46 description_ = ss.str();
47 }
48
OnBeginExecute(uint64_t scheduleId,const std::vector<uint8_t> & publicKey,const Attributes & commandAttrs)49 int32_t FrameworkExecutorCallback::OnBeginExecute(uint64_t scheduleId, const std::vector<uint8_t> &publicKey,
50 const Attributes &commandAttrs)
51 {
52 auto pk(publicKey);
53
54 return OnBeginExecuteInner(scheduleId, pk, commandAttrs);
55 }
56
OnBeginExecuteInner(uint64_t scheduleId,std::vector<uint8_t> & publicKey,const Attributes & commandAttrs)57 ResultCode FrameworkExecutorCallback::OnBeginExecuteInner(uint64_t scheduleId, std::vector<uint8_t> &publicKey,
58 const Attributes &commandAttrs)
59 {
60 static_cast<void>(publicKey);
61 int32_t commandId = 0;
62 bool getScheduleModeRet =
63 commandAttrs.GetInt32Value(Attributes::ATTR_SCHEDULE_MODE, commandId);
64 IF_FALSE_LOGE_AND_RETURN_VAL(getScheduleModeRet == true, ResultCode::GENERAL_ERROR);
65
66 IAM_LOGD("%{public}s start process cmd %{public}u", GetDescription(), commandId);
67 ResultCode ret = ResultCode::GENERAL_ERROR;
68 switch (commandId) {
69 case ENROLL:
70 ret = ProcessEnrollCommand(scheduleId, commandAttrs);
71 break;
72 case AUTH:
73 ret = ProcessAuthCommand(scheduleId, commandAttrs);
74 break;
75 case IDENTIFY:
76 ret = ProcessIdentifyCommand(scheduleId, commandAttrs);
77 break;
78 case ABANDON:
79 ret = ProcessAbandonCommand(scheduleId, commandAttrs);
80 break;
81 default:
82 IAM_LOGE("command id %{public}u is not supported", commandId);
83 }
84
85 IAM_LOGD("command id = %{public}u ret = %{public}d", commandId, ret);
86 return ret;
87 }
88
OnEndExecute(uint64_t scheduleId,const Attributes & commandAttrs)89 int32_t FrameworkExecutorCallback::OnEndExecute(uint64_t scheduleId, const Attributes &commandAttrs)
90 {
91 return OnEndExecuteInner(scheduleId, commandAttrs);
92 }
93
OnEndExecuteInner(uint64_t scheduleId,const Attributes & consumerAttr)94 ResultCode FrameworkExecutorCallback::OnEndExecuteInner(uint64_t scheduleId, const Attributes &consumerAttr)
95 {
96 ResultCode ret = ProcessCancelCommand(scheduleId);
97 IAM_LOGI("%{public}s cancel scheduleId %{public}s ret %{public}d", GetDescription(),
98 GET_MASKED_STRING(scheduleId).c_str(), ret);
99 return ret;
100 }
101
OnMessengerReady(const std::shared_ptr<ExecutorMessenger> & messenger,const std::vector<uint8_t> & publicKey,const std::vector<uint64_t> & templateIdList)102 void FrameworkExecutorCallback::OnMessengerReady(const std::shared_ptr<ExecutorMessenger> &messenger,
103 const std::vector<uint8_t> &publicKey, const std::vector<uint64_t> &templateIdList)
104 {
105 IAM_LOGD("%{public}s start", GetDescription());
106 std::lock_guard<std::recursive_mutex> lock(mutex_);
107 auto executor = executor_.lock();
108 if (executor == nullptr) {
109 IAM_LOGE("executor has been released, process failed");
110 return;
111 }
112 auto hdi = executor->GetExecutorHdi();
113 IF_FALSE_LOGE_AND_RETURN(hdi != nullptr);
114 executorMessenger_ = messenger;
115 std::vector<uint8_t> extraInfo;
116 hdi->OnRegisterFinish(templateIdList, publicKey, extraInfo);
117 }
118
OnSetProperty(const Attributes & properties)119 int32_t FrameworkExecutorCallback::OnSetProperty(const Attributes &properties)
120 {
121 return OnSetPropertyInner(properties);
122 }
123
OnSetPropertyInner(const Attributes & properties)124 ResultCode FrameworkExecutorCallback::OnSetPropertyInner(const Attributes &properties)
125 {
126 uint32_t commandId = 0;
127 bool getAuthPropertyModeRet =
128 properties.GetUint32Value(Attributes::ATTR_PROPERTY_MODE, commandId);
129 IF_FALSE_LOGE_AND_RETURN_VAL(getAuthPropertyModeRet == true, ResultCode::GENERAL_ERROR);
130 IAM_LOGD("%{public}s start process cmd %{public}u", GetDescription(), commandId);
131 ResultCode ret;
132 if (commandId == PROPERTY_MODE_DEL) {
133 ret = ProcessDeleteTemplateCommand(properties);
134 } else if (commandId == PROPERTY_MODE_SET_CACHED_TEMPLATES) {
135 ret = ProcessSetCachedTemplates(properties);
136 } else if (commandId == PROPERTY_MODE_NOTIFY_COLLECTOR_READY) {
137 ret = ProcessNotifyExecutorReady(properties);
138 } else {
139 ret = ProcessCustomCommand(properties);
140 }
141 IAM_LOGI("command id = %{public}u ret = %{public}d", commandId, ret);
142 return ret;
143 }
144
OnGetProperty(const Attributes & conditions,Attributes & results)145 int32_t FrameworkExecutorCallback::OnGetProperty(const Attributes &conditions, Attributes &results)
146 {
147 auto cond = Common::MakeShared<Attributes>(conditions.Serialize());
148 auto values = Common::MakeShared<Attributes>(results.Serialize());
149 auto ret = OnGetPropertyInner(cond, values);
150 if (values) {
151 results = std::move(*values);
152 }
153 return ret;
154 }
155
OnSendData(uint64_t scheduleId,const Attributes & data)156 int32_t FrameworkExecutorCallback::OnSendData(uint64_t scheduleId, const Attributes &data)
157 {
158 int32_t srcRole = 0;
159 bool getDestRoleRet = data.GetInt32Value(Attributes::ATTR_SRC_ROLE, srcRole);
160 IF_FALSE_LOGE_AND_RETURN_VAL(getDestRoleRet == true, ResultCode::GENERAL_ERROR);
161 std::vector<uint8_t> extraInfo;
162 bool getExtraInfoRet = data.GetUint8ArrayValue(Attributes::ATTR_EXTRA_INFO, extraInfo);
163 IF_FALSE_LOGE_AND_RETURN_VAL(getExtraInfoRet == true, ResultCode::GENERAL_ERROR);
164
165 auto executor = executor_.lock();
166 if (executor == nullptr) {
167 IAM_LOGE("executor has been released, process failed");
168 return ResultCode::GENERAL_ERROR;
169 }
170 auto hdi = executor->GetExecutorHdi();
171 IF_FALSE_LOGE_AND_RETURN_VAL(hdi != nullptr, ResultCode::GENERAL_ERROR);
172 return hdi->SendMessage(scheduleId, srcRole, extraInfo);
173 }
174
OnGetPropertyInner(std::shared_ptr<Attributes> conditions,std::shared_ptr<Attributes> values)175 ResultCode FrameworkExecutorCallback::OnGetPropertyInner(std::shared_ptr<Attributes> conditions,
176 std::shared_ptr<Attributes> values)
177 {
178 IAM_LOGD("%{public}s start", GetDescription());
179 IF_FALSE_LOGE_AND_RETURN_VAL(conditions != nullptr, ResultCode::GENERAL_ERROR);
180 IF_FALSE_LOGE_AND_RETURN_VAL(values != nullptr, ResultCode::GENERAL_ERROR);
181 uint32_t commandId = 0;
182 bool getAuthPropertyModeRet =
183 conditions->GetUint32Value(Attributes::ATTR_PROPERTY_MODE, commandId);
184 IF_FALSE_LOGE_AND_RETURN_VAL(getAuthPropertyModeRet == true, ResultCode::GENERAL_ERROR);
185 if (commandId != PROPERTY_MODE_GET) {
186 IAM_LOGE("command id not recognised");
187 return ResultCode::GENERAL_ERROR;
188 }
189
190 ResultCode ret = ProcessGetPropertyCommand(conditions, values);
191 IAM_LOGD("command id = %{public}u ret = %{public}d", commandId, ret);
192 return ret;
193 }
194
ProcessEnrollCommand(uint64_t scheduleId,const Attributes & properties)195 ResultCode FrameworkExecutorCallback::ProcessEnrollCommand(uint64_t scheduleId, const Attributes &properties)
196 {
197 std::lock_guard<std::recursive_mutex> lock(mutex_);
198 auto command = Common::MakeShared<EnrollCommand>(executor_, scheduleId, properties, executorMessenger_);
199 IF_FALSE_LOGE_AND_RETURN_VAL(command != nullptr, ResultCode::GENERAL_ERROR);
200 return command->StartProcess();
201 }
202
ProcessAuthCommand(uint64_t scheduleId,const Attributes & properties)203 ResultCode FrameworkExecutorCallback::ProcessAuthCommand(uint64_t scheduleId, const Attributes &properties)
204 {
205 std::lock_guard<std::recursive_mutex> lock(mutex_);
206 auto executor = executor_.lock();
207 if (executor == nullptr) {
208 IAM_LOGE("executor has been released, process failed");
209 return ResultCode::GENERAL_ERROR;
210 }
211
212 std::shared_ptr<AsyncCommandBase> command = nullptr;
213 if (executor->GetExecutorRole() == COLLECTOR) {
214 command = Common::MakeShared<CollectCommand>(executor_, scheduleId, properties, executorMessenger_);
215 } else {
216 command = Common::MakeShared<AuthCommand>(executor_, scheduleId, properties, executorMessenger_);
217 }
218 IF_FALSE_LOGE_AND_RETURN_VAL(command != nullptr, ResultCode::GENERAL_ERROR);
219 return command->StartProcess();
220 }
221
ProcessIdentifyCommand(uint64_t scheduleId,const Attributes & properties)222 ResultCode FrameworkExecutorCallback::ProcessIdentifyCommand(uint64_t scheduleId, const Attributes &properties)
223 {
224 std::lock_guard<std::recursive_mutex> lock(mutex_);
225 auto command = Common::MakeShared<IdentifyCommand>(executor_, scheduleId, properties, executorMessenger_);
226 IF_FALSE_LOGE_AND_RETURN_VAL(command != nullptr, ResultCode::GENERAL_ERROR);
227 return command->StartProcess();
228 }
229
ProcessCancelCommand(uint64_t scheduleId)230 ResultCode FrameworkExecutorCallback::ProcessCancelCommand(uint64_t scheduleId)
231 {
232 auto executor = executor_.lock();
233 if (executor == nullptr) {
234 IAM_LOGE("executor has been released, process failed");
235 return ResultCode::GENERAL_ERROR;
236 }
237 auto hdi = executor->GetExecutorHdi();
238 IF_FALSE_LOGE_AND_RETURN_VAL(hdi != nullptr, ResultCode::GENERAL_ERROR);
239 return hdi->Cancel(scheduleId);
240 }
241
ProcessDeleteTemplateCommand(const Attributes & properties)242 ResultCode FrameworkExecutorCallback::ProcessDeleteTemplateCommand(const Attributes &properties)
243 {
244 IAM_LOGI("start");
245 auto executor = executor_.lock();
246 if (executor == nullptr) {
247 IAM_LOGE("executor has been released, process failed");
248 return ResultCode::GENERAL_ERROR;
249 }
250 auto hdi = executor->GetExecutorHdi();
251 IF_FALSE_LOGE_AND_RETURN_VAL(hdi != nullptr, ResultCode::GENERAL_ERROR);
252 uint64_t templateId = 0;
253 bool getAuthTemplateIdRet = properties.GetUint64Value(Attributes::ATTR_TEMPLATE_ID, templateId);
254 IF_FALSE_LOGE_AND_RETURN_VAL(getAuthTemplateIdRet == true, ResultCode::GENERAL_ERROR);
255 std::vector<uint64_t> templateIdList;
256
257 templateIdList.push_back(templateId);
258 IamHitraceHelper traceHelper("hdi Delete");
259 ResultCode ret = hdi->Delete(templateIdList);
260 if (ret == ResultCode::SUCCESS) {
261 TemplateChangeTrace info = {};
262 info.changeType = TRACE_DELETE_CREDENTIAL;
263 std::string templateChangeReason = "";
264 properties.GetStringValue(Attributes::ATTR_TEMPLATE_CHANGE_REASON, templateChangeReason);
265 info.reason = templateChangeReason;
266 info.executorType = executor->GetAuthType();
267 UserIam::UserAuth::ReportSecurityTemplateChange(info);
268 }
269 return ret;
270 }
271
ProcessSetCachedTemplates(const Attributes & properties)272 ResultCode FrameworkExecutorCallback::ProcessSetCachedTemplates(const Attributes &properties)
273 {
274 IAM_LOGI("start");
275 auto executor = executor_.lock();
276 if (executor == nullptr) {
277 IAM_LOGE("executor has been released, process failed");
278 return ResultCode::GENERAL_ERROR;
279 }
280 auto hdi = executor->GetExecutorHdi();
281 IF_FALSE_LOGE_AND_RETURN_VAL(hdi != nullptr, ResultCode::GENERAL_ERROR);
282
283 std::vector<uint64_t> templateIdList;
284 bool getTemplateIdListRet = properties.GetUint64ArrayValue(Attributes::ATTR_TEMPLATE_ID_LIST, templateIdList);
285 IF_FALSE_LOGE_AND_RETURN_VAL(getTemplateIdListRet == true, ResultCode::GENERAL_ERROR);
286
287 return hdi->SetCachedTemplates(templateIdList);
288 }
289
ProcessNotifyExecutorReady(const Attributes & properties)290 ResultCode FrameworkExecutorCallback::ProcessNotifyExecutorReady(const Attributes &properties)
291 {
292 IAM_LOGI("start");
293 auto executor = executor_.lock();
294 if (executor == nullptr) {
295 IAM_LOGE("executor has been released, process failed");
296 return ResultCode::GENERAL_ERROR;
297 }
298
299 auto hdi = executor->GetExecutorHdi();
300 IF_FALSE_LOGE_AND_RETURN_VAL(hdi != nullptr, ResultCode::GENERAL_ERROR);
301
302 uint64_t scheduleId;
303 bool getScheduleIdRet = properties.GetUint64Value(Attributes::ATTR_SCHEDULE_ID, scheduleId);
304 IF_FALSE_LOGE_AND_RETURN_VAL(getScheduleIdRet == true, ResultCode::GENERAL_ERROR);
305
306 return hdi->NotifyCollectorReady(scheduleId);
307 }
308
ProcessCustomCommand(const Attributes & properties)309 ResultCode FrameworkExecutorCallback::ProcessCustomCommand(const Attributes &properties)
310 {
311 auto command = Common::MakeShared<CustomCommand>(executor_, properties);
312 IF_FALSE_LOGE_AND_RETURN_VAL(command != nullptr, ResultCode::GENERAL_ERROR);
313 ResultCode ret = command->StartProcess();
314 if (ret != ResultCode::SUCCESS) {
315 IAM_LOGE("start process command fail ret = %{public}d", ret);
316 return ret;
317 }
318
319 return command->GetResult();
320 }
321
ProcessGetPropertyCommand(std::shared_ptr<Attributes> conditions,std::shared_ptr<Attributes> values)322 ResultCode FrameworkExecutorCallback::ProcessGetPropertyCommand(std::shared_ptr<Attributes> conditions,
323 std::shared_ptr<Attributes> values)
324 {
325 IAM_LOGD("start");
326 IF_FALSE_LOGE_AND_RETURN_VAL(conditions != nullptr, ResultCode::GENERAL_ERROR);
327 IF_FALSE_LOGE_AND_RETURN_VAL(values != nullptr, ResultCode::GENERAL_ERROR);
328 auto executor = executor_.lock();
329 if (executor == nullptr) {
330 IAM_LOGE("executor has been released, process failed");
331 return ResultCode::GENERAL_ERROR;
332 }
333 auto hdi = executor->GetExecutorHdi();
334 IF_FALSE_LOGE_AND_RETURN_VAL(hdi != nullptr, ResultCode::GENERAL_ERROR);
335
336 std::vector<uint64_t> templateIdList;
337 bool getTemplateIdListRet = conditions->GetUint64ArrayValue(Attributes::ATTR_TEMPLATE_ID_LIST, templateIdList);
338 IF_FALSE_LOGE_AND_RETURN_VAL(getTemplateIdListRet == true, ResultCode::GENERAL_ERROR);
339
340 std::vector<uint32_t> uint32KeyList;
341 bool getKeyListRet = conditions->GetUint32ArrayValue(Attributes::ATTR_KEY_LIST, uint32KeyList);
342 IF_FALSE_LOGE_AND_RETURN_VAL(getKeyListRet == true, ResultCode::GENERAL_ERROR);
343
344 std::vector<Attributes::AttributeKey> keyList;
345 keyList.reserve(uint32KeyList.size());
346 for (auto &uint32Key : uint32KeyList) {
347 keyList.push_back(static_cast<Attributes::AttributeKey>(uint32Key));
348 }
349
350 Property property = {};
351
352 ResultCode getPropertyRet = hdi->GetProperty(templateIdList, keyList, property);
353 IF_FALSE_LOGE_AND_RETURN_VAL(getPropertyRet == SUCCESS, ResultCode::GENERAL_ERROR);
354
355 ResultCode fillAttributeRet = FillPropertyToAttribute(keyList, property, values);
356 IF_FALSE_LOGE_AND_RETURN_VAL(fillAttributeRet == SUCCESS, ResultCode::GENERAL_ERROR);
357
358 return ResultCode::SUCCESS;
359 }
360
ProcessAbandonCommand(uint64_t scheduleId,const Attributes & properties)361 ResultCode FrameworkExecutorCallback::ProcessAbandonCommand(uint64_t scheduleId, const Attributes &properties)
362 {
363 std::lock_guard<std::recursive_mutex> lock(mutex_);
364 auto command = Common::MakeShared<AbandonCommand>(executor_, scheduleId, properties, executorMessenger_);
365 IF_FALSE_LOGE_AND_RETURN_VAL(command != nullptr, ResultCode::GENERAL_ERROR);
366 return command->StartProcess();
367 }
368
FillPropertyToAttribute(const std::vector<Attributes::AttributeKey> & keyList,const Property property,std::shared_ptr<Attributes> values)369 ResultCode FrameworkExecutorCallback::FillPropertyToAttribute(const std::vector<Attributes::AttributeKey> &keyList,
370 const Property property, std::shared_ptr<Attributes> values)
371 {
372 bool ret = false;
373 for (auto &key : keyList) {
374 switch (key) {
375 case Attributes::ATTR_PIN_SUB_TYPE: {
376 ret = values->SetInt32Value(Attributes::ATTR_PIN_SUB_TYPE, property.authSubType);
377 IF_FALSE_LOGE_AND_RETURN_VAL(ret, ResultCode::GENERAL_ERROR);
378 break;
379 }
380 case Attributes::ATTR_FREEZING_TIME: {
381 ret = values->SetInt32Value(Attributes::ATTR_FREEZING_TIME, property.lockoutDuration);
382 IF_FALSE_LOGE_AND_RETURN_VAL(ret, ResultCode::GENERAL_ERROR);
383 break;
384 }
385 case Attributes::ATTR_REMAIN_TIMES: {
386 ret = values->SetInt32Value(Attributes::ATTR_REMAIN_TIMES, property.remainAttempts);
387 IF_FALSE_LOGE_AND_RETURN_VAL(ret, ResultCode::GENERAL_ERROR);
388 break;
389 }
390 case Attributes::ATTR_ENROLL_PROGRESS: {
391 ret = values->SetStringValue(Attributes::ATTR_ENROLL_PROGRESS, property.enrollmentProgress);
392 IF_FALSE_LOGE_AND_RETURN_VAL(ret, ResultCode::GENERAL_ERROR);
393 break;
394 }
395 case Attributes::ATTR_SENSOR_INFO: {
396 ret = values->SetStringValue(Attributes::ATTR_SENSOR_INFO, property.sensorInfo);
397 IF_FALSE_LOGE_AND_RETURN_VAL(ret, ResultCode::GENERAL_ERROR);
398 break;
399 }
400 case Attributes::ATTR_NEXT_FAIL_LOCKOUT_DURATION: {
401 ret = values->SetInt32Value(Attributes::ATTR_NEXT_FAIL_LOCKOUT_DURATION,
402 property.nextFailLockoutDuration);
403 IF_FALSE_LOGE_AND_RETURN_VAL(ret, ResultCode::GENERAL_ERROR);
404 break;
405 }
406 case Attributes::ATTR_CREDENTIAL_LENGTH: {
407 if (property.credentialLength != 0) {
408 ret = values->SetUint32Value(Attributes::ATTR_CREDENTIAL_LENGTH, property.credentialLength);
409 IF_FALSE_LOGE_AND_RETURN_VAL(ret, ResultCode::GENERAL_ERROR);
410 }
411 break;
412 }
413 default:
414 IAM_LOGE("key %{public}d is not recognized", key);
415 return ResultCode::GENERAL_ERROR;
416 }
417 }
418
419 return ResultCode::SUCCESS;
420 }
421
GenerateExecutorCallbackId()422 uint32_t FrameworkExecutorCallback::GenerateExecutorCallbackId()
423 {
424 static std::mutex mutex;
425 static uint32_t callbackId = 0;
426 std::lock_guard<std::mutex> guard(mutex);
427 // callbackId is only used in log, uint32 overflow or duplicate is ok
428 ++callbackId;
429 return callbackId;
430 }
431
GetDescription()432 const char *FrameworkExecutorCallback::GetDescription()
433 {
434 return description_.c_str();
435 }
436 } // namespace UserAuth
437 } // namespace UserIam
438 } // namespace OHOS
439