Browse code

Applying patch for CVE-2018-1000805 for paramiko

Change-Id: I2d765ec98a93a81e6d3a596c1bfc6ea1ad52d451
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/6497
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Anish Swaminathan <anishs@vmware.com>

smaliakkal authored on 2019/01/12 11:03:41
Showing 2 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,160 @@
0
+diff -ru a/paramiko/auth_handler.py b/paramiko/auth_handler.py
1
+--- a/paramiko/auth_handler.py	2018-03-13 01:02:51.000000000 +0000
2
+@@ -630,17 +630,41 @@
3
+             self.auth_event.set()
4
+         return
5
+ 
6
+-    _handler_table = {
7
++    # TODO: do the same to the other tables, in Transport.
8
++    # TODO 3.0: MAY make sense to make these tables into actual
9
++    # classes/instances that can be fed a mode bool or whatever. Or,
10
++    # alternately (both?) make the message types small classes or enums that
11
++    # embed this info within themselves (which could also then tidy up the
12
++    # current 'integer -> human readable short string' stuff in common.py).
13
++    # TODO: if we do that, also expose 'em publicly.
14
++
15
++    # Messages which should be handled _by_ servers (sent by clients)
16
++    _server_handler_table = {
17
+         MSG_SERVICE_REQUEST: _parse_service_request,
18
+-        MSG_SERVICE_ACCEPT: _parse_service_accept,
19
+         MSG_USERAUTH_REQUEST: _parse_userauth_request,
20
++        MSG_USERAUTH_INFO_RESPONSE: _parse_userauth_info_response,
21
++    }
22
++
23
++    # Messages which should be handled _by_ clients (sent by servers)
24
++    _client_handler_table = {
25
++        MSG_SERVICE_ACCEPT: _parse_service_accept,        
26
+         MSG_USERAUTH_SUCCESS: _parse_userauth_success,
27
+         MSG_USERAUTH_FAILURE: _parse_userauth_failure,
28
+         MSG_USERAUTH_BANNER: _parse_userauth_banner,
29
+         MSG_USERAUTH_INFO_REQUEST: _parse_userauth_info_request,
30
+-        MSG_USERAUTH_INFO_RESPONSE: _parse_userauth_info_response,
31
+     }
32
+ 
33
++    # NOTE: prior to the fix for #1283, this was a static dict instead of a
34
++    # property. Should be backwards compatible in most/all cases.
35
++    @property
36
++    def _handler_table(self):
37
++        if self.transport.server_mode:
38
++            return self._server_handler_table
39
++        else:
40
++            return self._client_handler_table
41
++
42
++
43
++
44
+ 
45
+ class GssapiWithMicAuthHandler(object):
46
+     """A specialized Auth handler for gssapi-with-mic
47
+@@ -733,9 +757,15 @@
48
+         self._restore_delegate_auth_handler()
49
+         return self._delegate._parse_userauth_request(m)
50
+ 
51
+-    _handler_table = {
52
++    __handler_table = {
53
+         MSG_SERVICE_REQUEST: _parse_service_request,
54
+         MSG_USERAUTH_REQUEST: _parse_userauth_request,
55
+         MSG_USERAUTH_GSSAPI_TOKEN: _parse_userauth_gssapi_token,
56
+         MSG_USERAUTH_GSSAPI_MIC: _parse_userauth_gssapi_mic,
57
+     }
58
++
59
++    @property
60
++    def _handler_table(self):
61
++        # TODO: determine if we can cut this up like we did for the primary
62
++        # AuthHandler class.
63
++        return self.__handler_table
64
+diff -ru a/sites/www/changelog.rst b/sites/www/changelog.rst
65
+--- a/sites/www/changelog.rst	2018-03-13 01:02:51.000000000 +0000
66
+@@ -3,6 +3,18 @@
67
+ =========
68
+ 
69
+ * :release:`2.1.5 <2018-03-12>`
70
++- :bug:`1283 (1.17+)` Fix exploit (CVE-2018-1000805) in Paramiko's server mode
71
++  (**not** client mode) where hostile clients could trick the server into
72
++  thinking they were authenticated without actually submitting valid
73
++  authentication.
74
++
75
++  Specifically, steps have been taken to start separating client and server
76
++  related message types in the message handling tables within ``Transport`` and
77
++  ``AuthHandler``; this work is not complete but enough has been performed to
78
++  close off this particular exploit (which was the only obvious such exploit
79
++  for this particular channel).
80
++
81
++  Thanks to Daniel Hoffman for the detailed report.
82
+ * :release:`2.0.8 <2018-03-12>`
83
+ * :bug:`1175 (1.17+)` Fix a security flaw (CVE-2018-7750) in Paramiko's server
84
+   mode (emphasis on **server** mode; this does **not** impact *client* use!)
85
+diff -ru a/tests/test_transport.py b/tests/test_transport.py
86
+--- a/tests/test_transport.py	2018-03-13 01:02:51.000000000 +0000
87
+@@ -33,15 +33,16 @@
88
+ 
89
+ from paramiko import (
90
+     Transport, SecurityOptions, ServerInterface, RSAKey, DSSKey, SSHException,
91
+-    ChannelException, Packetizer, Channel,
92
++    ChannelException, Packetizer, Channel, AuthHandler,
93
+ )
94
+ from paramiko import AUTH_FAILED, AUTH_SUCCESSFUL
95
+ from paramiko import OPEN_SUCCEEDED, OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
96
+ from paramiko.common import (
97
+     MSG_KEXINIT, cMSG_CHANNEL_WINDOW_ADJUST, MIN_PACKET_SIZE, MIN_WINDOW_SIZE,
98
+-    MAX_WINDOW_SIZE, DEFAULT_WINDOW_SIZE, DEFAULT_MAX_PACKET_SIZE,
99
++    MAX_WINDOW_SIZE, DEFAULT_WINDOW_SIZE, DEFAULT_MAX_PACKET_SIZE, MSG_NAMES,
100
++    MSG_UNIMPLEMENTED, MSG_USERAUTH_SUCCESS,
101
+ )
102
+-from paramiko.py3compat import bytes
103
++from paramiko.py3compat import bytes, byte_chr
104
+ from paramiko.message import Message
105
+ from tests import skipUnlessBuiltin
106
+ from tests.loop import LoopSocket
107
+@@ -972,3 +973,49 @@
108
+             assert "forwarding request denied" in str(e)
109
+         else:
110
+             assert False, "Did not raise SSHException!"
111
++
112
++
113
++    def _send_client_message(self, message_type):
114
++        self.setup_test_server(connect_kwargs={})
115
++        self.ts._send_message = Mock()
116
++        # NOTE: this isn't 100% realistic (most of these message types would
117
++        # have actual other fields in 'em) but it suffices to test the level of
118
++        # message dispatch we're interested in here.
119
++        msg = Message()
120
++        # TODO: really not liking the whole cMSG_XXX vs MSG_XXX duality right
121
++        # now, esp since the former is almost always just byte_chr(the
122
++        # latter)...but since that's the case...
123
++        msg.add_byte(byte_chr(message_type))
124
++        self.tc._send_message(msg)
125
++        # No good way to actually wait for server action (see above tests re:
126
++        # MSG_UNIMPLEMENTED). Grump.
127
++        time.sleep(0.1)
128
++
129
++    def _expect_unimplemented(self):
130
++        # Ensure MSG_UNIMPLEMENTED was sent (implies it hit end of loop instead
131
++        # of truly handling the given message).
132
++        # NOTE: When bug present, this will actually be the first thing that
133
++        # fails (since in many cases actual message handling doesn't involve
134
++        # sending a message back right away).
135
++        assert self.ts._send_message.call_count == 1
136
++        reply = self.ts._send_message.call_args[0][0]
137
++        reply.rewind()  # Because it's pre-send, not post-receive
138
++        assert reply.get_byte() == cMSG_UNIMPLEMENTED
139
++
140
++    def test_server_transports_reject_client_message_types(self):
141
++        # TODO: handle Transport's own tables too, not just its inner auth
142
++        # handler's table. See TODOs in auth_handler.py
143
++        for message_type in AuthHandler._client_handler_table:
144
++            self._send_client_message(message_type)
145
++            self._expect_unimplemented()
146
++            # Reset for rest of loop
147
++            self.tearDown()
148
++            self.setUp()
149
++
150
++    def test_server_rejects_client_MSG_USERAUTH_SUCCESS(self):
151
++        self._send_client_message(MSG_USERAUTH_SUCCESS)
152
++        # Sanity checks
153
++        assert not self.ts.authenticated
154
++        assert not self.ts.auth_handler.authenticated
155
++        # Real fix's behavior
156
++        self._expect_unimplemented()
... ...
@@ -3,7 +3,7 @@
3 3
 Summary:        Python SSH module
4 4
 Name:           paramiko
5 5
 Version:        2.1.5
6
-Release:        1%{?dist}
6
+Release:        2%{?dist}
7 7
 License:        LGPL
8 8
 Group:          System Environment/Security
9 9
 Vendor:         VMware, Inc.
... ...
@@ -11,7 +11,7 @@ Distribution:   Photon
11 11
 URL:            http://www.paramiko.org/
12 12
 Source0:        https://github.com/paramiko/paramiko/archive/paramiko-%{version}.tar.gz
13 13
 %define         sha1 paramiko=0f1e47ec1822964aeb96974562716c834292962c
14
-
14
+Patch0:		paramiko-CVE-2018-1000805.patch
15 15
 BuildArch:      noarch
16 16
 
17 17
 BuildRequires:  python-setuptools
... ...
@@ -48,6 +48,7 @@ Python 3 version.
48 48
 
49 49
 %prep
50 50
 %setup -q
51
+%patch0 -p1
51 52
 
52 53
 %build
53 54
 python2 setup.py build
... ...
@@ -81,6 +82,8 @@ LANG=en_US.UTF-8 python3 test.py
81 81
 %{python3_sitelib}/*
82 82
 
83 83
 %changelog
84
+*   Fri Jan 11 2019 Siju Maliakkal <smaliakkal@vmware.com> 2.1.5-2
85
+-   Applied patch for CVE-2018-1000805
84 86
 *   Mon Apr 16 2018 Xiaolin Li <xiaolinl@vmware.com> 2.1.5-1
85 87
 -   Update version to 2.1.5 for CVE-2018-1000132
86 88
 *   Tue Jul 25 2017 Divya Thaluru <dthaluru@vmware.com> 2.1.2-5