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 #define LOG_TAG "DataShareCalledConfig"
16
17 #include "data_share_called_config.h"
18
19 #include <string>
20 #include <utility>
21
22 #include "access_token.h"
23 #include "accesstoken_kit.h"
24 #include "bundle_mgr_helper.h"
25 #include "datashare_errno.h"
26 #include "datashare_log.h"
27 #include "datashare_string_utils.h"
28 #include "data_share_permission.h"
29 #include "hiview_datashare.h"
30 #include "if_system_ability_manager.h"
31 #include "iservice_registry.h"
32 #include "ipc_skeleton.h"
33 #include "system_ability_definition.h"
34
35 namespace OHOS::DataShare {
36 using namespace OHOS::AppExecFwk;
37 using namespace OHOS::Security::AccessToken;
DataShareCalledConfig(const std::string & uri)38 DataShareCalledConfig::DataShareCalledConfig(const std::string &uri)
39 {
40 providerInfo_.uri = uri;
41 Uri uriTemp(providerInfo_.uri);
42 providerInfo_.schema = uriTemp.GetScheme();
43 auto isProxyData = PROXY_URI_SCHEMA == providerInfo_.schema;
44 std::string bundleName = uriTemp.GetAuthority();
45 if (!isProxyData) {
46 std::vector<std::string> pathSegments;
47 uriTemp.GetPathSegments(pathSegments);
48 if (pathSegments.size() != 0) {
49 bundleName = pathSegments[0];
50 }
51 }
52 providerInfo_.bundleName = bundleName;
53 }
54
BundleName()55 std::string DataShareCalledConfig::BundleName()
56 {
57 return providerInfo_.bundleName;
58 }
59
GetUserByToken(uint32_t tokenId)60 int32_t DataShareCalledConfig::GetUserByToken(uint32_t tokenId)
61 {
62 auto type = AccessTokenKit::GetTokenTypeFlag(tokenId);
63 if (type == TOKEN_NATIVE || type == TOKEN_SHELL) {
64 return 0;
65 }
66 HapTokenInfo tokenInfo;
67 auto result = AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo);
68 if (result != RET_SUCCESS) {
69 LOG_ERROR("Get user failed!token:0x%{public}x, result:%{public}d",
70 tokenId, result);
71 return -1;
72 }
73 return tokenInfo.userID;
74 }
75
GetFromProxyData()76 int DataShareCalledConfig::GetFromProxyData()
77 {
78 auto [success, bundleInfo] = GetBundleInfoFromBMS(providerInfo_.bundleName, providerInfo_.currentUserId);
79 if (!success) {
80 LOG_ERROR("Get bundleInfo failed! bundleName:%{public}s, userId:%{public}d, uri:%{public}s",
81 providerInfo_.bundleName.c_str(), providerInfo_.currentUserId,
82 DataShareStringUtils::Anonymous(providerInfo_.uri).c_str());
83 return E_BUNDLE_NAME_NOT_EXIST;
84 }
85 std::string uriWithoutQuery = providerInfo_.uri;
86 DataShareStringUtils::RemoveFromQuery(uriWithoutQuery);
87 size_t schemePos = uriWithoutQuery.find(Constants::PARAM_URI_SEPARATOR);
88 if (schemePos != uriWithoutQuery.npos) {
89 uriWithoutQuery.replace(schemePos, Constants::PARAM_URI_SEPARATOR_LEN, Constants::URI_SEPARATOR);
90 }
91 schemePos = uriWithoutQuery.find(EXT_URI_SCHEMA_SEPARATOR);
92 if (schemePos != uriWithoutQuery.npos) {
93 uriWithoutQuery.replace(schemePos, strlen(EXT_URI_SCHEMA_SEPARATOR), PROXY_URI_SCHEMA_SEPARATOR);
94 }
95 for (auto &hapModuleInfo : bundleInfo.hapModuleInfos) {
96 for (auto &data : hapModuleInfo.proxyDatas) {
97 if (data.uri.length() > uriWithoutQuery.length() ||
98 uriWithoutQuery.compare(0, data.uri.length(), data.uri) != 0) {
99 continue;
100 }
101 providerInfo_.readPermission = std::move(data.requiredReadPermission);
102 providerInfo_.writePermission = std::move(data.requiredWritePermission);
103 providerInfo_.moduleName = std::move(hapModuleInfo.moduleName);
104 return E_OK;
105 }
106 }
107 LOG_ERROR("E_URI_NOT_EXIST uriWithoutQuery %{public}s", uriWithoutQuery.c_str());
108 return E_URI_NOT_EXIST;
109 }
110
GetProviderInfo(int32_t user)111 std::pair<int, DataShareCalledConfig::ProviderInfo> DataShareCalledConfig::GetProviderInfo(int32_t user)
112 {
113 if (providerInfo_.bundleName.empty()) {
114 LOG_ERROR("BundleName not exist!, user:%{public}d, uri:%{public}s",
115 user, DataShareStringUtils::Anonymous(providerInfo_.uri).c_str());
116 return std::make_pair(E_BUNDLE_NAME_NOT_EXIST, DataShareCalledConfig::ProviderInfo{});
117 }
118 providerInfo_.currentUserId = user;
119 auto ret = GetFromProxyData();
120 if (ret != E_OK) {
121 LOG_ERROR("GetFromProxyData Failed! ret:%{public}d,user:%{public}d,uri:%{public}s",
122 ret, user, providerInfo_.uri.c_str());
123 }
124 return std::make_pair(ret, providerInfo_);
125 }
126
GetBundleInfoFromBMS(std::string bundleName,int32_t user)127 std::pair<bool, BundleInfo> DataShareCalledConfig::GetBundleInfoFromBMS(std::string bundleName, int32_t user)
128 {
129 BundleInfo bundleInfo;
130 auto bmsHelper = DelayedSingleton<BundleMgrHelper>::GetInstance();
131 if (bmsHelper == nullptr) {
132 LOG_ERROR("BmsHelper is nullptr!.uri: %{public}s",
133 DataShareStringUtils::Anonymous(bundleName).c_str());
134 return std::make_pair(false, bundleInfo);
135 }
136
137 if (user == 0) {
138 user = Constants::ANY_USERID;
139 }
140 // because BMS and obs are in the same process.
141 // set IPCSkeleton tokenid to this process's tokenid.
142 // otherwise BMS may check permission failed.
143 std::string identity = IPCSkeleton::ResetCallingIdentity();
144 bool ret = bmsHelper->GetBundleInfo(bundleName,
145 BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo, user);
146 IPCSkeleton::SetCallingIdentity(identity);
147 if (!ret) {
148 LOG_ERROR("Get BundleInfo failed! bundleName:%{public}s, userId:%{public}d",
149 bundleName.c_str(), user);
150 return std::make_pair(false, bundleInfo);
151 }
152 return std::make_pair(true, bundleInfo);
153 }
154
GetExtensionInfoFromBMS(std::string & uri,int32_t user)155 std::pair<bool, ExtensionAbilityInfo> DataShareCalledConfig::GetExtensionInfoFromBMS(std::string &uri, int32_t user)
156 {
157 ExtensionAbilityInfo info;
158 auto bmsHelper = DelayedSingleton<BundleMgrHelper>::GetInstance();
159 if (bmsHelper == nullptr) {
160 LOG_ERROR("BmsHelper is nullptr!.uri: %{public}s",
161 DataShareStringUtils::Anonymous(uri).c_str());
162 return std::make_pair(false, info);
163 }
164
165 if (user == 0) {
166 user = Constants::ANY_USERID;
167 }
168 // because BMS and obs are in the same process.
169 // set IPCSkeleton tokenid to this process's tokenid.
170 // otherwise BMS may check permission failed.
171 std::string identity = IPCSkeleton::ResetCallingIdentity();
172 bool ret = bmsHelper->QueryExtensionAbilityInfoByUri(uri, user, info);
173 IPCSkeleton::SetCallingIdentity(identity);
174 if (!ret) {
175 LOG_ERROR("QueryExtensionAbilityInfoByUri failed! uri:%{public}s, userId:%{public}d",
176 uri.c_str(), user);
177 return std::make_pair(false, info);
178 }
179 return std::make_pair(true, info);
180 }
181 } // namespace OHOS::DataShare