• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "remote_executor_stub.h"
17 
18 #include "iam_check.h"
19 #include "schedule_node.h"
20 
21 #include "context_factory.h"
22 #include "context_pool.h"
23 #include "device_manager_util.h"
24 #include "hdi_wrapper.h"
25 #include "hisysevent_adapter.h"
26 #include "iam_logger.h"
27 #include "iam_para2str.h"
28 #include "iam_ptr.h"
29 #include "remote_auth_service.h"
30 #include "remote_msg_util.h"
31 #include "resource_node_pool.h"
32 #include "schedule_resource_node_listener.h"
33 #include "thread_handler.h"
34 
35 #define LOG_TAG "USER_AUTH_SA"
36 
37 namespace OHOS {
38 namespace UserIam {
39 namespace UserAuth {
40 class RemoteExecutorStubScheduleNode : public ScheduleNode,
41                                        public std::enable_shared_from_this<ScheduleNode>,
42                                        public NoCopyable {
43 public:
RemoteExecutorStubScheduleNode(HdiScheduleInfo & scheduleInfo,std::weak_ptr<RemoteExecutorStub> callback,std::weak_ptr<ResourceNode> collectorExecutor)44     RemoteExecutorStubScheduleNode(HdiScheduleInfo &scheduleInfo, std::weak_ptr<RemoteExecutorStub> callback,
45         std::weak_ptr<ResourceNode> collectorExecutor)
46         : scheduleId_(scheduleInfo.scheduleId),
47           callback_(callback),
48           collectorExecutor_(collectorExecutor)
49     {
50     }
51 
~RemoteExecutorStubScheduleNode()52     ~RemoteExecutorStubScheduleNode()
53     {
54         if (resourceNodePoolListener_ != nullptr) {
55             ResourceNodePool::Instance().DeregisterResourceNodePoolListener(resourceNodePoolListener_);
56         }
57     }
58 
GetScheduleId() const59     uint64_t GetScheduleId() const override
60     {
61         return scheduleId_;
62     }
63 
GetContextId() const64     uint64_t GetContextId() const override
65     {
66         return 0;
67     }
68 
GetAuthType() const69     AuthType GetAuthType() const override
70     {
71         return AuthType::ALL;
72     }
73 
GetExecutorMatcher() const74     uint64_t GetExecutorMatcher() const override
75     {
76         return 0;
77     }
GetScheduleMode() const78     ScheduleMode GetScheduleMode() const override
79     {
80         return ScheduleMode::AUTH;
81     }
GetCollectorExecutor() const82     std::weak_ptr<ResourceNode> GetCollectorExecutor() const override
83     {
84         return collectorExecutor_;
85     }
GetVerifyExecutor() const86     std::weak_ptr<ResourceNode> GetVerifyExecutor() const override
87     {
88         static std::weak_ptr<ResourceNode> nullNode;
89         return nullNode;
90     }
GetTemplateIdList() const91     std::optional<std::vector<uint64_t>> GetTemplateIdList() const override
92     {
93         return std::nullopt;
94     }
GetCurrentScheduleState() const95     State GetCurrentScheduleState() const override
96     {
97         return State::S_INIT;
98     }
GetScheduleCallback()99     std::shared_ptr<ScheduleNodeCallback> GetScheduleCallback() override
100     {
101         return nullptr;
102     }
GetAuthIntent() const103     int32_t GetAuthIntent() const override
104     {
105         return 0;
106     }
ClearScheduleCallback()107     void ClearScheduleCallback() override
108     {
109         return;
110     }
StartSchedule()111     bool StartSchedule() override
112     {
113         std::lock_guard<std::recursive_mutex> lock(mutex_);
114         resourceNodePoolListener_ = Common::MakeShared<ScheduleResourceNodeListener>(weak_from_this());
115         IF_FALSE_LOGE_AND_RETURN_VAL(resourceNodePoolListener_ != nullptr, false);
116         bool registerRet = ResourceNodePool::Instance().RegisterResourceNodePoolListener(resourceNodePoolListener_);
117         IF_FALSE_LOGE_AND_RETURN_VAL(registerRet, false);
118         return true;
119     }
StopSchedule()120     bool StopSchedule() override
121     {
122         return true;
123     }
StopSchedule(ResultCode errorCode)124     bool StopSchedule(ResultCode errorCode) override
125     {
126         std::lock_guard<std::recursive_mutex> lock(mutex_);
127         IAM_LOGI("stop schedule errorCode %{public}d", errorCode);
128         auto finalResult = Common::MakeShared<Attributes>();
129         IF_FALSE_LOGE_AND_RETURN_VAL(finalResult != nullptr, false);
130         bool setResultCodeRet = finalResult->SetInt32Value(Attributes::ATTR_RESULT_CODE, errorCode);
131         IF_FALSE_LOGE_AND_RETURN_VAL(setResultCodeRet, false);
132 
133         return ContinueSchedule(errorCode, finalResult);
134     }
SendMessage(ExecutorRole dstRole,const std::vector<uint8_t> & msg)135     bool SendMessage(ExecutorRole dstRole, const std::vector<uint8_t> &msg) override
136     {
137         std::lock_guard<std::recursive_mutex> lock(mutex_);
138         auto callback = callback_.lock();
139         IF_FALSE_LOGE_AND_RETURN_VAL(callback != nullptr, GENERAL_ERROR);
140         int32_t ret = callback->OnMessage(dstRole, msg);
141         return ret == ResultCode::SUCCESS;
142     }
ContinueSchedule(ResultCode resultCode,const std::shared_ptr<Attributes> & finalResult)143     bool ContinueSchedule(ResultCode resultCode, const std::shared_ptr<Attributes> &finalResult) override
144     {
145         std::lock_guard<std::recursive_mutex> lock(mutex_);
146         auto callback = callback_.lock();
147         IF_FALSE_LOGE_AND_RETURN_VAL(callback != nullptr, GENERAL_ERROR);
148         int32_t ret = callback->ContinueSchedule(resultCode, finalResult);
149         return ret == ResultCode::SUCCESS;
150     }
151 
152 private:
153     std::recursive_mutex mutex_;
154     uint64_t scheduleId_;
155     std::weak_ptr<RemoteExecutorStub> callback_;
156     std::weak_ptr<ResourceNode> collectorExecutor_;
157     std::shared_ptr<ResourceNodePool::ResourceNodePoolListener> resourceNodePoolListener_ {nullptr};
158 };
159 
160 class RemoteExecutorStubMessageCallback : public ConnectionListener, public NoCopyable {
161 public:
RemoteExecutorStubMessageCallback(uint64_t scheduleId,std::weak_ptr<RemoteExecutorStub> callback)162     explicit RemoteExecutorStubMessageCallback(uint64_t scheduleId, std::weak_ptr<RemoteExecutorStub> callback)
163         : scheduleId_(scheduleId),
164           callback_(callback),
165           threadHandler_(ThreadHandler::GetSingleThreadInstance())
166     {
167     }
168     ~RemoteExecutorStubMessageCallback() = default;
169 
OnMessage(const std::string & connectionName,const std::string & srcEndPoint,const std::shared_ptr<Attributes> & request,std::shared_ptr<Attributes> & reply)170     void OnMessage(const std::string &connectionName, const std::string &srcEndPoint,
171         const std::shared_ptr<Attributes> &request, std::shared_ptr<Attributes> &reply) override
172     {
173         IF_FALSE_LOGE_AND_RETURN(request != nullptr);
174         IF_FALSE_LOGE_AND_RETURN(reply != nullptr);
175 
176         IAM_LOGI("connectionName: %{public}s, srcEndPoint: %{public}s", connectionName.c_str(), srcEndPoint.c_str());
177 
178         auto callback = callback_.lock();
179         IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
180         callback->OnMessage(connectionName, srcEndPoint, request, reply);
181     }
182 
OnConnectStatus(const std::string & connectionName,ConnectStatus connectStatus)183     void OnConnectStatus(const std::string &connectionName, ConnectStatus connectStatus) override
184     {
185         IAM_LOGI("connectionName: %{public}s, connectStatus %{public}d, scheduleId "
186                  "%{public}s",
187             connectionName.c_str(), connectStatus, GET_MASKED_STRING(scheduleId_).c_str());
188 
189         IF_FALSE_LOGE_AND_RETURN(connectStatus == ConnectStatus::DISCONNECTED);
190 
191         IF_FALSE_LOGE_AND_RETURN(threadHandler_ != nullptr);
192 
193         threadHandler_->PostTask([scheduleId = scheduleId_]() {
194             IAM_LOGI("OnConnectStatus process begin, scheduleId %{public}s", GET_MASKED_STRING(scheduleId).c_str());
195 
196             auto request = Common::MakeShared<Attributes>();
197             IF_FALSE_LOGE_AND_RETURN(request != nullptr);
198             bool setScheduleIdRet = request->SetUint64Value(Attributes::ATTR_SCHEDULE_ID, scheduleId);
199             IF_FALSE_LOGE_AND_RETURN(setScheduleIdRet);
200 
201             auto reply = Common::MakeShared<Attributes>();
202             IF_FALSE_LOGE_AND_RETURN(reply != nullptr);
203             RemoteAuthService::GetInstance().ProcEndExecuteRequest(request, reply);
204             IAM_LOGI("OnConnectStatus process success, scheduleId %{public}s", GET_MASKED_STRING(scheduleId).c_str());
205         });
206 
207         IAM_LOGI("task posted");
208     }
209 
210 private:
211     uint64_t scheduleId_;
212     std::weak_ptr<RemoteExecutorStub> callback_;
213     std::shared_ptr<ThreadHandler> threadHandler_ = nullptr;
214 };
215 
RemoteExecutorStub()216 RemoteExecutorStub::RemoteExecutorStub() : endPointName_(EXECUTOR_STUB_ENDPOINT_NAME)
217 {
218 }
219 
~RemoteExecutorStub()220 RemoteExecutorStub::~RemoteExecutorStub()
221 {
222     std::lock_guard<std::recursive_mutex> lock(mutex_);
223     if (connectionCallback_ != nullptr) {
224         RemoteConnectionManager::GetInstance().UnregisterConnectionListener(connectionName_, endPointName_);
225     }
226     if (contextId_.has_value()) {
227         ContextPool::Instance().Delete(contextId_.value());
228     }
229     IAM_LOGI("ConnectionName %{public}s RemoteExecutorStub destructed", connectionName_.c_str());
230 }
231 
ProcBeginExecuteRequest(Attributes & attr,RemoteExecuteTrace & trace)232 int32_t RemoteExecutorStub::ProcBeginExecuteRequest(Attributes &attr, RemoteExecuteTrace &trace)
233 {
234     std::lock_guard<std::recursive_mutex> lock(mutex_);
235     IAM_LOGI("start");
236 
237     bool getScheduleIdRet = attr.GetUint64Value(Attributes::ATTR_SCHEDULE_ID, trace.scheduleId);
238     IF_FALSE_LOGE_AND_RETURN_VAL(getScheduleIdRet, GENERAL_ERROR);
239     IAM_LOGI("scheduleId %{public}s begin execute", GET_MASKED_STRING(trace.scheduleId).c_str());
240 
241     connectionCallback_ = Common::MakeShared<RemoteExecutorStubMessageCallback>(trace.scheduleId, shared_from_this());
242     IF_FALSE_LOGE_AND_RETURN_VAL(connectionCallback_ != nullptr, GENERAL_ERROR);
243 
244     bool getConnectionName = attr.GetStringValue(Attributes::ATTR_CONNECTION_NAME, connectionName_);
245     IF_FALSE_LOGE_AND_RETURN_VAL(getConnectionName, GENERAL_ERROR);
246     trace.connectionName = connectionName_;
247 
248     ResultCode registerResult = RemoteConnectionManager::GetInstance().RegisterConnectionListener(connectionName_,
249         endPointName_, connectionCallback_);
250     IF_FALSE_LOGE_AND_RETURN_VAL(registerResult == SUCCESS, GENERAL_ERROR);
251 
252     std::string srcUdid;
253     bool getSrcUdidRet = attr.GetStringValue(Attributes::ATTR_MSG_SRC_UDID, srcUdid);
254     IF_FALSE_LOGE_AND_RETURN_VAL(getSrcUdidRet, GENERAL_ERROR);
255 
256     std::vector<uint8_t> scheduleData;
257     bool getScheduleDataRet = attr.GetUint8ArrayValue(Attributes::ATTR_SCHEDULE_DATA, scheduleData);
258     IF_FALSE_LOGE_AND_RETURN_VAL(getScheduleDataRet, GENERAL_ERROR);
259 
260     HdiScheduleInfo scheduleInfo;
261     auto hdi = HdiWrapper::GetHdiInstance();
262     IF_FALSE_LOGE_AND_RETURN_VAL(hdi != nullptr, GENERAL_ERROR);
263 
264     int32_t ret = hdi->GetLocalScheduleFromMessage(srcUdid, scheduleData, scheduleInfo);
265     IF_FALSE_LOGE_AND_RETURN_VAL(ret == SUCCESS, GENERAL_ERROR);
266     IF_FALSE_LOGE_AND_RETURN_VAL(scheduleInfo.executorIndexes.size() == 1, GENERAL_ERROR);
267     IF_FALSE_LOGE_AND_RETURN_VAL(scheduleInfo.executorMessages.size() == 1, GENERAL_ERROR);
268 
269     executorIndex_ = scheduleInfo.executorIndexes[0];
270     std::weak_ptr<ResourceNode> weakNode = ResourceNodePool::Instance().Select(executorIndex_);
271     std::shared_ptr<ResourceNode> node = weakNode.lock();
272     IF_FALSE_LOGE_AND_RETURN_VAL(node != nullptr, GENERAL_ERROR);
273 
274     remoteScheduleNode_ = Common::MakeShared<RemoteExecutorStubScheduleNode>(scheduleInfo, weak_from_this(), node);
275     IF_FALSE_LOGE_AND_RETURN_VAL(remoteScheduleNode_ != nullptr, GENERAL_ERROR);
276 
277     bool startScheduleRet = remoteScheduleNode_->StartSchedule();
278     IF_FALSE_LOGE_AND_RETURN_VAL(startScheduleRet, GENERAL_ERROR);
279 
280     auto context = ContextFactory::CreateScheduleHolderContext(remoteScheduleNode_);
281     IF_FALSE_LOGE_AND_RETURN_VAL(context != nullptr, GENERAL_ERROR);
282 
283     bool addContextRet = ContextPool::Instance().Insert(context);
284     IF_FALSE_LOGE_AND_RETURN_VAL(addContextRet, GENERAL_ERROR);
285     contextId_ = context->GetContextId();
286 
287     bool setExtraInfo = attr.SetUint8ArrayValue(Attributes::ATTR_EXTRA_INFO, scheduleInfo.executorMessages[0]);
288     IF_FALSE_LOGE_AND_RETURN_VAL(setExtraInfo, GENERAL_ERROR);
289 
290     std::vector<uint8_t> publicKey;
291     ret = node->BeginExecute(scheduleInfo.scheduleId, publicKey, attr);
292 
293     IAM_LOGI("ConnectionName %{public}s scheduleId %{public}s begin execute ret %{public}d", connectionName_.c_str(),
294         GET_MASKED_STRING(trace.scheduleId).c_str(), ret);
295     return ret;
296 }
297 
OnMessage(const std::string & connectionName,const std::string & srcEndPoint,const std::shared_ptr<Attributes> & request,std::shared_ptr<Attributes> & reply)298 void RemoteExecutorStub::OnMessage(const std::string &connectionName, const std::string &srcEndPoint,
299     const std::shared_ptr<Attributes> &request, std::shared_ptr<Attributes> &reply)
300 {
301     std::lock_guard<std::recursive_mutex> lock(mutex_);
302     IAM_LOGI("start");
303     IF_FALSE_LOGE_AND_RETURN(request != nullptr);
304     IF_FALSE_LOGE_AND_RETURN(reply != nullptr);
305 
306     int32_t msgType;
307     bool getMsgTypeRet = request->GetInt32Value(Attributes::ATTR_MSG_TYPE, msgType);
308     IF_FALSE_LOGE_AND_RETURN(getMsgTypeRet);
309 
310     int32_t resultCode = ResultCode::GENERAL_ERROR;
311     switch (msgType) {
312         case MessageType::SEND_DATA_TO_EXECUTOR:
313             resultCode = ProcSendDataMsg(*request);
314             break;
315         default:
316             IAM_LOGE("unsupported message type: %{public}d", msgType);
317             break;
318     }
319 
320     IF_FALSE_LOGE_AND_RETURN(resultCode == ResultCode::SUCCESS);
321     bool setResultCodeRet = reply->SetInt32Value(Attributes::ATTR_RESULT_CODE, ResultCode::SUCCESS);
322     IF_FALSE_LOGE_AND_RETURN(setResultCodeRet);
323 
324     IAM_LOGI("success");
325 }
326 
OnMessage(ExecutorRole dstRole,const std::vector<uint8_t> & msg)327 int32_t RemoteExecutorStub::OnMessage(ExecutorRole dstRole, const std::vector<uint8_t> &msg)
328 {
329     std::lock_guard<std::recursive_mutex> lock(mutex_);
330     IF_FALSE_LOGE_AND_RETURN_VAL(remoteScheduleNode_ != nullptr, GENERAL_ERROR);
331 
332     IAM_LOGI("start, scheduleId %{public}s", GET_MASKED_STRING(remoteScheduleNode_->GetScheduleId()).c_str());
333 
334     std::shared_ptr<Attributes> request = Common::MakeShared<Attributes>(msg);
335     IF_FALSE_LOGE_AND_RETURN_VAL(request != nullptr, GENERAL_ERROR);
336 
337     bool setMsgTypeRet = request->SetInt32Value(Attributes::ATTR_MSG_TYPE, MessageType::EXECUTOR_SEND_DATA);
338     IF_FALSE_LOGE_AND_RETURN_VAL(setMsgTypeRet, GENERAL_ERROR);
339 
340     bool setScheduleIdRet = request->SetUint64Value(Attributes::ATTR_SCHEDULE_ID, remoteScheduleNode_->GetScheduleId());
341     IF_FALSE_LOGE_AND_RETURN_VAL(setScheduleIdRet, GENERAL_ERROR);
342 
343     bool setDestRoleRet = request->SetInt32Value(Attributes::ATTR_DEST_ROLE, dstRole);
344     IF_FALSE_LOGE_AND_RETURN_VAL(setDestRoleRet, GENERAL_ERROR);
345 
346     MsgCallback msgCallback = [](const std::shared_ptr<Attributes> &) { IAM_LOGI("message sent"); };
347 
348     ResultCode sendMsgRet = RemoteConnectionManager::GetInstance().SendMessage(connectionName_, endPointName_,
349         EXECUTOR_PROXY_ENDPOINT_NAME, request, msgCallback);
350     IF_FALSE_LOGE_AND_RETURN_VAL(sendMsgRet == ResultCode::SUCCESS, GENERAL_ERROR);
351 
352     IAM_LOGI("success, ConnectionName %{public}s scheduleId %{public}s", connectionName_.c_str(),
353         GET_MASKED_STRING(remoteScheduleNode_->GetScheduleId()).c_str());
354     return SUCCESS;
355 }
356 
ContinueSchedule(ResultCode resultCode,const std::shared_ptr<Attributes> & finalResult)357 int32_t RemoteExecutorStub::ContinueSchedule(ResultCode resultCode, const std::shared_ptr<Attributes> &finalResult)
358 {
359     std::lock_guard<std::recursive_mutex> lock(mutex_);
360     IAM_LOGI("start");
361 
362     IF_FALSE_LOGE_AND_RETURN_VAL(finalResult != nullptr, GENERAL_ERROR);
363     IF_FALSE_LOGE_AND_RETURN_VAL(remoteScheduleNode_ != nullptr, GENERAL_ERROR);
364     IAM_LOGI("ConnectionName %{public}s scheduleId %{public}s continue schedule", connectionName_.c_str(),
365         GET_MASKED_STRING(remoteScheduleNode_->GetScheduleId()).c_str());
366 
367     std::shared_ptr<Attributes> request = Common::MakeShared<Attributes>(finalResult->Serialize());
368     IF_FALSE_LOGE_AND_RETURN_VAL(request != nullptr, GENERAL_ERROR);
369 
370     bool setMsgTypeRet = request->SetInt32Value(Attributes::ATTR_MSG_TYPE, MessageType::EXECUTOR_FINISH);
371     IF_FALSE_LOGE_AND_RETURN_VAL(setMsgTypeRet, GENERAL_ERROR);
372 
373     bool setScheduleIdRet = request->SetUint64Value(Attributes::ATTR_SCHEDULE_ID, remoteScheduleNode_->GetScheduleId());
374     IF_FALSE_LOGE_AND_RETURN_VAL(setScheduleIdRet, GENERAL_ERROR);
375 
376     bool setResultCodeRet = request->SetInt32Value(Attributes::ATTR_RESULT_CODE, resultCode);
377     IF_FALSE_LOGE_AND_RETURN_VAL(setResultCodeRet, GENERAL_ERROR);
378 
379     MsgCallback msgCallback = [](const std::shared_ptr<Attributes> &) { IAM_LOGI("message sent"); };
380 
381     ResultCode sendMsgRet = RemoteConnectionManager::GetInstance().SendMessage(connectionName_, endPointName_,
382         EXECUTOR_PROXY_ENDPOINT_NAME, request, msgCallback);
383     IF_FALSE_LOGE_AND_RETURN_VAL(sendMsgRet == ResultCode::SUCCESS, GENERAL_ERROR);
384 
385     IAM_LOGI("ConnectionName %{public}s scheduleId %{public}s continue schedule "
386              "success",
387         connectionName_.c_str(), GET_MASKED_STRING(remoteScheduleNode_->GetScheduleId()).c_str());
388     return SUCCESS;
389 }
390 
ProcSendDataMsg(Attributes & attr)391 int32_t RemoteExecutorStub::ProcSendDataMsg(Attributes &attr)
392 {
393     std::lock_guard<std::recursive_mutex> lock(mutex_);
394     IAM_LOGI("start");
395 
396     uint64_t scheduleId;
397     bool getScheduleIdRet = attr.GetUint64Value(Attributes::ATTR_SCHEDULE_ID, scheduleId);
398     IF_FALSE_LOGE_AND_RETURN_VAL(getScheduleIdRet, GENERAL_ERROR);
399     IAM_LOGI("ConnectionName %{public}s scheduleId %{public}s proc send data", connectionName_.c_str(),
400         GET_MASKED_STRING(scheduleId).c_str());
401 
402     std::weak_ptr<ResourceNode> weakNode = ResourceNodePool::Instance().Select(executorIndex_);
403     std::shared_ptr<ResourceNode> node = weakNode.lock();
404     IF_FALSE_LOGE_AND_RETURN_VAL(node != nullptr, GENERAL_ERROR);
405 
406     int32_t ret = node->SendData(scheduleId, attr);
407     IF_FALSE_LOGE_AND_RETURN_VAL(ret == ResultCode::SUCCESS, GENERAL_ERROR);
408 
409     IAM_LOGI("ConnectionName %{public}s scheduleId %{public}s proc send data success", connectionName_.c_str(),
410         GET_MASKED_STRING(scheduleId).c_str());
411     return ret;
412 }
413 
414 } // namespace UserAuth
415 } // namespace UserIam
416 } // namespace OHOS