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