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