1 /*
2 * Copyright (c) 2023 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 "PreProcessUtils"
16
17 #include "preprocess_utils.h"
18
19 #include <random>
20 #include <sstream>
21
22 #include "accesstoken_kit.h"
23 #include "bundlemgr/bundle_mgr_client_impl.h"
24 #include "device_manager_adapter.h"
25 #include "error_code.h"
26 #include "file.h"
27 #include "ipc_skeleton.h"
28 #include "log_print.h"
29 #include "udmf_radar_reporter.h"
30 #include "remote_file_share.h"
31 #include "uri.h"
32 #include "utils/crypto.h"
33 #include "want.h"
34 #include "uri_permission_manager_client.h"
35 namespace OHOS {
36 namespace UDMF {
37 static constexpr int ID_LEN = 32;
38 static constexpr int MINIMUM = 48;
39 static constexpr int MAXIMUM = 121;
40 constexpr char SPECIAL = '^';
41 constexpr const char *FILE_SCHEME = "file";
42 static constexpr uint32_t VERIFY_URI_PERMISSION_MAX_SIZE = 500;
43 using namespace Security::AccessToken;
44 using namespace OHOS::AppFileService::ModuleRemoteFileShare;
45 using namespace RadarReporter;
46
RuntimeDataImputation(UnifiedData & data,CustomOption & option)47 int32_t PreProcessUtils::RuntimeDataImputation(UnifiedData &data, CustomOption &option)
48 {
49 auto it = UD_INTENTION_MAP.find(option.intention);
50 if (it == UD_INTENTION_MAP.end()) {
51 return E_ERROR;
52 }
53 std::string bundleName;
54 GetHapBundleNameByToken(option.tokenId, bundleName);
55 std::string intention = it->second;
56 UnifiedKey key(intention, bundleName, GenerateId());
57 Privilege privilege;
58 privilege.tokenId = option.tokenId;
59 Runtime runtime;
60 runtime.key = key;
61 runtime.privileges.emplace_back(privilege);
62 runtime.createTime = GetTimestamp();
63 runtime.sourcePackage = bundleName;
64 runtime.createPackage = bundleName;
65 runtime.deviceId = GetLocalDeviceId();
66 runtime.recordTotalNum = static_cast<uint32_t>(data.GetRecords().size());
67 runtime.tokenId = option.tokenId;
68 data.SetRuntime(runtime);
69 return E_OK;
70 }
71
GenerateId()72 std::string PreProcessUtils::GenerateId()
73 {
74 std::vector<uint8_t> randomDevices = DistributedData::Crypto::Random(ID_LEN, MINIMUM, MAXIMUM);
75 std::stringstream idStr;
76 for (auto &randomDevice : randomDevices) {
77 auto asc = randomDevice;
78 asc = asc >= SPECIAL ? asc + 1 : asc;
79 idStr << static_cast<uint8_t>(asc);
80 }
81 return idStr.str();
82 }
83
GetTimestamp()84 time_t PreProcessUtils::GetTimestamp()
85 {
86 std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds> tp =
87 std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
88 time_t timestamp = tp.time_since_epoch().count();
89 return timestamp;
90 }
91
GetHapUidByToken(uint32_t tokenId)92 int32_t PreProcessUtils::GetHapUidByToken(uint32_t tokenId)
93 {
94 Security::AccessToken::HapTokenInfo tokenInfo;
95 auto result = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo);
96 if (result != Security::AccessToken::AccessTokenKitRet::RET_SUCCESS) {
97 ZLOGE("GetHapUidByToken failed, result = %{public}d.", result);
98 return E_ERROR;
99 }
100 return tokenInfo.userID;
101 }
102
GetHapBundleNameByToken(int tokenId,std::string & bundleName)103 bool PreProcessUtils::GetHapBundleNameByToken(int tokenId, std::string &bundleName)
104 {
105 Security::AccessToken::HapTokenInfo hapInfo;
106 if (Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo)
107 != Security::AccessToken::AccessTokenKitRet::RET_SUCCESS) {
108 return false;
109 }
110 bundleName = hapInfo.bundleName;
111 return true;
112 }
113
GetNativeProcessNameByToken(int tokenId,std::string & processName)114 bool PreProcessUtils::GetNativeProcessNameByToken(int tokenId, std::string &processName)
115 {
116 Security::AccessToken::NativeTokenInfo nativeInfo;
117 if (Security::AccessToken::AccessTokenKit::GetNativeTokenInfo(tokenId, nativeInfo)
118 != Security::AccessToken::AccessTokenKitRet::RET_SUCCESS) {
119 return false;
120 }
121 processName = nativeInfo.processName;
122 return true;
123 }
124
GetLocalDeviceId()125 std::string PreProcessUtils::GetLocalDeviceId()
126 {
127 auto info = DistributedData::DeviceManagerAdapter::GetInstance().GetLocalDevice();
128 std::string encryptedUuid = DistributedData::DeviceManagerAdapter::GetInstance().CalcClientUuid(" ", info.uuid);
129 return encryptedUuid;
130 }
131
SetRemoteData(UnifiedData & data)132 void PreProcessUtils::SetRemoteData(UnifiedData &data)
133 {
134 if (data.IsEmpty()) {
135 ZLOGD("invalid data.");
136 return;
137 }
138 std::shared_ptr<Runtime> runtime = data.GetRuntime();
139 if (runtime->deviceId == GetLocalDeviceId()) {
140 ZLOGD("not remote data.");
141 return;
142 }
143 ZLOGD("is remote data.");
144 auto records = data.GetRecords();
145 for (auto record : records) {
146 auto type = record->GetType();
147 if (IsFileType(type)) {
148 auto file = static_cast<File *>(record.get());
149 UDDetails details = file->GetDetails();
150 details.insert({ "isRemote", "true" });
151 file->SetDetails(details);
152 }
153 }
154 }
155
IsFileType(UDType udType)156 bool PreProcessUtils::IsFileType(UDType udType)
157 {
158 return (udType == UDType::FILE || udType == UDType::IMAGE || udType == UDType::VIDEO || udType == UDType::AUDIO
159 || udType == UDType::FOLDER);
160 }
161
SetRemoteUri(uint32_t tokenId,UnifiedData & data)162 int32_t PreProcessUtils::SetRemoteUri(uint32_t tokenId, UnifiedData &data)
163 {
164 int32_t userId = GetHapUidByToken(tokenId);
165 std::vector<std::string> uris;
166 for (const auto &record : data.GetRecords()) {
167 if (record != nullptr && IsFileType(record->GetType())) {
168 auto file = static_cast<File *>(record.get());
169 if (file->GetUri().empty()) {
170 ZLOGW("Get uri empty, plase check the uri.");
171 continue;
172 }
173 Uri uri(file->GetUri());
174 std::string scheme = uri.GetScheme();
175 std::transform(scheme.begin(), scheme.end(), scheme.begin(), ::tolower);
176 if (uri.GetAuthority().empty() || scheme != FILE_SCHEME) {
177 ZLOGW("Get uri authority empty or uri scheme not equals to file.");
178 continue;
179 }
180 uris.push_back(file->GetUri());
181 }
182 }
183 if (!uris.empty()) {
184 if (!CheckUriAuthorization(uris, tokenId)) {
185 ZLOGE("CheckUriAuthorization failed, bundleName:%{public}s, tokenId: %{public}d, uris size:%{public}zu.",
186 data.GetRuntime()->createPackage.c_str(), tokenId, uris.size());
187 RadarReporterAdapter::ReportFail(std::string(__FUNCTION__),
188 BizScene::SET_DATA, SetDataStage::VERIFY_SHARE_PERMISSIONS, StageRes::FAILED, E_NO_PERMISSION);
189 return E_NO_PERMISSION;
190 }
191 if (!IsNetworkingEnabled()) {
192 return E_OK;
193 }
194 int ret = GetDfsUrisFromLocal(uris, userId, data);
195 if (ret != E_OK) {
196 RadarReporterAdapter::ReportFail(std::string(__FUNCTION__),
197 BizScene::SET_DATA, SetDataStage::GERERATE_DFS_URI, StageRes::FAILED, E_FS_ERROR);
198 ZLOGE("Get remoteUri failed, ret = %{public}d, userId: %{public}d, uri size:%{public}zu.",
199 ret, userId, uris.size());
200 return E_FS_ERROR;
201 }
202 }
203 return E_OK;
204 }
205
GetDfsUrisFromLocal(const std::vector<std::string> & uris,int32_t userId,UnifiedData & data)206 int32_t PreProcessUtils::GetDfsUrisFromLocal(const std::vector<std::string> &uris, int32_t userId, UnifiedData &data)
207 {
208 std::unordered_map<std::string, HmdfsUriInfo> dfsUris;
209 int ret = RemoteFileShare::GetDfsUrisFromLocal(uris, userId, dfsUris);
210 if (ret != 0 || dfsUris.empty()) {
211 ZLOGE("Get remoteUri failed, ret = %{public}d, userId: %{public}d, uri size:%{public}zu.",
212 ret, userId, uris.size());
213 return E_FS_ERROR;
214 }
215 for (const auto &record : data.GetRecords()) {
216 if (record != nullptr && IsFileType(record->GetType())) {
217 auto file = static_cast<File *>(record.get());
218 auto iter = dfsUris.find(file->GetUri());
219 if (iter != dfsUris.end()) {
220 file->SetRemoteUri((iter->second).uriStr);
221 }
222 }
223 }
224 return E_OK;
225 }
226
CheckUriAuthorization(const std::vector<std::string> & uris,uint32_t tokenId)227 bool PreProcessUtils::CheckUriAuthorization(const std::vector<std::string>& uris, uint32_t tokenId)
228 {
229 for (size_t index = 0; index < uris.size(); index += VERIFY_URI_PERMISSION_MAX_SIZE) {
230 std::vector<std::string> urisToBeChecked(
231 uris.begin() + index, uris.begin() + std::min(index + VERIFY_URI_PERMISSION_MAX_SIZE, uris.size()));
232 auto checkResults = AAFwk::UriPermissionManagerClient::GetInstance().CheckUriAuthorization(
233 urisToBeChecked, AAFwk::Want::FLAG_AUTH_READ_URI_PERMISSION, tokenId);
234 auto iter = find(checkResults.begin(), checkResults.end(), false);
235 if (iter != checkResults.end()) {
236 return false;
237 }
238 }
239 return true;
240 }
241
GetInstIndex(uint32_t tokenId,int32_t & instIndex)242 bool PreProcessUtils::GetInstIndex(uint32_t tokenId, int32_t &instIndex)
243 {
244 if (AccessTokenKit::GetTokenTypeFlag(tokenId) != TOKEN_HAP) {
245 instIndex = 0;
246 return true;
247 }
248 HapTokenInfo tokenInfo;
249 int errCode = AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo);
250 if (errCode != RET_SUCCESS) {
251 ZLOGE("Get Hap TokenInfo error:%{public}d, tokenId:0x%{public}x", errCode, tokenId);
252 return false;
253 }
254 instIndex = tokenInfo.instIndex;
255 return true;
256 }
257
IsNetworkingEnabled()258 bool PreProcessUtils::IsNetworkingEnabled()
259 {
260 std::vector<AppDistributedKv::DeviceInfo> devInfos =
261 DistributedData::DeviceManagerAdapter::GetInstance().GetRemoteDevices();
262 ZLOGI("DM remote devices count is %{public}u.", static_cast<uint32_t>(devInfos.size()));
263 if (devInfos.empty()) {
264 return false;
265 }
266 return true;
267 }
268 } // namespace UDMF
269 } // namespace OHOS