mirror of
https://github.com/samsonjs/vdirsyncer.git
synced 2026-03-31 09:55:55 +00:00
Merge pull request #161 from untitaker/verify_docs
Document certificate verification properly
This commit is contained in:
commit
4384823cd1
7 changed files with 89 additions and 23 deletions
|
|
@ -18,8 +18,9 @@ Table of Contents
|
|||
:maxdepth: 1
|
||||
|
||||
tutorial
|
||||
config
|
||||
ssl-tutorial
|
||||
keyring
|
||||
config
|
||||
supported
|
||||
problems
|
||||
vdir
|
||||
|
|
|
|||
56
docs/ssl-tutorial.rst
Normal file
56
docs/ssl-tutorial.rst
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
.. _ssl-tutorial:
|
||||
|
||||
==============================
|
||||
SSL and certificate validation
|
||||
==============================
|
||||
|
||||
Vdirsyncer uses the requests_ library for all its HTTP and SSL interaction.
|
||||
|
||||
All SSL configuration is done per-storage. Storages that have anything to do
|
||||
with SSL have two parameters: ``verify`` and ``verify_fingerprint``.
|
||||
|
||||
- The ``verify`` parameter determines whether to verify SSL certificates.
|
||||
|
||||
1. The default, ``true``, means that certificates will be validated against a
|
||||
set of trusted CAs. See :ref:`ssl-cas`.
|
||||
|
||||
2. The value ``false`` will disable both trusted-CA-validation and the
|
||||
validation of the certificate's expiration date. Unless combined with
|
||||
``verify_fingerprint``, **you should not use this value at all, because
|
||||
it's a security risk**.
|
||||
|
||||
3. You can also set ``verify`` to a path of the server's certificate in PEM
|
||||
format, instead of relying on the default root CAs::
|
||||
|
||||
[storage foo]
|
||||
type = caldav
|
||||
...
|
||||
verify = "/path/to/cert.pem"
|
||||
|
||||
- The ``verify_fingerprint`` parameter can be used to compare the SSL
|
||||
fingerprint to a fixed value. The value can be either a SHA1-fingerprint or
|
||||
an MD5 one::
|
||||
|
||||
[storage foo]
|
||||
type = caldav
|
||||
...
|
||||
verify_fingerprint = "94:FD:7A:CB:50:75:A4:69:82:0A:F8:23:DF:07:FC:69:3E:CD:90:CA"
|
||||
|
||||
Using it will effectively set ``verify=False``.
|
||||
|
||||
.. _ssl-cas:
|
||||
|
||||
Trusted CAs
|
||||
-----------
|
||||
|
||||
As said, vdirsyncer uses the requests_ library for such parts, which, by
|
||||
default, `uses its own set of trusted CAs
|
||||
<http://www.python-requests.org/en/latest/user/advanced/#ca-certificates>`_.
|
||||
|
||||
However, the actual behavior depends on how you have installed it. Some Linux
|
||||
distributions, such as Debian, patch their ``python-requests`` package to use
|
||||
the system certificate CAs. Normally these two stores are similar enough for
|
||||
you not to care. If the behavior on your system is somehow confusing, your best
|
||||
bet is explicitly setting the SSL options above.
|
||||
|
||||
.. _requests: www.python-requests.org/
|
||||
5
setup.py
5
setup.py
|
|
@ -38,10 +38,13 @@ setup(
|
|||
'console_scripts': ['vdirsyncer = vdirsyncer.cli:main']
|
||||
},
|
||||
install_requires=[
|
||||
# https://github.com/mitsuhiko/click/issues/200
|
||||
'click>=3.1',
|
||||
'requests>=2.1',
|
||||
# https://github.com/shazow/urllib3/pull/444
|
||||
'requests>=2.4.1',
|
||||
'lxml>=3.0',
|
||||
'icalendar>=3.6',
|
||||
# https://github.com/sigmavirus24/requests-toolbelt/pull/28
|
||||
'requests_toolbelt>=0.3.0'
|
||||
],
|
||||
extras_require={'keyring': ['keyring']}
|
||||
|
|
|
|||
|
|
@ -208,6 +208,8 @@ def test_get_class_init_args_on_storage():
|
|||
assert not required
|
||||
|
||||
|
||||
@pytest.mark.skipif(not utils.compat.PY2,
|
||||
reason='https://github.com/shazow/urllib3/issues/529')
|
||||
def test_request_ssl(httpsserver):
|
||||
sha1 = '94:FD:7A:CB:50:75:A4:69:82:0A:F8:23:DF:07:FC:69:3E:CD:90:CA'
|
||||
md5 = '19:90:F7:23:94:F2:EF:AB:2B:64:2D:57:3D:25:95:2D'
|
||||
|
|
@ -218,6 +220,10 @@ def test_request_ssl(httpsserver):
|
|||
utils.request('GET', httpsserver.url)
|
||||
assert 'certificate verify failed' in str(excinfo.value)
|
||||
utils.request('GET', httpsserver.url, verify=False)
|
||||
utils.request('GET', httpsserver.url, verify=False,
|
||||
utils.request('GET', httpsserver.url,
|
||||
verify_fingerprint=sha1)
|
||||
utils.request('GET', httpsserver.url, verify=False, verify_fingerprint=md5)
|
||||
utils.request('GET', httpsserver.url, verify_fingerprint=md5)
|
||||
with pytest.raises(requests.exceptions.SSLError) as excinfo:
|
||||
utils.request('GET', httpsserver.url,
|
||||
verify_fingerprint=''.join(reversed(sha1)))
|
||||
assert 'Fingerprints did not match' in str(excinfo.value)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ from requests import session as requests_session
|
|||
from requests.exceptions import HTTPError
|
||||
|
||||
from .base import Item, Storage
|
||||
from .http import USERAGENT, prepare_auth, prepare_verify
|
||||
from .http import HTTP_STORAGE_PARAMETERS, USERAGENT, prepare_auth, \
|
||||
prepare_verify
|
||||
from .. import exceptions, log, utils
|
||||
|
||||
|
||||
|
|
@ -250,18 +251,9 @@ class DavSession(object):
|
|||
|
||||
class DavStorage(Storage):
|
||||
|
||||
'''
|
||||
__doc__ = '''
|
||||
:param url: Base URL or an URL to a collection.
|
||||
:param username: Username for authentication.
|
||||
:param password: Password for authentication.
|
||||
:param verify: Verify SSL certificate, default True. This can also be a
|
||||
local path to a self-signed SSL certificate.
|
||||
:param verify_fingerprint: Optional. SHA1 or MD5 fingerprint of the
|
||||
expected server certificate.
|
||||
:param auth: Optional. Either ``basic``, ``digest`` or ``guess``. Default
|
||||
``guess``. If you know yours, consider setting it explicitly for
|
||||
performance.
|
||||
:param useragent: Default ``vdirsyncer``.
|
||||
''' + HTTP_STORAGE_PARAMETERS + '''
|
||||
:param unsafe_href_chars: Replace the given characters when generating
|
||||
hrefs. Defaults to ``'@'``.
|
||||
|
||||
|
|
|
|||
|
|
@ -44,21 +44,28 @@ def prepare_verify(verify):
|
|||
return verify
|
||||
|
||||
|
||||
class HttpStorage(Storage):
|
||||
'''
|
||||
Use a simple ``.ics`` file (or similar) from the web.
|
||||
|
||||
:param url: URL to the ``.ics`` file.
|
||||
HTTP_STORAGE_PARAMETERS = '''
|
||||
:param username: Username for authentication.
|
||||
:param password: Password for authentication.
|
||||
:param verify: Verify SSL certificate, default True. This can also be a
|
||||
local path to a self-signed SSL certificate.
|
||||
local path to a self-signed SSL certificate. See :ref:`ssl-tutorial`
|
||||
for more information.
|
||||
:param verify_fingerprint: Optional. SHA1 or MD5 fingerprint of the
|
||||
expected server certificate.
|
||||
expected server certificate. See :ref:`ssl-tutorial` for more
|
||||
information.
|
||||
:param auth: Optional. Either ``basic``, ``digest`` or ``guess``. Default
|
||||
``guess``. If you know yours, consider setting it explicitly for
|
||||
performance.
|
||||
:param useragent: Default ``vdirsyncer``.
|
||||
'''
|
||||
|
||||
|
||||
class HttpStorage(Storage):
|
||||
__doc__ = '''
|
||||
Use a simple ``.ics`` file (or similar) from the web.
|
||||
|
||||
:param url: URL to the ``.ics`` file.
|
||||
''' + HTTP_STORAGE_PARAMETERS + '''
|
||||
|
||||
A simple example::
|
||||
|
||||
|
|
|
|||
|
|
@ -205,6 +205,7 @@ def request(method, url, session=None, latin1_fallback=True,
|
|||
session = requests.Session()
|
||||
|
||||
if verify_fingerprint is not None:
|
||||
kwargs['verify'] = False
|
||||
https_prefix = 'https://'
|
||||
|
||||
if not isinstance(session.adapters[https_prefix], _FingerprintAdapter):
|
||||
|
|
|
|||
Loading…
Reference in a new issue