• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "dlp_permission_service.h"
17 #include <chrono>
18 #include "accesstoken_kit.h"
19 #include "account_adapt.h"
20 #include "app_mgr_client.h"
21 #include "bundle_manager_adapter.h"
22 #include "bundle_mgr_client.h"
23 #include "config_policy_utils.h"
24 #include "dlp_credential_client.h"
25 #include "dlp_credential.h"
26 #include "dlp_kv_data_storage.h"
27 #include "dlp_permission.h"
28 #include "dlp_permission_log.h"
29 #include "dlp_permission_serializer.h"
30 #include "dlp_policy_mgr_client.h"
31 #include "dlp_sandbox_change_callback_manager.h"
32 #include "dlp_sandbox_info.h"
33 #include "file_operator.h"
34 #include "hap_token_info.h"
35 #include "if_system_ability_manager.h"
36 #include "ipc_skeleton.h"
37 #include "iservice_registry.h"
38 #include "open_dlp_file_callback_manager.h"
39 #if defined(DLP_DEBUG_ENABLE) && DLP_DEBUG_ENABLE == 1
40 #include "parameter.h"
41 #endif
42 #include "parameters.h"
43 #include "param_wrapper.h"
44 #include "permission_policy.h"
45 #include "system_ability_definition.h"
46 #include "visit_record_file_manager.h"
47 
48 namespace OHOS {
49 namespace Security {
50 namespace DlpPermission {
51 using namespace Security::AccessToken;
52 using namespace OHOS::AppExecFwk;
53 namespace {
54 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, SECURITY_DOMAIN_DLP_PERMISSION, "DlpPermissionService" };
55 constexpr const int32_t EDM_UID = 3057;
56 const std::string PERMISSION_ACCESS_DLP_FILE = "ohos.permission.ACCESS_DLP_FILE";
57 static const std::string ALLOW_ACTION[] = {"ohos.want.action.CREATE_FILE"};
58 static const std::string DLP_MANAGER = "com.ohos.dlpmanager";
59 static const std::chrono::seconds SLEEP_TIME(120);
60 static const int REPEAT_TIME = 5;
61 static const std::string DLP_CONFIG = "etc/dlp_permission/dlp_config.json";
62 static const std::string SUPPORT_FILE_TYPE = "support_file_type";
63 static const std::string DEAULT_DLP_CONFIG = "/system/etc/dlp_config.json";
64 static const std::string DLP_ENABLE = "const.dlp.dlp_enable";
65 static const std::string DEVELOPER_MODE = "const.security.developermode.state";
66 static const std::string TRUE_VALUE = "true";
67 static const std::string FALSE_VALUE = "false";
68 static const std::string SEPARATOR = "_";
69 }
70 REGISTER_SYSTEM_ABILITY_BY_ID(DlpPermissionService, SA_ID_DLP_PERMISSION_SERVICE, true);
71 
DlpPermissionService(int saId,bool runOnCreate)72 DlpPermissionService::DlpPermissionService(int saId, bool runOnCreate)
73     : SystemAbility(saId, runOnCreate), state_(ServiceRunningState::STATE_NOT_START)
74 {
75     DLP_LOG_INFO(LABEL, "DlpPermissionService()");
76 }
77 
~DlpPermissionService()78 DlpPermissionService::~DlpPermissionService()
79 {
80     DLP_LOG_INFO(LABEL, "~DlpPermissionService()");
81     UnregisterAppStateObserver();
82     iAppMgr_ = nullptr;
83     appStateObserver_ = nullptr;
84     std::unique_lock<std::shared_mutex> lock(dlpSandboxDataMutex_);
85     dlpSandboxData_.clear();
86 }
87 
OnStart()88 void DlpPermissionService::OnStart()
89 {
90     if (state_ == ServiceRunningState::STATE_RUNNING) {
91         DLP_LOG_INFO(LABEL, "DlpPermissionService has already started!");
92         return;
93     }
94     DLP_LOG_INFO(LABEL, "DlpPermissionService is starting");
95     if (!RegisterAppStateObserver()) {
96         DLP_LOG_ERROR(LABEL, "Failed to register app state observer!");
97         return;
98     }
99     dlpEventSubSubscriber_ = std::make_shared<DlpEventSubSubscriber>();
100     bool ret = Publish(this);
101     if (!ret) {
102         DLP_LOG_ERROR(LABEL, "Failed to publish service!");
103         return;
104     }
105     state_ = ServiceRunningState::STATE_RUNNING;
106     DLP_LOG_INFO(LABEL, "Congratulations, DlpPermissionService start successfully!");
107 }
108 
OnStop()109 void DlpPermissionService::OnStop()
110 {
111     DLP_LOG_INFO(LABEL, "Stop service");
112     dlpEventSubSubscriber_ = nullptr;
113 }
114 
RegisterAppStateObserver()115 bool DlpPermissionService::RegisterAppStateObserver()
116 {
117     if (appStateObserver_ != nullptr) {
118         DLP_LOG_INFO(LABEL, "AppStateObserver instance already create");
119         return true;
120     }
121     sptr<AppStateObserver> tempAppStateObserver = new (std::nothrow) AppStateObserver();
122     if (tempAppStateObserver == nullptr) {
123         DLP_LOG_ERROR(LABEL, "Failed to create AppStateObserver instance");
124         return false;
125     }
126     sptr<ISystemAbilityManager> samgrClient = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
127     if (samgrClient == nullptr) {
128         DLP_LOG_ERROR(LABEL, "Failed to get system ability manager");
129         return false;
130     }
131     auto obj = samgrClient->GetSystemAbility(APP_MGR_SERVICE_ID);
132     iAppMgr_ = iface_cast<AppExecFwk::IAppMgr>(obj);
133     if (iAppMgr_ == nullptr) {
134         DLP_LOG_ERROR(LABEL, "Failed to get ability manager service");
135         return false;
136     }
137     int32_t result = iAppMgr_->RegisterApplicationStateObserver(tempAppStateObserver);
138     if (result != DLP_OK) {
139         DLP_LOG_ERROR(LABEL, "Failed to Register app state observer");
140         iAppMgr_ = nullptr;
141         return false;
142     }
143     sptr<AppExecFwk::AppMgrProxy> proxy = new (std::nothrow)AppExecFwk::AppMgrProxy(obj);
144     if (proxy == nullptr) {
145         DLP_LOG_ERROR(LABEL, "Failed to create AppMgrProxy instance");
146         iAppMgr_ = nullptr;
147         return false;
148     }
149     appStateObserver_ = tempAppStateObserver;
150     appStateObserver_->SetAppProxy(proxy);
151     return true;
152 }
153 
UnregisterAppStateObserver()154 void DlpPermissionService::UnregisterAppStateObserver()
155 {
156     if (iAppMgr_ != nullptr && appStateObserver_ != nullptr) {
157         iAppMgr_->UnregisterApplicationStateObserver(appStateObserver_);
158     }
159 }
160 
GenerateDlpCertificate(const sptr<DlpPolicyParcel> & policyParcel,const sptr<IDlpPermissionCallback> & callback)161 int32_t DlpPermissionService::GenerateDlpCertificate(
162     const sptr<DlpPolicyParcel>& policyParcel, const sptr<IDlpPermissionCallback>& callback)
163 {
164     if (callback == nullptr) {
165         DLP_LOG_ERROR(LABEL, "Callback is null");
166         return DLP_SERVICE_ERROR_VALUE_INVALID;
167     }
168 
169     if (!policyParcel->policyParams_.IsValid()) {
170         return DLP_SERVICE_ERROR_VALUE_INVALID;
171     }
172     policyParcel->policyParams_.SetDebug(OHOS::system::GetBoolParameter(DEVELOPER_MODE, false));
173     unordered_json jsonObj;
174     int32_t res = DlpPermissionSerializer::GetInstance().SerializeDlpPermission(policyParcel->policyParams_, jsonObj);
175     if (res != DLP_OK) {
176         return res;
177     }
178 
179     return DlpCredential::GetInstance().GenerateDlpCertificate(
180         jsonObj.dump(), policyParcel->policyParams_.ownerAccountId_,
181         policyParcel->policyParams_.ownerAccountType_, callback);
182 }
183 
GetApplicationInfo(std::string appId,AppExecFwk::ApplicationInfo & applicationInfo)184 static bool GetApplicationInfo(std::string appId, AppExecFwk::ApplicationInfo& applicationInfo)
185 {
186     size_t pos = appId.find_last_of(SEPARATOR);
187     if (pos > appId.length()) {
188         DLP_LOG_ERROR(LABEL, "AppId=%{public}s pos=%{public}zu can not find bundleName", appId.c_str(), pos);
189         return false;
190     }
191     std::string bundleName = appId.substr(0, pos);
192 
193     int32_t userId = GetCallingUserId();
194     if (userId < 0) {
195         DLP_LOG_ERROR(LABEL, "Get userId error.");
196         return false;
197     }
198     if (!BundleManagerAdapter::GetInstance().GetApplicationInfo(bundleName,
199         OHOS::AppExecFwk::ApplicationFlag::GET_ALL_APPLICATION_INFO, userId, applicationInfo)) {
200         DLP_LOG_ERROR(LABEL, "Get applicationInfo error bundleName=%{public}s", bundleName.c_str());
201         return false;
202     }
203     return true;
204 }
205 
ParseDlpCertificate(sptr<CertParcel> & certParcel,const sptr<IDlpPermissionCallback> & callback,const std::string & appId,const bool & offlineAccess)206 int32_t DlpPermissionService::ParseDlpCertificate(sptr<CertParcel>& certParcel,
207     const sptr<IDlpPermissionCallback>& callback, const std::string& appId, const bool& offlineAccess)
208 {
209     if (callback == nullptr) {
210         DLP_LOG_ERROR(LABEL, "Callback is null");
211         return DLP_SERVICE_ERROR_VALUE_INVALID;
212     }
213     if (appId.empty()) {
214         DLP_LOG_ERROR(LABEL, "AppId is empty");
215         return DLP_CREDENTIAL_ERROR_APPID_NOT_AUTHORIZED;
216     }
217     AppExecFwk::ApplicationInfo applicationInfo;
218     if (!GetApplicationInfo(appId, applicationInfo)) {
219         DLP_LOG_ERROR(LABEL, "Permission check fail.");
220         return DLP_SERVICE_ERROR_VALUE_INVALID;
221     }
222     return DlpCredential::GetInstance().ParseDlpCertificate(
223         certParcel, callback, appId, offlineAccess, applicationInfo);
224 }
225 
InsertDlpSandboxInfo(DlpSandboxInfo & sandboxInfo,bool hasRetention)226 bool DlpPermissionService::InsertDlpSandboxInfo(DlpSandboxInfo& sandboxInfo, bool hasRetention)
227 {
228     AppExecFwk::BundleInfo info;
229     AppExecFwk::BundleMgrClient bundleMgrClient;
230     if (bundleMgrClient.GetSandboxBundleInfo(sandboxInfo.bundleName, sandboxInfo.appIndex, sandboxInfo.userId, info) !=
231         DLP_OK) {
232         DLP_LOG_ERROR(LABEL, "Get sandbox bundle info fail appIndex=%{public}d", sandboxInfo.appIndex);
233         if (hasRetention) {
234             RetentionFileManager::GetInstance().ClearUnreservedSandbox();
235         }
236         return false;
237     }
238     sandboxInfo.uid = info.uid;
239     sandboxInfo.tokenId = AccessToken::AccessTokenKit::GetHapTokenID(sandboxInfo.userId, sandboxInfo.bundleName,
240         sandboxInfo.appIndex);
241     appStateObserver_->AddDlpSandboxInfo(sandboxInfo);
242     VisitRecordFileManager::GetInstance().AddVisitRecord(sandboxInfo.bundleName, sandboxInfo.userId, sandboxInfo.uri);
243     return true;
244 }
245 
GetAppIndexFromRetentionInfo(const std::string & bundleName,bool isReadOnly,const std::string & uri,DlpSandboxInfo & dlpSandBoxInfo,bool & isNeedInstall)246 static int32_t GetAppIndexFromRetentionInfo(const std::string& bundleName, bool isReadOnly, const std::string& uri,
247     DlpSandboxInfo& dlpSandBoxInfo, bool& isNeedInstall)
248 {
249     std::vector<RetentionSandBoxInfo> infoVec;
250     auto res = RetentionFileManager::GetInstance().GetRetentionSandboxList(bundleName, infoVec, true);
251     if (res != DLP_OK) {
252         DLP_LOG_ERROR(LABEL, "GetRetentionSandboxList fail bundleName:%{public}s,uri:%{public}s, error=%{public}d",
253             bundleName.c_str(), uri.c_str(), res);
254         return res;
255     }
256     for (auto iter = infoVec.begin(); iter != infoVec.end(); ++iter) {
257         if (isReadOnly && iter->dlpFileAccess_ == DLPFileAccess::READ_ONLY) {
258             dlpSandBoxInfo.appIndex = iter->appIndex_;
259             dlpSandBoxInfo.hasRead = iter->hasRead_;
260             isNeedInstall = false;
261             break;
262         }
263         if (isReadOnly) {
264             continue;
265         }
266         auto setIter = iter->docUriSet_.find(uri);
267         if (setIter != iter->docUriSet_.end()) {
268             dlpSandBoxInfo.appIndex = iter->appIndex_;
269             dlpSandBoxInfo.hasRead = iter->hasRead_;
270             isNeedInstall = false;
271             break;
272         }
273     }
274     return DLP_OK;
275 }
276 
InstallDlpSandbox(const std::string & bundleName,DLPFileAccess dlpFileAccess,int32_t userId,SandboxInfo & sandboxInfo,const std::string & uri)277 int32_t DlpPermissionService::InstallDlpSandbox(const std::string& bundleName, DLPFileAccess dlpFileAccess,
278     int32_t userId, SandboxInfo& sandboxInfo, const std::string& uri)
279 {
280     if (bundleName.empty() || dlpFileAccess > FULL_CONTROL || dlpFileAccess <= NO_PERMISSION) {
281         DLP_LOG_ERROR(LABEL, "param is invalid");
282         return DLP_SERVICE_ERROR_VALUE_INVALID;
283     }
284     if (appStateObserver_->GetOpeningSandboxInfo(bundleName, uri, userId, sandboxInfo)) {
285         return DLP_OK;
286     }
287     bool isReadOnly = dlpFileAccess == DLPFileAccess::READ_ONLY;
288     bool isNeedInstall = true;
289     DlpSandboxInfo dlpSandboxInfo;
290     dlpSandboxInfo.bundleName = bundleName;
291     int32_t res = GetAppIndexFromRetentionInfo(bundleName, isReadOnly, uri, dlpSandboxInfo, isNeedInstall);
292     if (res != DLP_OK) {
293         return res;
294     }
295     if (isNeedInstall && isReadOnly) {
296         appStateObserver_->GetOpeningReadOnlySandbox(bundleName, userId, dlpSandboxInfo.appIndex);
297         isNeedInstall = (dlpSandboxInfo.appIndex != -1) ? false : true;
298     }
299     if (isNeedInstall) {
300         AppExecFwk::BundleMgrClient bundleMgrClient;
301         DLPFileAccess permForBMS = (dlpFileAccess == READ_ONLY) ? READ_ONLY : CONTENT_EDIT;
302         int32_t bundleClientRes = bundleMgrClient.InstallSandboxApp(bundleName, permForBMS, userId,
303             dlpSandboxInfo.appIndex);
304         if (bundleClientRes != DLP_OK) {
305             DLP_LOG_ERROR(LABEL, "install sandbox %{public}s fail, error=%{public}d", bundleName.c_str(),
306                 bundleClientRes);
307             return DLP_SERVICE_ERROR_INSTALL_SANDBOX_FAIL;
308         }
309     }
310 
311     dlpSandboxInfo.dlpFileAccess = dlpFileAccess;
312     dlpSandboxInfo.userId = userId;
313     dlpSandboxInfo.pid = IPCSkeleton::GetCallingRealPid();
314     dlpSandboxInfo.uri = uri;
315     dlpSandboxInfo.timeStamp = static_cast<uint64_t>(
316         std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count());
317     if (!InsertDlpSandboxInfo(dlpSandboxInfo, !isNeedInstall)) {
318         return DLP_SERVICE_ERROR_INSTALL_SANDBOX_FAIL;
319     }
320     sandboxInfo.appIndex = dlpSandboxInfo.appIndex;
321     sandboxInfo.tokenId = dlpSandboxInfo.tokenId;
322 
323     std::unique_lock<std::shared_mutex> lock(dlpSandboxDataMutex_);
324     auto it = dlpSandboxData_.find(dlpSandboxInfo.uid);
325     if (it == dlpSandboxData_.end()) {
326         dlpSandboxData_.insert(std::make_pair(dlpSandboxInfo.uid, dlpSandboxInfo.dlpFileAccess));
327     }
328     return DLP_OK;
329 }
330 
DeleteDlpSandboxInfo(const std::string & bundleName,int32_t appIndex,int32_t userId)331 uint32_t DlpPermissionService::DeleteDlpSandboxInfo(const std::string& bundleName, int32_t appIndex, int32_t userId)
332 {
333     AppExecFwk::BundleMgrClient bundleMgrClient;
334     AppExecFwk::BundleInfo info;
335     int32_t result = bundleMgrClient.GetSandboxBundleInfo(bundleName, appIndex, userId, info);
336     if (result != DLP_OK) {
337         DLP_LOG_ERROR(LABEL, "Get sandbox bundle info fail");
338         return 0;
339     }
340 
341     std::unique_lock<std::shared_mutex> lock(dlpSandboxDataMutex_);
342     auto it = dlpSandboxData_.find(info.uid);
343     if (it != dlpSandboxData_.end()) {
344         dlpSandboxData_.erase(info.uid);
345     }
346 
347     return appStateObserver_->EraseDlpSandboxInfo(info.uid);
348 }
349 
UninstallDlpSandboxApp(const std::string & bundleName,int32_t appIndex,int32_t userId)350 int32_t DlpPermissionService::UninstallDlpSandboxApp(const std::string& bundleName, int32_t appIndex, int32_t userId)
351 {
352     AppExecFwk::BundleMgrClient bundleMgrClient;
353     int32_t res = bundleMgrClient.UninstallSandboxApp(bundleName, appIndex, userId);
354     if (res != DLP_OK) {
355         DLP_LOG_ERROR(LABEL, "uninstall sandbox %{public}s fail, index=%{public}d, error=%{public}d",
356             bundleName.c_str(), appIndex, res);
357         return DLP_SERVICE_ERROR_UNINSTALL_SANDBOX_FAIL;
358     }
359     return DLP_OK;
360 }
361 
UninstallDlpSandbox(const std::string & bundleName,int32_t appIndex,int32_t userId)362 int32_t DlpPermissionService::UninstallDlpSandbox(const std::string& bundleName, int32_t appIndex, int32_t userId)
363 {
364     if (bundleName.empty() || appIndex < 0 || userId < 0) {
365         DLP_LOG_ERROR(LABEL, "param is invalid");
366         return DLP_SERVICE_ERROR_VALUE_INVALID;
367     }
368 
369     uint32_t tokenId = DeleteDlpSandboxInfo(bundleName, appIndex, userId);
370     if (tokenId == 0) {
371         DLP_LOG_ERROR(LABEL, "DeleteDlpSandboxInfo sandbox %{public}s fail, index=%{public}d", bundleName.c_str(),
372             appIndex);
373         return DLP_SERVICE_ERROR_UNINSTALL_SANDBOX_FAIL;
374     }
375     if (RetentionFileManager::GetInstance().CanUninstall(tokenId)) {
376         return UninstallDlpSandboxApp(bundleName, appIndex, userId);
377     }
378     return DLP_OK;
379 }
380 
CheckAllowAbilityList(const AAFwk::Want & want)381 static bool CheckAllowAbilityList(const AAFwk::Want& want)
382 {
383     std::string bundleName = want.GetBundle();
384     std::string actionName = want.GetAction();
385     DLP_LOG_DEBUG(LABEL, "CheckAllowAbilityList %{public}s %{public}s", bundleName.c_str(), actionName.c_str());
386     bool bundleCheck = (bundleName == DLP_MANAGER) &&
387         BundleManagerAdapter::GetInstance().CheckHapPermission(bundleName, PERMISSION_ACCESS_DLP_FILE);
388     bool actionCheck = std::any_of(std::begin(ALLOW_ACTION), std::end(ALLOW_ACTION),
389         [actionName](const std::string& action) { return action == actionName; });
390     return actionCheck || bundleCheck;
391 }
392 
GetSandboxExternalAuthorization(int sandboxUid,const AAFwk::Want & want,SandBoxExternalAuthorType & authType)393 int32_t DlpPermissionService::GetSandboxExternalAuthorization(
394     int sandboxUid, const AAFwk::Want& want, SandBoxExternalAuthorType& authType)
395 {
396     if (sandboxUid < 0) {
397         DLP_LOG_ERROR(LABEL, "param is invalid");
398         return DLP_SERVICE_ERROR_VALUE_INVALID;
399     }
400     bool isSandbox = false;
401 
402     appStateObserver_->IsInDlpSandbox(isSandbox, sandboxUid);
403 
404     std::unique_lock<std::shared_mutex> lock(dlpSandboxDataMutex_);
405     auto it = dlpSandboxData_.find(sandboxUid);
406     if (isSandbox && it != dlpSandboxData_.end() && dlpSandboxData_[sandboxUid] != READ_ONLY) {
407         authType = ALLOW_START_ABILITY;
408         return DLP_OK;
409     }
410 
411     if (isSandbox && !CheckAllowAbilityList(want)) {
412         authType = DENY_START_ABILITY;
413     } else {
414         authType = ALLOW_START_ABILITY;
415     }
416 
417     return DLP_OK;
418 }
419 
QueryDlpFileCopyableByTokenId(bool & copyable,uint32_t tokenId)420 int32_t DlpPermissionService::QueryDlpFileCopyableByTokenId(bool& copyable, uint32_t tokenId)
421 {
422     if (tokenId == 0) {
423         return DLP_SERVICE_ERROR_VALUE_INVALID;
424     }
425     return appStateObserver_->QueryDlpFileCopyableByTokenId(copyable, tokenId);
426 }
427 
GetDlpActionFlag(DLPFileAccess dlpFileAccess)428 static ActionFlags GetDlpActionFlag(DLPFileAccess dlpFileAccess)
429 {
430     switch (dlpFileAccess) {
431         case READ_ONLY: {
432             return ACTION_VIEW;
433         }
434         case CONTENT_EDIT: {
435             return static_cast<ActionFlags>(ACTION_VIEW | ACTION_SAVE | ACTION_SAVE_AS | ACTION_EDIT |
436             ACTION_SCREEN_CAPTURE | ACTION_SCREEN_SHARE | ACTION_SCREEN_RECORD | ACTION_COPY);
437         }
438         case FULL_CONTROL: {
439             return static_cast<ActionFlags>(ACTION_VIEW | ACTION_SAVE | ACTION_SAVE_AS | ACTION_EDIT |
440                 ACTION_SCREEN_CAPTURE | ACTION_SCREEN_SHARE | ACTION_SCREEN_RECORD | ACTION_COPY | ACTION_PRINT |
441                 ACTION_EXPORT | ACTION_PERMISSION_CHANGE);
442         }
443         default:
444             return ACTION_INVALID;
445     }
446 }
447 
QueryDlpFileAccess(DLPPermissionInfoParcel & permInfoParcel)448 int32_t DlpPermissionService::QueryDlpFileAccess(DLPPermissionInfoParcel& permInfoParcel)
449 {
450     int32_t uid = IPCSkeleton::GetCallingUid();
451     DLPFileAccess dlpFileAccess = NO_PERMISSION;
452     int32_t res = appStateObserver_->QueryDlpFileAccessByUid(dlpFileAccess, uid);
453     permInfoParcel.permInfo_.dlpFileAccess = dlpFileAccess;
454     permInfoParcel.permInfo_.flags = GetDlpActionFlag(dlpFileAccess);
455     return res;
456 }
457 
IsInDlpSandbox(bool & inSandbox)458 int32_t DlpPermissionService::IsInDlpSandbox(bool& inSandbox)
459 {
460     int32_t uid = IPCSkeleton::GetCallingUid();
461     return appStateObserver_->IsInDlpSandbox(inSandbox, uid);
462 }
463 
GetCfgFilesList(std::vector<std::string> & cfgFilesList)464 void DlpPermissionService::GetCfgFilesList(std::vector<std::string>& cfgFilesList)
465 {
466     CfgFiles *cfgFiles = GetCfgFiles(DLP_CONFIG.c_str()); // need free
467     if (cfgFiles != nullptr) {
468         for (auto& cfgPath : cfgFiles->paths) {
469             if (cfgPath != nullptr) {
470                 cfgFilesList.emplace_back(cfgPath);
471             }
472         }
473         FreeCfgFiles(cfgFiles); // free memory
474     }
475     std::reverse(cfgFilesList.begin(), cfgFilesList.end()); // priority from low to high, need reverse
476 }
477 
GetConfigFileValue(const std::string & cfgFile,std::vector<std::string> & typeList)478 void DlpPermissionService::GetConfigFileValue(const std::string& cfgFile, std::vector<std::string>& typeList)
479 {
480     std::string content;
481     (void)FileOperator().GetFileContentByPath(cfgFile, content);
482     if (content.empty()) {
483         return ;
484     }
485     auto jsonObj = nlohmann::json::parse(content, nullptr, false);
486     if (jsonObj.is_discarded() || (!jsonObj.is_object())) {
487         DLP_LOG_WARN(LABEL, "JsonObj is discarded");
488         return ;
489     }
490     auto result = jsonObj.find(SUPPORT_FILE_TYPE);
491     if (result != jsonObj.end() && result->is_array() && !result->empty() && (*result)[0].is_string()) {
492         typeList = result->get<std::vector<std::string>>();
493     }
494 }
495 
InitConfig(std::vector<std::string> & typeList)496 void DlpPermissionService::InitConfig(std::vector<std::string>& typeList)
497 {
498     static std::vector<std::string> typeListTemp;
499     static bool cfgInit = true;
500     std::lock_guard<std::mutex> lock(mutex_);
501     if (cfgInit) {
502         cfgInit = false;
503         std::vector<std::string> cfgFilesList;
504         GetCfgFilesList(cfgFilesList);
505         for (const auto& cfgFile : cfgFilesList) {
506             GetConfigFileValue(cfgFile, typeListTemp);
507             if (!typeListTemp.empty()) {
508                 typeList = typeListTemp;
509                 return;
510             }
511         }
512         DLP_LOG_INFO(LABEL, "get config value failed, use default file path");
513         GetConfigFileValue(DEAULT_DLP_CONFIG, typeListTemp);
514         if (typeListTemp.empty()) {
515             DLP_LOG_ERROR(LABEL, "support file type list is empty");
516         }
517     }
518     typeList = typeListTemp;
519 }
520 
GetDlpSupportFileType(std::vector<std::string> & supportFileType)521 int32_t DlpPermissionService::GetDlpSupportFileType(std::vector<std::string>& supportFileType)
522 {
523     InitConfig(supportFileType);
524     return DLP_OK;
525 }
526 
RegisterDlpSandboxChangeCallback(const sptr<IRemoteObject> & callback)527 int32_t DlpPermissionService::RegisterDlpSandboxChangeCallback(const sptr<IRemoteObject>& callback)
528 {
529     int32_t pid = IPCSkeleton::GetCallingRealPid();
530     DLP_LOG_INFO(LABEL, "GetCallingRealPid,%{public}d", pid);
531     return DlpSandboxChangeCallbackManager::GetInstance().AddCallback(pid, callback);
532 }
533 
UnRegisterDlpSandboxChangeCallback(bool & result)534 int32_t DlpPermissionService::UnRegisterDlpSandboxChangeCallback(bool& result)
535 {
536     int32_t pid = IPCSkeleton::GetCallingRealPid();
537     DLP_LOG_INFO(LABEL, "GetCallingRealPid,%{public}d", pid);
538     return DlpSandboxChangeCallbackManager::GetInstance().RemoveCallback(pid, result);
539 }
540 
RegisterOpenDlpFileCallback(const sptr<IRemoteObject> & callback)541 int32_t DlpPermissionService::RegisterOpenDlpFileCallback(const sptr<IRemoteObject>& callback)
542 {
543     std::string callerBundleName;
544     if (!GetCallerBundleName(IPCSkeleton::GetCallingTokenID(), callerBundleName)) {
545         DLP_LOG_ERROR(LABEL, "get callerBundleName error");
546         return DLP_SERVICE_ERROR_VALUE_INVALID;
547     }
548     int32_t uid = IPCSkeleton::GetCallingUid();
549     int32_t userId;
550     if (GetUserIdFromUid(uid, &userId) != 0) {
551         DLP_LOG_ERROR(LABEL, "GetUserIdFromUid error");
552         return false;
553     }
554     int32_t pid = IPCSkeleton::GetCallingRealPid();
555 
556     DLP_LOG_INFO(LABEL, "CallingPid: %{public}d, userId: %{public}d, CallingBundle: %{public}s", pid, userId,
557         callerBundleName.c_str());
558 
559     int res = OpenDlpFileCallbackManager::GetInstance().AddCallback(pid, userId, callerBundleName, callback);
560     if (res != DLP_OK) {
561         return res;
562     }
563     appStateObserver_->AddCallbackListener(pid);
564     return DLP_OK;
565 }
566 
UnRegisterOpenDlpFileCallback(const sptr<IRemoteObject> & callback)567 int32_t DlpPermissionService::UnRegisterOpenDlpFileCallback(const sptr<IRemoteObject>& callback)
568 {
569     int32_t pid = IPCSkeleton::GetCallingRealPid();
570     int32_t res = OpenDlpFileCallbackManager::GetInstance().RemoveCallback(pid, callback);
571     appStateObserver_->RemoveCallbackListener(pid);
572     return res;
573 }
574 
GetDlpGatheringPolicy(bool & isGathering)575 int32_t DlpPermissionService::GetDlpGatheringPolicy(bool& isGathering)
576 {
577     isGathering = true;
578 #if defined(DLP_DEBUG_ENABLE) && DLP_DEBUG_ENABLE == 1
579     const char* PARAM_KEY = "dlp.permission.gathering.policy";
580     const int32_t VALUE_MAX_LEN = 32;
581     char value[VALUE_MAX_LEN] = {0};
582     int32_t ret = GetParameter(PARAM_KEY, "false", value, VALUE_MAX_LEN - 1);
583     if (ret <= 0) {
584         DLP_LOG_WARN(LABEL, "Failed to get parameter, %{public}s", PARAM_KEY);
585         return DLP_OK;
586     }
587 
588     std::string tmp(value);
589     if (tmp == "true") {
590         isGathering = true;
591     }
592 
593     if (tmp == "false") {
594         isGathering = false;
595     }
596 #endif
597     return DLP_OK;
598 }
599 
SetRetentionState(const std::vector<std::string> & docUriVec)600 int32_t DlpPermissionService::SetRetentionState(const std::vector<std::string>& docUriVec)
601 {
602     if (docUriVec.empty()) {
603         DLP_LOG_ERROR(LABEL, "get docUriVec empty");
604         return DLP_SERVICE_ERROR_VALUE_INVALID;
605     }
606     RetentionInfo info;
607     info.tokenId = IPCSkeleton::GetCallingTokenID();
608     std::set<std::string> docUriSet(docUriVec.begin(), docUriVec.end());
609     int32_t uid = IPCSkeleton::GetCallingUid();
610     DlpSandboxInfo sandboxInfo;
611     bool result = appStateObserver_->GetSandboxInfo(uid, sandboxInfo);
612     if (!result) {
613         DLP_LOG_ERROR(LABEL, "Can not found sandbox info");
614         return DLP_SERVICE_ERROR_VALUE_INVALID;
615     }
616     info.hasRead = sandboxInfo.hasRead;
617     return RetentionFileManager::GetInstance().UpdateSandboxInfo(docUriSet, info, true);
618 }
619 
CancelRetentionState(const std::vector<std::string> & docUriVec)620 int32_t DlpPermissionService::CancelRetentionState(const std::vector<std::string>& docUriVec)
621 {
622     if (docUriVec.empty()) {
623         DLP_LOG_ERROR(LABEL, "get docUriVec empty");
624         return DLP_SERVICE_ERROR_VALUE_INVALID;
625     }
626     RetentionInfo info;
627     info.tokenId = IPCSkeleton::GetCallingTokenID();
628     if (!GetCallerBundleName(info.tokenId, info.bundleName)) {
629         DLP_LOG_ERROR(LABEL, "get callerBundleName error");
630         return DLP_SERVICE_ERROR_VALUE_INVALID;
631     }
632     bool isInSandbox = false;
633     IsInDlpSandbox(isInSandbox);
634     if (!isInSandbox) {
635         info.tokenId = 0;
636     }
637     int32_t res = 0;
638     {
639         std::lock_guard<std::mutex> lock(terminalMutex_);
640         std::set<std::string> docUriSet(docUriVec.begin(), docUriVec.end());
641         res = RetentionFileManager::GetInstance().UpdateSandboxInfo(docUriSet, info, false);
642         if (isInSandbox) {
643             return res;
644         }
645         std::vector<RetentionSandBoxInfo> retentionSandBoxInfoVec;
646         int32_t getRes = RetentionFileManager::GetInstance().GetRetentionSandboxList(info.bundleName,
647             retentionSandBoxInfoVec, false);
648         if (getRes != DLP_OK) {
649             DLP_LOG_ERROR(LABEL, "getRes != DLP_OK");
650             return getRes;
651         }
652         if (!retentionSandBoxInfoVec.empty()) {
653             if (!RemoveRetentionInfo(retentionSandBoxInfoVec, info)) {
654                 return DLP_SERVICE_ERROR_VALUE_INVALID;
655             }
656         }
657     }
658     return res;
659 }
660 
RemoveRetentionInfo(std::vector<RetentionSandBoxInfo> & retentionSandBoxInfoVec,RetentionInfo & info)661 bool DlpPermissionService::RemoveRetentionInfo(std::vector<RetentionSandBoxInfo>& retentionSandBoxInfoVec,
662     RetentionInfo& info)
663 {
664     int32_t uid = IPCSkeleton::GetCallingUid();
665     int32_t userId;
666     if (GetUserIdFromUid(uid, &userId) != 0) {
667         DLP_LOG_ERROR(LABEL, "get GetUserIdFromUid error");
668         return false;
669     }
670     for (auto iter = retentionSandBoxInfoVec.begin(); iter != retentionSandBoxInfoVec.end(); ++iter) {
671         if (appStateObserver_->CheckSandboxInfo(info.bundleName, iter->appIndex_, userId)) {
672             continue;
673         }
674         DeleteDlpSandboxInfo(info.bundleName, iter->appIndex_, userId);
675         UninstallDlpSandboxApp(info.bundleName, iter->appIndex_, userId);
676         RetentionFileManager::GetInstance().RemoveRetentionState(info.bundleName, iter->appIndex_);
677     }
678     return true;
679 }
680 
StartTimer()681 void DlpPermissionService::StartTimer()
682 {
683     std::lock_guard<std::mutex> lock(mutex_);
684     repeatTime_ = REPEAT_TIME;
685     if (thread_ != nullptr && !thread_->joinable()) { // avoid double assign to an active thread
686         DLP_LOG_ERROR(LABEL, "thread is active");
687         return;
688     }
689     thread_ = std::make_shared<std::thread>([this] { this->TerminalService(); });
690     thread_->detach();
691     return;
692 }
693 
TerminalService()694 void DlpPermissionService::TerminalService()
695 {
696     DLP_LOG_DEBUG(LABEL, "enter");
697     int32_t remainingTime = repeatTime_.load();
698     while (remainingTime > 0) {
699         std::this_thread::sleep_for(SLEEP_TIME);
700         repeatTime_--;
701         remainingTime = repeatTime_.load();
702         DLP_LOG_DEBUG(LABEL, "repeatTime_ %{public}d", remainingTime);
703     }
704     std::lock_guard<std::mutex> lock(terminalMutex_);
705     appStateObserver_->ExitSaAfterAllDlpManagerDie();
706 }
707 
GetRetentionSandboxList(const std::string & bundleName,std::vector<RetentionSandBoxInfo> & retentionSandBoxInfoVec)708 int32_t DlpPermissionService::GetRetentionSandboxList(const std::string& bundleName,
709     std::vector<RetentionSandBoxInfo>& retentionSandBoxInfoVec)
710 {
711     std::string callerBundleName;
712     uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
713     GetCallerBundleName(tokenId, callerBundleName);
714     if (callerBundleName == DLP_MANAGER &&
715         BundleManagerAdapter::GetInstance().CheckHapPermission(callerBundleName, PERMISSION_ACCESS_DLP_FILE)) {
716         callerBundleName = bundleName;
717     }
718     if (callerBundleName.empty()) {
719         DLP_LOG_ERROR(LABEL, "get bundleName error");
720         return DLP_SERVICE_ERROR_VALUE_INVALID;
721     }
722     return RetentionFileManager::GetInstance().GetRetentionSandboxList(callerBundleName, retentionSandBoxInfoVec, true);
723 }
724 
ClearKvStorage()725 static void ClearKvStorage()
726 {
727     int32_t userId;
728     if (!GetUserIdByForegroundAccount(&userId)) {
729         DLP_LOG_ERROR(LABEL, "get userID fail");
730         return;
731     }
732     std::map<std::string, std::string> keyMap;
733     SandboxConfigKvDataStorage::GetInstance().GetKeyMapByUserId(userId, keyMap);
734     for (auto iter = keyMap.begin(); iter != keyMap.end(); iter++) {
735         AccessTokenID tokenId = AccessToken::AccessTokenKit::GetHapTokenID(userId, iter->first, 0);
736         if (tokenId == 0 || std::to_string(tokenId) != iter->second) {
737             SandboxConfigKvDataStorage::GetInstance().DeleteSandboxConfigFromDataStorage(userId,
738                 iter->first, iter->second);
739         }
740     }
741 }
742 
ClearUnreservedSandbox()743 int32_t DlpPermissionService::ClearUnreservedSandbox()
744 {
745     std::lock_guard<std::mutex> lock(terminalMutex_);
746     ClearKvStorage();
747     RetentionFileManager::GetInstance().ClearUnreservedSandbox();
748     return DLP_OK;
749 }
750 
GetCallerBundleName(const uint32_t tokenId,std::string & bundleName)751 bool DlpPermissionService::GetCallerBundleName(const uint32_t tokenId, std::string& bundleName)
752 {
753     HapTokenInfo tokenInfo;
754     auto result = AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo);
755     if (result != RET_SUCCESS) {
756         DLP_LOG_ERROR(LABEL, "token:0x%{public}x, result:%{public}d", tokenId, result);
757         return false;
758     }
759     if (tokenInfo.bundleName.empty()) {
760         DLP_LOG_ERROR(LABEL, "bundlename is empty");
761         return false;
762     }
763     bundleName = tokenInfo.bundleName;
764     return true;
765 }
766 
GetDLPFileVisitRecord(std::vector<VisitedDLPFileInfo> & infoVec)767 int32_t DlpPermissionService::GetDLPFileVisitRecord(std::vector<VisitedDLPFileInfo>& infoVec)
768 {
769     std::string callerBundleName;
770     uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
771     if (!GetCallerBundleName(tokenId, callerBundleName)) {
772         return DLP_SERVICE_ERROR_VALUE_INVALID;
773     }
774     int32_t userId = GetCallingUserId();
775     if (userId < 0) {
776         DLP_LOG_ERROR(LABEL, "get userId error");
777         return DLP_SERVICE_ERROR_VALUE_INVALID;
778     }
779     int32_t result = DLP_OK;
780     {
781         std::lock_guard<std::mutex> lock(terminalMutex_);
782         result = VisitRecordFileManager::GetInstance().GetVisitRecordList(callerBundleName, userId, infoVec);
783     }
784     return result;
785 }
786 
SetMDMPolicy(const std::vector<std::string> & appIdList)787 int32_t DlpPermissionService::SetMDMPolicy(const std::vector<std::string>& appIdList)
788 {
789     if (appIdList.empty()) {
790         DLP_LOG_ERROR(LABEL, "get appIdList empty");
791         return DLP_SERVICE_ERROR_VALUE_INVALID;
792     }
793     int32_t uid = IPCSkeleton::GetCallingUid();
794     if (uid != EDM_UID) {
795         DLP_LOG_ERROR(LABEL, "invalid caller");
796         return DLP_SERVICE_ERROR_PERMISSION_DENY;
797     }
798     return DlpCredential::GetInstance().SetMDMPolicy(appIdList);
799 }
800 
GetMDMPolicy(std::vector<std::string> & appIdList)801 int32_t DlpPermissionService::GetMDMPolicy(std::vector<std::string>& appIdList)
802 {
803     int32_t uid = IPCSkeleton::GetCallingUid();
804     if (uid != EDM_UID) {
805         DLP_LOG_ERROR(LABEL, "invalid caller");
806         return DLP_SERVICE_ERROR_PERMISSION_DENY;
807     }
808     return DlpCredential::GetInstance().GetMDMPolicy(appIdList);
809 }
810 
RemoveMDMPolicy()811 int32_t DlpPermissionService::RemoveMDMPolicy()
812 {
813     int32_t uid = IPCSkeleton::GetCallingUid();
814     if (uid != EDM_UID) {
815         DLP_LOG_ERROR(LABEL, "invalid caller");
816         return DLP_SERVICE_ERROR_PERMISSION_DENY;
817     }
818     return DlpCredential::GetInstance().RemoveMDMPolicy();
819 }
820 
SetSandboxAppConfig(const std::string & configInfo)821 int32_t DlpPermissionService::SetSandboxAppConfig(const std::string& configInfo)
822 {
823     if (configInfo.size() >= OHOS::DistributedKv::Entry::MAX_VALUE_LENGTH) {
824         DLP_LOG_ERROR(LABEL, "configInfo is too long");
825         return DLP_PARSE_ERROR_VALUE_INVALID;
826     }
827     std::string temp = configInfo;
828     return SandboxConfigOperate(temp, SandboxConfigOperationEnum::ADD);
829 }
830 
CleanSandboxAppConfig()831 int32_t DlpPermissionService::CleanSandboxAppConfig()
832 {
833     std::string emptyStr = "";
834     return SandboxConfigOperate(emptyStr, SandboxConfigOperationEnum::CLEAN);
835 }
836 
GetSandboxAppConfig(std::string & configInfo)837 int32_t DlpPermissionService::GetSandboxAppConfig(std::string& configInfo)
838 {
839     return SandboxConfigOperate(configInfo, SandboxConfigOperationEnum::GET);
840 }
841 
IsDLPFeatureProvided(bool & isProvideDLPFeature)842 int32_t DlpPermissionService::IsDLPFeatureProvided(bool& isProvideDLPFeature)
843 {
844     std::string value = OHOS::system::GetParameter(DLP_ENABLE, "");
845     isProvideDLPFeature = (value == TRUE_VALUE);
846     return DLP_OK;
847 }
848 
SandConfigOperateCheck(SandboxConfigOperationEnum operationEnum,std::string & bundleName,int32_t & userId,AccessToken::AccessTokenID & originalTokenId)849 int32_t DlpPermissionService::SandConfigOperateCheck(SandboxConfigOperationEnum operationEnum, std::string& bundleName,
850     int32_t& userId, AccessToken::AccessTokenID& originalTokenId)
851 {
852     uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
853     bool result = GetCallerBundleName(tokenId, bundleName);
854     if (!result) {
855         return DLP_SERVICE_ERROR_VALUE_INVALID;
856     }
857     userId = GetCallingUserId();
858     if (userId < 0) {
859         DLP_LOG_ERROR(LABEL, "get userId error");
860         return DLP_SERVICE_ERROR_VALUE_INVALID;
861     }
862     originalTokenId = AccessToken::AccessTokenKit::GetHapTokenID(userId, bundleName, 0);
863     if (originalTokenId == 0) {
864         DLP_LOG_ERROR(LABEL, "Get normal tokenId error.");
865         return DLP_SERVICE_ERROR_VALUE_INVALID;
866     }
867     if (operationEnum == ADD && originalTokenId != tokenId) {
868         int32_t uid = IPCSkeleton::GetCallingUid();
869         DlpSandboxInfo info;
870         result = appStateObserver_->GetSandboxInfo(uid, info);
871         if (!result) {
872             DLP_LOG_ERROR(LABEL, "Can not found sandbox info, tokenId=%{public}u", tokenId);
873             return DLP_SERVICE_ERROR_VALUE_INVALID;
874         }
875         if (info.hasRead) {
876             DLP_LOG_ERROR(LABEL, "Sandbox has read dlp file, tokenId=%{public}u", tokenId);
877             return DLP_SERVICE_ERROR_API_NOT_FOR_SANDBOX_ERROR;
878         }
879     }
880     return DLP_OK;
881 }
882 
SandboxConfigOperate(std::string & configInfo,SandboxConfigOperationEnum operationEnum)883 int32_t DlpPermissionService::SandboxConfigOperate(std::string& configInfo, SandboxConfigOperationEnum operationEnum)
884 {
885     std::string callerBundleName;
886     int32_t userId;
887     AccessTokenID originalTokenId;
888     int32_t res = SandConfigOperateCheck(operationEnum, callerBundleName, userId, originalTokenId);
889     if (res != DLP_OK) {
890         return res;
891     }
892     res = DlpCredential::GetInstance().CheckMdmPermission(callerBundleName, userId);
893     if (res != DLP_OK) {
894         return res;
895     }
896     switch (operationEnum) {
897         case ADD:
898             res = SandboxConfigKvDataStorage::GetInstance().AddSandboxConfigIntoDataStorage(userId, callerBundleName,
899                 configInfo, std::to_string(originalTokenId));
900             break;
901         case GET:
902             res = SandboxConfigKvDataStorage::GetInstance().GetSandboxConfigFromDataStorage(userId, callerBundleName,
903                 configInfo, std::to_string(originalTokenId));
904             break;
905         case CLEAN:
906             res = SandboxConfigKvDataStorage::GetInstance().DeleteSandboxConfigFromDataStorage(userId,
907                 callerBundleName, std::to_string(originalTokenId));
908             break;
909         default:
910             DLP_LOG_ERROR(LABEL, "enter default case");
911             break;
912     }
913     return res;
914 }
915 
SetReadFlag(uint32_t uid)916 int32_t DlpPermissionService::SetReadFlag(uint32_t uid)
917 {
918     DlpSandboxInfo info;
919     appStateObserver_->GetSandboxInfo(uid, info);
920     int32_t res = RetentionFileManager::GetInstance().UpdateReadFlag(info.tokenId);
921     if (res != 0) {
922         return res;
923     }
924     appStateObserver_->UpdatReadFlag(uid);
925     return DLP_OK;
926 }
927 
Dump(int fd,const std::vector<std::u16string> & args)928 int DlpPermissionService::Dump(int fd, const std::vector<std::u16string>& args)
929 {
930     if (fd < 0) {
931         return ERR_INVALID_VALUE;
932     }
933 
934     dprintf(fd, "DlpPermission Dump:\n");
935     std::string arg0 = (args.size() == 0) ? "" : Str16ToStr8(args.at(0));
936     if (arg0.compare("-h") == 0) {
937         dprintf(fd, "Usage:\n");
938         dprintf(fd, "      -h: command help\n");
939         dprintf(fd, "      -d: default dump\n");
940     } else if (arg0.compare("-d") == 0 || arg0.compare("") == 0) {
941         if (appStateObserver_ != nullptr) {
942             appStateObserver_->DumpSandbox(fd);
943         } else {
944             return ERR_INVALID_VALUE;
945         }
946     }
947 
948     return ERR_OK;
949 }
950 } // namespace DlpPermission
951 } // namespace Security
952 } // namespace OHOS
953