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