• 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_auth_invoker_context.h"
17 
18 #include "device_manager_util.h"
19 #include "hdi_wrapper.h"
20 #include "iam_check.h"
21 #include "iam_logger.h"
22 #include "iam_para2str.h"
23 #include "iam_ptr.h"
24 #include "relative_timer.h"
25 #include "remote_connect_manager.h"
26 #include "thread_handler.h"
27 #include "thread_handler_manager.h"
28 #include "user_auth_hdi.h"
29 
30 #define LOG_TAG "USER_AUTH_SA"
31 
32 namespace OHOS {
33 namespace UserIam {
34 namespace UserAuth {
35 namespace {
36 constexpr uint32_t TIME_OUT_MS = 3 * 60 * 1000; // 3min
37 }
38 class RemoteAuthInvokerContextMessageCallback : public ConnectionListener, public NoCopyable {
39 public:
RemoteAuthInvokerContextMessageCallback(std::weak_ptr<BaseContext> callbackWeakBase,RemoteAuthInvokerContext * callback)40     explicit RemoteAuthInvokerContextMessageCallback(std::weak_ptr<BaseContext> callbackWeakBase,
41         RemoteAuthInvokerContext *callback)
42         : callbackWeakBase_(callbackWeakBase),
43           callback_(callback),
44           threadHandler_(ThreadHandler::GetSingleThreadInstance())
45     {
46     }
47 
48     ~RemoteAuthInvokerContextMessageCallback() = default;
49 
OnMessage(const std::string & connectionName,const std::string & srcEndPoint,const std::shared_ptr<Attributes> & request,std::shared_ptr<Attributes> & reply)50     void OnMessage(const std::string &connectionName, const std::string &srcEndPoint,
51         const std::shared_ptr<Attributes> &request, std::shared_ptr<Attributes> &reply) override
52     {
53         IF_FALSE_LOGE_AND_RETURN(request != nullptr);
54         IF_FALSE_LOGE_AND_RETURN(reply != nullptr);
55 
56         IAM_LOGI("connectionName: %{public}s, srcEndPoint: %{public}s", connectionName.c_str(), srcEndPoint.c_str());
57 
58         std::shared_ptr<BaseContext> callbackSharedBase = callbackWeakBase_.lock();
59         IF_FALSE_LOGE_AND_RETURN(callbackSharedBase != nullptr);
60 
61         IF_FALSE_LOGE_AND_RETURN(callback_ != nullptr);
62         callback_->OnMessage(connectionName, srcEndPoint, request, reply);
63     }
64 
OnConnectStatus(const std::string & connectionName,ConnectStatus connectStatus)65     void OnConnectStatus(const std::string &connectionName, ConnectStatus connectStatus) override
66     {
67         IAM_LOGI("connectionName: %{public}s, connectStatus %{public}d", connectionName.c_str(), connectStatus);
68 
69         IF_FALSE_LOGE_AND_RETURN(threadHandler_ != nullptr);
70         threadHandler_->PostTask(
71             [connectionName, connectStatus, callbackWeakBase = callbackWeakBase_, callback = callback_, this]() {
72                 IAM_LOGI("OnConnectStatus process begin");
73                 auto callbackSharedBase = callbackWeakBase.lock();
74                 IF_FALSE_LOGE_AND_RETURN(callbackSharedBase != nullptr);
75 
76                 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
77                 callback->OnConnectStatus(connectionName, connectStatus);
78                 IAM_LOGI("OnConnectStatus process success");
79             });
80         IAM_LOGI("task posted");
81     }
82 
83 private:
84     std::weak_ptr<BaseContext> callbackWeakBase_;
85     RemoteAuthInvokerContext *callback_;
86     std::shared_ptr<ThreadHandler> threadHandler_ = nullptr;
87 };
88 
RemoteAuthInvokerContext(uint64_t contextId,AuthParamInner authParam,RemoteAuthInvokerContextParam param,std::shared_ptr<ContextCallback> callback)89 RemoteAuthInvokerContext::RemoteAuthInvokerContext(uint64_t contextId, AuthParamInner authParam,
90     RemoteAuthInvokerContextParam param, std::shared_ptr<ContextCallback> callback)
91     : BaseContext("RemoteAuthInvokerContext", contextId, callback, true),
92       authParam_(authParam),
93       connectionName_(param.connectionName),
94       verifierNetworkId_(param.verifierNetworkId),
95       collectorNetworkId_(param.collectorNetworkId),
96       tokenId_(param.tokenId),
97       collectorTokenId_(param.collectorTokenId),
98       callerName_(param.callerName),
99       callerType_(param.callerType),
100       callback_(callback)
101 {
102     endPointName_ = REMOTE_AUTH_INVOKER_CONTEXT_ENDPOINT_NAME;
103     ThreadHandlerManager::GetInstance().CreateThreadHandler(connectionName_);
104 }
105 
~RemoteAuthInvokerContext()106 RemoteAuthInvokerContext::~RemoteAuthInvokerContext()
107 {
108     std::lock_guard<std::recursive_mutex> lock(mutex_);
109     if (cancelTimerId_.has_value()) {
110         RelativeTimer::GetInstance().Unregister(cancelTimerId_.value());
111     }
112     RemoteConnectionManager::GetInstance().UnregisterConnectionListener(connectionName_, endPointName_);
113     RemoteConnectionManager::GetInstance().CloseConnection(connectionName_);
114     ThreadHandlerManager::GetInstance().DestroyThreadHandler(connectionName_);
115     IAM_LOGI("%{public}s destroy", GetDescription());
116 }
117 
GetContextType() const118 ContextType RemoteAuthInvokerContext::GetContextType() const
119 {
120     return ContextType::REMOTE_AUTH_INVOKER_CONTEXT;
121 }
122 
GetTokenId() const123 uint32_t RemoteAuthInvokerContext::GetTokenId() const
124 {
125     return tokenId_;
126 }
127 
OnMessage(const std::string & connectionName,const std::string & srcEndPoint,const std::shared_ptr<Attributes> & request,std::shared_ptr<Attributes> & reply)128 void RemoteAuthInvokerContext::OnMessage(const std::string &connectionName, const std::string &srcEndPoint,
129     const std::shared_ptr<Attributes> &request, std::shared_ptr<Attributes> &reply)
130 {
131     std::lock_guard<std::recursive_mutex> lock(mutex_);
132 
133     int32_t msgType;
134     IF_FALSE_LOGE_AND_RETURN(request->GetInt32Value(Attributes::ATTR_MSG_TYPE, msgType));
135 
136     int32_t resultCode = ResultCode::GENERAL_ERROR;
137     switch (msgType) {
138         case SEND_REMOTE_AUTH_TIP:
139             resultCode = ProcAuthTipMsg(*request);
140             break;
141         case SEND_REMOTE_AUTH_RESULT:
142             resultCode = ProcAuthResultMsg(*request);
143             break;
144         default:
145             IAM_LOGE("%{public}s invalid msgType:%{public}d", GetDescription(), msgType);
146             break;
147     }
148 
149     IF_FALSE_LOGE_AND_RETURN(resultCode == ResultCode::SUCCESS);
150     IF_FALSE_LOGE_AND_RETURN(reply != nullptr);
151     bool setResultCodeRet = reply->SetInt32Value(Attributes::ATTR_RESULT_CODE, ResultCode::SUCCESS);
152     IF_FALSE_LOGE_AND_RETURN(setResultCodeRet);
153 }
154 
OnConnectStatus(const std::string & connectionName,ConnectStatus connectStatus)155 void RemoteAuthInvokerContext::OnConnectStatus(const std::string &connectionName, ConnectStatus connectStatus)
156 {
157     std::lock_guard<std::recursive_mutex> lock(mutex_);
158     IAM_LOGI("%{public}s start", GetDescription());
159     IF_FALSE_LOGE_AND_RETURN(callback_ != nullptr);
160 
161     Attributes attr;
162     if (connectStatus == ConnectStatus::DISCONNECTED) {
163         IAM_LOGI("%{public}s connection is disconnected", GetDescription());
164         callback_->SetTraceAuthFinishReason("RemoteAuthInvokerContext OnConnectStatus disconnected");
165         callback_->OnResult(ResultCode::GENERAL_ERROR, attr);
166         return;
167     } else {
168         IAM_LOGI("%{public}s connection is connected", GetDescription());
169         bool sendRequestRet = SendRequest();
170         if (!sendRequestRet) {
171             IAM_LOGE("%{public}s SendRequest failed", GetDescription());
172             callback_->SetTraceAuthFinishReason("RemoteAuthInvokerContext OnConnectStatus send message fail");
173             callback_->OnResult(GENERAL_ERROR, attr);
174             return;
175         }
176         IAM_LOGI("%{public}s connection is connected processed", GetDescription());
177     }
178 }
179 
SetVerifierContextId(uint64_t contextId)180 void RemoteAuthInvokerContext::SetVerifierContextId(uint64_t contextId)
181 {
182     std::lock_guard<std::recursive_mutex> lock(mutex_);
183     verifierContextId_ = contextId;
184     IAM_LOGI("%{public}s set verifierContextId %{public}s success", GetDescription(),
185         GET_MASKED_STRING(contextId).c_str());
186 }
187 
OnStart()188 bool RemoteAuthInvokerContext::OnStart()
189 {
190     std::lock_guard<std::recursive_mutex> lock(mutex_);
191     IAM_LOGI("%{public}s start", GetDescription());
192 
193     cancelTimerId_ = RelativeTimer::GetInstance().Register(
194         [weakThis = weak_from_this(), this]() {
195             auto sharedThis = weakThis.lock();
196             IF_FALSE_LOGE_AND_RETURN(sharedThis != nullptr);
197             OnTimeOut();
198         },
199         TIME_OUT_MS);
200 
201     bool getUdidRet = DeviceManagerUtil::GetInstance().GetUdidByNetworkId(verifierNetworkId_, verifierUdid_);
202     IF_FALSE_LOGE_AND_RETURN_VAL(getUdidRet, false);
203     IF_FALSE_LOGE_AND_RETURN_VAL(callback_ != nullptr, false);
204     callback_->SetTraceIsRemoteAuth(true);
205     callback_->SetTraceRemoteUdid(verifierUdid_);
206     callback_->SetTraceConnectionName(connectionName_);
207     std::string localUdid;
208     IF_FALSE_LOGE_AND_RETURN_VAL(DeviceManagerUtil::GetInstance().GetLocalDeviceUdid(localUdid), false);
209     callback_->SetTraceLocalUdid(localUdid);
210     endPointName_ = REMOTE_AUTH_INVOKER_CONTEXT_ENDPOINT_NAME;
211 
212     std::shared_ptr<RemoteAuthInvokerContextMessageCallback> callback =
213         Common::MakeShared<RemoteAuthInvokerContextMessageCallback>(shared_from_this(), this);
214     IF_FALSE_LOGE_AND_RETURN_VAL(callback != nullptr, false);
215 
216     ResultCode registerResult =
217         RemoteConnectionManager::GetInstance().RegisterConnectionListener(connectionName_, endPointName_, callback);
218     IF_FALSE_LOGE_AND_RETURN_VAL(registerResult == SUCCESS, false);
219 
220     ResultCode connectResult =
221         RemoteConnectionManager::GetInstance().OpenConnection(connectionName_, verifierNetworkId_, GetTokenId());
222     IF_FALSE_LOGE_AND_RETURN_VAL(connectResult == SUCCESS, false);
223 
224     IAM_LOGI("%{public}s success", GetDescription());
225     return true;
226 }
227 
SendRequest()228 bool RemoteAuthInvokerContext::SendRequest()
229 {
230     std::lock_guard<std::recursive_mutex> lock(mutex_);
231     IAM_LOGI("%{public}s start", GetDescription());
232 
233     request_ = Common::MakeShared<Attributes>();
234     IF_FALSE_LOGE_AND_RETURN_VAL(request_ != nullptr, false);
235 
236     bool setMsgTypeRet = request_->SetInt32Value(Attributes::ATTR_MSG_TYPE, START_REMOTE_AUTH);
237     IF_FALSE_LOGE_AND_RETURN_VAL(setMsgTypeRet, false);
238 
239     std::vector<int32_t> authTypes = { static_cast<int32_t>(authParam_.authType) };
240     bool getExecutorInfoRet = RemoteMsgUtil::GetQueryExecutorInfoReply(authTypes, COLLECTOR, verifierUdid_, *request_);
241     IF_FALSE_LOGE_AND_RETURN_VAL(getExecutorInfoRet, false);
242 
243     bool encodeAuthParamRet = RemoteMsgUtil::EncodeAuthParam(authParam_, *request_);
244     IF_FALSE_LOGE_AND_RETURN_VAL(encodeAuthParamRet, false);
245 
246     bool setTokenIdRet = request_->SetUint32Value(Attributes::ATTR_COLLECTOR_TOKEN_ID, collectorTokenId_);
247     IF_FALSE_LOGE_AND_RETURN_VAL(setTokenIdRet, false);
248 
249     bool setCallerNameRet = request_->SetStringValue(Attributes::ATTR_CALLER_NAME, callerName_);
250     IF_FALSE_LOGE_AND_RETURN_VAL(setCallerNameRet, false);
251 
252     bool setCallerTypeRet = request_->SetInt32Value(Attributes::ATTR_CALLER_TYPE, callerType_);
253     IF_FALSE_LOGE_AND_RETURN_VAL(setCallerTypeRet, false);
254 
255     bool setCollectorNetworkIdRet =
256         request_->SetStringValue(Attributes::ATTR_COLLECTOR_NETWORK_ID, collectorNetworkId_);
257     IF_FALSE_LOGE_AND_RETURN_VAL(setCollectorNetworkIdRet, false);
258 
259     MsgCallback msgCallback = [weakThis = weak_from_this(), this](const std::shared_ptr<Attributes> &reply) {
260         IF_FALSE_LOGE_AND_RETURN(reply != nullptr);
261 
262         auto sharedThis = weakThis.lock();
263         IF_FALSE_LOGE_AND_RETURN(sharedThis != nullptr);
264 
265         int32_t resultCode;
266         bool getResultCodeRet = reply->GetInt32Value(Attributes::ATTR_RESULT_CODE, resultCode);
267         IF_FALSE_LOGE_AND_RETURN(getResultCodeRet);
268 
269         if (resultCode != ResultCode::SUCCESS) {
270             IAM_LOGE("%{public}s start remote auth failed %{public}d", GetDescription(), resultCode);
271             Attributes attr;
272             callback_->SetTraceAuthFinishReason("RemoteAuthInvokerContext START_REMOTE_AUTH fail");
273             callback_->OnResult(resultCode, attr);
274             return;
275         }
276 
277         uint64_t contextId;
278         bool getContextIdRet = reply->GetUint64Value(Attributes::ATTR_CONTEXT_ID, contextId);
279         IF_FALSE_LOGE_AND_RETURN(getContextIdRet);
280 
281         this->SetVerifierContextId(contextId);
282         IAM_LOGI("%{public}s start remote auth success %{public}d", GetDescription(), resultCode);
283     };
284     IF_FALSE_LOGE_AND_RETURN_VAL(request_ != nullptr, false);
285     ResultCode sendMsgRet = RemoteConnectionManager::GetInstance().SendMessage(connectionName_, endPointName_,
286         REMOTE_SERVICE_ENDPOINT_NAME, request_, msgCallback);
287     IF_FALSE_LOGE_AND_RETURN_VAL(sendMsgRet == SUCCESS, false);
288 
289     IAM_LOGI("%{public}s success", GetDescription());
290     return true;
291 }
292 
OnResult(int32_t resultCode,const std::shared_ptr<Attributes> & scheduleResultAttr)293 void RemoteAuthInvokerContext::OnResult(int32_t resultCode, const std::shared_ptr<Attributes> &scheduleResultAttr)
294 {
295     IAM_LOGE("%{public}s this method is not supported", GetDescription());
296 }
297 
OnStop()298 bool RemoteAuthInvokerContext::OnStop()
299 {
300     std::lock_guard<std::recursive_mutex> lock(mutex_);
301     IAM_LOGI("%{public}s canceled", GetDescription());
302     Attributes attr;
303     IF_FALSE_LOGE_AND_RETURN_VAL(callback_ != nullptr, false);
304     callback_->SetTraceAuthFinishReason("RemoteAuthInvokerContext OnStop");
305     callback_->OnResult(ResultCode::CANCELED, attr);
306     // other module is canceled by disconnecting the connection
307 
308     IAM_LOGI("%{public}s success", GetDescription());
309     return true;
310 }
311 
ProcAuthTipMsg(Attributes & message)312 int32_t RemoteAuthInvokerContext::ProcAuthTipMsg(Attributes &message)
313 {
314     std::lock_guard<std::recursive_mutex> lock(mutex_);
315     IAM_LOGI("%{public}s start", GetDescription());
316 
317     int32_t destRole;
318     bool getDestRoleRet = message.GetInt32Value(Attributes::ATTR_DEST_ROLE, destRole);
319     IF_FALSE_LOGE_AND_RETURN_VAL(getDestRoleRet, ResultCode::GENERAL_ERROR);
320 
321     int32_t tipInfo;
322     bool getAcquireInfoRet = message.GetInt32Value(Attributes::ATTR_TIP_INFO, tipInfo);
323     IF_FALSE_LOGE_AND_RETURN_VAL(getAcquireInfoRet, ResultCode::GENERAL_ERROR);
324 
325     IF_FALSE_LOGE_AND_RETURN_VAL(callback_ != nullptr, ResultCode::GENERAL_ERROR);
326     callback_->OnAcquireInfo(static_cast<ExecutorRole>(destRole), tipInfo, message.Serialize());
327 
328     IAM_LOGI("%{public}s success", GetDescription());
329     return ResultCode::SUCCESS;
330 }
331 
ProcAuthResultMsgInner(Attributes & message,int32_t & resultCode,Attributes & attr)332 int32_t RemoteAuthInvokerContext::ProcAuthResultMsgInner(Attributes &message, int32_t &resultCode, Attributes &attr)
333 {
334     resultCode = GENERAL_ERROR;
335     bool getResultCodeRet = message.GetInt32Value(Attributes::ATTR_RESULT, resultCode);
336     IF_FALSE_LOGE_AND_RETURN_VAL(getResultCodeRet, ResultCode::GENERAL_ERROR);
337 
338     std::vector<uint8_t> remoteAuthResult;
339     bool getRemoteAuthResultRet = message.GetUint8ArrayValue(Attributes::ATTR_SIGNED_AUTH_RESULT, remoteAuthResult);
340     if (getRemoteAuthResultRet) {
341         auto hdi = HdiWrapper::GetHdiInstance();
342         IF_FALSE_LOGE_AND_RETURN_VAL(hdi != nullptr, ResultCode::GENERAL_ERROR);
343         HdiAuthResultInfo authResultInfo;
344         int32_t hdiRet = hdi->GetAuthResultFromMessage(verifierUdid_, remoteAuthResult, authResultInfo);
345         IF_FALSE_LOGE_AND_RETURN_VAL(hdiRet == SUCCESS, ResultCode::GENERAL_ERROR);
346 
347         resultCode = authResultInfo.result;
348         if (resultCode == ResultCode::FAIL || resultCode == ResultCode::LOCKED || resultCode == ResultCode::SUCCESS) {
349             bool setLockOutDurationRet =
350                 attr.SetInt32Value(Attributes::ATTR_LOCKOUT_DURATION, authResultInfo.lockoutDuration);
351             IF_FALSE_LOGE_AND_RETURN_VAL(setLockOutDurationRet, ResultCode::GENERAL_ERROR);
352             bool setRemainAttemptsRet =
353                 attr.SetInt32Value(Attributes::ATTR_REMAIN_ATTEMPTS, authResultInfo.remainAttempts);
354             IF_FALSE_LOGE_AND_RETURN_VAL(setRemainAttemptsRet, ResultCode::GENERAL_ERROR);
355         }
356         if (resultCode == ResultCode::SUCCESS) {
357             bool setTokenRet = attr.SetUint8ArrayValue(Attributes::ATTR_SIGNATURE, authResultInfo.token);
358             IF_FALSE_LOGE_AND_RETURN_VAL(setTokenRet, ResultCode::GENERAL_ERROR);
359             bool setUserId = attr.SetInt32Value(Attributes::ATTR_USER_ID, authResultInfo.userId);
360             IF_FALSE_LOGE_AND_RETURN_VAL(setUserId, ResultCode::GENERAL_ERROR);
361         }
362         IAM_LOGI("%{public}s parsed auth result: %{public}d, lockout duration %{public}d, "
363                  "remain attempts %{public}d, token size %{public}zu, user id %{public}d",
364             GetDescription(), resultCode, authResultInfo.lockoutDuration, authResultInfo.remainAttempts,
365             authResultInfo.token.size(), authResultInfo.userId);
366     } else if (resultCode == ResultCode::SUCCESS) {
367         IAM_LOGE("%{public}s remote auth result is empty, set result GENERAL_ERROR", GetDescription());
368         resultCode = ResultCode::GENERAL_ERROR;
369     }
370 
371     IAM_LOGI("%{public}s result code %{public}d", GetDescription(), resultCode);
372     bool setResultCodeRet = attr.SetInt32Value(Attributes::ATTR_RESULT, resultCode);
373     IF_FALSE_LOGE_AND_RETURN_VAL(setResultCodeRet, ResultCode::GENERAL_ERROR);
374 
375     return ResultCode::SUCCESS;
376 }
377 
ProcAuthResultMsg(Attributes & message)378 int32_t RemoteAuthInvokerContext::ProcAuthResultMsg(Attributes &message)
379 {
380     std::lock_guard<std::recursive_mutex> lock(mutex_);
381     IAM_LOGI("%{public}s start", GetDescription());
382 
383     int32_t authResultCode = GENERAL_ERROR;
384     Attributes attr;
385 
386     int32_t ret = ProcAuthResultMsgInner(message, authResultCode, attr);
387 
388     callback_->SetTraceAuthFinishReason("RemoteAuthInvokerContext ProcAuthResultMsg");
389     callback_->OnResult(authResultCode, attr);
390 
391     IAM_LOGI("%{public}s success", GetDescription());
392     return ret;
393 }
394 
OnTimeOut()395 void RemoteAuthInvokerContext::OnTimeOut()
396 {
397     IAM_LOGI("%{public}s timeout", GetDescription());
398     IF_FALSE_LOGE_AND_RETURN(callback_ != nullptr);
399 
400     Attributes attr;
401     callback_->SetTraceAuthFinishReason("RemoteAuthInvokerContext OnTimeOut");
402     callback_->OnResult(TIMEOUT, attr);
403 }
404 } // namespace UserAuth
405 } // namespace UserIam
406 } // namespace OHOS