Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot setup new account with DAVx5 to radicale 3.1.7 #1249

Open
tsailer opened this issue Jun 1, 2022 · 6 comments
Open

Cannot setup new account with DAVx5 to radicale 3.1.7 #1249

tsailer opened this issue Jun 1, 2022 · 6 comments
Labels
need:reporter feedback feedback from reporter required

Comments

@tsailer
Copy link

tsailer commented Jun 1, 2022

When an account is already setup, DAVx5 works well with radicale.

However, I cannot manage to set up a new account in DAVx5 to radicale. When I enter the account details, DAVx5 succeeds connecting to radicale, but then fails to find any calendars or address books. DAVx5 issues a PROPFIND to find calendars, which is answered by radicale with 403. At this point DAVx5 gives up. This is the debug log:

radicale[12345]: [2022-06-01 04:15:43 +0200] [31459] [INFO] Loaded default config
radicale[12345]: [2022-06-01 04:15:43 +0200] [31459] [INFO] Loaded config file '/etc/radicale/config'
radicale[12345]: [2022-06-01 04:15:43 +0200] [31459] [INFO] Skipped missing config file '/var/lib/radicale/.config/radicale/config'
radicale[12345]: [2022-06-01 04:15:43 +0200] [31459] [INFO] Starting Radicale
radicale[12345]: [2022-06-01 04:15:43 +0200] [31459] [INFO] auth type is 'radicale.auth.htpasswd'
radicale[12345]: [2022-06-01 04:15:43 +0200] [31459] [INFO] storage type is 'radicale.storage.multifilesystem'
radicale[12345]: [2022-06-01 04:15:43 +0200] [31459] [INFO] rights type is 'radicale.rights.owner_only'
radicale[12345]: [2022-06-01 04:15:43 +0200] [31459] [INFO] web type is 'radicale.web.internal'
radicale[12345]: [2022-06-01 04:15:43 +0200] [31459] [INFO] Listening on '[0.0.0.0]:5232' with SSL
radicale[12345]: [2022-06-01 04:15:43 +0200] [31459] [INFO] Listening on '[::]:5232' with SSL
radicale[12345]: [2022-06-01 04:15:43 +0200] [31459] [INFO] Radicale server ready
radicale[12345]: [2022-06-01 04:15:46 +0200] [31459/Thread-1 (process_request_thread)] [INFO] PROPFIND request for '/user/' with depth '0' received from 192.168.1.218 using '>
radicale[12345]: [2022-06-01 04:15:46 +0200] [31459/Thread-1 (process_request_thread)] [DEBUG] Request headers:
radicale[12345]: {'CONTENT_LENGTH': '236',
radicale[12345]: 'CONTENT_TYPE': 'application/xml; charset=utf-8',
radicale[12345]: 'GATEWAY_INTERFACE': 'CGI/1.1',
radicale[12345]: 'HTTP_ACCEPT_ENCODING': 'gzip',
radicale[12345]: 'HTTP_ACCEPT_LANGUAGE': 'de-CH, de;q=0.7, *;q=0.5',
radicale[12345]: 'HTTP_AUTHORIZATION': 'Basic masked',
radicale[12345]: 'HTTP_CONNECTION': 'Keep-Alive',
radicale[12345]: 'HTTP_DEPTH': '0',
radicale[12345]: 'HTTP_HOST': 'example.com:5232',
radicale[12345]: 'HTTP_USER_AGENT': 'DAVx5/4.2.1-ose (2022/05/08; dav4jvm; okhttp/4.9.3) '
radicale[12345]: 'Android/11',
radicale[12345]: 'PATH_INFO': '/user/',
radicale[12345]: 'QUERY_STRING': '',
radicale[12345]: 'REMOTE_ADDR': '192.168.1.218',
radicale[12345]: 'REMOTE_CERTIFICATE': None,
radicale[12345]: 'REMOTE_HOST': '',
radicale[12345]: 'REQUEST_METHOD': 'PROPFIND',
radicale[12345]: 'SCRIPT_NAME': '',
radicale[12345]: 'SERVER_NAME': 'example.com',
radicale[12345]: 'SERVER_PORT': '5232',
radicale[12345]: 'SERVER_PROTOCOL': 'HTTP/1.1',
radicale[12345]: 'SERVER_SOFTWARE': 'WSGIServer/0.2',
radicale[12345]: 'wsgi.errors': <_io.TextIOWrapper name='' mode='w' encoding='utf-8'>,
radicale[12345]: 'wsgi.file_wrapper': <class 'wsgiref.util.FileWrapper'>,
radicale[12345]: 'wsgi.input': <_io.BufferedReader name=7>,
radicale[12345]: 'wsgi.multiprocess': False,
radicale[12345]: 'wsgi.multithread': True,
radicale[12345]: 'wsgi.run_once': False,
radicale[12345]: 'wsgi.url_scheme': 'http',
radicale[12345]: 'wsgi.version': (1, 0)}
radicale[12345]: [2022-06-01 04:15:46 +0200] [31459/Thread-1 (process_request_thread)] [DEBUG] Base prefix (from SCRIPT_NAME): ''
radicale[12345]: [2022-06-01 04:15:46 +0200] [31459/Thread-1 (process_request_thread)] [DEBUG] Sanitized path: '/user/'
radicale[12345]: [2022-06-01 04:15:46 +0200] [31459/Thread-1 (process_request_thread)] [INFO] Successful login: 'user'
radicale[12345]: [2022-06-01 04:15:46 +0200] [31459/Thread-1 (process_request_thread)] [DEBUG] Request content:
radicale[12345]:
radicale[12345]:
radicale[12345]:
radicale[12345]:
radicale[12345]: <CR:addressbook-home-set />
radicale[12345]:
radicale[12345]:
radicale[12345]:
radicale[12345]: [2022-06-01 04:15:46 +0200] [31459/Thread-1 (process_request_thread)] [INFO] Access to '/user/' denied for 'user'
radicale[12345]: [2022-06-01 04:15:46 +0200] [31459/Thread-1 (process_request_thread)] [DEBUG] Response content:
radicale[12345]: Access to the requested resource forbidden.
radicale[12345]: [2022-06-01 04:15:46 +0200] [31459/Thread-1 (process_request_thread)] [INFO] PROPFIND response status for '/user/' with depth '0' in 0.002 seconds: 403 Forbidden

