• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }