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