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