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 const std::string BACKFLASH = "/";
35 
CheckPermission(uint64_t tokenCaller,const std::string & permission)36 static bool CheckPermission(uint64_t tokenCaller, const std::string &permission)
37 {
38     return PermissionVerification::GetInstance()->VerifyPermissionByTokenId(tokenCaller, permission);
39 }
40 
CheckFileManagerUriPermission(uint64_t providerTokenId,const std::string & filePath,const std::string & bundleName)41 static bool CheckFileManagerUriPermission(uint64_t providerTokenId,
42                                           const std::string &filePath,
43                                           const std::string &bundleName)
44 {
45     std::string path = filePath;
46     if (path.find(DOWNLOAD_PATH) == 0) {
47         path = path.substr(DOWNLOAD_PATH.size());
48         if (path.find(BACKFLASH) == 0) {
49             path = path.substr(1);
50         }
51         std::string dirname = "";
52         if (path.find(BACKFLASH) != std::string::npos) {
53             size_t pos = path.find(BACKFLASH);
54             dirname = path.substr(0, pos);
55         } else {
56             dirname = path;
57         }
58         if (dirname == bundleName) {
59             return true;
60         }
61         return CheckPermission(providerTokenId, PermissionConstants::PERMISSION_READ_WRITE_DOWNLOAD);
62     }
63     if (path.find(DESKTOP_PATH) == 0) {
64         return CheckPermission(providerTokenId, PermissionConstants::PERMISSION_READ_WRITE_DESKTON);
65     }
66     if (path.find(DOCUMENTS_PATH) == 0) {
67         return CheckPermission(providerTokenId, PermissionConstants::PERMISSION_READ_WRITE_DOCUMENTS);
68     }
69     return false;
70 }
71 
GetPathPolicyInfoFromUri(Uri & uri,uint32_t flag,const std::string & bundleName)72 PolicyInfo FilePermissionManager::GetPathPolicyInfoFromUri(Uri &uri, uint32_t flag, const std::string &bundleName)
73 {
74     AppFileService::ModuleFileUri::FileUri fileUri(uri.ToString());
75     std::string path = fileUri.GetRealPathBySA(bundleName);
76     PolicyInfo policyInfo;
77     policyInfo.path = path;
78     policyInfo.mode = (flag & (OperationMode::READ_MODE | OperationMode::WRITE_MODE));
79     return policyInfo;
80 }
81 
CheckUriPersistentPermission(std::vector<Uri> & uriVec,uint32_t callerTokenId,uint32_t flag,std::vector<PolicyInfo> & pathPolicies,const std::string & bundleName)82 std::vector<bool> FilePermissionManager::CheckUriPersistentPermission(std::vector<Uri> &uriVec,
83     uint32_t callerTokenId, uint32_t flag, std::vector<PolicyInfo> &pathPolicies, const std::string &bundleName)
84 {
85     TAG_LOGI(AAFwkTag::URIPERMMGR,
86              "CheckUriPersistentPermission call, size of uri is %{public}zu", uriVec.size());
87     std::vector<bool> resultCodes(uriVec.size(), false);
88     pathPolicies.clear();
89     if (CheckPermission(callerTokenId, PermissionConstants::PERMISSION_FILE_ACCESS_MANAGER)) {
90         for (size_t i = 0; i < uriVec.size(); i++) {
91             resultCodes[i] = true;
92             PolicyInfo policyInfo = GetPathPolicyInfoFromUri(uriVec[i], flag);
93             pathPolicies.emplace_back(policyInfo);
94         }
95         return resultCodes;
96     }
97     std::vector<int32_t> resultIndex;
98     std::vector<PolicyInfo> persistPolicys;
99     for (size_t i = 0; i < uriVec.size(); i++) {
100         PolicyInfo policyInfo = GetPathPolicyInfoFromUri(uriVec[i], flag);
101         pathPolicies.emplace_back(policyInfo);
102         if (uriVec[i].GetAuthority() == FILE_MANAGER_AUTHORITY &&
103             CheckFileManagerUriPermission(callerTokenId, policyInfo.path, bundleName)) {
104             resultCodes[i] = true;
105             continue;
106         }
107         resultIndex.emplace_back(i);
108         persistPolicys.emplace_back(policyInfo);
109     }
110 #ifdef ABILITY_RUNTIME_FEATURE_SANDBOXMANAGER
111     std::vector<bool> persistResultCodes;
112     int32_t ret = SandboxManagerKit::CheckPersistPolicy(callerTokenId, persistPolicys, persistResultCodes);
113     if (ret == SANDBOX_MANAGER_OK && persistResultCodes.size() == resultIndex.size()) {
114         for (size_t i = 0; i < persistResultCodes.size(); i++) {
115             auto index = resultIndex[i];
116             resultCodes[index] = persistResultCodes[i];
117         }
118     }
119 #endif
120     return resultCodes;
121 }
122 }
123 }
124