Skip to content

Commit 59ad4b8

Browse files
authored
Auth check (#270)
* Added check for no auth methods left. Added test. * Updated coveragerc * Added logging * Fixed libssh client agent authentication, added tests * Bumped gevent requirements * Updated changelog
1 parent aab7caf commit 59ad4b8

File tree

9 files changed

+84
-19
lines changed

9 files changed

+84
-19
lines changed

.coveragerc

-13
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,8 @@ source = pssh
33

44
[report]
55
omit =
6-
*/python?.?/*
7-
*/site-packages/nose/*
8-
fake_server/*
9-
*/test*
10-
eggs/*
11-
pssh_local.py
12-
setup.py
13-
/home/travis/virtualenv/python*/lib/python*/*
146
*/_version.py
15-
*.pyx
167
exclude_lines =
178
pragma: no cover
189
def __repr__
19-
raise AssertionError
2010
raise NotImplementedError
21-
if __name__ == .__main__.:
22-
logger.debug
23-
continue

Changelog.rst

+10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
Change Log
22
============
33

4+
2.5.2
5+
+++++
6+
7+
Fixes
8+
-----
9+
10+
* Agent authentication would not work for the libssh clients under ``pssh.clients.ssh`` - #267.
11+
* Password authentication would be attempted if all other methods failed even when no password was provided.
12+
* Gevent minimum version was too low - #269.
13+
414
2.5.1
515
+++++
616

pssh/clients/base/single.py

+10-3
Original file line numberDiff line numberDiff line change
@@ -330,10 +330,10 @@ def auth(self):
330330
self._agent_auth()
331331
except (AgentAuthenticationError, AgentConnectionError, AgentGetIdentityError,
332332
AgentListIdentitiesError) as ex:
333-
logger.debug("Agent auth failed with %s"
334-
"continuing with other authentication methods", ex)
333+
logger.debug("Agent auth failed with %s "
334+
"continuing with other authentication methods", repr(ex))
335335
except Exception as ex:
336-
logger.error("Agent auth failed with - %s", ex)
336+
logger.error("Agent auth failed with - %s", repr(ex))
337337
else:
338338
logger.debug("Authentication with SSH Agent succeeded")
339339
return
@@ -343,9 +343,16 @@ def auth(self):
343343
except AuthenticationError:
344344
if self.password is None:
345345
raise
346+
if self.password is None:
347+
msg = "No remaining authentication methods"
348+
logger.error(msg)
349+
raise AuthenticationError(msg)
346350
logger.debug("Private key auth failed, trying password")
347351
self._password_auth()
348352

353+
def _agent_auth(self):
354+
raise NotImplementedError
355+
349356
def _password_auth(self):
350357
raise NotImplementedError
351358

pssh/clients/native/single.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ def _pkey_auth(self, pkey_file, password=None):
221221
self.session.userauth_publickey_fromfile(
222222
self.user,
223223
pkey_file,
224-
passphrase=password if password is not None else '')
224+
passphrase=password if password is not None else b'')
225225

226226
def _password_auth(self):
227227
try:

pssh/clients/ssh/single.py

+3
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ def disconnect(self):
120120
if self.sock is not None and not self.sock.closed:
121121
self.sock.close()
122122

123+
def _agent_auth(self):
124+
self.session.userauth_agent(self.user)
125+
123126
def _keepalive(self):
124127
pass
125128

requirements.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
gevent>=1.1
1+
gevent>=1.3.0
22
ssh2-python>=0.22.0
33
ssh-python>=0.9.0

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
'*.tests', '*.tests.*')
3939
),
4040
install_requires=[
41-
'gevent>=1.1', 'ssh2-python>=0.22.0', 'ssh-python>=0.9.0'],
41+
'gevent>=1.3.0', 'ssh2-python>=0.22.0', 'ssh-python>=0.9.0'],
4242
classifiers=[
4343
'Development Status :: 5 - Production/Stable',
4444
'License :: OSI Approved :: GNU Lesser General Public License v2 (LGPLv2)',

tests/native/test_single_client.py

+11
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,17 @@ class _SSHClient(SSHClient):
198198
allow_agent=False)
199199
self.assertIsInstance(client, SSHClient)
200200

201+
def test_no_auth(self):
202+
self.assertRaises(
203+
AuthenticationError,
204+
SSHClient,
205+
self.host,
206+
port=self.port,
207+
num_retries=1,
208+
allow_agent=False,
209+
identity_auth=False,
210+
)
211+
201212
def test_agent_auth_failure(self):
202213
class UnknownError(Exception):
203214
pass

tests/ssh/test_single_client.py

+47
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
from gevent import sleep, Timeout as GTimeout, spawn
2424
from ssh.session import Session
25+
from ssh.exceptions import AuthenticationDenied
2526
from pssh.exceptions import AuthenticationException, ConnectionErrorException, \
2627
SessionError, SFTPIOError, SFTPError, SCPError, PKeyFileError, Timeout, \
2728
AuthenticationError
@@ -238,5 +239,51 @@ def _session():
238239
def test_invalid_mkdir(self):
239240
self.assertRaises(OSError, self.client._make_local_dir, '/my_new_dir')
240241

242+
def test_no_auth(self):
243+
self.assertRaises(
244+
AuthenticationError,
245+
SSHClient,
246+
self.host,
247+
port=self.port,
248+
num_retries=1,
249+
allow_agent=False,
250+
identity_auth=False,
251+
)
252+
253+
def test_agent_auth_failure(self):
254+
class UnknownError(Exception):
255+
pass
256+
def _agent_auth_unk():
257+
raise UnknownError
258+
def _agent_auth_agent_err():
259+
raise AuthenticationDenied
260+
client = SSHClient(self.host, port=self.port,
261+
pkey=self.user_key,
262+
num_retries=1,
263+
allow_agent=True,
264+
identity_auth=False)
265+
client.session.disconnect()
266+
client.pkey = None
267+
client._connect(self.host, self.port)
268+
self.assertRaises(AuthenticationDenied, client._agent_auth)
269+
client._agent_auth = _agent_auth_unk
270+
self.assertRaises(AuthenticationError, client.auth)
271+
client._agent_auth = _agent_auth_agent_err
272+
self.assertRaises(AuthenticationError, client.auth)
273+
274+
def test_agent_auth_fake_success(self):
275+
def _agent_auth():
276+
return
277+
client = SSHClient(self.host, port=self.port,
278+
pkey=self.user_key,
279+
num_retries=1,
280+
allow_agent=True,
281+
identity_auth=False)
282+
client.session.disconnect()
283+
client.pkey = None
284+
client._connect(self.host, self.port)
285+
client._agent_auth = _agent_auth
286+
self.assertIsNone(client.auth())
287+
241288
# TODO:
242289
# * disconnect exc

0 commit comments

Comments
 (0)