• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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