Enable SSL for EC2Tokens.
When keystone is deployed behind SSL, the ec2_authtoken options doesn't have a way to include the same SSL options that the various clients use, so it's not possible to authenticate tokens. Capability to handle SSL options is added. ec2token makes use of HTTP request object from httplib. Config options to specify CA file, client side certificate, key file and "verify server certificate option" will be listed under "ec2authtoken" group in conf file. Change-Id: Ibede73a17ae951cff00a7d9629a4c08f82208139 Closes-Bug: #1415223
This commit is contained in:
parent
fb32508af5
commit
11d04c8d6a
@ -39,7 +39,21 @@ opts = [
|
||||
default=[],
|
||||
help=_('Allowed keystone endpoints for auth_uri when '
|
||||
'multi_cloud is enabled. At least one endpoint needs '
|
||||
'to be specified.'))
|
||||
'to be specified.')),
|
||||
cfg.StrOpt('cert_file',
|
||||
default=None,
|
||||
help=_('Optional PEM-formatted certificate chain file.')),
|
||||
cfg.StrOpt('key_file',
|
||||
default=None,
|
||||
help=_('Optional PEM-formatted file that contains the '
|
||||
'private key.')),
|
||||
cfg.StrOpt('ca_file',
|
||||
default=None,
|
||||
help=_('Optional CA cert file to use in SSL connections.')),
|
||||
cfg.BoolOpt('insecure',
|
||||
default=False,
|
||||
help=_('If set, then the server\'s certificate will not '
|
||||
'be verified.')),
|
||||
]
|
||||
cfg.CONF.register_opts(opts, group='ec2authtoken')
|
||||
|
||||
@ -50,6 +64,7 @@ class EC2Token(wsgi.Middleware):
|
||||
def __init__(self, app, conf):
|
||||
self.conf = conf
|
||||
self.application = app
|
||||
self._ssl_options = None
|
||||
|
||||
def _conf_get(self, name):
|
||||
# try config from paste-deploy first
|
||||
@ -131,6 +146,19 @@ class EC2Token(wsgi.Middleware):
|
||||
last_failure = e
|
||||
raise last_failure or exception.HeatAccessDeniedError()
|
||||
|
||||
@property
|
||||
def ssl_options(self):
|
||||
if not self._ssl_options:
|
||||
cacert = self._conf_get('ca_file')
|
||||
insecure = self._conf_get('insecure')
|
||||
cert = self._conf_get('cert_file')
|
||||
key = self._conf_get('key_file')
|
||||
self._ssl_options = {
|
||||
'verify': cacert if cacert else not insecure,
|
||||
'cert': (cert, key) if cert else None
|
||||
}
|
||||
return self._ssl_options
|
||||
|
||||
def _authorize(self, req, auth_uri):
|
||||
# Read request signature and access id.
|
||||
# If we find X-Auth-User in the headers we ignore a key error
|
||||
@ -185,7 +213,9 @@ class EC2Token(wsgi.Middleware):
|
||||
keystone_ec2_uri = self._conf_get_keystone_ec2_uri(auth_uri)
|
||||
LOG.info(_LI('Authenticating with %s'), keystone_ec2_uri)
|
||||
response = requests.post(keystone_ec2_uri, data=creds_json,
|
||||
headers=headers)
|
||||
headers=headers,
|
||||
verify=self.ssl_options['verify'],
|
||||
cert=self.ssl_options['cert'])
|
||||
result = response.json()
|
||||
try:
|
||||
token_id = result['access']['token']['id']
|
||||
|
@ -60,6 +60,34 @@ class Ec2TokenTest(common.HeatTestCase):
|
||||
'http://192.0.2.9/v2.0/ec2tokens',
|
||||
ec2._conf_get_keystone_ec2_uri('http://192.0.2.9/v2.0/'))
|
||||
|
||||
def test_conf_get_ssl_default_options(self):
|
||||
ec2 = ec2token.EC2Token(app=None, conf={})
|
||||
self.assertTrue(ec2.ssl_options['verify'],
|
||||
"SSL verify should be True by default")
|
||||
self.assertIsNone(ec2.ssl_options['cert'],
|
||||
"SSL client cert should be None by default")
|
||||
|
||||
def test_conf_ssl_insecure_option(self):
|
||||
ec2 = ec2token.EC2Token(app=None, conf={})
|
||||
cfg.CONF.set_default('insecure', 'True', group='ec2authtoken')
|
||||
cfg.CONF.set_default('ca_file', None, group='ec2authtoken')
|
||||
self.assertFalse(ec2.ssl_options['verify'])
|
||||
|
||||
def test_conf_get_ssl_opts(self):
|
||||
cfg.CONF.set_default('auth_uri', 'https://192.0.2.9/v2.0/',
|
||||
group='ec2authtoken')
|
||||
cfg.CONF.set_default('ca_file', '/home/user/cacert.pem',
|
||||
group='ec2authtoken')
|
||||
cfg.CONF.set_default('insecure', 'false', group='ec2authtoken')
|
||||
cfg.CONF.set_default('cert_file', '/home/user/mycert',
|
||||
group='ec2authtoken')
|
||||
cfg.CONF.set_default('key_file', '/home/user/mykey',
|
||||
group='ec2authtoken')
|
||||
ec2 = ec2token.EC2Token(app=None, conf={})
|
||||
self.assertEqual('/home/user/cacert.pem', ec2.ssl_options['verify'])
|
||||
self.assertEqual(('/home/user/mycert', '/home/user/mykey'),
|
||||
ec2.ssl_options['cert'])
|
||||
|
||||
def test_get_signature_param_old(self):
|
||||
params = {'Signature': 'foo'}
|
||||
dummy_req = self._dummy_GET_request(params)
|
||||
@ -183,7 +211,8 @@ class Ec2TokenTest(common.HeatTestCase):
|
||||
self.assertEqual('xyz', ec2.__call__(dummy_req))
|
||||
|
||||
def _stub_http_connection(self, headers=None, params=None, response=None,
|
||||
req_url='http://123:5000/v2.0/ec2tokens'):
|
||||
req_url='http://123:5000/v2.0/ec2tokens',
|
||||
verify=True, cert=None):
|
||||
|
||||
headers = headers or {}
|
||||
params = params or {}
|
||||
@ -206,7 +235,7 @@ class Ec2TokenTest(common.HeatTestCase):
|
||||
"path": "/v1",
|
||||
"body_hash": body_hash}})
|
||||
req_headers = {'Content-Type': 'application/json'}
|
||||
requests.post(req_url, data=req_creds,
|
||||
requests.post(req_url, data=req_creds, verify=verify, cert=cert,
|
||||
headers=req_headers).AndReturn(DummyHTTPResponse())
|
||||
|
||||
def test_call_ok(self):
|
||||
|
Loading…
Reference in New Issue
Block a user