From 897c6e50833fcd1bc4a7d0fd23e9beb21598dc9c Mon Sep 17 00:00:00 2001 From: Christian Herdtweck Date: Tue, 9 Apr 2019 10:20:55 +0200 Subject: [PATCH] Make certificate checks optional, enable per default Also give an option to give an extra certificate to accept as .pem --- src/web_interface.py | 27 ++++++++++++++++++++++----- 1 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/web_interface.py b/src/web_interface.py index 18316ab..a647a9c 100644 --- a/src/web_interface.py +++ b/src/web_interface.py @@ -42,17 +42,19 @@ log = logging.getLogger('pyi2ncommon.web_interface') from .arnied_wrapper import accept_licence -def find_in_form(regex, form="status", escape=False): +def find_in_form(regex, form="status", escape=False, check_certs=True): """ Find a regex in I2N web page's status frame. :param str regex: regular expression to find :param bool escape: whether to escape the regex + :param check_certs: forwarded to :py:func:`web_page_request`, see doc there :returns: whether the regex was found :rtype: bool """ accept_licence() - data = web_page_request(method="GET", url="/arnie?form=" + form) + data = web_page_request(method="GET", url="/arnie?form=" + form, + check_certs=check_certs) if escape: regex = re.escape(regex) if re.search(regex, data): @@ -62,14 +64,24 @@ def find_in_form(regex, form="status", escape=False): return False -def web_page_request(method="GET", url="/", body=None): +def web_page_request(method="GET", url="/", body=None, check_certs=True): """ Send an HTTPS request and return any response data. + SSL certificates are checked against a default set of certificates + installed on you system. This can be disabled (not recommended, security + implications!) by setting `check_certs` to `False`. To allow a secure + connection to host with e.g. a self-signed certificate, the caller can + load this certificate by specifying `check_certs=/path/to/cert.pem`. + (see also: :py:meth:`ssl.SSLContext.load_verify_locations`) + :param str method: GET or POST method for the request :param str url: url location within the remote host :param body: dictionary to be parsed and added to the url :type body: {str, str} or None + :param check_certs: Whether or not to check ssl certificates for connection + or file name to a certificate file + :type check_certs: bool or str :returns: data from the response if any :rtype: str """ @@ -77,8 +89,13 @@ def web_page_request(method="GET", url="/", body=None): headers = {"Content-Type": "application/x-www-form-urlencoded", "Accept": "text/plain"} - # Allow for an HTTPS connection with self-signed certificates - context = ssl._create_unverified_context() + if isinstance(check_certs, str): + context = ssl.create_default_context(cafile=check_certs) + elif check_certs: + context = ssl.create_default_context() + else: + # disable certificate checks + context = ssl._create_unverified_context() conn = client.HTTPSConnection("localhost", context=context) conn.request(method, url, body, headers) resp = conn.getresponse() -- 1.7.1