• 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 "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