Mercurial > hg
annotate mercurial/sslutil.py @ 24066:afdf5f6ab37a
pager: set an attribute on ui indicating that a pager is active
A subsequent patch will teach the color extension to do different things
depending on whether a pager is active. This patch leaves a breadcrumb
on the ui instance to allow it do that that.
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Fri, 06 Feb 2015 12:07:56 -0800 |
parents | 948a8ca27152 |
children | 922e087ba158 |
rev | line source |
---|---|
14204
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
1 # sslutil.py - SSL handling for mercurial |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
2 # |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
3 # Copyright 2005, 2006, 2007, 2008 Matt Mackall <mpm@selenic.com> |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
4 # Copyright 2006, 2007 Alexis S. L. Carvalho <alexis@cecm.usp.br> |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
5 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com> |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
6 # |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
7 # This software may be used and distributed according to the terms of the |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
8 # GNU General Public License version 2 or any later version. |
22575
d7f7f1860f00
ssl: on OS X, use a dummy cert to trick Python/OpenSSL to use system CA certs
Mads Kiilerich <madski@unity3d.com>
parents:
22574
diff
changeset
|
9 import os, sys |
14204
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
10 |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
11 from mercurial import util |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
12 from mercurial.i18n import _ |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
13 try: |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
14 # avoid using deprecated/broken FakeSocket in python 2.6 |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
15 import ssl |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
16 CERT_REQUIRED = ssl.CERT_REQUIRED |
23834
bf07c19b4c82
https: support tls sni (server name indication) for https urls (issue3090)
Alex Orange <crazycasta@gmail.com>
parents:
23069
diff
changeset
|
17 try: |
bf07c19b4c82
https: support tls sni (server name indication) for https urls (issue3090)
Alex Orange <crazycasta@gmail.com>
parents:
23069
diff
changeset
|
18 ssl_context = ssl.SSLContext |
bf07c19b4c82
https: support tls sni (server name indication) for https urls (issue3090)
Alex Orange <crazycasta@gmail.com>
parents:
23069
diff
changeset
|
19 |
23849
58080815f667
sslutil: drop support for clients of sslutil specifying a TLS version
Augie Fackler <augie@google.com>
parents:
23834
diff
changeset
|
20 def ssl_wrap_socket(sock, keyfile, certfile, cert_reqs=ssl.CERT_NONE, |
58080815f667
sslutil: drop support for clients of sslutil specifying a TLS version
Augie Fackler <augie@google.com>
parents:
23834
diff
changeset
|
21 ca_certs=None, serverhostname=None): |
23850
e1931f7cd977
sslutil: use saner TLS settings on Python 2.7.9
Augie Fackler <augie@google.com>
parents:
23849
diff
changeset
|
22 # Allow any version of SSL starting with TLSv1 and |
e1931f7cd977
sslutil: use saner TLS settings on Python 2.7.9
Augie Fackler <augie@google.com>
parents:
23849
diff
changeset
|
23 # up. Note that specifying TLSv1 here prohibits use of |
e1931f7cd977
sslutil: use saner TLS settings on Python 2.7.9
Augie Fackler <augie@google.com>
parents:
23849
diff
changeset
|
24 # newer standards (like TLSv1_2), so this is the right way |
e1931f7cd977
sslutil: use saner TLS settings on Python 2.7.9
Augie Fackler <augie@google.com>
parents:
23849
diff
changeset
|
25 # to do this. Note that in the future it'd be better to |
e1931f7cd977
sslutil: use saner TLS settings on Python 2.7.9
Augie Fackler <augie@google.com>
parents:
23849
diff
changeset
|
26 # support using ssl.create_default_context(), which sets |
e1931f7cd977
sslutil: use saner TLS settings on Python 2.7.9
Augie Fackler <augie@google.com>
parents:
23849
diff
changeset
|
27 # up a bunch of things in smart ways (strong ciphers, |
e1931f7cd977
sslutil: use saner TLS settings on Python 2.7.9
Augie Fackler <augie@google.com>
parents:
23849
diff
changeset
|
28 # protocol versions, etc) and is upgraded by Python |
e1931f7cd977
sslutil: use saner TLS settings on Python 2.7.9
Augie Fackler <augie@google.com>
parents:
23849
diff
changeset
|
29 # maintainers for us, but that breaks too many things to |
e1931f7cd977
sslutil: use saner TLS settings on Python 2.7.9
Augie Fackler <augie@google.com>
parents:
23849
diff
changeset
|
30 # do it in a hurry. |
e1931f7cd977
sslutil: use saner TLS settings on Python 2.7.9
Augie Fackler <augie@google.com>
parents:
23849
diff
changeset
|
31 sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23) |
e1931f7cd977
sslutil: use saner TLS settings on Python 2.7.9
Augie Fackler <augie@google.com>
parents:
23849
diff
changeset
|
32 sslcontext.options &= ssl.OP_NO_SSLv2 & ssl.OP_NO_SSLv3 |
23834
bf07c19b4c82
https: support tls sni (server name indication) for https urls (issue3090)
Alex Orange <crazycasta@gmail.com>
parents:
23069
diff
changeset
|
33 if certfile is not None: |
bf07c19b4c82
https: support tls sni (server name indication) for https urls (issue3090)
Alex Orange <crazycasta@gmail.com>
parents:
23069
diff
changeset
|
34 sslcontext.load_cert_chain(certfile, keyfile) |
bf07c19b4c82
https: support tls sni (server name indication) for https urls (issue3090)
Alex Orange <crazycasta@gmail.com>
parents:
23069
diff
changeset
|
35 sslcontext.verify_mode = cert_reqs |
bf07c19b4c82
https: support tls sni (server name indication) for https urls (issue3090)
Alex Orange <crazycasta@gmail.com>
parents:
23069
diff
changeset
|
36 if ca_certs is not None: |
bf07c19b4c82
https: support tls sni (server name indication) for https urls (issue3090)
Alex Orange <crazycasta@gmail.com>
parents:
23069
diff
changeset
|
37 sslcontext.load_verify_locations(cafile=ca_certs) |
bf07c19b4c82
https: support tls sni (server name indication) for https urls (issue3090)
Alex Orange <crazycasta@gmail.com>
parents:
23069
diff
changeset
|
38 |
bf07c19b4c82
https: support tls sni (server name indication) for https urls (issue3090)
Alex Orange <crazycasta@gmail.com>
parents:
23069
diff
changeset
|
39 sslsocket = sslcontext.wrap_socket(sock, |
bf07c19b4c82
https: support tls sni (server name indication) for https urls (issue3090)
Alex Orange <crazycasta@gmail.com>
parents:
23069
diff
changeset
|
40 server_hostname=serverhostname) |
bf07c19b4c82
https: support tls sni (server name indication) for https urls (issue3090)
Alex Orange <crazycasta@gmail.com>
parents:
23069
diff
changeset
|
41 # check if wrap_socket failed silently because socket had been |
bf07c19b4c82
https: support tls sni (server name indication) for https urls (issue3090)
Alex Orange <crazycasta@gmail.com>
parents:
23069
diff
changeset
|
42 # closed |
bf07c19b4c82
https: support tls sni (server name indication) for https urls (issue3090)
Alex Orange <crazycasta@gmail.com>
parents:
23069
diff
changeset
|
43 # - see http://bugs.python.org/issue13721 |
bf07c19b4c82
https: support tls sni (server name indication) for https urls (issue3090)
Alex Orange <crazycasta@gmail.com>
parents:
23069
diff
changeset
|
44 if not sslsocket.cipher(): |
bf07c19b4c82
https: support tls sni (server name indication) for https urls (issue3090)
Alex Orange <crazycasta@gmail.com>
parents:
23069
diff
changeset
|
45 raise util.Abort(_('ssl connection failed')) |
bf07c19b4c82
https: support tls sni (server name indication) for https urls (issue3090)
Alex Orange <crazycasta@gmail.com>
parents:
23069
diff
changeset
|
46 return sslsocket |
bf07c19b4c82
https: support tls sni (server name indication) for https urls (issue3090)
Alex Orange <crazycasta@gmail.com>
parents:
23069
diff
changeset
|
47 except AttributeError: |
23849
58080815f667
sslutil: drop support for clients of sslutil specifying a TLS version
Augie Fackler <augie@google.com>
parents:
23834
diff
changeset
|
48 def ssl_wrap_socket(sock, keyfile, certfile, cert_reqs=ssl.CERT_NONE, |
58080815f667
sslutil: drop support for clients of sslutil specifying a TLS version
Augie Fackler <augie@google.com>
parents:
23834
diff
changeset
|
49 ca_certs=None, serverhostname=None): |
23834
bf07c19b4c82
https: support tls sni (server name indication) for https urls (issue3090)
Alex Orange <crazycasta@gmail.com>
parents:
23069
diff
changeset
|
50 sslsocket = ssl.wrap_socket(sock, keyfile, certfile, |
bf07c19b4c82
https: support tls sni (server name indication) for https urls (issue3090)
Alex Orange <crazycasta@gmail.com>
parents:
23069
diff
changeset
|
51 cert_reqs=cert_reqs, ca_certs=ca_certs, |
23851
948a8ca27152
sslutil: drop defunct ssl version constants
Augie Fackler <augie@google.com>
parents:
23850
diff
changeset
|
52 ssl_version=ssl.PROTOCOL_TLSv1) |
23834
bf07c19b4c82
https: support tls sni (server name indication) for https urls (issue3090)
Alex Orange <crazycasta@gmail.com>
parents:
23069
diff
changeset
|
53 # check if wrap_socket failed silently because socket had been |
bf07c19b4c82
https: support tls sni (server name indication) for https urls (issue3090)
Alex Orange <crazycasta@gmail.com>
parents:
23069
diff
changeset
|
54 # closed |
bf07c19b4c82
https: support tls sni (server name indication) for https urls (issue3090)
Alex Orange <crazycasta@gmail.com>
parents:
23069
diff
changeset
|
55 # - see http://bugs.python.org/issue13721 |
bf07c19b4c82
https: support tls sni (server name indication) for https urls (issue3090)
Alex Orange <crazycasta@gmail.com>
parents:
23069
diff
changeset
|
56 if not sslsocket.cipher(): |
bf07c19b4c82
https: support tls sni (server name indication) for https urls (issue3090)
Alex Orange <crazycasta@gmail.com>
parents:
23069
diff
changeset
|
57 raise util.Abort(_('ssl connection failed')) |
bf07c19b4c82
https: support tls sni (server name indication) for https urls (issue3090)
Alex Orange <crazycasta@gmail.com>
parents:
23069
diff
changeset
|
58 return sslsocket |
14204
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
59 except ImportError: |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
60 CERT_REQUIRED = 2 |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
61 |
14616
64dfbe576455
sslutil: Restore missing imports of socket and httplib to sslutil
Stephen Thorne <stephen@thorne.id.au>
parents:
14204
diff
changeset
|
62 import socket, httplib |
64dfbe576455
sslutil: Restore missing imports of socket and httplib to sslutil
Stephen Thorne <stephen@thorne.id.au>
parents:
14204
diff
changeset
|
63 |
23849
58080815f667
sslutil: drop support for clients of sslutil specifying a TLS version
Augie Fackler <augie@google.com>
parents:
23834
diff
changeset
|
64 def ssl_wrap_socket(sock, keyfile, certfile, cert_reqs=CERT_REQUIRED, |
58080815f667
sslutil: drop support for clients of sslutil specifying a TLS version
Augie Fackler <augie@google.com>
parents:
23834
diff
changeset
|
65 ca_certs=None, serverhostname=None): |
15160
b2d4400398f3
sslutil: abort when ssl module is needed but not found
Mads Kiilerich <mads@kiilerich.com>
parents:
14667
diff
changeset
|
66 if not util.safehasattr(socket, 'ssl'): |
b2d4400398f3
sslutil: abort when ssl module is needed but not found
Mads Kiilerich <mads@kiilerich.com>
parents:
14667
diff
changeset
|
67 raise util.Abort(_('Python SSL support not found')) |
14204
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
68 if ca_certs: |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
69 raise util.Abort(_( |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
70 'certificate checking requires Python 2.6')) |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
71 |
19808
3b82d412e9e8
sslutil: make keyfile and certfile arguments consistent between 2.6+ and 2.5-
Augie Fackler <raf@durin42.com>
parents:
19806
diff
changeset
|
72 ssl = socket.ssl(sock, keyfile, certfile) |
14204
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
73 return httplib.FakeSocket(sock, ssl) |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
74 |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
75 def _verifycert(cert, hostname): |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
76 '''Verify that cert (in socket.getpeercert() format) matches hostname. |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
77 CRLs is not handled. |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
78 |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
79 Returns error message if any problems are found and None on success. |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
80 ''' |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
81 if not cert: |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
82 return _('no certificate received') |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
83 dnsname = hostname.lower() |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
84 def matchdnsname(certname): |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
85 return (certname == dnsname or |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
86 '.' in dnsname and certname == '*.' + dnsname.split('.', 1)[1]) |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
87 |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
88 san = cert.get('subjectAltName', []) |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
89 if san: |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
90 certnames = [value.lower() for key, value in san if key == 'DNS'] |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
91 for name in certnames: |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
92 if matchdnsname(name): |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
93 return None |
14666
27b080aa880a
sslutil: fall back to commonName when no dNSName in subjectAltName (issue2798)
Nicolas Bareil <nico@chdir.org>
parents:
14616
diff
changeset
|
94 if certnames: |
27b080aa880a
sslutil: fall back to commonName when no dNSName in subjectAltName (issue2798)
Nicolas Bareil <nico@chdir.org>
parents:
14616
diff
changeset
|
95 return _('certificate is for %s') % ', '.join(certnames) |
14204
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
96 |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
97 # subject is only checked when subjectAltName is empty |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
98 for s in cert.get('subject', []): |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
99 key, value = s[0] |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
100 if key == 'commonName': |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
101 try: |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
102 # 'subject' entries are unicode |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
103 certname = value.lower().encode('ascii') |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
104 except UnicodeEncodeError: |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
105 return _('IDN in certificate not supported') |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
106 if matchdnsname(certname): |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
107 return None |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
108 return _('certificate is for %s') % certname |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
109 return _('no commonName or subjectAltName found in certificate') |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
110 |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
111 |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
112 # CERT_REQUIRED means fetch the cert from the server all the time AND |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
113 # validate it against the CA store provided in web.cacerts. |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
114 # |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
115 # We COMPLETELY ignore CERT_REQUIRED on Python <= 2.5, as it's totally |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
116 # busted on those versions. |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
117 |
23042
2cd3fa4412dc
ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents:
22575
diff
changeset
|
118 def _plainapplepython(): |
2cd3fa4412dc
ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents:
22575
diff
changeset
|
119 """return true if this seems to be a pure Apple Python that |
2cd3fa4412dc
ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents:
22575
diff
changeset
|
120 * is unfrozen and presumably has the whole mercurial module in the file |
2cd3fa4412dc
ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents:
22575
diff
changeset
|
121 system |
2cd3fa4412dc
ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents:
22575
diff
changeset
|
122 * presumably is an Apple Python that uses Apple OpenSSL which has patches |
2cd3fa4412dc
ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents:
22575
diff
changeset
|
123 for using system certificate store CAs in addition to the provided |
2cd3fa4412dc
ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents:
22575
diff
changeset
|
124 cacerts file |
2cd3fa4412dc
ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents:
22575
diff
changeset
|
125 """ |
2cd3fa4412dc
ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents:
22575
diff
changeset
|
126 if sys.platform != 'darwin' or util.mainfrozen(): |
2cd3fa4412dc
ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents:
22575
diff
changeset
|
127 return False |
2cd3fa4412dc
ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents:
22575
diff
changeset
|
128 exe = (sys.executable or '').lower() |
2cd3fa4412dc
ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents:
22575
diff
changeset
|
129 return (exe.startswith('/usr/bin/python') or |
2cd3fa4412dc
ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents:
22575
diff
changeset
|
130 exe.startswith('/system/library/frameworks/python.framework/')) |
2cd3fa4412dc
ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents:
22575
diff
changeset
|
131 |
14204
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
132 def sslkwargs(ui, host): |
23849
58080815f667
sslutil: drop support for clients of sslutil specifying a TLS version
Augie Fackler <augie@google.com>
parents:
23834
diff
changeset
|
133 kws = {} |
22574
a00a7951b20c
ssl: refactor sslkwargs - move things around a bit, preparing for next change
Mads Kiilerich <madski@unity3d.com>
parents:
19808
diff
changeset
|
134 hostfingerprint = ui.config('hostfingerprints', host) |
a00a7951b20c
ssl: refactor sslkwargs - move things around a bit, preparing for next change
Mads Kiilerich <madski@unity3d.com>
parents:
19808
diff
changeset
|
135 if hostfingerprint: |
a00a7951b20c
ssl: refactor sslkwargs - move things around a bit, preparing for next change
Mads Kiilerich <madski@unity3d.com>
parents:
19808
diff
changeset
|
136 return kws |
a00a7951b20c
ssl: refactor sslkwargs - move things around a bit, preparing for next change
Mads Kiilerich <madski@unity3d.com>
parents:
19808
diff
changeset
|
137 cacerts = ui.config('web', 'cacerts') |
a00a7951b20c
ssl: refactor sslkwargs - move things around a bit, preparing for next change
Mads Kiilerich <madski@unity3d.com>
parents:
19808
diff
changeset
|
138 if cacerts: |
14204
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
139 cacerts = util.expandpath(cacerts) |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
140 if not os.path.exists(cacerts): |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
141 raise util.Abort(_('could not find web.cacerts: %s') % cacerts) |
23042
2cd3fa4412dc
ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents:
22575
diff
changeset
|
142 elif cacerts is None and _plainapplepython(): |
22575
d7f7f1860f00
ssl: on OS X, use a dummy cert to trick Python/OpenSSL to use system CA certs
Mads Kiilerich <madski@unity3d.com>
parents:
22574
diff
changeset
|
143 dummycert = os.path.join(os.path.dirname(__file__), 'dummycert.pem') |
d7f7f1860f00
ssl: on OS X, use a dummy cert to trick Python/OpenSSL to use system CA certs
Mads Kiilerich <madski@unity3d.com>
parents:
22574
diff
changeset
|
144 if os.path.exists(dummycert): |
d7f7f1860f00
ssl: on OS X, use a dummy cert to trick Python/OpenSSL to use system CA certs
Mads Kiilerich <madski@unity3d.com>
parents:
22574
diff
changeset
|
145 ui.debug('using %s to enable OS X system CA\n' % dummycert) |
d7f7f1860f00
ssl: on OS X, use a dummy cert to trick Python/OpenSSL to use system CA certs
Mads Kiilerich <madski@unity3d.com>
parents:
22574
diff
changeset
|
146 ui.setconfig('web', 'cacerts', dummycert, 'dummy') |
d7f7f1860f00
ssl: on OS X, use a dummy cert to trick Python/OpenSSL to use system CA certs
Mads Kiilerich <madski@unity3d.com>
parents:
22574
diff
changeset
|
147 cacerts = dummycert |
d7f7f1860f00
ssl: on OS X, use a dummy cert to trick Python/OpenSSL to use system CA certs
Mads Kiilerich <madski@unity3d.com>
parents:
22574
diff
changeset
|
148 if cacerts: |
19806
47ff9d1abfa9
sslutil: add a config knob to support TLS (default) or SSLv23 (bc) (issue4038)
Augie Fackler <raf@durin42.com>
parents:
19749
diff
changeset
|
149 kws.update({'ca_certs': cacerts, |
47ff9d1abfa9
sslutil: add a config knob to support TLS (default) or SSLv23 (bc) (issue4038)
Augie Fackler <raf@durin42.com>
parents:
19749
diff
changeset
|
150 'cert_reqs': CERT_REQUIRED, |
47ff9d1abfa9
sslutil: add a config knob to support TLS (default) or SSLv23 (bc) (issue4038)
Augie Fackler <raf@durin42.com>
parents:
19749
diff
changeset
|
151 }) |
47ff9d1abfa9
sslutil: add a config knob to support TLS (default) or SSLv23 (bc) (issue4038)
Augie Fackler <raf@durin42.com>
parents:
19749
diff
changeset
|
152 return kws |
14204
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
153 |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
154 class validator(object): |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
155 def __init__(self, ui, host): |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
156 self.ui = ui |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
157 self.host = host |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
158 |
18887
2d7fac049d3a
sslutil: abort if peer certificate is not verified for secure use
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
18879
diff
changeset
|
159 def __call__(self, sock, strict=False): |
14204
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
160 host = self.host |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
161 cacerts = self.ui.config('web', 'cacerts') |
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
162 hostfingerprint = self.ui.config('hostfingerprints', host) |
15813
3ae04eb5e38a
sslutil: handle setups without .getpeercert() early in the validator
Mads Kiilerich <mads@kiilerich.com>
parents:
15812
diff
changeset
|
163 if not getattr(sock, 'getpeercert', False): # python 2.5 ? |
3ae04eb5e38a
sslutil: handle setups without .getpeercert() early in the validator
Mads Kiilerich <mads@kiilerich.com>
parents:
15812
diff
changeset
|
164 if hostfingerprint: |
3ae04eb5e38a
sslutil: handle setups without .getpeercert() early in the validator
Mads Kiilerich <mads@kiilerich.com>
parents:
15812
diff
changeset
|
165 raise util.Abort(_("host fingerprint for %s can't be " |
3ae04eb5e38a
sslutil: handle setups without .getpeercert() early in the validator
Mads Kiilerich <mads@kiilerich.com>
parents:
15812
diff
changeset
|
166 "verified (Python too old)") % host) |
18887
2d7fac049d3a
sslutil: abort if peer certificate is not verified for secure use
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
18879
diff
changeset
|
167 if strict: |
2d7fac049d3a
sslutil: abort if peer certificate is not verified for secure use
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
18879
diff
changeset
|
168 raise util.Abort(_("certificate for %s can't be verified " |
2d7fac049d3a
sslutil: abort if peer certificate is not verified for secure use
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
18879
diff
changeset
|
169 "(Python too old)") % host) |
16391
9cf7c9d529d0
ui: optionally quiesce ssl verification warnings on python 2.5
Steven Stallion <sstallion@gmail.com>
parents:
15997
diff
changeset
|
170 if self.ui.configbool('ui', 'reportoldssl', True): |
9cf7c9d529d0
ui: optionally quiesce ssl verification warnings on python 2.5
Steven Stallion <sstallion@gmail.com>
parents:
15997
diff
changeset
|
171 self.ui.warn(_("warning: certificate for %s can't be verified " |
9cf7c9d529d0
ui: optionally quiesce ssl verification warnings on python 2.5
Steven Stallion <sstallion@gmail.com>
parents:
15997
diff
changeset
|
172 "(Python too old)\n") % host) |
15813
3ae04eb5e38a
sslutil: handle setups without .getpeercert() early in the validator
Mads Kiilerich <mads@kiilerich.com>
parents:
15812
diff
changeset
|
173 return |
18879
93b03a222c3e
sslutil: try harder to avoid getpeercert problems
Matt Mackall <mpm@selenic.com>
parents:
16391
diff
changeset
|
174 |
15816
4bb59919c905
sslutil: work around validator crash getting certificate on failed sockets
Mads Kiilerich <mads@kiilerich.com>
parents:
15815
diff
changeset
|
175 if not sock.cipher(): # work around http://bugs.python.org/issue13721 |
4bb59919c905
sslutil: work around validator crash getting certificate on failed sockets
Mads Kiilerich <mads@kiilerich.com>
parents:
15815
diff
changeset
|
176 raise util.Abort(_('%s ssl connection error') % host) |
18879
93b03a222c3e
sslutil: try harder to avoid getpeercert problems
Matt Mackall <mpm@selenic.com>
parents:
16391
diff
changeset
|
177 try: |
93b03a222c3e
sslutil: try harder to avoid getpeercert problems
Matt Mackall <mpm@selenic.com>
parents:
16391
diff
changeset
|
178 peercert = sock.getpeercert(True) |
93b03a222c3e
sslutil: try harder to avoid getpeercert problems
Matt Mackall <mpm@selenic.com>
parents:
16391
diff
changeset
|
179 peercert2 = sock.getpeercert() |
93b03a222c3e
sslutil: try harder to avoid getpeercert problems
Matt Mackall <mpm@selenic.com>
parents:
16391
diff
changeset
|
180 except AttributeError: |
93b03a222c3e
sslutil: try harder to avoid getpeercert problems
Matt Mackall <mpm@selenic.com>
parents:
16391
diff
changeset
|
181 raise util.Abort(_('%s ssl connection error') % host) |
93b03a222c3e
sslutil: try harder to avoid getpeercert problems
Matt Mackall <mpm@selenic.com>
parents:
16391
diff
changeset
|
182 |
15817
8f377751b510
sslutil: abort properly if no certificate received for https connection
Mads Kiilerich <mads@kiilerich.com>
parents:
15816
diff
changeset
|
183 if not peercert: |
8f377751b510
sslutil: abort properly if no certificate received for https connection
Mads Kiilerich <mads@kiilerich.com>
parents:
15816
diff
changeset
|
184 raise util.Abort(_('%s certificate error: ' |
8f377751b510
sslutil: abort properly if no certificate received for https connection
Mads Kiilerich <mads@kiilerich.com>
parents:
15816
diff
changeset
|
185 'no certificate received') % host) |
15814
c3e958b50a22
sslutil: show fingerprint when cacerts validation fails
Mads Kiilerich <mads@kiilerich.com>
parents:
15813
diff
changeset
|
186 peerfingerprint = util.sha1(peercert).hexdigest() |
c3e958b50a22
sslutil: show fingerprint when cacerts validation fails
Mads Kiilerich <mads@kiilerich.com>
parents:
15813
diff
changeset
|
187 nicefingerprint = ":".join([peerfingerprint[x:x + 2] |
c3e958b50a22
sslutil: show fingerprint when cacerts validation fails
Mads Kiilerich <mads@kiilerich.com>
parents:
15813
diff
changeset
|
188 for x in xrange(0, len(peerfingerprint), 2)]) |
15815
edc3a901a63d
sslutil: reorder validator code to make it more readable
Mads Kiilerich <mads@kiilerich.com>
parents:
15814
diff
changeset
|
189 if hostfingerprint: |
edc3a901a63d
sslutil: reorder validator code to make it more readable
Mads Kiilerich <mads@kiilerich.com>
parents:
15814
diff
changeset
|
190 if peerfingerprint.lower() != \ |
edc3a901a63d
sslutil: reorder validator code to make it more readable
Mads Kiilerich <mads@kiilerich.com>
parents:
15814
diff
changeset
|
191 hostfingerprint.replace(':', '').lower(): |
15997
a45516cb8d9f
sslutil: more helpful fingerprint mismatch message
Matt Mackall <mpm@selenic.com>
parents:
15817
diff
changeset
|
192 raise util.Abort(_('certificate for %s has unexpected ' |
a45516cb8d9f
sslutil: more helpful fingerprint mismatch message
Matt Mackall <mpm@selenic.com>
parents:
15817
diff
changeset
|
193 'fingerprint %s') % (host, nicefingerprint), |
a45516cb8d9f
sslutil: more helpful fingerprint mismatch message
Matt Mackall <mpm@selenic.com>
parents:
15817
diff
changeset
|
194 hint=_('check hostfingerprint configuration')) |
15815
edc3a901a63d
sslutil: reorder validator code to make it more readable
Mads Kiilerich <mads@kiilerich.com>
parents:
15814
diff
changeset
|
195 self.ui.debug('%s certificate matched fingerprint %s\n' % |
edc3a901a63d
sslutil: reorder validator code to make it more readable
Mads Kiilerich <mads@kiilerich.com>
parents:
15814
diff
changeset
|
196 (host, nicefingerprint)) |
edc3a901a63d
sslutil: reorder validator code to make it more readable
Mads Kiilerich <mads@kiilerich.com>
parents:
15814
diff
changeset
|
197 elif cacerts: |
18879
93b03a222c3e
sslutil: try harder to avoid getpeercert problems
Matt Mackall <mpm@selenic.com>
parents:
16391
diff
changeset
|
198 msg = _verifycert(peercert2, host) |
14204
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
199 if msg: |
15814
c3e958b50a22
sslutil: show fingerprint when cacerts validation fails
Mads Kiilerich <mads@kiilerich.com>
parents:
15813
diff
changeset
|
200 raise util.Abort(_('%s certificate error: %s') % (host, msg), |
c3e958b50a22
sslutil: show fingerprint when cacerts validation fails
Mads Kiilerich <mads@kiilerich.com>
parents:
15813
diff
changeset
|
201 hint=_('configure hostfingerprint %s or use ' |
c3e958b50a22
sslutil: show fingerprint when cacerts validation fails
Mads Kiilerich <mads@kiilerich.com>
parents:
15813
diff
changeset
|
202 '--insecure to connect insecurely') % |
c3e958b50a22
sslutil: show fingerprint when cacerts validation fails
Mads Kiilerich <mads@kiilerich.com>
parents:
15813
diff
changeset
|
203 nicefingerprint) |
14204
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
204 self.ui.debug('%s certificate successfully verified\n' % host) |
18887
2d7fac049d3a
sslutil: abort if peer certificate is not verified for secure use
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
18879
diff
changeset
|
205 elif strict: |
2d7fac049d3a
sslutil: abort if peer certificate is not verified for secure use
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
18879
diff
changeset
|
206 raise util.Abort(_('%s certificate with fingerprint %s not ' |
2d7fac049d3a
sslutil: abort if peer certificate is not verified for secure use
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
18879
diff
changeset
|
207 'verified') % (host, nicefingerprint), |
2d7fac049d3a
sslutil: abort if peer certificate is not verified for secure use
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
18879
diff
changeset
|
208 hint=_('check hostfingerprints or web.cacerts ' |
2d7fac049d3a
sslutil: abort if peer certificate is not verified for secure use
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
18879
diff
changeset
|
209 'config setting')) |
14204
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
210 else: |
15815
edc3a901a63d
sslutil: reorder validator code to make it more readable
Mads Kiilerich <mads@kiilerich.com>
parents:
15814
diff
changeset
|
211 self.ui.warn(_('warning: %s certificate with fingerprint %s not ' |
edc3a901a63d
sslutil: reorder validator code to make it more readable
Mads Kiilerich <mads@kiilerich.com>
parents:
15814
diff
changeset
|
212 'verified (check hostfingerprints or web.cacerts ' |
edc3a901a63d
sslutil: reorder validator code to make it more readable
Mads Kiilerich <mads@kiilerich.com>
parents:
15814
diff
changeset
|
213 'config setting)\n') % |
edc3a901a63d
sslutil: reorder validator code to make it more readable
Mads Kiilerich <mads@kiilerich.com>
parents:
15814
diff
changeset
|
214 (host, nicefingerprint)) |