Commit Graph

109 Commits

Author SHA1 Message Date
Matt Harbison
26d7de6319 tests: add a substitution for EADDRINUSE/WSAEADDRINUSE messages
I suspect some more of these are globbed out, so this is a bit of future
proofing.
2017-12-02 20:03:28 -05:00
Denis Laxalde
9efc7f05e3 transaction-summary: show the range of new revisions upon pull/unbundle (BC)
Upon pull or unbundle, we display a message with the range of new revisions
fetched. This revision range could readily be used after a pull to look out
what's new with 'hg log'. The algorithm takes care of filtering "obsolete"
revisions that might be present in transaction's "changes" but should not be
displayed to the end user.
2017-10-12 09:39:50 +02:00
Matt Harbison
72e29cff86 run-tests: drop required (feature !) style lines when the output is missing
Essentially, these were acting as a verbose (?) flag, since they weren't being
dropped when required.  Foozy has a nice description [1].  Basically, a couple
more places needed to check the features before treating it as optional.

I don't like how test-run-tests.py had to be hacked, but _hghave() can't be made
a static method.  The test change was a change while developing `debugssl`,
prior to tightening up the cases where the message is printed, that this fix
would have caught.

[1] https://www.mercurial-scm.org/pipermail/mercurial-devel/2017-July/101941.html
2017-07-18 00:12:44 -04:00
Matt Harbison
cdf9eba4e7 test-https: properly conditionalize Windows vs non-Windows output
There's a bug in the (feature !) annotation, and this needs to be resolved
before fixing it.  Once fixed, the glob '*/missing' will match the output
'/missing' on non-Windows platforms, consuming the output line and leaving
nothing for the no-windows required line.

I probably should have made (foo !) match only the 'foo' feature, and be ignored
otherwise instead of optional.  (re) didn't work here, because the parenthesis
need to be escaped too.
2017-07-18 19:49:51 -04:00
Matt Harbison
d41b1d2ec2 sslutil: inform the user about how to fix an incomplete certificate chain
This is a Windows only thing.  Unfortunately, the socket is closed at this point
(so the certificate is unavailable to check the chain).  That means it's printed
out when verification fails as a guess, on the assumption that 1) most of the
time verification won't fail, and 2) sites using expired or certs that are too
new will be rare.  Maybe this is an argument for adding more functionality to
debugssl, to test for problems and print certificate info.  Or maybe it's an
argument for bundling certificates with the Windows builds.  That idea was set
aside when the enhanced SSL code went in last summer, and it looks like there
were issues with using certifi on Windows anyway[1].

This was tested by deleting the certificate out of certmgr.msc > "Third-Party
Root Certification Authorities" > "Certificates", seeing `hg pull` fail (with
the new message), trying this command, and then successfully performing the pull
command.

[1] https://www.mercurial-scm.org/pipermail/mercurial-devel/2016-October/089573.html
2017-07-12 18:37:13 -04:00
Matt Harbison
3fbb2994cb test-https: stabilize for Windows
A leading '/' without a following drive letter is resolved to the location of
the MSYS installation.  These could be collapsed into a single line of output,
but this seems more self documenting.
2017-07-11 22:06:57 -04:00
Gregory Szorc
596098a717 sslutil: check for missing certificate and key files (issue5598)
Currently, sslutil._hostsettings() performs validation that web.cacerts
exists. However, client certificates are passed in to the function
and not all callers may validate them. This includes
httpconnection.readauthforuri(), which loads the [auth] section.

If a missing file is specified, the ssl module will raise a generic
IOException. And, it doesn't even give us the courtesy of telling
us which file is missing! Mercurial then prints a generic
"abort: No such file or directory" (or similar) error, leaving users
to scratch their head as to what file is missing.

This commit introduces explicit validation of all paths passed as
arguments to wrapsocket() and wrapserversocket(). Any missing file
is alerted about explicitly.

