From 7f8afac092e44ca3c93350a73c7b9ff29a0642ba Mon Sep 17 00:00:00 2001 From: Iury Gregory Melo Ferreira Date: Wed, 18 Mar 2020 17:14:29 +0100 Subject: [PATCH] Use crypt to generate salt Let's use the crypt to generate the salt, the crypt.crypt can handle the generation of the salt if we don't pass. Change-Id: I63fca663940e44924a201b166bdd79d8f7710bee Story: 2007443 Task: 39103 --- ironic_python_agent/extensions/rescue.py | 15 +---------- .../tests/unit/extensions/test_rescue.py | 26 +++---------------- ...pt_generate_the_salt-99876591325275a1.yaml | 9 +++++++ 3 files changed, 14 insertions(+), 36 deletions(-) create mode 100644 releasenotes/notes/let_crypt_generate_the_salt-99876591325275a1.yaml diff --git a/ironic_python_agent/extensions/rescue.py b/ironic_python_agent/extensions/rescue.py index 6ec8a2f99..036a17f79 100644 --- a/ironic_python_agent/extensions/rescue.py +++ b/ironic_python_agent/extensions/rescue.py @@ -11,8 +11,6 @@ # limitations under the License. import crypt -import random -import string from oslo_log import log @@ -25,16 +23,6 @@ PASSWORD_FILE = '/etc/ipa-rescue-config/ipa-rescue-password' class RescueExtension(base.BaseAgentExtension): - def make_salt(self): - """Generate a random salt for hashing the rescue password. - - Salt should be a two-character string from the set [a-zA-Z0-9]. - - :returns: a valid salt for use with crypt.crypt - """ - allowed_chars = string.ascii_letters + string.digits - return random.choice(allowed_chars) + random.choice(allowed_chars) - def write_rescue_password(self, rescue_password="", hashed=False): """Write rescue password to a file for use after IPA exits. @@ -55,8 +43,7 @@ class RescueExtension(base.BaseAgentExtension): if hashed: hashed_password = password else: - salt = self.make_salt() - hashed_password = crypt.crypt(rescue_password, salt) + hashed_password = crypt.crypt(rescue_password) try: with open(PASSWORD_FILE, 'w') as f: f.write(hashed_password) diff --git a/ironic_python_agent/tests/unit/extensions/test_rescue.py b/ironic_python_agent/tests/unit/extensions/test_rescue.py index c7b4148b4..1d3b94561 100644 --- a/ironic_python_agent/tests/unit/extensions/test_rescue.py +++ b/ironic_python_agent/tests/unit/extensions/test_rescue.py @@ -10,8 +10,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import string - import mock from oslotest import base as test_base @@ -26,25 +24,16 @@ class TestRescueExtension(test_base.BaseTestCase): self.agent_extension = rescue.RescueExtension() self.agent_extension.agent = FakeAgent() - def test_make_salt(self): - salt = self.agent_extension.make_salt() - self.assertEqual(2, len(salt)) - for char in salt: - self.assertIn(char, string.ascii_letters + string.digits) - @mock.patch('ironic_python_agent.extensions.rescue.crypt.crypt', autospec=True) - @mock.patch('ironic_python_agent.extensions.rescue.RescueExtension.' - 'make_salt', autospec=True) - def test_write_rescue_password(self, mock_salt, mock_crypt): - mock_salt.return_value = '12' + def test_write_rescue_password(self, mock_crypt): mock_crypt.return_value = '12deadbeef' mock_open = mock.mock_open() with mock.patch('ironic_python_agent.extensions.rescue.open', mock_open): self.agent_extension.write_rescue_password('password') - mock_crypt.assert_called_once_with('password', '12') + mock_crypt.assert_called_once_with('password') mock_open.assert_called_once_with( '/etc/ipa-rescue-config/ipa-rescue-password', 'w') file_handle = mock_open() @@ -52,10 +41,7 @@ class TestRescueExtension(test_base.BaseTestCase): @mock.patch('ironic_python_agent.extensions.rescue.crypt.crypt', autospec=True) - @mock.patch('ironic_python_agent.extensions.rescue.RescueExtension.' - 'make_salt', autospec=True) - def test_write_rescue_password_ioerror(self, mock_salt, mock_crypt): - mock_salt.return_value = '12' + def test_write_rescue_password_ioerror(self, mock_crypt): mock_crypt.return_value = '12deadbeef' mock_open = mock.mock_open() with mock.patch('ironic_python_agent.extensions.rescue.open', @@ -68,16 +54,12 @@ class TestRescueExtension(test_base.BaseTestCase): @mock.patch('ironic_python_agent.extensions.rescue.crypt.crypt', autospec=True) - @mock.patch('ironic_python_agent.extensions.rescue.RescueExtension.' - 'make_salt', autospec=True) - def _write_password_hashed_test(self, password, mock_salt, - mock_crypt): + def _write_password_hashed_test(self, password, mock_crypt): mock_open = mock.mock_open() with mock.patch('ironic_python_agent.extensions.rescue.open', mock_open): self.agent_extension.write_rescue_password(password, hashed=True) - self.assertFalse(mock_salt.called) self.assertFalse(mock_crypt.called) mock_open.assert_called_once_with( '/etc/ipa-rescue-config/ipa-rescue-password', 'w') diff --git a/releasenotes/notes/let_crypt_generate_the_salt-99876591325275a1.yaml b/releasenotes/notes/let_crypt_generate_the_salt-99876591325275a1.yaml new file mode 100644 index 000000000..090ac56b9 --- /dev/null +++ b/releasenotes/notes/let_crypt_generate_the_salt-99876591325275a1.yaml @@ -0,0 +1,9 @@ +--- +security: + - | + The salt was generated using random and the module it's not in compliance + with FIPS 140-2. Now we let the salt be automatically generated by the + crypt function (it will use the strongest method available). +fixes: + - | + The salt now will be automatically generated by the crypt function.