summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJeff Forcier <jeff@bitprophet.org>2016-04-25 18:44:59 -0700
committerJeff Forcier <jeff@bitprophet.org>2016-04-25 18:44:59 -0700
commit8a89fb0e2924e8f5c3ed31ddcd0cc0ee1337dd57 (patch)
tree7e497e9df54e2a87eac98258f9e21f64870a2aa7
parent268acf810a15228e0d14a8ee3a4d96c0997f8e5d (diff)
parenta9f222be52639e82ecdd9839293df5f3f74f6673 (diff)
Merge branch '1.16' into 1.17
-rw-r--r--paramiko/config.py19
-rw-r--r--sites/www/changelog.rst6
-rw-r--r--tests/test_util.py30
3 files changed, 49 insertions, 6 deletions
diff --git a/paramiko/config.py b/paramiko/config.py
index e18fa4bf..7374eb1a 100644
--- a/paramiko/config.py
+++ b/paramiko/config.py
@@ -76,15 +76,17 @@ class SSHConfig (object):
'config': {}
}
elif key == 'proxycommand' and value.lower() == 'none':
- # Proxycommands of none should not be added as an actual value. (Issue #415)
- continue
+ # Store 'none' as None; prior to 3.x, it will get stripped out
+ # at the end (for compatibility with issue #415). After 3.x, it
+ # will simply not get stripped, leaving a nice explicit marker.
+ host['config'][key] = None
else:
if value.startswith('"') and value.endswith('"'):
value = value[1:-1]
- #identityfile, localforward, remoteforward keys are special cases, since they are allowed to be
- # specified multiple times and they should be tried in order
- # of specification.
+ # identityfile, localforward, remoteforward keys are special
+ # cases, since they are allowed to be specified multiple times
+ # and they should be tried in order of specification.
if key in ['identityfile', 'localforward', 'remoteforward']:
if key in host['config']:
host['config'][key].append(value)
@@ -127,10 +129,13 @@ class SSHConfig (object):
# else it will reference the original list
# in self._config and update that value too
# when the extend() is being called.
- ret[key] = value[:]
+ ret[key] = value[:] if value is not None else value
elif key == 'identityfile':
ret[key].extend(value)
ret = self._expand_variables(ret, hostname)
+ # TODO: remove in 3.x re #670
+ if 'proxycommand' in ret and ret['proxycommand'] is None:
+ del ret['proxycommand']
return ret
def get_hostnames(self):
@@ -211,6 +216,8 @@ class SSHConfig (object):
}
for k in config:
+ if config[k] is None:
+ continue
if k in replacements:
for find, replace in replacements[k]:
if isinstance(config[k], list):
diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst
index 740174b9..2c097986 100644
--- a/sites/www/changelog.rst
+++ b/sites/www/changelog.rst
@@ -5,6 +5,12 @@ Changelog
* :release:`1.17.0 <2016-04-25>`
* :release:`1.16.1 <2016-04-25>`
* :release:`1.15.5 <2016-04-25>`
+* :bug:`670` Due to an earlier bugfix, less-specific ``Host`` blocks'
+ ``ProxyCommand`` values were overriding ``ProxyCommand none`` in
+ more-specific ``Host`` blocks. This has been fixed in a backwards compatible
+ manner (i.e. ``ProxyCommand none`` continues to appear as a total lack of any
+ ``proxycommand`` key in parsed config structures). Thanks to Pat Brisbin for
+ the catch.
* :bug:`676` (via :issue:`677`) Fix a backwards incompatibility issue that
cropped up in `SFTPFile.prefetch <~paramiko.sftp_file.prefetch>` re: the
erroneously non-optional ``file_size`` parameter. Should only affect users
diff --git a/tests/test_util.py b/tests/test_util.py
index a6a2c30b..e25f0563 100644
--- a/tests/test_util.py
+++ b/tests/test_util.py
@@ -485,3 +485,33 @@ Host proxycommand-with-equals-none
paramiko.util.lookup_ssh_host_config(host, config),
values
)
+
+ def test_proxycommand_none_masking(self):
+ # Re: https://github.com/paramiko/paramiko/issues/670
+ source_config = """
+Host specific-host
+ ProxyCommand none
+
+Host other-host
+ ProxyCommand other-proxy
+
+Host *
+ ProxyCommand default-proxy
+"""
+ config = paramiko.SSHConfig()
+ config.parse(StringIO(source_config))
+ # When bug is present, the full stripping-out of specific-host's
+ # ProxyCommand means it actually appears to pick up the default
+ # ProxyCommand value instead, due to cascading. It should (for
+ # backwards compatibility reasons in 1.x/2.x) appear completely blank,
+ # as if the host had no ProxyCommand whatsoever.
+ # Threw another unrelated host in there just for sanity reasons.
+ self.assertFalse('proxycommand' in config.lookup('specific-host'))
+ self.assertEqual(
+ config.lookup('other-host')['proxycommand'],
+ 'other-proxy'
+ )
+ self.assertEqual(
+ config.lookup('some-random-host')['proxycommand'],
+ 'default-proxy'
+ )