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