In order to set up the account, I temporarily patched out the permission checks:
diff -urN radicale/app/propfind.py radicale/app/propfind.py
--- radicale/app/propfind.py 2022-04-20 17:57:41.000000000 +0200
+++ radicale/app/propfind.py 2022-06-01 07:33:33.000000000 +0200
@@ -350,8 +350,8 @@
permission = "r"
status = "read"
else:

  •            permission = ""
    
  •            status = "NO"
    
  •            permission = "r"
    
  •            status = "read"
           logger.debug(
               "%s has %s access to %s",
               repr(user) if user else "anonymous user", status, target)
    

@@ -362,8 +362,8 @@
path: str, user: str) -> types.WSGIResponse:
"""Manage PROPFIND request."""
access = Access(self._rights, user, path)

  •    if not access.check("r"):
    
  •        return httputils.NOT_ALLOWED
    
  •    #if not access.check("r"):
    
  •    #    return httputils.NOT_ALLOWED
       try:
           xml_content = self._read_xml_request_body(environ)
       except RuntimeError as e:
    

@@ -380,8 +380,8 @@
item = next(items_iter, None)
if not item:
return httputils.NOT_FOUND

  •        if not access.check("r", item):
    
  •            return httputils.NOT_ALLOWED
    
  •        #if not access.check("r", item):
    
  •        #    return httputils.NOT_ALLOWED
           # put item back
           items_iter = itertools.chain([item], items_iter)
           allowed_items = self._collect_allowed_items(items_iter, user)
    

@@ -390,5 +390,6 @@
xml_answer = xml_propfind(base_prefix, path, xml_content,
allowed_items, user, self._encoding)
if xml_answer is None:

  •            logger.warning("xml_propfind returned no answer")
               return httputils.NOT_ALLOWED
           return client.MULTI_STATUS, headers, self._xml_response(xml_answer)
    

Which allowed me to set up the account. After that I reverted them and DAVx5 continues to work now.

I also downgraded radicale to 3.0.6, which didn't help. Neither did an older version of DAVx5 (2.6.3.1)

@tsailer
Copy link
Author

tsailer commented Jun 1, 2022

diff.txt

@jheidemann
Copy link

I have this same bug. Note that pre-existing accounts continue to work with DavX5 and Radicale-3.1.7.

I also traced the cause to the same issue is the OP: DavX5 sends a PROPFIND to URI/user/ to ask for what calenders are there, and Radicale returns 403.

With existing accounts, URIs to URI/user/calendar.ics/ work fine. But if you delete the account (or switch to a new phone) you can't recover. (In the existing accounts, calendars were discovered with Radicale-2.x.)

The problem may be base_prefix related, but it occurs both with WSGI and reverse-proxy setups (yes, with X-Script-Name set when using reverse proxy).

@jheidemann
Copy link

As a work-around, one can specific a full URL to each calendar (i.e., URI/user/calendar.ics/). This succeeds for me. One then must do that for each existing calendar if you have several. Android (and therefore DAVX5) requires each get a unique account, so you might specify the account as user+calendar.

I tried to look into what's going on. I thought it was because I had an empty rights file (how can that be, and what are the defaults?), but filling it in and then making it wide open didn't help. It's not clear to me how calendar discovery is supposed to work in the code.

@jheidemann
Copy link

(Oh, one more thing: the problem is not DAVX5 specific. I get the same 403 when I point cadavar at https://host/radicale/user/ as well [where cadaver is a Linux CLI Caldav client].)

@pbiering pbiering added the need:reporter feedback feedback from reporter required label Mar 16, 2024
@pbiering
Copy link
Collaborator

pbiering commented Mar 16, 2024

I can't replicate the issue

  • precondition

    • "new account" user is known in authentication database - but has never logged on so far
    • therefore no "user" subdirectory exists in collection-root for this user
    • rights type "owner_only" (default)
  • Successful logon via WebUI or "DAVx" will result in that "radicale" creates the "user" folder in collection-root

    • New calendars can be created via WebU
    • New calendars can be created via "DAVx

btw: "mkcol" with cadaver will not work because this is sent without XML request and therefore blocked by "radicale" by default.

@pbiering
Copy link
Collaborator

#1455 extended logging related to "mkcol"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
need:reporter feedback feedback from reporter required
Projects
None yet
Development

No branches or pull requests

3 participants