We should probably catch missing files earlier - as part of loading
the [auth] section. However, I think the sslutil functions should
check for file presence regardless of what callers do because that's
the only way to be sure that missing files are always detected.
2017-07-10 21:09:46 -07:00
Gregory Szorc
4cbe1b2aa1 sslutil: tweak the legacy [hostfingerprints] warning message
Lars Rohwedder noted in issue5559 that the previous wording was
confusing. I agree.
2017-05-10 23:49:37 -07:00
Martin von Zweigbergk
09d53c160b merge with stable 2017-05-12 11:20:25 -07:00
Gregory Szorc
3ffdc76e66 sslutil: reference fingerprints config option properly (issue5559)
The config option is "host:fingerprints" not "host.fingerprints".

This warning message is bad and misleads users.
2017-05-08 09:30:26 -07:00
Gregory Szorc
886ce31bbb tests: remove test targeting Python 2.6
We just removed support for Python 2.7. This test is dead since it only
ran on <2.7.
2017-05-08 15:30:15 -07:00
Augie Fackler
59830ae1dc tests: fix missing (glob) annotations in test-https.t 2017-04-03 18:56:08 -04:00
Matt Harbison
be3883cbff test-http: update output for Windows
The http test simply wasn't updated in d264983c27fa for Windows.  It looks like
the https test meant to glob away the error message in fa7f5826debe, but forgot
the '*', and was subsequently removed in 01af1e5e4062.
2017-04-01 18:30:51 -04:00
Matt Harbison
f5d65c9a00 tests: add globs for Windows 2017-04-01 14:48:39 -04:00
Pierre-Yves David
e3a8075346 hook: add hook name information to external hook
While we are here, we can also add the hook name information to external hook.
2017-03-31 11:53:56 +02:00
Pierre-Yves David
833b1335ba hook: provide hook type information to external hook
The python hooks have access to the hook type information. There is not reason
for external hook to not be aware of it too.

For the record my use case is to make sure a hook script is configured for the
right type.
2017-03-31 11:08:11 +02:00
Pierre-Yves David
7a17c488e7 run-tests: auto-replace 'TXNID' output
Hooks related to the transaction are aware of the transaction id. By definition
this txn-id is unique and different for each transaction. As a result it can
never be predicted in test and always needs matching. As a result, touching any
like with this data is annoying. We solve the problem once and for all by
installing an automatic replacement. In test, this will now show as:

  TXNID=TXN:$ID$
2017-03-30 17:29:03 +02:00
Gregory Szorc
967eed8566 sslutil: issue warning when [hostfingerprint] is used
Mercurial 3.9 added the [hostsecurity] section, which is better
than [hostfingerprints] in every way.

One of the ways that [hostsecurity] is better is that it supports
SHA-256 and SHA-512 fingerprints, not just SHA-1 fingerprints.

The world is moving away from SHA-1 because it is borderline
secure. Mercurial should be part of that movement.

This patch adds a warning when a valid SHA-1 fingerprint from
the [hostfingerprints] section is being used. The warning informs
users to switch to [hostsecurity]. It even prints the config
option they should set. It uses the SHA-256 fingerprint because
recommending a SHA-1 fingerprint in 2017 would be ill-advised.

The warning will print itself on every connection to a server until
it is fixed. There is no way to suppress the warning. I admit this
is annoying. But given the security implications of sticking with
SHA-1, I think this is justified. If this patch is accepted,
I'll likely send a follow-up to start warning on SHA-1
certificates in [hostsecurity] as well. Then sometime down
the road, we can drop support for SHA-1 fingerprints.

Credit for this idea comes from timeless in issue 5466.
2017-03-09 20:33:29 -08:00
Jun Wu
ff1c9b7606 runtests: set web.address to localhost
Previously, "hg serve" will listen on "", which is not clear which interface
it will actually listen on - it could listen on all interfaces (ex. 0.0.0.0
on IPv4).

The run-tests.py script only checks "localhost" for available ports. So
let's make it the same for "hg serve" by explicitly setting "web.address" to
"localhost".

This resolves some IPv6 EADDRINUSE errors.
2017-02-16 00:13:29 -08:00
Jun Wu
7bdcbacb01 tests: use LOCALIP
This patch replaces hardcoded 127.0.0.1 with $LOCALIP in all tests.

