mercurial/sslutil.py
author Gregory Szorc <gregory.szorc@gmail.com>
Sat, 28 May 2016 12:58:46 -0700
changeset 29268 f200b58497f1
parent 29267 f0ccb6cde3e5
child 29286 a05a91a3f120
permissions -rw-r--r--
sslutil: reference appropriate config section in messaging Error messages reference the config section defining the host fingerprint. Now that we have multiple sections where this config setting could live, we need to point the user at the appropriate one. We default to the new "hostsecurity" section. But we will still refer them to the "hostfingerprint" section if a value is defined there. There are some corner cases where the messaging might be off. e.g. they could define a SHA-1 fingerprint in both sections. IMO the messaging needs a massive overhaul. I plan to do this as part of future refactoring to security settings.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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.
25977
696f6e2be282 sslutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25432
diff changeset
     9
696f6e2be282 sslutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25432
diff changeset
    10
from __future__ import absolute_import
14204
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
    11
25977
696f6e2be282 sslutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25432
diff changeset
    12
import os
696f6e2be282 sslutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25432
diff changeset
    13
import ssl
696f6e2be282 sslutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25432
diff changeset
    14
import sys
696f6e2be282 sslutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25432
diff changeset
    15
696f6e2be282 sslutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25432
diff changeset
    16
from .i18n import _
28577
7efff6ce9826 sslutil: use preferred formatting for import syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28525
diff changeset
    17
from . import (
7efff6ce9826 sslutil: use preferred formatting for import syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28525
diff changeset
    18
    error,
7efff6ce9826 sslutil: use preferred formatting for import syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28525
diff changeset
    19
    util,
7efff6ce9826 sslutil: use preferred formatting for import syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28525
diff changeset
    20
)
24291
760a86865f80 ssl: load CA certificates from system's store by default on Python 2.7.9
Yuya Nishihara <yuya@tcha.org>
parents: 24290
diff changeset
    21
28647
834d1c4ba749 sslutil: better document state of security/ssl module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28577
diff changeset
    22
# Python 2.7.9+ overhauled the built-in SSL/TLS features of Python. It added
834d1c4ba749 sslutil: better document state of security/ssl module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28577
diff changeset
    23
# support for TLS 1.1, TLS 1.2, SNI, system CA stores, etc. These features are
834d1c4ba749 sslutil: better document state of security/ssl module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28577
diff changeset
    24
# all exposed via the "ssl" module.
834d1c4ba749 sslutil: better document state of security/ssl module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28577
diff changeset
    25
#
834d1c4ba749 sslutil: better document state of security/ssl module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28577
diff changeset
    26
# Depending on the version of Python being used, SSL/TLS support is either
834d1c4ba749 sslutil: better document state of security/ssl module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28577
diff changeset
    27
# modern/secure or legacy/insecure. Many operations in this module have
834d1c4ba749 sslutil: better document state of security/ssl module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28577
diff changeset
    28
# separate code paths depending on support in Python.
834d1c4ba749 sslutil: better document state of security/ssl module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28577
diff changeset
    29
26622
9e15286609ae sslutil: expose attribute indicating whether SNI is supported
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
    30
hassni = getattr(ssl, 'HAS_SNI', False)
9e15286609ae sslutil: expose attribute indicating whether SNI is supported
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
    31
28648
7fc787e5d8ec sslutil: store OP_NO_SSL* constants in module scope
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28647
diff changeset
    32
try:
7fc787e5d8ec sslutil: store OP_NO_SSL* constants in module scope
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28647
diff changeset
    33
    OP_NO_SSLv2 = ssl.OP_NO_SSLv2
7fc787e5d8ec sslutil: store OP_NO_SSL* constants in module scope
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28647
diff changeset
    34
    OP_NO_SSLv3 = ssl.OP_NO_SSLv3
7fc787e5d8ec sslutil: store OP_NO_SSL* constants in module scope
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28647
diff changeset
    35
