Skip to content

Commit

Permalink
Merge branch 'ssl_cert_verification' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
garnaat committed Sep 19, 2012
2 parents f7b10ee + 2429168 commit de97481
Show file tree
Hide file tree
Showing 63 changed files with 1,315 additions and 284 deletions.
2 changes: 1 addition & 1 deletion boto/cloudformation/__init__.py
Expand Up @@ -15,7 +15,7 @@
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
Expand Down
5 changes: 3 additions & 2 deletions boto/cloudformation/connection.py
Expand Up @@ -50,7 +50,7 @@ def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
is_secure=True, port=None, proxy=None, proxy_port=None,
proxy_user=None, proxy_pass=None, debug=0,
https_connection_factory=None, region=None, path='/',
converter=None, security_token=None):
converter=None, security_token=None, validate_certs=True):
if not region:
region = RegionInfo(self, self.DefaultRegionName,
self.DefaultRegionEndpoint, CloudFormationConnection)
Expand All @@ -61,7 +61,8 @@ def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
proxy_user, proxy_pass,
self.region.endpoint, debug,
https_connection_factory, path,
security_token)
security_token,
validate_certs=validate_certs)

def _required_auth_capability(self):
return ['hmac-v4']
Expand Down
6 changes: 4 additions & 2 deletions boto/cloudfront/__init__.py
Expand Up @@ -42,11 +42,13 @@ class CloudFrontConnection(AWSAuthConnection):

def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
port=None, proxy=None, proxy_port=None,
host=DefaultHost, debug=0, security_token=None):
host=DefaultHost, debug=0, security_token=None,
validate_certs=True):
AWSAuthConnection.__init__(self, host,
aws_access_key_id, aws_secret_access_key,
True, port, proxy, proxy_port, debug=debug,
security_token=security_token)
security_token=security_token,
validate_certs=validate_certs)

def get_etag(self, response):
response_headers = response.msg
Expand Down
6 changes: 4 additions & 2 deletions boto/cloudsearch/layer1.py
Expand Up @@ -45,7 +45,8 @@ def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
proxy=None, proxy_port=None,
proxy_user=None, proxy_pass=None, debug=0,
https_connection_factory=None, region=None, path='/',
api_version=None, security_token=None):
api_version=None, security_token=None,
validate_certs=True):
if not region:
region = RegionInfo(self, self.DefaultRegionName,
self.DefaultRegionEndpoint)
Expand All @@ -56,7 +57,8 @@ def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
proxy_user, proxy_pass,
self.region.endpoint, debug,
https_connection_factory, path,
security_token)
security_token,
validate_certs=validate_certs)

def _required_auth_capability(self):
return ['sign-v2']
Expand Down
6 changes: 4 additions & 2 deletions boto/cloudsearch/layer2.py
Expand Up @@ -30,10 +30,12 @@ class Layer2(object):

def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
is_secure=True, port=None, proxy=None, proxy_port=None,
host=None, debug=0, session_token=None, region=None):
host=None, debug=0, session_token=None, region=None,
validate_certs=True):
self.layer1 = Layer1(aws_access_key_id, aws_secret_access_key,
is_secure, port, proxy, proxy_port,
host, debug, session_token, region)
host, debug, session_token, region,
validate_certs=validate_certs)

def list_domains(self, domain_names=None):
"""
Expand Down
63 changes: 40 additions & 23 deletions boto/connection.py
@@ -1,4 +1,5 @@
# Copyright (c) 2006-2010 Mitch Garnaat http://garnaat.org/
# Copyright (c) 2006-2012 Mitch Garnaat http://garnaat.org/
# Copyright (c) 2012 Amazon.com, Inc. or its affiliates.
# Copyright (c) 2010 Google
# Copyright (c) 2008 rPath, Inc.
# Copyright (c) 2009 The Echo Nest Corporation
Expand Down Expand Up @@ -53,7 +54,8 @@
import socket
import sys
import time
import urllib, urlparse
import urllib
import urlparse
import xml.sax
import copy

Expand Down Expand Up @@ -88,10 +90,11 @@
ON_APP_ENGINE = all(key in os.environ for key in (
'USER_IS_ADMIN', 'CURRENT_VERSION_ID', 'APPLICATION_ID'))

PORTS_BY_SECURITY = { True: 443, False: 80 }
PORTS_BY_SECURITY = {True: 443,
False: 80}

DEFAULT_CA_CERTS_FILE = os.path.join(os.path.dirname(os.path.abspath(boto.cacerts.__file__ )), "cacerts.txt")

DEFAULT_CA_CERTS_FILE = os.path.join(
os.path.dirname(os.path.abspath(boto.cacerts.__file__ )), "cacerts.txt")

class HostConnectionPool(object):

Expand Down Expand Up @@ -171,7 +174,7 @@ def _conn_ready(self, conn):
state we care about isn't available in any public methods.
"""
if ON_APP_ENGINE:
# Google App Engine implementation of HTTPConnection doesn't contain
# Google AppEngine implementation of HTTPConnection doesn't contain
# _HTTPConnection__response attribute. Moreover, it's not possible
# to determine if given connection is ready. Reusing connections
# simply doesn't make sense with App Engine urlfetch service.
Expand All @@ -198,6 +201,7 @@ def _pair_stale(self, pair):
now = time.time()
return return_time + ConnectionPool.STALE_DURATION < now


