summaryrefslogtreecommitdiff
path: root/devel/bzr/patches/patch-CVE-2017-14176
blob: c5095c7182a7167f3dac0c7a9a40f7a4aff0fd69 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
$NetBSD: patch-CVE-2017-14176,v 1.1 2018/01/09 22:18:57 tez Exp $

Patch for CVE-2017-14176 from http://bazaar.launchpad.net/~brz/brz/trunk/revision/6754


--- bzrlib/transport/ssh.py.orig	2013-07-27 11:50:53.000000000 +0000
+++ bzrlib/transport/ssh.py
@@ -45,6 +45,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 = {}
 
@@ -359,6 +363,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
@@ -423,9 +432,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())
@@ -438,6 +447,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)])
@@ -459,6 +469,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)])
@@ -480,6 +491,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)])

--- bzrlib/tests/test_ssh_transport.py.orig	2013-07-27 11:50:53.000000000 +0000
+++ 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(