except AttributeError:
7fc787e5d8ec sslutil: store OP_NO_SSL* constants in module scope
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28647
diff changeset
    36
    OP_NO_SSLv2 = 0x1000000
7fc787e5d8ec sslutil: store OP_NO_SSL* constants in module scope
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28647
diff changeset
    37
    OP_NO_SSLv3 = 0x2000000
7fc787e5d8ec sslutil: store OP_NO_SSL* constants in module scope
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28647
diff changeset
    38
28649
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    39
try:
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    40
    # ssl.SSLContext was added in 2.7.9 and presence indicates modern
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    41
    # SSL/TLS features are available.
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    42
    SSLContext = ssl.SSLContext
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    43
    modernssl = True
28650
737863b01d9f sslutil: move _canloaddefaultcerts logic
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28649
diff changeset
    44
    _canloaddefaultcerts = util.safehasattr(SSLContext, 'load_default_certs')
28649
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    45
except AttributeError:
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    46
    modernssl = False
28650
737863b01d9f sslutil: move _canloaddefaultcerts logic
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28649
diff changeset
    47
    _canloaddefaultcerts = False
28649
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    48
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    49
    # We implement SSLContext using the interface from the standard library.
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    50
    class SSLContext(object):
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    51
        # ssl.wrap_socket gained the "ciphers" named argument in 2.7.
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    52
        _supportsciphers = sys.version_info >= (2, 7)
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    53
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    54
        def __init__(self, protocol):
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    55
            # From the public interface of SSLContext
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    56
            self.protocol = protocol
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    57
            self.check_hostname = False
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    58
            self.options = 0
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    59
            self.verify_mode = ssl.CERT_NONE
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    60
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    61
            # Used by our implementation.
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    62
            self._certfile = None
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    63
            self._keyfile = None
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    64
            self._certpassword = None
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    65
            self._cacerts = None
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    66
            self._ciphers = None
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    67
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    68
        def load_cert_chain(self, certfile, keyfile=None, password=None):
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    69
            self._certfile = certfile
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    70
            self._keyfile = keyfile
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    71
            self._certpassword = password
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    72
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    73
        def load_default_certs(self, purpose=None):
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    74
            pass
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    75
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    76
        def load_verify_locations(self, cafile=None, capath=None, cadata=None):
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    77
            if capath:
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    78
                raise error.Abort('capath not supported')
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    79
            if cadata:
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    80
                raise error.Abort('cadata not supported')
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    81
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    82
            self._cacerts = cafile
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    83
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    84
        def set_ciphers(self, ciphers):
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    85
            if not self._supportsciphers:
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    86
                raise error.Abort('setting ciphers not supported')
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    87
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    88
            self._ciphers = ciphers
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    89
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    90
        def wrap_socket(self, socket, server_hostname=None, server_side=False):
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    91
            # server_hostname is unique to SSLContext.wrap_socket and is used
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    92
            # for SNI in that context. So there's nothing for us to do with it
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    93
            # in this legacy code since we don't support SNI.
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    94
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    95
            args = {
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    96
                'keyfile': self._keyfile,
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    97
                'certfile': self._certfile,
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    98
                'server_side': server_side,
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
    99
                'cert_reqs': self.verify_mode,
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
   100
                'ssl_version': self.protocol,
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
   101
                'ca_certs': self._cacerts,
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
   102
            }
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
   103
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
   104
            if self._supportsciphers:
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
   105
                args['ciphers'] = self._ciphers
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
   106
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
   107
            return ssl.wrap_socket(socket, **args)
7acab42ef184 sslutil: implement SSLContext class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28648
diff changeset
   108
29258
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
   109
