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_service.h"
17 
18 #include "iam_check.h"
19 #include "iam_logger.h"
20 #include "iam_para2str.h"
21 
22 #include "context_factory.h"
23 #include "context_helper.h"
24 #include "context_pool.h"
25 #include "device_manager_util.h"
26 #include "hdi_wrapper.h"
27 #include "iam_defines.h"
28 #include "iam_para2str.h"
29 #include "iam_ptr.h"
30 #include "remote_executor_stub.h"
31 #include "remote_iam_callback.h"
32 #include "remote_msg_util.h"
33 
34 #define LOG_TAG "USER_AUTH_SA"
35 
36 namespace OHOS {
37 namespace UserIam {
38 namespace UserAuth {
39 class RemoteAuthServiceImpl : public RemoteAuthService {
40 public:
41     static RemoteAuthServiceImpl &GetInstance();
42     RemoteAuthServiceImpl() = default;
43     ~RemoteAuthServiceImpl() override = default;
44 
45     bool Start() override;
46     void OnMessage(const std::string &connectionName, const std::string &srcEndPoint,
47         const std::shared_ptr<Attributes> &request, std::shared_ptr<Attributes> &reply) override;
48 
49     int32_t ProcStartRemoteAuthRequest(std::string connectionName, const std::shared_ptr<Attributes> &request,
50         std::shared_ptr<Attributes> &reply) override;
51     int32_t ProcQueryExecutorInfoRequest(const std::shared_ptr<Attributes> &request,
52         std::shared_ptr<Attributes> &reply) override;
53     int32_t ProcBeginExecuteRequest(const std::shared_ptr<Attributes> &request,
54         std::shared_ptr<Attributes> &reply) override;
55     int32_t ProcEndExecuteRequest(const std::shared_ptr<Attributes> &request,
56         std::shared_ptr<Attributes> &reply) override;
57 
58     uint64_t StartRemoteAuthContext(Authentication::AuthenticationPara para,
59         RemoteAuthContextParam remoteAuthContextParam,
60         const std::shared_ptr<ContextCallback> &contextCallback, int &lastError) override;
61 
62 private:
63     std::recursive_mutex mutex_;
64     std::map<uint64_t, std::shared_ptr<RemoteExecutorStub>> scheduleId2executorStub_;
65 };
66 
67 class RemoteAuthServiceImplConnectionListener : public ConnectionListener {
68 public:
69     RemoteAuthServiceImplConnectionListener() = default;
70     ~RemoteAuthServiceImplConnectionListener() override = default;
71 
OnMessage(const std::string & connectionName,const std::string & srcEndPoint,const std::shared_ptr<Attributes> & request,std::shared_ptr<Attributes> & reply)72     void OnMessage(const std::string &connectionName, const std::string &srcEndPoint,
73         const std::shared_ptr<Attributes> &request, std::shared_ptr<Attributes> &reply) override
74     {
75         IF_FALSE_LOGE_AND_RETURN(request != nullptr);
76         IF_FALSE_LOGE_AND_RETURN(reply != nullptr);
77 
78         IAM_LOGI("connectionName: %{public}s, srcEndPoint: %{public}s", connectionName.c_str(), srcEndPoint.c_str());
79 
80         RemoteAuthServiceImpl::GetInstance().OnMessage(connectionName, srcEndPoint, request, reply);
81     }
82 
OnConnectStatus(const std::string & connectionName,ConnectStatus connectStatus)83     void OnConnectStatus(const std::string &connectionName, ConnectStatus connectStatus) override
84     {
85     }
86 };
87 
GetInstance()88 RemoteAuthServiceImpl &RemoteAuthServiceImpl::GetInstance()
89 {
90     static RemoteAuthServiceImpl remoteAuthServiceImpl;
91     return remoteAuthServiceImpl;
92 }
93 
Start()94 bool RemoteAuthServiceImpl::Start()
95 {
96     std::lock_guard<std::recursive_mutex> lock(mutex_);
97     IAM_LOGI("start");
98 
99     static auto callback = Common::MakeShared<RemoteAuthServiceImplConnectionListener>();
100     IF_FALSE_LOGE_AND_RETURN_VAL(callback != nullptr, false);
101     ResultCode registerResult = RemoteConnectionManager::GetInstance().RegisterConnectionListener(
102         REMOTE_SERVICE_ENDPOINT_NAME, callback);
103     IF_FALSE_LOGE_AND_RETURN_VAL(registerResult == SUCCESS, false);
104     IAM_LOGI("success");
105     return true;
106 }
107 
OnMessage(const std::string & connectionName,const std::string & srcEndPoint,const std::shared_ptr<Attributes> & request,std::shared_ptr<Attributes> & reply)108 void RemoteAuthServiceImpl::OnMessage(const std::string &connectionName, const std::string &srcEndPoint,
109     const std::shared_ptr<Attributes> &request, std::shared_ptr<Attributes> &reply)
110 {
111     IAM_LOGI("start");
112     std::lock_guard<std::recursive_mutex> lock(mutex_);
113 
114     IF_FALSE_LOGE_AND_RETURN(request != nullptr);
115     IF_FALSE_LOGE_AND_RETURN(reply != nullptr);
116 
117     int32_t msgType;
118     bool getMsgTypeRet = request->GetInt32Value(Attributes::ATTR_MSG_TYPE, msgType);
119     IF_FALSE_LOGE_AND_RETURN(getMsgTypeRet);
120 
121     IAM_LOGI("msgType is %{public}d", msgType);
122     int32_t resultCode = ResultCode::GENERAL_ERROR;
123     switch (msgType) {
124         case START_REMOTE_AUTH:
125             resultCode = ProcStartRemoteAuthRequest(connectionName, request, reply);
126             break;
127         case QUERY_EXECUTOR_INFO:
128             resultCode = ProcQueryExecutorInfoRequest(request, reply);
129             break;
130         case BEGIN_EXECUTE:
131             resultCode = ProcBeginExecuteRequest(request, reply);
132             break;
133         case END_EXECUTE:
134             resultCode = ProcEndExecuteRequest(request, reply);
135             break;
136         case KEEP_ALIVE:
137             resultCode = SUCCESS;
138             break;
139         default:
140             IAM_LOGE("unsupported request type: %{public}d", msgType);
141             break;
142     }
143 
144     bool setResultCodeRet = reply->SetInt32Value(Attributes::ATTR_RESULT_CODE, resultCode);
145     IF_FALSE_LOGE_AND_RETURN(setResultCodeRet);
146 
147     IAM_LOGI("success, msg result %{public}d", resultCode);
148 }
149 
StartRemoteAuthContext(Authentication::AuthenticationPara para,RemoteAuthContextParam remoteAuthContextParam,const std::shared_ptr<ContextCallback> & contextCallback,int & lastError)150 uint64_t RemoteAuthServiceImpl::StartRemoteAuthContext(Authentication::AuthenticationPara para,
151     RemoteAuthContextParam remoteAuthContextParam, const std::shared_ptr<ContextCallback> &contextCallback,
152     int &lastError)
153 {
154     IAM_LOGI("start");
155     IF_FALSE_LOGE_AND_RETURN_VAL(contextCallback != nullptr, BAD_CONTEXT_ID);
156     Attributes extraInfo;
157     std::shared_ptr<Context> context = ContextFactory::CreateRemoteAuthContext(para, remoteAuthContextParam,
158         contextCallback);
159     if (context == nullptr || !ContextPool::Instance().Insert(context)) {
160         IAM_LOGE("failed to insert context");
161         contextCallback->OnResult(GENERAL_ERROR, extraInfo);
162         return BAD_CONTEXT_ID;
163     }
164     contextCallback->SetCleaner(ContextHelper::Cleaner(context));
165 
166     if (!context->Start()) {
167         lastError = context->GetLatestError();
168         IAM_LOGE("failed to start auth errorCode:%{public}d", lastError);
169         return BAD_CONTEXT_ID;
170     }
171     lastError = SUCCESS;
172     IAM_LOGI("success");
173     return context->GetContextId();
174 }
175 
ProcStartRemoteAuthRequest(std::string connectionName,const std::shared_ptr<Attributes> & request,std::shared_ptr<Attributes> & reply)176 int32_t RemoteAuthServiceImpl::ProcStartRemoteAuthRequest(std::string connectionName,
177     const std::shared_ptr<Attributes> &request, std::shared_ptr<Attributes> &reply)
178 {
179     std::lock_guard<std::recursive_mutex> lock(mutex_);
180     IAM_LOGI("start");
181     AuthParamInner authParam = {};
182     bool getAuthParamRet = RemoteMsgUtil::DecodeAuthParam(*request, authParam);
183     IF_FALSE_LOGE_AND_RETURN_VAL(getAuthParamRet, GENERAL_ERROR);
184 
185     std::string collectorNetworkId;
186     bool getCollectorNetworkIdRet = request->GetStringValue(Attributes::ATTR_COLLECTOR_NETWORK_ID, collectorNetworkId);
187     IF_FALSE_LOGE_AND_RETURN_VAL(getCollectorNetworkIdRet, GENERAL_ERROR);
188 
189     uint32_t collectorTokenId;
190     bool getCollectorTokenIdRet = request->GetUint32Value(Attributes::ATTR_COLLECTOR_TOKEN_ID, collectorTokenId);
191     IF_FALSE_LOGE_AND_RETURN_VAL(getCollectorTokenIdRet, GENERAL_ERROR);
192 
193     Authentication::AuthenticationPara para = {};
194     para.userId = authParam.userId;
195     para.authType = authParam.authType;
196     para.atl = authParam.authTrustLevel;
197     para.collectorTokenId = collectorTokenId;
198     para.challenge = authParam.challenge;
199     para.sdkVersion = INNER_API_VERSION_10000;
200 
201     bool getCallerNameRet = request->GetStringValue(Attributes::ATTR_CALLER_NAME, para.callerName);
202     IF_FALSE_LOGE_AND_RETURN_VAL(getCallerNameRet, GENERAL_ERROR);
203     bool getCallerTypeRet = request->GetInt32Value(Attributes::ATTR_CALLER_TYPE, para.callerType);
204     IF_FALSE_LOGE_AND_RETURN_VAL(getCallerTypeRet, GENERAL_ERROR);
205 
206     RemoteAuthContextParam remoteAuthContextParam;
207     remoteAuthContextParam.authType = authParam.authType;
208     remoteAuthContextParam.connectionName = connectionName;
209     remoteAuthContextParam.collectorNetworkId = collectorNetworkId;
210     remoteAuthContextParam.executorInfoMsg = request->Serialize();
211 
212     sptr<IamCallbackInterface> callback(new RemoteIamCallback(connectionName));
213     IF_FALSE_LOGE_AND_RETURN_VAL(callback != nullptr, GENERAL_ERROR);
214 
215     auto contextCallback = ContextCallback::NewInstance(callback, NO_NEED_TRACE);
216     IF_FALSE_LOGE_AND_RETURN_VAL(contextCallback != nullptr, GENERAL_ERROR);
217 
218     int32_t lastError;
219     auto contextId = StartRemoteAuthContext(para, remoteAuthContextParam, contextCallback, lastError);
220     IF_FALSE_LOGE_AND_RETURN_VAL(contextId != BAD_CONTEXT_ID, lastError);
221 
222     bool setContextIdRet = reply->SetUint64Value(Attributes::ATTR_CONTEXT_ID, contextId);
223     IF_FALSE_LOGE_AND_RETURN_VAL(setContextIdRet, GENERAL_ERROR);
224 
225     IAM_LOGI("success");
226     return SUCCESS;
227 }
228 
ProcQueryExecutorInfoRequest(const std::shared_ptr<Attributes> & request,std::shared_ptr<Attributes> & reply)229 int32_t RemoteAuthServiceImpl::ProcQueryExecutorInfoRequest(const std::shared_ptr<Attributes> &request,
230     std::shared_ptr<Attributes> &reply)
231 {
232     std::lock_guard<std::recursive_mutex> lock(mutex_);
233     IAM_LOGI("start");
234 
235     std::vector<int32_t> authTypes;
236     bool getAuthTypesRet = request->GetInt32ArrayValue(Attributes::ATTR_AUTH_TYPES, authTypes);
237     IF_FALSE_LOGE_AND_RETURN_VAL(getAuthTypesRet, GENERAL_ERROR);
238 
239     int32_t executorRole;
240     bool getExecutorRoleRet = request->GetInt32Value(Attributes::ATTR_EXECUTOR_ROLE, executorRole);
241     IF_FALSE_LOGE_AND_RETURN_VAL(getExecutorRoleRet, GENERAL_ERROR);
242 
243     std::string srcUdid;
244     bool getSrcUdidRet = request->GetStringValue(Attributes::ATTR_MSG_SRC_UDID, srcUdid);
245     IF_FALSE_LOGE_AND_RETURN_VAL(getSrcUdidRet, GENERAL_ERROR);
246 
247     bool getQueryExecutorInfoRet = RemoteMsgUtil::GetQueryExecutorInfoReply(authTypes, executorRole, srcUdid, *reply);
248     IF_FALSE_LOGE_AND_RETURN_VAL(getQueryExecutorInfoRet, GENERAL_ERROR);
249 
250     IAM_LOGI("success");
251     return SUCCESS;
252 }
253 
ProcBeginExecuteRequest(const std::shared_ptr<Attributes> & request,std::shared_ptr<Attributes> & reply)254 int32_t RemoteAuthServiceImpl::ProcBeginExecuteRequest(const std::shared_ptr<Attributes> &request,
255     std::shared_ptr<Attributes> &reply)
256 {
257     std::lock_guard<std::recursive_mutex> lock(mutex_);
258     IAM_LOGI("start");
259 
260     std::shared_ptr<RemoteExecutorStub> executorStub = Common::MakeShared<RemoteExecutorStub>();
261     IF_FALSE_LOGE_AND_RETURN_VAL(executorStub != nullptr, GENERAL_ERROR);
262 
263     int32_t resultCode = executorStub->ProcBeginExecuteRequest(*request);
264     IF_FALSE_LOGE_AND_RETURN_VAL(resultCode == SUCCESS, GENERAL_ERROR);
265 
266     uint64_t scheduleId;
267     bool getScheduleIdRet = request->GetUint64Value(Attributes::ATTR_SCHEDULE_ID, scheduleId);
268     IF_FALSE_LOGE_AND_RETURN_VAL(getScheduleIdRet, GENERAL_ERROR);
269 
270     scheduleId2executorStub_.emplace(scheduleId, executorStub);
271     IAM_LOGI("scheduleId %{public}s begin execute success", GET_MASKED_STRING(scheduleId).c_str());
272     return SUCCESS;
273 }
274 
ProcEndExecuteRequest(const std::shared_ptr<Attributes> & request,std::shared_ptr<Attributes> & reply)275 int32_t RemoteAuthServiceImpl::ProcEndExecuteRequest(const std::shared_ptr<Attributes> &request,
276     std::shared_ptr<Attributes> &reply)
277 {
278     std::lock_guard<std::recursive_mutex> lock(mutex_);
279     IAM_LOGI("start");
280 
281     uint64_t scheduleId;
282     bool getScheduleIdRet = request->GetUint64Value(Attributes::ATTR_SCHEDULE_ID, scheduleId);
283     IF_FALSE_LOGE_AND_RETURN_VAL(getScheduleIdRet, GENERAL_ERROR);
284 
285     auto it = scheduleId2executorStub_.find(scheduleId);
286     IF_FALSE_LOGE_AND_RETURN_VAL(it != scheduleId2executorStub_.end(), GENERAL_ERROR);
287     scheduleId2executorStub_.erase(it);
288     IAM_LOGI("scheduleId %{public}s end execute success", GET_MASKED_STRING(scheduleId).c_str());
289     return SUCCESS;
290 }
291 
GetInstance()292 RemoteAuthService &RemoteAuthService::GetInstance()
293 {
294     RemoteAuthServiceImpl &impl = RemoteAuthServiceImpl::GetInstance();
295     return impl;
296 }
297 } // namespace UserAuth
298 } // namespace UserIam
299 } // namespace OHOS
300