Show More
@@ -106,54 +106,51 b' except AttributeError:' | |||||
106 |
|
106 | |||
107 | return ssl.wrap_socket(socket, **args) |
|
107 | return ssl.wrap_socket(socket, **args) | |
108 |
|
108 | |||
109 | try: |
|
109 | def wrapsocket(sock, keyfile, certfile, ui, cert_reqs=ssl.CERT_NONE, | |
110 | def wrapsocket(sock, keyfile, certfile, ui, cert_reqs=ssl.CERT_NONE, |
|
110 | ca_certs=None, serverhostname=None): | |
111 | ca_certs=None, serverhostname=None): |
|
111 | # Despite its name, PROTOCOL_SSLv23 selects the highest protocol | |
112 | # Despite its name, PROTOCOL_SSLv23 selects the highest protocol |
|
112 | # that both ends support, including TLS protocols. On legacy stacks, | |
113 | # that both ends support, including TLS protocols. On legacy stacks, |
|
113 | # the highest it likely goes in TLS 1.0. On modern stacks, it can | |
114 | # the highest it likely goes in TLS 1.0. On modern stacks, it can |
|
114 | # support TLS 1.2. | |
115 | # support TLS 1.2. |
|
115 | # | |
116 | # |
|
116 | # The PROTOCOL_TLSv* constants select a specific TLS version | |
117 | # The PROTOCOL_TLSv* constants select a specific TLS version |
|
117 | # only (as opposed to multiple versions). So the method for | |
118 | # only (as opposed to multiple versions). So the method for |
|
118 | # supporting multiple TLS versions is to use PROTOCOL_SSLv23 and | |
119 | # supporting multiple TLS versions is to use PROTOCOL_SSLv23 and |
|
119 | # disable protocols via SSLContext.options and OP_NO_* constants. | |
120 | # disable protocols via SSLContext.options and OP_NO_* constants. |
|
120 | # However, SSLContext.options doesn't work unless we have the | |
121 | # However, SSLContext.options doesn't work unless we have the |
|
121 | # full/real SSLContext available to us. | |
122 | # full/real SSLContext available to us. |
|
122 | # | |
123 | # |
|
123 | # SSLv2 and SSLv3 are broken. We ban them outright. | |
124 | # SSLv2 and SSLv3 are broken. We ban them outright. |
|
124 | if modernssl: | |
125 | if modernssl: |
|
125 | protocol = ssl.PROTOCOL_SSLv23 | |
126 | protocol = ssl.PROTOCOL_SSLv23 |
|
126 | else: | |
127 | else: |
|
127 | protocol = ssl.PROTOCOL_TLSv1 | |
128 | protocol = ssl.PROTOCOL_TLSv1 |
|
|||
129 |
|
128 | |||
130 |
|
|
129 | # TODO use ssl.create_default_context() on modernssl. | |
131 |
|
|
130 | sslcontext = SSLContext(protocol) | |
132 |
|
131 | |||
133 |
|
|
132 | # This is a no-op on old Python. | |
134 |
|
|
133 | sslcontext.options |= OP_NO_SSLv2 | OP_NO_SSLv3 | |
135 |
|
134 | |||
136 |
|
|
135 | if certfile is not None: | |
137 |
|
|
136 | def password(): | |
138 |
|
|
137 | f = keyfile or certfile | |
139 |
|
|
138 | return ui.getpass(_('passphrase for %s: ') % f, '') | |
140 |
|
|
139 | sslcontext.load_cert_chain(certfile, keyfile, password) | |
141 |
|
|
140 | sslcontext.verify_mode = cert_reqs | |
142 |
|
|
141 | if ca_certs is not None: | |
143 |
|
|
142 | sslcontext.load_verify_locations(cafile=ca_certs) | |
144 |
|
|
143 | else: | |
145 |
|
|
144 | # This is a no-op on old Python. | |
146 |
|
|
145 | sslcontext.load_default_certs() | |
147 |
|
146 | |||
148 |
|
|
147 | sslsocket = sslcontext.wrap_socket(sock, server_hostname=serverhostname) | |
149 |
|
|
148 | # check if wrap_socket failed silently because socket had been | |
150 |
|
|
149 | # closed | |
151 |
|
|
150 | # - see http://bugs.python.org/issue13721 | |
152 |
|
|
151 | if not sslsocket.cipher(): | |
153 |
|
|
152 | raise error.Abort(_('ssl connection failed')) | |
154 |
|
|
153 | return sslsocket | |
155 | except AttributeError: |
|
|||
156 | raise util.Abort('this should not happen') |
|
|||
157 |
|
154 | |||
158 | def _verifycert(cert, hostname): |
|
155 | def _verifycert(cert, hostname): | |
159 | '''Verify that cert (in socket.getpeercert() format) matches hostname. |
|
156 | '''Verify that cert (in socket.getpeercert() format) matches hostname. |
General Comments 0
You need to be logged in to leave comments.
Login now