diff --git a/CHANGELOG.md b/CHANGELOG.md index e7a6186..e0f206b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,4 +20,10 @@ # v2.1.0 - Upgraded dnspython to 2.0.x and fixed deprecated call to dns.resolver.query() - Upgraded validators to 0.17 -- Various pylint and type checking fixes \ No newline at end of file +- Various pylint and type checking fixes + +# v2.2.0 +- Upgraded SSLyze to 3.1 +- Removed pytest from requirements +- Various pylint and type checking fixes +- Removed TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 and TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 from "strong" TLS 1.2 ciphers \ No newline at end of file diff --git a/README.md b/README.md index 6d3f286..d884e3c 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ SSLChecker is a serverless API written in Python and running on Azure Functions. ## Pre-requisites -__Python__ - Python 3.7 (64-bit) and above. +__Python__ - Python 3.7 and 3.8 (64-bit). Python 3.9 is not supported yet. __Development__ - To set up a local development environment, follow the guidance from Microsoft [here](https://docs.microsoft.com/en-us/azure/azure-functions/functions-create-first-azure-function-azure-cli?pivots=programming-language-python&tabs=bash%2Cbrowser). diff --git a/SSLChecker/requirements.txt b/SSLChecker/requirements.txt index 5dddcfe..1a44b85 100644 --- a/SSLChecker/requirements.txt +++ b/SSLChecker/requirements.txt @@ -1,7 +1,6 @@ azure-functions dnspython==2.00.0 -requests==2.22.0 -sslyze==3.0.8 -validators==0.17.1 +requests>=2.24.0 +sslyze==3.1.0 +validators==0.18.1 typing-extensions==3.7.4.2 -pytest==5.4.3 diff --git a/SSLChecker/sharedcode/results.py b/SSLChecker/sharedcode/results.py index 9e2d4ce..9d10269 100644 --- a/SSLChecker/sharedcode/results.py +++ b/SSLChecker/sharedcode/results.py @@ -1,11 +1,15 @@ -# Setters for the results dictionary +""" Setters for the results dictionary """ +from typing import Dict, Any -def set_error(error_type, message): + +def set_error(error_type, message) -> Dict[str, str]: return {"Error Type": error_type, "Message": message} -def new_result_set(): +def new_result_set() -> Dict[str, Any]: + """ Result set """ + return {"Target": None, "IP": None, "MD5": None, "Scan": None, "View": None, "Results": []} diff --git a/SSLChecker/sharedcode/scanner.py b/SSLChecker/sharedcode/scanner.py index 485c3e4..2b359a6 100644 --- a/SSLChecker/sharedcode/scanner.py +++ b/SSLChecker/sharedcode/scanner.py @@ -1,4 +1,5 @@ from hashlib import md5 +from typing import Dict, Any from sslyze import ( ServerNetworkLocationViaDirectConnection, @@ -33,17 +34,16 @@ } # Currently, only The following TLS 1.2 ciphers are considered "strong" -ALLOWED_TLS12_CIPHERS = { +OK_TLS12_CIPHERS = { "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", - "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", - "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256", + "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256" } @@ -53,7 +53,7 @@ ) -def scan(target, ip, port, view, suite): +def scan(target, ip, port, view, suite) -> Dict[str, Any]: """ Five inputs: web site name, ip, port split-dns view, and cipher suite """ @@ -99,7 +99,7 @@ def scan(target, ip, port, view, suite): if suite == "policy" and scan_result.tls_version_used.name == "TLS_1_2": if ( accepted_cipher_suite.cipher_suite.name - not in ALLOWED_TLS12_CIPHERS + not in OK_TLS12_CIPHERS ): results.set_ciphers( scan_output, diff --git a/SSLChecker/sharedcode/shared_dns.py b/SSLChecker/sharedcode/shared_dns.py index 864dfef..7fd8fe2 100644 --- a/SSLChecker/sharedcode/shared_dns.py +++ b/SSLChecker/sharedcode/shared_dns.py @@ -1,3 +1,5 @@ +""" Shared module for dns operations """ + import pathlib from configparser import ConfigParser, ParsingError from typing import Tuple @@ -8,8 +10,8 @@ from .errors import InvalidConfig, InvalidFQDN, UnknownError, DNSError # Alias str type to better reflect the intented type and value -fqdn = str -ip = str +Fqdn = str +IpAddress = str def get_dns_options() -> Tuple[str, str]: @@ -33,7 +35,7 @@ def get_dns_options() -> Tuple[str, str]: return external_dns, internal_dns -def _init_resolver(dnsserver: ip, timeout: int, lifetime: int) -> resolver.Resolver: +def _init_resolver(dnsserver: IpAddress, timeout: int, lifetime: int) -> resolver.Resolver: """ initialize a resolver """ @@ -45,9 +47,9 @@ def _init_resolver(dnsserver: ip, timeout: int, lifetime: int) -> resolver.Resol def resolve_dns( - dnsserver: ip, dnsname: fqdn, + dnsserver: IpAddress, dnsname: Fqdn, timeout: int = 3, lifetime: int = 3 - ) -> ip: + ) -> IpAddress: """ Resolve dns name """ _iplist = [] # results @@ -90,7 +92,7 @@ def resolve_dns( ) -def parse_name(name: str) -> fqdn: +def parse_name(name: str) -> Fqdn: """ Parse a DNS name to ensure it does not contain http(s) """ parsed_name = urlparse(name)