You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by to...@apache.org on 2020/04/04 20:45:05 UTC
[libcloud] 03/21: Add support for Ed25519 key types when using
paramiko >= 2.2.0.
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 b3f36cd27a47dcce885a972f55b52c4e2eddf624
Author: Tomaz Muraus <to...@tomaz.me>
AuthorDate: Tue Mar 31 23:06:18 2020 +0200
Add support for Ed25519 key types when using paramiko >= 2.2.0.
---
libcloud/compute/ssh.py | 19 +++++++++---
libcloud/test/compute/test_ssh_client.py | 53 ++++++++++++++++++++++++++++++++
2 files changed, 68 insertions(+), 4 deletions(-)
diff --git a/libcloud/compute/ssh.py b/libcloud/compute/ssh.py
index 78718fe..fcc5d01 100644
--- a/libcloud/compute/ssh.py
+++ b/libcloud/compute/ssh.py
@@ -517,10 +517,20 @@ class ParamikoSSHClient(BaseSSHClient):
# NOTE: Paramiko only supports key in PKCS#1 PEM format.
"""
+ key_types = [
+ (paramiko.RSAKey, 'RSA'),
+ (paramiko.DSSKey, 'DSA'),
+ (paramiko.ECDSAKey, 'EC')
+ ]
- for cls, key_type in [(paramiko.RSAKey, 'RSA'),
- (paramiko.DSSKey, 'DSA'),
- (paramiko.ECDSAKey, 'EC')]:
+ paramiko_version = getattr(paramiko, '__version__', '0.0.0')
+ paramiko_version = tuple([int(c) for c in paramiko_version.split('.')])
+
+ if paramiko_version >= (2, 2, 0):
+ # Ed25519 is only supported in paramiko >= 2.2.0
+ key_types.append((paramiko.ed25519key.Ed25519Key, 'Ed25519'))
+
+ for cls, key_type in key_types:
# Work around for paramiko not recognizing keys which start with
# "----BEGIN PRIVATE KEY-----"
# Since key is already in PEM format, we just try changing the
@@ -546,7 +556,8 @@ class ParamikoSSHClient(BaseSSHClient):
else:
return key
- msg = ('Invalid or unsupported key type (only RSA, DSS and ECDSA keys'
+ msg = ('Invalid or unsupported key type (only RSA, DSS, ECDSA and'
+ ' Ed25519 keys'
' in PEM format are supported). For more information on '
' supported key file types, see %s' % (SUPPORTED_KEY_TYPES_URL))
raise paramiko.ssh_exception.SSHException(msg)
diff --git a/libcloud/test/compute/test_ssh_client.py b/libcloud/test/compute/test_ssh_client.py
index dc59df5..1a323df 100644
--- a/libcloud/test/compute/test_ssh_client.py
+++ b/libcloud/test/compute/test_ssh_client.py
@@ -183,6 +183,59 @@ class ParamikoSSHClientTests(LibcloudTestCase):
assertRaisesRegex(self, paramiko.ssh_exception.PasswordRequiredException,
expected_msg, mock.connect)
+ conn_params = {'hostname': 'dummy.host.org',
+ 'username': 'ubuntu',
+ 'key_files': path}
+
+ mock = ParamikoSSHClient(**conn_params)
+
+ expected_msg = 'private key file is encrypted'
+ assertRaisesRegex(self, paramiko.ssh_exception.PasswordRequiredException,
+ 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',
+ '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,
+ 'key_password': 'foobar'}
+
+ mock = ParamikoSSHClient(**conn_params)
+ self.assertTrue(mock.connect())
+
+ conn_params = {'hostname': 'dummy.host.org',
+ 'username': 'ubuntu',
+ 'key_files': path,
+ 'key_password': 'foobar'}
+
+ mock = ParamikoSSHClient(**conn_params)
+ self.assertTrue(mock.connect())
+
+ @patch('paramiko.SSHClient', Mock)
+ def test_ed25519_key_type(self):
+ path = os.path.join(os.path.dirname(__file__),
+ 'fixtures', 'misc',
+ 'test_ed25519.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}
+
+ mock = ParamikoSSHClient(**conn_params)
+ self.assertTrue(mock.connect())
+
def test_key_material_valid_pem_keys_invalid_header_auto_conversion(self):
# Test a scenario where valid PEM keys with invalid headers which is
# not recognized by paramiko are automatically converted in a format