Commit 2a2faa29 authored by Stavros Sachtouris's avatar Stavros Sachtouris

Handle SSL unicode bug with grace

Fixes grnet/kamaki#67

SSL module breaks when dealing with non-ascii filenames (known bug).
Catch the Unicode error when it occurs and add an instructive error
message for the kamaki library users.
Check the file name for validity when it is set and inform the kamaki
CLI users.
parent 3fc52244
...@@ -15,6 +15,7 @@ Bug fixes ...@@ -15,6 +15,7 @@ Bug fixes
[grnet/kamaki#71] [grnet/kamaki#71]
* Handle non-ascii characters when managing configuration options * Handle non-ascii characters when managing configuration options
[grnet/kamaki#76] [grnet/kamaki#76]
* Handle SSL unicode bug with grace [grnet/kamaki#67]
v0.13rc5 v0.13rc5
======== ========
......
...@@ -235,7 +235,17 @@ def _init_session(arguments, is_non_api=False): ...@@ -235,7 +235,17 @@ def _init_session(arguments, is_non_api=False):
_cnf.get('global', 'ignore_ssl').lower() == 'on') _cnf.get('global', 'ignore_ssl').lower() == 'on')
if ca_file: if ca_file:
https.patch_with_certs(ca_file) try:
https.patch_with_certs(ca_file)
except https.SSLUnicodeError as sslu:
raise CLIError(
'Failed to set CA certificates file %s' % ca_file,
importance=2, details=[
'SSL module cannot handle non-ascii file names',
'Check the file path and consider moving and renaming',
'To set the new CA certificates path',
' kamaki config set ca_certs CA_FILE',
sslu, ])
else: else:
warn = red('CA certifications path not set (insecure) ') warn = red('CA certifications path not set (insecure) ')
kloger.warning(warn) kloger.warning(warn)
......
...@@ -40,6 +40,10 @@ from objpool import http ...@@ -40,6 +40,10 @@ from objpool import http
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class SSLUnicodeError(ssl.SSLError):
"""SSL module cannot handle unicode file names"""
class HTTPSClientAuthConnection(httplib.HTTPSConnection): class HTTPSClientAuthConnection(httplib.HTTPSConnection):
"""HTTPS connection, with full client-based SSL Authentication support""" """HTTPS connection, with full client-based SSL Authentication support"""
...@@ -50,7 +54,11 @@ class HTTPSClientAuthConnection(httplib.HTTPSConnection): ...@@ -50,7 +54,11 @@ class HTTPSClientAuthConnection(httplib.HTTPSConnection):
:param ca_file: path to CA certificates bundle (default: None) :param ca_file: path to CA certificates bundle (default: None)
:param ignore_ssl: flag (default: False) :param ignore_ssl: flag (default: False)
""" """
self.ca_file = kwargs.pop('ca_file', self.ca_file) try:
self.ca_file = str(kwargs.pop('ca_file', self.ca_file))
except UnicodeError as ue:
raise SSLUnicodeError(0, SSLUnicodeError.__doc__, ue)
self.ignore_ssl = kwargs.pop('ignore_ssl', self.ignore_ssl) self.ignore_ssl = kwargs.pop('ignore_ssl', self.ignore_ssl)
httplib.HTTPSConnection.__init__(self, *args, **kwargs) httplib.HTTPSConnection.__init__(self, *args, **kwargs)
...@@ -72,13 +80,17 @@ class HTTPSClientAuthConnection(httplib.HTTPSConnection): ...@@ -72,13 +80,17 @@ class HTTPSClientAuthConnection(httplib.HTTPSConnection):
self.sock = sock self.sock = sock
self._tunnel() self._tunnel()
if self.ignore_ssl: try:
self.sock = ssl.wrap_socket( if self.ignore_ssl:
sock, self.key_file, self.cert_file, cert_reqs=ssl.CERT_NONE) self.sock = ssl.wrap_socket(
else: sock, self.key_file, self.cert_file,
self.sock = ssl.wrap_socket( cert_reqs=ssl.CERT_NONE)
sock, self.key_file, self.cert_file, else:
ca_certs=self.ca_file, cert_reqs=ssl.CERT_REQUIRED) self.sock = ssl.wrap_socket(
sock, self.key_file, self.cert_file,
ca_certs=self.ca_file, cert_reqs=ssl.CERT_REQUIRED)
except UnicodeError as ue:
raise SSLUnicodeError(0, SSLUnicodeError.__doc__, ue)
http.HTTPConnectionPool._scheme_to_class['https'] = HTTPSClientAuthConnection http.HTTPConnectionPool._scheme_to_class['https'] = HTTPSClientAuthConnection
...@@ -86,7 +98,10 @@ PooledHTTPConnection = http.PooledHTTPConnection ...@@ -86,7 +98,10 @@ PooledHTTPConnection = http.PooledHTTPConnection
def patch_with_certs(ca_file): def patch_with_certs(ca_file):
HTTPSClientAuthConnection.ca_file = ca_file try:
HTTPSClientAuthConnection.ca_file = str(ca_file)
except UnicodeError as ue:
raise SSLUnicodeError(0, SSLUnicodeError.__doc__, ue)
def patch_ignore_ssl(insecure_connection=True): def patch_ignore_ssl(insecure_connection=True):
......
Markdown is supported
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