Till now, the IPv6 series should make tests pass on common IPv6 systems
where the local device has the address "::1" and the hostname "localhost"
resolves to "::1".
2017-02-16 09:38:52 -08:00
Mads Kiilerich
38cb771268 spelling: fixes of non-dictionary words 2016-10-17 23:16:55 +02:00
FUJIWARA Katsunori
2568974470 tests: invoke printenv.py via sh -c for test portability
On Windows platform, invoking printenv.py directly via hook is
problematic, because:

  - unless binding between *.py suffix and python runtime, application
    selector dialog is displayed, and running test is blocked at each
    printenv.py invocations

  - it isn't safe to assume binding between *.py suffix and python
    runtime, because application binding is easily broken

    For example, installing IDE (VisualStudio with Python Tools, or
    so) often requires binding between source files and IDE itself.

This patch invokes printenv.py via sh -c for test portability. This is
a kind of follow up for 9e4331825bea, which eliminated explicit
"python" for printenv.py. There are already other 'sh -c "printenv.py"'
in *.t files, and this fix should be reasonable.

This changes were confirmed in cases below:

  - without any application binding for *.py suffix
  - with binding between *.py suffix and VisualStudio

This patch also replaces "echo + redirection" style with "heredoc"
style, because:

  - hook command line is parsed by cmd.exe as shell at first, and
  - single quotation can't quote arguments on cmd.exe, therefore,
  - "printenv.py foobar" should be quoted by double quotation, but
  - nested quoting (or tricky escaping) isn't readable
2016-10-29 02:44:45 +09:00
Augie Fackler
1a37c09b9f test-https: drop two spurious --traceback flags
These make test failures scarier than they are.
2016-08-25 01:00:54 -04:00
Gregory Szorc
e14145640d tests: glob over ssl error
We do this in the rest of the file. This bad line was introduced in
fbde510a858d.
2016-07-28 08:53:36 -07:00
Gregory Szorc
9a4d440133 sslutil: improve messaging around unsupported protocols (issue5303)
There are various causes for the inability to negotiate common SSL/TLS
protocol between client and server. Previously, we had a single, not
very actionable warning message for all of them.

As people encountered TLS 1.0 servers in real life, it was quickly
obvious that the existing messaging was inadequate to help users
rectify the situation.

This patch makes the warning messages much more verbose in hopes of
making them more actionable while simultaneously encouraging users
and servers to adopt better security practices.

This messaging flirts with the anti-pattern of "never blame the
user" by signaling out poorly-configured servers. But if we're going to
disallow TLS 1.0 by default, I think we need to say *something* or
people are just going to blame Mercurial for not being able to connect.
The messaging tries to exonerate Mercurial from being the at fault
party by pointing out the server is the entity that doesn't support
proper security (when appropriate, of course).
2016-07-19 21:09:58 -07:00
Gregory Szorc
866f60c870 sslutil: allow TLS 1.0 when --insecure is used
--insecure is our psuedo-supported footgun for disabling connection
security.

The flag already disables CA verification. I think allowing the use of
TLS 1.0 when specified is appropriate.
2016-07-19 20:16:51 -07:00
Gregory Szorc
7c2f430ebc hg: copy [hostsecurity] options to remote ui instances (issue5305)
TIL that ui instances for remote/peer repos don't automagically inherit
config options from .hg/hgrc files.

This patch makes remote ui instances inherit options from the
[hostsecurity] section. We were already inheriting options
from [hostfingerprints] and [auth]. So adding [hostsecurity] to the
list seems appropriate.
2016-07-19 19:57:34 -07:00
Gregory Szorc
6ba507acfc sslutil: more robustly detect protocol support
The Python ssl module conditionally sets the TLS 1.1 and TLS 1.2
constants depending on whether HAVE_TLSv1_2 is defined. Yes, these
are both tied to the same constant (I would think there would be
separate constants for each version). Perhaps support for TLS 1.1
and 1.2 were added at the same time and the assumption is that
OpenSSL either has neither or both. I don't know.

As part of developing this patch, it was discovered that Apple's
/usr/bin/python2.7 does not support TLS 1.1 and 1.2 (only TLS 1.0)!
On OS X 10.11, Apple Python has the modern ssl module including
SSLContext, but it doesn't appear to negotiate TLS 1.1+ nor does
it expose the constants related to TLS 1.1+. Since this code is
doing more robust feature detection (and not assuming modern ssl
implies TLS 1.1+ support), we now get TLS 1.0 warnings when running
on Apple Python. Hence the test changes.

