This is an automated email from the ASF dual-hosted git repository.

tomaz pushed a commit to branch 2.8.x
in repository https://gitbox.apache.org/repos/asf/libcloud.git

commit 88cbb601839a6e2de3c2ed28b61a4d3460f0d997
Author: Tomaz Muraus <[email protected]>
AuthorDate: Tue Mar 31 23:38:37 2020 +0200

    Also correctly handle and abort on invalid encrypted key password.
---
 libcloud/compute/base.py                 |  3 ++-
 libcloud/compute/ssh.py                  |  8 +++++++-
 libcloud/test/compute/test_deployment.py |  3 ++-
 libcloud/test/compute/test_ssh_client.py | 21 +++++++++++++++++++++
 4 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/libcloud/compute/base.py b/libcloud/compute/base.py
index 0f555fc..5ccad79 100644
--- a/libcloud/compute/base.py
+++ b/libcloud/compute/base.py
@@ -1734,7 +1734,8 @@ class NodeDriver(BaseDriver):
                     'not a valid ',
                     'invalid or unsupported key type',
                     'private file is encrypted',
-                    'private key file is encrypted'
+                    'private key file is encrypted',
+                    'private key file checkints do not match'
                 ]
 
                 # Propagate (key) file doesn't exist errors
diff --git a/libcloud/compute/ssh.py b/libcloud/compute/ssh.py
index bacae1a..1fad910 100644
--- a/libcloud/compute/ssh.py
+++ b/libcloud/compute/ssh.py
@@ -555,7 +555,13 @@ class ParamikoSSHClient(BaseSSHClient):
                 key = cls.from_private_key(StringIO(key_value), passpharse)
             except paramiko.ssh_exception.PasswordRequiredException as e:
                 raise e
-            except (paramiko.ssh_exception.SSHException, AssertionError):
+            except (paramiko.ssh_exception.SSHException, AssertionError) as e:
+                if 'private key file checkints do not match' in str(e).lower():
+                    msg = ('Invalid passpharse provided for encrypted key. '
+                           'Original error: %s' % (str(e)))
+                    # Indicates invalid password for password protected keys
+                    raise paramiko.ssh_exception.SSHException(msg)
+
                 # Invalid key, try other key type
                 pass
             else:
diff --git a/libcloud/test/compute/test_deployment.py 
b/libcloud/test/compute/test_deployment.py
index e7aa9e0..54cb666 100644
--- a/libcloud/test/compute/test_deployment.py
+++ b/libcloud/test/compute/test_deployment.py
@@ -371,7 +371,8 @@ class DeploymentTests(unittest.TestCase):
 
         mock_exceptions = [
             SSHException('Invalid or unsupported key type'),
-            PasswordRequiredException('private key file is encrypted')
+            PasswordRequiredException('private key file is encrypted'),
+            SSHException('OpenSSH private key file checkints do not match')
         ]
 
         for mock_exception in mock_exceptions:
diff --git a/libcloud/test/compute/test_ssh_client.py 
b/libcloud/test/compute/test_ssh_client.py
index 1a323df..b308028 100644
--- a/libcloud/test/compute/test_ssh_client.py
+++ b/libcloud/test/compute/test_ssh_client.py
@@ -194,6 +194,27 @@ class ParamikoSSHClientTests(LibcloudTestCase):
                           expected_msg, mock.connect)
 
     @patch('paramiko.SSHClient', Mock)
+    def test_password_protected_key_no_password_provided(self):
+        path = os.path.join(os.path.dirname(__file__),
+                            'fixtures', 'misc',
+                            'test_rsa_2048b_pass_foobar.key')
+
+        # Supplied as key_material
+        with open(path, 'r') as fp:
+            private_key = fp.read()
+
+        conn_params = {'hostname': 'dummy.host.org',
+                       'username': 'ubuntu',
+                       'key_material': private_key,
+                       'password': 'invalid'}
+
+        mock = ParamikoSSHClient(**conn_params)
+
+        expected_msg = 'OpenSSH private key file checkints do not match'
+        assertRaisesRegex(self, paramiko.ssh_exception.SSHException,
+                          expected_msg, mock.connect)
+
+    @patch('paramiko.SSHClient', Mock)
     def test_password_protected_key_valid_password_provided(self):
         path = os.path.join(os.path.dirname(__file__),
                             'fixtures', 'misc',

Reply via email to