mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 12:17:07 +00:00
Correct socket use in cert_expiry platform (#25011)
* Make sure we use same family for ssl socket and connection getaddrinfo result could be different from what connection was made with. It also blocks potential use of happy eye balls algorithm This also fixes lingering sockets until python garbage collection. * Add availability value if unable to get expiry * Fix lint issue
This commit is contained in:
parent
31d7b702a6
commit
c2f1c4b981
@ -55,6 +55,7 @@ class SSLCertificate(Entity):
|
||||
self.server_port = server_port
|
||||
self._name = sensor_name
|
||||
self._state = None
|
||||
self._available = False
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
@ -76,34 +77,39 @@ class SSLCertificate(Entity):
|
||||
"""Icon to use in the frontend, if any."""
|
||||
return 'mdi:certificate'
|
||||
|
||||
@property
|
||||
def available(self):
|
||||
"""Icon to use in the frontend, if any."""
|
||||
return self._available
|
||||
|
||||
def update(self):
|
||||
"""Fetch the certificate information."""
|
||||
ctx = ssl.create_default_context()
|
||||
try:
|
||||
ctx = ssl.create_default_context()
|
||||
host_info = socket.getaddrinfo(self.server_name, self.server_port)
|
||||
family = host_info[0][0]
|
||||
sock = ctx.wrap_socket(
|
||||
socket.socket(family=family), server_hostname=self.server_name)
|
||||
sock.settimeout(TIMEOUT)
|
||||
sock.connect((self.server_name, self.server_port))
|
||||
address = (self.server_name, self.server_port)
|
||||
with socket.create_connection(
|
||||
address, timeout=TIMEOUT) as sock:
|
||||
with ctx.wrap_socket(
|
||||
sock, server_hostname=address[0]) as ssock:
|
||||
cert = ssock.getpeercert()
|
||||
|
||||
except socket.gaierror:
|
||||
_LOGGER.error("Cannot resolve hostname: %s", self.server_name)
|
||||
self._available = False
|
||||
return
|
||||
except socket.timeout:
|
||||
_LOGGER.error(
|
||||
"Connection timeout with server: %s", self.server_name)
|
||||
self._available = False
|
||||
return
|
||||
except OSError:
|
||||
_LOGGER.error("Cannot connect to %s", self.server_name)
|
||||
return
|
||||
|
||||
try:
|
||||
cert = sock.getpeercert()
|
||||
except OSError:
|
||||
_LOGGER.error("Cannot fetch certificate from %s", self.server_name)
|
||||
_LOGGER.error("Cannot fetch certificate from %s",
|
||||
self.server_name, exc_info=1)
|
||||
self._available = False
|
||||
return
|
||||
|
||||
ts_seconds = ssl.cert_time_to_seconds(cert['notAfter'])
|
||||
timestamp = datetime.fromtimestamp(ts_seconds)
|
||||
expiry = timestamp - datetime.today()
|
||||
self._available = True
|
||||
self._state = expiry.days
|
||||
|
Loading…
x
Reference in New Issue
Block a user