Skip to content

Commit

Permalink
Replace httplib.HTTPSConnection in ec2_token
Browse files Browse the repository at this point in the history
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
  • Loading branch information
gollub authored and Brant Knudson committed Mar 17, 2014
1 parent dc9370c commit 5bd4c29
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 14 deletions.
16 changes: 16 additions & 0 deletions etc/keystone.conf.sample
Original file line number Diff line number Diff line change
Expand Up @@ -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=<None>

# Client certificate key filename. Required if EC2 server
# requires client certificate. (string value)
#keystone_ec2_certfile=<None>

# A PEM encoded certificate authority to use when verifying
# HTTPS connections. Defaults to the system CAs. (string
# value)
#keystone_ec2_cafile=<None>

# Disable SSL certificate verification. (boolean value)
#keystone_ec2_insecure=false


#
# Options defined in keystone.openstack.common.eventlet_backdoor
Expand Down
40 changes: 26 additions & 14 deletions keystone/middleware/ec2_token.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@
"""

from eventlet.green import httplib
from oslo.config import cfg
from six.moves import urllib
import requests
import webob.dec
import webob.exc

Expand All @@ -34,6 +33,16 @@
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
Expand Down Expand Up @@ -71,23 +80,26 @@ def __call__(self, req):
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):
Expand Down

0 comments on commit 5bd4c29

Please sign in to comment.