Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 1 addition & 12 deletions docker/ssladapter/ssladapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
"""
from distutils.version import StrictVersion
from requests.adapters import HTTPAdapter
import ssl

try:
import requests.packages.urllib3 as urllib3
Expand All @@ -14,20 +13,10 @@
PoolManager = urllib3.poolmanager.PoolManager


def get_max_tls_protocol():
protocols = ('PROTOCOL_TLSv1_2',
'PROTOCOL_TLSv1_1',
'PROTOCOL_TLSv1')
for proto in protocols:
if hasattr(ssl, proto):
return getattr(ssl, proto)


class SSLAdapter(HTTPAdapter):
'''An HTTPS Transport Adapter that uses an arbitrary SSL version.'''
def __init__(self, ssl_version=None, assert_hostname=None,
assert_fingerprint=None, **kwargs):
ssl_version = ssl_version or get_max_tls_protocol()
self.ssl_version = ssl_version
self.assert_hostname = assert_hostname
self.assert_fingerprint = assert_fingerprint
Expand All @@ -41,7 +30,7 @@ def init_poolmanager(self, connections, maxsize, block=False):
'assert_hostname': self.assert_hostname,
'assert_fingerprint': self.assert_fingerprint,
}
if self.can_override_ssl_version():
if self.ssl_version and self.can_override_ssl_version():
kwargs['ssl_version'] = self.ssl_version

self.poolmanager = PoolManager(**kwargs)
Expand Down
5 changes: 0 additions & 5 deletions docker/tls.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,6 @@ def __init__(self, client_cert=None, ca_cert=None, verify=None,
# here, but also disable any public/default CA pool verification by
# leaving tls_verify=False

# urllib3 sets a default ssl_version if ssl_version is None,
# but that default is the vulnerable PROTOCOL_SSLv23 selection,
# so we override the default with the maximum supported in the running
# Python interpeter up to TLS 1.2. (see: http://tinyurl.com/kxga8hb)
ssl_version = ssl_version or ssladapter.get_max_tls_protocol()
self.ssl_version = ssl_version
self.assert_hostname = assert_hostname
self.assert_fingerprint = assert_fingerprint
Expand Down
17 changes: 17 additions & 0 deletions tests/unit/utils_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,17 @@
import pytest
import six

try:
from ssl import OP_NO_SSLv3, OP_NO_SSLv2, OP_NO_TLSv1
except ImportError:
OP_NO_SSLv2 = 0x1000000
OP_NO_SSLv3 = 0x2000000
OP_NO_TLSv1 = 0x4000000

from docker.client import Client
from docker.constants import DEFAULT_DOCKER_API_VERSION
from docker.errors import DockerException, InvalidVersion
from docker.ssladapter import ssladapter
from docker.utils import (
parse_repository_tag, parse_host, convert_filters, kwargs_from_env,
create_host_config, Ulimit, LogConfig, parse_bytes, parse_env_file,
Expand Down Expand Up @@ -872,3 +880,12 @@ def test_tar_with_directory_symlinks(self):
self.assertEqual(
sorted(tar_data.getnames()), ['bar', 'bar/foo', 'foo']
)


class SSLAdapterTest(base.BaseTestCase):
def test_only_uses_tls(self):
ssl_context = ssladapter.urllib3.util.ssl_.create_urllib3_context()

assert ssl_context.options & OP_NO_SSLv3
assert ssl_context.options & OP_NO_SSLv2
assert not ssl_context.options & OP_NO_TLSv1