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_proxy.h"
17
18 #include <functional>
19 #include <mutex>
20
21 #include "co_auth_client.h"
22 #include "iam_check.h"
23 #include "iam_logger.h"
24 #include "iam_para2str.h"
25 #include "iam_ptr.h"
26 #include "thread_handler.h"
27
28 #define LOG_TAG "USER_AUTH_SA"
29
30 namespace OHOS {
31 namespace UserIam {
32 namespace UserAuth {
33 class RemoteExecutorProxyCallback : public ExecutorRegisterCallback, public NoCopyable {
34 public:
RemoteExecutorProxyCallback(std::weak_ptr<RemoteExecutorProxy> callback)35 explicit RemoteExecutorProxyCallback(std::weak_ptr<RemoteExecutorProxy> callback) : callback_(callback)
36 {
37 }
38 ~RemoteExecutorProxyCallback() override = default;
39
OnMessengerReady(const std::shared_ptr<ExecutorMessenger> & messenger,const std::vector<uint8_t> & publicKey,const std::vector<uint64_t> & templateIdList)40 void OnMessengerReady(const std::shared_ptr<ExecutorMessenger> &messenger,
41 const std::vector<uint8_t> &publicKey, const std::vector<uint64_t> &templateIdList) override
42 {
43 auto callback = callback_.lock();
44 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
45 callback->OnMessengerReady(messenger, publicKey, templateIdList);
46 }
47
OnBeginExecute(uint64_t scheduleId,const std::vector<uint8_t> & publicKey,const Attributes & commandAttrs)48 int32_t OnBeginExecute(uint64_t scheduleId, const std::vector<uint8_t> &publicKey,
49 const Attributes &commandAttrs) override
50 {
51 auto callback = callback_.lock();
52 IF_FALSE_LOGE_AND_RETURN_VAL(callback != nullptr, GENERAL_ERROR);
53 return callback->OnBeginExecute(scheduleId, publicKey, commandAttrs);
54 }
OnEndExecute(uint64_t scheduleId,const Attributes & commandAttrs)55 int32_t OnEndExecute(uint64_t scheduleId, const Attributes &commandAttrs) override
56 {
57 auto callback = callback_.lock();
58 IF_FALSE_LOGE_AND_RETURN_VAL(callback != nullptr, GENERAL_ERROR);
59 return callback->OnEndExecute(scheduleId, commandAttrs);
60 }
61
OnSetProperty(const Attributes & properties)62 int32_t OnSetProperty(const Attributes &properties) override
63 {
64 IAM_LOGE("OnSetProperty is not supported");
65 return GENERAL_ERROR;
66 }
67
OnGetProperty(const Attributes & conditions,Attributes & results)68 int32_t OnGetProperty(const Attributes &conditions, Attributes &results) override
69 {
70 IAM_LOGE("OnGetProperty is not supported");
71 return GENERAL_ERROR;
72 }
73
OnSendData(uint64_t scheduleId,const Attributes & data)74 int32_t OnSendData(uint64_t scheduleId, const Attributes &data) override
75 {
76 auto callback = callback_.lock();
77 IF_FALSE_LOGE_AND_RETURN_VAL(callback != nullptr, GENERAL_ERROR);
78 return callback->OnSendData(scheduleId, data);
79 }
80
81 private:
82 std::weak_ptr<RemoteExecutorProxy> callback_;
83 };
84
85 class RemoteExecutorProxyMessageCallback : public ConnectionListener, public NoCopyable {
86 public:
RemoteExecutorProxyMessageCallback(std::weak_ptr<RemoteExecutorProxy> callback)87 explicit RemoteExecutorProxyMessageCallback(std::weak_ptr<RemoteExecutorProxy> callback)
88 : callback_(callback),
89 threadHandler_(ThreadHandler::GetSingleThreadInstance())
90 {
91 }
92 ~RemoteExecutorProxyMessageCallback() = default;
93
OnMessage(const std::string & connectionName,const std::string & srcEndPoint,const std::shared_ptr<Attributes> & request,std::shared_ptr<Attributes> & reply)94 void OnMessage(const std::string &connectionName, const std::string &srcEndPoint,
95 const std::shared_ptr<Attributes> &request, std::shared_ptr<Attributes> &reply) override
96 {
97 IF_FALSE_LOGE_AND_RETURN(request != nullptr);
98 IF_FALSE_LOGE_AND_RETURN(reply != nullptr);
99
100 IAM_LOGI("connectionName: %{public}s, srcEndPoint: %{public}s", connectionName.c_str(), srcEndPoint.c_str());
101
102 auto callback = callback_.lock();
103 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
104 callback->OnMessage(connectionName, srcEndPoint, request, reply);
105 }
106
OnConnectStatus(const std::string & connectionName,ConnectStatus connectStatus)107 void OnConnectStatus(const std::string &connectionName, ConnectStatus connectStatus) override
108 {
109 IAM_LOGI("connectionName: %{public}s, connectStatus %{public}d", connectionName.c_str(), connectStatus);
110
111 IF_FALSE_LOGE_AND_RETURN(connectStatus == ConnectStatus::DISCONNECTED);
112 IF_FALSE_LOGE_AND_RETURN(threadHandler_ != nullptr);
113 threadHandler_->PostTask([connectionName, connectStatus, callbackTemp = callback_, this]() {
114 IAM_LOGI("OnConnectStatus process begin");
115 auto callback = callbackTemp.lock();
116 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
117 callback->OnConnectStatus(connectionName, connectStatus);
118 IAM_LOGI("OnConnectStatus process success");
119 });
120
121 IAM_LOGI("task posted");
122 }
123
124 private:
125 std::weak_ptr<RemoteExecutorProxy> callback_;
126 std::shared_ptr<ThreadHandler> threadHandler_ = nullptr;
127 };
128
RemoteExecutorProxy(std::string connectionName,ExecutorInfo registerInfo)129 RemoteExecutorProxy::RemoteExecutorProxy(std::string connectionName, ExecutorInfo registerInfo)
130 : connectionName_(connectionName),
131 registerInfo_(registerInfo),
132 endPointName_(EXECUTOR_PROXY_ENDPOINT_NAME)
133 {
134 }
135
~RemoteExecutorProxy()136 RemoteExecutorProxy::~RemoteExecutorProxy()
137 {
138 IAM_LOGI("start");
139
140 RemoteConnectionManager::GetInstance().UnregisterConnectionListener(connectionName_, endPointName_);
141 CoAuthClient::GetInstance().Unregister(executorIndex_);
142
143 IAM_LOGI("success");
144 }
145
Start()146 ResultCode RemoteExecutorProxy::Start()
147 {
148 IAM_LOGI("start");
149 {
150 std::lock_guard<std::recursive_mutex> lock(mutex_);
151 connectionCallback_ = Common::MakeShared<RemoteExecutorProxyMessageCallback>(weak_from_this());
152 IF_FALSE_LOGE_AND_RETURN_VAL(connectionCallback_ != nullptr, GENERAL_ERROR);
153
154 ResultCode registerResult = RemoteConnectionManager::GetInstance().RegisterConnectionListener(connectionName_,
155 endPointName_, connectionCallback_);
156 IF_FALSE_LOGE_AND_RETURN_VAL(registerResult == SUCCESS, GENERAL_ERROR);
157
158 executorCallback_ = Common::MakeShared<RemoteExecutorProxyCallback>(weak_from_this());
159 IF_FALSE_LOGE_AND_RETURN_VAL(executorCallback_ != nullptr, GENERAL_ERROR);
160 }
161
162 uint64_t executorIndex = CoAuthClient::GetInstance().Register(registerInfo_, executorCallback_);
163 IF_FALSE_LOGE_AND_RETURN_VAL(executorIndex != INVALID_EXECUTOR_INDEX, GENERAL_ERROR);
164
165 {
166 std::lock_guard<std::recursive_mutex> lock(mutex_);
167 executorIndex_ = executorIndex;
168 }
169
170 IAM_LOGI("success");
171 return ResultCode::SUCCESS;
172 }
173
OnMessage(const std::string & connectionName,const std::string & srcEndPoint,const std::shared_ptr<Attributes> & request,std::shared_ptr<Attributes> & reply)174 void RemoteExecutorProxy::OnMessage(const std::string &connectionName, const std::string &srcEndPoint,
175 const std::shared_ptr<Attributes> &request, std::shared_ptr<Attributes> &reply)
176 {
177 std::lock_guard<std::recursive_mutex> lock(mutex_);
178 IAM_LOGI("start");
179
180 IF_FALSE_LOGE_AND_RETURN(connectionName_ == connectionName);
181 IF_FALSE_LOGE_AND_RETURN(request != nullptr);
182 IF_FALSE_LOGE_AND_RETURN(reply != nullptr);
183
184 int32_t msgType;
185 bool getMsgTypeRet = request->GetInt32Value(Attributes::ATTR_MSG_TYPE, msgType);
186 IF_FALSE_LOGE_AND_RETURN(getMsgTypeRet);
187
188 int32_t resultCode = ResultCode::GENERAL_ERROR;
189 switch (msgType) {
190 case MessageType::EXECUTOR_SEND_DATA:
191 resultCode = ProcSendDataMsg(*request);
192 break;
193 case MessageType::EXECUTOR_FINISH:
194 resultCode = ProcFinishMsg(*request);
195 break;
196 default:
197 IAM_LOGE("unsupported message type: %{public}d", msgType);
198 break;
199 }
200
201 IF_FALSE_LOGE_AND_RETURN(resultCode == ResultCode::SUCCESS);
202 bool setResultCodeRet = reply->SetInt32Value(Attributes::ATTR_RESULT_CODE, ResultCode::SUCCESS);
203 IF_FALSE_LOGE_AND_RETURN(setResultCodeRet);
204
205 IAM_LOGI("success");
206 }
207
OnConnectStatus(const std::string & connectionName,ConnectStatus connectStatus)208 void RemoteExecutorProxy::OnConnectStatus(const std::string &connectionName, ConnectStatus connectStatus)
209 {
210 }
211
OnMessengerReady(const std::shared_ptr<ExecutorMessenger> & messenger,const std::vector<uint8_t> & publicKey,const std::vector<uint64_t> & templateIdList)212 void RemoteExecutorProxy::OnMessengerReady(const std::shared_ptr<ExecutorMessenger> &messenger,
213 const std::vector<uint8_t> &publicKey, const std::vector<uint64_t> &templateIdList)
214 {
215 std::lock_guard<std::recursive_mutex> lock(mutex_);
216 IAM_LOGI("start");
217
218 messenger_ = messenger;
219 IAM_LOGI("success");
220 }
221
OnBeginExecute(uint64_t scheduleId,const std::vector<uint8_t> & publicKey,const Attributes & command)222 int32_t RemoteExecutorProxy::OnBeginExecute(uint64_t scheduleId, const std::vector<uint8_t> &publicKey,
223 const Attributes &command)
224 {
225 std::lock_guard<std::recursive_mutex> lock(mutex_);
226 IAM_LOGI("start, scheduleId: %{public}s", GET_MASKED_STRING(scheduleId).c_str());
227
228 std::shared_ptr<Attributes> request = Common::MakeShared<Attributes>(command.Serialize());
229 IF_FALSE_LOGE_AND_RETURN_VAL(request != nullptr, GENERAL_ERROR);
230
231 bool setMessageTypeRet = request->SetInt32Value(Attributes::ATTR_MSG_TYPE, MessageType::BEGIN_EXECUTE);
232 IF_FALSE_LOGE_AND_RETURN_VAL(setMessageTypeRet, GENERAL_ERROR);
233
234 bool setScheduleIdRet = request->SetUint64Value(Attributes::ATTR_SCHEDULE_ID, scheduleId);
235 IF_FALSE_LOGE_AND_RETURN_VAL(setScheduleIdRet, GENERAL_ERROR);
236
237 std::vector<uint8_t> collectorMessage;
238 bool getCollectorMessageRet = request->GetUint8ArrayValue(Attributes::ATTR_EXTRA_INFO, collectorMessage);
239 IF_FALSE_LOGE_AND_RETURN_VAL(getCollectorMessageRet, GENERAL_ERROR);
240
241 bool setScheduleDataRet = request->SetUint8ArrayValue(Attributes::ATTR_SCHEDULE_DATA, collectorMessage);
242 IF_FALSE_LOGE_AND_RETURN_VAL(setScheduleDataRet, GENERAL_ERROR);
243
244 MsgCallback msgCallback = [self = weak_from_this(), scheduleId](const std::shared_ptr<Attributes> &reply) {
245 IF_FALSE_LOGE_AND_RETURN(reply != nullptr);
246
247 auto sharedSelf = self.lock();
248 IF_FALSE_LOGE_AND_RETURN(sharedSelf != nullptr);
249 int32_t resultCode;
250 bool getResultCodeRet = reply->GetInt32Value(Attributes::ATTR_RESULT_CODE, resultCode);
251 IF_FALSE_LOGE_AND_RETURN(getResultCodeRet);
252 if (resultCode != ResultCode::SUCCESS) {
253 IAM_LOGE("scheduleId %{public}s begin execute failed", GET_MASKED_STRING(scheduleId).c_str());
254 sharedSelf->OnErrorFinish(scheduleId);
255 return;
256 }
257 IAM_LOGI("scheduleId %{public}s begin execute success", GET_MASKED_STRING(scheduleId).c_str());
258 };
259
260 ResultCode sendMsgRet = RemoteConnectionManager::GetInstance().SendMessage(connectionName_, endPointName_,
261 REMOTE_SERVICE_ENDPOINT_NAME, request, msgCallback);
262 IF_FALSE_LOGE_AND_RETURN_VAL(sendMsgRet == ResultCode::SUCCESS, GENERAL_ERROR);
263
264 IAM_LOGI("success, scheduleId %{public}s", GET_MASKED_STRING(scheduleId).c_str());
265 return ResultCode::SUCCESS;
266 }
267
OnEndExecute(uint64_t scheduleId,const Attributes & command)268 int32_t RemoteExecutorProxy::OnEndExecute(uint64_t scheduleId, const Attributes &command)
269 {
270 std::lock_guard<std::recursive_mutex> lock(mutex_);
271 IAM_LOGI("start, scheduleId: %{public}s", GET_MASKED_STRING(scheduleId).c_str());
272
273 std::shared_ptr<Attributes> request = Common::MakeShared<Attributes>(command.Serialize());
274 IF_FALSE_LOGE_AND_RETURN_VAL(request != nullptr, GENERAL_ERROR);
275
276 bool setMessageTypeRet = request->SetInt32Value(Attributes::ATTR_MSG_TYPE, MessageType::END_EXECUTE);
277 IF_FALSE_LOGE_AND_RETURN_VAL(setMessageTypeRet, GENERAL_ERROR);
278
279 bool setScheduleIdRet = request->SetUint64Value(Attributes::ATTR_SCHEDULE_ID, scheduleId);
280 IF_FALSE_LOGE_AND_RETURN_VAL(setScheduleIdRet, GENERAL_ERROR);
281
282 MsgCallback msgCallback = [](const std::shared_ptr<Attributes> &) { IAM_LOGI("message sent"); };
283
284 ResultCode sendMsgRet = RemoteConnectionManager::GetInstance().SendMessage(connectionName_, endPointName_,
285 REMOTE_SERVICE_ENDPOINT_NAME, request, msgCallback);
286 IF_FALSE_LOGE_AND_RETURN_VAL(sendMsgRet == ResultCode::SUCCESS, GENERAL_ERROR);
287
288 IAM_LOGI("success, scheduleId %{public}s", GET_MASKED_STRING(scheduleId).c_str());
289 return ResultCode::SUCCESS;
290 }
291
OnSendData(uint64_t scheduleId,const Attributes & data)292 int32_t RemoteExecutorProxy::OnSendData(uint64_t scheduleId, const Attributes &data)
293 {
294 std::lock_guard<std::recursive_mutex> lock(mutex_);
295 IAM_LOGI("start");
296
297 std::shared_ptr<Attributes> request = Common::MakeShared<Attributes>(data.Serialize());
298 IF_FALSE_LOGE_AND_RETURN_VAL(request != nullptr, GENERAL_ERROR);
299
300 bool setMessageTypeRet = request->SetInt32Value(Attributes::ATTR_MSG_TYPE, MessageType::SEND_DATA_TO_EXECUTOR);
301 IF_FALSE_LOGE_AND_RETURN_VAL(setMessageTypeRet, GENERAL_ERROR);
302
303 bool setScheduleIdRet = request->SetUint64Value(Attributes::ATTR_SCHEDULE_ID, scheduleId);
304 IF_FALSE_LOGE_AND_RETURN_VAL(setScheduleIdRet, GENERAL_ERROR);
305
306 MsgCallback msgCallback = [weakThis = weak_from_this(), scheduleId](const std::shared_ptr<Attributes> &reply) {
307 int32_t resultCode;
308 IF_FALSE_LOGE_AND_RETURN(reply != nullptr);
309 bool getResultCodeRet = reply->GetInt32Value(Attributes::ATTR_RESULT_CODE, resultCode);
310 IF_FALSE_LOGE_AND_RETURN(getResultCodeRet);
311
312 if (resultCode != ResultCode::SUCCESS) {
313 IAM_LOGE("send data to executor failed");
314 auto sharedThis = weakThis.lock();
315 IF_FALSE_LOGE_AND_RETURN(sharedThis != nullptr);
316 sharedThis->OnErrorFinish(scheduleId);
317 return;
318 }
319 };
320
321 ResultCode sendMsgRet = RemoteConnectionManager::GetInstance().SendMessage(connectionName_, endPointName_,
322 EXECUTOR_STUB_ENDPOINT_NAME, request, msgCallback);
323 IF_FALSE_LOGE_AND_RETURN_VAL(sendMsgRet == ResultCode::SUCCESS, GENERAL_ERROR);
324
325 IAM_LOGI("success");
326 return ResultCode::SUCCESS;
327 }
328
ProcSendDataMsg(Attributes & data)329 int32_t RemoteExecutorProxy::ProcSendDataMsg(Attributes &data)
330 {
331 std::lock_guard<std::recursive_mutex> lock(mutex_);
332 IAM_LOGI("start");
333
334 uint64_t scheduleId;
335 bool getScheduleIdRet = data.GetUint64Value(Attributes::ATTR_SCHEDULE_ID, scheduleId);
336 IF_FALSE_LOGE_AND_RETURN_VAL(getScheduleIdRet, GENERAL_ERROR);
337
338 int32_t dstRole;
339 bool getDstRoleRet = data.GetInt32Value(Attributes::ATTR_DEST_ROLE, dstRole);
340 IF_FALSE_LOGE_AND_RETURN_VAL(getDstRoleRet, GENERAL_ERROR);
341
342 auto msg = AuthMessage::As(data.Serialize());
343 IF_FALSE_LOGE_AND_RETURN_VAL(msg != nullptr, GENERAL_ERROR);
344
345 IAM_LOGI("scheduleId %{public}s send data", GET_MASKED_STRING(scheduleId).c_str());
346 IF_FALSE_LOGE_AND_RETURN_VAL(messenger_ != nullptr, GENERAL_ERROR);
347 int32_t ret = messenger_->SendData(scheduleId, static_cast<ExecutorRole>(dstRole), msg);
348 IF_FALSE_LOGE_AND_RETURN_VAL(ret == SUCCESS, GENERAL_ERROR);
349
350 IAM_LOGI("success");
351 return ret;
352 }
353
ProcFinishMsg(Attributes & data)354 int32_t RemoteExecutorProxy::ProcFinishMsg(Attributes &data)
355 {
356 std::lock_guard<std::recursive_mutex> lock(mutex_);
357 IAM_LOGI("start");
358
359 uint64_t scheduleId;
360 bool getScheduleIdRet = data.GetUint64Value(Attributes::ATTR_SCHEDULE_ID, scheduleId);
361 IF_FALSE_LOGE_AND_RETURN_VAL(getScheduleIdRet, GENERAL_ERROR);
362
363 int32_t resultCode;
364 bool getResultCodeRet = data.GetInt32Value(Attributes::ATTR_RESULT_CODE, resultCode);
365 IF_FALSE_LOGE_AND_RETURN_VAL(getResultCodeRet, GENERAL_ERROR);
366
367 IF_FALSE_LOGE_AND_RETURN_VAL(messenger_ != nullptr, GENERAL_ERROR);
368
369 IAM_LOGI("scheduleId %{public}s proc finish code %{public}d", GET_MASKED_STRING(scheduleId).c_str(), resultCode);
370 int32_t ret = messenger_->Finish(scheduleId, static_cast<ResultCode>(resultCode), data);
371 IF_FALSE_LOGE_AND_RETURN_VAL(ret == SUCCESS, GENERAL_ERROR);
372 IAM_LOGI("success");
373 return ret;
374 }
375
OnErrorFinish(uint64_t scheduleId)376 void RemoteExecutorProxy::OnErrorFinish(uint64_t scheduleId)
377 {
378 IAM_LOGI("start");
379 std::lock_guard<std::recursive_mutex> lock(mutex_);
380
381 Attributes request;
382
383 bool setScheduleIdRet = request.SetUint64Value(Attributes::ATTR_SCHEDULE_ID, scheduleId);
384 IF_FALSE_LOGE_AND_RETURN(setScheduleIdRet);
385
386 bool setResultCodeRet = request.SetInt32Value(Attributes::ATTR_RESULT_CODE, ResultCode::GENERAL_ERROR);
387 IF_FALSE_LOGE_AND_RETURN(setResultCodeRet);
388
389 ProcFinishMsg(request);
390 IAM_LOGI("success");
391 }
392 } // namespace UserAuth
393 } // namespace UserIam
394 } // namespace OHOS