I'm not super thrilled about shipping a Mercurial that always
whines about TLS 1.0 on OS X. We may want a follow-up patch to
suppress this warning.
2016-07-18 11:27:27 -07:00
Gregory Szorc
a7364efe16 sslutil: support defining cipher list
Python 2.7 supports specifying a custom cipher list to TLS sockets.
Advanced users may wish to specify a custom cipher list to increase
security. Or in some cases they may wish to prefer weaker ciphers
in order to increase performance (e.g. when doing stream clones
of very large repositories).

This patch introduces a [hostsecurity] config option for defining
the cipher list. The help documentation states that it is for
advanced users only.

Honestly, I'm a bit on the fence about providing this because
it is a footgun and can be used to decrease security. However,
there are legitimate use cases for it, so I think support should
be provided.
2016-07-17 10:59:32 -07:00
Gregory Szorc
9f52df0840 sslutil: print a warning when using TLS 1.0 on legacy Python
Mercurial now requires TLS 1.1+ when TLS 1.1+ is supported by the
client. Since we made the decision to require TLS 1.1+ when running
with modern Python versions, it makes sense to do something for
legacy Python versions that only support TLS 1.0.

Feature parity would be to prevent TLS 1.0 connections out of the
box and require a config option to enable them. However, this is
extremely user hostile since Mercurial wouldn't talk to https://
by default in these installations! I can easily see how someone
would do something foolish like use "--insecure" instead - and
that would be worse than allowing TLS 1.0!

This patch takes the compromise position of printing a warning when
performing TLS 1.0 connections when running on old Python
versions. While this warning is no more annoying than the
CA certificate / fingerprint warnings in Mercurial 3.8, we provide
a config option to disable the warning because to many people
upgrading Python to make the warning go away is not an available
recourse (unlike pinning fingerprints is for the CA warning).

The warning appears as optional output in a lot of tests.
2016-07-13 21:49:17 -07:00
Gregory Szorc
91047cde9d sslutil: require TLS 1.1+ when supported
Currently, Mercurial will use TLS 1.0 or newer when connecting to
remote servers, selecting the highest TLS version supported by both
peers. On older Pythons, only TLS 1.0 is available. On newer Pythons,
TLS 1.1 and 1.2 should be available.

Security professionals recommend avoiding TLS 1.0 if possible.
PCI DSS 3.1 "strongly encourages" the use of TLS 1.2.

Known attacks like BEAST and POODLE exist against TLS 1.0 (although
mitigations are available and properly configured servers aren't
vulnerable).

I asked Eric Rescorla - Mozilla's resident crypto expert - whether
Mercurial should drop support for TLS 1.0. His response was
"if you can get away with it." Essentially, a number of servers on
the Internet don't support TLS 1.1+. This is why web browsers
continue to support TLS 1.0 despite desires from security experts.

This patch changes Mercurial's default behavior on modern Python
versions to require TLS 1.1+, thus avoiding known security issues
with TLS 1.0 and making Mercurial more secure by default. Rather
than drop TLS 1.0 support wholesale, we still allow TLS 1.0 to be
used if configured. This is a compromise solution - ideally we'd
disallow TLS 1.0. However, since we're not sure how many Mercurial
servers don't support TLS 1.1+ and we're not sure how much user
inconvenience this change will bring, I think it is prudent to ship
an escape hatch that still allows usage of TLS 1.0. In the default
case our users get better security. In the worst case, they are no
worse off than before this patch.

This patch has no effect when running on Python versions that don't
support TLS 1.1+.

As the added test shows, connecting to a server that doesn't
support TLS 1.1+ will display a warning message with a link to
our wiki, where we can guide people to configure their client to
allow less secure connections.
2016-07-13 21:35:54 -07:00
Gregory Szorc
0ed5c4ca7f sslutil: config option to specify TLS protocol version
Currently, Mercurial will use TLS 1.0 or newer when connecting to
remote servers, selecting the highest TLS version supported by both
peers. On older Pythons, only TLS 1.0 is available. On newer Pythons,
TLS 1.1 and 1.2 should be available.

