1 /*
2  * Copyright (c) 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 #include "file_permission_manager.h"
16 
17 #include "accesstoken_kit.h"
18 #include "file_uri.h"
19 #include "hilog_tag_wrapper.h"
20 #include "ipc_skeleton.h"
21 #include "permission_constants.h"
22 #include "permission_verification.h"
23 #include "tokenid_kit.h"
24 #include "uri.h"
25 
26 namespace OHOS {
27 namespace AAFwk {
28 constexpr const uint32_t SANDBOX_MANAGER_OK = 0;
29 const std::string FILE_MANAGER_AUTHORITY = "docs";
30 const std::string DOWNLOAD_PATH = "/storage/Users/currentUser/Download";
31 const std::string DESKTOP_PATH = "/storage/Users/currentUser/Desktop";
32 const std::string DOCUMENTS_PATH = "/storage/Users/currentUser/Documents";
33 const std::string CURRENTUSER = "currentUser";
34 
CheckPermission(uint64_t tokenCaller, const std::string &permission)35 static bool CheckPermission(uint64_t tokenCaller, const std::string &permission)
36 {
37     return PermissionVerification::GetInstance()->VerifyPermissionByTokenId(tokenCaller, permission);
38 }
39 
CheckFileManagerUriPermission(uint64_t providerTokenId, std::string &path)40 static bool CheckFileManagerUriPermission(uint64_t providerTokenId, std::string &path)
41 {
42     if (path.find(DOWNLOAD_PATH) == 0) {
43         return CheckPermission(providerTokenId, PermissionConstants::PERMISSION_READ_WRITE_DOWNLOAD);
44     }
45     if (path.find(DESKTOP_PATH) == 0) {
46         return CheckPermission(providerTokenId, PermissionConstants::PERMISSION_READ_WRITE_DESKTON);
47     }
48     if (path.find(DOCUMENTS_PATH) == 0) {
49         return CheckPermission(providerTokenId, PermissionConstants::PERMISSION_READ_WRITE_DOCUMENTS);
50     }
51     return false;
52 }
53 
GetPathPolicyInfoFromUri(Uri &uri, uint32_t flag, const std::string &bundleName)54 PolicyInfo FilePermissionManager::GetPathPolicyInfoFromUri(Uri &uri, uint32_t flag, const std::string &bundleName)
55 {
56     AppFileService::ModuleFileUri::FileUri fileUri(uri.ToString());
57     std::string path = fileUri.GetRealPathBySA(bundleName);
58     PolicyInfo policyInfo;
59     policyInfo.path = path;
60     policyInfo.mode = (flag & (OperationMode::READ_MODE | OperationMode::WRITE_MODE));
61     return policyInfo;
62 }
63 
CheckUriPersistentPermission(std::vector<Uri> &uriVec, uint32_t callerTokenId, uint32_t flag, std::vector<PolicyInfo> &pathPolicies)64 std::vector<bool> FilePermissionManager::CheckUriPersistentPermission(std::vector<Uri> &uriVec,
65     uint32_t callerTokenId, uint32_t flag, std::vector<PolicyInfo> &pathPolicies)
66 {
67     TAG_LOGI(AAFwkTag::URIPERMMGR,
68         "call, uri size:%{public}zu", uriVec.size());
69     std::vector<bool> resultCodes(uriVec.size(), false);
70     pathPolicies.clear();
71     if (CheckPermission(callerTokenId, PermissionConstants::PERMISSION_FILE_ACCESS_MANAGER)) {
72         for (size_t i = 0; i < uriVec.size(); i++) {
73             resultCodes[i] = true;
74             PolicyInfo policyInfo = GetPathPolicyInfoFromUri(uriVec[i], flag);
75             pathPolicies.emplace_back(policyInfo);
76         }
77         return resultCodes;
78     }
79     std::vector<int32_t> resultIndex;
80     std::vector<PolicyInfo> persistPolicys;
81     for (size_t i = 0; i < uriVec.size(); i++) {
82         PolicyInfo policyInfo = GetPathPolicyInfoFromUri(uriVec[i], flag);
83         pathPolicies.emplace_back(policyInfo);
84         if (uriVec[i].GetAuthority() == FILE_MANAGER_AUTHORITY &&
85             CheckFileManagerUriPermission(callerTokenId, policyInfo.path)) {
86             resultCodes[i] = true;
87             continue;
88         }
89         resultIndex.emplace_back(i);
90         persistPolicys.emplace_back(policyInfo);
91     }
92 #ifdef ABILITY_RUNTIME_FEATURE_SANDBOXMANAGER
93     std::vector<bool> persistResultCodes;
94     int32_t ret = SandboxManagerKit::CheckPersistPolicy(callerTokenId, persistPolicys, persistResultCodes);
95     if (ret == SANDBOX_MANAGER_OK && persistResultCodes.size() == resultIndex.size()) {
96         for (size_t i = 0; i < persistResultCodes.size(); i++) {
97             auto index = resultIndex[i];
98             resultCodes[index] = persistResultCodes[i];
99         }
100     }
101 #endif
102     return resultCodes;
103 }
104 }
105 }
106