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
16 #include "oh_file_share.h"
17
18 #include <cstdint>
19 #include <cstdlib>
20 #include <iostream>
21
22 #include "access_token.h"
23 #include "accesstoken_kit.h"
24 #include "file_permission.h"
25 #include "ipc_skeleton.h"
26 #include "log.h"
27 #include "parameter.h"
28 #include "securec.h"
29 #include "tokenid_kit.h"
30
31 const int32_t FOO_MAX_LEN = sizeof(FileShare_PolicyErrorResult) * OHOS::AppFileService::MAX_ARRAY_SIZE;
32
33 using Exec = std::function<int(const std::vector<OHOS::AppFileService::UriPolicyInfo> &uriPolicies,
34 std::deque<struct OHOS::AppFileService::PolicyErrorResult> &errorResults)>;
35
ConvertPolicyInfo(const FileShare_PolicyInfo * policies,int policyNum,std::vector<OHOS::AppFileService::UriPolicyInfo> & uriPolicies)36 static bool ConvertPolicyInfo(const FileShare_PolicyInfo *policies,
37 int policyNum,
38 std::vector<OHOS::AppFileService::UriPolicyInfo> &uriPolicies)
39 {
40 for (int32_t i = 0; i < policyNum; i++) {
41 OHOS::AppFileService::UriPolicyInfo policyInfo;
42 if (policies[i].uri == nullptr || policies[i].length == 0) {
43 LOGE("The uri pointer is nullptr or length is 0");
44 return false;
45 }
46 auto uriLength = strnlen(policies[i].uri, policies[i].length);
47 if (uriLength != policies[i].length) {
48 LOGE("The uri length abnormal");
49 return false;
50 }
51 policyInfo.uri = std::string(policies[i].uri, policies[i].length);
52 policyInfo.mode = policies[i].operationMode;
53 uriPolicies.push_back(policyInfo);
54 }
55 return true;
56 }
57
ConvertPolicyErrorResult(const std::deque<OHOS::AppFileService::PolicyErrorResult> & errorResults,FileShare_PolicyErrorResult ** result,unsigned int & resultNum)58 static bool ConvertPolicyErrorResult(const std::deque<OHOS::AppFileService::PolicyErrorResult> &errorResults,
59 FileShare_PolicyErrorResult **result,
60 unsigned int &resultNum)
61 {
62 resultNum = 0;
63 auto count = errorResults.size();
64 auto memorySize = count * sizeof(FileShare_PolicyErrorResult);
65 if (memorySize == 0 || memorySize > FOO_MAX_LEN) {
66 LOGE("The size of the return value array is abnormal");
67 return false;
68 }
69 *result = static_cast<FileShare_PolicyErrorResult *>(malloc(memorySize));
70 if (*result == nullptr) {
71 LOGE("Failed to apply for FileShare_PolicyErrorResult array memory");
72 return false;
73 }
74 for (uint32_t i = 0; i < count; i++) {
75 size_t size = errorResults[i].uri.size() + 1;
76 (*result)[i].uri = static_cast<char *>(malloc(size));
77 if ((*result)[i].uri == nullptr) {
78 LOGE("Failed to apply for URI memory");
79 return false;
80 }
81 auto ret = strcpy_s((*result)[i].uri, size, errorResults[i].uri.c_str());
82 if (ret != 0) {
83 LOGE("Copy uri failed uri:%{private}s, errno:%{public}d", errorResults[i].uri.c_str(), ret);
84 free((*result)[i].uri);
85 return false;
86 }
87 (*result)[i].code = static_cast<FileShare_PolicyErrorCode>(errorResults[i].code);
88 size = errorResults[i].message.size() + 1;
89 (*result)[i].message = static_cast<char *>(malloc(size));
90 if ((*result)[i].message == nullptr) {
91 LOGE("Failed to apply for message memory");
92 free((*result)[i].uri);
93 return false;
94 }
95 ret = strcpy_s((*result)[i].message, size, errorResults[i].message.c_str());
96 if (ret != 0) {
97 LOGE("Copy message failed message:%{public}s, errno:%{public}d", errorResults[i].message.c_str(), ret);
98 free((*result)[i].uri);
99 free((*result)[i].message);
100 return false;
101 }
102 resultNum++;
103 }
104 return true;
105 }
106
ConvertPolicyErrorResultBool(const std::vector<bool> & errorResults,bool ** result)107 static bool ConvertPolicyErrorResultBool(const std::vector<bool> &errorResults, bool **result)
108 {
109 auto count = errorResults.size();
110 auto memorySize = count * sizeof(bool);
111 if (memorySize == 0 || memorySize > FOO_MAX_LEN) {
112 LOGE("The size of the return value array is abnormal");
113 return false;
114 }
115 *result = (bool *)malloc(memorySize);
116 if (*result == nullptr) {
117 LOGE("Failed to apply for bool array memory");
118 return false;
119 }
120 for (uint32_t i = 0; i < count; i++) {
121 (*result)[i] = errorResults[i];
122 }
123 return true;
124 }
125
ErrorCodeConversion(int32_t errorCode)126 static FileManagement_ErrCode ErrorCodeConversion(int32_t errorCode)
127 {
128 FileManagement_ErrCode errCode = ERR_UNKNOWN;
129 switch (errorCode) {
130 case static_cast<int32_t>(ERR_OK):
131 errCode = ERR_OK;
132 break;
133 case static_cast<int32_t>(ERR_PERMISSION_ERROR):
134 errCode = ERR_PERMISSION_ERROR;
135 break;
136 case static_cast<int32_t>(ERR_PARAMS):
137 errCode = ERR_PARAMS;
138 break;
139 case EPERM:
140 errCode = ERR_EPERM;
141 break;
142 default:
143 break;
144 }
145 return errCode;
146 }
147
148 void OH_FileShare_ReleasePolicyErrorResult(FileShare_PolicyErrorResult *result, unsigned int num);
ExecAction(const FileShare_PolicyInfo * policies,unsigned int policyNum,FileShare_PolicyErrorResult ** result,unsigned int * resultNum,Exec exec)149 static FileManagement_ErrCode ExecAction(const FileShare_PolicyInfo *policies,
150 unsigned int policyNum,
151 FileShare_PolicyErrorResult **result,
152 unsigned int *resultNum,
153 Exec exec)
154 {
155 (*resultNum) = 0;
156 std::vector<OHOS::AppFileService::UriPolicyInfo> uriPolicies;
157 if (!ConvertPolicyInfo(policies, policyNum, uriPolicies)) {
158 return ERR_PARAMS;
159 }
160 std::deque<OHOS::AppFileService::PolicyErrorResult> errorResults;
161 auto ret = ErrorCodeConversion(exec(uriPolicies, errorResults));
162 if (ret == ERR_OK) {
163 return ERR_OK;
164 }
165 if (!ConvertPolicyErrorResult(errorResults, result, *resultNum)) {
166 OH_FileShare_ReleasePolicyErrorResult(*result, *resultNum);
167 return ERR_ENOMEM;
168 }
169 return ret;
170 }
171
OH_FileShare_PersistPermission(const FileShare_PolicyInfo * policies,unsigned int policyNum,FileShare_PolicyErrorResult ** result,unsigned int * resultNum)172 FileManagement_ErrCode OH_FileShare_PersistPermission(const FileShare_PolicyInfo *policies,
173 unsigned int policyNum,
174 FileShare_PolicyErrorResult **result,
175 unsigned int *resultNum)
176 {
177 if (policies == nullptr || result == nullptr || resultNum == nullptr) {
178 LOGE("The external input pointer is abnormal");
179 return ERR_PARAMS;
180 }
181 if (policyNum == 0 || policyNum > OHOS::AppFileService::MAX_ARRAY_SIZE) {
182 LOGE("The policyNum is abnormal");
183 return ERR_PARAMS;
184 }
185 return ExecAction(policies, policyNum, result, resultNum, OHOS::AppFileService::FilePermission::PersistPermission);
186 }
187
OH_FileShare_RevokePermission(const FileShare_PolicyInfo * policies,unsigned int policyNum,FileShare_PolicyErrorResult ** result,unsigned int * resultNum)188 FileManagement_ErrCode OH_FileShare_RevokePermission(const FileShare_PolicyInfo *policies,
189 unsigned int policyNum,
190 FileShare_PolicyErrorResult **result,
191 unsigned int *resultNum)
192 {
193 if (policies == nullptr || result == nullptr || resultNum == nullptr) {
194 LOGE("The external input pointer is abnormal");
195 return ERR_PARAMS;
196 }
197 if (policyNum == 0 || policyNum > OHOS::AppFileService::MAX_ARRAY_SIZE) {
198 LOGE("The policyNum is abnormal");
199 return ERR_PARAMS;
200 }
201 return ExecAction(policies, policyNum, result, resultNum, OHOS::AppFileService::FilePermission::RevokePermission);
202 }
203
OH_FileShare_ActivatePermission(const FileShare_PolicyInfo * policies,unsigned int policyNum,FileShare_PolicyErrorResult ** result,unsigned int * resultNum)204 FileManagement_ErrCode OH_FileShare_ActivatePermission(const FileShare_PolicyInfo *policies,
205 unsigned int policyNum,
206 FileShare_PolicyErrorResult **result,
207 unsigned int *resultNum)
208 {
209 if (policies == nullptr || result == nullptr || resultNum == nullptr) {
210 LOGE("The external input pointer is abnormal");
211 return ERR_PARAMS;
212 }
213 if (policyNum == 0 || policyNum > OHOS::AppFileService::MAX_ARRAY_SIZE) {
214 LOGE("The policyNum is abnormal");
215 return ERR_PARAMS;
216 }
217 return ExecAction(policies, policyNum, result, resultNum, OHOS::AppFileService::FilePermission::ActivatePermission);
218 }
219
OH_FileShare_DeactivatePermission(const FileShare_PolicyInfo * policies,unsigned int policyNum,FileShare_PolicyErrorResult ** result,unsigned int * resultNum)220 FileManagement_ErrCode OH_FileShare_DeactivatePermission(const FileShare_PolicyInfo *policies,
221 unsigned int policyNum,
222 FileShare_PolicyErrorResult **result,
223 unsigned int *resultNum)
224 {
225 if (policies == nullptr || result == nullptr || resultNum == nullptr) {
226 LOGE("The external input pointer is abnormal");
227 return ERR_PARAMS;
228 }
229 if (policyNum == 0 || policyNum > OHOS::AppFileService::MAX_ARRAY_SIZE) {
230 LOGE("The policyNum is abnormal");
231 return ERR_PARAMS;
232 }
233 return ExecAction(policies, policyNum, result, resultNum,
234 OHOS::AppFileService::FilePermission::DeactivatePermission);
235 }
236
OH_FileShare_CheckPersistentPermission(const FileShare_PolicyInfo * policies,unsigned int policyNum,bool ** result,unsigned int * resultNum)237 FileManagement_ErrCode OH_FileShare_CheckPersistentPermission(const FileShare_PolicyInfo *policies,
238 unsigned int policyNum,
239 bool **result,
240 unsigned int *resultNum)
241 {
242 if (policies == nullptr || result == nullptr || resultNum == nullptr) {
243 LOGE("The external input pointer is abnormal");
244 return ERR_PARAMS;
245 }
246 if (policyNum == 0 || policyNum > OHOS::AppFileService::MAX_ARRAY_SIZE) {
247 LOGE("The policyNum is abnormal");
248 return ERR_PARAMS;
249 }
250 *resultNum = 0;
251 std::vector<OHOS::AppFileService::UriPolicyInfo> uriPolicies;
252 if (!ConvertPolicyInfo(policies, policyNum, uriPolicies)) {
253 return ERR_PARAMS;
254 }
255 std::vector<bool> errorResults;
256 auto ret = OHOS::AppFileService::FilePermission::CheckPersistentPermission(uriPolicies, errorResults);
257 if (ret != 0) {
258 return ErrorCodeConversion(ret);
259 }
260 if (!ConvertPolicyErrorResultBool(errorResults, result)) {
261 return ERR_ENOMEM;
262 }
263 *resultNum = errorResults.size();
264 return ERR_OK;
265 }
266
OH_FileShare_ReleasePolicyErrorResult(FileShare_PolicyErrorResult * result,unsigned int num)267 void OH_FileShare_ReleasePolicyErrorResult(FileShare_PolicyErrorResult *result, unsigned int num)
268 {
269 if (result == nullptr) {
270 return;
271 }
272 for (unsigned i = 0; i < num; i++) {
273 if (result[i].uri != nullptr) {
274 free(result[i].uri);
275 }
276 if (result[i].message != nullptr) {
277 free(result[i].message);
278 }
279 }
280 free(result);
281 }