From cf6b8420944da714093a9b90806826d193550a2f Mon Sep 17 00:00:00 2001 From: Panos Date: Thu, 28 Jan 2021 18:03:06 +0000 Subject: [PATCH] Ssh passwd auth (#277) * Fixed password authentication for ssh client. Added tests. * Simplify exceptions * Added pre-commit to dev requirements. Updated single clients * Updated changelog --- .circleci/config.yml | 9 ++++---- .pre-commit-config.yaml | 6 ++++++ Changelog.rst | 10 +++++++++ pssh/clients/native/single.py | 7 ++----- pssh/clients/ssh/single.py | 7 ++----- requirements_dev.txt | 1 + tests/native/test_single_client.py | 33 ++++++++++++++++++++---------- tests/ssh/test_single_client.py | 15 ++++++++++---- 8 files changed, 59 insertions(+), 29 deletions(-) create mode 100644 .pre-commit-config.yaml diff --git a/.circleci/config.yml b/.circleci/config.yml index 4ff9b9b0..90f85a98 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -20,6 +20,10 @@ jobs: name: Deps command: | sudo apt-get install openssh-server --fix-missing + - run: + command: | + pip install -U -r requirements_dev.txt + name: Build - python/save-cache: dependency-file: requirements_dev.txt key: depsv3-{{ .Branch }}.{{ arch }}-PY<< parameters.python_ver >> @@ -27,16 +31,13 @@ jobs: command: | python setup.py check --restructuredtext name: Check readme - - run: - command: | - pip install -U -r requirements_dev.txt - name: Build - run: command: | flake8 pssh name: flake - run: command: | + set -x eval "$(ssh-agent -s)" pytest --cov-append --cov=pssh tests/test_output.py tests/test_utils.py tests/test_host_config.py pytest --reruns 10 --cov-append --cov=pssh tests/native/test_tunnel.py tests/native/test_agent.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..891ef877 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,6 @@ +repos: + - repo: https://gitlab.com/pycqa/flake8 + rev: 3.7.9 + hooks: + - id: flake8 + exclude: ^[tests,doc,versioneer] diff --git a/Changelog.rst b/Changelog.rst index 4b27d86e..abc09571 100644 --- a/Changelog.rst +++ b/Changelog.rst @@ -1,6 +1,16 @@ Change Log ============ + +2.5.4 ++++++ + +Fixes +------ + +* Password authentication via ``pssh.clients.ssh`` would not work - #276 + + 2.5.3 +++++ diff --git a/pssh/clients/native/single.py b/pssh/clients/native/single.py index ceaaae31..fe3ee571 100644 --- a/pssh/clients/native/single.py +++ b/pssh/clients/native/single.py @@ -34,7 +34,7 @@ from ..base.single import BaseSSHClient from ...output import HostOutput from ...exceptions import SessionError, SFTPError, \ - SFTPIOError, Timeout, SCPError, ProxyError, AuthenticationError + SFTPIOError, Timeout, SCPError, ProxyError from ...constants import DEFAULT_RETRIES, RETRY_DELAY @@ -226,10 +226,7 @@ def _pkey_auth(self, pkey_file, password=None): passphrase=password if password is not None else b'') def _password_auth(self): - try: - self.session.userauth_password(self.user, self.password) - except Exception as ex: - raise AuthenticationError("Password authentication failed - %s", ex) + self.session.userauth_password(self.user, self.password) def _open_session(self): chan = self._eagain(self.session.open_session) diff --git a/pssh/clients/ssh/single.py b/pssh/clients/ssh/single.py index 8b048054..781f86e3 100644 --- a/pssh/clients/ssh/single.py +++ b/pssh/clients/ssh/single.py @@ -27,7 +27,7 @@ from ..base.single import BaseSSHClient from ..common import _validate_pkey_path from ...output import HostOutput -from ...exceptions import AuthenticationError, SessionError, Timeout +from ...exceptions import SessionError, Timeout from ...constants import DEFAULT_RETRIES, RETRY_DELAY @@ -168,10 +168,7 @@ def auth(self): return super(SSHClient, self).auth() def _password_auth(self): - try: - self.session.userauth_password(self.password) - except Exception as ex: - raise AuthenticationError("Password authentication failed - %s", ex) + self.session.userauth_password(self.user, self.password) def _pkey_auth(self, pkey_file, password=None): pkey = import_privkey_file(pkey_file, passphrase=password if password is not None else '') diff --git a/requirements_dev.txt b/requirements_dev.txt index 3389bb73..423ff31f 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -7,5 +7,6 @@ pytest<6.1.0 pytest-cov pytest-rerunfailures jinja2 +pre-commit -r requirements.txt -e . diff --git a/tests/native/test_single_client.py b/tests/native/test_single_client.py index da10472b..140b2d2d 100644 --- a/tests/native/test_single_client.py +++ b/tests/native/test_single_client.py @@ -26,12 +26,15 @@ from pssh.clients.native import SSHClient from ssh2.session import Session -from ssh2.exceptions import SocketDisconnectError, BannerRecvError, SocketRecvError, \ - AgentConnectionError, AgentListIdentitiesError, \ - AgentAuthenticationError, AgentGetIdentityError, SFTPProtocolError -from pssh.exceptions import AuthenticationException, ConnectionErrorException, \ - SessionError, SFTPIOError, SFTPError, SCPError, PKeyFileError, Timeout, \ - AuthenticationError +from ssh2.exceptions import (SocketDisconnectError, BannerRecvError, SocketRecvError, + AgentConnectionError, AgentListIdentitiesError, + AgentAuthenticationError, AgentGetIdentityError, SFTPProtocolError, + AuthenticationError as SSH2AuthenticationError, + ) +from pssh.exceptions import (AuthenticationException, ConnectionErrorException, + SessionError, SFTPIOError, SFTPError, SCPError, PKeyFileError, Timeout, + AuthenticationError, + ) from .base_ssh2_case import SSH2TestCase @@ -292,10 +295,16 @@ def test_identity_auth_failure(self): allow_agent=False) def test_password_auth_failure(self): - self.assertRaises(AuthenticationException, - SSHClient, self.host, port=self.port, num_retries=1, - allow_agent=False, - password='blah blah blah') + try: + client = SSHClient(self.host, port=self.port, num_retries=1, + allow_agent=False, + identity_auth=False, + password='blah blah blah', + ) + except AuthenticationException as ex: + self.assertIsInstance(ex.args[3], SSH2AuthenticationError) + else: + raise AssertionError def test_retry_failure(self): self.assertRaises(ConnectionErrorException, @@ -311,7 +320,9 @@ def test_auth_retry_failure(self): password='fake', num_retries=3, retry_delay=.1, - allow_agent=False) + allow_agent=False, + identity_auth=False, + ) def test_connection_timeout(self): cmd = spawn(SSHClient, 'fakehost.com', port=12345, diff --git a/tests/ssh/test_single_client.py b/tests/ssh/test_single_client.py index 19fc6691..5c4cfb28 100644 --- a/tests/ssh/test_single_client.py +++ b/tests/ssh/test_single_client.py @@ -200,10 +200,16 @@ def test_identity_auth_failure(self): allow_agent=False) def test_password_auth_failure(self): - self.assertRaises(AuthenticationError, - SSHClient, self.host, port=self.port, num_retries=1, - allow_agent=False, - password='blah blah blah') + try: + client = SSHClient(self.host, port=self.port, num_retries=1, + allow_agent=False, + identity_auth=False, + password='blah blah blah', + ) + except AuthenticationException as ex: + self.assertIsInstance(ex.args[3], AuthenticationDenied) + else: + raise AssertionError def test_retry_failure(self): self.assertRaises(ConnectionErrorException, @@ -221,6 +227,7 @@ def test_auth_retry_failure(self): retry_delay=.1, num_retries=2, allow_agent=False, + identity_auth=False, ) def test_connection_timeout(self):