lfos / calcurse

A text-based calendar and scheduling application
https://calcurse.org
BSD 2-Clause "Simplified" License
991 stars 94 forks source link

SSL error when running calcurse-caldav #374

Open gorrila20 opened 3 years ago

gorrila20 commented 3 years ago

Version information.
Calcurse version: 4.7.0 Operating System: OpenBSD 6.9 $ openssl version LibreSSL 3.3.2 python3 -c "import ssl; print(ssl.OPENSSL_VERSION)" LibreSSL 3.3.2 Caldav server: radicale version 2.1.12

calcurse-caldav configuration

[General] Binary = /usr/local/bin/calcurse Hostname = xx.xx:5232 Path = A super duper secret path AuthMethod = basic InsecureSSL = No HTTPS = Yes SyncFilter = cal,todo DryRun = Yes Verbose = Yes [Auth] Username = xx.xx

Bug description. When running calcurse-caldav --init=keep-remote I get a ssl error and cannot continue. The error I get: Traceback (most recent call last): File "/usr/local/bin/calcurse-caldav", line 756, in <module> etagdict = get_etags(conn) File "/usr/local/bin/calcurse-caldav", line 277, in get_etags headers, body = remote_query(conn, "REPORT", absolute_uri, headers, body) File "/usr/local/bin/calcurse-caldav", line 238, in remote_query resp, body = conn.request(path, cmd, body=body, headers=headers) File "/usr/local/lib/python3.8/site-packages/httplib2/__init__.py", line 1322, in request (response, content) = self._request(conn, authority, uri, request_uri, method, body, headers, redirections, cachekey) File "/usr/local/lib/python3.8/site-packages/httplib2/__init__.py", line 1072, in _request (response, content) = self._conn_request(conn, request_uri, method, body, headers) File "/usr/local/lib/python3.8/site-packages/httplib2/__init__.py", line 995, in _conn_request conn.connect() File "/usr/local/lib/python3.8/http/client.py", line 1424, in connect self.sock = self._context.wrap_socket(self.sock, File "/usr/local/lib/python3.8/ssl.py", line 500, in wrap_socket return self.sslsocket_class._create( File "/usr/local/lib/python3.8/ssl.py", line 1040, in _create self.do_handshake() File "/usr/local/lib/python3.8/ssl.py", line 1309, in do_handshake self._sslobj.do_handshake() ssl.SSLError: [SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl.c:1129)

This seems to be a duplicate of issue #82, I presume that because the port numbers in the config are the same and therefore I believe we use the same caldav server. I am pretty sure I have set up my caldav server correctly as it syncs perfectly with my phone using davx5. Some help on this issue would be appreciated. The password is given via environment variable so that cannot be the problem.

lfos commented 2 years ago

Jordan Bancino investigated and found that this seems to be caused through a combination of OpenBSD's SSL library and the httplib2 version currently shipped with OpenBSD. Including Jordan's full email on Jordan's behalf here:

I discovered that this not an issue with the calcurse-caldav script, nor is it an issue with Radicale. It's also not an issue with OpenBSD, although it is OpenBSD's strict security measures that make this issue appear. The issue lies in the Python library httplib2, more specifically, version 0.10.3p3 (and probably earlier versions), which is the version shipped with OpenBSD 7.0 and earlier. The issue is essentially this:

  1. httplib2 v0.10.3 and earlier force the underlying Python ssl module to use TLSv1.
  2. OpenBSD's SSL library does not have TLSv1 enabled by default, because it is considered obsolete. This is not a problem with OpenBSD's SSL libary. As a security-focused operating system, OpenBSD is correct in its decision to disable TLSv1.
  3. httplib2 fails when attempting to connect because OpenBSD does not support the old TLS protocol that it is trying to use. This is the real problem: httplib2 trying to force Python's ssl module to use a specific TLS protocol, instead of just letting the underlying library figure it out.

The newest version of httplib2 was added to ports last month, which means that we can expect to see it with the release of OpenBSD 7.1. I am fairly confident, looking through the source code for the newest release, that it has fixed this issue. However, OpenBSD users are stuck on the old version for the next few months until OpenBSD 7.1 is released. Fortunately, the fix is actually quite simple:

Use the following diff to patch /usr/local/lib/python3.8/site-packages/httplib2/__init__.py

846c846
<             context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
---
>             context = ssl.SSLContext()

This will allow the ssl library to automatically use the correct TLS protocol. If you upgrade OpenBSD to -current, or wait until 7.1, this issue should go away on its own. But until then, this patch should get things working.

Thanks Jordan!