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