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 "plugin_manager.h"
30 
31 namespace OHOS {
32 namespace EDM {
33 const bool REGISTER_RESULT = PluginManager::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_.permission = "ohos.permission.ENTERPRISE_MANAGE_USB";
43     permissionConfig_.permissionType = IPlugin::PermissionType::SUPER_DEVICE_ADMIN;
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         std::string beforeHandle = policyData.policyData;
55         int32_t accessPolicy = data.ReadInt32();
56         EDMLOGI("UsbReadOnlyPlugin OnHandlePolicy: %{public}d", accessPolicy);
57         std::string afterHandle = std::to_string(accessPolicy);
58         ErrCode ret = SetUsbStorageAccessPolicy(accessPolicy, userId);
59         if (ret != ERR_OK) {
60             return ret;
61         }
62         policyData.isChanged = afterHandle != beforeHandle;
63         if (policyData.isChanged) {
64             policyData.policyData = afterHandle;
65         }
66         return ERR_OK;
67     }
68     return EdmReturnErrCode::SYSTEM_ABNORMALLY;
69 }
70 
SetUsbStorageAccessPolicy(int32_t accessPolicy,int32_t userId)71 ErrCode UsbReadOnlyPlugin::SetUsbStorageAccessPolicy(int32_t accessPolicy, int32_t userId)
72 {
73     auto policyManager = IPolicyManager::GetInstance();
74     std::string allowUsbDevicePolicy;
75     policyManager->GetPolicy("", "allowed_usb_devices", allowUsbDevicePolicy);
76     if (HasConflictPolicy(accessPolicy, allowUsbDevicePolicy)) {
77         return EdmReturnErrCode::CONFIGURATION_CONFLICT_FAILED;
78     }
79     std::vector<USB::UsbDeviceType> usbDeviceTypes;
80     GetDisallowedUsbDeviceTypes(usbDeviceTypes);
81     if (accessPolicy == EdmConstants::STORAGE_USB_POLICY_DISABLED) {
82         return DealDisablePolicy(usbDeviceTypes);
83     }
84     return DealReadPolicy(accessPolicy, allowUsbDevicePolicy, usbDeviceTypes);
85 }
86 
HasConflictPolicy(int32_t accessPolicy,const std::string & allowUsbDevice)87 bool UsbReadOnlyPlugin::HasConflictPolicy(int32_t accessPolicy, const std::string &allowUsbDevice)
88 {
89     if (accessPolicy == EdmConstants::STORAGE_USB_POLICY_DISABLED && !allowUsbDevice.empty()) {
90         EDMLOGE("UsbReadOnlyPlugin policy conflict! AllowedUsbDevice: %{public}s", allowUsbDevice.c_str());
91         return true;
92     }
93     if (IsStorageDisabledByDisallowedPolicy() &&
94         (accessPolicy == EdmConstants::STORAGE_USB_POLICY_READ_WRITE ||
95         accessPolicy == EdmConstants::STORAGE_USB_POLICY_READ_ONLY)) {
96         EDMLOGE("UsbReadOnlyPlugin policy conflict! Storage is disabled by disallowed policy.");
97         return true;
98     }
99     auto policyManager = IPolicyManager::GetInstance();
100     std::string disableUsb;
101     policyManager->GetPolicy("", "disable_usb", disableUsb);
102     if (disableUsb == "true") {
103         EDMLOGE("UsbReadOnlyPlugin policy conflict! Usb is disabled.");
104         return true;
105     }
106     return false;
107 }
108 
GetDisallowedUsbDeviceTypes(std::vector<USB::UsbDeviceType> & usbDeviceTypes)109 void UsbReadOnlyPlugin::GetDisallowedUsbDeviceTypes(std::vector<USB::UsbDeviceType> &usbDeviceTypes)
110 {
111     auto policyManager = IPolicyManager::GetInstance();
112     std::string disallowUsbDevicePolicy;
113     policyManager->GetPolicy("", "disallowed_usb_devices", disallowUsbDevicePolicy);
114     ArrayUsbDeviceTypeSerializer::GetInstance()->Deserialize(disallowUsbDevicePolicy, usbDeviceTypes);
115     EDMLOGI("UsbReadOnlyPlugin GetDisallowedUsbDeviceTypes: size: %{public}zu", usbDeviceTypes.size());
116 }
117 
DealDisablePolicy(std::vector<USB::UsbDeviceType> usbDeviceTypes)118 ErrCode UsbReadOnlyPlugin::DealDisablePolicy(std::vector<USB::UsbDeviceType> usbDeviceTypes)
119 {
120     USB::UsbDeviceType storageType;
121     storageType.baseClass = USB_DEVICE_TYPE_BASE_CLASS_STORAGE;
122     storageType.subClass = USB_DEVICE_TYPE_BASE_CLASS_STORAGE;
123     storageType.protocol = USB_DEVICE_TYPE_BASE_CLASS_STORAGE;
124     storageType.isDeviceType = false;
125     std::vector<USB::UsbDeviceType> usbStorageTypes;
126     usbStorageTypes.emplace_back(storageType);
127     std::vector<USB::UsbDeviceType> disallowedUsbDeviceTypes =
128         ArrayUsbDeviceTypeSerializer::GetInstance()->SetUnionPolicyData(usbDeviceTypes, usbStorageTypes);
129     EDMLOGI("UsbReadOnlyPlugin OnHandlePolicy: ManageInterfaceType disallowed size: %{public}zu",
130         disallowedUsbDeviceTypes.size());
131     return UsbPolicyUtils::SetDisallowedUsbDevices(disallowedUsbDeviceTypes);
132 }
133 
DealReadPolicy(int32_t accessPolicy,const std::string & allowUsbDevice,std::vector<USB::UsbDeviceType> usbDeviceTypes)134 ErrCode UsbReadOnlyPlugin::DealReadPolicy(int32_t accessPolicy, const std::string &allowUsbDevice,
135     std::vector<USB::UsbDeviceType> usbDeviceTypes)
136 {
137     std::string usbValue = (accessPolicy == EdmConstants::STORAGE_USB_POLICY_READ_ONLY) ? "true" : "false";
138     bool ret = OHOS::system::SetParameter(PARAM_USB_READ_ONLY_KEY, usbValue);
139     if (!ret) {
140         EDMLOGE("UsbReadOnlyPlugin OnHandlePolicy failed! readonly value: %{public}s", usbValue.c_str());
141         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
142     }
143 
144     int32_t usbRet = ERR_OK;
145     if (allowUsbDevice.empty()) {
146         usbDeviceTypes.erase(std::remove_if(usbDeviceTypes.begin(), usbDeviceTypes.end(),
147             [&](const auto usbDeviceType) { return usbDeviceType.baseClass == USB_DEVICE_TYPE_BASE_CLASS_STORAGE; }),
148             usbDeviceTypes.end());
149         EDMLOGI("UsbReadOnlyPlugin OnHandlePolicy: ManageInterfaceType disallowed size: %{public}zu",
150             usbDeviceTypes.size());
151         usbRet = USB::UsbSrvClient::GetInstance().ManageInterfaceType(usbDeviceTypes, true);
152     }
153     EDMLOGI("UsbReadOnlyPlugin OnHandlePolicy sysParam: readonly value:%{public}s  ret:%{public}d usbRet:%{public}d",
154         usbValue.c_str(), ret, usbRet);
155     if (usbRet == EdmConstants::USB_ERRCODE_INTERFACE_NO_INIT) {
156         EDMLOGW("UsbReadOnlyPlugin OnHandlePolicy: ManageInterfaceType failed! USB interface not init!");
157     }
158     if (usbRet != ERR_OK && usbRet != EdmConstants::USB_ERRCODE_INTERFACE_NO_INIT) {
159         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
160     }
161     ErrCode reloadRet = ReloadUsbDevice();
162     if (reloadRet != ERR_OK) {
163         return reloadRet;
164     }
165     return ERR_OK;
166 }
167 
GetStorageManager()168 OHOS::sptr<OHOS::StorageManager::IStorageManager> UsbReadOnlyPlugin::GetStorageManager()
169 {
170     auto saMgr = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
171     if (saMgr == nullptr) {
172         EDMLOGE("UsbReadOnlyPlugin GetStorageManager:get saMgr fail");
173         return nullptr;
174     }
175     sptr<IRemoteObject> obj = saMgr->GetSystemAbility(STORAGE_MANAGER_MANAGER_ID);
176     if (obj == nullptr) {
177         EDMLOGE("UsbReadOnlyPlugin GetStorageManager:get storage manager client fail");
178         return nullptr;
179     }
180     auto storageMgrProxy = iface_cast<OHOS::StorageManager::IStorageManager>(obj);
181     if (storageMgrProxy == nullptr) {
182         EDMLOGE("UsbReadOnlyPlugin GetStorageManager:get storageMgrProxy fail");
183     }
184     return storageMgrProxy;
185 }
186 
ReloadUsbDevice()187 ErrCode UsbReadOnlyPlugin::ReloadUsbDevice()
188 {
189     auto storageMgrProxy = GetStorageManager();
190     if (storageMgrProxy == nullptr) {
191         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
192     }
193     std::vector<StorageManager::VolumeExternal> volList;
194     int32_t storageRet = storageMgrProxy->GetAllVolumes(volList);
195     if (storageRet != ERR_OK) {
196         EDMLOGE("UsbReadOnlyPlugin SetPolicy storageMgrProxy GetAllVolumes failed! ret:%{public}d", storageRet);
197         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
198     }
199     if (volList.empty()) {
200         return ERR_OK;
201     }
202     for (auto &vol : volList) {
203         if (storageMgrProxy->Unmount(vol.GetId()) != ERR_OK) {
204             EDMLOGE("UsbReadOnlyPlugin SetPolicy storageMgrProxy Unmount failed!");
205             return EdmReturnErrCode::SYSTEM_ABNORMALLY;
206         }
207         if (storageMgrProxy->Mount(vol.GetId()) != ERR_OK) {
208             EDMLOGE("UsbReadOnlyPlugin SetPolicy storageMgrProxy Mount failed!");
209             return EdmReturnErrCode::SYSTEM_ABNORMALLY;
210         }
211     }
212     return ERR_OK;
213 }
214 
OnGetPolicy(std::string & policyData,MessageParcel & data,MessageParcel & reply,int32_t userId)215 ErrCode UsbReadOnlyPlugin::OnGetPolicy(std::string &policyData, MessageParcel &data, MessageParcel &reply,
216     int32_t userId)
217 {
218     EDMLOGI("UsbReadOnlyPlugin OnGetPolicy: %{public}s", policyData.c_str());
219     policyData = policyData.empty() ? "0" : policyData;
220     int32_t result = EdmConstants::STORAGE_USB_POLICY_READ_ONLY;
221     ErrCode parseRet = EdmUtils::ParseStringToInt(policyData, result);
222     if (FAILED(parseRet)) {
223         reply.WriteInt32(EdmReturnErrCode::SYSTEM_ABNORMALLY);
224         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
225     }
226     reply.WriteInt32(ERR_OK);
227     reply.WriteInt32(result);
228     return ERR_OK;
229 }
230 
IsStorageDisabledByDisallowedPolicy()231 bool UsbReadOnlyPlugin::IsStorageDisabledByDisallowedPolicy()
232 {
233     std::vector<USB::UsbDeviceType> usbDeviceTypes;
234     GetDisallowedUsbDeviceTypes(usbDeviceTypes);
235     return usbDeviceTypes.size() <= EdmConstants::DISALLOWED_USB_DEVICES_TYPES_MAX_SIZE &&
236         (std::find_if(usbDeviceTypes.begin(), usbDeviceTypes.end(), [&](USB::UsbDeviceType disallowedType) {
237             return disallowedType.baseClass == USB_DEVICE_TYPE_BASE_CLASS_STORAGE;
238         }) != usbDeviceTypes.end());
239 }
240 
OnAdminRemove(const std::string & adminName,const std::string & policyData,int32_t userId)241 ErrCode UsbReadOnlyPlugin::OnAdminRemove(const std::string &adminName, const std::string &policyData, int32_t userId)
242 {
243     EDMLOGI("UsbReadOnlyPlugin OnAdminRemove adminName: %{public}s, userId: %{public}d, value: %{public}s",
244         adminName.c_str(), userId, policyData.c_str());
245     int32_t data = strtol(policyData.c_str(), nullptr, EdmConstants::DECIMAL);
246     if (data == EdmConstants::STORAGE_USB_POLICY_DISABLED) {
247         ErrCode disableUsbRet = UsbPolicyUtils::SetUsbDisabled(false);
248         if (disableUsbRet != ERR_OK) {
249             EDMLOGW("UsbReadOnlyPlugin OnAdminRemove SetUsbDisabled Error: %{public}d", disableUsbRet);
250             return disableUsbRet;
251         }
252     }
253     std::string usbValue = "false";
254     bool ret = OHOS::system::SetParameter(PARAM_USB_READ_ONLY_KEY, usbValue);
255     return ret ? ERR_OK : EdmReturnErrCode::SYSTEM_ABNORMALLY;
256 }
257 } // namespace EDM
258 } // namespace OHOS
259