Security-minded people may want to not take any risks running
TLS 1.0 (or even TLS 1.1). This patch gives those people a config
option to explicitly control which TLS versions Mercurial should use.
By providing this option, one can require newer TLS versions
before they are formally deprecated by Mercurial/Python/OpenSSL/etc
and lower their security exposure. This option also provides an
easy mechanism to change protocol policies in Mercurial. If there
is a 0-day and TLS 1.0 is completely broken, we can act quickly
without changing much code.

Because setting the minimum TLS protocol is something you'll likely
want to do globally, this patch introduces a global config option under
[hostsecurity] for that purpose.

wrapserversocket() has been taught a hidden config option to define
the explicit protocol to use. This is queried in this function and
not passed as an argument because I don't want to expose this dangerous
option as part of the Python API. There is a risk someone could footgun
themselves. But the config option is a devel option, has a warning
comment, and I doubt most people are using `hg serve` to run a
production HTTPS server (I would have something not Mercurial/Python
handle TLS). If this is problematic, we can go back to using a
custom extension in tests to coerce the server into bad behavior.
2016-07-14 20:47:22 -07:00
Gregory Szorc
c023f774e6 hgweb: use sslutil.wrapserversocket()
This patch transitions the built-in HTTPS server to use sslutil for
creating the server socket.

As part of this transition, we implement developer-only config options
to control CA loading and whether to require client certificates. This
eliminates the need for the custom extension in test-https.t to define
these.

There is a slight change in behavior with regards to protocol
selection. Before, we would always use the TLS 1.0 constant to define
the protocol version. This would *only* use TLS 1.0. sslutil defaults
to TLS 1.0+. So this patch improves the security of `hg serve` out of
the box by allowing it to use TLS 1.1 and 1.2 (if available).
2016-07-12 23:12:03 -07:00
Gregory Szorc
6052136b07 hgweb: pass ui into preparehttpserver
Upcoming patches will need the built-in HTTPS server to be more
configurable.
2016-07-13 00:14:50 -07:00
Gregory Szorc
a17406014b tests: regenerate x509 test certificates
The old x509 test certificates were using cryptographic settings
that are ancient by today's standards, namely 512 bit RSA keys.
To put things in perspective, browsers have been dropping support
for 1024 bit RSA keys.

I think it is important that tests match the realities of the times.
And 2048 bit RSA keys with SHA-2 hashing are what the world is
moving to.

This patch replaces all the x509 certificates with new versions using
modern best practices. In addition, the docs for generating the
keys have been updated, as the existing docs left out a few steps,
namely how to generate certs that were not active yet or expired.
2016-07-12 22:26:04 -07:00
Augie Fackler
a746cac8cc tests: add (glob) annotations to output lines with 127.0.0.1 2016-07-09 23:03:45 -04:00
Gregory Szorc
0786299e33 sslutil: try to find CA certficates in well-known locations
Many Linux distros and other Nixen have CA certificates in well-defined
locations. Rather than potentially fail to load any CA certificates at
all (which will always result in a certificate verification failure),
we scan for paths to known CA certificate files and load one if seen.
Because a proper Mercurial install will have the path to the CA
certificate file defined at install time, we print a warning that
the install isn't proper and provide a URL with instructions to
correct things.

We only perform path-based fallback on Pythons that don't know
how to call into OpenSSL to load the default verify locations. This
is because we trust that Python/OpenSSL is properly configured
and knows better than Mercurial. So this new code effectively only
runs on Python <2.7.9 (technically Pythons without the modern ssl
module).
2016-07-06 21:16:00 -07:00
Gregory Szorc
0ede6720a7 sslutil: issue warning when unable to load certificates on OS X
Previously, failure to load system certificates on OS X would lead
to a certificate verify failure and that's it. We now print a warning
message with a URL that will contain information on how to configure
certificates on OS X.

As the inline comment states, there is room to improve here. I think
we could try harder to detect Homebrew and MacPorts installed
certificate files, for example. It's worth noting that Homebrew's
openssl package uses `security find-certificate -a -p` during package
installation to export the system keychain root CAs to
etc/openssl/cert.pem. This is something we could consider adding
to setup.py. We could also encourage packagers to do this. For now,
I'd just like to get this warning (which matches Windows behavior)
landed. We should have time to improve things before release.
2016-07-06 20:46:05 -07:00
Gregory Szorc
a15cc9fbbd sslutil: handle default CA certificate loading on Windows
See the inline comment for what's going on here.

