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