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