• 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 #include "datashare_uri_utils.h"
16 #define LOG_TAG "DataSharePermission"
17 
18 #include "data_share_permission.h"
19 
20 #include <string>
21 
22 #include "access_token.h"
23 #include "bundle_mgr_helper.h"
24 #include "data_share_called_config.h"
25 #include "datashare_errno.h"
26 #include "datashare_log.h"
27 #include "datashare_string_utils.h"
28 #include "data_share_config.h"
29 #include "hiview_datashare.h"
30 #include "ipc_skeleton.h"
31 
32 namespace OHOS {
33 namespace DataShare {
34 using namespace AppExecFwk;
35 static constexpr const char *NO_PERMISSION = "noPermission";
VerifyPermission(Security::AccessToken::AccessTokenID tokenID,const Uri & uri,bool isRead)36 int DataSharePermission::VerifyPermission(Security::AccessToken::AccessTokenID tokenID, const Uri &uri, bool isRead)
37 {
38     if (uri.ToString().empty()) {
39         LOG_ERROR("Uri empty, tokenId:0x%{public}x", tokenID);
40         return ERR_INVALID_VALUE;
41     }
42     DataShareCalledConfig calledConfig(uri.ToString());
43     int32_t user = DataShareCalledConfig::GetUserByToken(tokenID);
44     auto [errCode, providerInfo] = calledConfig.GetProviderInfo(user);
45     if (errCode != E_OK) {
46         LOG_ERROR("ProviderInfo failed! token:0x%{public}x, errCode:%{public}d,uri:%{public}s", tokenID,
47             errCode, DataShareStringUtils::Anonymous(uri.ToString()).c_str());
48         return errCode;
49     }
50     auto permission = isRead ? providerInfo.readPermission : providerInfo.writePermission;
51     if (permission.empty()) {
52         LOG_ERROR("Reject, tokenId:0x%{public}x, uri:%{public}s", tokenID,
53             DataShareStringUtils::Anonymous(providerInfo.uri).c_str());
54         return ERR_PERMISSION_DENIED;
55     }
56     int status =
57         Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenID, permission);
58     if (status != Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
59         LOG_ERROR("Permission denied! token:0x%{public}x,permission:%{public}s,uri:%{public}s",
60             tokenID, permission.c_str(), DataShareStringUtils::Anonymous(providerInfo.uri).c_str());
61         return ERR_PERMISSION_DENIED;
62     }
63     return E_OK;
64 }
65 
IsInUriTrusts(Uri & uri)66 bool IsInUriTrusts(Uri &uri)
67 {
68     auto config = ConfigFactory::GetInstance().GetDataShareConfig();
69     if (config == nullptr) {
70         LOG_ERROR("GetDataShareConfig null");
71         return false;
72     }
73     std::string uriStr = uri.ToString();
74     for (std::string& item : config->uriTrusts) {
75         if (item.length() > uriStr.length() ||
76             uriStr.compare(0, item.length(), item) != 0) {
77             continue;
78         }
79         return true;
80     }
81     return false;
82 }
83 
CheckAppIdentifier(std::string & name,std::string & appIdentifier)84 bool CheckAppIdentifier(std::string &name, std::string &appIdentifier)
85 {
86     auto [isSuccess, bundleInfo]  = DataShareCalledConfig::GetBundleInfoFromBMS(name, 0);
87     if (!isSuccess) {
88         return false;
89     }
90     if (bundleInfo.signatureInfo.appIdentifier == appIdentifier) {
91         return true;
92     }
93     return false;
94 }
95 
IsInExtensionTrusts(std::string & consumer,std::string & provider)96 bool IsInExtensionTrusts(std::string& consumer, std::string& provider)
97 {
98     auto config = ConfigFactory::GetInstance().GetDataShareConfig();
99     if (config == nullptr) {
100         LOG_ERROR("GetDataShareConfig is null");
101         return false;
102     }
103     std::string appIdentifier;
104     for (DataShareConfig::ConsumerProvider& item : config->extensionObsTrusts) {
105         if (item.provider.name != provider) {
106             continue;
107         }
108         if (!CheckAppIdentifier(item.provider.name, item.provider.appIdentifier)) {
109             return false;
110         }
111         for (auto item : item.consumer) {
112             if (item.name == consumer) {
113                 appIdentifier = item.appIdentifier;
114                 break;
115             }
116         }
117     }
118     if (consumer == provider) {
119         return true;
120     }
121     if (CheckAppIdentifier(consumer, appIdentifier)) {
122         return true;
123     }
124     return false;
125 }
126 
UriIsTrust(Uri & uri)127 int32_t DataSharePermission::UriIsTrust(Uri &uri)
128 {
129     std::string schema = uri.GetScheme();
130     if (schema == SCHEMA_PREFERENCE ||  schema == SCHEMA_RDB || schema == SCHEMA_FILE) {
131         return E_OK;
132     }
133     if (IsInUriTrusts(uri)) {
134         return E_OK;
135     }
136     if (!schema.empty() && schema != SCHEMA_DATASHARE && schema != SCHEMA_DATASHARE_PROXY) {
137         LOG_ERROR("invalid uri %{public}s, schema %{public}s",
138             uri.ToString().c_str(), uri.GetScheme().c_str());
139         return E_DATASHARE_INVALID_URI;
140     }
141     return E_ERROR;
142 }
143 
GetExtensionUriPermission(Uri & uri,int32_t user,bool isRead)144 std::pair<int, std::string> DataSharePermission::GetExtensionUriPermission(Uri &uri,
145     int32_t user, bool isRead)
146 {
147     std::string uriStr = uri.ToString();
148     std::string permission;
149     auto [isSuccess, extensionInfo] = DataShareCalledConfig::GetExtensionInfoFromBMS(uriStr, user);
150     if (isSuccess) {
151         permission = isRead ? extensionInfo.readPermission : extensionInfo.writePermission;
152         LOG_ERROR("GetExtensionUriPermission uri %{public}s %{public}s %{public}s",
153             extensionInfo.uri.c_str(), extensionInfo.readPermission.c_str(), extensionInfo.writePermission.c_str());
154         return std::make_pair(E_OK, permission);
155     }
156     return std::make_pair(E_URI_NOT_EXIST, "");
157 }
158 
GetUriPermission(Uri & uri,int32_t user,bool isRead,bool isExtension)159 std::pair<int, std::string> DataSharePermission::GetUriPermission(Uri &uri, int32_t user, bool isRead, bool isExtension)
160 {
161     std::string uriStr = uri.ToString();
162     if (uriStr.empty()) {
163         return std::make_pair(E_EMPTY_URI, "");
164     }
165     int32_t ret = UriIsTrust(uri);
166     if (ret == E_OK) {
167         return std::make_pair(E_OK, NO_PERMISSION);
168     } else if (ret == E_DATASHARE_INVALID_URI) {
169         return std::make_pair(E_DATASHARE_INVALID_URI, "");
170     }
171     std::string permission;
172     if (isExtension) {
173         std::tie(ret, permission) = GetExtensionUriPermission(uri, user, isRead);
174     } else {
175         std::tie(ret, permission) = GetSilentUriPermission(uri, user, isRead);
176     }
177     if (ret == E_OK) {
178         return std::make_pair(E_OK, permission);
179     }
180     return std::make_pair(ret, "");
181 }
182 
ReportExcuteFault(int32_t errCode,std::string & consumer,std::string & provider)183 void DataSharePermission::ReportExcuteFault(int32_t errCode,  std::string &consumer, std::string &provider)
184 {
185     DataShareFaultInfo faultInfo = {HiViewFaultAdapter::trustsFailed, consumer, provider,
186         "", "", errCode, ""};
187     HiViewFaultAdapter::ReportDataFault(faultInfo);
188 }
189 
ReportExtensionFault(int32_t errCode,uint32_t tokenId,std::string & uri,std::string & bussinessType)190 void DataSharePermission::ReportExtensionFault(int32_t errCode, uint32_t tokenId,
191     std::string &uri, std::string &bussinessType)
192 {
193     auto [bundleName, ret] = HiViewFaultAdapter::GetCallingName(tokenId);
194     DataShareFaultInfo faultInfo = {HiViewFaultAdapter::extensionFailed, bundleName, "",
195         "", bussinessType, errCode, uri};
196     HiViewFaultAdapter::ReportDataFault(faultInfo);
197 }
198 
GetSilentUriPermission(Uri & uri,int32_t user,bool isRead)199 std::pair<int, std::string> DataSharePermission::GetSilentUriPermission(Uri &uri, int32_t user, bool isRead)
200 {
201     std::string uriStr = uri.ToString();
202     DataShareCalledConfig calledConfig(uriStr);
203 
204     auto [errCode, providerInfo] = calledConfig.GetProviderInfo(user);
205     if (errCode != E_OK) {
206         LOG_ERROR("ProviderInfo failed! user:%{public}d, errCode:%{public}d,uri:%{public}s", user,
207             errCode, uri.ToString().c_str());
208         return std::make_pair(errCode, "");
209     }
210     auto permission = isRead ? providerInfo.readPermission : providerInfo.writePermission;
211     return std::make_pair(E_OK, permission);
212 }
213 
CheckExtensionTrusts(uint32_t consumerToken,uint32_t providerToken)214 int DataSharePermission::CheckExtensionTrusts(uint32_t consumerToken, uint32_t providerToken)
215 {
216     auto [consumer, ret1] = HiViewFaultAdapter::GetCallingName(consumerToken);
217     auto [provider, ret2] = HiViewFaultAdapter::GetCallingName(providerToken);
218     if (ret1 != E_OK || ret2 != E_OK) {
219         LOG_ERROR("GetCallingName failed, consumer %{public}d %{public}s provider %{public}d "
220             "%{public}s", consumerToken, consumer.c_str(), providerToken, provider.c_str());
221         return E_GET_CALLER_NAME_FAILED;
222     }
223     if (IsInExtensionTrusts(consumer, provider)) {
224         return E_OK;
225     }
226     LOG_ERROR("CheckExtensionTrusts failed, consumer %{public}d %{public}s provider %{public}d "
227         "%{public}s", consumerToken, consumer.c_str(), providerToken, provider.c_str());
228     ReportExcuteFault(E_NOT_IN_TRUSTS, consumer, provider);
229     return E_NOT_IN_TRUSTS;
230 }
231 
VerifyPermission(uint32_t tokenID,std::string & permission)232 bool DataSharePermission::VerifyPermission(uint32_t tokenID, std::string &permission)
233 {
234     if (permission.empty() || permission == NO_PERMISSION) {
235         return true;
236     }
237     int status = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenID, permission);
238     if (status != Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
239         return false;
240     }
241     return true;
242 }
243 
VerifyPermission(Uri & uri,uint32_t tokenID,std::string & permission,bool isExtension)244 bool DataSharePermission::VerifyPermission(Uri &uri, uint32_t tokenID, std::string &permission, bool isExtension)
245 {
246     if (permission == NO_PERMISSION) {
247         return true;
248     }
249 
250     std::string uriStr = uri.ToString();
251     DataShareCalledConfig calledConfig(uriStr);
252     std::string providerName = calledConfig.BundleName();
253 
254     auto [callingName, ret] = HiViewFaultAdapter::GetCallingName(tokenID);
255     if (ret != E_OK) {
256         LOG_WARN("GetCallingName failed, ret %{public}d", ret);
257     }
258     if (permission.empty() && isExtension) {
259         return true;
260     }
261 
262     if (permission.empty() && !isExtension) {
263         LOG_INFO("Permission empty! token: %{public}d", tokenID);
264         Security::AccessToken::HapTokenInfo tokenInfo;
265         auto result = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenID, tokenInfo);
266         if (result == Security::AccessToken::RET_SUCCESS && tokenInfo.bundleName == providerName) {
267             return true;
268         }
269         LOG_ERROR("Permission denied! uri %{public}s callingName %{public}s token %{public}d",
270             uri.ToString().c_str(), providerName.c_str(), tokenID);
271         return false;
272     }
273 
274     int status = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenID, permission);
275     if (status != Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
276         return false;
277     }
278     return true;
279 }
280 
IsExtensionValid(uint32_t tokenId,uint32_t fullToken,int32_t user)281 int32_t DataSharePermission::IsExtensionValid(uint32_t tokenId, uint32_t fullToken, int32_t user)
282 {
283     Security::AccessToken::ATokenTypeEnum tokenType =
284         Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
285     if (tokenType != Security::AccessToken::ATokenTypeEnum::TOKEN_HAP) {
286         return E_NOT_HAP;
287     }
288     if (Security::AccessToken::AccessTokenKit::IsSystemAppByFullTokenID(fullToken)) {
289         return E_OK;
290     }
291     auto [bundleName, ret] = HiViewFaultAdapter::GetCallingName(tokenId);
292     if (ret != 0) {
293         return ret;
294     }
295 
296     auto [success, bundleInfo] = DataShareCalledConfig::GetBundleInfoFromBMS(bundleName, user);
297     if (!success) {
298         LOG_ERROR("Get bundleInfo failed! bundleName:%{public}s, userId:%{public}d",
299             bundleName.c_str(), user);
300         return E_GET_BUNDLEINFO_FAILED;
301     }
302     for (auto &item : bundleInfo.extensionInfos) {
303         if (item.type == AppExecFwk::ExtensionAbilityType::DATASHARE) {
304             return E_OK;
305         }
306     }
307     return E_NOT_DATASHARE_EXTENSION;
308 }
309 
310 } // namespace DataShare
311 } // namespace OHOS