~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/http/_urllib2_wrappers.py

  • Committer: Jelmer Vernooij
  • Date: 2012-02-06 11:36:02 UTC
  • mfrom: (6462 +trunk)
  • mto: This revision was merged to the branch mainline in revision 6463.
  • Revision ID: jelmer@samba.org-20120206113602-yu3j0xe7qbk1szw9
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2011 Canonical Ltd
 
1
# Copyright (C) 2006-2012 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
74
74
import ssl
75
75
""")
76
76
 
77
 
DEFAULT_CA_PATH = u"/etc/ssl/certs/ca-certificates.crt"
78
77
 
 
78
# Note for packagers: if there is no package providing certs for your platform,
 
79
# the curl project produces http://curl.haxx.se/ca/cacert.pem weekly.
 
80
_ssl_ca_certs_known_locations = [
 
81
    u'/etc/ssl/certs/ca-certificates.crt', # Ubuntu/debian/gentoo
 
82
    u'/etc/pki/tls/certs/ca-bundle.crt', # Fedora/CentOS/RH
 
83
    u'/etc/ssl/ca-bundle.pem', # OpenSuse
 
84
    u'/etc/ssl/cert.pem', # OpenSuse
 
85
    u"/usr/local/share/certs/ca-root-nss.crt", # FreeBSD
 
86
    # XXX: Needs checking, can't trust the interweb ;) -- vila 2012-01-25
 
87
    u'/etc/openssl/certs/ca-certificates.crt', # Solaris
 
88
    ]
79
89
 
80
90
def default_ca_certs():
81
 
    if not os.path.exists(DEFAULT_CA_PATH):
82
 
        raise ValueError("default ca certs path %s does not exist" %
83
 
            DEFAULT_CA_PATH)
84
 
    return DEFAULT_CA_PATH
 
91
    if sys.platform == 'win32':
 
92
        return os.path.join(os.path.dirname(sys.executable), u"ca_bundle.crt")
 
93
    elif sys.platform == 'darwin':
 
94
        # FIXME: Needs some default value for osx, waiting for osx installers
 
95
        # guys feedback -- vila 2012-01-25
 
96
        pass
 
97
    else:
 
98
        # Try known locations for friendly OSes providing the root certificates
 
99
        # without making them hard to use for any https client.
 
100
        for path in _ssl_ca_certs_known_locations:
 
101
            if os.path.exists(path):
 
102
                # First found wins
 
103
                return path
 
104
    # A default path that makes sense and will be mentioned in the error
 
105
    # presented to the user, even if not correct for all platforms
 
106
    return _ssl_ca_certs_known_locations[0]
85
107
 
86
108
 
87
109
def ca_certs_from_store(path):
90
112
    return path
91
113
 
92
114
 
93
 
def default_cert_reqs():
94
 
    return u"required"
95
 
 
96
 
 
97
115
def cert_reqs_from_store(unicode_str):
98
116
    import ssl
99
117
    try:
100
118
        return {
101
119
            "required": ssl.CERT_REQUIRED,
102
 
            "optional": ssl.CERT_OPTIONAL,
103
120
            "none": ssl.CERT_NONE
104
121
            }[unicode_str]
105
122
    except KeyError:
112
129
        invalid='warning',
113
130
        help="""\
114
131
Path to certification authority certificates to trust.
 
132
 
 
133
This should be a valid path to a bundle containing all root Certificate
 
134
Authorities used to verify an https server certificate.
 
135
 
 
136
Use ssl.cert_reqs=none to disable certificate verification.
115
137
""")
116
138
 
117
139
opt_ssl_cert_reqs = config.Option('ssl.cert_reqs',
118
 
        default=default_cert_reqs,
 
140
        default=u"required",
119
141
        from_unicode=cert_reqs_from_store,
120
142
        invalid='error',
121
143
        help="""\
123
145
 
124
146
Possible values:
125
147
 * none: Certificates ignored
126
 
 * optional: Certificates not required, but validated if provided
127
 
 * required: Certificates required, and validated
 
148
 * required: Certificates required and validated
128
149
""")
129
150
 
130
151
checked_kerberos = False
448
469
    def connect_to_origin(self):
449
470
        # FIXME JRV 2011-12-18: Use location config here?
450
471
        config_stack = config.GlobalStack()
451
 
        if self.ca_certs is None:
452
 
            ca_certs = config_stack.get('ssl.ca_certs')
453
 
        else:
454
 
            ca_certs = self.ca_certs
455
472
        cert_reqs = config_stack.get('ssl.cert_reqs')
456
473
        if cert_reqs == ssl.CERT_NONE:
457
 
            trace.warning("not checking SSL certificates for %s: %d",
 
474
            trace.warning("Not checking SSL certificate for %s: %d",
458
475
                self.host, self.port)
 
476
            ca_certs = None
459
477
        else:
 
478
            if self.ca_certs is None:
 
479
                ca_certs = config_stack.get('ssl.ca_certs')
 
480
            else:
 
481
                ca_certs = self.ca_certs
460
482
            if ca_certs is None:
461
483
                trace.warning(
462
 
                    "no valid trusted SSL CA certificates file set. See "
 
484
                    "No valid trusted SSL CA certificates file set. See "
463
485
                    "'bzr help ssl.ca_certs' for more information on setting "
464
 
                    "trusted CA's.")
 
486
                    "trusted CAs.")
465
487
        try:
466
488
            ssl_sock = ssl.wrap_socket(self.sock, self.key_file, self.cert_file,
467
489
                cert_reqs=cert_reqs, ca_certs=ca_certs)
468
490
        except ssl.SSLError, e:
469
 
            if e.errno != ssl.SSL_ERROR_SSL:
470
 
                raise
471
491
            trace.note(
472
 
                "To disable SSL certificate verification, use "
473
 
                "-Ossl.cert_reqs=none. See ``bzr help ssl.ca_certs`` for "
474
 
                "more information on specifying trusted CA certificates.")
 
492
                "\n"
 
493
                "See `bzr help ssl.ca_certs` for how to specify trusted CA"
 
494
                "certificates.\n"
 
495
                "Pass -Ossl.cert_reqs=none to disable certificate "
 
496
                "verification entirely.\n")
475
497
            raise
476
 
        peer_cert = ssl_sock.getpeercert()
477
 
        if (cert_reqs == ssl.CERT_REQUIRED or
478
 
            (cert_reqs == ssl.CERT_OPTIONAL and peer_cert)):
 
498
        if cert_reqs == ssl.CERT_REQUIRED:
 
499
            peer_cert = ssl_sock.getpeercert()
479
500
            match_hostname(peer_cert, self.host)
480
501
 
481
502
        # Wrap the ssl socket before anybody use it