blob: 4c589f3a7a7214ae2051f38f32722f869776e3c6 [file] [log] [blame]
#!/usr/bin/env python
"""
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import httplib
import ssl
import socket
import urllib2
from ambari_commons.logging_utils import print_warning_msg
from resource_management.core.exceptions import Fail
# overrides default httplib.HTTPSConnection implementation to use specified ssl version
class HTTPSConnectionWithCustomSslVersion(httplib.HTTPSConnection):
def __init__(self, host, port, ssl_version, **kwargs):
httplib.HTTPSConnection.__init__(self, host, port, **kwargs)
self.ssl_version = ssl_version
def connect(self):
conn_socket = socket.create_connection((self.host, self.port),
self.timeout)
if getattr(self, '_tunnel_host', None):
self.sock = conn_socket
self._tunnel()
self.sock = ssl.wrap_socket(conn_socket, self.key_file, self.cert_file,
ssl_version=self.ssl_version)
def get_http_connection(host, port, https_enabled=False, ca_certs=None):
if https_enabled:
ssl_version = ssl.PROTOCOL_SSLv23
if ca_certs:
ssl_version = check_ssl_certificate_and_return_ssl_version(host, port, ca_certs)
return HTTPSConnectionWithCustomSslVersion(host, port, ssl_version)
else:
return httplib.HTTPConnection(host, port)
def check_ssl_certificate_and_return_ssl_version(host, port, ca_certs):
try:
# Try with TLSv1 first.
ssl_version = ssl.PROTOCOL_TLSv1
ssl.get_server_certificate((host, port), ssl_version=ssl_version, ca_certs=ca_certs)
except ssl.SSLError as ssl_error:
print_warning_msg("Failed to verify the SSL certificate for https://{0}:{1} with CA certificate in {2} using ssl.PROTOCOL_TLSv1."
" Trying to use less secure ssl.PROTOCOL_SSLv23. Error : {3}".format(host, port, ca_certs, str(ssl_error)))
try:
# Try with SSLv23 only if TLSv1 failed.
ssl_version = ssl.PROTOCOL_SSLv23
ssl.get_server_certificate((host, port), ssl_version=ssl_version, ca_certs=ca_certs)
except ssl.SSLError as ssl_error:
raise Fail("Failed to verify the SSL certificate for https://{0}:{1} with CA certificate in {2}. Error : {3}"
.format(host, port, ca_certs, str(ssl_error)))
return ssl_version
def reconfigure_urllib2_opener(ignore_system_proxy=False):
"""
Reconfigure urllib opener
:type ignore_system_proxy bool
"""
if ignore_system_proxy:
proxy_handler = urllib2.ProxyHandler({})
opener = urllib2.build_opener(proxy_handler)
urllib2.install_opener(opener)