1 /*
2 * Copyright (c) 2023-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 "allowed_usb_devices_plugin.h"
17
18 #include <algorithm>
19 #include <system_ability_definition.h>
20 #include "array_usb_device_id_serializer.h"
21 #include "edm_constants.h"
22 #include "edm_ipc_interface_code.h"
23 #include "edm_sys_manager.h"
24 #include "edm_utils.h"
25 #include "usb_device.h"
26 #include "usb_device_id.h"
27 #include "usb_policy_utils.h"
28 #include "usb_srv_client.h"
29 #include "iplugin_manager.h"
30 #include "ipolicy_manager.h"
31
32 namespace OHOS {
33 namespace EDM {
34 const bool REGISTER_RESULT = IPluginManager::GetInstance()->AddPlugin(AllowUsbDevicesPlugin::GetPlugin());
35
InitPlugin(std::shared_ptr<IPluginTemplate<AllowUsbDevicesPlugin,std::vector<UsbDeviceId>>> ptr)36 void AllowUsbDevicesPlugin::InitPlugin(
37 std::shared_ptr<IPluginTemplate<AllowUsbDevicesPlugin, std::vector<UsbDeviceId>>> ptr)
38 {
39 EDMLOGI("AllowUsbDevicesPlugin InitPlugin...");
40 ptr->InitAttribute(EdmInterfaceCode::ALLOWED_USB_DEVICES, PolicyName::POLICY_ALLOWED_USB_DEVICES,
41 EdmPermission::PERMISSION_ENTERPRISE_MANAGE_USB, IPlugin::PermissionType::SUPER_DEVICE_ADMIN, true);
42 ptr->SetSerializer(ArrayUsbDeviceIdSerializer::GetInstance());
43 ptr->SetOnHandlePolicyListener(&AllowUsbDevicesPlugin::OnSetPolicy, FuncOperateType::SET);
44 ptr->SetOnHandlePolicyListener(&AllowUsbDevicesPlugin::OnRemovePolicy, FuncOperateType::REMOVE);
45 ptr->SetOnAdminRemoveListener(&AllowUsbDevicesPlugin::OnAdminRemove);
46 ptr->SetOtherServiceStartListener(&AllowUsbDevicesPlugin::OnOtherServiceStart);
47 }
48
OnSetPolicy(std::vector<UsbDeviceId> & data,std::vector<UsbDeviceId> & currentData,std::vector<UsbDeviceId> & mergeData,int32_t userId)49 ErrCode AllowUsbDevicesPlugin::OnSetPolicy(std::vector<UsbDeviceId> &data,
50 std::vector<UsbDeviceId> ¤tData, std::vector<UsbDeviceId> &mergeData, int32_t userId)
51 {
52 EDMLOGI("AllowUsbDevicesPlugin OnSetPolicy");
53 if (data.empty()) {
54 EDMLOGW("AllowUsbDevicesPlugin OnSetPolicy data is empty");
55 return ERR_OK;
56 }
57 if (data.size() > EdmConstants::ALLOWED_USB_DEVICES_MAX_SIZE) {
58 EDMLOGE("AllowUsbDevicesPlugin OnSetPolicy data size=[%{public}zu] is too large", data.size());
59 return EdmReturnErrCode::PARAM_ERROR;
60 }
61 if (HasConflictPolicy()) {
62 return EdmReturnErrCode::CONFIGURATION_CONFLICT_FAILED;
63 }
64
65 std::vector<UsbDeviceId> needAddData =
66 ArrayUsbDeviceIdSerializer::GetInstance()->SetDifferencePolicyData(currentData, data);
67 std::vector<UsbDeviceId> needAddMergeData =
68 ArrayUsbDeviceIdSerializer::GetInstance()->SetDifferencePolicyData(mergeData, needAddData);
69 std::vector<UsbDeviceId> afterHandle =
70 ArrayUsbDeviceIdSerializer::GetInstance()->SetUnionPolicyData(currentData, needAddData);
71 std::vector<UsbDeviceId> afterMerge =
72 ArrayUsbDeviceIdSerializer::GetInstance()->SetUnionPolicyData(mergeData, afterHandle);
73
74 if (afterMerge.size() > EdmConstants::ALLOWED_USB_DEVICES_MAX_SIZE) {
75 EDMLOGE("AllowUsbDevicesPlugin OnSetPolicy union data size=[%{public}zu] is too large", mergeData.size());
76 return EdmReturnErrCode::PARAM_ERROR;
77 }
78 ErrCode errCode = UsbPolicyUtils::AddAllowedUsbDevices(needAddMergeData);
79 if (errCode != ERR_OK) {
80 return errCode;
81 }
82 currentData = afterHandle;
83 mergeData = afterMerge;
84 return ERR_OK;
85 }
86
HasConflictPolicy()87 bool AllowUsbDevicesPlugin::HasConflictPolicy()
88 {
89 auto policyManager = IPolicyManager::GetInstance();
90 std::string disableUsbPolicy;
91 policyManager->GetPolicy("", PolicyName::POLICY_DISABLE_USB, disableUsbPolicy);
92 if (disableUsbPolicy == "true") {
93 EDMLOGE("AllowUsbDevicesPlugin POLICY CONFLICT! Usb is disabled.");
94 return true;
95 }
96
97 std::string usbStoragePolicy;
98 policyManager->GetPolicy("", PolicyName::POLICY_USB_READ_ONLY, usbStoragePolicy);
99 if (usbStoragePolicy == std::to_string(EdmConstants::STORAGE_USB_POLICY_DISABLED)) {
100 EDMLOGE("AllowUsbDevicesPlugin POLICY CONFLICT! usbStoragePolicy is disabled.");
101 return true;
102 }
103
104 std::string disallowUsbDevicePolicy;
105 policyManager->GetPolicy("", PolicyName::POLICY_DISALLOWED_USB_DEVICES, disallowUsbDevicePolicy);
106 if (!disallowUsbDevicePolicy.empty()) {
107 EDMLOGE("AllowUsbDevicesPlugin POLICY CONFLICT! disallowedUsbDevice: %{public}s",
108 disallowUsbDevicePolicy.c_str());
109 return true;
110 }
111 return false;
112 }
113
OnRemovePolicy(std::vector<UsbDeviceId> & data,std::vector<UsbDeviceId> & currentData,std::vector<UsbDeviceId> & mergeData,int32_t userId)114 ErrCode AllowUsbDevicesPlugin::OnRemovePolicy(std::vector<UsbDeviceId> &data, std::vector<UsbDeviceId> ¤tData,
115 std::vector<UsbDeviceId> &mergeData, int32_t userId)
116 {
117 EDMLOGD("AllowUsbDevicesPlugin OnRemovePolicy");
118 if (data.empty()) {
119 EDMLOGW("AllowUsbDevicesPlugin OnRemovePolicy data is empty:");
120 return ERR_OK;
121 }
122 if (data.size() > EdmConstants::ALLOWED_USB_DEVICES_MAX_SIZE) {
123 EDMLOGE("AllowUsbDevicesPlugin OnRemovePolicy input data is too large");
124 return EdmReturnErrCode::PARAM_ERROR;
125 }
126
127 std::vector<UsbDeviceId> afterHandle =
128 ArrayUsbDeviceIdSerializer::GetInstance()->SetDifferencePolicyData(data, currentData);
129 std::vector<UsbDeviceId> afterMerge =
130 ArrayUsbDeviceIdSerializer::GetInstance()->SetUnionPolicyData(mergeData, afterHandle);
131
132 if (afterMerge.empty()) {
133 auto &srvClient = OHOS::USB::UsbSrvClient::GetInstance();
134 std::vector<OHOS::USB::UsbDevice> allDevices;
135 int32_t getRet = srvClient.GetDevices(allDevices);
136 if (getRet == EdmConstants::USB_ERRCODE_INTERFACE_NO_INIT) {
137 EDMLOGW("AllowUsbDevicesPlugin OnRemovePolicy: getDevices failed! USB interface not init!");
138 }
139 if (getRet != ERR_OK && getRet != EdmConstants::USB_ERRCODE_INTERFACE_NO_INIT) {
140 EDMLOGE("AllowUsbDevicesPlugin OnRemovePolicy getDevices failed: %{public}d", getRet);
141 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
142 }
143 EDMLOGI("AllowUsbDevicesPlugin OnRemovePolicy: clear to empty, enable all.");
144 std::for_each(allDevices.begin(), allDevices.end(), [&](const auto usbDevice) {
145 if (srvClient.ManageDevice(usbDevice.GetVendorId(), usbDevice.GetProductId(), false) != ERR_OK) {
146 EDMLOGW("AllowUsbDevicesPlugin OnRemovePolicy ManageDevice vid: %{public}d, pid: %{public}d failed!",
147 usbDevice.GetVendorId(), usbDevice.GetProductId());
148 }
149 });
150 } else {
151 std::vector<UsbDeviceId> needRemovePolicy =
152 ArrayUsbDeviceIdSerializer::GetInstance()->SetDifferencePolicyData(afterHandle, currentData);
153 std::vector<UsbDeviceId> needRemoveMergePolicy =
154 ArrayUsbDeviceIdSerializer::GetInstance()->SetDifferencePolicyData(mergeData, needRemovePolicy);
155 EDMLOGI("AllowUsbDevicesPlugin OnRemovePolicy: remove data size: %{public}zu", needRemoveMergePolicy.size());
156 auto &srvClient = OHOS::USB::UsbSrvClient::GetInstance();
157 std::for_each(needRemoveMergePolicy.begin(), needRemoveMergePolicy.end(), [&](const auto usbDeviceId) {
158 if (srvClient.ManageDevice(usbDeviceId.GetVendorId(), usbDeviceId.GetProductId(), true) != ERR_OK) {
159 EDMLOGW("AllowUsbDevicesPlugin OnRemovePolicy ManageDevice vid: %{public}d, pid: %{public}d failed!",
160 usbDeviceId.GetVendorId(), usbDeviceId.GetProductId());
161 }
162 });
163 }
164 currentData = afterHandle;
165 mergeData = afterMerge;
166 return ERR_OK;
167 }
168
OnAdminRemove(const std::string & adminName,std::vector<UsbDeviceId> & data,std::vector<UsbDeviceId> & mergeData,int32_t userId)169 ErrCode AllowUsbDevicesPlugin::OnAdminRemove(const std::string &adminName, std::vector<UsbDeviceId> &data,
170 std::vector<UsbDeviceId> &mergeData, int32_t userId)
171 {
172 EDMLOGD("AllowUsbDevicesPlugin OnAdminRemove");
173 if (data.empty()) {
174 EDMLOGW("AllowUsbDevicesPlugin OnRemovePolicy data is empty:");
175 return ERR_OK;
176 }
177 if (mergeData.empty()) {
178 return UsbPolicyUtils::SetUsbDisabled(false);
179 }
180 std::vector<UsbDeviceId> needRemoveMergePolicy =
181 ArrayUsbDeviceIdSerializer::GetInstance()->SetDifferencePolicyData(mergeData, data);
182 auto &srvClient = OHOS::USB::UsbSrvClient::GetInstance();
183 std::for_each(needRemoveMergePolicy.begin(), needRemoveMergePolicy.end(), [&](const auto usbDeviceId) {
184 if (srvClient.ManageDevice(usbDeviceId.GetVendorId(), usbDeviceId.GetProductId(), true) != ERR_OK) {
185 EDMLOGW("AllowUsbDevicesPlugin OnRemovePolicy ManageDevice vid: %{public}d, pid: %{public}d failed!",
186 usbDeviceId.GetVendorId(), usbDeviceId.GetProductId());
187 }
188 });
189 return ERR_OK;
190 }
191
OnOtherServiceStart(int32_t systemAbilityId)192 void AllowUsbDevicesPlugin::OnOtherServiceStart(int32_t systemAbilityId)
193 {
194 EDMLOGI("DisableUsbPlugin::OnOtherServiceStart start");
195 std::string allowUsbDevicePolicy;
196 IPolicyManager::GetInstance()->GetPolicy("", PolicyName::POLICY_ALLOWED_USB_DEVICES, allowUsbDevicePolicy,
197 EdmConstants::DEFAULT_USER_ID);
198 std::vector<UsbDeviceId> usbDeviceIds;
199 ArrayUsbDeviceIdSerializer::GetInstance()->Deserialize(allowUsbDevicePolicy, usbDeviceIds);
200 if (!usbDeviceIds.empty()) {
201 ErrCode allowedUsbRet = UsbPolicyUtils::AddAllowedUsbDevices(usbDeviceIds);
202 if (allowedUsbRet != ERR_OK) {
203 EDMLOGW("AddAllowedUsbDevices Error: %{public}d", allowedUsbRet);
204 }
205 }
206 }
207 } // namespace EDM
208 } // namespace OHOS
209