• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "co_auth_service.h"
17 
18 #include <cinttypes>
19 #include <thread>
20 
21 #include "string_ex.h"
22 
23 #include "device_manager_util.h"
24 #include "driver_state_manager.h"
25 #include "executor_messenger_service.h"
26 #include "hdi_message_callback_service.h"
27 #include "hdi_wrapper.h"
28 #include "hisysevent_adapter.h"
29 #include "iam_logger.h"
30 #include "iam_ptr.h"
31 #include "iam_para2str.h"
32 #include "ipc_common.h"
33 #include "iam_check.h"
34 #include "iam_time.h"
35 #include "iam_common_defines.h"
36 #include "ipc_skeleton.h"
37 #include "load_mode_handler.h"
38 #include "parameter.h"
39 #include "relative_timer.h"
40 #include "remote_connect_manager.h"
41 #include "risk_event_manager.h"
42 #include "service_init_manager.h"
43 #include "system_param_manager.h"
44 #include "template_cache_manager.h"
45 #include "remote_msg_util.h"
46 #include "xcollie_helper.h"
47 
48 #define LOG_TAG "USER_AUTH_SA"
49 
50 namespace OHOS {
51 namespace UserIam {
52 namespace UserAuth {
53 namespace {
54 const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(CoAuthService::GetInstance().get());
55 } // namespace
56 
57 constexpr int32_t USERIAM_IPC_THREAD_NUM = 4;
58 std::shared_ptr<CoAuthService> CoAuthService::instance_ = nullptr;
59 
GetInstance()60 std::shared_ptr<CoAuthService> CoAuthService::GetInstance()
61 {
62     static std::recursive_mutex mutex;
63     if (instance_ == nullptr) {
64         std::lock_guard<std::recursive_mutex> guard(mutex);
65         if (instance_ == nullptr) {
66             instance_ = Common::MakeShared<CoAuthService>();
67             if (instance_ == nullptr) {
68                 IAM_LOGE("make share failed");
69             }
70         }
71     }
72     return instance_;
73 }
74 
CoAuthService()75 CoAuthService::CoAuthService()
76     : SystemAbility(SUBSYS_USERIAM_SYS_ABILITY_AUTHEXECUTORMGR, true), CoAuthStub(true)
77 {
78     IAM_LOGI("CoAuthService init");
79 }
80 
OnStart()81 void CoAuthService::OnStart()
82 {
83     std::lock_guard<std::recursive_mutex> guard(mutex_);
84     IAM_LOGI("Sa start CoAuthService");
85     IPCSkeleton::SetMaxWorkThreadNum(USERIAM_IPC_THREAD_NUM);
86     if (!Publish(this)) {
87         IAM_LOGE("Failed to publish service");
88         return;
89     }
90 
91     ServiceInitManager::GetInstance().OnCoAuthServiceStart();
92 }
93 
OnStop()94 void CoAuthService::OnStop()
95 {
96     IAM_LOGI("Sa stop CoAuthService");
97     ServiceInitManager::GetInstance().OnCoAuthServiceStop();
98 }
99 
SetIsReady(bool isReady)100 void CoAuthService::SetIsReady(bool isReady)
101 {
102     std::lock_guard<std::recursive_mutex> guard(mutex_);
103     isReady_ = isReady;
104     IAM_LOGI("Set isReady %{public}d", isReady);
105 }
106 
SetAccessTokenReady(bool isReady)107 void CoAuthService::SetAccessTokenReady(bool isReady)
108 {
109     std::lock_guard<std::recursive_mutex> guard(mutex_);
110     accessTokenReady_ = isReady;
111     IAM_LOGI("Set accesstk ready %{public}d", isReady);
112 }
113 
IsFwkReady()114 bool CoAuthService::IsFwkReady()
115 {
116     std::lock_guard<std::recursive_mutex> guard(mutex_);
117     return isReady_ && accessTokenReady_;
118 }
119 
AddExecutorDeathRecipient(uint64_t executorIndex,AuthType authType,ExecutorRole role,std::shared_ptr<IExecutorCallback> callback)120 void CoAuthService::AddExecutorDeathRecipient(uint64_t executorIndex, AuthType authType, ExecutorRole role,
121     std::shared_ptr<IExecutorCallback> callback)
122 {
123     IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
124     auto obj = callback->AsObject();
125     IF_FALSE_LOGE_AND_RETURN(obj != nullptr);
126 
127     obj->AddDeathRecipient(new (std::nothrow) IpcCommon::PeerDeathRecipient([executorIndex, authType, role]() {
128         IAM_LOGE("executorCallback is down");
129         auto weakNode = ResourceNodePool::Instance().Select(executorIndex);
130         auto sharedNode = weakNode.lock();
131         if (sharedNode != nullptr) {
132             auto result = ResourceNodePool::Instance().Delete(executorIndex);
133             IAM_LOGI("delete executor %{public}s, executorIndex is ****%{public}hx authType is %{public}d "
134                 "executorRole is %{public}d", (result ? "succ" : "failed"), static_cast<uint16_t>(executorIndex),
135                 sharedNode->GetAuthType(), sharedNode->GetExecutorRole());
136         }
137         LoadModeHandler::GetInstance().OnExecutorUnregistered(authType, role);
138         std::string executorDesc = "executor, type " + std::to_string(authType);
139         UserIam::UserAuth::ReportSystemFault(Common::GetNowTimeString(), executorDesc);
140         IAM_LOGI("executorCallback is down processed");
141     }));
142 }
143 
ProcExecutorRegisterSuccess(std::shared_ptr<ResourceNode> & resourceNode,const std::shared_ptr<IExecutorCallback> & callback,std::vector<uint64_t> & templateIdList,std::vector<uint8_t> & fwkPublicKey)144 int32_t CoAuthService::ProcExecutorRegisterSuccess(std::shared_ptr<ResourceNode> &resourceNode,
145     const std::shared_ptr<IExecutorCallback> &callback, std::vector<uint64_t> &templateIdList,
146     std::vector<uint8_t> &fwkPublicKey)
147 {
148     IAM_LOGI("start");
149     uint64_t executorIndex = resourceNode->GetExecutorIndex();
150     auto handler = ThreadHandler::GetSingleThreadInstance();
151     std::weak_ptr<ResourceNode> weakNode = resourceNode;
152     IF_FALSE_LOGE_AND_RETURN_VAL(handler != nullptr, GENERAL_ERROR);
153     handler->PostTask([callback, fwkPublicKey, templateIdList, weakNode, executorIndex]() {
154         auto resourceNode = weakNode.lock();
155         IF_FALSE_LOGE_AND_RETURN(resourceNode != nullptr);
156         sptr<IExecutorMessenger> messenger = ExecutorMessengerService::GetInstance();
157         callback->OnMessengerReady(messenger, fwkPublicKey, templateIdList);
158         IAM_LOGI("register successful, executorType is %{public}d, executorRole is %{public}d, "
159             "executorIndex is ****%{public}hx",
160             resourceNode->GetAuthType(), resourceNode->GetExecutorRole(), static_cast<uint16_t>(executorIndex));
161         LoadModeHandler::GetInstance().OnExecutorRegistered(resourceNode->GetAuthType(),
162             resourceNode->GetExecutorRole());
163         AddExecutorDeathRecipient(executorIndex, resourceNode->GetAuthType(), resourceNode->GetExecutorRole(),
164             callback);
165         IAM_LOGI("update template cache after register success");
166         TemplateCacheManager::GetInstance().UpdateTemplateCache(resourceNode->GetAuthType());
167         RiskEventManager::GetInstance().SyncRiskEvents();
168     });
169 
170     return SUCCESS;
171 }
172 
ExecutorRegister(const IpcExecutorRegisterInfo & ipcExecutorRegisterInfo,const sptr<IExecutorCallback> & executorCallback,uint64_t & executorIndex)173 int32_t CoAuthService::ExecutorRegister(const IpcExecutorRegisterInfo &ipcExecutorRegisterInfo,
174     const sptr<IExecutorCallback> &executorCallback, uint64_t &executorIndex)
175 {
176     IAM_LOGI("register resource node begin");
177     executorIndex = INVALID_EXECUTOR_INDEX;
178     Common::XCollieHelper xcollie(__FUNCTION__, Common::API_CALL_TIMEOUT);
179     if (executorCallback == nullptr) {
180         IAM_LOGE("executor callback is nullptr");
181         return INVALID_PARAMETERS;
182     }
183 
184     std::lock_guard<std::recursive_mutex> guard(mutex_);
185     if (!IsFwkReady()) {
186         IAM_LOGE("framework is not ready");
187         return GENERAL_ERROR;
188     }
189 
190     if (!IpcCommon::CheckPermission(*this, ACCESS_AUTH_RESPOOL)) {
191         IAM_LOGE("failed to check permission");
192         return CHECK_PERMISSION_FAILED;
193     }
194 
195     std::vector<uint64_t> templateIdList;
196     std::vector<uint8_t> fwkPublicKey;
197     ExecutorRegisterInfo executorRegisterInfo = {};
198     InitExecutorRegisterInfo(ipcExecutorRegisterInfo, executorRegisterInfo);
199     sptr<IExecutorCallback> tempCallBack = executorCallback;
200     auto callback = Common::SptrToStdSharedPtr<IExecutorCallback>(tempCallBack);
201     auto resourceNode = ResourceNode::MakeNewResource(executorRegisterInfo, callback,
202         templateIdList, fwkPublicKey);
203     if (resourceNode == nullptr) {
204         IAM_LOGE("create resource node failed");
205         return GENERAL_ERROR;
206     }
207     if (!ResourceNodePool::Instance().Insert(resourceNode)) {
208         IAM_LOGE("insert resource node failed");
209         return GENERAL_ERROR;
210     }
211     executorIndex = resourceNode->GetExecutorIndex();
212     return ProcExecutorRegisterSuccess(resourceNode, callback, templateIdList, fwkPublicKey);
213 }
214 
ExecutorUnregister(uint64_t executorIndex)215 int32_t CoAuthService::ExecutorUnregister(uint64_t executorIndex)
216 {
217     IAM_LOGI("delete resource node begin");
218     Common::XCollieHelper xcollie(__FUNCTION__, Common::API_CALL_TIMEOUT);
219     std::lock_guard<std::recursive_mutex> guard(mutex_);
220     if (!IsFwkReady()) {
221         IAM_LOGE("framework is not ready");
222         return SUCCESS;
223     }
224 
225     if (!IpcCommon::CheckPermission(*this, ACCESS_AUTH_RESPOOL)) {
226         IAM_LOGE("failed to check permission");
227         return CHECK_PERMISSION_FAILED;
228     }
229 
230     {
231         auto resourceNode = ResourceNodePool::Instance().Select(executorIndex).lock();
232         IF_FALSE_LOGE_AND_RETURN_VAL(resourceNode != nullptr, GENERAL_ERROR);
233         LoadModeHandler::GetInstance().OnExecutorUnregistered(resourceNode->GetAuthType(),
234             resourceNode->GetExecutorRole());
235     }
236 
237     if (!ResourceNodePool::Instance().Delete(executorIndex)) {
238         IAM_LOGE("delete resource node failed");
239         return GENERAL_ERROR;
240     }
241     IAM_LOGI("delete resource node success, executorIndex is ****%{public}hx", static_cast<uint16_t>(executorIndex));
242     return SUCCESS;
243 }
244 
OnDriverStart()245 void CoAuthService::OnDriverStart()
246 {
247     std::lock_guard<std::recursive_mutex> guard(mutex_);
248     IAM_LOGI("process driver start begin");
249     if (isReady_) {
250         IAM_LOGI("already ready");
251         return;
252     }
253     std::string localUdid;
254     bool getLocalUdidRet = DeviceManagerUtil::GetInstance().GetLocalDeviceUdid(localUdid);
255     IF_FALSE_LOGE_AND_RETURN(getLocalUdidRet);
256     auto service = HdiWrapper::GetHdiInstance();
257     IF_FALSE_LOGE_AND_RETURN(service != nullptr);
258     int32_t initRet = service->Init(localUdid);
259     IF_FALSE_LOGE_AND_RETURN(initRet == HDF_SUCCESS);
260     auto callbackService = HdiMessageCallbackService::GetInstance();
261     IF_FALSE_LOGE_AND_RETURN(callbackService != nullptr);
262     callbackService->OnHdiConnect();
263     SetIsReady(true);
264     NotifyFwkReady();
265     IAM_LOGI("process driver start success");
266 }
267 
OnDriverStop()268 void CoAuthService::OnDriverStop()
269 {
270     std::lock_guard<std::recursive_mutex> guard(mutex_);
271     IAM_LOGE("process driver stop begin");
272     if (isReady_) {
273         IAM_LOGI("service is ready, clear status");
274         ResourceNodePool::Instance().DeleteAll();
275         UserIam::UserAuth::ReportSystemFault(Common::GetNowTimeString(), "user_auth_hdi host");
276         SetIsReady(false);
277     }
278     IAM_LOGI("process driver stop success");
279 }
280 
Dump(int fd,const std::vector<std::u16string> & args)281 int CoAuthService::Dump(int fd, const std::vector<std::u16string> &args)
282 {
283     IAM_LOGI("start");
284     if (fd < 0) {
285         IAM_LOGE("invalid parameters");
286         return INVALID_PARAMETERS;
287     }
288     std::string arg0 = (args.empty() ? "" : Str16ToStr8(args[0]));
289     if (arg0.empty() || arg0.compare("-h") == 0) {
290         dprintf(fd, "Usage:\n");
291         dprintf(fd, "      -h: command help.\n");
292         dprintf(fd, "      -l: resource pool dump.\n");
293         return SUCCESS;
294     }
295     if (arg0.compare("-l") == 0) {
296         ResourceNodePool::Instance().Enumerate([fd](const std::weak_ptr<ResourceNode> &node) {
297             auto nodeTmp = node.lock();
298             if (nodeTmp != nullptr) {
299                 dprintf(fd, "ExecutorIndex is: %" PRIx64 ".\n", nodeTmp->GetExecutorIndex());
300                 dprintf(fd, "ExecutorType is: %s.\n", Common::AuthTypeToStr(nodeTmp->GetAuthType()));
301                 dprintf(fd, "ExecutorRole is: %s.\n", Common::ExecutorRoleToStr(nodeTmp->GetExecutorRole()));
302             }
303         });
304         return SUCCESS;
305     }
306     IAM_LOGE("invalid option");
307     dprintf(fd, "Invalid option\n");
308     return GENERAL_ERROR;
309 }
310 
RegisterAccessTokenListener()311 ResultCode CoAuthService::RegisterAccessTokenListener()
312 {
313     IAM_LOGD("start.");
314     std::lock_guard<std::recursive_mutex> lock(mutex_);
315     if (accessTokenListener_ != nullptr) {
316         IAM_LOGI("accessTokenListener_ is not nullptr.");
317         return SUCCESS;
318     }
319 
320     accessTokenListener_ = SystemAbilityListener::Subscribe("accesstoken_service", ACCESS_TOKEN_MANAGER_SERVICE_ID,
321         []() {
322             auto instance = CoAuthService::GetInstance();
323             if (instance == nullptr) {
324                 IAM_LOGE("CoAuthService instance is nullptr.");
325                 return;
326             }
327             instance->SetAccessTokenReady(true);
328             instance->NotifyFwkReady();
329         },
330         nullptr);
331     if (accessTokenListener_ == nullptr) {
332         IAM_LOGE("accessTokenListener_ is nullptr.");
333         return GENERAL_ERROR;
334     }
335 
336     IAM_LOGI("RegisterAccessTokenListener success.");
337     return SUCCESS;
338 }
339 
UnRegisterAccessTokenListener()340 ResultCode CoAuthService::UnRegisterAccessTokenListener()
341 {
342     IAM_LOGD("start.");
343     std::lock_guard<std::recursive_mutex> lock(mutex_);
344     if (accessTokenListener_ == nullptr) {
345         IAM_LOGI("accessTokenListener_ is nullptr.");
346         return SUCCESS;
347     }
348 
349     int32_t ret = SystemAbilityListener::UnSubscribe(ACCESS_TOKEN_MANAGER_SERVICE_ID, accessTokenListener_);
350     if (ret != SUCCESS) {
351         IAM_LOGE("UnSubscribe service fail.");
352         return GENERAL_ERROR;
353     }
354 
355     accessTokenListener_ = nullptr;
356     IAM_LOGI("UnRegisterAccessTokenListener success.");
357     return SUCCESS;
358 }
359 
NotifyFwkReady()360 void CoAuthService::NotifyFwkReady()
361 {
362     IAM_LOGD("start.");
363     if (IsFwkReady()) {
364         LoadModeHandler::GetInstance().OnFwkReady();
365     }
366 }
367 
InitExecutorRegisterInfo(const IpcExecutorRegisterInfo & ipcExecutorRegisterInfo,ExecutorRegisterInfo & executorRegisterInfo)368 void CoAuthService::InitExecutorRegisterInfo(const IpcExecutorRegisterInfo &ipcExecutorRegisterInfo,
369     ExecutorRegisterInfo &executorRegisterInfo)
370 {
371     executorRegisterInfo.authType = static_cast<AuthType>(ipcExecutorRegisterInfo.authType);
372     executorRegisterInfo.executorRole = static_cast<ExecutorRole>(ipcExecutorRegisterInfo.executorRole);
373     executorRegisterInfo.executorSensorHint = ipcExecutorRegisterInfo.executorSensorHint;
374     executorRegisterInfo.executorMatcher = ipcExecutorRegisterInfo.executorMatcher;
375     executorRegisterInfo.esl = static_cast<ExecutorSecureLevel>(ipcExecutorRegisterInfo.esl);
376     executorRegisterInfo.maxTemplateAcl = ipcExecutorRegisterInfo.maxTemplateAcl;
377     executorRegisterInfo.publicKey = ipcExecutorRegisterInfo.publicKey;
378     executorRegisterInfo.deviceUdid = ipcExecutorRegisterInfo.deviceUdid;
379     executorRegisterInfo.signedRemoteExecutorInfo = ipcExecutorRegisterInfo.signedRemoteExecutorInfo;
380 }
381 
CallbackEnter(uint32_t code)382 int32_t CoAuthService::CallbackEnter([[maybe_unused]] uint32_t code)
383 {
384     IAM_LOGI("start, code:%{public}u", code);
385     return SUCCESS;
386 }
387 
CallbackExit(uint32_t code,int32_t result)388 int32_t CoAuthService::CallbackExit([[maybe_unused]] uint32_t code, [[maybe_unused]] int32_t result)
389 {
390     IAM_LOGI("leave, code:%{public}u, result:%{public}d", code, result);
391     return SUCCESS;
392 }
393 } // namespace UserAuth
394 } // namespace UserIam
395 } // namespace OHOS