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