Package: python-astropy
Version: 0.4.2-1
Severity: serious
Forwarded: https://github.com/astropy/astropy/issues/3306
Tags: patch pending upstream

After SSLv2 and SSLv3 were removed, python-astropy fails to build:

The errors are like

_________________ ERROR collecting astropy/vo/samp/__init__.py _________________
astropy/vo/samp/__init__.py:15: in <module>
>   from .hub import *
astropy/vo/samp/hub.py:33: in <module>
>       from .ssl_utils import SafeTransport, SecureXMLRPCServer
astropy/vo/samp/ssl_utils.py:26: in <module>
>       class HTTPSConnection(HTTPConnection):
astropy/vo/samp/ssl_utils.py:35: in HTTPSConnection
>                    ssl_version=ssl.PROTOCOL_SSLv3, strict=None):
E           AttributeError: 'module' object has no attribute 'PROTOCOL_SSLv3'

The applied patch will fix this; I will upload a new package soon.
>From 40d05e497bcbf7a43bfdab8d81cbb30b15f9537f Mon Sep 17 00:00:00 2001
From: Michael Droettboom <mdb...@gmail.com>
Date: Fri, 16 Jan 2015 09:58:27 -0500
Subject: [PATCH] Let Python choose the default SSL protocol for us.

---
 astropy/vo/samp/client.py            | 17 ++++++---------
 astropy/vo/samp/hub.py               | 19 +++++++---------
 astropy/vo/samp/hub_proxy.py         | 19 +++++++---------
 astropy/vo/samp/hub_script.py        | 28 +++++++++++++-----------
 astropy/vo/samp/integrated_client.py | 30 +++++++++++++-------------
 astropy/vo/samp/ssl_utils.py         | 42 +++++++++++++++++++++++-------------
 6 files changed, 81 insertions(+), 74 deletions(-)

diff --git a/astropy/vo/samp/client.py b/astropy/vo/samp/client.py
index 63cf2f6..63328fe 100644
--- a/astropy/vo/samp/client.py
+++ b/astropy/vo/samp/client.py
@@ -85,13 +85,13 @@ class SAMPClient(object):
         passed from the Hub end of the connection.
 
     ssl_version : int, optional
-        Which version of the SSL protocol to use. Typically, the server
-        chooses a particular protocol version, and the client must adapt to
-        the server's choice. Most of the versions are not interoperable with
-        the other versions. If not specified the default SSL version is
-        `ssl.PROTOCOL_SSLv23`. This version provides the most compatibility
-        with other versions Hub side. Other SSL protocol versions are:
-        `ssl.PROTOCOL_SSLv2`, `ssl.PROTOCOL_SSLv3` and `ssl.PROTOCOL_TLSv1`.
+        Which version of the SSL protocol to use. Typically, the
+        server chooses a particular protocol version, and the client
+        must adapt to the server's choice. Most of the versions are
+        not interoperable with the other versions. If not specified,
+        the default SSL version is taken from the default in the
+        installed version of the Python standard `ssl` library.  See
+        the `ssl` documentation for more information.
 
     callable : bool, optional
         Whether the client can receive calls and notifications. If set to
