From 5bd4c2984d329625a2a8442b316fa235dbb88a3d Mon Sep 17 00:00:00 2001 From: Daniel Gollub Date: Wed, 26 Feb 2014 06:56:13 +0100 Subject: [PATCH] Replace httplib.HTTPSConnection in ec2_token httplib.HTTPSConnection is known to not verify SSL certificates in Python 2.x. Implementation got adapted to make use of the requests module instead. SSL Verification is from now on enabled by default. Can be disabled via an additional introduced configuration option: `keystone_ec2_insecure=True` SecurityImpact DocImpact Partial-Bug: 1188189 Change-Id: Ie6a6620685995add56f38dc34c9a0a733558146a --- etc/keystone.conf.sample | 16 +++++++++++++ keystone/middleware/ec2_token.py | 40 +++++++++++++++++++++----------- 2 files changed, 42 insertions(+), 14 deletions(-) diff --git a/etc/keystone.conf.sample b/etc/keystone.conf.sample index f7f5afcec5..4c5a3a6e68 100644 --- a/etc/keystone.conf.sample +++ b/etc/keystone.conf.sample @@ -309,6 +309,22 @@ # URL to get token from ec2 request. (string value) #keystone_ec2_url=http://localhost:5000/v2.0/ec2tokens +# Required if EC2 server requires client certificate. (string +# value) +#keystone_ec2_keyfile= + +# Client certificate key filename. Required if EC2 server +# requires client certificate. (string value) +#keystone_ec2_certfile= + +# A PEM encoded certificate authority to use when verifying +# HTTPS connections. Defaults to the system CAs. (string +# value) +#keystone_ec2_cafile= + +# Disable SSL certificate verification. (boolean value) +#keystone_ec2_insecure=false + # # Options defined in keystone.openstack.common.eventlet_backdoor diff --git a/keystone/middleware/ec2_token.py b/keystone/middleware/ec2_token.py index db5010c606..9d40ef84af 100644 --- a/keystone/middleware/ec2_token.py +++ b/keystone/middleware/ec2_token.py @@ -20,9 +20,8 @@ Starting point for routing EC2 requests. """ -from eventlet.green import httplib from oslo.config import cfg -from six.moves import urllib +import requests import webob.dec import webob.exc @@ -34,6 +33,16 @@ keystone_ec2_opts = [ cfg.StrOpt('keystone_ec2_url', default='http://localhost:5000/v2.0/ec2tokens', help='URL to get token from ec2 request.'), + cfg.StrOpt('keystone_ec2_keyfile', help='Required if EC2 server requires ' + 'client certificate.'), + cfg.StrOpt('keystone_ec2_certfile', help='Client certificate key ' + 'filename. Required if EC2 server requires client ' + 'certificate.'), + cfg.StrOpt('keystone_ec2_cafile', help='A PEM encoded certificate ' + 'authority to use when verifying HTTPS connections. Defaults ' + 'to the system CAs.'), + cfg.BoolOpt('keystone_ec2_insecure', default=False, help='Disable SSL ' + 'certificate verification.'), ] CONF = config.CONF @@ -71,23 +80,26 @@ class EC2Token(wsgi.Middleware): creds_json = jsonutils.dumps(creds) headers = {'Content-Type': 'application/json'} - # Disable 'has no x member' pylint error - # for httplib and urlparse - # pylint: disable-msg=E1101 - o = urllib.parse.urlparse(CONF.keystone_ec2_url) - if o.scheme == 'http': - conn = httplib.HTTPConnection(o.netloc) - else: - conn = httplib.HTTPSConnection(o.netloc) - conn.request('POST', o.path, body=creds_json, headers=headers) - response = conn.getresponse().read() - conn.close() + verify = True + if CONF.keystone_ec2_insecure: + verify = False + elif CONF.keystone_ec2_cafile: + verify = CONF.keystone_ec2_cafile + + cert = None + if CONF.keystone_ec2_certfile and CONF.keystone_ec2_keyfile: + cert = (CONF.keystone_ec2_certfile, CONF.keystone_ec2_keyfile) + elif CONF.keystone_ec2_certfile: + cert = CONF.keystone_ec2_certfile + + response = requests.post(CONF.keystone_ec2_url, data=creds_json, + headers=headers, verify=verify, cert=cert) # NOTE(vish): We could save a call to keystone by # having keystone return token, tenant, # user, and roles from this call. - result = jsonutils.loads(response) + result = response.json() try: token_id = result['access']['token']['id'] except (AttributeError, KeyError):