• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 #include "sec_comp_client.h"
16 
17 #include "iservice_registry.h"
18 #include "sec_comp_load_callback.h"
19 #include "sec_comp_log.h"
20 #include "sec_comp_proxy.h"
21 
22 namespace OHOS {
23 namespace Security {
24 namespace SecurityComponent {
25 namespace {
26 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_SECURITY_COMPONENT, "SecCompClient"};
27 }  // namespace
28 
GetInstance()29 SecCompClient& SecCompClient::GetInstance()
30 {
31     static SecCompClient instance;
32     return instance;
33 }
34 
SecCompClient()35 SecCompClient::SecCompClient()
36 {}
37 
~SecCompClient()38 SecCompClient::~SecCompClient()
39 {
40     if (proxy_ == nullptr) {
41         return;
42     }
43     auto remoteObj = proxy_->AsObject();
44     if ((remoteObj != nullptr) && (serviceDeathObserver_ != nullptr)) {
45         remoteObj->RemoveDeathRecipient(serviceDeathObserver_);
46     }
47 }
48 
RegisterSecurityComponent(SecCompType type,const std::string & componentInfo,int32_t & scId)49 int32_t SecCompClient::RegisterSecurityComponent(SecCompType type,
50     const std::string& componentInfo, int32_t& scId)
51 {
52     auto proxy = GetProxy(true);
53     if (proxy == nullptr) {
54         SC_LOG_ERROR(LABEL, "Proxy is null");
55         return SC_SERVICE_ERROR_VALUE_INVALID;
56     }
57 
58     return proxy->RegisterSecurityComponent(type, componentInfo, scId);
59 }
60 
UpdateSecurityComponent(int32_t scId,const std::string & componentInfo)61 int32_t SecCompClient::UpdateSecurityComponent(int32_t scId, const std::string& componentInfo)
62 {
63     auto proxy = GetProxy(true);
64     if (proxy == nullptr) {
65         SC_LOG_ERROR(LABEL, "Proxy is null");
66         return SC_SERVICE_ERROR_VALUE_INVALID;
67     }
68 
69     return proxy->UpdateSecurityComponent(scId, componentInfo);
70 }
71 
UnregisterSecurityComponent(int32_t scId)72 int32_t SecCompClient::UnregisterSecurityComponent(int32_t scId)
73 {
74     auto proxy = GetProxy(true);
75     if (proxy == nullptr) {
76         SC_LOG_ERROR(LABEL, "Proxy is null");
77         return SC_SERVICE_ERROR_VALUE_INVALID;
78     }
79 
80     return proxy->UnregisterSecurityComponent(scId);
81 }
82 
ReportSecurityComponentClickEvent(int32_t scId,const std::string & componentInfo,const SecCompClickEvent & clickInfo,sptr<IRemoteObject> callerToken)83 int32_t SecCompClient::ReportSecurityComponentClickEvent(int32_t scId,
84     const std::string& componentInfo, const SecCompClickEvent& clickInfo, sptr<IRemoteObject> callerToken)
85 {
86     auto proxy = GetProxy(true);
87     if (proxy == nullptr) {
88         SC_LOG_ERROR(LABEL, "Proxy is null");
89         return SC_SERVICE_ERROR_VALUE_INVALID;
90     }
91 
92     return proxy->ReportSecurityComponentClickEvent(scId, componentInfo, clickInfo, callerToken);
93 }
94 
VerifySavePermission(AccessToken::AccessTokenID tokenId)95 bool SecCompClient::VerifySavePermission(AccessToken::AccessTokenID tokenId)
96 {
97     auto proxy = GetProxy(false);
98     if (proxy == nullptr) {
99         SC_LOG_ERROR(LABEL, "Proxy is null");
100         return false;
101     }
102 
103     return proxy->VerifySavePermission(tokenId);
104 }
105 
GetEnhanceRemoteObject(bool doLoadSa)106 sptr<IRemoteObject> SecCompClient::GetEnhanceRemoteObject(bool doLoadSa)
107 {
108     auto proxy = GetProxy(doLoadSa);
109     if (proxy == nullptr) {
110         return nullptr;
111     }
112 
113     return proxy->GetEnhanceRemoteObject();
114 }
115 
PreRegisterSecCompProcess()116 int32_t SecCompClient::PreRegisterSecCompProcess()
117 {
118     auto proxy = GetProxy(true);
119     if (proxy == nullptr) {
120         SC_LOG_ERROR(LABEL, "Proxy is null");
121         return SC_SERVICE_ERROR_VALUE_INVALID;
122     }
123 
124     return proxy->PreRegisterSecCompProcess();
125 }
126 
StartLoadSecCompSa()127 bool SecCompClient::StartLoadSecCompSa()
128 {
129     {
130         std::unique_lock<std::mutex> lock(cvLock_);
131         readyFlag_ = false;
132     }
133     auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
134     if (sam == nullptr) {
135         SC_LOG_ERROR(LABEL, "GetSystemAbilityManager return null");
136         return false;
137     }
138     sptr<SecCompLoadCallback> ptrSecCompLoadCallback =
139         new (std::nothrow) SecCompLoadCallback();
140     if (ptrSecCompLoadCallback == nullptr) {
141         SC_LOG_ERROR(LABEL, "New ptrSecCompLoadCallback fail.");
142         return false;
143     }
144 
145     int32_t result = sam->LoadSystemAbility(SA_ID_SECURITY_COMPONENT_SERVICE,
146         ptrSecCompLoadCallback);
147     if (result != SC_OK) {
148         SC_LOG_ERROR(LABEL, "LoadSystemAbility %{public}d failed", SA_ID_SECURITY_COMPONENT_SERVICE);
149         return false;
150     }
151     SC_LOG_INFO(LABEL, "Notify samgr load sa %{public}d, waiting for service start", SA_ID_SECURITY_COMPONENT_SERVICE);
152     return true;
153 }
154 
TryToGetSecCompSa()155 bool SecCompClient::TryToGetSecCompSa()
156 {
157     auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
158     if (sam == nullptr) {
159         SC_LOG_ERROR(LABEL, "GetSystemAbilityManager return null");
160         return false;
161     }
162 
163     auto secCompSa = sam->CheckSystemAbility(SA_ID_SECURITY_COMPONENT_SERVICE);
164     if (secCompSa == nullptr) {
165         SC_LOG_INFO(LABEL, "Service is not start.");
166         return false;
167     }
168     GetProxyFromRemoteObject(secCompSa);
169     return true;
170 }
171 
WaitForSecCompSa()172 void SecCompClient::WaitForSecCompSa()
173 {
174     // wait_for release lock and block until time out(1s) or match the condition with notice
175     std::unique_lock<std::mutex> lock(cvLock_);
176     auto waitStatus = secComCon_.wait_for(
177         lock, std::chrono::milliseconds(SA_ID_SECURITY_COMPONENT_SERVICE), [this]() { return readyFlag_; });
178     if (!waitStatus) {
179         // time out or loadcallback fail
180         SC_LOG_ERROR(LABEL, "security component load sa timeout");
181         return;
182     }
183 }
184 
FinishStartSASuccess(const sptr<IRemoteObject> & remoteObject)185 void SecCompClient::FinishStartSASuccess(const sptr<IRemoteObject>& remoteObject)
186 {
187     GetProxyFromRemoteObject(remoteObject);
188     // get lock which wait_for release and send a notice so that wait_for can out of block
189     std::unique_lock<std::mutex> lock(cvLock_);
190     readyFlag_ = true;
191     secComCon_.notify_one();
192 }
193 
FinishStartSAFail()194 void SecCompClient::FinishStartSAFail()
195 {
196     SC_LOG_ERROR(LABEL, "get security component sa failed.");
197     // get lock which wait_for release and send a notice
198     std::unique_lock<std::mutex> lock(cvLock_);
199     readyFlag_ = true;
200     secComCon_.notify_one();
201 }
202 
LoadSecCompSa()203 void SecCompClient::LoadSecCompSa()
204 {
205     if (!StartLoadSecCompSa()) {
206         return;
207     }
208     WaitForSecCompSa();
209 }
210 
OnRemoteDiedHandle()211 void SecCompClient::OnRemoteDiedHandle()
212 {
213     SC_LOG_ERROR(LABEL, "Remote service died");
214     std::unique_lock<std::mutex> lock(proxyMutex_);
215     proxy_ = nullptr;
216     serviceDeathObserver_ = nullptr;
217     {
218         std::unique_lock<std::mutex> lock1(cvLock_);
219         readyFlag_ = false;
220     }
221 }
222 
GetProxyFromRemoteObject(const sptr<IRemoteObject> & remoteObject)223 void SecCompClient::GetProxyFromRemoteObject(const sptr<IRemoteObject>& remoteObject)
224 {
225     if (remoteObject == nullptr) {
226         return;
227     }
228 
229     sptr<SecCompDeathRecipient> serviceDeathObserver = new (std::nothrow) SecCompDeathRecipient();
230     if (serviceDeathObserver == nullptr) {
231         SC_LOG_ERROR(LABEL, "Alloc service death observer fail");
232         return;
233     }
234 
235     if (!remoteObject->AddDeathRecipient(serviceDeathObserver)) {
236         SC_LOG_ERROR(LABEL, "Add service death observer fail");
237         return;
238     }
239 
240     auto proxy = iface_cast<ISecCompService>(remoteObject);
241     if (proxy == nullptr) {
242         SC_LOG_ERROR(LABEL, "iface_cast get null");
243         return;
244     }
245     proxy_ = proxy;
246     serviceDeathObserver_ = serviceDeathObserver;
247     SC_LOG_INFO(LABEL, "GetSystemAbility %{public}d success", SA_ID_SECURITY_COMPONENT_SERVICE);
248     return;
249 }
250 
GetProxy(bool doLoadSa)251 sptr<ISecCompService> SecCompClient::GetProxy(bool doLoadSa)
252 {
253     std::unique_lock<std::mutex> lock(proxyMutex_);
254     if (proxy_ != nullptr) {
255         return proxy_;
256     }
257     if (TryToGetSecCompSa() || !doLoadSa) {
258         return proxy_;
259     }
260 
261     LoadSecCompSa();
262     return proxy_;
263 }
264 }  // namespace SecurityComponent
265 }  // namespace Security
266 }  // namespace OHOS
267