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