class ConnectionPool(object):

"""
Expand Down Expand Up @@ -298,6 +302,7 @@ def clean(self):
del self.host_to_pool[host]
self.last_clean_time = now


class HTTPRequest(object):

def __init__(self, method, protocol, host, port, path, auth_path,
Expand All @@ -315,26 +320,26 @@ def __init__(self, method, protocol, host, port, path, auth_path,
:type port: int
:param port: port on which the request is being sent. Zero means unset,
in which case default port will be chosen.
in which case default port will be chosen.
:type path: string
:param path: URL path that is being accessed.
:type auth_path: string
:param path: The part of the URL path used when creating the
authentication string.
authentication string.
:type params: dict
:param params: HTTP url query parameters, with key as name of the param,
and value as value of param.
:param params: HTTP url query parameters, with key as name of
the param, and value as value of param.
:type headers: dict
:param headers: HTTP headers, with key as name of the header and value
as value of header.
as value of header.
:type body: string
:param body: Body of the HTTP request. If not present, will be None or
empty string ('').
empty string ('').
"""
self.method = method
self.protocol = protocol
Expand Down Expand Up @@ -408,12 +413,14 @@ def read(self, amt=None):


class AWSAuthConnection(object):
def __init__(self, host, aws_access_key_id=None, aws_secret_access_key=None,
def __init__(self, host, aws_access_key_id=None,
aws_secret_access_key=None,
is_secure=True, port=None, proxy=None, proxy_port=None,
proxy_user=None, proxy_pass=None, debug=0,
https_connection_factory=None, path='/',
provider='aws', security_token=None,
suppress_consec_slashes=True):
suppress_consec_slashes=True,
validate_certs=True):
"""
:type host: str
:param host: The host to make the connection to
Expand All @@ -430,9 +437,8 @@ def __init__(self, host, aws_access_key_id=None, aws_secret_access_key=None,
:type https_connection_factory: list or tuple
:param https_connection_factory: A pair of an HTTP connection
factory and the exceptions to catch.
The factory should have a similar
interface to L{httplib.HTTPSConnection}.
factory and the exceptions to catch. The factory should have
a similar interface to L{httplib.HTTPSConnection}.
:param str proxy: Address/hostname for a proxy server
Expand All @@ -451,17 +457,24 @@ def __init__(self, host, aws_access_key_id=None, aws_secret_access_key=None,
:type suppress_consec_slashes: bool
:param suppress_consec_slashes: If provided, controls whether
consecutive slashes will be suppressed in key paths.
:type validate_certs: bool
:param validate_certs: Controls whether SSL certificates
will be validated or not. Defaults to True.
"""
self.suppress_consec_slashes = suppress_consec_slashes
self.num_retries = 6
# Override passed-in is_secure setting if value was defined in config.
if config.has_option('Boto', 'is_secure'):
is_secure = config.getboolean('Boto', 'is_secure')
self.is_secure = is_secure
# Whether or not to validate server certificates. At some point in the
# future, the default should be flipped to true.
# Whether or not to validate server certificates.
# The default is now to validate certificates. This can be
# overridden in the boto config file are by passing an
# explicit validate_certs parameter to the class constructor.
self.https_validate_certificates = config.getbool(
'Boto', 'https_validate_certificates', False)
'Boto', 'https_validate_certificates',
validate_certs)
if self.https_validate_certificates and not HAVE_HTTPS_CONNECTION:
raise BotoClientError(
"SSL server certificate validation is enabled in boto "
Expand Down Expand Up @@ -717,7 +730,8 @@ def proxy_ssl(self):
# been generated by the socket library
raise socket.error(-71,
"Error talking to HTTP proxy %s:%s: %s (%s)" %
(self.proxy, self.proxy_port, resp.status, resp.reason))
(self.proxy, self.proxy_port,
resp.status, resp.reason))

# We can safely close the response, it duped the original socket
resp.close()
Expand Down Expand Up @@ -899,6 +913,7 @@ def close(self):
boto.log.debug('closing all HTTP connections')
self._connection = None # compat field


class AWSQueryConnection(AWSAuthConnection):

