• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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