On Mon, Jul 10, 2017 at 2:34 PM, Jay Rolette <role...@infinite.io> wrote:

>
> On Mon, Jul 10, 2017 at 9:37 AM, Markos Gogoulos <mgogou...@mist.io>
> wrote:
>
>> Hi all,
>>
>> I'm trying to disable SSL verification via an optional switch, for
>> OpenStack connections. I cannot use the 'global' VERIFY_SSL_CERT in my
>> case, because multiple OpenStack connections take place at the same time,
>> some of them should perform SSL verification while others shouldn't.
>>
>> That is, by instantiating a libcloud connection driver, I'd like to
>> specify
>> a verify False/True switch, and this should affect  the resulting requests
>> call.
>>
>> As far as I know there's not a directional relationship between a
>> connection and driver, so this makes things harder and although I can
>> 'store' the switch on the driver object, connection cannot read it.
>>
>> Do you have any ideas or suggestions what would be a simple way of
>> achieving the above?
>>
>> Regards,
>> Markos
>>
>
> It's not quite as simple as you'd hope due to the connection vs. driver
> split, but here are diffs for how we did it. This should be relative
> to apache-libcloud-1.0.0-pre1.
>
> Jay
>
> diff -r 17df54435983 -r 28d56440b52b libcloud/common/aws.py
> --- a/libcloud/common/aws.py    Tue Mar 22 22:56:44 2016 +0000
> +++ b/libcloud/common/aws.py    Wed Mar 23 22:46:52 2016 +0000
> @@ -134,15 +134,19 @@
>
>  class AWSTokenConnection(ConnectionUserAndKey):
>      def __init__(self, user_id, key, secure=True,
> -                 host=None, port=None, url=None, timeout=None,
> proxy_url=None,
> -                 token=None, retry_delay=None, backoff=None):
> -        self.token = token
> +                 host=None, port=None, url=None, timeout=None, **kwargs):
> +                 # -redacted-
> +                 # add kwargs to the various Libcloud Connection classes
> +                 # so we can extend parameters
> +                 #
> +                 # proxy_url=None, token=None, retry_delay=None,
> backoff=None):
> +        self.token = kwargs.get('token', None)
>          super(AWSTokenConnection, self).__init__(user_id, key,
> secure=secure,
>                                                   host=host, port=port,
> url=url,
> -                                                 timeout=timeout,
> -                                                 retry_delay=retry_delay,
> -                                                 backoff=backoff,
> -                                                 proxy_url=proxy_url)
> +                                                 timeout=timeout,
> **kwargs)
> +                                                 #
> retry_delay=retry_delay,
> +                                                 # backoff=backoff,
> +                                                 # proxy_url=proxy_url)
>
>      def add_default_params(self, params):
>          # Even though we are adding it to the headers, we need it here too
> diff -r 17df54435983 -r 28d56440b52b libcloud/common/base.py
> --- a/libcloud/common/base.py   Tue Mar 22 22:56:44 2016 +0000
> +++ b/libcloud/common/base.py   Wed Mar 23 22:46:52 2016 +0000
> @@ -528,7 +528,12 @@
>      allow_insecure = True
>
>      def __init__(self, secure=True, host=None, port=None, url=None,
> -                 timeout=None, proxy_url=None, retry_delay=None,
> backoff=None):
> +                 timeout=None, **kwargs):
> +                 # -redacted-
> +                 # add kwargs to the various Libcloud Connection classes
> +                 # so we can extend parameters
> +                 #
> +                 # timeout=None, proxy_url=None, retry_delay=None,
> backoff=None):
>          self.secure = secure and 1 or 0
>          self.ua = []
>          self.context = {}
> @@ -557,9 +562,12 @@
>               self.request_path) = self._tuple_from_url(url)
>
>          self.timeout = timeout or self.timeout
> -        self.retry_delay = retry_delay
> -        self.backoff = backoff
> -        self.proxy_url = proxy_url
> +        self.retry_delay = kwargs.get('retry_delay', None)
> +        self.backoff = kwargs.get('backoff', None)
> +        self.proxy_url = kwargs.get('proxy_url', None)
> +
> +        # -redacted-
> +        self.verify_ssl_cert = kwargs.get('verify_ssl_cert', None)
>
>      def set_http_proxy(self, proxy_url):
>          """
> @@ -660,6 +668,10 @@
>          if self.proxy_url:
>              kwargs.update({'proxy_url': self.proxy_url})
>
> +        # -redacted-
> +        if self.verify_ssl_cert is not None:
> +            kwargs['verify_ssl_cert'] = self.verify_ssl_cert
> +
>          connection = self.conn_classes[secure](**kwargs)
>          # You can uncoment this line, if you setup a reverse proxy server
>          # which proxies to your endpoint, and lets you easily capture
> @@ -1023,7 +1035,9 @@
>      Base connection class which accepts a single ``key`` argument.
>      """
>      def __init__(self, key, secure=True, host=None, port=None, url=None,
> -                 timeout=None, proxy_url=None, backoff=None,
> retry_delay=None):
> +                 timeout=None, **kwargs):
> +                 # -redacted-
> +                 # timeout=None, proxy_url=None, backoff=None,
> retry_delay=None):
>          """
>          Initialize `user_id` and `key`; set `secure` to an ``int`` based
> on
>          passed value.
> @@ -1031,9 +1045,10 @@
>          super(ConnectionKey, self).__init__(secure=secure, host=host,
>                                              port=port, url=url,
>                                              timeout=timeout,
> -                                            proxy_url=proxy_url,
> -                                            backoff=backoff,
> -                                            retry_delay=retry_delay)
> +                                            **kwargs)
> +                                            # proxy_url=proxy_url,
> +                                            # backoff=backoff,
> +                                            # retry_delay=retry_delay)
>          self.key = key
>
>
> @@ -1042,17 +1057,19 @@
>      Base connection class which accepts a single ``cert_file`` argument.
>      """
>      def __init__(self, cert_file, secure=True, host=None, port=None,
> url=None,
> -                 proxy_url=None, timeout=None, backoff=None,
> retry_delay=None):
> +                 proxy_url=None, timeout=None, **kwargs):
> +                 # -redacted-
> +                 # backoff=None, retry_delay=None):
>          """
>          Initialize `cert_file`; set `secure` to an ``int`` based on
>          passed value.
>          """
>          super(CertificateConnection, self).__init__(secure=secure,
> host=host,
>                                                      port=port, url=url,
> -                                                    timeout=timeout,
> -                                                    backoff=backoff,
> -
>  retry_delay=retry_delay,
> -                                                    proxy_url=proxy_url)
> +                                                    timeout=timeout,
> **kwargs)
> +                                                    # backoff=backoff,
> +                                                    #
> retry_delay=retry_delay,
> +                                                    # proxy_url=proxy_url)
>
>          self.cert_file = cert_file
>
> @@ -1065,14 +1082,16 @@
>      user_id = None
>
>      def __init__(self, user_id, key, secure=True, host=None, port=None,
> -                 url=None, timeout=None, proxy_url=None,
> -                 backoff=None, retry_delay=None):
> +                 url=None, timeout=None, **kwargs):
> +                 # -redacted-
> +                 # proxy_url=None, backoff=None, retry_delay=None):
>          super(ConnectionUserAndKey, self).__init__(key, secure=secure,
>                                                     host=host, port=port,
>                                                     url=url,
> timeout=timeout,
> -                                                   backoff=backoff,
> -
> retry_delay=retry_delay,
> -                                                   proxy_url=proxy_url)
> +                                                   **kwargs)
> +                                                   # backoff=backoff,
> +                                                   #
> retry_delay=retry_delay,
> +                                                   # proxy_url=proxy_url)
>          self.user_id = user_id
>
>
> @@ -1132,6 +1151,9 @@
>          self.api_version = api_version
>          self.region = region
>
> +        # -redacted-
> +        self.verify_ssl_cert = kwargs.get('verify_ssl_cert', None)
> +
>          conn_kwargs = self._ex_connection_class_kwargs()
>          conn_kwargs.update({'timeout': kwargs.pop('timeout', None),
>                              'retry_delay': kwargs.pop('retry_delay',
> None),
> diff -r 17df54435983 -r 28d56440b52b libcloud/common/openstack.py
> --- a/libcloud/common/openstack.py      Tue Mar 22 22:56:44 2016 +0000
> +++ b/libcloud/common/openstack.py      Wed Mar 23 22:46:52 2016 +0000
> @@ -137,10 +137,15 @@
>                   ex_force_service_type=None,
>                   ex_force_service_name=None,
>                   ex_force_service_region=None,
> -                 retry_delay=None, backoff=None):
> +                 retry_delay=None, backoff=None, **kwargs):
> +                 # -redacted-
> +                 # add kwargs to the various Libcloud Connection classes
> +                 # so we can extend parameters
> +
>          super(OpenStackBaseConnection, self).__init__(
>              user_id, key, secure=secure, timeout=timeout,
> -            retry_delay=retry_delay, backoff=backoff, proxy_url=proxy_url)
> +            retry_delay=retry_delay, backoff=backoff, proxy_url=proxy_url,
> +            **kwargs)
>
>          if ex_force_auth_version:
>              self._auth_version = ex_force_auth_version
> diff -r 17df54435983 -r 28d56440b52b libcloud/httplib_ssl.py
> --- a/libcloud/httplib_ssl.py   Tue Mar 22 22:56:44 2016 +0000
> +++ b/libcloud/httplib_ssl.py   Wed Mar 23 22:46:52 2016 +0000
> @@ -201,6 +201,11 @@
>          proxy_url_env = os.environ.get(HTTP_PROXY_ENV_VARIABLE_NAME,
> None)
>          proxy_url = kwargs.pop('proxy_url', proxy_url_env)
>
> +        # httplib.HTTPConnection doesn't support general **kwargs, so
> +        # strip off verify_ssl_cert (if present). It's only needed for
> +        # HTTPS connections anyway.
> +        kwargs.pop('verify_ssl_cert', None)
> +
>          super(LibcloudHTTPConnection, self).__init__(*args, **kwargs)
>
>          if proxy_url:
> @@ -221,7 +226,10 @@
>          """
>          Constructor
>          """
> -        self._setup_verify()
> +        # -redacted-
> +        verify_ssl_cert = kwargs.pop('verify_ssl_cert', None)
> +        self._setup_verify(verify_ssl_cert)
> +
>          # Support for HTTP proxy
>          proxy_url_env = os.environ.get(HTTP_PROXY_ENV_VARIABLE_NAME,
> None)
>          proxy_url = kwargs.pop('proxy_url', proxy_url_env)
> @@ -231,7 +239,7 @@
>          if proxy_url:
>              self.set_http_proxy(proxy_url=proxy_url)
>
> -    def _setup_verify(self):
> +    def _setup_verify(self, verify_ssl_cert=None):
>          """
>          Setup Verify SSL or not
>
> @@ -239,6 +247,11 @@
>          the class overrides the connect() class method or runs the
>          inherited httplib.HTTPSConnection connect()
>          """
> +        # Added per connection control over whether we should
> +        # verify the certificate or not. If not specified, use
> +        # original global default.
> +        self.verify = verify_ssl_cert
> +        if self.verify is None:
>          self.verify = libcloud.security.VERIFY_SSL_CERT
>
>          if self.verify:
>
>
Additional fix required for Python 3.5+:

diff -r f8c37677f484 -r 7087a8f4114e libcloud/httplib_ssl.py
--- a/libcloud/httplib_ssl.py   Wed Jul 13 14:23:41 2016 +0000
+++ b/libcloud/httplib_ssl.py   Thu Jul 14 13:00:47 2016 -0500
@@ -231,6 +231,10 @@
         # -redacted-
         verify_ssl_cert = kwargs.pop('verify_ssl_cert', None)
         self._setup_verify(verify_ssl_cert)
+        if not self.verify:
+            context = ssl.SSLContext (ssl.PROTOCOL_SSLv23)
+            context.check_hostname = False
+            kwargs['context'] = context

         # Support for HTTP proxy
         proxy_url_env = os.environ.get(HTTP_PROXY_ENV_VARIABLE_NAME, None)

Reply via email to