1 /*
2 * Copyright (c) 2022-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
16 #include "usb_read_only_plugin.h"
17
18 #include <algorithm>
19 #include "array_usb_device_type_serializer.h"
20 #include "int_serializer.h"
21 #include "edm_constants.h"
22 #include "edm_ipc_interface_code.h"
23 #include "edm_utils.h"
24 #include "iservice_registry.h"
25 #include "parameters.h"
26 #include "usb_policy_utils.h"
27 #include "usb_srv_client.h"
28 #include "volume_external.h"
29 #include "iplugin_manager.h"
30
31 namespace OHOS {
32 namespace EDM {
33 const bool REGISTER_RESULT = IPluginManager::GetInstance()->AddPlugin(std::make_shared<UsbReadOnlyPlugin>());
34 constexpr int32_t STORAGE_MANAGER_MANAGER_ID = 5003;
35 constexpr int32_t USB_DEVICE_TYPE_BASE_CLASS_STORAGE = 8;
36 const std::string PARAM_USB_READ_ONLY_KEY = "persist.filemanagement.usb.readonly";
37
UsbReadOnlyPlugin()38 UsbReadOnlyPlugin::UsbReadOnlyPlugin()
39 {
40 policyCode_ = EdmInterfaceCode::USB_READ_ONLY;
41 policyName_ = "usb_read_only";
42 permissionConfig_.typePermissions.emplace(IPlugin::PermissionType::SUPER_DEVICE_ADMIN,
43 EdmPermission::PERMISSION_ENTERPRISE_MANAGE_USB);
44 permissionConfig_.apiType = IPlugin::ApiType::PUBLIC;
45 needSave_ = true;
46 }
47
OnHandlePolicy(std::uint32_t funcCode,MessageParcel & data,MessageParcel & reply,HandlePolicyData & policyData,int32_t userId)48 ErrCode UsbReadOnlyPlugin::OnHandlePolicy(std::uint32_t funcCode, MessageParcel &data, MessageParcel &reply,
49 HandlePolicyData &policyData, int32_t userId)
50 {
51 uint32_t typeCode = FUNC_TO_OPERATE(funcCode);
52 FuncOperateType type = FuncCodeUtils::ConvertOperateType(typeCode);
53 if (type != FuncOperateType::SET) {
54 EDMLOGE("UsbReadOnlyPlugin OnHandlePolicy can not handle this operate type.");
55 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
56 }
57 int32_t currentPolicy = 0;
58 int32_t mergePolicy = 0;
59 if (!IntSerializer::GetInstance()->Deserialize(policyData.policyData, currentPolicy) ||
60 !IntSerializer::GetInstance()->Deserialize(policyData.mergePolicyData, mergePolicy)) {
61 EDMLOGE("UsbReadOnlyPlugin OnHandlePolicy deserialize current policy and merge policy failed.");
62 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
63 }
64 int32_t accessPolicy = data.ReadInt32();
65 EDMLOGI("UsbReadOnlyPlugin OnHandlePolicy: %{public}d", accessPolicy);
66 if (mergePolicy == 0 || mergePolicy < accessPolicy) {
67 ErrCode ret = SetUsbStorageAccessPolicy(accessPolicy, userId);
68 if (ret != ERR_OK) {
69 return ret;
70 }
71 policyData.mergePolicyData = std::to_string(accessPolicy);
72 }
73 policyData.isChanged = accessPolicy != currentPolicy;
74 policyData.policyData = std::to_string(accessPolicy);
75 return ERR_OK;
76 }
77
SetUsbStorageAccessPolicy(int32_t accessPolicy,int32_t userId)78 ErrCode UsbReadOnlyPlugin::SetUsbStorageAccessPolicy(int32_t accessPolicy, int32_t userId)
79 {
80 auto policyManager = IPolicyManager::GetInstance();
81 std::string allowUsbDevicePolicy;
82 policyManager->GetPolicy("", "allowed_usb_devices", allowUsbDevicePolicy);
83 if (HasConflictPolicy(accessPolicy, allowUsbDevicePolicy)) {
84 return EdmReturnErrCode::CONFIGURATION_CONFLICT_FAILED;
85 }
86 std::vector<USB::UsbDeviceType> usbDeviceTypes;
87 GetDisallowedUsbDeviceTypes(usbDeviceTypes);
88 if (accessPolicy == EdmConstants::STORAGE_USB_POLICY_DISABLED) {
89 return DealDisablePolicy(usbDeviceTypes);
90 }
91 return DealReadPolicy(accessPolicy, allowUsbDevicePolicy, usbDeviceTypes);
92 }
93
HasConflictPolicy(int32_t accessPolicy,const std::string & allowUsbDevice)94 bool UsbReadOnlyPlugin::HasConflictPolicy(int32_t accessPolicy, const std::string &allowUsbDevice)
95 {
96 if (accessPolicy == EdmConstants::STORAGE_USB_POLICY_DISABLED && !allowUsbDevice.empty()) {
97 EDMLOGE("UsbReadOnlyPlugin policy conflict! AllowedUsbDevice: %{public}s", allowUsbDevice.c_str());
98 return true;
99 }
100 if (IsStorageDisabledByDisallowedPolicy() &&
101 (accessPolicy == EdmConstants::STORAGE_USB_POLICY_READ_WRITE ||
102 accessPolicy == EdmConstants::STORAGE_USB_POLICY_READ_ONLY)) {
103 EDMLOGE("UsbReadOnlyPlugin policy conflict! Storage is disabled by disallowed policy.");
104 return true;
105 }
106 auto policyManager = IPolicyManager::GetInstance();
107 std::string disableUsb;
108 policyManager->GetPolicy("", "disable_usb", disableUsb);
109 if (disableUsb == "true") {
110 EDMLOGE("UsbReadOnlyPlugin policy conflict! Usb is disabled.");
111 return true;
112 }
113 return false;
114 }
115
GetDisallowedUsbDeviceTypes(std::vector<USB::UsbDeviceType> & usbDeviceTypes)116 void UsbReadOnlyPlugin::GetDisallowedUsbDeviceTypes(std::vector<USB::UsbDeviceType> &usbDeviceTypes)
117 {
118 auto policyManager = IPolicyManager::GetInstance();
119 std::string disallowUsbDevicePolicy;
120 policyManager->GetPolicy("", "disallowed_usb_devices", disallowUsbDevicePolicy);
121 ArrayUsbDeviceTypeSerializer::GetInstance()->Deserialize(disallowUsbDevicePolicy, usbDeviceTypes);
122 EDMLOGI("UsbReadOnlyPlugin GetDisallowedUsbDeviceTypes: size: %{public}zu", usbDeviceTypes.size());
123 }
124
DealDisablePolicy(std::vector<USB::UsbDeviceType> usbDeviceTypes)125 ErrCode UsbReadOnlyPlugin::DealDisablePolicy(std::vector<USB::UsbDeviceType> usbDeviceTypes)
126 {
127 USB::UsbDeviceType storageType;
128 storageType.baseClass = USB_DEVICE_TYPE_BASE_CLASS_STORAGE;
129 storageType.subClass = USB_DEVICE_TYPE_BASE_CLASS_STORAGE;
130 storageType.protocol = USB_DEVICE_TYPE_BASE_CLASS_STORAGE;
131 storageType.isDeviceType = false;
132 std::vector<USB::UsbDeviceType> usbStorageTypes;
133 usbStorageTypes.emplace_back(storageType);
134 std::vector<USB::UsbDeviceType> disallowedUsbDeviceTypes =
135 ArrayUsbDeviceTypeSerializer::GetInstance()->SetUnionPolicyData(usbDeviceTypes, usbStorageTypes);
136 EDMLOGI("UsbReadOnlyPlugin OnHandlePolicy: ManageInterfaceType disallowed size: %{public}zu",
137 disallowedUsbDeviceTypes.size());
138 return UsbPolicyUtils::SetDisallowedUsbDevices(disallowedUsbDeviceTypes);
139 }
140
DealReadPolicy(int32_t accessPolicy,const std::string & allowUsbDevice,std::vector<USB::UsbDeviceType> usbDeviceTypes)141 ErrCode UsbReadOnlyPlugin::DealReadPolicy(int32_t accessPolicy, const std::string &allowUsbDevice,
142 std::vector<USB::UsbDeviceType> usbDeviceTypes)
143 {
144 std::string usbValue = (accessPolicy == EdmConstants::STORAGE_USB_POLICY_READ_ONLY) ? "true" : "false";
145 bool ret = OHOS::system::SetParameter(PARAM_USB_READ_ONLY_KEY, usbValue);
146 if (!ret) {
147 EDMLOGE("UsbReadOnlyPlugin OnHandlePolicy failed! readonly value: %{public}s", usbValue.c_str());
148 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
149 }
150
151 int32_t usbRet = ERR_OK;
152 if (allowUsbDevice.empty()) {
153 usbDeviceTypes.erase(std::remove_if(usbDeviceTypes.begin(), usbDeviceTypes.end(),
154 [&](const auto usbDeviceType) { return usbDeviceType.baseClass == USB_DEVICE_TYPE_BASE_CLASS_STORAGE; }),
155 usbDeviceTypes.end());
156 EDMLOGI("UsbReadOnlyPlugin OnHandlePolicy: ManageInterfaceType disallowed size: %{public}zu",
157 usbDeviceTypes.size());
158 usbRet = USB::UsbSrvClient::GetInstance().ManageInterfaceType(usbDeviceTypes, true);
159 }
160 EDMLOGI("UsbReadOnlyPlugin OnHandlePolicy sysParam: readonly value:%{public}s ret:%{public}d usbRet:%{public}d",
161 usbValue.c_str(), ret, usbRet);
162 if (usbRet == EdmConstants::USB_ERRCODE_INTERFACE_NO_INIT) {
163 EDMLOGW("UsbReadOnlyPlugin OnHandlePolicy: ManageInterfaceType failed! USB interface not init!");
164 }
165 if (usbRet != ERR_OK && usbRet != EdmConstants::USB_ERRCODE_INTERFACE_NO_INIT) {
166 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
167 }
168 ErrCode reloadRet = ReloadUsbDevice();
169 if (reloadRet != ERR_OK) {
170 return reloadRet;
171 }
172 return ERR_OK;
173 }
174
GetStorageManager()175 OHOS::sptr<OHOS::StorageManager::IStorageManager> UsbReadOnlyPlugin::GetStorageManager()
176 {
177 auto saMgr = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
178 if (saMgr == nullptr) {
179 EDMLOGE("UsbReadOnlyPlugin GetStorageManager:get saMgr fail");
180 return nullptr;
181 }
182 sptr<IRemoteObject> obj = saMgr->GetSystemAbility(STORAGE_MANAGER_MANAGER_ID);
183 if (obj == nullptr) {
184 EDMLOGE("UsbReadOnlyPlugin GetStorageManager:get storage manager client fail");
185 return nullptr;
186 }
187 auto storageMgrProxy = iface_cast<OHOS::StorageManager::IStorageManager>(obj);
188 if (storageMgrProxy == nullptr) {
189 EDMLOGE("UsbReadOnlyPlugin GetStorageManager:get storageMgrProxy fail");
190 }
191 return storageMgrProxy;
192 }
193
ReloadUsbDevice()194 ErrCode UsbReadOnlyPlugin::ReloadUsbDevice()
195 {
196 auto storageMgrProxy = GetStorageManager();
197 if (storageMgrProxy == nullptr) {
198 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
199 }
200 std::vector<StorageManager::VolumeExternal> volList;
201 int32_t storageRet = storageMgrProxy->GetAllVolumes(volList);
202 if (storageRet != ERR_OK) {
203 EDMLOGE("UsbReadOnlyPlugin SetPolicy storageMgrProxy GetAllVolumes failed! ret:%{public}d", storageRet);
204 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
205 }
206 if (volList.empty()) {
207 return ERR_OK;
208 }
209 for (auto &vol : volList) {
210 if (storageMgrProxy->Unmount(vol.GetId()) != ERR_OK) {
211 EDMLOGE("UsbReadOnlyPlugin SetPolicy storageMgrProxy Unmount failed!");
212 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
213 }
214 if (storageMgrProxy->Mount(vol.GetId()) != ERR_OK) {
215 EDMLOGE("UsbReadOnlyPlugin SetPolicy storageMgrProxy Mount failed!");
216 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
217 }
218 }
219 return ERR_OK;
220 }
221
OnGetPolicy(std::string & policyData,MessageParcel & data,MessageParcel & reply,int32_t userId)222 ErrCode UsbReadOnlyPlugin::OnGetPolicy(std::string &policyData, MessageParcel &data, MessageParcel &reply,
223 int32_t userId)
224 {
225 return ERR_OK;
226 }
227
IsStorageDisabledByDisallowedPolicy()228 bool UsbReadOnlyPlugin::IsStorageDisabledByDisallowedPolicy()
229 {
230 std::vector<USB::UsbDeviceType> usbDeviceTypes;
231 GetDisallowedUsbDeviceTypes(usbDeviceTypes);
232 return usbDeviceTypes.size() <= EdmConstants::DISALLOWED_USB_DEVICES_TYPES_MAX_SIZE &&
233 (std::find_if(usbDeviceTypes.begin(), usbDeviceTypes.end(), [&](USB::UsbDeviceType disallowedType) {
234 return disallowedType.baseClass == USB_DEVICE_TYPE_BASE_CLASS_STORAGE;
235 }) != usbDeviceTypes.end());
236 }
237
OnAdminRemove(const std::string & adminName,const std::string & policyData,const std::string & mergeData,int32_t userId)238 ErrCode UsbReadOnlyPlugin::OnAdminRemove(const std::string &adminName, const std::string &policyData,
239 const std::string &mergeData, int32_t userId)
240 {
241 EDMLOGI("UsbReadOnlyPlugin OnAdminRemove adminName: %{public}s, userId: %{public}d, value: %{public}s",
242 adminName.c_str(), userId, policyData.c_str());
243 int32_t adminPolicy = 0;
244 int32_t mergePolicy = 0;
245 if (!IntSerializer::GetInstance()->Deserialize(policyData, adminPolicy) ||
246 !IntSerializer::GetInstance()->Deserialize(mergeData, mergePolicy)) {
247 EDMLOGE("UsbReadOnlyPlugin OnHandlePolicy deserialize admin policy and merge policy failed.");
248 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
249 }
250 if (adminPolicy > mergePolicy) {
251 std::vector<USB::UsbDeviceType> usbDeviceTypes;
252 GetDisallowedUsbDeviceTypes(usbDeviceTypes);
253 std::string allowUsbDevicePolicy;
254 IPolicyManager::GetInstance()->GetPolicy("", "allowed_usb_devices", allowUsbDevicePolicy);
255 return DealReadPolicy(mergePolicy, allowUsbDevicePolicy, usbDeviceTypes);
256 }
257 return ERR_OK;
258 }
259
GetOthersMergePolicyData(const std::string & adminName,std::string & othersMergePolicyData)260 ErrCode UsbReadOnlyPlugin::GetOthersMergePolicyData(const std::string &adminName, std::string &othersMergePolicyData)
261 {
262 AdminValueItemsMap adminValues;
263 IPolicyManager::GetInstance()->GetAdminByPolicyName(GetPolicyName(), adminValues);
264 EDMLOGD("UsbReadOnlyPlugin::GetOthersMergePolicyData %{public}s value size %{public}d.", GetPolicyName().c_str(),
265 (uint32_t)adminValues.size());
266 if (adminValues.empty()) {
267 return ERR_OK;
268 }
269 auto entry = adminValues.find(adminName);
270 if (entry != adminValues.end()) {
271 adminValues.erase(entry);
272 }
273 if (adminValues.empty()) {
274 return ERR_OK;
275 }
276 int32_t result = 0;
277 for (const auto &item : adminValues) {
278 int32_t dataItem = 0;
279 if (!item.second.empty()) {
280 if (!IntSerializer::GetInstance()->Deserialize(item.second, dataItem)) {
281 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
282 }
283 if (dataItem > result) {
284 result = dataItem;
285 }
286 }
287 }
288 if (!IntSerializer::GetInstance()->Serialize(result, othersMergePolicyData)) {
289 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
290 }
291 return ERR_OK;
292 }
293 } // namespace EDM
294 } // namespace OHOS
295