• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "dds_trace.h"
23 #include "udmf_radar_reporter.h"
24 #include "accesstoken_kit.h"
25 #include "bundlemgr/bundle_mgr_client_impl.h"
26 #include "device_manager_adapter.h"
27 #include "error_code.h"
28 #include "ipc_skeleton.h"
29 #include "log_print.h"
30 #include "udmf_radar_reporter.h"
31 #include "udmf_utils.h"
32 #include "remote_file_share.h"
33 #include "uri.h"
34 #include "utils/crypto.h"
35 #include "want.h"
36 #include "uri_permission_manager_client.h"
37 namespace OHOS {
38 namespace UDMF {
39 static constexpr int ID_LEN = 32;
40 static constexpr int MINIMUM = 48;
41 static constexpr int MAXIMUM = 121;
42 constexpr char SPECIAL = '^';
43 constexpr const char *FILE_SCHEME = "file";
44 constexpr const char *TAG = "PreProcessUtils::";
45 static constexpr uint32_t VERIFY_URI_PERMISSION_MAX_SIZE = 500;
46 using namespace OHOS::DistributedDataDfx;
47 using namespace Security::AccessToken;
48 using namespace OHOS::AppFileService::ModuleRemoteFileShare;
49 using namespace RadarReporter;
50 
RuntimeDataImputation(UnifiedData & data,CustomOption & option)51 int32_t PreProcessUtils::RuntimeDataImputation(UnifiedData &data, CustomOption &option)
52 {
53     auto it = UD_INTENTION_MAP.find(option.intention);
54     if (it == UD_INTENTION_MAP.end()) {
55         return E_ERROR;
56     }
57     std::string bundleName;
58     GetHapBundleNameByToken(option.tokenId, bundleName);
59     std::string intention = it->second;
60     UnifiedKey key(intention, bundleName, GenerateId());
61     Privilege privilege;
62     privilege.tokenId = option.tokenId;
63     Runtime runtime;
64     runtime.key = key;
65     runtime.privileges.emplace_back(privilege);
66     runtime.createTime = GetTimestamp();
67     runtime.sourcePackage = bundleName;
68     runtime.createPackage = bundleName;
69     runtime.deviceId = GetLocalDeviceId();
70     runtime.recordTotalNum = static_cast<uint32_t>(data.GetRecords().size());
71     runtime.tokenId = option.tokenId;
72     data.SetRuntime(runtime);
73     return E_OK;
74 }
75 
GenerateId()76 std::string PreProcessUtils::GenerateId()
77 {
78     std::vector<uint8_t> randomDevices = DistributedData::Crypto::Random(ID_LEN, MINIMUM, MAXIMUM);
79     std::stringstream idStr;
80     for (auto &randomDevice : randomDevices) {
81         auto asc = randomDevice;
82         asc = asc >= SPECIAL ? asc + 1 : asc;
83         idStr << static_cast<uint8_t>(asc);
84     }
85     return idStr.str();
86 }
87 
GetTimestamp()88 time_t PreProcessUtils::GetTimestamp()
89 {
90     std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds> tp =
91         std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
92     time_t timestamp = tp.time_since_epoch().count();
93     return timestamp;
94 }
95 
GetHapUidByToken(uint32_t tokenId,int & userId)96 int32_t PreProcessUtils::GetHapUidByToken(uint32_t tokenId, int &userId)
97 {
98     Security::AccessToken::HapTokenInfo tokenInfo;
99     auto result = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo);
100     if (result != Security::AccessToken::AccessTokenKitRet::RET_SUCCESS) {
101         ZLOGE("GetHapUidByToken failed, result = %{public}d.", result);
102         return E_ERROR;
103     }
104     userId = tokenInfo.userID;
105     return E_OK;
106 }
107 
GetHapBundleNameByToken(int tokenId,std::string & bundleName)108 bool PreProcessUtils::GetHapBundleNameByToken(int tokenId, std::string &bundleName)
109 {
110     Security::AccessToken::HapTokenInfo hapInfo;
111     if (Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo)
112         == Security::AccessToken::AccessTokenKitRet::RET_SUCCESS) {
113         bundleName = hapInfo.bundleName;
114         return true;
115     }
116     if (UTILS::IsTokenNative()) {
117         ZLOGD("TypeATokenTypeEnum is TOKEN_HAP");
118         std::string processName;
119         if (GetNativeProcessNameByToken(tokenId, processName)) {
120             bundleName = processName;
121             return true;
122         }
123     }
124     ZLOGE("GetHapBundleNameByToken faild");
125     return false;
126 }
127 
GetNativeProcessNameByToken(int tokenId,std::string & processName)128 bool PreProcessUtils::GetNativeProcessNameByToken(int tokenId, std::string &processName)
129 {
130     Security::AccessToken::NativeTokenInfo nativeInfo;
131     if (Security::AccessToken::AccessTokenKit::GetNativeTokenInfo(tokenId, nativeInfo)
132         != Security::AccessToken::AccessTokenKitRet::RET_SUCCESS) {
133         return false;
134     }
135     processName = nativeInfo.processName;
136     return true;
137 }
138 
GetLocalDeviceId()139 std::string PreProcessUtils::GetLocalDeviceId()
140 {
141     auto info = DistributedData::DeviceManagerAdapter::GetInstance().GetLocalDevice();
142     std::string encryptedUuid = DistributedData::DeviceManagerAdapter::GetInstance().CalcClientUuid(" ", info.uuid);
143     return encryptedUuid;
144 }
145 
SetRemoteData(UnifiedData & data)146 void PreProcessUtils::SetRemoteData(UnifiedData &data)
147 {
148     if (data.IsEmpty()) {
149         ZLOGD("invalid data.");
150         return;
151     }
152     std::shared_ptr<Runtime> runtime = data.GetRuntime();
153     if (runtime->deviceId == GetLocalDeviceId()) {
154         ZLOGD("not remote data.");
155         return;
156     }
157     ZLOGD("is remote data.");
158     auto records = data.GetRecords();
159     ProcessFileType(records, [] (std::shared_ptr<Object> obj) {
160         std::shared_ptr<Object> detailObj;
161         obj->GetValue(DETAILS, detailObj);
162         if (detailObj == nullptr) {
163             ZLOGE("Not contain details for object!");
164             return false;
165         }
166         UDDetails details = ObjectUtils::ConvertToUDDetails(detailObj);
167         details.insert({ "isRemote", "true" });
168         obj->value_[DETAILS] = ObjectUtils::ConvertToObject(details);
169         return true;
170     });
171 }
172 
IsFileType(std::shared_ptr<UnifiedRecord> record)173 bool PreProcessUtils::IsFileType(std::shared_ptr<UnifiedRecord> record)
174 {
175     if (record == nullptr) {
176         return false;
177     }
178     if (!std::holds_alternative<std::shared_ptr<Object>>(record->GetOriginValue())) {
179         return false;
180     }
181     auto obj = std::get<std::shared_ptr<Object>>(record->GetOriginValue());
182     return obj->value_.find(ORI_URI) != obj->value_.end();
183 }
184 
SetRemoteUri(uint32_t tokenId,UnifiedData & data)185 int32_t PreProcessUtils::SetRemoteUri(uint32_t tokenId, UnifiedData &data)
186 {
187     std::vector<std::string> uris;
188     ProcessFileType(data.GetRecords(), [&uris](std::shared_ptr<Object> obj) {
189         std::string oriUri;
190         obj->GetValue(ORI_URI, oriUri);
191         if (oriUri.empty()) {
192             ZLOGW("Get uri empty, plase check the uri.");
193             return false;
194         }
195         Uri uri(oriUri);
196         std::string scheme = uri.GetScheme();
197         std::transform(scheme.begin(), scheme.end(), scheme.begin(), ::tolower);
198         if (uri.GetAuthority().empty() || scheme != FILE_SCHEME) {
199             ZLOGW("Get uri authority empty or uri scheme not equals to file.");
200             return false;
201         }
202         uris.push_back(oriUri);
203         return true;
204     });
205     if (!uris.empty()) {
206         ZLOGI("Read to check uri authorization");
207         if (!CheckUriAuthorization(uris, tokenId)) {
208             ZLOGE("CheckUriAuthorization failed, bundleName:%{public}s, tokenId: %{public}d, uris size:%{public}zu.",
209                   data.GetRuntime()->createPackage.c_str(), tokenId, uris.size());
210             RadarReporterAdapter::ReportFail(std::string(__FUNCTION__),
211                 BizScene::SET_DATA, SetDataStage::VERIFY_SHARE_PERMISSIONS, StageRes::FAILED, E_NO_PERMISSION);
212             return E_NO_PERMISSION;
213         }
214         if (!IsNetworkingEnabled()) {
215             return E_OK;
216         }
217         int32_t userId;
218         if (GetHapUidByToken(tokenId, userId) == E_OK) {
219             GetDfsUrisFromLocal(uris, userId, data);
220         }
221     }
222     return E_OK;
223 }
224 
GetDfsUrisFromLocal(const std::vector<std::string> & uris,int32_t userId,UnifiedData & data)225 int32_t PreProcessUtils::GetDfsUrisFromLocal(const std::vector<std::string> &uris, int32_t userId, UnifiedData &data)
226 {
227     DdsTrace trace(
228         std::string(TAG) + std::string(__FUNCTION__), TraceSwitch::BYTRACE_ON | TraceSwitch::TRACE_CHAIN_ON);
229     RadarReporterAdapter::ReportNormal(std::string(__FUNCTION__),
230         BizScene::SET_DATA, SetDataStage::GERERATE_DFS_URI, StageRes::IDLE, BizState::DFX_BEGIN);
231     std::unordered_map<std::string, HmdfsUriInfo> dfsUris;
232     int ret = RemoteFileShare::GetDfsUrisFromLocal(uris, userId, dfsUris);
233     if (ret != 0 || dfsUris.empty()) {
234         RadarReporterAdapter::ReportFail(std::string(__FUNCTION__),
235             BizScene::SET_DATA, SetDataStage::GERERATE_DFS_URI, StageRes::FAILED, E_FS_ERROR, BizState::DFX_END);
236         ZLOGE("Get remoteUri failed, ret = %{public}d, userId: %{public}d, uri size:%{public}zu.",
237               ret, userId, uris.size());
238         return E_FS_ERROR;
239     }
240     RadarReporterAdapter::ReportNormal(std::string(__FUNCTION__),
241         BizScene::SET_DATA, SetDataStage::GERERATE_DFS_URI, StageRes::SUCCESS);
242     ProcessFileType(data.GetRecords(), [&dfsUris] (std::shared_ptr<Object> obj) {
243         std::string oriUri;
244         obj->GetValue(ORI_URI, oriUri);
245         auto iter = dfsUris.find(oriUri);
246         if (iter != dfsUris.end()) {
247             obj->value_[REMOTE_URI] = (iter->second).uriStr;
248         }
249         return true;
250     });
251     RadarReporterAdapter::ReportNormal(std::string(__FUNCTION__),
252         BizScene::SET_DATA, SetDataStage::GERERATE_DFS_URI, StageRes::SUCCESS, BizState::DFX_END);
253     return E_OK;
254 }
255 
CheckUriAuthorization(const std::vector<std::string> & uris,uint32_t tokenId)256 bool PreProcessUtils::CheckUriAuthorization(const std::vector<std::string>& uris, uint32_t tokenId)
257 {
258     for (size_t index = 0; index < uris.size(); index += VERIFY_URI_PERMISSION_MAX_SIZE) {
259         std::vector<std::string> urisToBeChecked(
260             uris.begin() + index, uris.begin() + std::min(index + VERIFY_URI_PERMISSION_MAX_SIZE, uris.size()));
261         auto checkResults = AAFwk::UriPermissionManagerClient::GetInstance().CheckUriAuthorization(
262             urisToBeChecked, AAFwk::Want::FLAG_AUTH_READ_URI_PERMISSION, tokenId);
263         auto iter = find(checkResults.begin(), checkResults.end(), false);
264         if (iter != checkResults.end()) {
265             return false;
266         }
267     }
268     return true;
269 }
270 
GetInstIndex(uint32_t tokenId,int32_t & instIndex)271 bool PreProcessUtils::GetInstIndex(uint32_t tokenId, int32_t &instIndex)
272 {
273     if (AccessTokenKit::GetTokenTypeFlag(tokenId) != TOKEN_HAP) {
274         instIndex = 0;
275         return true;
276     }
277     HapTokenInfo tokenInfo;
278     int errCode = AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo);
279     if (errCode != RET_SUCCESS) {
280         ZLOGE("Get Hap TokenInfo error:%{public}d, tokenId:0x%{public}x", errCode, tokenId);
281         return false;
282     }
283     instIndex = tokenInfo.instIndex;
284     return true;
285 }
286 
IsNetworkingEnabled()287 bool PreProcessUtils::IsNetworkingEnabled()
288 {
289     std::vector<AppDistributedKv::DeviceInfo> devInfos =
290         DistributedData::DeviceManagerAdapter::GetInstance().GetRemoteDevices();
291     ZLOGI("DM remote devices count is %{public}u.", static_cast<uint32_t>(devInfos.size()));
292     if (devInfos.empty()) {
293         return false;
294     }
295     return true;
296 }
297 
ProcessFileType(std::vector<std::shared_ptr<UnifiedRecord>> records,std::function<bool (std::shared_ptr<Object>)> callback)298 void PreProcessUtils::ProcessFileType(std::vector<std::shared_ptr<UnifiedRecord>> records,
299     std::function<bool(std::shared_ptr<Object>)> callback)
300 {
301     for (auto record : records) {
302         if (record == nullptr) {
303             continue;
304         }
305         if (!PreProcessUtils::IsFileType(record)) {
306             continue;
307         }
308         auto obj = std::get<std::shared_ptr<Object>>(record->GetOriginValue());
309         if (obj == nullptr) {
310             ZLOGE("ValueType is not Object, Not convert to remote uri!");
311             continue;
312         }
313         if (!callback(obj)) {
314             continue;
315         }
316     }
317 }
318 } // namespace UDMF
319 } // namespace OHOS