• 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 & touchInfo,sptr<IRemoteObject> callerToken)83 int32_t SecCompClient::ReportSecurityComponentClickEvent(int32_t scId,
84     const std::string& componentInfo, const SecCompClickEvent& touchInfo, 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, touchInfo, callerToken);
93 }
94 
ReduceAfterVerifySavePermission(AccessToken::AccessTokenID tokenId)95 bool SecCompClient::ReduceAfterVerifySavePermission(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->ReduceAfterVerifySavePermission(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 
StartLoadSecCompSa()116 bool SecCompClient::StartLoadSecCompSa()
117 {
118     {
119         std::unique_lock<std::mutex> lock(cvLock_);
120         readyFlag_ = false;
121     }
122     auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
123     if (sam == nullptr) {
124         SC_LOG_ERROR(LABEL, "GetSystemAbilityManager return null");
125         return false;
126     }
127     sptr<SecCompLoadCallback> ptrSecCompLoadCallback =
128         new (std::nothrow) SecCompLoadCallback();
129     if (ptrSecCompLoadCallback == nullptr) {
130         SC_LOG_ERROR(LABEL, "New ptrSecCompLoadCallback fail.");
131         return false;
132     }
133 
134     int32_t result = sam->LoadSystemAbility(SA_ID_SECURITY_COMPONENT_SERVICE,
135         ptrSecCompLoadCallback);
136     if (result != SC_OK) {
137         SC_LOG_ERROR(LABEL, "LoadSystemAbility %{public}d failed", SA_ID_SECURITY_COMPONENT_SERVICE);
138         return false;
139     }
140     SC_LOG_INFO(LABEL, "Notify samgr load sa %{public}d, waiting for service start", SA_ID_SECURITY_COMPONENT_SERVICE);
141     return true;
142 }
143 
TryToGetSecCompSa()144 bool SecCompClient::TryToGetSecCompSa()
145 {
146     auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
147     if (sam == nullptr) {
148         SC_LOG_ERROR(LABEL, "GetSystemAbilityManager return null");
149         return false;
150     }
151 
152     auto secCompSa = sam->CheckSystemAbility(SA_ID_SECURITY_COMPONENT_SERVICE);
153     if (secCompSa == nullptr) {
154         SC_LOG_INFO(LABEL, "Service is not start.");
155         return false;
156     }
157     GetProxyFromRemoteObject(secCompSa);
158     return true;
159 }
160 
WaitForSecCompSa()161 void SecCompClient::WaitForSecCompSa()
162 {
163     // wait_for release lock and block until time out(1s) or match the condition with notice
164     std::unique_lock<std::mutex> lock(cvLock_);
165     auto waitStatus = secComCon_.wait_for(
166         lock, std::chrono::milliseconds(SA_ID_SECURITY_COMPONENT_SERVICE), [this]() { return readyFlag_; });
167     if (!waitStatus) {
168         // time out or loadcallback fail
169         SC_LOG_ERROR(LABEL, "security component load sa timeout");
170         return;
171     }
172 }
173 
FinishStartSASuccess(const sptr<IRemoteObject> & remoteObject)174 void SecCompClient::FinishStartSASuccess(const sptr<IRemoteObject>& remoteObject)
175 {
176     GetProxyFromRemoteObject(remoteObject);
177     // get lock which wait_for release and send a notice so that wait_for can out of block
178     std::unique_lock<std::mutex> lock(cvLock_);
179     readyFlag_ = true;
180     secComCon_.notify_one();
181 }
182 
FinishStartSAFail()183 void SecCompClient::FinishStartSAFail()
184 {
185     SC_LOG_ERROR(LABEL, "get security component sa failed.");
186     // get lock which wait_for release and send a notice
187     std::unique_lock<std::mutex> lock(cvLock_);
188     readyFlag_ = true;
189     secComCon_.notify_one();
190 }
191 
LoadSecCompSa()192 void SecCompClient::LoadSecCompSa()
193 {
194     if (!StartLoadSecCompSa()) {
195         return;
196     }
197     WaitForSecCompSa();
198 }
199 
OnRemoteDiedHandle()200 void SecCompClient::OnRemoteDiedHandle()
201 {
202     SC_LOG_ERROR(LABEL, "Remote service died");
203     std::unique_lock<std::mutex> lock(proxyMutex_);
204     proxy_ = nullptr;
205     serviceDeathObserver_ = nullptr;
206     {
207         std::unique_lock<std::mutex> lock1(cvLock_);
208         readyFlag_ = false;
209     }
210 }
211 
GetProxyFromRemoteObject(const sptr<IRemoteObject> & remoteObject)212 void SecCompClient::GetProxyFromRemoteObject(const sptr<IRemoteObject>& remoteObject)
213 {
214     if (remoteObject == nullptr) {
215         return;
216     }
217 
218     sptr<SecCompDeathRecipient> serviceDeathObserver = new (std::nothrow) SecCompDeathRecipient();
219     if (serviceDeathObserver == nullptr) {
220         SC_LOG_ERROR(LABEL, "Alloc service death observer fail");
221         return;
222     }
223 
224     if (!remoteObject->AddDeathRecipient(serviceDeathObserver)) {
225         SC_LOG_ERROR(LABEL, "Add service death observer fail");
226         return;
227     }
228 
229     auto proxy = iface_cast<ISecCompService>(remoteObject);
230     if (proxy == nullptr) {
231         SC_LOG_ERROR(LABEL, "iface_cast get null");
232         return;
233     }
234     proxy_ = proxy;
235     serviceDeathObserver_ = serviceDeathObserver;
236     SC_LOG_INFO(LABEL, "GetSystemAbility %{public}d success", SA_ID_SECURITY_COMPONENT_SERVICE);
237     return;
238 }
239 
GetProxy(bool doLoadSa)240 sptr<ISecCompService> SecCompClient::GetProxy(bool doLoadSa)
241 {
242     std::unique_lock<std::mutex> lock(proxyMutex_);
243     if (proxy_ != nullptr) {
244         return proxy_;
245     }
246     if (TryToGetSecCompSa() || !doLoadSa) {
247         return proxy_;
248     }
249 
250     LoadSecCompSa();
251     return proxy_;
252 }
253 }  // namespace SecurityComponent
254 }  // namespace Security
255 }  // namespace OHOS
256