From 9ccc274d592a5fb522290dc25166646290296db6 Mon Sep 17 00:00:00 2001 From: Rick Sherman Date: Wed, 16 Jul 2014 17:45:49 -0500 Subject: [PATCH 1/3] Fixed ssh-key auth Added the ability to use IdentityFile from .ssh/config file Also re-enabled default of underlying ncclient allow_agent and look_for_keys By default ncclient will: 1. Try passed in keyfile 2. Look for keys loaded in agent 3. Look for default keys in user home 4. Try passed in user/pass combo --- lib/jnpr/junos/device.py | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/lib/jnpr/junos/device.py b/lib/jnpr/junos/device.py index f63338017..7d9c5d369 100644 --- a/lib/jnpr/junos/device.py +++ b/lib/jnpr/junos/device.py @@ -239,6 +239,7 @@ def _sshconf_lkup(self): self._hostname = found.get('hostname', self._hostname) self._port = found.get('port', self._port) self._auth_user = found.get('user') + self._ssh_private_key_file = found.get('identityfile') def __init__(self, *vargs, **kvargs): """ @@ -307,7 +308,8 @@ def __init__(self, *vargs, **kvargs): # but if user is explit from call, then use it. self._auth_user = kvargs.get('user') or self._auth_user self._auth_password = kvargs.get('password') or kvargs.get('passwd') - self._ssh_private_key_file = kvargs.get('ssh_private_key_file') + if not hasattr(self, '_ssh_private_key_file'): + self._ssh_private_key_file = kvargs.get('ssh_private_key_file') # ----------------------------- # initialize instance variables @@ -370,14 +372,6 @@ def open(self, *vargs, **kvargs): try: ts_start = datetime.datetime.now() - # we want to disable the ssh-agent if-and-only-if we are - # given a password and we are not given an ssh key file. - # in this condition it means that the password is - # the 'plain-text' password - - allow_agent = not bool((self._auth_password is not None) and - (self._ssh_private_key_file is None)) - # open connection using ncclient transport self._conn = netconf_ssh.connect( host=self._hostname, @@ -386,8 +380,6 @@ def open(self, *vargs, **kvargs): password=self._auth_password, hostkey_verify=False, key_filename=self._ssh_private_key_file, - look_for_keys=False, - allow_agent=allow_agent, device_params={'name': 'junos'}) except NcErrors.AuthenticationError as err: From 7abe593a93dcfdaa3dbc68f66b7462894271c032 Mon Sep 17 00:00:00 2001 From: Rick Sherman Date: Thu, 17 Jul 2014 10:24:56 -0500 Subject: [PATCH 2/3] Re-added proper logic for allow_agent --- lib/jnpr/junos/device.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/jnpr/junos/device.py b/lib/jnpr/junos/device.py index 7d9c5d369..8a72932b2 100644 --- a/lib/jnpr/junos/device.py +++ b/lib/jnpr/junos/device.py @@ -372,6 +372,14 @@ def open(self, *vargs, **kvargs): try: ts_start = datetime.datetime.now() + # we want to enable the ssh-agent if-and-only-if we are + # not given a password or an ssh key file. + # in this condition it means we want to query the agent + # for available ssh keys + + allow_agent = bool((self._auth_password is None) and + (self._ssh_private_key_file is None)) + # open connection using ncclient transport self._conn = netconf_ssh.connect( host=self._hostname, @@ -380,6 +388,7 @@ def open(self, *vargs, **kvargs): password=self._auth_password, hostkey_verify=False, key_filename=self._ssh_private_key_file, + allow_agent=allow_agent, device_params={'name': 'junos'}) except NcErrors.AuthenticationError as err: From 9f32d681eafa929b5153f09a2d2f5bcd89f77ad7 Mon Sep 17 00:00:00 2001 From: Rick Sherman Date: Thu, 17 Jul 2014 11:04:38 -0500 Subject: [PATCH 3/3] Functional test for SSH keys (non-agent) --- tests/functional/test_device_ssh.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 tests/functional/test_device_ssh.py diff --git a/tests/functional/test_device_ssh.py b/tests/functional/test_device_ssh.py new file mode 100644 index 000000000..a187480d3 --- /dev/null +++ b/tests/functional/test_device_ssh.py @@ -0,0 +1,25 @@ +''' + +@author: rsherman +''' +import unittest +from nose.plugins.attrib import attr + +from jnpr.junos import Device + + +@attr('functional') +class TestDeviceSsh(unittest.TestCase): + + def tearDown(self): + self.dev.close() + + def test_device_open_default_key(self): + self.dev = Device('pabst.englab.juniper.net') + self.dev.open() + self.assertEqual(self.dev.connected, True) + + def test_device_open_key_pass(self): + self.dev = Device(host='pabst.englab.juniper.net', ssh_private_key_file='/var/lib/jenkins/.ssh/passkey', passwd='password') + self.dev.open() + self.assertEqual(self.dev.connected, True)