diff --git a/CHANGELOG.md b/CHANGELOG.md index 4bba322ce1e61c765e16f058bd5cecd41e4f3da4..e1979d1cb3e24e369720188a0880d94ffee7a79e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.0.1] - 2022-02-28 + +### Changed +- Optional public key algorithms disabling by prefixing ssh-host with "RSA:" + + ## [1.0.0] - 2022-02-28 ### Changed diff --git a/passwordclient/legacy/__init__.py b/passwordclient/legacy/__init__.py index f2524d9803e1e24cda90a0270f4ab9480a36cda0..18a7814d3c096c6208a7a3d64c62210b3cea1662 100644 --- a/passwordclient/legacy/__init__.py +++ b/passwordclient/legacy/__init__.py @@ -36,7 +36,8 @@ Options: <ssh-user> Remote user on SSH host. - <ssh-host> Remote host to connect to. + <ssh-host> Remote host to connect to. If prefixed with "RSA:" then the SSH public key + algorithms will downgraded to `ssh-rsa`. <timeout> Timeout for SSH connection. If both --timeout and this option are given, this value takes priority. @@ -349,13 +350,19 @@ def run_command_old_style(ssh_user, ssh_host, ssh_command): client = paramiko.client.SSHClient() client.load_system_host_keys() + # SSH Hosts prefixed with "RSA:" connect with public key algorithms disabled + disabled_algorithms = None + if ssh_host[:4].upper() == 'RSA:': + ssh_host = ssh_host[4:] + disabled_algorithms = {'pubkeys': ['rsa-sha2-512', 'rsa-sha2-256']} + with contextlib.closing(client): try: # Connect and execute command # Public key algorithms need disabling in order to connect to old servers client.connect( hostname=ssh_host, username=ssh_user, timeout=settings.timeout, - disabled_algorithms={'pubkeys': ['rsa-sha2-512', 'rsa-sha2-256']} + disabled_algorithms=disabled_algorithms, ) except Exception: # Connection errors print a traceback only in debug mode diff --git a/setup.py b/setup.py index e9a8f11e2fbb47f03ff895c4f5977d0b31c25cac..58f1ac5ae6abf0cd9b99cdd4874c945a837fa5d9 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ def load_requirements(): setup( name='passwordclient', - version='1.0.0', + version='1.0.1', packages=find_packages(exclude=['tests']), install_requires=load_requirements(), entry_points={ diff --git a/tests/test_legacy_cli.py b/tests/test_legacy_cli.py index 260a1f8ad4fa71dbcc03c9b17fd0c0e613c4c6bc..cce5d64ea16c87b6201d50d2120a60ab25508d05 100644 --- a/tests/test_legacy_cli.py +++ b/tests/test_legacy_cli.py @@ -252,6 +252,22 @@ class SSHTestCase(BaseTestCase): self.assertEqual(ar.exception.code, 0) self.mock_client.connect.assert_called_with( hostname="some-host", username="some-user", timeout=15, + disabled_algorithms=None, + ) + self.mock_client.exec_command.assert_called_with("some-cmd") + + def test_connect_called_rsa(self): + """ + Parameters are passed to paramiko's connect() when ssh-host prefixed + with "RSA:" + + """ + self.argv_mock[2] = 'RSA:rsa-host' + with self.assertRaises(SystemExit) as ar: + legacy.main() + self.assertEqual(ar.exception.code, 0) + self.mock_client.connect.assert_called_with( + hostname="rsa-host", username="some-user", timeout=15, disabled_algorithms={'pubkeys': ['rsa-sha2-512', 'rsa-sha2-256']} ) self.mock_client.exec_command.assert_called_with("some-cmd")