summaryrefslogtreecommitdiff
path: root/devel/bzr/files/patch-ssh_hostname
diff options
context:
space:
mode:
Diffstat (limited to 'devel/bzr/files/patch-ssh_hostname')
-rw-r--r--devel/bzr/files/patch-ssh_hostname167
1 files changed, 167 insertions, 0 deletions
diff --git a/devel/bzr/files/patch-ssh_hostname b/devel/bzr/files/patch-ssh_hostname
new file mode 100644
index 000000000000..46eb86bfcbf5
--- /dev/null
+++ b/devel/bzr/files/patch-ssh_hostname
@@ -0,0 +1,167 @@
+Source: https://launchpadlibrarian.net/370632961/24_ssh_hostnames-lp1710979
+Description: Refuse to connect to ssh hostnames starting with a dash. Fixes LP:1710979
+Author: Jelmer Vernooij <jelmer@jelmer.uk>
+Origin: commit, Revision ID: jelmer@jelmer.uk-20170819145828-qk2p7qlg5j2fbsiz
+
+* Security fix: hostnames starting with a dash in bzr+ssh URLs
+ are now filtered out when using a subprocess SSH client.
+ .
+ Thanks to Augie Fackler for reporting.
+ (Jelmer Vernooij, #1710979)
+
+
+=== modified file 'bzrlib/tests/test_ssh_transport.py'
+---
+ bzrlib/tests/test_ssh_transport.py | 38 ++++++++++++++++++++++++++++++++++++-
+ bzrlib/transport/ssh.py | 16 +++++++++++++--
+ 2 files changed, 51 insertions(+), 3 deletions(-)
+
+Index: bzrlib/tests/test_ssh_transport.py
+===================================================================
+--- bzrlib/tests/test_ssh_transport.py
++++ bzrlib/tests/test_ssh_transport.py
+@@ -22,6 +22,7 @@ from bzrlib.transport.ssh import (
+ SSHCorpSubprocessVendor,
+ LSHSubprocessVendor,
+ SSHVendorManager,
++ StrangeHostname,
+ )
+
+
+@@ -161,6 +162,19 @@ class SSHVendorManagerTests(TestCase):
+
+ class SubprocessVendorsTests(TestCase):
+
++ def test_openssh_command_tricked(self):
++ vendor = OpenSSHSubprocessVendor()
++ self.assertEqual(
++ vendor._get_vendor_specific_argv(
++ "user", "-oProxyCommand=blah", 100, command=["bzr"]),
++ ["ssh", "-oForwardX11=no", "-oForwardAgent=no",
++ "-oClearAllForwardings=yes",
++ "-oNoHostAuthenticationForLocalhost=yes",
++ "-p", "100",
++ "-l", "user",
++ "--",
++ "-oProxyCommand=blah", "bzr"])
++
+ def test_openssh_command_arguments(self):
+ vendor = OpenSSHSubprocessVendor()
+ self.assertEqual(
+@@ -171,6 +185,7 @@ class SubprocessVendorsTests(TestCase):
+ "-oNoHostAuthenticationForLocalhost=yes",
+ "-p", "100",
+ "-l", "user",
++ "--",
+ "host", "bzr"]
+ )
+
+@@ -184,9 +199,16 @@ class SubprocessVendorsTests(TestCase):
+ "-oNoHostAuthenticationForLocalhost=yes",
+ "-p", "100",
+ "-l", "user",
+- "-s", "host", "sftp"]
++ "-s", "--", "host", "sftp"]
+ )
+
++ def test_openssh_command_tricked(self):
++ vendor = SSHCorpSubprocessVendor()
++ self.assertRaises(
++ StrangeHostname,
++ vendor._get_vendor_specific_argv,
++ "user", "-oProxyCommand=host", 100, command=["bzr"])
++
+ def test_sshcorp_command_arguments(self):
+ vendor = SSHCorpSubprocessVendor()
+ self.assertEqual(
+@@ -209,6 +231,13 @@ class SubprocessVendorsTests(TestCase):
+ "-s", "sftp", "host"]
+ )
+
++ def test_lsh_command_tricked(self):
++ vendor = LSHSubprocessVendor()
++ self.assertRaises(
++ StrangeHostname,
++ vendor._get_vendor_specific_argv,
++ "user", "-oProxyCommand=host", 100, command=["bzr"])
++
+ def test_lsh_command_arguments(self):
+ vendor = LSHSubprocessVendor()
+ self.assertEqual(
+@@ -231,6 +260,13 @@ class SubprocessVendorsTests(TestCase):
+ "--subsystem", "sftp", "host"]
+ )
+
++ def test_plink_command_tricked(self):
++ vendor = PLinkSubprocessVendor()
++ self.assertRaises(
++ StrangeHostname,
++ vendor._get_vendor_specific_argv,
++ "user", "-oProxyCommand=host", 100, command=["bzr"])
++
+ def test_plink_command_arguments(self):
+ vendor = PLinkSubprocessVendor()
+ self.assertEqual(
+Index: bzrlib/transport/ssh.py
+===================================================================
+--- bzrlib/transport/ssh.py
++++ bzrlib/transport/ssh.py
+@@ -46,6 +46,10 @@ else:
+ from paramiko.sftp_client import SFTPClient
+
+
++class StrangeHostname(errors.BzrError):
++ _fmt = "Refusing to connect to strange SSH hostname %(hostname)s"
++
++
+ SYSTEM_HOSTKEYS = {}
+ BZR_HOSTKEYS = {}
+
+@@ -360,6 +364,11 @@ class SubprocessVendor(SSHVendor):
+ # tests, but beware of using PIPE which may hang due to not being read.
+ _stderr_target = None
+
++ @staticmethod
++ def _check_hostname(arg):
++ if arg.startswith('-'):
++ raise StrangeHostname(hostname=arg)
++
+ def _connect(self, argv):
+ # Attempt to make a socketpair to use as stdin/stdout for the SSH
+ # subprocess. We prefer sockets to pipes because they support
+@@ -424,9 +433,9 @@ class OpenSSHSubprocessVendor(Subprocess
+ if username is not None:
+ args.extend(['-l', username])
+ if subsystem is not None:
+- args.extend(['-s', host, subsystem])
++ args.extend(['-s', '--', host, subsystem])
+ else:
+- args.extend([host] + command)
++ args.extend(['--', host] + command)
+ return args
+
+ register_ssh_vendor('openssh', OpenSSHSubprocessVendor())
+@@ -439,6 +448,7 @@ class SSHCorpSubprocessVendor(Subprocess
+
+ def _get_vendor_specific_argv(self, username, host, port, subsystem=None,
+ command=None):
++ self._check_hostname(host)
+ args = [self.executable_path, '-x']
+ if port is not None:
+ args.extend(['-p', str(port)])
+@@ -460,6 +470,7 @@ class LSHSubprocessVendor(SubprocessVend
+
+ def _get_vendor_specific_argv(self, username, host, port, subsystem=None,
+ command=None):
++ self._check_hostname(host)
+ args = [self.executable_path]
+ if port is not None:
+ args.extend(['-p', str(port)])
+@@ -481,6 +492,7 @@ class PLinkSubprocessVendor(SubprocessVe
+
+ def _get_vendor_specific_argv(self, username, host, port, subsystem=None,
+ command=None):
++ self._check_hostname(host)
+ args = [self.executable_path, '-x', '-a', '-ssh', '-2', '-batch']
+ if port is not None:
+ args.extend(['-P', str(port)])