def _hostsettings(ui, hostname):
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
   110
    """Obtain security settings for a hostname.
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
   111
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
   112
    Returns a dict of settings relevant to that hostname.
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
   113
    """
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
   114
    s = {
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
   115
        # List of 2-tuple of (hash algorithm, hash).
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
   116
        'certfingerprints': [],
29260
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   117
        # Path to file containing concatenated CA certs. Used by
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   118
        # SSLContext.load_verify_locations().
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   119
        'cafile': None,
29268
f200b58497f1 sslutil: reference appropriate config section in messaging
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29267
diff changeset
   120
        # Whether the legacy [hostfingerprints] section has data for this host.
f200b58497f1 sslutil: reference appropriate config section in messaging
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29267
diff changeset
   121
        'legacyfingerprint': False,
29259
ec247e8595f9 sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29258
diff changeset
   122
        # ssl.CERT_* constant used by SSLContext.verify_mode.
ec247e8595f9 sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29258
diff changeset
   123
        'verifymode': None,
29258
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
   124
    }
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
   125
29267
f0ccb6cde3e5 sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29262
diff changeset
   126
    # Look for fingerprints in [hostsecurity] section. Value is a list
f0ccb6cde3e5 sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29262
diff changeset
   127
    # of <alg>:<fingerprint> strings.
f0ccb6cde3e5 sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29262
diff changeset
   128
    fingerprints = ui.configlist('hostsecurity', '%s:fingerprints' % hostname,
f0ccb6cde3e5 sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29262
diff changeset
   129
                                 [])
f0ccb6cde3e5 sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29262
diff changeset
   130
    for fingerprint in fingerprints:
f0ccb6cde3e5 sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29262
diff changeset
   131
        if not (fingerprint.startswith(('sha1:', 'sha256:', 'sha512:'))):
f0ccb6cde3e5 sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29262
diff changeset
   132
            raise error.Abort(_('invalid fingerprint for %s: %s') % (
f0ccb6cde3e5 sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29262
diff changeset
   133
                                hostname, fingerprint),
f0ccb6cde3e5 sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29262
diff changeset
   134
                              hint=_('must begin with "sha1:", "sha256:", '
f0ccb6cde3e5 sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29262
diff changeset
   135
                                     'or "sha512:"'))
f0ccb6cde3e5 sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29262
diff changeset
   136
f0ccb6cde3e5 sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29262
diff changeset
   137
        alg, fingerprint = fingerprint.split(':', 1)
f0ccb6cde3e5 sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29262
diff changeset
   138
        fingerprint = fingerprint.replace(':', '').lower()
f0ccb6cde3e5 sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29262
diff changeset
   139
        s['certfingerprints'].append((alg, fingerprint))
f0ccb6cde3e5 sslutil: allow fingerprints to be specified in [hostsecurity]
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29262
diff changeset
   140
29258
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
   141
    # Fingerprints from [hostfingerprints] are always SHA-1.
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
   142
    for fingerprint in ui.configlist('hostfingerprints', hostname, []):
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
   143
        fingerprint = fingerprint.replace(':', '').lower()
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
   144
        s['certfingerprints'].append(('sha1', fingerprint))
29268
f200b58497f1 sslutil: reference appropriate config section in messaging
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29267
diff changeset
   145
        s['legacyfingerprint'] = True
29258
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
   146
29259
ec247e8595f9 sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29258
diff changeset
   147
    # If a host cert fingerprint is defined, it is the only thing that
ec247e8595f9 sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29258
diff changeset
   148
    # matters. No need to validate CA certs.
ec247e8595f9 sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29258
diff changeset
   149
    if s['certfingerprints']:
ec247e8595f9 sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29258
diff changeset
   150
        s['verifymode'] = ssl.CERT_NONE
ec247e8595f9 sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29258
diff changeset
   151
ec247e8595f9 sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29258
diff changeset
   152
    # If --insecure is used, don't take CAs into consideration.
ec247e8595f9 sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29258
diff changeset
   153
    elif ui.insecureconnections:
ec247e8595f9 sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29258
diff changeset
   154
        s['verifymode'] = ssl.CERT_NONE
ec247e8595f9 sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29258
diff changeset
   155
