12 from mercurial.i18n import _ |
12 from mercurial.i18n import _ |
13 try: |
13 try: |
14 # avoid using deprecated/broken FakeSocket in python 2.6 |
14 # avoid using deprecated/broken FakeSocket in python 2.6 |
15 import ssl |
15 import ssl |
16 CERT_REQUIRED = ssl.CERT_REQUIRED |
16 CERT_REQUIRED = ssl.CERT_REQUIRED |
17 def ssl_wrap_socket(sock, keyfile, certfile, |
17 PROTOCOL_SSLv23 = ssl.PROTOCOL_SSLv23 |
|
18 PROTOCOL_TLSv1 = ssl.PROTOCOL_TLSv1 |
|
19 def ssl_wrap_socket(sock, keyfile, certfile, ssl_version=PROTOCOL_TLSv1, |
18 cert_reqs=ssl.CERT_NONE, ca_certs=None): |
20 cert_reqs=ssl.CERT_NONE, ca_certs=None): |
19 sslsocket = ssl.wrap_socket(sock, keyfile, certfile, |
21 sslsocket = ssl.wrap_socket(sock, keyfile, certfile, |
20 cert_reqs=cert_reqs, ca_certs=ca_certs) |
22 cert_reqs=cert_reqs, ca_certs=ca_certs, |
|
23 ssl_version=ssl_version) |
21 # check if wrap_socket failed silently because socket had been closed |
24 # check if wrap_socket failed silently because socket had been closed |
22 # - see http://bugs.python.org/issue13721 |
25 # - see http://bugs.python.org/issue13721 |
23 if not sslsocket.cipher(): |
26 if not sslsocket.cipher(): |
24 raise util.Abort(_('ssl connection failed')) |
27 raise util.Abort(_('ssl connection failed')) |
25 return sslsocket |
28 return sslsocket |
26 except ImportError: |
29 except ImportError: |
27 CERT_REQUIRED = 2 |
30 CERT_REQUIRED = 2 |
28 |
31 |
|
32 PROTOCOL_SSLv23 = 2 |
|
33 PROTOCOL_TLSv1 = 3 |
|
34 |
29 import socket, httplib |
35 import socket, httplib |
30 |
36 |
31 def ssl_wrap_socket(sock, key_file, cert_file, |
37 def ssl_wrap_socket(sock, key_file, cert_file, ssl_version=PROTOCOL_TLSv1, |
32 cert_reqs=CERT_REQUIRED, ca_certs=None): |
38 cert_reqs=CERT_REQUIRED, ca_certs=None): |
33 if not util.safehasattr(socket, 'ssl'): |
39 if not util.safehasattr(socket, 'ssl'): |
34 raise util.Abort(_('Python SSL support not found')) |
40 raise util.Abort(_('Python SSL support not found')) |
35 if ca_certs: |
41 if ca_certs: |
36 raise util.Abort(_( |
42 raise util.Abort(_( |
82 # We COMPLETELY ignore CERT_REQUIRED on Python <= 2.5, as it's totally |
88 # We COMPLETELY ignore CERT_REQUIRED on Python <= 2.5, as it's totally |
83 # busted on those versions. |
89 # busted on those versions. |
84 |
90 |
85 def sslkwargs(ui, host): |
91 def sslkwargs(ui, host): |
86 cacerts = ui.config('web', 'cacerts') |
92 cacerts = ui.config('web', 'cacerts') |
|
93 forcetls = ui.configbool('ui', 'tls', default=True) |
|
94 if forcetls: |
|
95 ssl_version = PROTOCOL_TLSv1 |
|
96 else: |
|
97 ssl_version = PROTOCOL_SSLv23 |
87 hostfingerprint = ui.config('hostfingerprints', host) |
98 hostfingerprint = ui.config('hostfingerprints', host) |
|
99 kws = {'ssl_version': ssl_version, |
|
100 } |
88 if cacerts and not hostfingerprint: |
101 if cacerts and not hostfingerprint: |
89 cacerts = util.expandpath(cacerts) |
102 cacerts = util.expandpath(cacerts) |
90 if not os.path.exists(cacerts): |
103 if not os.path.exists(cacerts): |
91 raise util.Abort(_('could not find web.cacerts: %s') % cacerts) |
104 raise util.Abort(_('could not find web.cacerts: %s') % cacerts) |
92 return {'ca_certs': cacerts, |
105 kws.update({'ca_certs': cacerts, |
93 'cert_reqs': CERT_REQUIRED, |
106 'cert_reqs': CERT_REQUIRED, |
94 } |
107 }) |
95 return {} |
108 return kws |
96 |
109 |
97 class validator(object): |
110 class validator(object): |
98 def __init__(self, ui, host): |
111 def __init__(self, ui, host): |
99 self.ui = ui |
112 self.ui = ui |
100 self.host = host |
113 self.host = host |