APIVersion = ''
Expand All @@ -907,13 +922,15 @@ class AWSQueryConnection(AWSAuthConnection):
def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
is_secure=True, port=None, proxy=None, proxy_port=None,
proxy_user=None, proxy_pass=None, host=None, debug=0,
https_connection_factory=None, path='/', security_token=None):
https_connection_factory=None, path='/', security_token=None,
validate_certs=True):
AWSAuthConnection.__init__(self, host, aws_access_key_id,
aws_secret_access_key,
is_secure, port, proxy,
proxy_port, proxy_user, proxy_pass,
debug, https_connection_factory, path,
security_token=security_token)
security_token=security_token,
validate_certs=validate_certs)

def _required_auth_capability(self):
return []
Expand Down
2 changes: 1 addition & 1 deletion boto/dynamodb/__init__.py
Expand Up @@ -21,7 +21,7 @@
# IN THE SOFTWARE.
#

from boto.ec2.regioninfo import RegionInfo
from boto.regioninfo import RegionInfo


def regions():
Expand Down
6 changes: 4 additions & 2 deletions boto/dynamodb/layer1.py
Expand Up @@ -80,7 +80,8 @@ class Layer1(AWSAuthConnection):

def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
is_secure=True, port=None, proxy=None, proxy_port=None,
debug=0, security_token=None, region=None):
debug=0, security_token=None, region=None,
validate_certs=True):
if not region:
region_name = boto.config.get('DynamoDB', 'region',
self.DefaultRegionName)
Expand All @@ -94,7 +95,8 @@ def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
aws_access_key_id,
aws_secret_access_key,
is_secure, port, proxy, proxy_port,
debug=debug, security_token=security_token)
debug=debug, security_token=security_token,
validate_certs=validate_certs)
self.throughput_exceeded_events = 0

def _get_session_token(self):
Expand Down
6 changes: 4 additions & 2 deletions boto/dynamodb/layer2.py
Expand Up @@ -112,10 +112,12 @@ class Layer2(object):

def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
is_secure=True, port=None, proxy=None, proxy_port=None,
debug=0, security_token=None, region=None):
debug=0, security_token=None, region=None,
validate_certs=True):
self.layer1 = Layer1(aws_access_key_id, aws_secret_access_key,
is_secure, port, proxy, proxy_port,
debug, security_token, region)
debug, security_token, region,
validate_certs=validate_certs)

def dynamize_attribute_updates(self, pending_updates):
"""
Expand Down
28 changes: 6 additions & 22 deletions boto/ec2/__init__.py
Expand Up @@ -14,7 +14,7 @@
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
Expand All @@ -25,29 +25,31 @@
"""
from boto.ec2.connection import EC2Connection


def regions(**kw_params):
"""
Get all available regions for the EC2 service.
You may pass any of the arguments accepted by the EC2Connection
object's constructor as keyword arguments and they will be
passed along to the EC2Connection object.
:rtype: list
:return: A list of :class:`boto.ec2.regioninfo.RegionInfo`
"""
c = EC2Connection(**kw_params)
return c.get_all_regions()


def connect_to_region(region_name, **kw_params):
"""
Given a valid region name, return a
Given a valid region name, return a
:class:`boto.ec2.connection.EC2Connection`.
Any additional parameters after the region_name are passed on to
the connect method of the region object.
:type: str
:param region_name: The name of the region to connect to.
:rtype: :class:`boto.ec2.connection.EC2Connection` or ``None``
:return: A connection to the given region, or None if an invalid region
name is given
Expand All @@ -56,21 +58,3 @@ def connect_to_region(region_name, **kw_params):
if region.name == region_name:
return region.connect(**kw_params)
return None

def get_region(region_name, **kw_params):
"""
Find and return a :class:`boto.ec2.regioninfo.RegionInfo` object
given a region name.
:type: str
:param: The name of the region.
:rtype: :class:`boto.ec2.regioninfo.RegionInfo`
:return: The RegionInfo object for the given region or None if
an invalid region name is provided.
"""
for region in regions(**kw_params):
if region.name == region_name:
return region
return None

5 changes: 3 additions & 2 deletions boto/ec2/autoscale/__init__.py
Expand Up @@ -98,7 +98,7 @@ def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
is_secure=True, port=None, proxy=None, proxy_port=None,
proxy_user=None, proxy_pass=None, debug=0,
https_connection_factory=None, region=None, path='/',
security_token=None):
security_token=None, validate_certs=True):
"""
Init method to create a new connection to the AutoScaling service.
Expand All @@ -116,7 +116,8 @@ def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
proxy_user, proxy_pass,
self.region.endpoint, debug,
https_connection_factory, path=path,
security_token=security_token)
security_token=security_token,
validate_certs=validate_certs)

def _required_auth_capability(self):
return ['hmac-v4']
Expand Down

0 comments on commit de97481

Please sign in to comment.