Skip to content

Commit

Permalink
improve TLS version precheck speed
Browse files Browse the repository at this point in the history
  • Loading branch information
mxsasha committed Oct 15, 2024
1 parent a4fae4f commit 22072e1
Showing 1 changed file with 55 additions and 41 deletions.
96 changes: 55 additions & 41 deletions checks/tasks/tls/scans.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import concurrent.futures
from binascii import hexlify
from enum import Enum
from pathlib import Path
Expand Down Expand Up @@ -487,47 +488,23 @@ def check_mail_tls_multiple(server_tuples, task) -> Dict[str, Dict[str, Any]]:
scans = []
dane_cb_per_server = {}
results = {}
for server, dane_cb_data in server_tuples:
try:
server_location = ServerNetworkLocation(hostname=server, port=25)
except ServerHostnameCouldNotBeResolved:
log.info(f"unable to resolve MX host {server}, marking server unreachable")
results[server] = dict(server_reachable=False, tls_enabled=False)
continue
network_configuration = ServerNetworkConfiguration(
tls_server_name_indication=server,
tls_opportunistic_encryption=ProtocolWithOpportunisticTlsEnum.SMTP,
smtp_ehlo_hostname=settings.SMTP_EHLO_DOMAIN,
network_timeout=SSLYZE_NETWORK_TIMEOUT,
)
# Catch errors from here
supported_tls_versions = check_supported_tls_versions(
ServerConnectivityInfo(
server_location=server_location,
network_configuration=network_configuration,
tls_probing_result=FAKE_SERVER_TLS_PROBING_RESULT,
)
)
if not supported_tls_versions:
log.info(f"no TLS version support found for MX host {server}, marking server unreachable")
results[server] = dict(server_reachable=False, tls_enabled=False)
continue
scan_commands = SSLYZE_SCAN_COMMANDS | {
SSLYZE_SCAN_COMMANDS_FOR_TLS[tls_version] for tls_version in supported_tls_versions
}
log.info(f"==== precheck on {server_location} supports {supported_tls_versions} {scan_commands=}")

dane_cb_per_server[server] = dane_cb_data
scans.append(
ServerScanRequest(
server_location=server_location,
network_configuration=network_configuration,
scan_commands=scan_commands,
scan_commands_extra_arguments=ScanCommandsExtraArguments(
session_renegotiation=SessionRenegotiationExtraArgument(client_renegotiation_attempts=1),
),
)
)
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
future_to_server = {}

for server, dane_cb_data in server_tuples:
dane_cb_per_server[server] = dane_cb_data
future = executor.submit(_generate_mail_server_scan_request, server)
future_to_server[future] = server

for future in concurrent.futures.as_completed(future_to_server):
server = future_to_server[future]
scan_request = future.result()

if scan_request:
scans.append(scan_request)
else:
results[server] = dict(server_reachable=False, tls_enabled=False)

if not scans:
return results
connection_limit = connection_limit_for_scans(scans)
Expand Down Expand Up @@ -560,6 +537,43 @@ def connection_limit_for_scans(scans: List[ServerScanRequest]):
return 1


def _generate_mail_server_scan_request(server: str) -> Optional[ServerScanRequest]:
try:
server_location = ServerNetworkLocation(hostname=server, port=25)
except ServerHostnameCouldNotBeResolved:
log.info(f"unable to resolve MX host {server}, marking server unreachable")
return None
network_configuration = ServerNetworkConfiguration(
tls_server_name_indication=server,
tls_opportunistic_encryption=ProtocolWithOpportunisticTlsEnum.SMTP,
smtp_ehlo_hostname=settings.SMTP_EHLO_DOMAIN,
network_timeout=SSLYZE_NETWORK_TIMEOUT,
)
supported_tls_versions = check_supported_tls_versions(
ServerConnectivityInfo(
server_location=server_location,
network_configuration=network_configuration,
tls_probing_result=FAKE_SERVER_TLS_PROBING_RESULT,
)
)
if not supported_tls_versions:
log.info(f"no TLS version support found for MX host {server}, marking server unreachable")
return None
scan_commands = SSLYZE_SCAN_COMMANDS | {
SSLYZE_SCAN_COMMANDS_FOR_TLS[tls_version] for tls_version in supported_tls_versions
}
log.info(f"==== precheck on {server_location} supports {supported_tls_versions} {scan_commands=}")

return ServerScanRequest(
server_location=server_location,
network_configuration=network_configuration,
scan_commands=scan_commands,
scan_commands_extra_arguments=ScanCommandsExtraArguments(
session_renegotiation=SessionRenegotiationExtraArgument(client_renegotiation_attempts=1),
),
)


def check_mail_tls(result: ServerScanResult, all_suites: List[CipherSuitesScanAttempt], dane_cb_data, task):
"""
Perform evaluation and additional probes for a single mail server.
Expand Down

0 comments on commit 22072e1

Please sign in to comment.