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