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