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 <sstream>
20
21 #include "accesstoken_kit.h"
22 #include "bundlemgr/bundle_mgr_client_impl.h"
23 #include "device_manager_adapter.h"
24 #include "error_code.h"
25 #include "file.h"
26 #include "ipc_skeleton.h"
27 #include "log_print.h"
28 #include "remote_file_share.h"
29 #include "uri.h"
30 namespace OHOS {
31 namespace UDMF {
32 static constexpr int ID_LEN = 32;
33 const char SPECIAL = '^';
34 const std::string PERMISSION_PROXY_AUTHORIZATION_URI = "ohos.permission.PROXY_AUTHORIZATION_URI";
35 using namespace Security::AccessToken;
36 using namespace OHOS::AppFileService::ModuleRemoteFileShare;
37
RuntimeDataImputation(UnifiedData & data,CustomOption & option)38 int32_t PreProcessUtils::RuntimeDataImputation(UnifiedData &data, CustomOption &option)
39 {
40 auto it = UD_INTENTION_MAP.find(option.intention);
41 if (it == UD_INTENTION_MAP.end()) {
42 return E_UNKNOWN;
43 }
44 std::string bundleName;
45 GetHapBundleNameByToken(option.tokenId, bundleName);
46 std::string intention = it->second;
47 UnifiedKey key(intention, bundleName, IdGenerator());
48 Privilege privilege;
49 privilege.tokenId = option.tokenId;
50 Runtime runtime;
51 runtime.key = key;
52 runtime.privileges.emplace_back(privilege);
53 runtime.createTime = GetTimeStamp();
54 runtime.sourcePackage = bundleName;
55 runtime.createPackage = bundleName;
56 runtime.deviceId = GetLocalDeviceId();
57 runtime.recordTotalNum = static_cast<uint32_t>(data.GetRecords().size());
58 data.SetRuntime(runtime);
59 return E_OK;
60 }
61
IdGenerator()62 std::string PreProcessUtils::IdGenerator()
63 {
64 std::random_device randomDevice;
65 int minimum = 48;
66 int maximum = 121;
67 std::uniform_int_distribution<int> distribution(minimum, maximum);
68 std::stringstream idStr;
69 for (int32_t i = 0; i < ID_LEN; i++) {
70 auto asc = distribution(randomDevice);
71 asc = asc >= SPECIAL ? asc + 1 : asc;
72 idStr << static_cast<uint8_t>(asc);
73 }
74 return idStr.str();
75 }
76
GetTimeStamp()77 time_t PreProcessUtils::GetTimeStamp()
78 {
79 std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds> tp =
80 std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
81 time_t timestamp = tp.time_since_epoch().count();
82 return timestamp;
83 }
84
GetHapUidByToken(uint32_t tokenId)85 int32_t PreProcessUtils::GetHapUidByToken(uint32_t tokenId)
86 {
87 Security::AccessToken::HapTokenInfo tokenInfo;
88 auto result = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo);
89 if (result != Security::AccessToken::AccessTokenKitRet::RET_SUCCESS) {
90 ZLOGE("GetHapUidByToken failed, result = %{public}d.", result);
91 return E_ERROR;
92 }
93 return tokenInfo.userID;
94 }
95
GetHapBundleNameByToken(int tokenId,std::string & bundleName)96 bool PreProcessUtils::GetHapBundleNameByToken(int tokenId, std::string &bundleName)
97 {
98 Security::AccessToken::HapTokenInfo hapInfo;
99 if (Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo)
100 != Security::AccessToken::AccessTokenKitRet::RET_SUCCESS) {
101 return false;
102 }
103 bundleName = hapInfo.bundleName;
104 return true;
105 }
106
GetNativeProcessNameByToken(int tokenId,std::string & processName)107 bool PreProcessUtils::GetNativeProcessNameByToken(int tokenId, std::string &processName)
108 {
109 Security::AccessToken::NativeTokenInfo nativeInfo;
110 if (Security::AccessToken::AccessTokenKit::GetNativeTokenInfo(tokenId, nativeInfo)
111 != Security::AccessToken::AccessTokenKitRet::RET_SUCCESS) {
112 return false;
113 }
114 processName = nativeInfo.processName;
115 return true;
116 }
117
GetLocalDeviceId()118 std::string PreProcessUtils::GetLocalDeviceId()
119 {
120 auto info = DistributedData::DeviceManagerAdapter::GetInstance().GetLocalDevice();
121 std::string encryptedUuid = DistributedData::DeviceManagerAdapter::GetInstance().CalcClientUuid(" ", info.uuid);
122 return encryptedUuid;
123 }
124
SetRemoteData(UnifiedData & data)125 void PreProcessUtils::SetRemoteData(UnifiedData &data)
126 {
127 if (data.IsEmpty()) {
128 ZLOGD("invalid data.");
129 return;
130 }
131 std::shared_ptr<Runtime> runtime = data.GetRuntime();
132 if (runtime->deviceId == GetLocalDeviceId()) {
133 ZLOGD("not remote data.");
134 return;
135 }
136 ZLOGD("is remote data.");
137 auto records = data.GetRecords();
138 for (auto record : records) {
139 auto type = record->GetType();
140 if (IsFileType(type)) {
141 auto file = static_cast<File *>(record.get());
142 UDDetails details = file->GetDetails();
143 details.insert({ "isRemote", "true" });
144 file->SetDetails(details);
145 }
146 }
147 }
148
IsFileType(UDType udType)149 bool PreProcessUtils::IsFileType(UDType udType)
150 {
151 return (udType == UDType::FILE || udType == UDType::IMAGE || udType == UDType::VIDEO || udType == UDType::AUDIO
152 || udType == UDType::FOLDER);
153 }
154
SetRemoteUri(uint32_t tokenId,UnifiedData & data)155 int32_t PreProcessUtils::SetRemoteUri(uint32_t tokenId, UnifiedData &data)
156 {
157 int32_t userId = GetHapUidByToken(tokenId);
158 std::string bundleName = data.GetRuntime()->createPackage;
159 for (const auto &record : data.GetRecords()) {
160 if (record != nullptr && IsFileType(record->GetType())) {
161 auto file = static_cast<File *>(record.get());
162 if (file->GetUri().empty()) {
163 ZLOGW("Get uri empty, plase check the uri.");
164 continue;
165 }
166 Uri uri(file->GetUri());
167 if (uri.GetAuthority().empty()) {
168 ZLOGW("Get uri authority empty.");
169 continue;
170 }
171 if (uri.GetAuthority() != bundleName
172 && !VerifyCallingPermission(tokenId, PERMISSION_PROXY_AUTHORIZATION_URI)) {
173 ZLOGE("No auth to handle this uri, authority=%{public}s, bundleName=%{public}s.",
174 uri.GetAuthority().c_str(), bundleName.c_str());
175 return E_NO_PERMISSION;
176 }
177 struct HmdfsUriInfo dfsUriInfo;
178 int ret = RemoteFileShare::GetDfsUriFromLocal(file->GetUri(), userId, dfsUriInfo);
179 if (ret != 0 || dfsUriInfo.uriStr.empty()) {
180 ZLOGE("Get remoteUri failed, ret = %{public}d, userId: %{public}d.", ret, userId);
181 return E_FS_ERROR;
182 }
183 file->SetRemoteUri(dfsUriInfo.uriStr);
184 }
185 }
186 return E_OK;
187 }
188
VerifyCallingPermission(uint32_t tokenId,const std::string & permissionName)189 bool PreProcessUtils::VerifyCallingPermission(uint32_t tokenId, const std::string &permissionName)
190 {
191 int32_t ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, permissionName);
192 if (ret != Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
193 ZLOGE("Permission %{public}s: PERMISSION_DENIED, ret=%{public}d ", permissionName.c_str(), ret);
194 return false;
195 }
196 ZLOGD("Verify AccessToken success, %{public}s", permissionName.c_str());
197 return true;
198 }
199 } // namespace UDMF
200 } // namespace OHOS