• 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 #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