There is magic built into the "ssl" module that ships with modern
CPython that knows how to load the system CA certificates on
Windows. Since we're not shipping a CA bundle with Mercurial,
if we're running on legacy CPython there's nothing we can do
to load CAs on Windows, so it makes sense to print a warning.

I don't anticipate many people will see this warning because
the official (presumed popular) Mercurial distributions on
Windows bundle Python and should be distributing a modern Python
capable of loading system CA certs.
2016-07-04 10:04:11 -07:00
Gregory Szorc
2121e65956 tests: better testing of loaded certificates
Tests were failing on systems like RHEL 7 where loading the system
certificates results in CA certs being reported to Python. We add
a feature that detects when we're able to load *and detect* the
loading of system certificates. We update the tests to cover the
3 scenarios:

1) system CAs are loadable and detected
2) system CAs are loadable but not detected
3) system CAs aren't loadable
2016-07-01 19:27:34 -07:00
Gregory Szorc
6adc4b7bac sslutil: emit warning when no CA certificates loaded
If no CA certificates are loaded, that is almost certainly a/the
reason certificate verification fails when connecting to a server.

The modern ssl module in Python 2.7.9+ provides an API to access
the list of loaded CA certificates. This patch emits a warning
on modern Python when certificate verification fails and there are
no loaded CA certificates.

There is no way to detect the number of loaded CA certificates
unless the modern ssl module is present. Hence the differences
in test output depending on whether modern ssl is available.

It's worth noting that a test which specifies a CA file still
renders this warning. That is because the certificate it is loading
is a x509 client certificate and not a CA certificate. This
test could be updated if anyone is so inclined.
2016-06-29 19:43:27 -07:00
Gregory Szorc
169cc46dab tests: test case where default ca certs not available
I'm not a fan of TLS tests not testing both branches of a possible
configuration. While we have test coverage of the inability to validate
a cert later in this file, I insist that we add this branch so
our testing of security code is extra comprehensive.
2016-06-29 19:49:39 -07:00
Gregory Szorc
9653d9a563 sslutil: display a better error message when CA file loading fails
Before, sslcontext.load_verify_locations() would raise a
ssl.SSLError which would be caught further up the stack and converted
to a urlerror. By that time, we lost track of what actually errored.

Trapping the error here gives users a slightly more actionable error
message.

The behavior between Python <2.7.9 and Python 2.7.9+ differs. This
is because our fake SSLContext class installed on <2.7.9 doesn't
actually do anything during load_verify_locations: it defers actions
until wrap_socket() time. Unfortunately, a number of errors can occur
at wrap_socket() time and we're unable to ascertain what the root
cause is. But that shouldn't stop us from providing better error
messages to people running a modern and secure Python version.
2016-06-29 19:37:38 -07:00
Gregory Szorc
3481b4d0f7 tests: add test for empty CA certs file
smf reported that an environment with no loaded CA certs resulted
in a weird error. I'd like to detect this a bit better so we can
display an actionable error message.

The actual error being globbed over in this patch is "unknown error"
with a ssl.c line number. That isn't useful at all.
2016-06-29 18:15:28 -07:00
Gregory Szorc
aa33fbc73f sslutil: abort when unable to verify peer connection (BC)
Previously, when we connected to a server and were unable to verify
its certificate against a trusted certificate authority we would
issue a warning and continue to connect. This is obviously not
great behavior because the x509 certificate model is based upon
trust of specific CAs. Failure to enforce that trust erodes security.
This behavior was defined several years ago when Python did not
support loading the system trusted CA store (Python 2.7.9's
backports of Python 3's improvements to the "ssl" module enabled
this).

This commit changes behavior when connecting to abort if the peer
certificate can't be validated. With an empty/default Mercurial
configuration, the peer certificate can be validated if Python is
able to load the system trusted CA store. Environments able to load
the system trusted CA store include:

* Python 2.7.9+ on most platforms and installations
* Python 2.7 distributions with a modern ssl module (e.g. RHEL7's
  patched 2.7.5 package)
* Python shipped on OS X

Environments unable to load the system trusted CA store include:

