Show More
@@ -107,23 +107,32 b' except AttributeError:' | |||||
107 | return ssl.wrap_socket(socket, **args) |
|
107 | return ssl.wrap_socket(socket, **args) | |
108 |
|
108 | |||
109 | try: |
|
109 | try: | |
110 | # ssl.SSLContext was added in 2.7.9 and presence indicates modern |
|
|||
111 | # SSL/TLS features are available. |
|
|||
112 | ssl_context = ssl.SSLContext |
|
|||
113 |
|
||||
114 | def wrapsocket(sock, keyfile, certfile, ui, cert_reqs=ssl.CERT_NONE, |
|
110 | def wrapsocket(sock, keyfile, certfile, ui, cert_reqs=ssl.CERT_NONE, | |
115 | ca_certs=None, serverhostname=None): |
|
111 | ca_certs=None, serverhostname=None): | |
116 | # Allow any version of SSL starting with TLSv1 and |
|
112 | # Despite its name, PROTOCOL_SSLv23 selects the highest protocol | |
117 | # up. Note that specifying TLSv1 here prohibits use of |
|
113 | # that both ends support, including TLS protocols. On legacy stacks, | |
118 | # newer standards (like TLSv1_2), so this is the right way |
|
114 | # the highest it likely goes in TLS 1.0. On modern stacks, it can | |
119 | # to do this. Note that in the future it'd be better to |
|
115 | # support TLS 1.2. | |
120 | # support using ssl.create_default_context(), which sets |
|
116 | # | |
121 | # up a bunch of things in smart ways (strong ciphers, |
|
117 | # The PROTOCOL_TLSv* constants select a specific TLS version | |
122 | # protocol versions, etc) and is upgraded by Python |
|
118 | # only (as opposed to multiple versions). So the method for | |
123 | # maintainers for us, but that breaks too many things to |
|
119 | # supporting multiple TLS versions is to use PROTOCOL_SSLv23 and | |
124 | # do it in a hurry. |
|
120 | # disable protocols via SSLContext.options and OP_NO_* constants. | |
125 | sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23) |
|
121 | # However, SSLContext.options doesn't work unless we have the | |
|
122 | # full/real SSLContext available to us. | |||
|
123 | # | |||
|
124 | # SSLv2 and SSLv3 are broken. We ban them outright. | |||
|
125 | if modernssl: | |||
|
126 | protocol = ssl.PROTOCOL_SSLv23 | |||
|
127 | else: | |||
|
128 | protocol = ssl.PROTOCOL_TLSv1 | |||
|
129 | ||||
|
130 | # TODO use ssl.create_default_context() on modernssl. | |||
|
131 | sslcontext = SSLContext(protocol) | |||
|
132 | ||||
|
133 | # This is a no-op on old Python. | |||
126 | sslcontext.options |= OP_NO_SSLv2 | OP_NO_SSLv3 |
|
134 | sslcontext.options |= OP_NO_SSLv2 | OP_NO_SSLv3 | |
|
135 | ||||
127 | if certfile is not None: |
|
136 | if certfile is not None: | |
128 | def password(): |
|
137 | def password(): | |
129 | f = keyfile or certfile |
|
138 | f = keyfile or certfile | |
@@ -132,7 +141,8 b' try:' | |||||
132 | sslcontext.verify_mode = cert_reqs |
|
141 | sslcontext.verify_mode = cert_reqs | |
133 | if ca_certs is not None: |
|
142 | if ca_certs is not None: | |
134 | sslcontext.load_verify_locations(cafile=ca_certs) |
|
143 | sslcontext.load_verify_locations(cafile=ca_certs) | |
135 | elif _canloaddefaultcerts: |
|
144 | else: | |
|
145 | # This is a no-op on old Python. | |||
136 | sslcontext.load_default_certs() |
|
146 | sslcontext.load_default_certs() | |
137 |
|
147 | |||
138 | sslsocket = sslcontext.wrap_socket(sock, server_hostname=serverhostname) |
|
148 | sslsocket = sslcontext.wrap_socket(sock, server_hostname=serverhostname) | |
@@ -143,19 +153,7 b' try:' | |||||
143 | raise error.Abort(_('ssl connection failed')) |
|
153 | raise error.Abort(_('ssl connection failed')) | |
144 | return sslsocket |
|
154 | return sslsocket | |
145 | except AttributeError: |
|
155 | except AttributeError: | |
146 | # We don't have a modern version of the "ssl" module and are running |
|
156 | raise util.Abort('this should not happen') | |
147 | # Python <2.7.9. |
|
|||
148 | def wrapsocket(sock, keyfile, certfile, ui, cert_reqs=ssl.CERT_NONE, |
|
|||
149 | ca_certs=None, serverhostname=None): |
|
|||
150 | sslsocket = ssl.wrap_socket(sock, keyfile, certfile, |
|
|||
151 | cert_reqs=cert_reqs, ca_certs=ca_certs, |
|
|||
152 | ssl_version=ssl.PROTOCOL_TLSv1) |
|
|||
153 | # check if wrap_socket failed silently because socket had been |
|
|||
154 | # closed |
|
|||
155 | # - see http://bugs.python.org/issue13721 |
|
|||
156 | if not sslsocket.cipher(): |
|
|||
157 | raise error.Abort(_('ssl connection failed')) |
|
|||
158 | return sslsocket |
|
|||
159 |
|
157 | |||
160 | def _verifycert(cert, hostname): |
|
158 | def _verifycert(cert, hostname): | |
161 | '''Verify that cert (in socket.getpeercert() format) matches hostname. |
|
159 | '''Verify that cert (in socket.getpeercert() format) matches hostname. |
General Comments 0
You need to be logged in to leave comments.
Login now