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