* Python 2.6
* Python 2.7 on many existing Linux installs (because they don't
  ship 2.7.9+ or haven't backported modern ssl module)
* Python 2.7.9+ on some installs where Python is unable to locate
  the system CA store (this is hopefully rare)

Users of these Pythongs will need to configure Mercurial to load the
system CA store using web.cacerts. This should ideally be performed
by packagers (by setting web.cacerts in the global/system hgrc file).
Where Mercurial packagers aren't setting this, the linked URL in the
new abort message can contain instructions for users.

In the future, we may want to add more code for finding the system
CA store. For example, many Linux distributions have the CA store
at well-known locations (such as /etc/ssl/certs/ca-certificates.crt
in the case of Ubuntu). This will enable CA loading to "just work"
on more Python configurations and will be best for our users since
they won't have to change anything after upgrading to a Mercurial
with this patch.

We may also want to consider distributing a trusted CA store with
Mercurial. Although we should think long and hard about that because
most systems have a global CA store and Mercurial should almost
certainly use the same store used by everything else on the system.
2016-06-25 07:26:43 -07:00
Durham Goode
78417c606d tests: increase test-https malform error glob
The recently introduced (fd348a6ace5a157c) test around malformed pem files hard
codes an error message which doesn't appear to be cross platform agnostic. On
our machines (centos6 if it matters) the test output differs:

-  abort: error: unknown error* (glob)
+  abort: error: _ssl.c:330: error:00000000:lib(0):func(0):reason(0)

This patch increases the glob to cover the entire error message.
2016-06-14 18:14:42 -07:00
Gregory Szorc
7a668208b8 sslutil: per-host config option to define certificates
Recent work has introduced the [hostsecurity] config section for
defining per-host security settings. This patch builds on top
of this foundation and implements the ability to define a per-host
path to a file containing certificates used for verifying the server
certificate. It is logically a per-host web.cacerts setting.

This patch also introduces a warning when both per-host
certificates and fingerprints are defined. These are mutually
exclusive for host verification and I think the user should be
alerted when security settings are ambiguous because, well,
security is important.

Tests validating the new behavior have been added.

I decided against putting "ca" in the option name because a
non-CA certificate can be specified and used to validate the server
certificate (commonly this will be the exact public certificate
used by the server). It's worth noting that the underlying
Python API used is load_verify_locations(cafile=X) and it calls
into OpenSSL's SSL_CTX_load_verify_locations(). Even OpenSSL's
documentation seems to omit that the file can contain a non-CA
certificate if it matches the server's certificate exactly. I
thought a CA certificate was a special kind of x509 certificate.
Perhaps I'm wrong and any x509 certificate can be used as a
CA certificate [as far as OpenSSL is concerned]. In any case,
I thought it best to drop "ca" from the name because this reflects
reality.
2016-06-07 20:29:54 -07:00
Yuya Nishihara
f447a4de76 tests: extract SSL certificates from test-https.t
They can be reused in SMTPS tests.
2016-05-27 22:40:09 +09:00
Gregory Szorc
0f55e28908 sslutil: print the fingerprint from the last hash used
Before, we would always print the unprefixed SHA-1 fingerprint when
fingerprint comparison failed. Now, we print the fingerprint of the
last hash used, including the prefix if necessary. This helps ensure
that the printed hash type matches what is in the user configuration.

There are still some cases where this can print a mismatched hash type.
e.g. if there are both SHA-1 and SHA-256 fingerprints in the config,
we could print a SHA-1 hash if it comes after the SHA-256 hash. But
I'm inclined to ignore this edge case.

While I was here, the "section" variable assignment has been moved to
just above where it is used because it is now only needed for this
error message and it makes the code easier to read.
2016-06-04 11:16:08 -07:00
Gregory Szorc
2337effc05 sslutil: make cert fingerprints messages more actionable
The previous warning and abort messages were difficult to understand.
This patch makes them slightly better.

I think there is still room to tweak the messaging. And as we adopt
new security defaults, these messages will certainly change again.
But at least this takes us a step in the right direction.

References to "section" have been removed because if no fingerprint
is defined, "section" can never be "hostfingerprints." So just print
"hostsecurity" every time.
2016-05-31 19:21:08 -07:00