@@ -118,9 +118,6 @@ def __init__(self, hub, name=None, description=None, metadata=None,
         if description is not None:
             metadata["samp.description.text"] = description
 
-        if SSL_SUPPORT and ssl_version is None:
-            ssl_version = ssl.PROTOCOL_SSLv23
-
         self._metadata = metadata
 
         self._addr = addr
diff --git a/astropy/vo/samp/hub.py b/astropy/vo/samp/hub.py
index 6e01b4f..ba0044a 100644
--- a/astropy/vo/samp/hub.py
+++ b/astropy/vo/samp/hub.py
@@ -114,14 +114,14 @@ class SAMPHubServer(object):
         passed from the Hub end of the connection.
 
     ssl_version : int, optional
-        The ``ssl_version`` option specifies which version of the SSL protocol
-        to use. Typically, the server chooses a particular protocol version,
-        and the client must adapt to the server's choice. Most of the versions
-        are not interoperable with the other versions. If not specified the
-        default SSL version is `ssl.PROTOCOL_SSLv23`. This version provides
-        the most compatibility with other versions client side. Other SSL
-        protocol versions are: `ssl.PROTOCOL_SSLv2`, `ssl.PROTOCOL_SSLv3` and
-        `ssl.PROTOCOL_TLSv1`.
+        The ``ssl_version`` option specifies which version of the SSL
+        protocol to use. Typically, the server chooses a particular
+        protocol version, and the client must adapt to the server's
+        choice. Most of the versions are not interoperable with the
+        other versions. If not specified, the default SSL version is
+        taken from the default in the installed version of the Python
+        standard `ssl` library.  See the `ssl` documentation for more
+        information.
 
     web_profile : bool, optional
         Enables or disables the Web Profile support.
@@ -165,9 +165,6 @@ def __init__(self, secret=None, addr=None, port=0, lockfile=None,
         self._client_timeout = client_timeout
         self._pool_size = pool_size
 
-        if SSL_SUPPORT and ssl_version is None:
-            ssl_version = ssl.PROTOCOL_SSLv23
-
         self._web_profile = web_profile
         self._web_profile_server = None
         self._web_profile_callbacks = {}
diff --git a/astropy/vo/samp/hub_proxy.py b/astropy/vo/samp/hub_proxy.py
index 503c063..d055b50 100644
--- a/astropy/vo/samp/hub_proxy.py
+++ b/astropy/vo/samp/hub_proxy.py
@@ -78,14 +78,14 @@ def connect(self, hub=None, hub_params=None,
             certificate passed from the Hub end of the connection.
 
         ssl_version : int, optional
-            Which version of the SSL protocol to use. Typically, the server
-            chooses a particular protocol version, and the client must adapt
-            to the server's choice. Most of the versions are not interoperable
-            with the other versions. If not specified the default SSL version
-            is `ssl.PROTOCOL_SSLv3`. This version provides the most
-            compatibility with other versions server side. Other SSL protocol
-            versions are: `ssl.PROTOCOL_SSLv2`, `ssl.PROTOCOL_SSLv3` and
-            `ssl.PROTOCOL_TLSv1`.
+            Which version of the SSL protocol to use. Typically, the
+            server chooses a particular protocol version, and the
+            client must adapt to the server's choice. Most of the
+            versions are not interoperable with the other versions. If
+            not specified, the default SSL version is taken from the
+            default in the installed version of the Python standard
+            `ssl` library.  See the `ssl` documentation for more
+            information.
 
         pool_size : int, optional
             The number of socket connections opened to communicate with the
@@ -95,9 +95,6 @@ def connect(self, hub=None, hub_params=None,
         self._connected = False
         self.lockfile = {}
 
-        if SSL_SUPPORT and ssl_version is None:
-            ssl_version = ssl.PROTOCOL_SSLv3
-
         if hub is not None and hub_params is not None:
             raise ValueError("Cannot specify both hub and hub_params")
 
diff --git a/astropy/vo/samp/hub_script.py b/astropy/vo/samp/hub_script.py
index 343319b..90b006f 100644
--- a/astropy/vo/samp/hub_script.py
+++ b/astropy/vo/samp/hub_script.py
@@ -148,10 +148,14 @@ def hub_script(timeout=0):
                                "SSL protocol to use. Typically, the server chooses a particular "
                                "protocol version, and the client must adapt to the server's choice. "
                                "Most of the versions are not interoperable with the other versions. "
-                               "If not specified the default SSL version is SSLv23. This version "
-                               "provides the most compatibility with other versions client side. "
-                               "Other SSL protocol versions are: SSLv2, SSLv3 and TLSv1.",
-                               type=str, choices=["SSLv23", "SSLv2", "SSLv3", "TLSv1"], default="SSLv23")
+                               "If not specified the default SSL version is taken from the default in "
+                               "the Python standard `ssl` library for the version of Python that is "
+                               "installed. Other SSL protocol versions are: SSLv2, SSLv3, SSLv23, "
+                               "TLSv1, TLSv1_1, TLSv1_2 but not all of them may be available on all "
+                               "versions of Python.",
+                               type=str,
+                               choices=["SSLv23", "SSLv2", "SSLv3", "TLSv1", "TLSv1_1", "TLSv1_2"],
+                               default=None)
 
         parser.add_argument_group(ssl_group)
 
@@ -170,14 +174,14 @@ def hub_script(timeout=0):
             else:
                 options.cert_reqs = ssl.CERT_NONE
 
-            if options.ssl_version == "SSLv2":
-                options.ssl_version = ssl.PROTOCOL_SSLv2
-            elif options.ssl_version == "SSLv3":
-                options.ssl_version = ssl.PROTOCOL_SSLv3
-            elif options.ssl_version == "TLSv1":
-                options.ssl_version = ssl.PROTOCOL_TLSv1
-            else:
-                options.ssl_version = ssl.PROTOCOL_SSLv23
+            if options.ssl_version is not None:
+                if hasattr(ssl, 'PROTOCOL_' + options.ssl_version):
+                    options.ssl_version = getattr(
+                        ssl, 'PROTOCOL_' + options.ssl_version)
+                else:
+                    raise ValueError(
+                        "SSL protocol '{0}' not supported on this version of "
+                        "Python".format(options.ssl_version))
 
         if options.loglevel in ("OFF", "ERROR", "WARNING", "DEBUG", "INFO"):
             log.setLevel(options.loglevel)
diff --git a/astropy/vo/samp/integrated_client.py b/astropy/vo/samp/integrated_client.py
index d273ba8..14bd22e 100644
--- a/astropy/vo/samp/integrated_client.py
+++ b/astropy/vo/samp/integrated_client.py
@@ -68,13 +68,13 @@ class SAMPIntegratedClient(object):
         passed from the Hub end of the connection.
 
     ssl_version : int, optional
-        Which version of the SSL protocol to use. Typically, the server chooses
-        a particular protocol version, and the client must adapt to the
-        server's choice. Most of the versions are not interoperable with the
-        other versions. If not specified the default SSL version is
-        `ssl.PROTOCOL_SSLv23`. This version provides the most compatibility
-        with other versions Hub side. Other SSL protocol versions are:
-        `ssl.PROTOCOL_SSLv2`, `ssl.PROTOCOL_SSLv3` and `ssl.PROTOCOL_TLSv1`.
+        Which version of the SSL protocol to use. Typically, the
+        server chooses a particular protocol version, and the client
+        must adapt to the server's choice. Most of the versions are
+        not interoperable with the other versions. If not specified,
+        the default SSL version is taken from the default in the
+        installed version of the Python standard `ssl` library.  See
+        the `ssl` documentation for more information.
 
     callable : bool, optional
         Whether the client can receive calls and notifications. If set to
@@ -167,14 +167,14 @@ def connect(self, hub=None, hub_params=None,
             certificate passed from the Hub end of the connection.
 
         ssl_version : int, optional
-            Which version of the SSL protocol to use. Typically, the server
-            chooses a particular protocol version, and the client must adapt
-            to the server's choice. Most of the versions are not interoperable
-            with the other versions. If not specified the default SSL version
-            is `ssl.PROTOCOL_SSLv3`. This version provides the most
-            compatibility with other versions server side. Other SSL protocol
-            versions are: `ssl.PROTOCOL_SSLv2`, `ssl.PROTOCOL_SSLv3` and
-            `ssl.PROTOCOL_TLSv1`.
+            Which version of the SSL protocol to use. Typically, the
+            server chooses a particular protocol version, and the
+            client must adapt to the server's choice. Most of the
+            versions are not interoperable with the other versions. If
+            not specified, the default SSL version is taken from the
+            default in the installed version of the Python standard
+            `ssl` library.  See the `ssl` documentation for more
+            information.
 
         pool_size : int, optional
             The number of socket connections opened to communicate with the
diff --git a/astropy/vo/samp/ssl_utils.py b/astropy/vo/samp/ssl_utils.py
index 6b4785b..94acc16 100644
--- a/astropy/vo/samp/ssl_utils.py
+++ b/astropy/vo/samp/ssl_utils.py
@@ -32,7 +32,7 @@ class HTTPSConnection(HTTPConnection):
 
         def __init__(self, host, port=None, key_file=None, cert_file=None,
                      cert_reqs=ssl.CERT_NONE, ca_certs=None,
-                     ssl_version=ssl.PROTOCOL_SSLv3, strict=None):
+                     ssl_version=None, strict=None):
 
             HTTPConnection.__init__(self, host, port, strict)
 
@@ -47,12 +47,18 @@ def connect(self):
 
             sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
             sock.connect((self.host, self.port))
-            sslconn = ssl.wrap_socket(sock, server_side=False,
-                                      certfile=self.cert_file,
-                                      keyfile=self.key_file,
-                                      cert_reqs=self.cert_reqs,
-                                      ca_certs=self.ca_certs,
-                                      ssl_version=self.ssl_version)
+            # We have to explicitly not pass the ssl_version to
+            # `ssl.wrap_socket` if it's None.
+            kwargs = {
+                'server_size': False,
+                'certfile': self.cert_file,
+                'keyfile': self.key_file,
+                'cert_reqs': self.cert_reqs,
+                'ca_certs': self.ca_certs,
+            }
+            if self.ssl_version is not None:
+                kwargs['ssl_version'] = self.ssl_version
+            sslconn = ssl.wrap_socket(sock, **args)
             self.sock = sslconn
 
     class HTTPS(HTTP):
@@ -64,7 +70,7 @@ class HTTPS(HTTP):
 
         def __init__(self, host='', port=None, key_file=None, cert_file=None,
                      cert_reqs=ssl.CERT_NONE, ca_certs=None,
-                     ssl_version=ssl.PROTOCOL_SSLv3):
+                     ssl_version=None):
 
             # provide a default host, pass the X509 cert info
 
@@ -97,7 +103,7 @@ class SafeTransport(xmlrpc.Transport):
 
     def __init__(self, key_file=None, cert_file=None,
                  cert_reqs=ssl.CERT_NONE, ca_certs=None,
-                 ssl_version=ssl.PROTOCOL_SSLv3, strict=None,
+                 ssl_version=None, strict=None,
                  use_datetime=0):
 
         xmlrpc.Transport.__init__(self, use_datetime)
@@ -151,10 +157,16 @@ def __init__(self, addr, key_file, cert_file, cert_reqs, ca_certs, ssl_version,
     def get_request(self):
         # override this to wrap socket with SSL
         sock, addr = self.socket.accept()
-        sslconn = ssl.wrap_socket(sock, server_side=True,
-                                  certfile=self.cert_file,
-                                  keyfile=self.key_file,
-                                  cert_reqs=self.cert_reqs,
-                                  ca_certs=self.ca_certs,
-                                  ssl_version=self.ssl_version)
+        # We have to explicitly not pass the ssl_version to
+        # `ssl.wrap_socket` if it's None.
+        kwargs = {
+            'server_side': True,
+            'certfile': self.cert_file,
+            'keyfile': self.key_file,
+            'cert_reqs': self.cert_reqs,
+            'ca_certs': self.ca_certs
+        }
+        if self.ssl_version is not None:
+            kwargs['ssl_version'] = self.ssl_version
+        sslconn = ssl.wrap_socket(sock, **kwargs)
         return sslconn, addr

Reply via email to