Commit 56488bdb authored by Matt Traudt's avatar Matt Traudt
Browse files

Add TLS verify option to destinations

parent 2483b40b
......@@ -39,7 +39,8 @@ def timed_recv_from_server(session, dest, byte_range):
# - What other exceptions can this throw?
# - Do we have to read the content, or did requests already do so?
requests_utils.get(session, dest.url, headers=headers)
session, dest.url, headers=headers, verify=dest.verify)
except requests.exceptions.ConnectionError as e:
return False, e
except requests.exceptions.ReadTimeout as e:
import logging
import random
import time
import os
from threading import RLock
import requests
from urllib.parse import urlparse
......@@ -11,6 +12,22 @@ import sbws.util.requests as requests_utils
log = logging.getLogger(__name__)
def _parse_verify_option(conf_section):
if 'verify' not in conf_section:
return True
return conf_section.getboolean('verify')
except ValueError:
'Currently sbws only supports verify=true/false, not a CA bundle '
'file. We think %s is not a bool, and thus must be a CA bundle '
'file. This is supposed to be allowed by the Python Requests '
'library, but pastly couldn\'t get it to work in his afternoon '
'of testing. So we will allow this, but expect Requests to throw '
'SSLError exceptions later. Have fun!', conf_section['verify'])
return conf_section['verify']
def connect_to_destination_over_circuit(dest, circ_id, session, cont, max_dl):
Connect to **dest* over the given **circ_id** using the given Requests
......@@ -56,7 +73,7 @@ def connect_to_destination_over_circuit(dest, circ_id, session, cont, max_dl):
# - What other exceptions can this throw?
head = requests_utils.head(session, dest.url)
head = requests_utils.head(session, dest.url, verify=dest.verify)
except (requests.exceptions.ConnectionError,
requests.exceptions.ReadTimeout) as e:
return False, 'Could not connect to {} over circ {} {}: {}'.format(
......@@ -78,7 +95,7 @@ def connect_to_destination_over_circuit(dest, circ_id, session, cont, max_dl):
class Destination:
def __init__(self, url, default_path, max_dl):
def __init__(self, url, default_path, max_dl, verify):
self._max_dl = max_dl
u = urlparse(url)
# these things should have been verified in verify_config
......@@ -89,11 +106,16 @@ class Destination:
parts = u[0:2] + default_path + u[2:]
u = urlparse('{}://{}{}{}{}{}'.format(*parts))
self._url = u
self._verify = verify
def is_usable(self, circ_id, session, cont):
''' Use **connect_to_destination_over_circuit** to determine if this
destination is usable and return what it returns. Just a small wrapper.
if not isinstance(self.verify, bool):
if not os.path.isfile(self.verify):
return False, '{} is believed to be a CA bundle file on disk '\
'but it does not exist'.format(self.verify)
return connect_to_destination_over_circuit(
self, circ_id, session, cont, self._max_dl)
......@@ -101,6 +123,10 @@ class Destination:
def url(self):
return self._url.geturl()
def verify(self):
return self._verify
def hostname(self):
return self._url.hostname
......@@ -123,7 +149,8 @@ class Destination:
def from_config(conf_section, default_path, max_dl):
assert 'url' in conf_section
url = conf_section['url']
return Destination(url, default_path, max_dl)
verify = _parse_verify_option(conf_section)
return Destination(url, default_path, max_dl, verify)
class DestinationList:
......@@ -250,14 +250,14 @@ def _validate_destinations(conf):
urls = {
'url': {},
all_valid_keys = list(urls.keys())
all_valid_keys = list(urls.keys()) + ['verify']
for sec in dest_sections:
if sec not in conf:
errors.append('{} is an enabled destination but is not a '
'section in the config'.format(sec))
errors.extend(_validate_section_keys(conf, sec, all_valid_keys,
conf, sec, all_valid_keys, err_tmpl, allow_missing=['verify']))
errors.extend(_validate_section_urls(conf, sec, urls, err_tmpl))
return errors
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment