Perform handshakes asynchronously
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
import asyncio
|
||||
import datetime
|
||||
import logging
|
||||
from collections import namedtuple
|
||||
|
||||
from dateutil.parser import parse as dtparse
|
||||
@@ -11,18 +13,38 @@ CertCheckResult = namedtuple(
|
||||
)
|
||||
|
||||
|
||||
def get_cert(hostname, timeout):
|
||||
# Unit of time slept asynchronously to simulate async socket handling
|
||||
AWAIT_IOTA = 0.001
|
||||
|
||||
|
||||
async def get_cert(hostname, timeout):
|
||||
ctx = ssl.create_default_context()
|
||||
with ctx.wrap_socket(socket.socket(), server_hostname=hostname) as s:
|
||||
with ctx.wrap_socket(
|
||||
socket.socket(), server_hostname=hostname, do_handshake_on_connect=False
|
||||
) as s:
|
||||
s.settimeout(timeout)
|
||||
|
||||
# @todo simulate async connect
|
||||
s.connect((hostname, 443))
|
||||
|
||||
s.setblocking(False)
|
||||
# Cannot await the handshake: simulate it with asyncio sleep
|
||||
while "Handshake not finished":
|
||||
try:
|
||||
s.do_handshake()
|
||||
break
|
||||
except ssl.SSLWantReadError:
|
||||
await asyncio.sleep(AWAIT_IOTA)
|
||||
except ssl.SSLWantWriteError:
|
||||
await asyncio.sleep(AWAIT_IOTA)
|
||||
|
||||
return s.getpeercert()
|
||||
|
||||
|
||||
def check_host_certificate_expiration(hostname, days_to_expiration, timeout=5):
|
||||
async def check_host_certificate_expiration(hostname, days_to_expiration, timeout=5):
|
||||
logging.info(f"Getting CERT from {hostname}")
|
||||
try:
|
||||
cert = get_cert(hostname, timeout)
|
||||
cert = await get_cert(hostname, timeout)
|
||||
except ssl.SSLCertVerificationError as e:
|
||||
return CertCheckResult(hostname, False, None, e.strerror)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user