1 /*
2 * Copyright (c) 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 "disallowed_usb_devices_plugin.h"
17
18 #include <algorithm>
19 #include <system_ability_definition.h>
20 #include "array_usb_device_type_serializer.h"
21 #include "edm_constants.h"
22 #include "edm_ipc_interface_code.h"
23 #include "iplugin_manager.h"
24 #include "usb_policy_utils.h"
25
26 namespace OHOS {
27 namespace EDM {
28 const bool REGISTER_RESULT = IPluginManager::GetInstance()->AddPlugin(DisallowedUsbDevicesPlugin::GetPlugin());
29 constexpr int32_t USB_DEVICE_TYPE_BASE_CLASS_STORAGE = 8;
30
InitPlugin(std::shared_ptr<IPluginTemplate<DisallowedUsbDevicesPlugin,std::vector<USB::UsbDeviceType>>> ptr)31 void DisallowedUsbDevicesPlugin::InitPlugin(
32 std::shared_ptr<IPluginTemplate<DisallowedUsbDevicesPlugin, std::vector<USB::UsbDeviceType>>> ptr)
33 {
34 EDMLOGI("DisallowedUsbDevicesPlugin InitPlugin...");
35 ptr->InitAttribute(EdmInterfaceCode::DISALLOWED_USB_DEVICES, PolicyName::POLICY_DISALLOWED_USB_DEVICES,
36 EdmPermission::PERMISSION_ENTERPRISE_MANAGE_USB, IPlugin::PermissionType::SUPER_DEVICE_ADMIN, true);
37 ptr->SetSerializer(ArrayUsbDeviceTypeSerializer::GetInstance());
38 ptr->SetOnHandlePolicyListener(&DisallowedUsbDevicesPlugin::OnSetPolicy, FuncOperateType::SET);
39 ptr->SetOnHandlePolicyListener(&DisallowedUsbDevicesPlugin::OnRemovePolicy, FuncOperateType::REMOVE);
40 ptr->SetOnAdminRemoveListener(&DisallowedUsbDevicesPlugin::OnAdminRemove);
41 ptr->SetOtherServiceStartListener(&DisallowedUsbDevicesPlugin::OnOtherServiceStart);
42 }
43
OnSetPolicy(std::vector<USB::UsbDeviceType> & data,std::vector<USB::UsbDeviceType> & currentData,std::vector<USB::UsbDeviceType> & mergeData,int32_t userId)44 ErrCode DisallowedUsbDevicesPlugin::OnSetPolicy(std::vector<USB::UsbDeviceType> &data,
45 std::vector<USB::UsbDeviceType> ¤tData, std::vector<USB::UsbDeviceType> &mergeData, int32_t userId)
46 {
47 EDMLOGI("AllowUsbDevicesPlugin OnSetPolicy");
48 if (data.empty()) {
49 EDMLOGW("AllowUsbDevicesPlugin OnSetPolicy data is empty");
50 return ERR_OK;
51 }
52 if (data.size() > EdmConstants::DISALLOWED_USB_DEVICES_TYPES_MAX_SIZE) {
53 EDMLOGE("AllowUsbDevicesPlugin OnSetPolicy data size=[%{public}zu] is too large", data.size());
54 return EdmReturnErrCode::PARAM_ERROR;
55 }
56 bool hasConflict = false;
57 #ifdef FEATURE_PC_ONLY
58 if (FAILED(HasConflictPolicy(hasConflict, data))) {
59 #else
60 std::vector<USB::UsbDeviceType> emptyData;
61 if (FAILED(HasConflictPolicy(hasConflict, emptyData))) {
62 #endif
63 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
64 }
65 if (hasConflict) {
66 return EdmReturnErrCode::CONFIGURATION_CONFLICT_FAILED;
67 }
68
69 std::vector<USB::UsbDeviceType> afterHandle =
70 ArrayUsbDeviceTypeSerializer::GetInstance()->SetUnionPolicyData(currentData, data);
71 std::vector<USB::UsbDeviceType> afterMerge =
72 ArrayUsbDeviceTypeSerializer::GetInstance()->SetUnionPolicyData(mergeData, afterHandle);
73
74 if (afterMerge.size() > EdmConstants::DISALLOWED_USB_DEVICES_TYPES_MAX_SIZE) {
75 EDMLOGE("AllowUsbDevicesPlugin OnSetPolicy union data size=[%{public}zu] is too large", mergeData.size());
76 return EdmReturnErrCode::PARAM_ERROR;
77 }
78
79 std::vector<USB::UsbDeviceType> disallowedUsbDeviceTypes;
80 CombineDataWithStorageAccessPolicy(afterMerge, disallowedUsbDeviceTypes);
81 ErrCode ret = UsbPolicyUtils::SetDisallowedUsbDevices(disallowedUsbDeviceTypes);
82 if (ret != ERR_OK) {
83 return ret;
84 }
85 currentData = afterHandle;
86 mergeData = afterMerge;
87 return ERR_OK;
88 }
89
90 ErrCode DisallowedUsbDevicesPlugin::OnRemovePolicy(std::vector<USB::UsbDeviceType> &data,
91 std::vector<USB::UsbDeviceType> ¤tData, std::vector<USB::UsbDeviceType> &mergeData, int32_t userId)
92 {
93 EDMLOGD("DisallowedUsbDevicesPlugin OnRemovePolicy");
94 if (data.empty()) {
95 EDMLOGW("DisallowedUsbDevicesPlugin OnRemovePolicy data is empty:");
96 return ERR_OK;
97 }
98 if (data.size() > EdmConstants::DISALLOWED_USB_DEVICES_TYPES_MAX_SIZE) {
99 EDMLOGE("DisallowedUsbDevicesPlugin OnRemovePolicy input data is too large");
100 return EdmReturnErrCode::PARAM_ERROR;
101 }
102
103 std::vector<USB::UsbDeviceType> afterHandle =
104 ArrayUsbDeviceTypeSerializer::GetInstance()->SetDifferencePolicyData(data, currentData);
105 std::vector<USB::UsbDeviceType> afterMerge =
106 ArrayUsbDeviceTypeSerializer::GetInstance()->SetUnionPolicyData(mergeData, afterHandle);
107 std::vector<USB::UsbDeviceType> disallowedUsbDeviceTypes;
108 CombineDataWithStorageAccessPolicy(afterMerge, disallowedUsbDeviceTypes);
109 ErrCode ret = ERR_OK;
110 if (disallowedUsbDeviceTypes.empty() && !currentData.empty()) {
111 ret = UsbPolicyUtils::SetUsbDisabled(false);
112 if (ret != ERR_OK) {
113 return ret;
114 }
115 }
116 ret = UsbPolicyUtils::SetDisallowedUsbDevices(disallowedUsbDeviceTypes);
117 if (ret != ERR_OK) {
118 return ret;
119 }
120 currentData = afterHandle;
121 mergeData = afterMerge;
122 return ERR_OK;
123 }
124
125 ErrCode DisallowedUsbDevicesPlugin::HasConflictPolicy(bool &hasConflict,
126 std::vector<USB::UsbDeviceType> &usbDeviceTypes)
127 {
128 auto policyManager = IPolicyManager::GetInstance();
129 std::string disableUsb;
130 policyManager->GetPolicy("", PolicyName::POLICY_DISABLE_USB, disableUsb);
131 if (disableUsb == "true") {
132 EDMLOGE("DisallowedUsbDevicesPlugin policy conflict! Usb is disabled.");
133 hasConflict = true;
134 return ERR_OK;
135 }
136 std::string allowUsbDevice;
137 policyManager->GetPolicy("", PolicyName::POLICY_ALLOWED_USB_DEVICES, allowUsbDevice);
138 if (!allowUsbDevice.empty()) {
139 EDMLOGE("DisallowedUsbDevicesPlugin policy conflict! AllowedUsbDevice: %{public}s", allowUsbDevice.c_str());
140 hasConflict = true;
141 return ERR_OK;
142 }
143 #ifdef FEATURE_PC_ONLY
144 bool isDisallowed = false;
145 if (FAILED(UsbPolicyUtils::IsUsbStorageDeviceWriteDisallowed(isDisallowed))) {
146 EDMLOGE("DisallowedUsbDevicesPlugin HasConflictPolicy, IsUsbStorageDeviceWriteDisallowed failed");
147 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
148 }
149 bool IsUsbStorageDeviceDisallowed =
150 std::find_if(usbDeviceTypes.begin(), usbDeviceTypes.end(), [&](USB::UsbDeviceType disallowedType) {
151 return disallowedType.baseClass == USB_DEVICE_TYPE_BASE_CLASS_STORAGE;
152 }) != usbDeviceTypes.end();
153 if (isDisallowed && IsUsbStorageDeviceDisallowed) {
154 EDMLOGE("DisallowedUsbDevicesPlugin policy conflict! usbStorageDeviceWrite and usbStorageDevice disallowed");
155 hasConflict = true;
156 return ERR_OK;
157 }
158 #endif
159 return ERR_OK;
160 }
161
162 void DisallowedUsbDevicesPlugin::CombineDataWithStorageAccessPolicy(std::vector<USB::UsbDeviceType> policyData,
163 std::vector<USB::UsbDeviceType> &combineData)
164 {
165 auto policyManager = IPolicyManager::GetInstance();
166 std::string usbStoragePolicy;
167 policyManager->GetPolicy("", PolicyName::POLICY_USB_READ_ONLY, usbStoragePolicy);
168 std::vector<USB::UsbDeviceType> usbStorageTypes;
169 if (usbStoragePolicy == std::to_string(EdmConstants::STORAGE_USB_POLICY_DISABLED)) {
170 USB::UsbDeviceType storageType;
171 storageType.baseClass = USB_DEVICE_TYPE_BASE_CLASS_STORAGE;
172 storageType.subClass = USB_DEVICE_TYPE_BASE_CLASS_STORAGE;
173 storageType.protocol = USB_DEVICE_TYPE_BASE_CLASS_STORAGE;
174 storageType.isDeviceType = false;
175 usbStorageTypes.emplace_back(storageType);
176 }
177 combineData = ArrayUsbDeviceTypeSerializer::GetInstance()->SetUnionPolicyData(policyData, usbStorageTypes);
178 }
179
180 ErrCode DisallowedUsbDevicesPlugin::OnGetPolicy(std::string &policyData, MessageParcel &data, MessageParcel &reply,
181 int32_t userId)
182 {
183 EDMLOGI("DisallowedUsbDevicesPlugin OnGetPolicy: policyData: %{public}s", policyData.c_str());
184 if (policyData.empty()) {
185 EDMLOGW("DisallowedUsbDevicesPlugin OnGetPolicy data is empty:");
186 reply.WriteInt32(ERR_OK);
187 reply.WriteUint32(0);
188 return ERR_OK;
189 }
190 std::vector<USB::UsbDeviceType> disallowedDevices;
191 ArrayUsbDeviceTypeSerializer::GetInstance()->Deserialize(policyData, disallowedDevices);
192 reply.WriteInt32(ERR_OK);
193 reply.WriteUint32(disallowedDevices.size());
194 for (const auto &usbDeviceType : disallowedDevices) {
195 if (!usbDeviceType.Marshalling(reply)) {
196 EDMLOGE("DisallowedUsbDevicesPlugin OnGetPolicy: write parcel failed!");
197 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
198 }
199 }
200 return ERR_OK;
201 }
202
203 ErrCode DisallowedUsbDevicesPlugin::OnAdminRemove(const std::string &adminName, std::vector<USB::UsbDeviceType> &data,
204 std::vector<USB::UsbDeviceType> &mergeData, int32_t userId)
205 {
206 EDMLOGD("DisallowedUsbDevicesPlugin OnAdminRemove");
207 std::vector<USB::UsbDeviceType> disallowedUsbDeviceTypes;
208 CombineDataWithStorageAccessPolicy(mergeData, disallowedUsbDeviceTypes);
209 if (disallowedUsbDeviceTypes.empty()) {
210 return UsbPolicyUtils::SetUsbDisabled(false);
211 }
212 return UsbPolicyUtils::SetDisallowedUsbDevices(disallowedUsbDeviceTypes);
213 }
214
215 void DisallowedUsbDevicesPlugin::OnOtherServiceStart(int32_t systemAbilityId)
216 {
217 std::string disallowUsbDevicePolicy;
218 IPolicyManager::GetInstance()->GetPolicy("", PolicyName::POLICY_DISALLOWED_USB_DEVICES, disallowUsbDevicePolicy,
219 EdmConstants::DEFAULT_USER_ID);
220 std::vector<USB::UsbDeviceType> disallowedDevices;
221 ArrayUsbDeviceTypeSerializer::GetInstance()->Deserialize(disallowUsbDevicePolicy, disallowedDevices);
222 #ifdef USB_STORAGE_SERVICE_EDM_ENABLE
223 std::string usbStoragePolicy;
224 IPolicyManager::GetInstance()->GetPolicy("", PolicyName::POLICY_USB_READ_ONLY,
225 usbStoragePolicy, EdmConstants::DEFAULT_USER_ID);
226 if (usbStoragePolicy == std::to_string(EdmConstants::STORAGE_USB_POLICY_DISABLED)) {
227 USB::UsbDeviceType storageType;
228 storageType.baseClass = USB_DEVICE_TYPE_BASE_CLASS_STORAGE;
229 storageType.subClass = USB_DEVICE_TYPE_BASE_CLASS_STORAGE;
230 storageType.protocol = USB_DEVICE_TYPE_BASE_CLASS_STORAGE;
231 storageType.isDeviceType = false;
232 disallowedDevices.emplace_back(storageType);
233 }
234 #endif
235 if (!disallowedDevices.empty()) {
236 ErrCode disallowedUsbRet = UsbPolicyUtils::SetDisallowedUsbDevices(disallowedDevices);
237 if (disallowedUsbRet != ERR_OK) {
238 EDMLOGW("SetDisallowedUsbDevices Error: %{public}d", disallowedUsbRet);
239 }
240 }
241 }
242 } // namespace EDM
243 } // namespace OHOS
244