29260
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   156
    # Try to hook up CA certificate validation unless something above
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   157
    # makes it not necessary.
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   158
    if s['verifymode'] is None:
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   159
        # Find global certificates file in config.
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   160
        cafile = ui.config('web', 'cacerts')
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   161
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   162
        if cafile:
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   163
            cafile = util.expandpath(cafile)
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   164
            if not os.path.exists(cafile):
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   165
                raise error.Abort(_('could not find web.cacerts: %s') % cafile)
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   166
        else:
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   167
            # No global CA certs. See if we can load defaults.
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   168
            cafile = _defaultcacerts()
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   169
            if cafile:
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   170
                ui.debug('using %s to enable OS X system CA\n' % cafile)
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   171
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   172
        s['cafile'] = cafile
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   173
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   174
        # Require certificate validation if CA certs are being loaded and
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   175
        # verification hasn't been disabled above.
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   176
        if cafile or _canloaddefaultcerts:
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   177
            s['verifymode'] = ssl.CERT_REQUIRED
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   178
        else:
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   179
            # At this point we don't have a fingerprint, aren't being
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   180
            # explicitly insecure, and can't load CA certs. Connecting
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   181
            # at this point is insecure. But we do it for BC reasons.
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   182
            # TODO abort here to make secure by default.
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   183
            s['verifymode'] = ssl.CERT_NONE
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   184
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   185
    assert s['verifymode'] is not None
29259
ec247e8595f9 sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29258
diff changeset
   186
29258
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
   187
    return s
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
   188
29249
cca59ef27e60 sslutil: move sslkwargs logic into internal function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29248
diff changeset
   189
def wrapsocket(sock, keyfile, certfile, ui, serverhostname=None):
28653
1eb0bd8adf39 sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28652
diff changeset
   190
    """Add SSL/TLS to a socket.
1eb0bd8adf39 sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28652
diff changeset
   191
1eb0bd8adf39 sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28652
diff changeset
   192
    This is a glorified wrapper for ``ssl.wrap_socket()``. It makes sane
1eb0bd8adf39 sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28652
diff changeset
   193
    choices based on what security options are available.
1eb0bd8adf39 sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28652
diff changeset
   194
1eb0bd8adf39 sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28652
diff changeset
   195
    In addition to the arguments supported by ``ssl.wrap_socket``, we allow
1eb0bd8adf39 sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28652
diff changeset
   196
    the following additional arguments:
1eb0bd8adf39 sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28652
diff changeset
   197
1eb0bd8adf39 sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28652
diff changeset
   198
    * serverhostname - The expected hostname of the remote server. If the
1eb0bd8adf39 sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28652
diff changeset
   199
      server (and client) support SNI, this tells the server which certificate
1eb0bd8adf39 sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28652
diff changeset
   200
      to use.
1eb0bd8adf39 sslutil: add docstring to wrapsocket()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28652
diff changeset
   201
    """
