1 /*
2 * Copyright (c) 2023-2024 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
16 #include "dlp_permission_client.h"
17 #include <unistd.h>
18 #include "accesstoken_kit.h"
19 #include "dlp_permission_async_stub.h"
20 #include "dlp_permission_load_callback.h"
21 #include "dlp_permission_log.h"
22 #include "dlp_permission_proxy.h"
23 #include "ipc_skeleton.h"
24 #include "iservice_registry.h"
25 #include "os_account_manager.h"
26 #include "permission_policy.h"
27 #include "token_setproc.h"
28
29 namespace OHOS {
30 namespace Security {
31 namespace DlpPermission {
32 using namespace OHOS::Security::AccessToken;
33 namespace {
34 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_DLP_PERMISSION, "DlpPermissionClient"};
35 static const int32_t DLP_PERMISSION_LOAD_SA_TIMEOUT_MS = 4000;
36 static const uint32_t MAX_CALLBACK_MAP_SIZE = 100;
37 static const std::string GRANT_SENSITIVE_PERMISSIONS = "ohos.permission.GRANT_SENSITIVE_PERMISSIONS";
38
CheckSandboxFlag(AccessToken::AccessTokenID tokenId,bool & sandboxFlag)39 static int32_t CheckSandboxFlag(AccessToken::AccessTokenID tokenId, bool& sandboxFlag)
40 {
41 int32_t res = AccessToken::AccessTokenKit::GetHapDlpFlag(tokenId);
42 if (res < 0) {
43 DLP_LOG_ERROR(LABEL, "Invalid tokenId");
44 return res;
45 }
46 sandboxFlag = (res == 1);
47 return DLP_OK;
48 }
49 } // namespace
50
GetInstance()51 DlpPermissionClient& DlpPermissionClient::GetInstance()
52 {
53 static DlpPermissionClient instance;
54 return instance;
55 }
56
DlpPermissionClient()57 DlpPermissionClient::DlpPermissionClient()
58 {}
59
~DlpPermissionClient()60 DlpPermissionClient::~DlpPermissionClient()
61 {
62 CleanUpResource();
63 }
64
CleanUpResource()65 void DlpPermissionClient::CleanUpResource()
66 {
67 std::unique_lock<std::mutex> lock(proxyMutex_);
68 if (proxy_ == nullptr) {
69 return;
70 }
71 auto remoteObj = proxy_->AsObject();
72 if (remoteObj == nullptr) {
73 return;
74 }
75 if (serviceDeathObserver_ != nullptr) {
76 remoteObj->RemoveDeathRecipient(serviceDeathObserver_);
77 }
78 }
79
CleanUp()80 extern "C" __attribute__((destructor)) void CleanUp()
81 {
82 DlpPermissionClient::GetInstance().CleanUpResource();
83 }
84
GenerateDlpCertificate(const PermissionPolicy & policy,std::shared_ptr<GenerateDlpCertificateCallback> callback)85 int32_t DlpPermissionClient::GenerateDlpCertificate(
86 const PermissionPolicy& policy, std::shared_ptr<GenerateDlpCertificateCallback> callback)
87 {
88 if (!policy.IsValid() || callback == nullptr) {
89 return DLP_SERVICE_ERROR_VALUE_INVALID;
90 }
91 auto proxy = GetProxy(true);
92 if (proxy == nullptr) {
93 DLP_LOG_ERROR(LABEL, "Proxy is null");
94 return DLP_SERVICE_ERROR_SERVICE_NOT_EXIST;
95 }
96
97 sptr<DlpPolicyParcel> policyParcel = new (std::nothrow) DlpPolicyParcel();
98 if (policyParcel == nullptr) {
99 DLP_LOG_ERROR(LABEL, "New memory fail");
100 return DLP_SERVICE_ERROR_MEMORY_OPERATE_FAIL;
101 }
102 policyParcel->policyParams_.CopyPermissionPolicy(policy);
103
104 sptr<IDlpPermissionCallback> asyncStub = new (std::nothrow) DlpPermissionAsyncStub(callback);
105 if (asyncStub == nullptr) {
106 DLP_LOG_ERROR(LABEL, "New memory fail");
107 return DLP_SERVICE_ERROR_MEMORY_OPERATE_FAIL;
108 }
109
110 return proxy->GenerateDlpCertificate(policyParcel, asyncStub);
111 }
112
ParseDlpCertificate(sptr<CertParcel> & certParcel,std::shared_ptr<ParseDlpCertificateCallback> callback,const std::string & appId,const bool & offlineAccess)113 int32_t DlpPermissionClient::ParseDlpCertificate(sptr<CertParcel>& certParcel,
114 std::shared_ptr<ParseDlpCertificateCallback> callback, const std::string& appId, const bool& offlineAccess)
115 {
116 if (callback == nullptr || certParcel->cert.size() == 0) {
117 return DLP_SERVICE_ERROR_VALUE_INVALID;
118 }
119 auto proxy = GetProxy(true);
120 if (proxy == nullptr) {
121 DLP_LOG_ERROR(LABEL, "Proxy is null");
122 return DLP_SERVICE_ERROR_SERVICE_NOT_EXIST;
123 }
124
125 sptr<IDlpPermissionCallback> asyncStub = new (std::nothrow) DlpPermissionAsyncStub(callback);
126 if (asyncStub == nullptr) {
127 DLP_LOG_ERROR(LABEL, "New memory fail");
128 return DLP_SERVICE_ERROR_MEMORY_OPERATE_FAIL;
129 }
130
131 return proxy->ParseDlpCertificate(certParcel, asyncStub, appId, offlineAccess);
132 }
133
InstallDlpSandbox(const std::string & bundleName,DLPFileAccess dlpFileAccess,int32_t userId,SandboxInfo & sandboxInfo,const std::string & uri)134 int32_t DlpPermissionClient::InstallDlpSandbox(const std::string& bundleName, DLPFileAccess dlpFileAccess,
135 int32_t userId, SandboxInfo& sandboxInfo, const std::string& uri)
136 {
137 if (bundleName.empty() || dlpFileAccess > FULL_CONTROL || dlpFileAccess <= NO_PERMISSION || uri.empty()) {
138 return DLP_SERVICE_ERROR_VALUE_INVALID;
139 }
140 auto proxy = GetProxy(true);
141 if (proxy == nullptr) {
142 DLP_LOG_ERROR(LABEL, "Proxy is null");
143 return DLP_SERVICE_ERROR_SERVICE_NOT_EXIST;
144 }
145
146 return proxy->InstallDlpSandbox(bundleName, dlpFileAccess, userId, sandboxInfo, uri);
147 }
148
UninstallDlpSandbox(const std::string & bundleName,int32_t appIndex,int32_t userId)149 int32_t DlpPermissionClient::UninstallDlpSandbox(const std::string& bundleName, int32_t appIndex, int32_t userId)
150 {
151 if (bundleName.empty() || appIndex < 0 || userId < 0) {
152 return DLP_SERVICE_ERROR_VALUE_INVALID;
153 }
154 auto proxy = GetProxy(true);
155 if (proxy == nullptr) {
156 DLP_LOG_ERROR(LABEL, "Proxy is null");
157 return DLP_SERVICE_ERROR_SERVICE_NOT_EXIST;
158 }
159
160 return proxy->UninstallDlpSandbox(bundleName, appIndex, userId);
161 }
162
CheckAllowAbilityList(const std::string & bundleName)163 static bool CheckAllowAbilityList(const std::string& bundleName)
164 {
165 int32_t userId;
166 int32_t res = OHOS::AccountSA::OsAccountManager::GetForegroundOsAccountLocalId(userId);
167 if (res != 0) {
168 DLP_LOG_ERROR(LABEL, "GetForegroundOsAccountLocalId failed %{public}d", res);
169 return false;
170 }
171 AccessTokenID tokenId = AccessTokenKit::GetHapTokenID(userId, bundleName, 0);
172 if (tokenId == 0) {
173 DLP_LOG_ERROR(LABEL, "GetHapTokenID is 0");
174 return false;
175 }
176 return PERMISSION_GRANTED == AccessTokenKit::VerifyAccessToken(tokenId, GRANT_SENSITIVE_PERMISSIONS);
177 }
178
GetSandboxExternalAuthorization(int sandboxUid,const AAFwk::Want & want,SandBoxExternalAuthorType & auth)179 int32_t DlpPermissionClient::GetSandboxExternalAuthorization(
180 int sandboxUid, const AAFwk::Want& want, SandBoxExternalAuthorType& auth)
181 {
182 bool sandboxFlag;
183 if (CheckSandboxFlag(IPCSkeleton::GetCallingTokenID(), sandboxFlag) != DLP_OK) {
184 return DLP_SERVICE_ERROR_VALUE_INVALID;
185 }
186 if (!sandboxFlag) {
187 DLP_LOG_ERROR(LABEL, "Forbid called by a non-sandbox app");
188 return DLP_SERVICE_ERROR_API_ONLY_FOR_SANDBOX_ERROR;
189 }
190 if (CheckAllowAbilityList(want.GetBundle())) {
191 auth = ALLOW_START_ABILITY;
192 return DLP_OK;
193 }
194 auto proxy = GetProxy(false);
195 if (proxy == nullptr) {
196 DLP_LOG_ERROR(LABEL, "Proxy is null, dlpmanager service no start.");
197 return DLP_SERVICE_ERROR_SERVICE_NOT_EXIST;
198 }
199
200 if (sandboxUid < 0) {
201 return DLP_SERVICE_ERROR_VALUE_INVALID;
202 }
203
204 return proxy->GetSandboxExternalAuthorization(sandboxUid, want, auth);
205 }
206
QueryDlpFileCopyableByTokenId(bool & copyable,uint32_t tokenId)207 int32_t DlpPermissionClient::QueryDlpFileCopyableByTokenId(bool& copyable, uint32_t tokenId)
208 {
209 bool sandboxFlag;
210 if ((tokenId == 0) || (CheckSandboxFlag(tokenId, sandboxFlag) != DLP_OK)) {
211 return DLP_SERVICE_ERROR_VALUE_INVALID;
212 }
213
214 if (!sandboxFlag) {
215 DLP_LOG_INFO(LABEL, "it is not a sandbox app");
216 copyable = true;
217 return DLP_OK;
218 }
219
220 auto proxy = GetProxy(false);
221 if (proxy == nullptr) {
222 DLP_LOG_ERROR(LABEL, "Proxy is null");
223 copyable = false;
224 return DLP_OK;
225 }
226
227 return proxy->QueryDlpFileCopyableByTokenId(copyable, tokenId);
228 }
229
QueryDlpFileAccess(DLPPermissionInfo & permInfo)230 int32_t DlpPermissionClient::QueryDlpFileAccess(DLPPermissionInfo& permInfo)
231 {
232 bool sandboxFlag;
233 if (CheckSandboxFlag(GetSelfTokenID(), sandboxFlag) != DLP_OK) {
234 return DLP_SERVICE_ERROR_VALUE_INVALID;
235 }
236 if (!sandboxFlag) {
237 DLP_LOG_ERROR(LABEL, "Forbid called by a non-sandbox app");
238 return DLP_SERVICE_ERROR_API_ONLY_FOR_SANDBOX_ERROR;
239 }
240
241 auto proxy = GetProxy(false);
242 if (proxy == nullptr) {
243 DLP_LOG_INFO(LABEL, "Proxy is null");
244 return DLP_OK;
245 }
246 sptr<DLPPermissionInfoParcel> permInfoyParcel = new (std::nothrow) DLPPermissionInfoParcel();
247 if (permInfoyParcel == nullptr) {
248 DLP_LOG_ERROR(LABEL, "New memory fail");
249 return DLP_SERVICE_ERROR_MEMORY_OPERATE_FAIL;
250 }
251
252 int32_t result = proxy->QueryDlpFileAccess(*permInfoyParcel);
253 if (result != DLP_OK) {
254 return result;
255 }
256 permInfo = permInfoyParcel->permInfo_;
257 return result;
258 }
259
IsInDlpSandbox(bool & inSandbox)260 int32_t DlpPermissionClient::IsInDlpSandbox(bool& inSandbox)
261 {
262 bool sandboxFlag;
263 if (CheckSandboxFlag(GetSelfTokenID(), sandboxFlag) != DLP_OK) {
264 return DLP_SERVICE_ERROR_VALUE_INVALID;
265 }
266
267 if (!sandboxFlag) {
268 DLP_LOG_INFO(LABEL, "it is not a sandbox app");
269 inSandbox = false;
270 return DLP_OK;
271 }
272
273 auto proxy = GetProxy(false);
274 if (proxy == nullptr) {
275 DLP_LOG_ERROR(LABEL, "Proxy is null");
276 inSandbox = true;
277 return DLP_OK;
278 }
279
280 return proxy->IsInDlpSandbox(inSandbox);
281 }
282
GetDlpSupportFileType(std::vector<std::string> & supportFileType)283 int32_t DlpPermissionClient::GetDlpSupportFileType(std::vector<std::string>& supportFileType)
284 {
285 auto proxy = GetProxy(true);
286 if (proxy == nullptr) {
287 DLP_LOG_INFO(LABEL, "Proxy is null");
288 return DLP_OK;
289 }
290
291 return proxy->GetDlpSupportFileType(supportFileType);
292 }
293
CreateDlpSandboxChangeCallback(const std::shared_ptr<DlpSandboxChangeCallbackCustomize> & customizedCb,sptr<DlpSandboxChangeCallback> & callback)294 int32_t DlpPermissionClient::CreateDlpSandboxChangeCallback(
295 const std::shared_ptr<DlpSandboxChangeCallbackCustomize> &customizedCb, sptr<DlpSandboxChangeCallback> &callback)
296 {
297 callback = new (std::nothrow) DlpSandboxChangeCallback(customizedCb);
298 if (callback == nullptr) {
299 DLP_LOG_ERROR(LABEL, "memory allocation for callback failed!");
300 return DLP_CALLBACK_SA_WORK_ABNORMAL;
301 }
302 return DLP_OK;
303 }
304
RegisterDlpSandboxChangeCallback(const std::shared_ptr<DlpSandboxChangeCallbackCustomize> & customizedCb)305 int32_t DlpPermissionClient::RegisterDlpSandboxChangeCallback(
306 const std::shared_ptr<DlpSandboxChangeCallbackCustomize> &customizedCb)
307 {
308 if (customizedCb == nullptr) {
309 DLP_LOG_ERROR(LABEL, "customizedCb is nullptr");
310 return DLP_SERVICE_ERROR_VALUE_INVALID;
311 }
312 sptr<DlpSandboxChangeCallback> callback = nullptr;
313 int32_t result = CreateDlpSandboxChangeCallback(customizedCb, callback);
314 if (result != DLP_OK) {
315 return result;
316 }
317 auto proxy = GetProxy(false);
318 if (proxy == nullptr) {
319 DLP_LOG_ERROR(LABEL, "proxy is null");
320 return DLP_CALLBACK_SA_WORK_ABNORMAL;
321 }
322 return proxy->RegisterDlpSandboxChangeCallback(callback->AsObject());
323 }
324
UnregisterDlpSandboxChangeCallback(bool & result)325 int32_t DlpPermissionClient::UnregisterDlpSandboxChangeCallback(bool &result)
326 {
327 auto proxy = GetProxy(false);
328 if (proxy == nullptr) {
329 DLP_LOG_ERROR(LABEL, "proxy is null");
330 return DLP_CALLBACK_SA_WORK_ABNORMAL;
331 }
332
333 return proxy->UnRegisterDlpSandboxChangeCallback(result);
334 }
335
CreateOpenDlpFileCallback(const std::shared_ptr<OpenDlpFileCallbackCustomize> & customizedCb,sptr<OpenDlpFileCallback> & callback)336 int32_t DlpPermissionClient::CreateOpenDlpFileCallback(
337 const std::shared_ptr<OpenDlpFileCallbackCustomize>& customizedCb, sptr<OpenDlpFileCallback>& callback)
338 {
339 std::lock_guard<std::mutex> lock(callbackMutex_);
340 if (callbackMap_.size() == MAX_CALLBACK_MAP_SIZE) {
341 DLP_LOG_ERROR(LABEL, "the maximum number of callback has been reached");
342 return DLP_SERVICE_ERROR_VALUE_INVALID;
343 }
344
345 auto goalCallback = callbackMap_.find(customizedCb);
346 if (goalCallback != callbackMap_.end()) {
347 DLP_LOG_ERROR(LABEL, "already has the same callback");
348 return DLP_SERVICE_ERROR_VALUE_INVALID;
349 } else {
350 callback = new (std::nothrow) OpenDlpFileCallback(customizedCb);
351 if (!callback) {
352 DLP_LOG_ERROR(LABEL, "memory allocation for callback failed!");
353 return DLP_SERVICE_ERROR_MEMORY_OPERATE_FAIL;
354 }
355 }
356 return DLP_OK;
357 }
358
RegisterOpenDlpFileCallback(const std::shared_ptr<OpenDlpFileCallbackCustomize> & callback)359 int32_t DlpPermissionClient::RegisterOpenDlpFileCallback(const std::shared_ptr<OpenDlpFileCallbackCustomize>& callback)
360 {
361 bool sandboxFlag;
362 if (CheckSandboxFlag(GetSelfTokenID(), sandboxFlag) != DLP_OK) {
363 return DLP_SERVICE_ERROR_VALUE_INVALID;
364 }
365 if (sandboxFlag) {
366 DLP_LOG_ERROR(LABEL, "Forbid called by a sandbox app");
367 return DLP_SERVICE_ERROR_API_NOT_FOR_SANDBOX_ERROR;
368 }
369 if (callback == nullptr) {
370 DLP_LOG_ERROR(LABEL, "callback is nullptr");
371 return DLP_SERVICE_ERROR_VALUE_INVALID;
372 }
373 sptr<OpenDlpFileCallback> cb = nullptr;
374 int32_t result = CreateOpenDlpFileCallback(callback, cb);
375 if (result != DLP_OK) {
376 return result;
377 }
378 auto proxy = GetProxy(true);
379 if (proxy == nullptr) {
380 DLP_LOG_ERROR(LABEL, "proxy is null");
381 return DLP_SERVICE_ERROR_SERVICE_NOT_EXIST;
382 }
383 result = proxy->RegisterOpenDlpFileCallback(cb->AsObject());
384 if (result == DLP_OK) {
385 std::lock_guard<std::mutex> lock(callbackMutex_);
386 callbackMap_[callback] = cb;
387 }
388 return result;
389 }
390
UnRegisterOpenDlpFileCallback(const std::shared_ptr<OpenDlpFileCallbackCustomize> & callback)391 int32_t DlpPermissionClient::UnRegisterOpenDlpFileCallback(
392 const std::shared_ptr<OpenDlpFileCallbackCustomize>& callback)
393 {
394 bool sandboxFlag;
395 if (CheckSandboxFlag(GetSelfTokenID(), sandboxFlag) != DLP_OK) {
396 return DLP_SERVICE_ERROR_VALUE_INVALID;
397 }
398 if (sandboxFlag) {
399 DLP_LOG_ERROR(LABEL, "Forbid called by a sandbox app");
400 return DLP_SERVICE_ERROR_API_NOT_FOR_SANDBOX_ERROR;
401 }
402 if (callback == nullptr) {
403 DLP_LOG_ERROR(LABEL, "callback is nullptr");
404 return DLP_SERVICE_ERROR_VALUE_INVALID;
405 }
406 std::lock_guard<std::mutex> lock(callbackMutex_);
407 auto goalCallback = callbackMap_.find(callback);
408 if (goalCallback == callbackMap_.end()) {
409 DLP_LOG_ERROR(LABEL, "goalCallback already is not exist");
410 return DLP_SERVICE_ERROR_VALUE_INVALID;
411 }
412
413 auto proxy = GetProxy(false);
414 if (proxy == nullptr) {
415 DLP_LOG_ERROR(LABEL, "proxy is null");
416 return DLP_SERVICE_ERROR_SERVICE_NOT_EXIST;
417 }
418
419 int32_t result = proxy->UnRegisterOpenDlpFileCallback(goalCallback->second->AsObject());
420 if (result == DLP_OK) {
421 callbackMap_.erase(goalCallback);
422 }
423 return result;
424 }
425
GetDlpGatheringPolicy(bool & isGathering)426 int32_t DlpPermissionClient::GetDlpGatheringPolicy(bool& isGathering)
427 {
428 auto proxy = GetProxy(false);
429 if (proxy == nullptr) {
430 DLP_LOG_ERROR(LABEL, "Proxy is null");
431 return DLP_OK;
432 }
433
434 return proxy->GetDlpGatheringPolicy(isGathering);
435 }
436
SetRetentionState(const std::vector<std::string> & docUriVec)437 int32_t DlpPermissionClient::SetRetentionState(const std::vector<std::string>& docUriVec)
438 {
439 bool sandboxFlag;
440 if (CheckSandboxFlag(GetSelfTokenID(), sandboxFlag) != DLP_OK) {
441 return DLP_SERVICE_ERROR_VALUE_INVALID;
442 }
443 if (!sandboxFlag) {
444 DLP_LOG_ERROR(LABEL, "Forbid called by a non-sandbox app");
445 return DLP_SERVICE_ERROR_API_ONLY_FOR_SANDBOX_ERROR;
446 }
447 auto proxy = GetProxy(false);
448 if (proxy == nullptr) {
449 DLP_LOG_INFO(LABEL, "Proxy is null");
450 return DLP_CALLBACK_SA_WORK_ABNORMAL;
451 }
452
453 return proxy->SetRetentionState(docUriVec);
454 }
455
CancelRetentionState(const std::vector<std::string> & docUriVec)456 int32_t DlpPermissionClient::CancelRetentionState(const std::vector<std::string>& docUriVec)
457 {
458 auto proxy = GetProxy(true);
459 if (proxy == nullptr) {
460 DLP_LOG_INFO(LABEL, "Proxy is null");
461 return DLP_CALLBACK_SA_WORK_ABNORMAL;
462 }
463
464 return proxy->CancelRetentionState(docUriVec);
465 }
466
GetRetentionSandboxList(const std::string & bundleName,std::vector<RetentionSandBoxInfo> & retentionSandBoxInfoVec)467 int32_t DlpPermissionClient::GetRetentionSandboxList(const std::string& bundleName,
468 std::vector<RetentionSandBoxInfo>& retentionSandBoxInfoVec)
469 {
470 bool sandboxFlag;
471 if (CheckSandboxFlag(GetSelfTokenID(), sandboxFlag) != DLP_OK) {
472 return DLP_SERVICE_ERROR_VALUE_INVALID;
473 }
474 if (sandboxFlag) {
475 DLP_LOG_ERROR(LABEL, "Forbid called by a sandbox app");
476 return DLP_SERVICE_ERROR_API_NOT_FOR_SANDBOX_ERROR;
477 }
478 auto proxy = GetProxy(true);
479 if (proxy == nullptr) {
480 DLP_LOG_INFO(LABEL, "Proxy is null");
481 return DLP_CALLBACK_SA_WORK_ABNORMAL;
482 }
483
484 return proxy->GetRetentionSandboxList(bundleName, retentionSandBoxInfoVec);
485 }
486
ClearUnreservedSandbox()487 int32_t DlpPermissionClient::ClearUnreservedSandbox()
488 {
489 auto proxy = GetProxy(true);
490 if (proxy == nullptr) {
491 DLP_LOG_INFO(LABEL, "Proxy is null");
492 return DLP_CALLBACK_SA_WORK_ABNORMAL;
493 }
494
495 return proxy->ClearUnreservedSandbox();
496 }
497
GetDLPFileVisitRecord(std::vector<VisitedDLPFileInfo> & infoVec)498 int32_t DlpPermissionClient::GetDLPFileVisitRecord(std::vector<VisitedDLPFileInfo>& infoVec)
499 {
500 bool sandboxFlag;
501 if (CheckSandboxFlag(GetSelfTokenID(), sandboxFlag) != DLP_OK) {
502 return DLP_SERVICE_ERROR_VALUE_INVALID;
503 }
504 if (sandboxFlag) {
505 DLP_LOG_ERROR(LABEL, "Forbid called by a sandbox app");
506 return DLP_SERVICE_ERROR_API_NOT_FOR_SANDBOX_ERROR;
507 }
508 auto proxy = GetProxy(true);
509 if (proxy == nullptr) {
510 DLP_LOG_INFO(LABEL, "Proxy is null");
511 return DLP_CALLBACK_SA_WORK_ABNORMAL;
512 }
513
514 return proxy->GetDLPFileVisitRecord(infoVec);
515 }
516
SetMDMPolicy(const std::vector<std::string> & appIdList)517 int32_t DlpPermissionClient::SetMDMPolicy(const std::vector<std::string>& appIdList)
518 {
519 auto proxy = GetProxy(true);
520 if (proxy == nullptr) {
521 DLP_LOG_ERROR(LABEL, "Proxy is null");
522 return DLP_OK;
523 }
524
525 return proxy->SetMDMPolicy(appIdList);
526 }
527
GetMDMPolicy(std::vector<std::string> & appIdList)528 int32_t DlpPermissionClient::GetMDMPolicy(std::vector<std::string>& appIdList)
529 {
530 auto proxy = GetProxy(true);
531 if (proxy == nullptr) {
532 DLP_LOG_ERROR(LABEL, "Proxy is null");
533 return DLP_OK;
534 }
535
536 return proxy->GetMDMPolicy(appIdList);
537 }
538
RemoveMDMPolicy()539 int32_t DlpPermissionClient::RemoveMDMPolicy()
540 {
541 auto proxy = GetProxy(true);
542 if (proxy == nullptr) {
543 DLP_LOG_ERROR(LABEL, "Proxy is null");
544 return DLP_OK;
545 }
546
547 return proxy->RemoveMDMPolicy();
548 }
549
SetSandboxAppConfig(const std::string & configInfo)550 int32_t DlpPermissionClient::SetSandboxAppConfig(const std::string& configInfo)
551 {
552 auto proxy = GetProxy(true);
553 if (proxy == nullptr) {
554 DLP_LOG_ERROR(LABEL, "Proxy is null");
555 return DLP_CALLBACK_SA_WORK_ABNORMAL;
556 }
557 return proxy->SetSandboxAppConfig(configInfo);
558 }
559
CleanSandboxAppConfig()560 int32_t DlpPermissionClient::CleanSandboxAppConfig()
561 {
562 auto proxy = GetProxy(true);
563 if (proxy == nullptr) {
564 DLP_LOG_ERROR(LABEL, "Proxy is null");
565 return DLP_CALLBACK_SA_WORK_ABNORMAL;
566 }
567 return proxy->CleanSandboxAppConfig();
568 }
569
GetSandboxAppConfig(std::string & configInfo)570 int32_t DlpPermissionClient::GetSandboxAppConfig(std::string& configInfo)
571 {
572 auto proxy = GetProxy(true);
573 if (proxy == nullptr) {
574 DLP_LOG_ERROR(LABEL, "Proxy is null");
575 return DLP_CALLBACK_SA_WORK_ABNORMAL;
576 }
577 return proxy->GetSandboxAppConfig(configInfo);
578 }
579
IsDLPFeatureProvided(bool & isProvideDLPFeature)580 int32_t DlpPermissionClient::IsDLPFeatureProvided(bool& isProvideDLPFeature)
581 {
582 auto proxy = GetProxy(true);
583 if (proxy == nullptr) {
584 DLP_LOG_ERROR(LABEL, "Proxy is null.");
585 return DLP_SERVICE_ERROR_SERVICE_NOT_EXIST;
586 }
587 return proxy->IsDLPFeatureProvided(isProvideDLPFeature);
588 }
589
SetReadFlag(uint32_t uid)590 int32_t DlpPermissionClient::SetReadFlag(uint32_t uid)
591 {
592 auto proxy = GetProxy(false);
593 if (proxy == nullptr) {
594 DLP_LOG_ERROR(LABEL, "Proxy is null");
595 return DLP_CALLBACK_SA_WORK_ABNORMAL;
596 }
597 return proxy->SetReadFlag(uid);
598 }
599
StartLoadDlpPermissionSa()600 bool DlpPermissionClient::StartLoadDlpPermissionSa()
601 {
602 {
603 std::unique_lock<std::mutex> lock(cvLock_);
604 readyFlag_ = false;
605 }
606 auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
607 if (sam == nullptr) {
608 DLP_LOG_ERROR(LABEL, "GetSystemAbilityManager return null");
609 return false;
610 }
611
612 sptr<DlpPermissionLoadCallback> ptrDlpPermissionLoadCallback = new (std::nothrow) DlpPermissionLoadCallback();
613 if (ptrDlpPermissionLoadCallback == nullptr) {
614 DLP_LOG_ERROR(LABEL, "New ptrDlpPermissionLoadCallback fail.");
615 return false;
616 }
617
618 int32_t result = sam->LoadSystemAbility(SA_ID_DLP_PERMISSION_SERVICE, ptrDlpPermissionLoadCallback);
619 if (result != DLP_OK) {
620 DLP_LOG_ERROR(LABEL, "LoadSystemAbility %{public}d failed", SA_ID_DLP_PERMISSION_SERVICE);
621 return false;
622 }
623 DLP_LOG_INFO(LABEL, "Notify samgr load sa %{public}d success", SA_ID_DLP_PERMISSION_SERVICE);
624 return true;
625 }
626
WaitForDlpPermissionSa()627 void DlpPermissionClient::WaitForDlpPermissionSa()
628 {
629 // wait_for release lock and block until time out(1s) or match the condition with notice
630 std::unique_lock<std::mutex> lock(cvLock_);
631 auto waitStatus = dlpPermissionCon_.wait_for(
632 lock, std::chrono::milliseconds(DLP_PERMISSION_LOAD_SA_TIMEOUT_MS), [this]() { return readyFlag_; });
633 if (!waitStatus) {
634 // time out or loadcallback fail
635 DLP_LOG_ERROR(LABEL, "Dlp Permission load sa timeout");
636 return;
637 }
638 }
639
GetDlpPermissionSa()640 void DlpPermissionClient::GetDlpPermissionSa()
641 {
642 auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
643 if (sam == nullptr) {
644 DLP_LOG_ERROR(LABEL, "GetSystemAbilityManager return null");
645 return;
646 }
647
648 auto dlpPermissionSa = sam->GetSystemAbility(SA_ID_DLP_PERMISSION_SERVICE);
649 if (dlpPermissionSa == nullptr) {
650 DLP_LOG_ERROR(LABEL, "GetSystemAbility %{public}d is null", SA_ID_DLP_PERMISSION_SERVICE);
651 return;
652 }
653
654 GetProxyFromRemoteObject(dlpPermissionSa);
655 }
656
FinishStartSASuccess(const sptr<IRemoteObject> & remoteObject)657 void DlpPermissionClient::FinishStartSASuccess(const sptr<IRemoteObject>& remoteObject)
658 {
659 DLP_LOG_INFO(LABEL, "Get dlp_permission sa success.");
660
661 GetProxyFromRemoteObject(remoteObject);
662
663 // get lock which wait_for release and send a notice so that wait_for can out of block
664 std::unique_lock<std::mutex> lock(cvLock_);
665 readyFlag_ = true;
666 dlpPermissionCon_.notify_one();
667 }
668
FinishStartSAFail()669 void DlpPermissionClient::FinishStartSAFail()
670 {
671 DLP_LOG_ERROR(LABEL, "get dlp_permission sa failed.");
672
673 // get lock which wait_for release and send a notice
674 std::unique_lock<std::mutex> lock(cvLock_);
675 readyFlag_ = true;
676 dlpPermissionCon_.notify_one();
677 }
678
LoadDlpPermissionSa()679 void DlpPermissionClient::LoadDlpPermissionSa()
680 {
681 if (!StartLoadDlpPermissionSa()) {
682 return;
683 }
684 WaitForDlpPermissionSa();
685 }
686
OnRemoteDiedHandle()687 void DlpPermissionClient::OnRemoteDiedHandle()
688 {
689 DLP_LOG_ERROR(LABEL, "Remote service died");
690 std::unique_lock<std::mutex> lock(proxyMutex_);
691 proxy_ = nullptr;
692 serviceDeathObserver_ = nullptr;
693 {
694 std::unique_lock<std::mutex> lock1(cvLock_);
695 readyFlag_ = false;
696 }
697 }
698
GetProxyFromRemoteObject(const sptr<IRemoteObject> & remoteObject)699 void DlpPermissionClient::GetProxyFromRemoteObject(const sptr<IRemoteObject>& remoteObject)
700 {
701 if (remoteObject == nullptr) {
702 return;
703 }
704
705 sptr<DlpPermissionDeathRecipient> serviceDeathObserver = new (std::nothrow) DlpPermissionDeathRecipient();
706 if (serviceDeathObserver == nullptr) {
707 DLP_LOG_ERROR(LABEL, "Alloc service death observer fail");
708 return;
709 }
710
711 if (!remoteObject->AddDeathRecipient(serviceDeathObserver)) {
712 DLP_LOG_ERROR(LABEL, "Add service death observer fail");
713 return;
714 }
715
716 auto proxy = iface_cast<IDlpPermissionService>(remoteObject);
717 if (proxy == nullptr) {
718 DLP_LOG_ERROR(LABEL, "iface_cast get null");
719 return;
720 }
721 std::unique_lock<std::mutex> lock(proxyMutex_);
722 proxy_ = proxy;
723 serviceDeathObserver_ = serviceDeathObserver;
724 DLP_LOG_INFO(LABEL, "GetSystemAbility %{public}d success", SA_ID_DLP_PERMISSION_SERVICE);
725 return;
726 }
727
GetProxy(bool doLoadSa)728 sptr<IDlpPermissionService> DlpPermissionClient::GetProxy(bool doLoadSa)
729 {
730 {
731 std::unique_lock<std::mutex> lock(proxyMutex_);
732 if (proxy_ != nullptr) {
733 return proxy_;
734 }
735 }
736 if (doLoadSa) {
737 LoadDlpPermissionSa();
738 } else {
739 GetDlpPermissionSa();
740 }
741 std::unique_lock<std::mutex> lock(proxyMutex_);
742 return proxy_;
743 }
744 } // namespace DlpPermission
745 } // namespace Security
746 } // namespace OHOS
747