150 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			150 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| diff --git a/bzrlib/tests/test_ssh_transport.py b/bzrlib/tests/test_ssh_transport.py
 | |
| index 9e37c3b..fe9f219 100644
 | |
| --- a/bzrlib/tests/test_ssh_transport.py
 | |
| +++ b/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(
 | |
| diff --git a/bzrlib/transport/ssh.py b/bzrlib/transport/ssh.py
 | |
| index eecaa26..6f22341 100644
 | |
| --- a/bzrlib/transport/ssh.py
 | |
| +++ b/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(SubprocessVendor):
 | |
|          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(SubprocessVendor):
 | |
|  
 | |
|      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(SubprocessVendor):
 | |
|  
 | |
|      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(SubprocessVendor):
 | |
|  
 | |
|      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)])
 | 
