mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 19:27:45 +00:00
Catch dhcp setup permission errors sooner (#47639)
This solves an unexpected thread exception on macs when running as a user intead of root
This commit is contained in:
parent
10eca5b986
commit
1dd35ff059
@ -207,8 +207,11 @@ class DHCPWatcher(WatcherBase):
|
|||||||
|
|
||||||
async def async_start(self):
|
async def async_start(self):
|
||||||
"""Start watching for dhcp packets."""
|
"""Start watching for dhcp packets."""
|
||||||
|
# disable scapy promiscuous mode as we do not need it
|
||||||
|
conf.sniff_promisc = 0
|
||||||
|
|
||||||
try:
|
try:
|
||||||
_verify_l2socket_creation_permission()
|
await self.hass.async_add_executor_job(_verify_l2socket_setup, FILTER)
|
||||||
except (Scapy_Exception, OSError) as ex:
|
except (Scapy_Exception, OSError) as ex:
|
||||||
if os.geteuid() == 0:
|
if os.geteuid() == 0:
|
||||||
_LOGGER.error("Cannot watch for dhcp packets: %s", ex)
|
_LOGGER.error("Cannot watch for dhcp packets: %s", ex)
|
||||||
@ -219,7 +222,7 @@ class DHCPWatcher(WatcherBase):
|
|||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
await _async_verify_working_pcap(self.hass, FILTER)
|
await self.hass.async_add_executor_job(_verify_working_pcap, FILTER)
|
||||||
except (Scapy_Exception, ImportError) as ex:
|
except (Scapy_Exception, ImportError) as ex:
|
||||||
_LOGGER.error(
|
_LOGGER.error(
|
||||||
"Cannot watch for dhcp packets without a functional packet filter: %s",
|
"Cannot watch for dhcp packets without a functional packet filter: %s",
|
||||||
@ -233,6 +236,7 @@ class DHCPWatcher(WatcherBase):
|
|||||||
prn=self.handle_dhcp_packet,
|
prn=self.handle_dhcp_packet,
|
||||||
store=0,
|
store=0,
|
||||||
)
|
)
|
||||||
|
|
||||||
self._sniffer.start()
|
self._sniffer.start()
|
||||||
|
|
||||||
def handle_dhcp_packet(self, packet):
|
def handle_dhcp_packet(self, packet):
|
||||||
@ -283,7 +287,7 @@ def _format_mac(mac_address):
|
|||||||
return format_mac(mac_address).replace(":", "")
|
return format_mac(mac_address).replace(":", "")
|
||||||
|
|
||||||
|
|
||||||
def _verify_l2socket_creation_permission():
|
def _verify_l2socket_setup(cap_filter):
|
||||||
"""Create a socket using the scapy configured l2socket.
|
"""Create a socket using the scapy configured l2socket.
|
||||||
|
|
||||||
Try to create the socket
|
Try to create the socket
|
||||||
@ -292,15 +296,13 @@ def _verify_l2socket_creation_permission():
|
|||||||
thread so we will not be able to capture
|
thread so we will not be able to capture
|
||||||
any permission or bind errors.
|
any permission or bind errors.
|
||||||
"""
|
"""
|
||||||
# disable scapy promiscuous mode as we do not need it
|
conf.L2socket(filter=cap_filter)
|
||||||
conf.sniff_promisc = 0
|
|
||||||
conf.L2socket()
|
|
||||||
|
|
||||||
|
|
||||||
async def _async_verify_working_pcap(hass, cap_filter):
|
def _verify_working_pcap(cap_filter):
|
||||||
"""Verify we can create a packet filter.
|
"""Verify we can create a packet filter.
|
||||||
|
|
||||||
If we cannot create a filter we will be listening for
|
If we cannot create a filter we will be listening for
|
||||||
all traffic which is too intensive.
|
all traffic which is too intensive.
|
||||||
"""
|
"""
|
||||||
await hass.async_add_executor_job(compile_filter, cap_filter)
|
compile_filter(cap_filter)
|
||||||
|
@ -281,7 +281,7 @@ async def test_setup_and_stop(hass):
|
|||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
with patch("homeassistant.components.dhcp.AsyncSniffer.start") as start_call, patch(
|
with patch("homeassistant.components.dhcp.AsyncSniffer.start") as start_call, patch(
|
||||||
"homeassistant.components.dhcp._verify_l2socket_creation_permission",
|
"homeassistant.components.dhcp._verify_l2socket_setup",
|
||||||
), patch(
|
), patch(
|
||||||
"homeassistant.components.dhcp.compile_filter",
|
"homeassistant.components.dhcp.compile_filter",
|
||||||
):
|
):
|
||||||
@ -307,7 +307,7 @@ async def test_setup_fails_as_root(hass, caplog):
|
|||||||
wait_event = threading.Event()
|
wait_event = threading.Event()
|
||||||
|
|
||||||
with patch("os.geteuid", return_value=0), patch(
|
with patch("os.geteuid", return_value=0), patch(
|
||||||
"homeassistant.components.dhcp._verify_l2socket_creation_permission",
|
"homeassistant.components.dhcp._verify_l2socket_setup",
|
||||||
side_effect=Scapy_Exception,
|
side_effect=Scapy_Exception,
|
||||||
):
|
):
|
||||||
hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED)
|
hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED)
|
||||||
@ -330,7 +330,7 @@ async def test_setup_fails_non_root(hass, caplog):
|
|||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
with patch("os.geteuid", return_value=10), patch(
|
with patch("os.geteuid", return_value=10), patch(
|
||||||
"homeassistant.components.dhcp._verify_l2socket_creation_permission",
|
"homeassistant.components.dhcp._verify_l2socket_setup",
|
||||||
side_effect=Scapy_Exception,
|
side_effect=Scapy_Exception,
|
||||||
):
|
):
|
||||||
hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED)
|
hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED)
|
||||||
@ -351,9 +351,7 @@ async def test_setup_fails_with_broken_libpcap(hass, caplog):
|
|||||||
)
|
)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
with patch(
|
with patch("homeassistant.components.dhcp._verify_l2socket_setup",), patch(
|
||||||
"homeassistant.components.dhcp._verify_l2socket_creation_permission",
|
|
||||||
), patch(
|
|
||||||
"homeassistant.components.dhcp.compile_filter",
|
"homeassistant.components.dhcp.compile_filter",
|
||||||
side_effect=ImportError,
|
side_effect=ImportError,
|
||||||
) as compile_filter, patch(
|
) as compile_filter, patch(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user