Added metadata service encryption key retrieval
The encryption public key, if existent, will be used to encrypt the user password to be sent to the metadata service. By default, in case of OpenStack, the first public key set by the user will be used to encrypt the user password. This special method is needed by metadata services implementations which will not rely on the same behaviour, as the the encryption key can be set at another metadata endpoint. Partially implements: blueprint packet-metadata-suport Co-Authored-By: Paula Madalina Crismaru <pcrismaru@cloudbasesolutions.com> Change-Id: I8bfde766d74dcd09e659d09a33a12f6f50b36ed2
This commit is contained in:
parent
526d939240
commit
8dd0d9dbc3
@ -110,6 +110,19 @@ class BaseMetadataService(object):
|
||||
"""Get a list of space-stripped strings as public keys."""
|
||||
pass
|
||||
|
||||
def get_user_pwd_encryption_key(self):
|
||||
"""Get the user password encryption public key as a string.
|
||||
|
||||
The encryption public key, if existent, will be used to encrypt the
|
||||
user password to be sent to the metadata service.
|
||||
By default, the first public key set by the user
|
||||
will be used to encrypt the user password.
|
||||
|
||||
"""
|
||||
public_keys = self.get_public_keys()
|
||||
if public_keys:
|
||||
return list(public_keys)[0]
|
||||
|
||||
def get_network_details(self):
|
||||
"""Return a list of `NetworkDetails` objects.
|
||||
|
||||
|
@ -36,11 +36,6 @@ class SetUserPasswordPlugin(base.BasePlugin):
|
||||
enc_password = rsa.public_encrypt(password.encode())
|
||||
return base64.b64encode(enc_password)
|
||||
|
||||
def _get_ssh_public_key(self, service):
|
||||
public_keys = service.get_public_keys()
|
||||
if public_keys:
|
||||
return list(public_keys)[0]
|
||||
|
||||
def _get_password(self, service, shared_data):
|
||||
injected = False
|
||||
if CONF.inject_user_password:
|
||||
@ -63,10 +58,10 @@ class SetUserPasswordPlugin(base.BasePlugin):
|
||||
'and it cannot be updated in the instance metadata')
|
||||
return True
|
||||
else:
|
||||
ssh_pub_key = self._get_ssh_public_key(service)
|
||||
if ssh_pub_key:
|
||||
enc_password_b64 = self._encrypt_password(ssh_pub_key,
|
||||
password)
|
||||
user_pwd_encryption_key = service.get_user_pwd_encryption_key()
|
||||
if user_pwd_encryption_key:
|
||||
enc_password_b64 = self._encrypt_password(
|
||||
user_pwd_encryption_key, password)
|
||||
return service.post_password(enc_password_b64)
|
||||
else:
|
||||
LOG.info('No SSH public key available for password encryption')
|
||||
|
@ -54,6 +54,13 @@ class TestBase(unittest.TestCase):
|
||||
def test_is_password_changed(self):
|
||||
self.assertFalse(self._service.is_password_changed())
|
||||
|
||||
@mock.patch('cloudbaseinit.metadata.services.base.'
|
||||
'BaseMetadataService.get_public_keys')
|
||||
def test_get_user_pwd_encryption_key(self, mock_get_public_keys):
|
||||
mock_get_public_keys.return_value = ['fake', 'keys']
|
||||
result = self._service.get_user_pwd_encryption_key()
|
||||
self.assertEqual(result, mock_get_public_keys.return_value[0])
|
||||
|
||||
|
||||
class TestBaseHTTPMetadataService(unittest.TestCase):
|
||||
|
||||
|
@ -57,22 +57,6 @@ class SetUserPasswordPluginTests(unittest.TestCase):
|
||||
mock_b64encode.assert_called_with('public encrypted')
|
||||
self.assertEqual('encrypted password', response)
|
||||
|
||||
def _test_get_ssh_public_key(self, data_exists):
|
||||
mock_service = mock.MagicMock()
|
||||
public_keys = self.fake_data['public_keys']
|
||||
mock_service.get_public_keys.return_value = public_keys.values()
|
||||
|
||||
response = self._setpassword_plugin._get_ssh_public_key(mock_service)
|
||||
|
||||
mock_service.get_public_keys.assert_called_with()
|
||||
self.assertEqual(list(public_keys.values())[0], response)
|
||||
|
||||
def test_get_ssh_plublic_key(self):
|
||||
self._test_get_ssh_public_key(data_exists=True)
|
||||
|
||||
def test_get_ssh_plublic_key_no_pub_keys(self):
|
||||
self._test_get_ssh_public_key(data_exists=False)
|
||||
|
||||
def _test_get_password(self, inject_password):
|
||||
shared_data = {}
|
||||
expected_password = 'Passw0rd'
|
||||
@ -112,18 +96,16 @@ class SetUserPasswordPluginTests(unittest.TestCase):
|
||||
def test_get_password_inject_false(self):
|
||||
self._test_get_password(inject_password=False)
|
||||
|
||||
@mock.patch('cloudbaseinit.plugins.common.setuserpassword.'
|
||||
'SetUserPasswordPlugin._get_ssh_public_key')
|
||||
@mock.patch('cloudbaseinit.plugins.common.setuserpassword.'
|
||||
'SetUserPasswordPlugin._encrypt_password')
|
||||
def _test_set_metadata_password(self, mock_encrypt_password,
|
||||
mock_get_key, ssh_pub_key):
|
||||
ssh_pub_key):
|
||||
fake_passw0rd = 'fake Passw0rd'
|
||||
mock_service = mock.MagicMock()
|
||||
mock_get_key.return_value = ssh_pub_key
|
||||
mock_encrypt_password.return_value = 'encrypted password'
|
||||
mock_service.post_password.return_value = 'value'
|
||||
mock_service.can_post_password = True
|
||||
mock_service.get_user_pwd_encryption_key.return_value = ssh_pub_key
|
||||
mock_service.is_password_set = False
|
||||
with testutils.LogSnatcher('cloudbaseinit.plugins.common.'
|
||||
'setuserpassword') as snatcher:
|
||||
@ -137,7 +119,6 @@ class SetUserPasswordPluginTests(unittest.TestCase):
|
||||
]
|
||||
self.assertTrue(response)
|
||||
else:
|
||||
mock_get_key.assert_called_once_with(mock_service)
|
||||
mock_encrypt_password.assert_called_once_with(ssh_pub_key,
|
||||
fake_passw0rd)
|
||||
mock_service.post_password.assert_called_with(
|
||||
|
Loading…
x
Reference in New Issue
Block a user