29224
7424f4294199 sslutil: require serverhostname argument (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29115
diff changeset
   202
    if not serverhostname:
7424f4294199 sslutil: require serverhostname argument (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29115
diff changeset
   203
        raise error.Abort('serverhostname argument is required')
7424f4294199 sslutil: require serverhostname argument (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29115
diff changeset
   204
29259
ec247e8595f9 sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29258
diff changeset
   205
    settings = _hostsettings(ui, serverhostname)
29249
cca59ef27e60 sslutil: move sslkwargs logic into internal function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29248
diff changeset
   206
28652
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   207
    # Despite its name, PROTOCOL_SSLv23 selects the highest protocol
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   208
    # that both ends support, including TLS protocols. On legacy stacks,
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   209
    # the highest it likely goes in TLS 1.0. On modern stacks, it can
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   210
    # support TLS 1.2.
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   211
    #
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   212
    # The PROTOCOL_TLSv* constants select a specific TLS version
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   213
    # only (as opposed to multiple versions). So the method for
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   214
    # supporting multiple TLS versions is to use PROTOCOL_SSLv23 and
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   215
    # disable protocols via SSLContext.options and OP_NO_* constants.
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   216
    # However, SSLContext.options doesn't work unless we have the
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   217
    # full/real SSLContext available to us.
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   218
    #
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   219
    # SSLv2 and SSLv3 are broken. We ban them outright.
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   220
    if modernssl:
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   221
        protocol = ssl.PROTOCOL_SSLv23
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   222
    else:
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   223
        protocol = ssl.PROTOCOL_TLSv1
28651
4827d07073e6 sslutil: always use SSLContext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28650
diff changeset
   224
28652
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   225
    # TODO use ssl.create_default_context() on modernssl.
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   226
    sslcontext = SSLContext(protocol)
28651
4827d07073e6 sslutil: always use SSLContext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28650
diff changeset
   227
28652
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   228
    # This is a no-op on old Python.
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   229
    sslcontext.options |= OP_NO_SSLv2 | OP_NO_SSLv3
28651
4827d07073e6 sslutil: always use SSLContext
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28650
diff changeset
   230
28848
e330db205b20 sslutil: move and document verify_mode assignment
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28653
diff changeset
   231
    # This still works on our fake SSLContext.
29260
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   232
    sslcontext.verify_mode = settings['verifymode']
28848
e330db205b20 sslutil: move and document verify_mode assignment
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28653
diff changeset
   233
28652
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   234
    if certfile is not None:
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   235
        def password():
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   236
            f = keyfile or certfile
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   237
            return ui.getpass(_('passphrase for %s: ') % f, '')
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   238
        sslcontext.load_cert_chain(certfile, keyfile, password)
28848
e330db205b20 sslutil: move and document verify_mode assignment
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28653
diff changeset
   239
29260
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   240
    if settings['cafile'] is not None:
70bc9912d83d sslutil: move CA file processing into _hostsettings()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29259
diff changeset
   241
        sslcontext.load_verify_locations(cafile=settings['cafile'])
29113
5b9577edf745 sslutil: use CA loaded state to drive validation logic
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29112
diff changeset
   242
        caloaded = True
28652
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   243
    else:
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   244
        # This is a no-op on old Python.
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   245
        sslcontext.load_default_certs()
29113
5b9577edf745 sslutil: use CA loaded state to drive validation logic
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29112
diff changeset
   246
        caloaded = _canloaddefaultcerts
23834
bf07c19b4c82 https: support tls sni (server name indication) for https urls (issue3090)
Alex Orange <crazycasta@gmail.com>
parents: 23069
diff changeset
   247
28652
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   248
    sslsocket = sslcontext.wrap_socket(sock, server_hostname=serverhostname)
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   249
    # check if wrap_socket failed silently because socket had been
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   250
    # closed
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   251
    # - see http://bugs.python.org/issue13721
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   252
    if not sslsocket.cipher():
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   253
        raise error.Abort(_('ssl connection failed'))
29113
5b9577edf745 sslutil: use CA loaded state to drive validation logic
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29112
diff changeset
   254
29225
b115eed11780 sslutil: use a dict for hanging hg state off the wrapped socket
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29224
diff changeset
   255
    sslsocket._hgstate = {
b115eed11780 sslutil: use a dict for hanging hg state off the wrapped socket
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29224
diff changeset
   256
        'caloaded': caloaded,
29226
33006bd6a1d7 sslutil: store and use hostname and ui in socket instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29225
diff changeset
   257
        'hostname': serverhostname,
29259
ec247e8595f9 sslutil: move SSLContext.verify_mode value into _hostsettings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29258
diff changeset
   258
        'settings': settings,
29226
33006bd6a1d7 sslutil: store and use hostname and ui in socket instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29225
diff changeset
   259
        'ui': ui,
29225
b115eed11780 sslutil: use a dict for hanging hg state off the wrapped socket
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29224
diff changeset
   260
    }
29113
5b9577edf745 sslutil: use CA loaded state to drive validation logic
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29112
diff changeset
   261
28652
c617614aefd2 sslutil: remove indentation in wrapsocket declaration
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28651
diff changeset
   262
    return sslsocket
14204
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   263
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   264
def _verifycert(cert, hostname):
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   265
    '''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
   266
    CRLs is not handled.
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   267
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   268
    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
   269
    '''
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   270
    if not cert:
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   271
        return _('no certificate received')
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   272
    dnsname = hostname.lower()
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   273
    def matchdnsname(certname):
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   274
        return (certname == dnsname or
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   275
                '.' 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
   276
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   277
    san = cert.get('subjectAltName', [])
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   278
    if san:
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   279
        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
   280
        for name in certnames:
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   281
            if matchdnsname(name):
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   282
                return None
14666
27b080aa880a sslutil: fall back to commonName when no dNSName in subjectAltName (issue2798)
Nicolas Bareil <nico@chdir.org>
parents: 14616
diff changeset
   283
        if certnames:
27b080aa880a sslutil: fall back to commonName when no dNSName in subjectAltName (issue2798)
Nicolas Bareil <nico@chdir.org>
parents: 14616
diff changeset
   284
            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
   285
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   286
    # 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
   287
    for s in cert.get('subject', []):
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   288
        key, value = s[0]
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   289
        if key == 'commonName':
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   290
            try:
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   291
                # 'subject' entries are unicode
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   292
                certname = value.lower().encode('ascii')
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   293
            except UnicodeEncodeError:
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   294
                return _('IDN in certificate not supported')
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   295
            if matchdnsname(certname):
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   296
                return None
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   297
            return _('certificate is for %s') % certname
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   298
    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
   299
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   300
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   301
# 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
   302
# 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
   303
23042
2cd3fa4412dc ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents: 22575
diff changeset
   304
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
   305
    """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
   306
    * 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
   307
      system
2cd3fa4412dc ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents: 22575
diff changeset
   308
    * 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
   309
      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
   310
      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
   311
    """
24614
241d98d84aed ssl: resolve symlink before checking for Apple python executable (issue4588)
Yuya Nishihara <yuya@tcha.org>
parents: 24291
diff changeset
   312
    if sys.platform != 'darwin' or util.mainfrozen() or not sys.executable:
23042
2cd3fa4412dc ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents: 22575
diff changeset
   313
        return False
24614
241d98d84aed ssl: resolve symlink before checking for Apple python executable (issue4588)
Yuya Nishihara <yuya@tcha.org>
parents: 24291
diff changeset
   314
    exe = os.path.realpath(sys.executable).lower()
23042
2cd3fa4412dc ssl: only use the dummy cert hack if using an Apple Python (issue4410)
Mads Kiilerich <madski@unity3d.com>
parents: 22575
diff changeset
   315
    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
   316
            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
   317
24288
922e087ba158 ssl: extract function that returns dummycert path on Apple python
Yuya Nishihara <yuya@tcha.org>
parents: 23851
diff changeset
   318
def _defaultcacerts():
29107
c8fbfb9163ce sslutil: move code examining _canloaddefaultcerts out of _defaultcacerts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29106
diff changeset
   319
    """return path to default CA certificates or None."""
24288
922e087ba158 ssl: extract function that returns dummycert path on Apple python
Yuya Nishihara <yuya@tcha.org>
parents: 23851
diff changeset
   320
    if _plainapplepython():
922e087ba158 ssl: extract function that returns dummycert path on Apple python
Yuya Nishihara <yuya@tcha.org>
parents: 23851
diff changeset
   321
        dummycert = os.path.join(os.path.dirname(__file__), 'dummycert.pem')
922e087ba158 ssl: extract function that returns dummycert path on Apple python
Yuya Nishihara <yuya@tcha.org>
parents: 23851
diff changeset
   322
        if os.path.exists(dummycert):
922e087ba158 ssl: extract function that returns dummycert path on Apple python
Yuya Nishihara <yuya@tcha.org>
parents: 23851
diff changeset
   323
            return dummycert
29107
c8fbfb9163ce sslutil: move code examining _canloaddefaultcerts out of _defaultcacerts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29106
diff changeset
   324
c8fbfb9163ce sslutil: move code examining _canloaddefaultcerts out of _defaultcacerts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29106
diff changeset
   325
    return None
24288
922e087ba158 ssl: extract function that returns dummycert path on Apple python
Yuya Nishihara <yuya@tcha.org>
parents: 23851
diff changeset
   326
29227
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   327
def validatesocket(sock, strict=False):
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   328
    """Validate a socket meets security requiremnets.
14204
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
   329
29227
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   330
    The passed socket must have been created with ``wrapsocket()``.
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   331
    """
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   332
    host = sock._hgstate['hostname']
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   333
    ui = sock._hgstate['ui']
29258
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
   334
    settings = sock._hgstate['settings']
18879
93b03a222c3e sslutil: try harder to avoid getpeercert problems
Matt Mackall <mpm@selenic.com>
parents: 16391
diff changeset
   335
29227
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   336
    try:
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   337
        peercert = sock.getpeercert(True)
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   338
        peercert2 = sock.getpeercert()
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   339
    except AttributeError:
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   340
        raise error.Abort(_('%s ssl connection error') % host)
18879
93b03a222c3e sslutil: try harder to avoid getpeercert problems
Matt Mackall <mpm@selenic.com>
parents: 16391
diff changeset
   341
29227
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   342
    if not peercert:
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   343
        raise error.Abort(_('%s certificate error: '
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   344
                           'no certificate received') % host)
28850
3819c349b194 sslutil: document and slightly refactor validation logic
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28849
diff changeset
   345
29227
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   346
    # If a certificate fingerprint is pinned, use it and only it to
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   347
    # validate the remote cert.
29262
dfc4f08aa160 sslutil: calculate host fingerprints from additional algorithms
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29260
diff changeset
   348
    peerfingerprints = {
dfc4f08aa160 sslutil: calculate host fingerprints from additional algorithms
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29260
diff changeset
   349
        'sha1': util.sha1(peercert).hexdigest(),
dfc4f08aa160 sslutil: calculate host fingerprints from additional algorithms
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29260
diff changeset
   350
        'sha256': util.sha256(peercert).hexdigest(),
dfc4f08aa160 sslutil: calculate host fingerprints from additional algorithms
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29260
diff changeset
   351
        'sha512': util.sha512(peercert).hexdigest(),
dfc4f08aa160 sslutil: calculate host fingerprints from additional algorithms
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29260
diff changeset
   352
    }
dfc4f08aa160 sslutil: calculate host fingerprints from additional algorithms
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29260
diff changeset
   353
    nicefingerprint = ':'.join([peerfingerprints['sha1'][x:x + 2]
dfc4f08aa160 sslutil: calculate host fingerprints from additional algorithms
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29260
diff changeset
   354
        for x in range(0, len(peerfingerprints['sha1']), 2)])
dfc4f08aa160 sslutil: calculate host fingerprints from additional algorithms
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29260
diff changeset
   355
29268
f200b58497f1 sslutil: reference appropriate config section in messaging
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29267
diff changeset
   356
    if settings['legacyfingerprint']:
f200b58497f1 sslutil: reference appropriate config section in messaging
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29267
diff changeset
   357
        section = 'hostfingerprint'
f200b58497f1 sslutil: reference appropriate config section in messaging
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29267
diff changeset
   358
    else:
f200b58497f1 sslutil: reference appropriate config section in messaging
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29267
diff changeset
   359
        section = 'hostsecurity'
f200b58497f1 sslutil: reference appropriate config section in messaging
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29267
diff changeset
   360
29258
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
   361
    if settings['certfingerprints']:
29227
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   362
        fingerprintmatch = False
29258
6315c1e14f75 sslutil: introduce a function for determining host-specific settings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29253
diff changeset
   363
        for hash, fingerprint in settings['certfingerprints']:
29262
dfc4f08aa160 sslutil: calculate host fingerprints from additional algorithms
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29260
diff changeset
   364
            if peerfingerprints[hash].lower() == fingerprint:
29227
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   365
                fingerprintmatch = True
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   366
                break
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   367
        if not fingerprintmatch:
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   368
            raise error.Abort(_('certificate for %s has unexpected '
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   369
                               'fingerprint %s') % (host, nicefingerprint),
29268
f200b58497f1 sslutil: reference appropriate config section in messaging
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29267
diff changeset
   370
                             hint=_('check %s configuration') % section)
29227
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   371
        ui.debug('%s certificate matched fingerprint %s\n' %
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   372
                 (host, nicefingerprint))
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   373
        return
28850
3819c349b194 sslutil: document and slightly refactor validation logic
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28849
diff changeset
   374
29227
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   375
    # If insecure connections were explicitly requested via --insecure,
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   376
    # print a warning and do no verification.
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   377
    #
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   378
    # It may seem odd that this is checked *after* host fingerprint pinning.
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   379
    # This is for backwards compatibility (for now). The message is also
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   380
    # the same as below for BC.
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   381
    if ui.insecureconnections:
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   382
        ui.warn(_('warning: %s certificate with fingerprint %s not '
29268
f200b58497f1 sslutil: reference appropriate config section in messaging
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29267
diff changeset
   383
                  'verified (check %s or web.cacerts '
29227
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   384
                  'config setting)\n') %
29268
f200b58497f1 sslutil: reference appropriate config section in messaging
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29267
diff changeset
   385
                (host, nicefingerprint, section))
29227
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   386
        return
29112
5edc5acecc83 sslutil: handle ui.insecureconnections in validator
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29111
diff changeset
   387
29227
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   388
    if not sock._hgstate['caloaded']:
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   389
        if strict:
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   390
            raise error.Abort(_('%s certificate with fingerprint %s not '
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   391
                                'verified') % (host, nicefingerprint),
29268
f200b58497f1 sslutil: reference appropriate config section in messaging
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29267
diff changeset
   392
                              hint=_('check %s or web.cacerts config '
f200b58497f1 sslutil: reference appropriate config section in messaging
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29267
diff changeset
   393
                                     'setting') % section)
29227
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   394
        else:
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   395
            ui.warn(_('warning: %s certificate with fingerprint %s '
29268
f200b58497f1 sslutil: reference appropriate config section in messaging
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29267
diff changeset
   396
                      'not verified (check %s or web.cacerts config '
f200b58497f1 sslutil: reference appropriate config section in messaging
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29267
diff changeset
   397
                      'setting)\n') %
f200b58497f1 sslutil: reference appropriate config section in messaging
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29267
diff changeset
   398
                    (host, nicefingerprint, section))
29113
5b9577edf745 sslutil: use CA loaded state to drive validation logic
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29112
diff changeset
   399
29227
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   400
        return
29113
5b9577edf745 sslutil: use CA loaded state to drive validation logic
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29112
diff changeset
   401
29227
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   402
    msg = _verifycert(peercert2, host)
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   403
    if msg:
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   404
        raise error.Abort(_('%s certificate error: %s') % (host, msg),
29268
f200b58497f1 sslutil: reference appropriate config section in messaging
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29267
diff changeset
   405
                         hint=_('configure %s %s or use '
29227
dffe78d80a6c sslutil: convert socket validation from a class to a function (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29226
diff changeset
   406
                                '--insecure to connect insecurely') %
29268
f200b58497f1 sslutil: reference appropriate config section in messaging
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29267
diff changeset
   407
                              (section, nicefingerprint))