summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjoern Kahl <mls@bjoern-kahl.de>2022-01-01 21:35:55 +0100
committerTobias Brox <tobias@redpill-linpro.com>2022-01-25 20:47:26 +0100
commita809c3420f30ceb8e7d8314bbed4425a9f0eda86 (patch)
tree5b43ffc3b4798027ae90d2b2e263863c812f8ae1
parentafde24719955ae1d1ac79c41ef4bb01007402282 (diff)
downloadpython-caldav-a809c3420f30ceb8e7d8314bbed4425a9f0eda86.zip
Fix HTTP Auth failure with old (pre UTF-8) serversv0.8-stable
Some servers, like really old SabreDAV based servers, seem to choke on password if we pass a bytes sequence instead of a string to the "requests" libraries HTTPDigestAuth object. This Fix retries authentication in case of authentication failure with the same password as plain string (which, in Python3 is anyway UTF-8).
-rw-r--r--caldav/davclient.py17
1 files changed, 17 insertions, 0 deletions
diff --git a/caldav/davclient.py b/caldav/davclient.py
index e5f9e51..894cd1a 100644
--- a/caldav/davclient.py
+++ b/caldav/davclient.py
@@ -518,6 +518,7 @@ class DAVClient:
(combined_headers, proxies) = self._pre_request(url, body, headers)
+ auth_type = None
if not self.auth:
## Try a test request w/o auth
resp = self.session.request(
@@ -557,6 +558,22 @@ class DAVClient:
verify=self.ssl_verify_cert, cert=self.ssl_cert)
if resp.status_code > 399:
+ ## Some (ancient) servers don't like UTF-8 binary auth with Digest authentication.
+ ## An example are old SabreDAV based servers. Not sure about UTF-8 and Basic Auth,
+ ## but likely the same. so retry if password is a bytes sequence and not a string
+ ## (see commit 13a4714, which introduced this regression)
+ if auth_type is not None and hasattr(self.password, 'decode'):
+ if auth_type == 'Basic':
+ self.auth = requests.auth.HTTPBasicAuth(self.username, self.password.decode())
+ elif auth_type == 'Digest':
+ self.auth = requests.auth.HTTPDigestAuth(self.username, self.password.decode())
+ resp = self.session.request(
+ method, url, data=to_wire(body),
+ headers=combined_headers, proxies=proxies, auth=self.auth,
+ verify=self.ssl_verify_cert, cert=self.ssl_cert)
+
+ if resp.status_code > 399:
+ ## We tried all we can, probably the credentials are _really_ wrong...
raise error.AuthorizationError(url=url, reason=resp.reason)
def request(self, url, method="GET", body="", headers={}):